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 pipe_query *
49dd_context_create_query(struct pipe_context *_pipe, unsigned query_type,
50                        unsigned index)
51{
52   struct pipe_context *pipe = dd_context(_pipe)->pipe;
53   struct pipe_query *query;
54
55   query = pipe->create_query(pipe, query_type, index);
56
57   /* Wrap query object. */
58   if (query) {
59      struct dd_query *dd_query = CALLOC_STRUCT(dd_query);
60      if (dd_query) {
61         dd_query->type = query_type;
62         dd_query->query = query;
63         query = (struct pipe_query *)dd_query;
64      } else {
65         pipe->destroy_query(pipe, query);
66         query = NULL;
67      }
68   }
69
70   return query;
71}
72
73static struct pipe_query *
74dd_context_create_batch_query(struct pipe_context *_pipe, unsigned num_queries,
75                              unsigned *query_types)
76{
77   struct pipe_context *pipe = dd_context(_pipe)->pipe;
78   struct pipe_query *query;
79
80   query = pipe->create_batch_query(pipe, num_queries, query_types);
81
82   /* Wrap query object. */
83   if (query) {
84      struct dd_query *dd_query = CALLOC_STRUCT(dd_query);
85      if (dd_query) {
86         /* no special handling for batch queries yet */
87         dd_query->type = query_types[0];
88         dd_query->query = query;
89         query = (struct pipe_query *)dd_query;
90      } else {
91         pipe->destroy_query(pipe, query);
92         query = NULL;
93      }
94   }
95
96   return query;
97}
98
99static void
100dd_context_destroy_query(struct pipe_context *_pipe,
101                         struct pipe_query *query)
102{
103   struct pipe_context *pipe = dd_context(_pipe)->pipe;
104
105   pipe->destroy_query(pipe, dd_query_unwrap(query));
106   FREE(query);
107}
108
109static bool
110dd_context_begin_query(struct pipe_context *_pipe, struct pipe_query *query)
111{
112   struct dd_context *dctx = dd_context(_pipe);
113   struct pipe_context *pipe = dctx->pipe;
114
115   return pipe->begin_query(pipe, dd_query_unwrap(query));
116}
117
118static bool
119dd_context_end_query(struct pipe_context *_pipe, struct pipe_query *query)
120{
121   struct dd_context *dctx = dd_context(_pipe);
122   struct pipe_context *pipe = dctx->pipe;
123
124   return pipe->end_query(pipe, dd_query_unwrap(query));
125}
126
127static bool
128dd_context_get_query_result(struct pipe_context *_pipe,
129                            struct pipe_query *query, bool wait,
130                            union pipe_query_result *result)
131{
132   struct pipe_context *pipe = dd_context(_pipe)->pipe;
133
134   return pipe->get_query_result(pipe, dd_query_unwrap(query), wait, result);
135}
136
137static void
138dd_context_set_active_query_state(struct pipe_context *_pipe, bool enable)
139{
140   struct pipe_context *pipe = dd_context(_pipe)->pipe;
141
142   pipe->set_active_query_state(pipe, enable);
143}
144
145static void
146dd_context_render_condition(struct pipe_context *_pipe,
147                            struct pipe_query *query, bool condition,
148                            enum pipe_render_cond_flag mode)
149{
150   struct dd_context *dctx = dd_context(_pipe);
151   struct pipe_context *pipe = dctx->pipe;
152   struct dd_draw_state *dstate = &dctx->draw_state;
153
154   pipe->render_condition(pipe, dd_query_unwrap(query), condition, mode);
155   dstate->render_cond.query = dd_query(query);
156   dstate->render_cond.condition = condition;
157   dstate->render_cond.mode = mode;
158}
159
160
161/********************************************************************
162 * constant (immutable) non-shader states
163 */
164
165#define DD_CSO_CREATE(name, shortname) \
166   static void * \
167   dd_context_create_##name##_state(struct pipe_context *_pipe, \
168                                    const struct pipe_##name##_state *state) \
169   { \
170      struct pipe_context *pipe = dd_context(_pipe)->pipe; \
171      struct dd_state *hstate = CALLOC_STRUCT(dd_state); \
172 \
173      if (!hstate) \
174         return NULL; \
175      hstate->cso = pipe->create_##name##_state(pipe, state); \
176      hstate->state.shortname = *state; \
177      return hstate; \
178   }
179
180#define DD_CSO_BIND(name, shortname) \
181   static void \
182   dd_context_bind_##name##_state(struct pipe_context *_pipe, void *state) \
183   { \
184      struct dd_context *dctx = dd_context(_pipe); \
185      struct pipe_context *pipe = dctx->pipe; \
186      struct dd_state *hstate = state; \
187 \
188      dctx->draw_state.shortname = hstate; \
189      pipe->bind_##name##_state(pipe, hstate ? hstate->cso : NULL); \
190   }
191
192#define DD_CSO_DELETE(name) \
193   static void \
194   dd_context_delete_##name##_state(struct pipe_context *_pipe, void *state) \
195   { \
196      struct dd_context *dctx = dd_context(_pipe); \
197      struct pipe_context *pipe = dctx->pipe; \
198      struct dd_state *hstate = state; \
199 \
200      pipe->delete_##name##_state(pipe, hstate->cso); \
201      FREE(hstate); \
202   }
203
204#define DD_CSO_WHOLE(name, shortname) \
205   DD_CSO_CREATE(name, shortname) \
206   DD_CSO_BIND(name, shortname) \
207   DD_CSO_DELETE(name)
208
209DD_CSO_WHOLE(blend, blend)
210DD_CSO_WHOLE(rasterizer, rs)
211DD_CSO_WHOLE(depth_stencil_alpha, dsa)
212
213DD_CSO_CREATE(sampler, sampler)
214DD_CSO_DELETE(sampler)
215
216static void
217dd_context_bind_sampler_states(struct pipe_context *_pipe,
218                               enum pipe_shader_type shader,
219                               unsigned start, unsigned count, void **states)
220{
221   struct dd_context *dctx = dd_context(_pipe);
222   struct pipe_context *pipe = dctx->pipe;
223
224   memcpy(&dctx->draw_state.sampler_states[shader][start], states,
225          sizeof(void*) * count);
226
227   if (states) {
228      void *samp[PIPE_MAX_SAMPLERS];
229      int i;
230
231      for (i = 0; i < count; i++) {
232         struct dd_state *s = states[i];
233         samp[i] = s ? s->cso : NULL;
234      }
235
236      pipe->bind_sampler_states(pipe, shader, start, count, samp);
237   }
238   else
239      pipe->bind_sampler_states(pipe, shader, start, count, NULL);
240}
241
242static void *
243dd_context_create_vertex_elements_state(struct pipe_context *_pipe,
244                                        unsigned num_elems,
245                                        const struct pipe_vertex_element *elems)
246{
247   struct pipe_context *pipe = dd_context(_pipe)->pipe;
248   struct dd_state *hstate = CALLOC_STRUCT(dd_state);
249
250   if (!hstate)
251      return NULL;
252   hstate->cso = pipe->create_vertex_elements_state(pipe, num_elems, elems);
253   memcpy(hstate->state.velems.velems, elems, sizeof(elems[0]) * num_elems);
254   hstate->state.velems.count = num_elems;
255   return hstate;
256}
257
258DD_CSO_BIND(vertex_elements, velems)
259DD_CSO_DELETE(vertex_elements)
260
261
262/********************************************************************
263 * shaders
264 */
265
266#define DD_SHADER_NOCREATE(NAME, name) \
267   static void \
268   dd_context_bind_##name##_state(struct pipe_context *_pipe, void *state) \
269   { \
270      struct dd_context *dctx = dd_context(_pipe); \
271      struct pipe_context *pipe = dctx->pipe; \
272      struct dd_state *hstate = state; \
273   \
274      dctx->draw_state.shaders[PIPE_SHADER_##NAME] = hstate; \
275      pipe->bind_##name##_state(pipe, hstate ? hstate->cso : NULL); \
276   } \
277    \
278   static void \
279   dd_context_delete_##name##_state(struct pipe_context *_pipe, void *state) \
280   { \
281      struct dd_context *dctx = dd_context(_pipe); \
282      struct pipe_context *pipe = dctx->pipe; \
283      struct dd_state *hstate = state; \
284   \
285      pipe->delete_##name##_state(pipe, hstate->cso); \
286      if (hstate->state.shader.type == PIPE_SHADER_IR_TGSI) \
287         tgsi_free_tokens(hstate->state.shader.tokens); \
288      FREE(hstate); \
289   }
290
291#define DD_SHADER(NAME, name) \
292   static void * \
293   dd_context_create_##name##_state(struct pipe_context *_pipe, \
294                                    const struct pipe_shader_state *state) \
295   { \
296      struct pipe_context *pipe = dd_context(_pipe)->pipe; \
297      struct dd_state *hstate = CALLOC_STRUCT(dd_state); \
298 \
299      if (!hstate) \
300         return NULL; \
301      hstate->cso = pipe->create_##name##_state(pipe, state); \
302      hstate->state.shader = *state; \
303      if (hstate->state.shader.type == PIPE_SHADER_IR_TGSI) \
304         hstate->state.shader.tokens = tgsi_dup_tokens(state->tokens); \
305      return hstate; \
306   } \
307    \
308   DD_SHADER_NOCREATE(NAME, name)
309
310DD_SHADER(FRAGMENT, fs)
311DD_SHADER(VERTEX, vs)
312DD_SHADER(GEOMETRY, gs)
313DD_SHADER(TESS_CTRL, tcs)
314DD_SHADER(TESS_EVAL, tes)
315
316static void * \
317dd_context_create_compute_state(struct pipe_context *_pipe,
318                                 const struct pipe_compute_state *state)
319{
320   struct pipe_context *pipe = dd_context(_pipe)->pipe;
321   struct dd_state *hstate = CALLOC_STRUCT(dd_state);
322
323   if (!hstate)
324      return NULL;
325   hstate->cso = pipe->create_compute_state(pipe, state);
326
327   hstate->state.shader.type = state->ir_type;
328
329   if (state->ir_type == PIPE_SHADER_IR_TGSI)
330      hstate->state.shader.tokens = tgsi_dup_tokens(state->prog);
331
332   return hstate;
333}
334
335DD_SHADER_NOCREATE(COMPUTE, compute)
336
337/********************************************************************
338 * immediate states
339 */
340
341#define DD_IMM_STATE(name, type, deref, ref) \
342   static void \
343   dd_context_set_##name(struct pipe_context *_pipe, type deref) \
344   { \
345      struct dd_context *dctx = dd_context(_pipe); \
346      struct pipe_context *pipe = dctx->pipe; \
347 \
348      dctx->draw_state.name = deref; \
349      pipe->set_##name(pipe, ref); \
350   }
351
352DD_IMM_STATE(blend_color, const struct pipe_blend_color, *state, state)
353DD_IMM_STATE(stencil_ref, const struct pipe_stencil_ref, state, state)
354DD_IMM_STATE(clip_state, const struct pipe_clip_state, *state, state)
355DD_IMM_STATE(sample_mask, unsigned, sample_mask, sample_mask)
356DD_IMM_STATE(min_samples, unsigned, min_samples, min_samples)
357DD_IMM_STATE(framebuffer_state, const struct pipe_framebuffer_state, *state, state)
358DD_IMM_STATE(polygon_stipple, const struct pipe_poly_stipple, *state, state)
359
360static void
361dd_context_set_constant_buffer(struct pipe_context *_pipe,
362                               enum pipe_shader_type shader, uint index,
363                               bool take_ownership,
364                               const struct pipe_constant_buffer *constant_buffer)
365{
366   struct dd_context *dctx = dd_context(_pipe);
367   struct pipe_context *pipe = dctx->pipe;
368
369   safe_memcpy(&dctx->draw_state.constant_buffers[shader][index],
370               constant_buffer, sizeof(*constant_buffer));
371   pipe->set_constant_buffer(pipe, shader, index, take_ownership, constant_buffer);
372}
373
374static void
375dd_context_set_scissor_states(struct pipe_context *_pipe,
376                              unsigned start_slot, unsigned num_scissors,
377                              const struct pipe_scissor_state *states)
378{
379   struct dd_context *dctx = dd_context(_pipe);
380   struct pipe_context *pipe = dctx->pipe;
381
382   safe_memcpy(&dctx->draw_state.scissors[start_slot], states,
383               sizeof(*states) * num_scissors);
384   pipe->set_scissor_states(pipe, start_slot, num_scissors, states);
385}
386
387static void
388dd_context_set_viewport_states(struct pipe_context *_pipe,
389                               unsigned start_slot, unsigned num_viewports,
390                               const struct pipe_viewport_state *states)
391{
392   struct dd_context *dctx = dd_context(_pipe);
393   struct pipe_context *pipe = dctx->pipe;
394
395   safe_memcpy(&dctx->draw_state.viewports[start_slot], states,
396               sizeof(*states) * num_viewports);
397   pipe->set_viewport_states(pipe, start_slot, num_viewports, states);
398}
399
400static void dd_context_set_tess_state(struct pipe_context *_pipe,
401                                      const float default_outer_level[4],
402                                      const float default_inner_level[2])
403{
404   struct dd_context *dctx = dd_context(_pipe);
405   struct pipe_context *pipe = dctx->pipe;
406
407   memcpy(dctx->draw_state.tess_default_levels, default_outer_level,
408          sizeof(float) * 4);
409   memcpy(dctx->draw_state.tess_default_levels+4, default_inner_level,
410          sizeof(float) * 2);
411   pipe->set_tess_state(pipe, default_outer_level, default_inner_level);
412}
413
414static void dd_context_set_patch_vertices(struct pipe_context *_pipe,
415                                          uint8_t patch_vertices)
416{
417   struct dd_context *dctx = dd_context(_pipe);
418   struct pipe_context *pipe = dctx->pipe;
419
420   pipe->set_patch_vertices(pipe, patch_vertices);
421}
422
423static void dd_context_set_window_rectangles(struct pipe_context *_pipe,
424                                             bool include,
425                                             unsigned num_rectangles,
426                                             const struct pipe_scissor_state *rects)
427{
428   struct dd_context *dctx = dd_context(_pipe);
429   struct pipe_context *pipe = dctx->pipe;
430
431   pipe->set_window_rectangles(pipe, include, num_rectangles, rects);
432}
433
434
435/********************************************************************
436 * views
437 */
438
439static struct pipe_surface *
440dd_context_create_surface(struct pipe_context *_pipe,
441                          struct pipe_resource *resource,
442                          const struct pipe_surface *surf_tmpl)
443{
444   struct pipe_context *pipe = dd_context(_pipe)->pipe;
445   struct pipe_surface *view =
446      pipe->create_surface(pipe, resource, surf_tmpl);
447
448   if (!view)
449      return NULL;
450   view->context = _pipe;
451   return view;
452}
453
454static void
455dd_context_surface_destroy(struct pipe_context *_pipe,
456                           struct pipe_surface *surf)
457{
458   struct pipe_context *pipe = dd_context(_pipe)->pipe;
459
460   pipe->surface_destroy(pipe, surf);
461}
462
463static struct pipe_sampler_view *
464dd_context_create_sampler_view(struct pipe_context *_pipe,
465                               struct pipe_resource *resource,
466                               const struct pipe_sampler_view *templ)
467{
468   struct pipe_context *pipe = dd_context(_pipe)->pipe;
469   struct pipe_sampler_view *view =
470      pipe->create_sampler_view(pipe, resource, templ);
471
472   if (!view)
473      return NULL;
474   view->context = _pipe;
475   return view;
476}
477
478static void
479dd_context_sampler_view_destroy(struct pipe_context *_pipe,
480                                struct pipe_sampler_view *view)
481{
482   struct pipe_context *pipe = dd_context(_pipe)->pipe;
483
484   pipe->sampler_view_destroy(pipe, view);
485}
486
487static struct pipe_stream_output_target *
488dd_context_create_stream_output_target(struct pipe_context *_pipe,
489                                       struct pipe_resource *res,
490                                       unsigned buffer_offset,
491                                       unsigned buffer_size)
492{
493   struct pipe_context *pipe = dd_context(_pipe)->pipe;
494   struct pipe_stream_output_target *view =
495      pipe->create_stream_output_target(pipe, res, buffer_offset,
496                                        buffer_size);
497
498   if (!view)
499      return NULL;
500   view->context = _pipe;
501   return view;
502}
503
504static void
505dd_context_stream_output_target_destroy(struct pipe_context *_pipe,
506                                        struct pipe_stream_output_target *target)
507{
508   struct pipe_context *pipe = dd_context(_pipe)->pipe;
509
510   pipe->stream_output_target_destroy(pipe, target);
511}
512
513
514/********************************************************************
515 * set states
516 */
517
518static void
519dd_context_set_sampler_views(struct pipe_context *_pipe,
520                             enum pipe_shader_type shader,
521                             unsigned start, unsigned num,
522                             unsigned unbind_num_trailing_slots,
523                             bool take_ownership,
524                             struct pipe_sampler_view **views)
525{
526   struct dd_context *dctx = dd_context(_pipe);
527   struct pipe_context *pipe = dctx->pipe;
528
529   safe_memcpy(&dctx->draw_state.sampler_views[shader][start], views,
530               sizeof(views[0]) * num);
531   safe_memcpy(&dctx->draw_state.sampler_views[shader][start + num], views,
532               sizeof(views[0]) * unbind_num_trailing_slots);
533   pipe->set_sampler_views(pipe, shader, start, num, take_ownership,
534                           unbind_num_trailing_slots, views);
535}
536
537static void
538dd_context_set_shader_images(struct pipe_context *_pipe,
539                             enum pipe_shader_type shader,
540                             unsigned start, unsigned num,
541                             unsigned unbind_num_trailing_slots,
542                             const struct pipe_image_view *views)
543{
544   struct dd_context *dctx = dd_context(_pipe);
545   struct pipe_context *pipe = dctx->pipe;
546
547   safe_memcpy(&dctx->draw_state.shader_images[shader][start], views,
548               sizeof(views[0]) * num);
549   safe_memcpy(&dctx->draw_state.shader_images[shader][start + num], NULL,
550               sizeof(views[0]) * unbind_num_trailing_slots);
551   pipe->set_shader_images(pipe, shader, start, num,
552                           unbind_num_trailing_slots, views);
553}
554
555static void
556dd_context_set_shader_buffers(struct pipe_context *_pipe,
557                              enum pipe_shader_type shader,
558                              unsigned start, unsigned num_buffers,
559                              const struct pipe_shader_buffer *buffers,
560                              unsigned writable_bitmask)
561{
562   struct dd_context *dctx = dd_context(_pipe);
563   struct pipe_context *pipe = dctx->pipe;
564
565   safe_memcpy(&dctx->draw_state.shader_buffers[shader][start], buffers,
566               sizeof(buffers[0]) * num_buffers);
567   pipe->set_shader_buffers(pipe, shader, start, num_buffers, buffers,
568                            writable_bitmask);
569}
570
571static void
572dd_context_set_vertex_buffers(struct pipe_context *_pipe,
573                              unsigned start, unsigned num_buffers,
574                              unsigned unbind_num_trailing_slots,
575                              bool take_ownership,
576                              const struct pipe_vertex_buffer *buffers)
577{
578   struct dd_context *dctx = dd_context(_pipe);
579   struct pipe_context *pipe = dctx->pipe;
580
581   safe_memcpy(&dctx->draw_state.vertex_buffers[start], buffers,
582               sizeof(buffers[0]) * num_buffers);
583   safe_memcpy(&dctx->draw_state.vertex_buffers[start + num_buffers], NULL,
584               sizeof(buffers[0]) * unbind_num_trailing_slots);
585   pipe->set_vertex_buffers(pipe, start, num_buffers,
586                            unbind_num_trailing_slots, take_ownership,
587                            buffers);
588}
589
590static void
591dd_context_set_stream_output_targets(struct pipe_context *_pipe,
592                                     unsigned num_targets,
593                                     struct pipe_stream_output_target **tgs,
594                                     const unsigned *offsets)
595{
596   struct dd_context *dctx = dd_context(_pipe);
597   struct pipe_context *pipe = dctx->pipe;
598   struct dd_draw_state *dstate = &dctx->draw_state;
599
600   dstate->num_so_targets = num_targets;
601   safe_memcpy(dstate->so_targets, tgs, sizeof(*tgs) * num_targets);
602   safe_memcpy(dstate->so_offsets, offsets, sizeof(*offsets) * num_targets);
603   pipe->set_stream_output_targets(pipe, num_targets, tgs, offsets);
604}
605
606
607static void
608dd_context_fence_server_sync(struct pipe_context *_pipe,
609                             struct pipe_fence_handle *fence)
610{
611   struct dd_context *dctx = dd_context(_pipe);
612   struct pipe_context *pipe = dctx->pipe;
613
614   pipe->fence_server_sync(pipe, fence);
615}
616
617
618static void
619dd_context_create_fence_fd(struct pipe_context *_pipe,
620                           struct pipe_fence_handle **fence,
621                           int fd,
622                           enum pipe_fd_type type)
623{
624   struct dd_context *dctx = dd_context(_pipe);
625   struct pipe_context *pipe = dctx->pipe;
626
627   pipe->create_fence_fd(pipe, fence, fd, type);
628}
629
630
631void
632dd_thread_join(struct dd_context *dctx)
633{
634   mtx_lock(&dctx->mutex);
635   dctx->kill_thread = true;
636   cnd_signal(&dctx->cond);
637   mtx_unlock(&dctx->mutex);
638   thrd_join(dctx->thread, NULL);
639}
640
641static void
642dd_context_destroy(struct pipe_context *_pipe)
643{
644   struct dd_context *dctx = dd_context(_pipe);
645   struct pipe_context *pipe = dctx->pipe;
646
647   dd_thread_join(dctx);
648   mtx_destroy(&dctx->mutex);
649   cnd_destroy(&dctx->cond);
650
651   assert(list_is_empty(&dctx->records));
652
653   if (pipe->set_log_context) {
654      pipe->set_log_context(pipe, NULL);
655
656      if (dd_screen(dctx->base.screen)->dump_mode == DD_DUMP_ALL_CALLS) {
657         FILE *f = dd_get_file_stream(dd_screen(dctx->base.screen), 0);
658         if (f) {
659            fprintf(f, "Remainder of driver log:\n\n");
660         }
661
662         u_log_new_page_print(&dctx->log, f);
663         fclose(f);
664      }
665   }
666   u_log_context_destroy(&dctx->log);
667
668   pipe->destroy(pipe);
669   FREE(dctx);
670}
671
672
673/********************************************************************
674 * miscellaneous
675 */
676
677static void
678dd_context_texture_barrier(struct pipe_context *_pipe, unsigned flags)
679{
680   struct pipe_context *pipe = dd_context(_pipe)->pipe;
681
682   pipe->texture_barrier(pipe, flags);
683}
684
685static void
686dd_context_memory_barrier(struct pipe_context *_pipe, unsigned flags)
687{
688   struct pipe_context *pipe = dd_context(_pipe)->pipe;
689
690   pipe->memory_barrier(pipe, flags);
691}
692
693static bool
694dd_context_resource_commit(struct pipe_context *_pipe,
695                           struct pipe_resource *resource,
696                           unsigned level, struct pipe_box *box, bool commit)
697{
698   struct pipe_context *pipe = dd_context(_pipe)->pipe;
699
700   return pipe->resource_commit(pipe, resource, level, box, commit);
701}
702
703static void
704dd_context_set_compute_resources(struct pipe_context *_pipe,
705				 unsigned start, unsigned count,
706				 struct pipe_surface **resources)
707{
708   struct pipe_context *pipe = dd_context(_pipe)->pipe;
709   pipe->set_compute_resources(pipe, start, count, resources);
710}
711
712static void
713dd_context_set_global_binding(struct pipe_context *_pipe,
714			      unsigned first, unsigned count,
715			      struct pipe_resource **resources,
716			      uint32_t **handles)
717{
718   struct pipe_context *pipe = dd_context(_pipe)->pipe;
719   pipe->set_global_binding(pipe, first, count, resources, handles);
720}
721
722static void
723dd_context_get_sample_position(struct pipe_context *_pipe,
724                               unsigned sample_count, unsigned sample_index,
725                               float *out_value)
726{
727   struct pipe_context *pipe = dd_context(_pipe)->pipe;
728
729   pipe->get_sample_position(pipe, sample_count, sample_index,
730                             out_value);
731}
732
733static void
734dd_context_invalidate_resource(struct pipe_context *_pipe,
735                               struct pipe_resource *resource)
736{
737   struct pipe_context *pipe = dd_context(_pipe)->pipe;
738
739   pipe->invalidate_resource(pipe, resource);
740}
741
742static enum pipe_reset_status
743dd_context_get_device_reset_status(struct pipe_context *_pipe)
744{
745   struct pipe_context *pipe = dd_context(_pipe)->pipe;
746
747   return pipe->get_device_reset_status(pipe);
748}
749
750static void
751dd_context_set_device_reset_callback(struct pipe_context *_pipe,
752                                     const struct pipe_device_reset_callback *cb)
753{
754   struct pipe_context *pipe = dd_context(_pipe)->pipe;
755
756   pipe->set_device_reset_callback(pipe, cb);
757}
758
759static void
760dd_context_emit_string_marker(struct pipe_context *_pipe,
761                              const char *string, int len)
762{
763   struct dd_context *dctx = dd_context(_pipe);
764   struct pipe_context *pipe = dctx->pipe;
765
766   pipe->emit_string_marker(pipe, string, len);
767   dd_parse_apitrace_marker(string, len, &dctx->draw_state.apitrace_call_number);
768}
769
770static void
771dd_context_dump_debug_state(struct pipe_context *_pipe, FILE *stream,
772                            unsigned flags)
773{
774   struct pipe_context *pipe = dd_context(_pipe)->pipe;
775
776   pipe->dump_debug_state(pipe, stream, flags);
777}
778
779static uint64_t
780dd_context_create_texture_handle(struct pipe_context *_pipe,
781                                 struct pipe_sampler_view *view,
782                                 const struct pipe_sampler_state *state)
783{
784   struct pipe_context *pipe = dd_context(_pipe)->pipe;
785
786   return pipe->create_texture_handle(pipe, view, state);
787}
788
789static void
790dd_context_delete_texture_handle(struct pipe_context *_pipe, uint64_t handle)
791{
792   struct pipe_context *pipe = dd_context(_pipe)->pipe;
793
794   pipe->delete_texture_handle(pipe, handle);
795}
796
797static void
798dd_context_make_texture_handle_resident(struct pipe_context *_pipe,
799                                        uint64_t handle, bool resident)
800{
801   struct pipe_context *pipe = dd_context(_pipe)->pipe;
802
803   pipe->make_texture_handle_resident(pipe, handle, resident);
804}
805
806static uint64_t
807dd_context_create_image_handle(struct pipe_context *_pipe,
808                               const struct pipe_image_view *image)
809{
810   struct pipe_context *pipe = dd_context(_pipe)->pipe;
811
812   return pipe->create_image_handle(pipe, image);
813}
814
815static void
816dd_context_delete_image_handle(struct pipe_context *_pipe, uint64_t handle)
817{
818   struct pipe_context *pipe = dd_context(_pipe)->pipe;
819
820   pipe->delete_image_handle(pipe, handle);
821}
822
823static void
824dd_context_make_image_handle_resident(struct pipe_context *_pipe,
825                                      uint64_t handle, unsigned access,
826                                      bool resident)
827{
828   struct pipe_context *pipe = dd_context(_pipe)->pipe;
829
830   pipe->make_image_handle_resident(pipe, handle, access, resident);
831}
832
833static void
834dd_context_set_context_param(struct pipe_context *_pipe,
835                             enum pipe_context_param param,
836                             unsigned value)
837{
838   struct pipe_context *pipe = dd_context(_pipe)->pipe;
839
840   pipe->set_context_param(pipe, param, value);
841}
842
843struct pipe_context *
844dd_context_create(struct dd_screen *dscreen, struct pipe_context *pipe)
845{
846   struct dd_context *dctx;
847
848   if (!pipe)
849      return NULL;
850
851   dctx = CALLOC_STRUCT(dd_context);
852   if (!dctx)
853      goto fail;
854
855   dctx->pipe = pipe;
856   dctx->base.priv = pipe->priv; /* expose wrapped priv data */
857   dctx->base.screen = &dscreen->base;
858   dctx->base.stream_uploader = pipe->stream_uploader;
859   dctx->base.const_uploader = pipe->const_uploader;
860
861   dctx->base.destroy = dd_context_destroy;
862
863   CTX_INIT(render_condition);
864   CTX_INIT(create_query);
865   CTX_INIT(create_batch_query);
866   CTX_INIT(destroy_query);
867   CTX_INIT(begin_query);
868   CTX_INIT(end_query);
869   CTX_INIT(get_query_result);
870   CTX_INIT(set_active_query_state);
871   CTX_INIT(create_blend_state);
872   CTX_INIT(bind_blend_state);
873   CTX_INIT(delete_blend_state);
874   CTX_INIT(create_sampler_state);
875   CTX_INIT(bind_sampler_states);
876   CTX_INIT(delete_sampler_state);
877   CTX_INIT(create_rasterizer_state);
878   CTX_INIT(bind_rasterizer_state);
879   CTX_INIT(delete_rasterizer_state);
880   CTX_INIT(create_depth_stencil_alpha_state);
881   CTX_INIT(bind_depth_stencil_alpha_state);
882   CTX_INIT(delete_depth_stencil_alpha_state);
883   CTX_INIT(create_fs_state);
884   CTX_INIT(bind_fs_state);
885   CTX_INIT(delete_fs_state);
886   CTX_INIT(create_vs_state);
887   CTX_INIT(bind_vs_state);
888   CTX_INIT(delete_vs_state);
889   CTX_INIT(create_gs_state);
890   CTX_INIT(bind_gs_state);
891   CTX_INIT(delete_gs_state);
892   CTX_INIT(create_tcs_state);
893   CTX_INIT(bind_tcs_state);
894   CTX_INIT(delete_tcs_state);
895   CTX_INIT(create_tes_state);
896   CTX_INIT(bind_tes_state);
897   CTX_INIT(delete_tes_state);
898   CTX_INIT(create_compute_state);
899   CTX_INIT(bind_compute_state);
900   CTX_INIT(delete_compute_state);
901   CTX_INIT(create_vertex_elements_state);
902   CTX_INIT(bind_vertex_elements_state);
903   CTX_INIT(delete_vertex_elements_state);
904   CTX_INIT(set_blend_color);
905   CTX_INIT(set_stencil_ref);
906   CTX_INIT(set_sample_mask);
907   CTX_INIT(set_min_samples);
908   CTX_INIT(set_clip_state);
909   CTX_INIT(set_constant_buffer);
910   CTX_INIT(set_framebuffer_state);
911   CTX_INIT(set_polygon_stipple);
912   CTX_INIT(set_scissor_states);
913   CTX_INIT(set_viewport_states);
914   CTX_INIT(set_sampler_views);
915   CTX_INIT(set_tess_state);
916   CTX_INIT(set_patch_vertices);
917   CTX_INIT(set_shader_buffers);
918   CTX_INIT(set_shader_images);
919   CTX_INIT(set_vertex_buffers);
920   CTX_INIT(set_window_rectangles);
921   CTX_INIT(create_stream_output_target);
922   CTX_INIT(stream_output_target_destroy);
923   CTX_INIT(set_stream_output_targets);
924   CTX_INIT(create_fence_fd);
925   CTX_INIT(fence_server_sync);
926   CTX_INIT(create_sampler_view);
927   CTX_INIT(sampler_view_destroy);
928   CTX_INIT(create_surface);
929   CTX_INIT(surface_destroy);
930   CTX_INIT(texture_barrier);
931   CTX_INIT(memory_barrier);
932   CTX_INIT(resource_commit);
933   CTX_INIT(set_compute_resources);
934   CTX_INIT(set_global_binding);
935   /* create_video_codec */
936   /* create_video_buffer */
937   CTX_INIT(get_sample_position);
938   CTX_INIT(invalidate_resource);
939   CTX_INIT(get_device_reset_status);
940   CTX_INIT(set_device_reset_callback);
941   CTX_INIT(dump_debug_state);
942   CTX_INIT(emit_string_marker);
943   CTX_INIT(create_texture_handle);
944   CTX_INIT(delete_texture_handle);
945   CTX_INIT(make_texture_handle_resident);
946   CTX_INIT(create_image_handle);
947   CTX_INIT(delete_image_handle);
948   CTX_INIT(make_image_handle_resident);
949   CTX_INIT(set_context_param);
950
951   dd_init_draw_functions(dctx);
952
953   u_log_context_init(&dctx->log);
954   if (pipe->set_log_context)
955      pipe->set_log_context(pipe, &dctx->log);
956
957   dctx->draw_state.sample_mask = ~0;
958
959   list_inithead(&dctx->records);
960   (void) mtx_init(&dctx->mutex, mtx_plain);
961   (void) cnd_init(&dctx->cond);
962   if (thrd_success != u_thread_create(&dctx->thread,dd_thread_main, dctx)) {
963      mtx_destroy(&dctx->mutex);
964      goto fail;
965   }
966
967   return &dctx->base;
968
969fail:
970   FREE(dctx);
971   pipe->destroy(pipe);
972   return NULL;
973}
974