1/**************************************************************************
2 *
3 * Copyright 2015 Advanced Micro Devices, Inc.
4 * Copyright 2008 VMware, Inc.
5 * All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * on the rights to use, copy, modify, merge, publish, distribute, sub
11 * license, and/or sell copies of the Software, and to permit persons to whom
12 * the Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
16 * Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
22 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24 * USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28#include "dd_pipe.h"
29#include "tgsi/tgsi_parse.h"
30#include "util/u_inlines.h"
31#include "util/u_memory.h"
32
33
34static void
35safe_memcpy(void *dst, const void *src, size_t size)
36{
37   if (src)
38      memcpy(dst, src, size);
39   else
40      memset(dst, 0, size);
41}
42
43
44/********************************************************************
45 * queries
46 */
47
48static struct dd_query *
49dd_query(struct pipe_query *query)
50{
51   return (struct dd_query *)query;
52}
53
54static struct pipe_query *
55dd_query_unwrap(struct pipe_query *query)
56{
57   if (query) {
58      return dd_query(query)->query;
59   } else {
60      return NULL;
61   }
62}
63
64static struct pipe_query *
65dd_context_create_query(struct pipe_context *_pipe, unsigned query_type,
66                        unsigned index)
67{
68   struct pipe_context *pipe = dd_context(_pipe)->pipe;
69   struct pipe_query *query;
70
71   query = pipe->create_query(pipe, query_type, index);
72
73   /* Wrap query object. */
74   if (query) {
75      struct dd_query *dd_query = CALLOC_STRUCT(dd_query);
76      if (dd_query) {
77         dd_query->type = query_type;
78         dd_query->query = query;
79         query = (struct pipe_query *)dd_query;
80      } else {
81         pipe->destroy_query(pipe, query);
82         query = NULL;
83      }
84   }
85
86   return query;
87}
88
89static struct pipe_query *
90dd_context_create_batch_query(struct pipe_context *_pipe, unsigned num_queries,
91                              unsigned *query_types)
92{
93   struct pipe_context *pipe = dd_context(_pipe)->pipe;
94   struct pipe_query *query;
95
96   query = pipe->create_batch_query(pipe, num_queries, query_types);
97
98   /* Wrap query object. */
99   if (query) {
100      struct dd_query *dd_query = CALLOC_STRUCT(dd_query);
101      if (dd_query) {
102         /* no special handling for batch queries yet */
103         dd_query->type = query_types[0];
104         dd_query->query = query;
105         query = (struct pipe_query *)dd_query;
106      } else {
107         pipe->destroy_query(pipe, query);
108         query = NULL;
109      }
110   }
111
112   return query;
113}
114
115static void
116dd_context_destroy_query(struct pipe_context *_pipe,
117                         struct pipe_query *query)
118{
119   struct pipe_context *pipe = dd_context(_pipe)->pipe;
120
121   pipe->destroy_query(pipe, dd_query_unwrap(query));
122   FREE(query);
123}
124
125static boolean
126dd_context_begin_query(struct pipe_context *_pipe, struct pipe_query *query)
127{
128   struct dd_context *dctx = dd_context(_pipe);
129   struct pipe_context *pipe = dctx->pipe;
130
131   return pipe->begin_query(pipe, dd_query_unwrap(query));
132}
133
134static bool
135dd_context_end_query(struct pipe_context *_pipe, struct pipe_query *query)
136{
137   struct dd_context *dctx = dd_context(_pipe);
138   struct pipe_context *pipe = dctx->pipe;
139
140   return pipe->end_query(pipe, dd_query_unwrap(query));
141}
142
143static boolean
144dd_context_get_query_result(struct pipe_context *_pipe,
145                            struct pipe_query *query, boolean wait,
146                            union pipe_query_result *result)
147{
148   struct pipe_context *pipe = dd_context(_pipe)->pipe;
149
150   return pipe->get_query_result(pipe, dd_query_unwrap(query), wait, result);
151}
152
153static void
154dd_context_set_active_query_state(struct pipe_context *_pipe, boolean enable)
155{
156   struct pipe_context *pipe = dd_context(_pipe)->pipe;
157
158   pipe->set_active_query_state(pipe, enable);
159}
160
161static void
162dd_context_render_condition(struct pipe_context *_pipe,
163                            struct pipe_query *query, boolean condition,
164                            uint mode)
165{
166   struct dd_context *dctx = dd_context(_pipe);
167   struct pipe_context *pipe = dctx->pipe;
168   struct dd_draw_state *dstate = &dctx->draw_state;
169
170   pipe->render_condition(pipe, dd_query_unwrap(query), condition, mode);
171   dstate->render_cond.query = dd_query(query);
172   dstate->render_cond.condition = condition;
173   dstate->render_cond.mode = mode;
174}
175
176
177/********************************************************************
178 * constant (immutable) non-shader states
179 */
180
181#define DD_CSO_CREATE(name, shortname) \
182   static void * \
183   dd_context_create_##name##_state(struct pipe_context *_pipe, \
184                                    const struct pipe_##name##_state *state) \
185   { \
186      struct pipe_context *pipe = dd_context(_pipe)->pipe; \
187      struct dd_state *hstate = CALLOC_STRUCT(dd_state); \
188 \
189      if (!hstate) \
190         return NULL; \
191      hstate->cso = pipe->create_##name##_state(pipe, state); \
192      hstate->state.shortname = *state; \
193      return hstate; \
194   }
195
196#define DD_CSO_BIND(name, shortname) \
197   static void \
198   dd_context_bind_##name##_state(struct pipe_context *_pipe, void *state) \
199   { \
200      struct dd_context *dctx = dd_context(_pipe); \
201      struct pipe_context *pipe = dctx->pipe; \
202      struct dd_state *hstate = state; \
203 \
204      dctx->draw_state.shortname = hstate; \
205      pipe->bind_##name##_state(pipe, hstate ? hstate->cso : NULL); \
206   }
207
208#define DD_CSO_DELETE(name) \
209   static void \
210   dd_context_delete_##name##_state(struct pipe_context *_pipe, void *state) \
211   { \
212      struct dd_context *dctx = dd_context(_pipe); \
213      struct pipe_context *pipe = dctx->pipe; \
214      struct dd_state *hstate = state; \
215 \
216      pipe->delete_##name##_state(pipe, hstate->cso); \
217      FREE(hstate); \
218   }
219
220#define DD_CSO_WHOLE(name, shortname) \
221   DD_CSO_CREATE(name, shortname) \
222   DD_CSO_BIND(name, shortname) \
223   DD_CSO_DELETE(name)
224
225DD_CSO_WHOLE(blend, blend)
226DD_CSO_WHOLE(rasterizer, rs)
227DD_CSO_WHOLE(depth_stencil_alpha, dsa)
228
229DD_CSO_CREATE(sampler, sampler)
230DD_CSO_DELETE(sampler)
231
232static void
233dd_context_bind_sampler_states(struct pipe_context *_pipe,
234                               enum pipe_shader_type shader,
235                               unsigned start, unsigned count, void **states)
236{
237   struct dd_context *dctx = dd_context(_pipe);
238   struct pipe_context *pipe = dctx->pipe;
239
240   memcpy(&dctx->draw_state.sampler_states[shader][start], states,
241          sizeof(void*) * count);
242
243   if (states) {
244      void *samp[PIPE_MAX_SAMPLERS];
245      int i;
246
247      for (i = 0; i < count; i++) {
248         struct dd_state *s = states[i];
249         samp[i] = s ? s->cso : NULL;
250      }
251
252      pipe->bind_sampler_states(pipe, shader, start, count, samp);
253   }
254   else
255      pipe->bind_sampler_states(pipe, shader, start, count, NULL);
256}
257
258static void *
259dd_context_create_vertex_elements_state(struct pipe_context *_pipe,
260                                        unsigned num_elems,
261                                        const struct pipe_vertex_element *elems)
262{
263   struct pipe_context *pipe = dd_context(_pipe)->pipe;
264   struct dd_state *hstate = CALLOC_STRUCT(dd_state);
265
266   if (!hstate)
267      return NULL;
268   hstate->cso = pipe->create_vertex_elements_state(pipe, num_elems, elems);
269   memcpy(hstate->state.velems.velems, elems, sizeof(elems[0]) * num_elems);
270   hstate->state.velems.count = num_elems;
271   return hstate;
272}
273
274DD_CSO_BIND(vertex_elements, velems)
275DD_CSO_DELETE(vertex_elements)
276
277
278/********************************************************************
279 * shaders
280 */
281
282#define DD_SHADER_NOCREATE(NAME, name) \
283   static void \
284   dd_context_bind_##name##_state(struct pipe_context *_pipe, void *state) \
285   { \
286      struct dd_context *dctx = dd_context(_pipe); \
287      struct pipe_context *pipe = dctx->pipe; \
288      struct dd_state *hstate = state; \
289   \
290      dctx->draw_state.shaders[PIPE_SHADER_##NAME] = hstate; \
291      pipe->bind_##name##_state(pipe, hstate ? hstate->cso : NULL); \
292   } \
293    \
294   static void \
295   dd_context_delete_##name##_state(struct pipe_context *_pipe, void *state) \
296   { \
297      struct dd_context *dctx = dd_context(_pipe); \
298      struct pipe_context *pipe = dctx->pipe; \
299      struct dd_state *hstate = state; \
300   \
301      pipe->delete_##name##_state(pipe, hstate->cso); \
302      tgsi_free_tokens(hstate->state.shader.tokens); \
303      FREE(hstate); \
304   }
305
306#define DD_SHADER(NAME, name) \
307   static void * \
308   dd_context_create_##name##_state(struct pipe_context *_pipe, \
309                                    const struct pipe_shader_state *state) \
310   { \
311      struct pipe_context *pipe = dd_context(_pipe)->pipe; \
312      struct dd_state *hstate = CALLOC_STRUCT(dd_state); \
313 \
314      if (!hstate) \
315         return NULL; \
316      hstate->cso = pipe->create_##name##_state(pipe, state); \
317      hstate->state.shader = *state; \
318      hstate->state.shader.tokens = tgsi_dup_tokens(state->tokens); \
319      return hstate; \
320   } \
321    \
322   DD_SHADER_NOCREATE(NAME, name)
323
324DD_SHADER(FRAGMENT, fs)
325DD_SHADER(VERTEX, vs)
326DD_SHADER(GEOMETRY, gs)
327DD_SHADER(TESS_CTRL, tcs)
328DD_SHADER(TESS_EVAL, tes)
329
330static void * \
331dd_context_create_compute_state(struct pipe_context *_pipe,
332                                 const struct pipe_compute_state *state)
333{
334   struct pipe_context *pipe = dd_context(_pipe)->pipe;
335   struct dd_state *hstate = CALLOC_STRUCT(dd_state);
336
337   if (!hstate)
338      return NULL;
339   hstate->cso = pipe->create_compute_state(pipe, state);
340
341   if (state->ir_type == PIPE_SHADER_IR_TGSI)
342      hstate->state.shader.tokens = tgsi_dup_tokens(state->prog);
343
344   return hstate;
345}
346
347DD_SHADER_NOCREATE(COMPUTE, compute)
348
349/********************************************************************
350 * immediate states
351 */
352
353#define DD_IMM_STATE(name, type, deref, ref) \
354   static void \
355   dd_context_set_##name(struct pipe_context *_pipe, type deref) \
356   { \
357      struct dd_context *dctx = dd_context(_pipe); \
358      struct pipe_context *pipe = dctx->pipe; \
359 \
360      dctx->draw_state.name = deref; \
361      pipe->set_##name(pipe, ref); \
362   }
363
364DD_IMM_STATE(blend_color, const struct pipe_blend_color, *state, state)
365DD_IMM_STATE(stencil_ref, const struct pipe_stencil_ref, *state, state)
366DD_IMM_STATE(clip_state, const struct pipe_clip_state, *state, state)
367DD_IMM_STATE(sample_mask, unsigned, sample_mask, sample_mask)
368DD_IMM_STATE(min_samples, unsigned, min_samples, min_samples)
369DD_IMM_STATE(framebuffer_state, const struct pipe_framebuffer_state, *state, state)
370DD_IMM_STATE(polygon_stipple, const struct pipe_poly_stipple, *state, state)
371
372static void
373dd_context_set_constant_buffer(struct pipe_context *_pipe,
374                               uint shader, uint index,
375                               const struct pipe_constant_buffer *constant_buffer)
376{
377   struct dd_context *dctx = dd_context(_pipe);
378   struct pipe_context *pipe = dctx->pipe;
379
380   safe_memcpy(&dctx->draw_state.constant_buffers[shader][index],
381               constant_buffer, sizeof(*constant_buffer));
382   pipe->set_constant_buffer(pipe, shader, index, constant_buffer);
383}
384
385static void
386dd_context_set_scissor_states(struct pipe_context *_pipe,
387                              unsigned start_slot, unsigned num_scissors,
388                              const struct pipe_scissor_state *states)
389{
390   struct dd_context *dctx = dd_context(_pipe);
391   struct pipe_context *pipe = dctx->pipe;
392
393   safe_memcpy(&dctx->draw_state.scissors[start_slot], states,
394               sizeof(*states) * num_scissors);
395   pipe->set_scissor_states(pipe, start_slot, num_scissors, states);
396}
397
398static void
399dd_context_set_viewport_states(struct pipe_context *_pipe,
400                               unsigned start_slot, unsigned num_viewports,
401                               const struct pipe_viewport_state *states)
402{
403   struct dd_context *dctx = dd_context(_pipe);
404   struct pipe_context *pipe = dctx->pipe;
405
406   safe_memcpy(&dctx->draw_state.viewports[start_slot], states,
407               sizeof(*states) * num_viewports);
408   pipe->set_viewport_states(pipe, start_slot, num_viewports, states);
409}
410
411static void dd_context_set_tess_state(struct pipe_context *_pipe,
412                                      const float default_outer_level[4],
413                                      const float default_inner_level[2])
414{
415   struct dd_context *dctx = dd_context(_pipe);
416   struct pipe_context *pipe = dctx->pipe;
417
418   memcpy(dctx->draw_state.tess_default_levels, default_outer_level,
419          sizeof(float) * 4);
420   memcpy(dctx->draw_state.tess_default_levels+4, default_inner_level,
421          sizeof(float) * 2);
422   pipe->set_tess_state(pipe, default_outer_level, default_inner_level);
423}
424
425
426/********************************************************************
427 * views
428 */
429
430static struct pipe_surface *
431dd_context_create_surface(struct pipe_context *_pipe,
432                          struct pipe_resource *resource,
433                          const struct pipe_surface *surf_tmpl)
434{
435   struct pipe_context *pipe = dd_context(_pipe)->pipe;
436   struct pipe_surface *view =
437      pipe->create_surface(pipe, resource, surf_tmpl);
438
439   if (!view)
440      return NULL;
441   view->context = _pipe;
442   return view;
443}
444
445static void
446dd_context_surface_destroy(struct pipe_context *_pipe,
447                           struct pipe_surface *surf)
448{
449   struct pipe_context *pipe = dd_context(_pipe)->pipe;
450
451   pipe->surface_destroy(pipe, surf);
452}
453
454static struct pipe_sampler_view *
455dd_context_create_sampler_view(struct pipe_context *_pipe,
456                               struct pipe_resource *resource,
457                               const struct pipe_sampler_view *templ)
458{
459   struct pipe_context *pipe = dd_context(_pipe)->pipe;
460   struct pipe_sampler_view *view =
461      pipe->create_sampler_view(pipe, resource, templ);
462
463   if (!view)
464      return NULL;
465   view->context = _pipe;
466   return view;
467}
468
469static void
470dd_context_sampler_view_destroy(struct pipe_context *_pipe,
471                                struct pipe_sampler_view *view)
472{
473   struct pipe_context *pipe = dd_context(_pipe)->pipe;
474
475   pipe->sampler_view_destroy(pipe, view);
476}
477
478static struct pipe_stream_output_target *
479dd_context_create_stream_output_target(struct pipe_context *_pipe,
480                                       struct pipe_resource *res,
481                                       unsigned buffer_offset,
482                                       unsigned buffer_size)
483{
484   struct pipe_context *pipe = dd_context(_pipe)->pipe;
485   struct pipe_stream_output_target *view =
486      pipe->create_stream_output_target(pipe, res, buffer_offset,
487                                        buffer_size);
488
489   if (!view)
490      return NULL;
491   view->context = _pipe;
492   return view;
493}
494
495static void
496dd_context_stream_output_target_destroy(struct pipe_context *_pipe,
497                                        struct pipe_stream_output_target *target)
498{
499   struct pipe_context *pipe = dd_context(_pipe)->pipe;
500
501   pipe->stream_output_target_destroy(pipe, target);
502}
503
504
505/********************************************************************
506 * set states
507 */
508
509static void
510dd_context_set_sampler_views(struct pipe_context *_pipe,
511                             enum pipe_shader_type shader,
512                             unsigned start, unsigned num,
513                             struct pipe_sampler_view **views)
514{
515   struct dd_context *dctx = dd_context(_pipe);
516   struct pipe_context *pipe = dctx->pipe;
517
518   safe_memcpy(&dctx->draw_state.sampler_views[shader][start], views,
519               sizeof(views[0]) * num);
520   pipe->set_sampler_views(pipe, shader, start, num, views);
521}
522
523static void
524dd_context_set_shader_images(struct pipe_context *_pipe,
525                             enum pipe_shader_type shader,
526                             unsigned start, unsigned num,
527                             const struct pipe_image_view *views)
528{
529   struct dd_context *dctx = dd_context(_pipe);
530   struct pipe_context *pipe = dctx->pipe;
531
532   safe_memcpy(&dctx->draw_state.shader_images[shader][start], views,
533               sizeof(views[0]) * num);
534   pipe->set_shader_images(pipe, shader, start, num, views);
535}
536
537static void
538dd_context_set_shader_buffers(struct pipe_context *_pipe, unsigned shader,
539                              unsigned start, unsigned num_buffers,
540                              const struct pipe_shader_buffer *buffers)
541{
542   struct dd_context *dctx = dd_context(_pipe);
543   struct pipe_context *pipe = dctx->pipe;
544
545   safe_memcpy(&dctx->draw_state.shader_buffers[shader][start], buffers,
546               sizeof(buffers[0]) * num_buffers);
547   pipe->set_shader_buffers(pipe, shader, start, num_buffers, buffers);
548}
549
550static void
551dd_context_set_vertex_buffers(struct pipe_context *_pipe,
552                              unsigned start, unsigned num_buffers,
553                              const struct pipe_vertex_buffer *buffers)
554{
555   struct dd_context *dctx = dd_context(_pipe);
556   struct pipe_context *pipe = dctx->pipe;
557
558   safe_memcpy(&dctx->draw_state.vertex_buffers[start], buffers,
559               sizeof(buffers[0]) * num_buffers);
560   pipe->set_vertex_buffers(pipe, start, num_buffers, buffers);
561}
562
563static void
564dd_context_set_index_buffer(struct pipe_context *_pipe,
565                            const struct pipe_index_buffer *ib)
566{
567   struct dd_context *dctx = dd_context(_pipe);
568   struct pipe_context *pipe = dctx->pipe;
569
570   safe_memcpy(&dctx->draw_state.index_buffer, ib, sizeof(*ib));
571   pipe->set_index_buffer(pipe, ib);
572}
573
574static void
575dd_context_set_stream_output_targets(struct pipe_context *_pipe,
576                                     unsigned num_targets,
577                                     struct pipe_stream_output_target **tgs,
578                                     const unsigned *offsets)
579{
580   struct dd_context *dctx = dd_context(_pipe);
581   struct pipe_context *pipe = dctx->pipe;
582   struct dd_draw_state *dstate = &dctx->draw_state;
583
584   dstate->num_so_targets = num_targets;
585   safe_memcpy(dstate->so_targets, tgs, sizeof(*tgs) * num_targets);
586   safe_memcpy(dstate->so_offsets, offsets, sizeof(*offsets) * num_targets);
587   pipe->set_stream_output_targets(pipe, num_targets, tgs, offsets);
588}
589
590static void
591dd_context_destroy(struct pipe_context *_pipe)
592{
593   struct dd_context *dctx = dd_context(_pipe);
594   struct pipe_context *pipe = dctx->pipe;
595
596   if (dctx->thread) {
597      pipe_mutex_lock(dctx->mutex);
598      dctx->kill_thread = 1;
599      pipe_mutex_unlock(dctx->mutex);
600      pipe_thread_wait(dctx->thread);
601      pipe_mutex_destroy(dctx->mutex);
602      assert(!dctx->records);
603   }
604
605   if (dctx->fence) {
606      pipe->transfer_unmap(pipe, dctx->fence_transfer);
607      pipe_resource_reference(&dctx->fence, NULL);
608   }
609   pipe->destroy(pipe);
610   FREE(dctx);
611}
612
613
614/********************************************************************
615 * transfer
616 */
617
618static void *
619dd_context_transfer_map(struct pipe_context *_pipe,
620                        struct pipe_resource *resource, unsigned level,
621                        unsigned usage, const struct pipe_box *box,
622                        struct pipe_transfer **transfer)
623{
624   struct pipe_context *pipe = dd_context(_pipe)->pipe;
625
626   return pipe->transfer_map(pipe, resource, level, usage, box, transfer);
627}
628
629static void
630dd_context_transfer_flush_region(struct pipe_context *_pipe,
631                                 struct pipe_transfer *transfer,
632                                 const struct pipe_box *box)
633{
634   struct pipe_context *pipe = dd_context(_pipe)->pipe;
635
636   pipe->transfer_flush_region(pipe, transfer, box);
637}
638
639static void
640dd_context_transfer_unmap(struct pipe_context *_pipe,
641                          struct pipe_transfer *transfer)
642{
643   struct pipe_context *pipe = dd_context(_pipe)->pipe;
644
645   pipe->transfer_unmap(pipe, transfer);
646}
647
648static void
649dd_context_buffer_subdata(struct pipe_context *_pipe,
650                          struct pipe_resource *resource,
651                          unsigned usage, unsigned offset,
652                          unsigned size, const void *data)
653{
654   struct pipe_context *pipe = dd_context(_pipe)->pipe;
655
656   pipe->buffer_subdata(pipe, resource, usage, offset, size, data);
657}
658
659static void
660dd_context_texture_subdata(struct pipe_context *_pipe,
661                           struct pipe_resource *resource,
662                           unsigned level, unsigned usage,
663                           const struct pipe_box *box,
664                           const void *data, unsigned stride,
665                           unsigned layer_stride)
666{
667   struct pipe_context *pipe = dd_context(_pipe)->pipe;
668
669   pipe->texture_subdata(pipe, resource, level, usage, box, data,
670                         stride, layer_stride);
671}
672
673
674/********************************************************************
675 * miscellaneous
676 */
677
678static void
679dd_context_texture_barrier(struct pipe_context *_pipe, unsigned flags)
680{
681   struct pipe_context *pipe = dd_context(_pipe)->pipe;
682
683   pipe->texture_barrier(pipe, flags);
684}
685
686static void
687dd_context_memory_barrier(struct pipe_context *_pipe, unsigned flags)
688{
689   struct pipe_context *pipe = dd_context(_pipe)->pipe;
690
691   pipe->memory_barrier(pipe, flags);
692}
693
694static void
695dd_context_get_sample_position(struct pipe_context *_pipe,
696                               unsigned sample_count, unsigned sample_index,
697                               float *out_value)
698{
699   struct pipe_context *pipe = dd_context(_pipe)->pipe;
700
701   return pipe->get_sample_position(pipe, sample_count, sample_index,
702                                    out_value);
703}
704
705static void
706dd_context_invalidate_resource(struct pipe_context *_pipe,
707                               struct pipe_resource *resource)
708{
709   struct pipe_context *pipe = dd_context(_pipe)->pipe;
710
711   pipe->invalidate_resource(pipe, resource);
712}
713
714static enum pipe_reset_status
715dd_context_get_device_reset_status(struct pipe_context *_pipe)
716{
717   struct pipe_context *pipe = dd_context(_pipe)->pipe;
718
719   return pipe->get_device_reset_status(pipe);
720}
721
722static void
723dd_context_set_device_reset_callback(struct pipe_context *_pipe,
724                                     const struct pipe_device_reset_callback *cb)
725{
726   struct pipe_context *pipe = dd_context(_pipe)->pipe;
727
728   return pipe->set_device_reset_callback(pipe, cb);
729}
730
731static void
732dd_context_emit_string_marker(struct pipe_context *_pipe,
733                              const char *string, int len)
734{
735   struct dd_context *dctx = dd_context(_pipe);
736   struct pipe_context *pipe = dctx->pipe;
737
738   pipe->emit_string_marker(pipe, string, len);
739   dd_parse_apitrace_marker(string, len, &dctx->draw_state.apitrace_call_number);
740}
741
742static void
743dd_context_dump_debug_state(struct pipe_context *_pipe, FILE *stream,
744                            unsigned flags)
745{
746   struct pipe_context *pipe = dd_context(_pipe)->pipe;
747
748   return pipe->dump_debug_state(pipe, stream, flags);
749}
750
751struct pipe_context *
752dd_context_create(struct dd_screen *dscreen, struct pipe_context *pipe)
753{
754   struct dd_context *dctx;
755
756   if (!pipe)
757      return NULL;
758
759   dctx = CALLOC_STRUCT(dd_context);
760   if (!dctx)
761      goto fail;
762
763   dctx->pipe = pipe;
764   dctx->base.priv = pipe->priv; /* expose wrapped priv data */
765   dctx->base.screen = &dscreen->base;
766
767   dctx->base.destroy = dd_context_destroy;
768
769   CTX_INIT(render_condition);
770   CTX_INIT(create_query);
771   CTX_INIT(create_batch_query);
772   CTX_INIT(destroy_query);
773   CTX_INIT(begin_query);
774   CTX_INIT(end_query);
775   CTX_INIT(get_query_result);
776   CTX_INIT(set_active_query_state);
777   CTX_INIT(create_blend_state);
778   CTX_INIT(bind_blend_state);
779   CTX_INIT(delete_blend_state);
780   CTX_INIT(create_sampler_state);
781   CTX_INIT(bind_sampler_states);
782   CTX_INIT(delete_sampler_state);
783   CTX_INIT(create_rasterizer_state);
784   CTX_INIT(bind_rasterizer_state);
785   CTX_INIT(delete_rasterizer_state);
786   CTX_INIT(create_depth_stencil_alpha_state);
787   CTX_INIT(bind_depth_stencil_alpha_state);
788   CTX_INIT(delete_depth_stencil_alpha_state);
789   CTX_INIT(create_fs_state);
790   CTX_INIT(bind_fs_state);
791   CTX_INIT(delete_fs_state);
792   CTX_INIT(create_vs_state);
793   CTX_INIT(bind_vs_state);
794   CTX_INIT(delete_vs_state);
795   CTX_INIT(create_gs_state);
796   CTX_INIT(bind_gs_state);
797   CTX_INIT(delete_gs_state);
798   CTX_INIT(create_tcs_state);
799   CTX_INIT(bind_tcs_state);
800   CTX_INIT(delete_tcs_state);
801   CTX_INIT(create_tes_state);
802   CTX_INIT(bind_tes_state);
803   CTX_INIT(delete_tes_state);
804   CTX_INIT(create_compute_state);
805   CTX_INIT(bind_compute_state);
806   CTX_INIT(delete_compute_state);
807   CTX_INIT(create_vertex_elements_state);
808   CTX_INIT(bind_vertex_elements_state);
809   CTX_INIT(delete_vertex_elements_state);
810   CTX_INIT(set_blend_color);
811   CTX_INIT(set_stencil_ref);
812   CTX_INIT(set_sample_mask);
813   CTX_INIT(set_min_samples);
814   CTX_INIT(set_clip_state);
815   CTX_INIT(set_constant_buffer);
816   CTX_INIT(set_framebuffer_state);
817   CTX_INIT(set_polygon_stipple);
818   CTX_INIT(set_scissor_states);
819   CTX_INIT(set_viewport_states);
820   CTX_INIT(set_sampler_views);
821   CTX_INIT(set_tess_state);
822   CTX_INIT(set_shader_buffers);
823   CTX_INIT(set_shader_images);
824   CTX_INIT(set_vertex_buffers);
825   CTX_INIT(set_index_buffer);
826   CTX_INIT(create_stream_output_target);
827   CTX_INIT(stream_output_target_destroy);
828   CTX_INIT(set_stream_output_targets);
829   CTX_INIT(create_sampler_view);
830   CTX_INIT(sampler_view_destroy);
831   CTX_INIT(create_surface);
832   CTX_INIT(surface_destroy);
833   CTX_INIT(transfer_map);
834   CTX_INIT(transfer_flush_region);
835   CTX_INIT(transfer_unmap);
836   CTX_INIT(buffer_subdata);
837   CTX_INIT(texture_subdata);
838   CTX_INIT(texture_barrier);
839   CTX_INIT(memory_barrier);
840   /* create_video_codec */
841   /* create_video_buffer */
842   /* set_compute_resources */
843   /* set_global_binding */
844   CTX_INIT(get_sample_position);
845   CTX_INIT(invalidate_resource);
846   CTX_INIT(get_device_reset_status);
847   CTX_INIT(set_device_reset_callback);
848   CTX_INIT(dump_debug_state);
849   CTX_INIT(emit_string_marker);
850
851   dd_init_draw_functions(dctx);
852
853   dctx->draw_state.sample_mask = ~0;
854
855   if (dscreen->mode == DD_DETECT_HANGS_PIPELINED) {
856      dctx->fence = pipe_buffer_create(dscreen->screen, PIPE_BIND_CUSTOM,
857                                            PIPE_USAGE_STAGING, 4);
858      if (!dctx->fence)
859         goto fail;
860
861      dctx->mapped_fence = pipe_buffer_map(pipe, dctx->fence,
862                                           PIPE_TRANSFER_READ_WRITE |
863                                           PIPE_TRANSFER_PERSISTENT |
864                                           PIPE_TRANSFER_COHERENT,
865                                           &dctx->fence_transfer);
866      if (!dctx->mapped_fence)
867         goto fail;
868
869      *dctx->mapped_fence = 0;
870
871      pipe_mutex_init(dctx->mutex);
872      dctx->thread = pipe_thread_create(dd_thread_pipelined_hang_detect, dctx);
873      if (!dctx->thread) {
874         pipe_mutex_destroy(dctx->mutex);
875         goto fail;
876      }
877   }
878
879   return &dctx->base;
880
881fail:
882   if (dctx) {
883      if (dctx->mapped_fence)
884         pipe_transfer_unmap(pipe, dctx->fence_transfer);
885      pipe_resource_reference(&dctx->fence, NULL);
886      FREE(dctx);
887   }
888   pipe->destroy(pipe);
889   return NULL;
890}
891