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 boolean
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 boolean
128dd_context_get_query_result(struct pipe_context *_pipe,
129                            struct pipe_query *query, boolean 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, boolean 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, boolean 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                               const struct pipe_constant_buffer *constant_buffer)
364{
365   struct dd_context *dctx = dd_context(_pipe);
366   struct pipe_context *pipe = dctx->pipe;
367
368   safe_memcpy(&dctx->draw_state.constant_buffers[shader][index],
369               constant_buffer, sizeof(*constant_buffer));
370   pipe->set_constant_buffer(pipe, shader, index, constant_buffer);
371}
372
373static void
374dd_context_set_scissor_states(struct pipe_context *_pipe,
375                              unsigned start_slot, unsigned num_scissors,
376                              const struct pipe_scissor_state *states)
377{
378   struct dd_context *dctx = dd_context(_pipe);
379   struct pipe_context *pipe = dctx->pipe;
380
381   safe_memcpy(&dctx->draw_state.scissors[start_slot], states,
382               sizeof(*states) * num_scissors);
383   pipe->set_scissor_states(pipe, start_slot, num_scissors, states);
384}
385
386static void
387dd_context_set_viewport_states(struct pipe_context *_pipe,
388                               unsigned start_slot, unsigned num_viewports,
389                               const struct pipe_viewport_state *states)
390{
391   struct dd_context *dctx = dd_context(_pipe);
392   struct pipe_context *pipe = dctx->pipe;
393
394   safe_memcpy(&dctx->draw_state.viewports[start_slot], states,
395               sizeof(*states) * num_viewports);
396   pipe->set_viewport_states(pipe, start_slot, num_viewports, states);
397}
398
399static void dd_context_set_tess_state(struct pipe_context *_pipe,
400                                      const float default_outer_level[4],
401                                      const float default_inner_level[2])
402{
403   struct dd_context *dctx = dd_context(_pipe);
404   struct pipe_context *pipe = dctx->pipe;
405
406   memcpy(dctx->draw_state.tess_default_levels, default_outer_level,
407          sizeof(float) * 4);
408   memcpy(dctx->draw_state.tess_default_levels+4, default_inner_level,
409          sizeof(float) * 2);
410   pipe->set_tess_state(pipe, default_outer_level, default_inner_level);
411}
412
413static void dd_context_set_window_rectangles(struct pipe_context *_pipe,
414                                             boolean include,
415                                             unsigned num_rectangles,
416                                             const struct pipe_scissor_state *rects)
417{
418   struct dd_context *dctx = dd_context(_pipe);
419   struct pipe_context *pipe = dctx->pipe;
420
421   pipe->set_window_rectangles(pipe, include, num_rectangles, rects);
422}
423
424
425/********************************************************************
426 * views
427 */
428
429static struct pipe_surface *
430dd_context_create_surface(struct pipe_context *_pipe,
431                          struct pipe_resource *resource,
432                          const struct pipe_surface *surf_tmpl)
433{
434   struct pipe_context *pipe = dd_context(_pipe)->pipe;
435   struct pipe_surface *view =
436      pipe->create_surface(pipe, resource, surf_tmpl);
437
438   if (!view)
439      return NULL;
440   view->context = _pipe;
441   return view;
442}
443
444static void
445dd_context_surface_destroy(struct pipe_context *_pipe,
446                           struct pipe_surface *surf)
447{
448   struct pipe_context *pipe = dd_context(_pipe)->pipe;
449
450   pipe->surface_destroy(pipe, surf);
451}
452
453static struct pipe_sampler_view *
454dd_context_create_sampler_view(struct pipe_context *_pipe,
455                               struct pipe_resource *resource,
456                               const struct pipe_sampler_view *templ)
457{
458   struct pipe_context *pipe = dd_context(_pipe)->pipe;
459   struct pipe_sampler_view *view =
460      pipe->create_sampler_view(pipe, resource, templ);
461
462   if (!view)
463      return NULL;
464   view->context = _pipe;
465   return view;
466}
467
468static void
469dd_context_sampler_view_destroy(struct pipe_context *_pipe,
470                                struct pipe_sampler_view *view)
471{
472   struct pipe_context *pipe = dd_context(_pipe)->pipe;
473
474   pipe->sampler_view_destroy(pipe, view);
475}
476
477static struct pipe_stream_output_target *
478dd_context_create_stream_output_target(struct pipe_context *_pipe,
479                                       struct pipe_resource *res,
480                                       unsigned buffer_offset,
481                                       unsigned buffer_size)
482{
483   struct pipe_context *pipe = dd_context(_pipe)->pipe;
484   struct pipe_stream_output_target *view =
485      pipe->create_stream_output_target(pipe, res, buffer_offset,
486                                        buffer_size);
487
488   if (!view)
489      return NULL;
490   view->context = _pipe;
491   return view;
492}
493
494static void
495dd_context_stream_output_target_destroy(struct pipe_context *_pipe,
496                                        struct pipe_stream_output_target *target)
497{
498   struct pipe_context *pipe = dd_context(_pipe)->pipe;
499
500   pipe->stream_output_target_destroy(pipe, target);
501}
502
503
504/********************************************************************
505 * set states
506 */
507
508static void
509dd_context_set_sampler_views(struct pipe_context *_pipe,
510                             enum pipe_shader_type shader,
511                             unsigned start, unsigned num,
512                             struct pipe_sampler_view **views)
513{
514   struct dd_context *dctx = dd_context(_pipe);
515   struct pipe_context *pipe = dctx->pipe;
516
517   safe_memcpy(&dctx->draw_state.sampler_views[shader][start], views,
518               sizeof(views[0]) * num);
519   pipe->set_sampler_views(pipe, shader, start, num, views);
520}
521
522static void
523dd_context_set_shader_images(struct pipe_context *_pipe,
524                             enum pipe_shader_type shader,
525                             unsigned start, unsigned num,
526                             const struct pipe_image_view *views)
527{
528   struct dd_context *dctx = dd_context(_pipe);
529   struct pipe_context *pipe = dctx->pipe;
530
531   safe_memcpy(&dctx->draw_state.shader_images[shader][start], views,
532               sizeof(views[0]) * num);
533   pipe->set_shader_images(pipe, shader, start, num, views);
534}
535
536static void
537dd_context_set_shader_buffers(struct pipe_context *_pipe, unsigned shader,
538                              unsigned start, unsigned num_buffers,
539                              const struct pipe_shader_buffer *buffers,
540                              unsigned writable_bitmask)
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                            writable_bitmask);
549}
550
551static void
552dd_context_set_vertex_buffers(struct pipe_context *_pipe,
553                              unsigned start, unsigned num_buffers,
554                              const struct pipe_vertex_buffer *buffers)
555{
556   struct dd_context *dctx = dd_context(_pipe);
557   struct pipe_context *pipe = dctx->pipe;
558
559   safe_memcpy(&dctx->draw_state.vertex_buffers[start], buffers,
560               sizeof(buffers[0]) * num_buffers);
561   pipe->set_vertex_buffers(pipe, start, num_buffers, buffers);
562}
563
564static void
565dd_context_set_stream_output_targets(struct pipe_context *_pipe,
566                                     unsigned num_targets,
567                                     struct pipe_stream_output_target **tgs,
568                                     const unsigned *offsets)
569{
570   struct dd_context *dctx = dd_context(_pipe);
571   struct pipe_context *pipe = dctx->pipe;
572   struct dd_draw_state *dstate = &dctx->draw_state;
573
574   dstate->num_so_targets = num_targets;
575   safe_memcpy(dstate->so_targets, tgs, sizeof(*tgs) * num_targets);
576   safe_memcpy(dstate->so_offsets, offsets, sizeof(*offsets) * num_targets);
577   pipe->set_stream_output_targets(pipe, num_targets, tgs, offsets);
578}
579
580
581static void
582dd_context_fence_server_sync(struct pipe_context *_pipe,
583                             struct pipe_fence_handle *fence)
584{
585   struct dd_context *dctx = dd_context(_pipe);
586   struct pipe_context *pipe = dctx->pipe;
587
588   pipe->fence_server_sync(pipe, fence);
589}
590
591
592static void
593dd_context_create_fence_fd(struct pipe_context *_pipe,
594                           struct pipe_fence_handle **fence,
595                           int fd,
596                           enum pipe_fd_type type)
597{
598   struct dd_context *dctx = dd_context(_pipe);
599   struct pipe_context *pipe = dctx->pipe;
600
601   pipe->create_fence_fd(pipe, fence, fd, type);
602}
603
604
605void
606dd_thread_join(struct dd_context *dctx)
607{
608   mtx_lock(&dctx->mutex);
609   dctx->kill_thread = true;
610   cnd_signal(&dctx->cond);
611   mtx_unlock(&dctx->mutex);
612   thrd_join(dctx->thread, NULL);
613}
614
615static void
616dd_context_destroy(struct pipe_context *_pipe)
617{
618   struct dd_context *dctx = dd_context(_pipe);
619   struct pipe_context *pipe = dctx->pipe;
620
621   dd_thread_join(dctx);
622   mtx_destroy(&dctx->mutex);
623   cnd_destroy(&dctx->cond);
624
625   assert(list_empty(&dctx->records));
626
627   if (pipe->set_log_context) {
628      pipe->set_log_context(pipe, NULL);
629
630      if (dd_screen(dctx->base.screen)->dump_mode == DD_DUMP_ALL_CALLS) {
631         FILE *f = dd_get_file_stream(dd_screen(dctx->base.screen), 0);
632         if (f) {
633            fprintf(f, "Remainder of driver log:\n\n");
634         }
635
636         u_log_new_page_print(&dctx->log, f);
637         fclose(f);
638      }
639   }
640   u_log_context_destroy(&dctx->log);
641
642   pipe->destroy(pipe);
643   FREE(dctx);
644}
645
646
647/********************************************************************
648 * miscellaneous
649 */
650
651static void
652dd_context_texture_barrier(struct pipe_context *_pipe, unsigned flags)
653{
654   struct pipe_context *pipe = dd_context(_pipe)->pipe;
655
656   pipe->texture_barrier(pipe, flags);
657}
658
659static void
660dd_context_memory_barrier(struct pipe_context *_pipe, unsigned flags)
661{
662   struct pipe_context *pipe = dd_context(_pipe)->pipe;
663
664   pipe->memory_barrier(pipe, flags);
665}
666
667static bool
668dd_context_resource_commit(struct pipe_context *_pipe,
669                           struct pipe_resource *resource,
670                           unsigned level, struct pipe_box *box, bool commit)
671{
672   struct pipe_context *pipe = dd_context(_pipe)->pipe;
673
674   return pipe->resource_commit(pipe, resource, level, box, commit);
675}
676
677static void
678dd_context_set_compute_resources(struct pipe_context *_pipe,
679				 unsigned start, unsigned count,
680				 struct pipe_surface **resources)
681{
682   struct pipe_context *pipe = dd_context(_pipe)->pipe;
683   return pipe->set_compute_resources(pipe, start, count, resources);
684}
685
686static void
687dd_context_set_global_binding(struct pipe_context *_pipe,
688			      unsigned first, unsigned count,
689			      struct pipe_resource **resources,
690			      uint32_t **handles)
691{
692   struct pipe_context *pipe = dd_context(_pipe)->pipe;
693   return pipe->set_global_binding(pipe, first, count, resources, handles);
694}
695
696static void
697dd_context_get_sample_position(struct pipe_context *_pipe,
698                               unsigned sample_count, unsigned sample_index,
699                               float *out_value)
700{
701   struct pipe_context *pipe = dd_context(_pipe)->pipe;
702
703   return pipe->get_sample_position(pipe, sample_count, sample_index,
704                                    out_value);
705}
706
707static void
708dd_context_invalidate_resource(struct pipe_context *_pipe,
709                               struct pipe_resource *resource)
710{
711   struct pipe_context *pipe = dd_context(_pipe)->pipe;
712
713   pipe->invalidate_resource(pipe, resource);
714}
715
716static enum pipe_reset_status
717dd_context_get_device_reset_status(struct pipe_context *_pipe)
718{
719   struct pipe_context *pipe = dd_context(_pipe)->pipe;
720
721   return pipe->get_device_reset_status(pipe);
722}
723
724static void
725dd_context_set_device_reset_callback(struct pipe_context *_pipe,
726                                     const struct pipe_device_reset_callback *cb)
727{
728   struct pipe_context *pipe = dd_context(_pipe)->pipe;
729
730   return pipe->set_device_reset_callback(pipe, cb);
731}
732
733static void
734dd_context_emit_string_marker(struct pipe_context *_pipe,
735                              const char *string, int len)
736{
737   struct dd_context *dctx = dd_context(_pipe);
738   struct pipe_context *pipe = dctx->pipe;
739
740   pipe->emit_string_marker(pipe, string, len);
741   dd_parse_apitrace_marker(string, len, &dctx->draw_state.apitrace_call_number);
742}
743
744static void
745dd_context_dump_debug_state(struct pipe_context *_pipe, FILE *stream,
746                            unsigned flags)
747{
748   struct pipe_context *pipe = dd_context(_pipe)->pipe;
749
750   return pipe->dump_debug_state(pipe, stream, flags);
751}
752
753static uint64_t
754dd_context_create_texture_handle(struct pipe_context *_pipe,
755                                 struct pipe_sampler_view *view,
756                                 const struct pipe_sampler_state *state)
757{
758   struct pipe_context *pipe = dd_context(_pipe)->pipe;
759
760   return pipe->create_texture_handle(pipe, view, state);
761}
762
763static void
764dd_context_delete_texture_handle(struct pipe_context *_pipe, uint64_t handle)
765{
766   struct pipe_context *pipe = dd_context(_pipe)->pipe;
767
768   pipe->delete_texture_handle(pipe, handle);
769}
770
771static void
772dd_context_make_texture_handle_resident(struct pipe_context *_pipe,
773                                        uint64_t handle, bool resident)
774{
775   struct pipe_context *pipe = dd_context(_pipe)->pipe;
776
777   pipe->make_texture_handle_resident(pipe, handle, resident);
778}
779
780static uint64_t
781dd_context_create_image_handle(struct pipe_context *_pipe,
782                               const struct pipe_image_view *image)
783{
784   struct pipe_context *pipe = dd_context(_pipe)->pipe;
785
786   return pipe->create_image_handle(pipe, image);
787}
788
789static void
790dd_context_delete_image_handle(struct pipe_context *_pipe, uint64_t handle)
791{
792   struct pipe_context *pipe = dd_context(_pipe)->pipe;
793
794   pipe->delete_image_handle(pipe, handle);
795}
796
797static void
798dd_context_make_image_handle_resident(struct pipe_context *_pipe,
799                                      uint64_t handle, unsigned access,
800                                      bool resident)
801{
802   struct pipe_context *pipe = dd_context(_pipe)->pipe;
803
804   pipe->make_image_handle_resident(pipe, handle, access, resident);
805}
806
807static void
808dd_context_set_context_param(struct pipe_context *_pipe,
809                             enum pipe_context_param param,
810                             unsigned value)
811{
812   struct pipe_context *pipe = dd_context(_pipe)->pipe;
813
814   pipe->set_context_param(pipe, param, value);
815}
816
817struct pipe_context *
818dd_context_create(struct dd_screen *dscreen, struct pipe_context *pipe)
819{
820   struct dd_context *dctx;
821
822   if (!pipe)
823      return NULL;
824
825   dctx = CALLOC_STRUCT(dd_context);
826   if (!dctx)
827      goto fail;
828
829   dctx->pipe = pipe;
830   dctx->base.priv = pipe->priv; /* expose wrapped priv data */
831   dctx->base.screen = &dscreen->base;
832   dctx->base.stream_uploader = pipe->stream_uploader;
833   dctx->base.const_uploader = pipe->const_uploader;
834
835   dctx->base.destroy = dd_context_destroy;
836
837   CTX_INIT(render_condition);
838   CTX_INIT(create_query);
839   CTX_INIT(create_batch_query);
840   CTX_INIT(destroy_query);
841   CTX_INIT(begin_query);
842   CTX_INIT(end_query);
843   CTX_INIT(get_query_result);
844   CTX_INIT(set_active_query_state);
845   CTX_INIT(create_blend_state);
846   CTX_INIT(bind_blend_state);
847   CTX_INIT(delete_blend_state);
848   CTX_INIT(create_sampler_state);
849   CTX_INIT(bind_sampler_states);
850   CTX_INIT(delete_sampler_state);
851   CTX_INIT(create_rasterizer_state);
852   CTX_INIT(bind_rasterizer_state);
853   CTX_INIT(delete_rasterizer_state);
854   CTX_INIT(create_depth_stencil_alpha_state);
855   CTX_INIT(bind_depth_stencil_alpha_state);
856   CTX_INIT(delete_depth_stencil_alpha_state);
857   CTX_INIT(create_fs_state);
858   CTX_INIT(bind_fs_state);
859   CTX_INIT(delete_fs_state);
860   CTX_INIT(create_vs_state);
861   CTX_INIT(bind_vs_state);
862   CTX_INIT(delete_vs_state);
863   CTX_INIT(create_gs_state);
864   CTX_INIT(bind_gs_state);
865   CTX_INIT(delete_gs_state);
866   CTX_INIT(create_tcs_state);
867   CTX_INIT(bind_tcs_state);
868   CTX_INIT(delete_tcs_state);
869   CTX_INIT(create_tes_state);
870   CTX_INIT(bind_tes_state);
871   CTX_INIT(delete_tes_state);
872   CTX_INIT(create_compute_state);
873   CTX_INIT(bind_compute_state);
874   CTX_INIT(delete_compute_state);
875   CTX_INIT(create_vertex_elements_state);
876   CTX_INIT(bind_vertex_elements_state);
877   CTX_INIT(delete_vertex_elements_state);
878   CTX_INIT(set_blend_color);
879   CTX_INIT(set_stencil_ref);
880   CTX_INIT(set_sample_mask);
881   CTX_INIT(set_min_samples);
882   CTX_INIT(set_clip_state);
883   CTX_INIT(set_constant_buffer);
884   CTX_INIT(set_framebuffer_state);
885   CTX_INIT(set_polygon_stipple);
886   CTX_INIT(set_scissor_states);
887   CTX_INIT(set_viewport_states);
888   CTX_INIT(set_sampler_views);
889   CTX_INIT(set_tess_state);
890   CTX_INIT(set_shader_buffers);
891   CTX_INIT(set_shader_images);
892   CTX_INIT(set_vertex_buffers);
893   CTX_INIT(set_window_rectangles);
894   CTX_INIT(create_stream_output_target);
895   CTX_INIT(stream_output_target_destroy);
896   CTX_INIT(set_stream_output_targets);
897   CTX_INIT(create_fence_fd);
898   CTX_INIT(fence_server_sync);
899   CTX_INIT(create_sampler_view);
900   CTX_INIT(sampler_view_destroy);
901   CTX_INIT(create_surface);
902   CTX_INIT(surface_destroy);
903   CTX_INIT(texture_barrier);
904   CTX_INIT(memory_barrier);
905   CTX_INIT(resource_commit);
906   CTX_INIT(set_compute_resources);
907   CTX_INIT(set_global_binding);
908   /* create_video_codec */
909   /* create_video_buffer */
910   CTX_INIT(get_sample_position);
911   CTX_INIT(invalidate_resource);
912   CTX_INIT(get_device_reset_status);
913   CTX_INIT(set_device_reset_callback);
914   CTX_INIT(dump_debug_state);
915   CTX_INIT(emit_string_marker);
916   CTX_INIT(create_texture_handle);
917   CTX_INIT(delete_texture_handle);
918   CTX_INIT(make_texture_handle_resident);
919   CTX_INIT(create_image_handle);
920   CTX_INIT(delete_image_handle);
921   CTX_INIT(make_image_handle_resident);
922   CTX_INIT(set_context_param);
923
924   dd_init_draw_functions(dctx);
925
926   u_log_context_init(&dctx->log);
927   if (pipe->set_log_context)
928      pipe->set_log_context(pipe, &dctx->log);
929
930   dctx->draw_state.sample_mask = ~0;
931
932   list_inithead(&dctx->records);
933   (void) mtx_init(&dctx->mutex, mtx_plain);
934   (void) cnd_init(&dctx->cond);
935   dctx->thread = u_thread_create(dd_thread_main, dctx);
936   if (!dctx->thread) {
937      mtx_destroy(&dctx->mutex);
938      goto fail;
939   }
940
941   return &dctx->base;
942
943fail:
944   FREE(dctx);
945   pipe->destroy(pipe);
946   return NULL;
947}
948