• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
34 static void
safe_memcpy(void * dst,const void * src,size_t size)35 safe_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 
48 static struct pipe_query *
dd_context_create_query(struct pipe_context * _pipe,unsigned query_type,unsigned index)49 dd_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 
73 static struct pipe_query *
dd_context_create_batch_query(struct pipe_context * _pipe,unsigned num_queries,unsigned * query_types)74 dd_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 
99 static void
dd_context_destroy_query(struct pipe_context * _pipe,struct pipe_query * query)100 dd_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 
109 static boolean
dd_context_begin_query(struct pipe_context * _pipe,struct pipe_query * query)110 dd_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 
118 static bool
dd_context_end_query(struct pipe_context * _pipe,struct pipe_query * query)119 dd_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 
127 static boolean
dd_context_get_query_result(struct pipe_context * _pipe,struct pipe_query * query,boolean wait,union pipe_query_result * result)128 dd_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 
137 static void
dd_context_set_active_query_state(struct pipe_context * _pipe,boolean enable)138 dd_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 
145 static void
dd_context_render_condition(struct pipe_context * _pipe,struct pipe_query * query,boolean condition,enum pipe_render_cond_flag mode)146 dd_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 
DD_CSO_WHOLE(blend,blend)209 DD_CSO_WHOLE(blend, blend)
210 DD_CSO_WHOLE(rasterizer, rs)
211 DD_CSO_WHOLE(depth_stencil_alpha, dsa)
212 
213 DD_CSO_CREATE(sampler, sampler)
214 DD_CSO_DELETE(sampler)
215 
216 static void
217 dd_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 
242 static void *
dd_context_create_vertex_elements_state(struct pipe_context * _pipe,unsigned num_elems,const struct pipe_vertex_element * elems)243 dd_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 
DD_CSO_BIND(vertex_elements,velems)258 DD_CSO_BIND(vertex_elements, velems)
259 DD_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 
310 DD_SHADER(FRAGMENT, fs)
311 DD_SHADER(VERTEX, vs)
312 DD_SHADER(GEOMETRY, gs)
313 DD_SHADER(TESS_CTRL, tcs)
314 DD_SHADER(TESS_EVAL, tes)
315 
316 static void * \
317 dd_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 
DD_SHADER_NOCREATE(COMPUTE,compute)335 DD_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 
352 DD_IMM_STATE(blend_color, const struct pipe_blend_color, *state, state)
353 DD_IMM_STATE(stencil_ref, const struct pipe_stencil_ref, *state, state)
354 DD_IMM_STATE(clip_state, const struct pipe_clip_state, *state, state)
355 DD_IMM_STATE(sample_mask, unsigned, sample_mask, sample_mask)
356 DD_IMM_STATE(min_samples, unsigned, min_samples, min_samples)
357 DD_IMM_STATE(framebuffer_state, const struct pipe_framebuffer_state, *state, state)
358 DD_IMM_STATE(polygon_stipple, const struct pipe_poly_stipple, *state, state)
359 
360 static void
361 dd_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 
373 static void
dd_context_set_scissor_states(struct pipe_context * _pipe,unsigned start_slot,unsigned num_scissors,const struct pipe_scissor_state * states)374 dd_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 
386 static void
dd_context_set_viewport_states(struct pipe_context * _pipe,unsigned start_slot,unsigned num_viewports,const struct pipe_viewport_state * states)387 dd_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 
dd_context_set_tess_state(struct pipe_context * _pipe,const float default_outer_level[4],const float default_inner_level[2])399 static 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 
413 
414 /********************************************************************
415  * views
416  */
417 
418 static struct pipe_surface *
dd_context_create_surface(struct pipe_context * _pipe,struct pipe_resource * resource,const struct pipe_surface * surf_tmpl)419 dd_context_create_surface(struct pipe_context *_pipe,
420                           struct pipe_resource *resource,
421                           const struct pipe_surface *surf_tmpl)
422 {
423    struct pipe_context *pipe = dd_context(_pipe)->pipe;
424    struct pipe_surface *view =
425       pipe->create_surface(pipe, resource, surf_tmpl);
426 
427    if (!view)
428       return NULL;
429    view->context = _pipe;
430    return view;
431 }
432 
433 static void
dd_context_surface_destroy(struct pipe_context * _pipe,struct pipe_surface * surf)434 dd_context_surface_destroy(struct pipe_context *_pipe,
435                            struct pipe_surface *surf)
436 {
437    struct pipe_context *pipe = dd_context(_pipe)->pipe;
438 
439    pipe->surface_destroy(pipe, surf);
440 }
441 
442 static struct pipe_sampler_view *
dd_context_create_sampler_view(struct pipe_context * _pipe,struct pipe_resource * resource,const struct pipe_sampler_view * templ)443 dd_context_create_sampler_view(struct pipe_context *_pipe,
444                                struct pipe_resource *resource,
445                                const struct pipe_sampler_view *templ)
446 {
447    struct pipe_context *pipe = dd_context(_pipe)->pipe;
448    struct pipe_sampler_view *view =
449       pipe->create_sampler_view(pipe, resource, templ);
450 
451    if (!view)
452       return NULL;
453    view->context = _pipe;
454    return view;
455 }
456 
457 static void
dd_context_sampler_view_destroy(struct pipe_context * _pipe,struct pipe_sampler_view * view)458 dd_context_sampler_view_destroy(struct pipe_context *_pipe,
459                                 struct pipe_sampler_view *view)
460 {
461    struct pipe_context *pipe = dd_context(_pipe)->pipe;
462 
463    pipe->sampler_view_destroy(pipe, view);
464 }
465 
466 static struct pipe_stream_output_target *
dd_context_create_stream_output_target(struct pipe_context * _pipe,struct pipe_resource * res,unsigned buffer_offset,unsigned buffer_size)467 dd_context_create_stream_output_target(struct pipe_context *_pipe,
468                                        struct pipe_resource *res,
469                                        unsigned buffer_offset,
470                                        unsigned buffer_size)
471 {
472    struct pipe_context *pipe = dd_context(_pipe)->pipe;
473    struct pipe_stream_output_target *view =
474       pipe->create_stream_output_target(pipe, res, buffer_offset,
475                                         buffer_size);
476 
477    if (!view)
478       return NULL;
479    view->context = _pipe;
480    return view;
481 }
482 
483 static void
dd_context_stream_output_target_destroy(struct pipe_context * _pipe,struct pipe_stream_output_target * target)484 dd_context_stream_output_target_destroy(struct pipe_context *_pipe,
485                                         struct pipe_stream_output_target *target)
486 {
487    struct pipe_context *pipe = dd_context(_pipe)->pipe;
488 
489    pipe->stream_output_target_destroy(pipe, target);
490 }
491 
492 
493 /********************************************************************
494  * set states
495  */
496 
497 static void
dd_context_set_sampler_views(struct pipe_context * _pipe,enum pipe_shader_type shader,unsigned start,unsigned num,struct pipe_sampler_view ** views)498 dd_context_set_sampler_views(struct pipe_context *_pipe,
499                              enum pipe_shader_type shader,
500                              unsigned start, unsigned num,
501                              struct pipe_sampler_view **views)
502 {
503    struct dd_context *dctx = dd_context(_pipe);
504    struct pipe_context *pipe = dctx->pipe;
505 
506    safe_memcpy(&dctx->draw_state.sampler_views[shader][start], views,
507                sizeof(views[0]) * num);
508    pipe->set_sampler_views(pipe, shader, start, num, views);
509 }
510 
511 static void
dd_context_set_shader_images(struct pipe_context * _pipe,enum pipe_shader_type shader,unsigned start,unsigned num,const struct pipe_image_view * views)512 dd_context_set_shader_images(struct pipe_context *_pipe,
513                              enum pipe_shader_type shader,
514                              unsigned start, unsigned num,
515                              const struct pipe_image_view *views)
516 {
517    struct dd_context *dctx = dd_context(_pipe);
518    struct pipe_context *pipe = dctx->pipe;
519 
520    safe_memcpy(&dctx->draw_state.shader_images[shader][start], views,
521                sizeof(views[0]) * num);
522    pipe->set_shader_images(pipe, shader, start, num, views);
523 }
524 
525 static void
dd_context_set_shader_buffers(struct pipe_context * _pipe,unsigned shader,unsigned start,unsigned num_buffers,const struct pipe_shader_buffer * buffers)526 dd_context_set_shader_buffers(struct pipe_context *_pipe, unsigned shader,
527                               unsigned start, unsigned num_buffers,
528                               const struct pipe_shader_buffer *buffers)
529 {
530    struct dd_context *dctx = dd_context(_pipe);
531    struct pipe_context *pipe = dctx->pipe;
532 
533    safe_memcpy(&dctx->draw_state.shader_buffers[shader][start], buffers,
534                sizeof(buffers[0]) * num_buffers);
535    pipe->set_shader_buffers(pipe, shader, start, num_buffers, buffers);
536 }
537 
538 static void
dd_context_set_vertex_buffers(struct pipe_context * _pipe,unsigned start,unsigned num_buffers,const struct pipe_vertex_buffer * buffers)539 dd_context_set_vertex_buffers(struct pipe_context *_pipe,
540                               unsigned start, unsigned num_buffers,
541                               const struct pipe_vertex_buffer *buffers)
542 {
543    struct dd_context *dctx = dd_context(_pipe);
544    struct pipe_context *pipe = dctx->pipe;
545 
546    safe_memcpy(&dctx->draw_state.vertex_buffers[start], buffers,
547                sizeof(buffers[0]) * num_buffers);
548    pipe->set_vertex_buffers(pipe, start, num_buffers, buffers);
549 }
550 
551 static void
dd_context_set_stream_output_targets(struct pipe_context * _pipe,unsigned num_targets,struct pipe_stream_output_target ** tgs,const unsigned * offsets)552 dd_context_set_stream_output_targets(struct pipe_context *_pipe,
553                                      unsigned num_targets,
554                                      struct pipe_stream_output_target **tgs,
555                                      const unsigned *offsets)
556 {
557    struct dd_context *dctx = dd_context(_pipe);
558    struct pipe_context *pipe = dctx->pipe;
559    struct dd_draw_state *dstate = &dctx->draw_state;
560 
561    dstate->num_so_targets = num_targets;
562    safe_memcpy(dstate->so_targets, tgs, sizeof(*tgs) * num_targets);
563    safe_memcpy(dstate->so_offsets, offsets, sizeof(*offsets) * num_targets);
564    pipe->set_stream_output_targets(pipe, num_targets, tgs, offsets);
565 }
566 
567 void
dd_thread_join(struct dd_context * dctx)568 dd_thread_join(struct dd_context *dctx)
569 {
570    mtx_lock(&dctx->mutex);
571    dctx->kill_thread = true;
572    cnd_signal(&dctx->cond);
573    mtx_unlock(&dctx->mutex);
574    thrd_join(dctx->thread, NULL);
575 }
576 
577 static void
dd_context_destroy(struct pipe_context * _pipe)578 dd_context_destroy(struct pipe_context *_pipe)
579 {
580    struct dd_context *dctx = dd_context(_pipe);
581    struct pipe_context *pipe = dctx->pipe;
582 
583    dd_thread_join(dctx);
584    mtx_destroy(&dctx->mutex);
585    cnd_destroy(&dctx->cond);
586 
587    assert(list_empty(&dctx->records));
588    assert(!dctx->record_pending);
589 
590    if (pipe->set_log_context) {
591       pipe->set_log_context(pipe, NULL);
592 
593       if (dd_screen(dctx->base.screen)->dump_mode == DD_DUMP_ALL_CALLS) {
594          FILE *f = dd_get_file_stream(dd_screen(dctx->base.screen), 0);
595          if (f) {
596             fprintf(f, "Remainder of driver log:\n\n");
597          }
598 
599          u_log_new_page_print(&dctx->log, f);
600          fclose(f);
601       }
602    }
603    u_log_context_destroy(&dctx->log);
604 
605    pipe->destroy(pipe);
606    FREE(dctx);
607 }
608 
609 
610 /********************************************************************
611  * miscellaneous
612  */
613 
614 static void
dd_context_texture_barrier(struct pipe_context * _pipe,unsigned flags)615 dd_context_texture_barrier(struct pipe_context *_pipe, unsigned flags)
616 {
617    struct pipe_context *pipe = dd_context(_pipe)->pipe;
618 
619    pipe->texture_barrier(pipe, flags);
620 }
621 
622 static void
dd_context_memory_barrier(struct pipe_context * _pipe,unsigned flags)623 dd_context_memory_barrier(struct pipe_context *_pipe, unsigned flags)
624 {
625    struct pipe_context *pipe = dd_context(_pipe)->pipe;
626 
627    pipe->memory_barrier(pipe, flags);
628 }
629 
630 static bool
dd_context_resource_commit(struct pipe_context * _pipe,struct pipe_resource * resource,unsigned level,struct pipe_box * box,bool commit)631 dd_context_resource_commit(struct pipe_context *_pipe,
632                            struct pipe_resource *resource,
633                            unsigned level, struct pipe_box *box, bool commit)
634 {
635    struct pipe_context *pipe = dd_context(_pipe)->pipe;
636 
637    return pipe->resource_commit(pipe, resource, level, box, commit);
638 }
639 
640 static void
dd_context_get_sample_position(struct pipe_context * _pipe,unsigned sample_count,unsigned sample_index,float * out_value)641 dd_context_get_sample_position(struct pipe_context *_pipe,
642                                unsigned sample_count, unsigned sample_index,
643                                float *out_value)
644 {
645    struct pipe_context *pipe = dd_context(_pipe)->pipe;
646 
647    return pipe->get_sample_position(pipe, sample_count, sample_index,
648                                     out_value);
649 }
650 
651 static void
dd_context_invalidate_resource(struct pipe_context * _pipe,struct pipe_resource * resource)652 dd_context_invalidate_resource(struct pipe_context *_pipe,
653                                struct pipe_resource *resource)
654 {
655    struct pipe_context *pipe = dd_context(_pipe)->pipe;
656 
657    pipe->invalidate_resource(pipe, resource);
658 }
659 
660 static enum pipe_reset_status
dd_context_get_device_reset_status(struct pipe_context * _pipe)661 dd_context_get_device_reset_status(struct pipe_context *_pipe)
662 {
663    struct pipe_context *pipe = dd_context(_pipe)->pipe;
664 
665    return pipe->get_device_reset_status(pipe);
666 }
667 
668 static void
dd_context_set_device_reset_callback(struct pipe_context * _pipe,const struct pipe_device_reset_callback * cb)669 dd_context_set_device_reset_callback(struct pipe_context *_pipe,
670                                      const struct pipe_device_reset_callback *cb)
671 {
672    struct pipe_context *pipe = dd_context(_pipe)->pipe;
673 
674    return pipe->set_device_reset_callback(pipe, cb);
675 }
676 
677 static void
dd_context_emit_string_marker(struct pipe_context * _pipe,const char * string,int len)678 dd_context_emit_string_marker(struct pipe_context *_pipe,
679                               const char *string, int len)
680 {
681    struct dd_context *dctx = dd_context(_pipe);
682    struct pipe_context *pipe = dctx->pipe;
683 
684    pipe->emit_string_marker(pipe, string, len);
685    dd_parse_apitrace_marker(string, len, &dctx->draw_state.apitrace_call_number);
686 }
687 
688 static void
dd_context_dump_debug_state(struct pipe_context * _pipe,FILE * stream,unsigned flags)689 dd_context_dump_debug_state(struct pipe_context *_pipe, FILE *stream,
690                             unsigned flags)
691 {
692    struct pipe_context *pipe = dd_context(_pipe)->pipe;
693 
694    return pipe->dump_debug_state(pipe, stream, flags);
695 }
696 
697 static uint64_t
dd_context_create_texture_handle(struct pipe_context * _pipe,struct pipe_sampler_view * view,const struct pipe_sampler_state * state)698 dd_context_create_texture_handle(struct pipe_context *_pipe,
699                                  struct pipe_sampler_view *view,
700                                  const struct pipe_sampler_state *state)
701 {
702    struct pipe_context *pipe = dd_context(_pipe)->pipe;
703 
704    return pipe->create_texture_handle(pipe, view, state);
705 }
706 
707 static void
dd_context_delete_texture_handle(struct pipe_context * _pipe,uint64_t handle)708 dd_context_delete_texture_handle(struct pipe_context *_pipe, uint64_t handle)
709 {
710    struct pipe_context *pipe = dd_context(_pipe)->pipe;
711 
712    pipe->delete_texture_handle(pipe, handle);
713 }
714 
715 static void
dd_context_make_texture_handle_resident(struct pipe_context * _pipe,uint64_t handle,bool resident)716 dd_context_make_texture_handle_resident(struct pipe_context *_pipe,
717                                         uint64_t handle, bool resident)
718 {
719    struct pipe_context *pipe = dd_context(_pipe)->pipe;
720 
721    pipe->make_texture_handle_resident(pipe, handle, resident);
722 }
723 
724 static uint64_t
dd_context_create_image_handle(struct pipe_context * _pipe,const struct pipe_image_view * image)725 dd_context_create_image_handle(struct pipe_context *_pipe,
726                                const struct pipe_image_view *image)
727 {
728    struct pipe_context *pipe = dd_context(_pipe)->pipe;
729 
730    return pipe->create_image_handle(pipe, image);
731 }
732 
733 static void
dd_context_delete_image_handle(struct pipe_context * _pipe,uint64_t handle)734 dd_context_delete_image_handle(struct pipe_context *_pipe, uint64_t handle)
735 {
736    struct pipe_context *pipe = dd_context(_pipe)->pipe;
737 
738    pipe->delete_image_handle(pipe, handle);
739 }
740 
741 static void
dd_context_make_image_handle_resident(struct pipe_context * _pipe,uint64_t handle,unsigned access,bool resident)742 dd_context_make_image_handle_resident(struct pipe_context *_pipe,
743                                       uint64_t handle, unsigned access,
744                                       bool resident)
745 {
746    struct pipe_context *pipe = dd_context(_pipe)->pipe;
747 
748    pipe->make_image_handle_resident(pipe, handle, access, resident);
749 }
750 
751 struct pipe_context *
dd_context_create(struct dd_screen * dscreen,struct pipe_context * pipe)752 dd_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    dctx->base.stream_uploader = pipe->stream_uploader;
767    dctx->base.const_uploader = pipe->const_uploader;
768 
769    dctx->base.destroy = dd_context_destroy;
770 
771    CTX_INIT(render_condition);
772    CTX_INIT(create_query);
773    CTX_INIT(create_batch_query);
774    CTX_INIT(destroy_query);
775    CTX_INIT(begin_query);
776    CTX_INIT(end_query);
777    CTX_INIT(get_query_result);
778    CTX_INIT(set_active_query_state);
779    CTX_INIT(create_blend_state);
780    CTX_INIT(bind_blend_state);
781    CTX_INIT(delete_blend_state);
782    CTX_INIT(create_sampler_state);
783    CTX_INIT(bind_sampler_states);
784    CTX_INIT(delete_sampler_state);
785    CTX_INIT(create_rasterizer_state);
786    CTX_INIT(bind_rasterizer_state);
787    CTX_INIT(delete_rasterizer_state);
788    CTX_INIT(create_depth_stencil_alpha_state);
789    CTX_INIT(bind_depth_stencil_alpha_state);
790    CTX_INIT(delete_depth_stencil_alpha_state);
791    CTX_INIT(create_fs_state);
792    CTX_INIT(bind_fs_state);
793    CTX_INIT(delete_fs_state);
794    CTX_INIT(create_vs_state);
795    CTX_INIT(bind_vs_state);
796    CTX_INIT(delete_vs_state);
797    CTX_INIT(create_gs_state);
798    CTX_INIT(bind_gs_state);
799    CTX_INIT(delete_gs_state);
800    CTX_INIT(create_tcs_state);
801    CTX_INIT(bind_tcs_state);
802    CTX_INIT(delete_tcs_state);
803    CTX_INIT(create_tes_state);
804    CTX_INIT(bind_tes_state);
805    CTX_INIT(delete_tes_state);
806    CTX_INIT(create_compute_state);
807    CTX_INIT(bind_compute_state);
808    CTX_INIT(delete_compute_state);
809    CTX_INIT(create_vertex_elements_state);
810    CTX_INIT(bind_vertex_elements_state);
811    CTX_INIT(delete_vertex_elements_state);
812    CTX_INIT(set_blend_color);
813    CTX_INIT(set_stencil_ref);
814    CTX_INIT(set_sample_mask);
815    CTX_INIT(set_min_samples);
816    CTX_INIT(set_clip_state);
817    CTX_INIT(set_constant_buffer);
818    CTX_INIT(set_framebuffer_state);
819    CTX_INIT(set_polygon_stipple);
820    CTX_INIT(set_scissor_states);
821    CTX_INIT(set_viewport_states);
822    CTX_INIT(set_sampler_views);
823    CTX_INIT(set_tess_state);
824    CTX_INIT(set_shader_buffers);
825    CTX_INIT(set_shader_images);
826    CTX_INIT(set_vertex_buffers);
827    CTX_INIT(create_stream_output_target);
828    CTX_INIT(stream_output_target_destroy);
829    CTX_INIT(set_stream_output_targets);
830    CTX_INIT(create_sampler_view);
831    CTX_INIT(sampler_view_destroy);
832    CTX_INIT(create_surface);
833    CTX_INIT(surface_destroy);
834    CTX_INIT(texture_barrier);
835    CTX_INIT(memory_barrier);
836    CTX_INIT(resource_commit);
837    /* create_video_codec */
838    /* create_video_buffer */
839    /* set_compute_resources */
840    /* set_global_binding */
841    CTX_INIT(get_sample_position);
842    CTX_INIT(invalidate_resource);
843    CTX_INIT(get_device_reset_status);
844    CTX_INIT(set_device_reset_callback);
845    CTX_INIT(dump_debug_state);
846    CTX_INIT(emit_string_marker);
847    CTX_INIT(create_texture_handle);
848    CTX_INIT(delete_texture_handle);
849    CTX_INIT(make_texture_handle_resident);
850    CTX_INIT(create_image_handle);
851    CTX_INIT(delete_image_handle);
852    CTX_INIT(make_image_handle_resident);
853 
854    dd_init_draw_functions(dctx);
855 
856    u_log_context_init(&dctx->log);
857    if (pipe->set_log_context)
858       pipe->set_log_context(pipe, &dctx->log);
859 
860    dctx->draw_state.sample_mask = ~0;
861 
862    list_inithead(&dctx->records);
863    (void) mtx_init(&dctx->mutex, mtx_plain);
864    (void) cnd_init(&dctx->cond);
865    dctx->thread = u_thread_create(dd_thread_main, dctx);
866    if (!dctx->thread) {
867       mtx_destroy(&dctx->mutex);
868       goto fail;
869    }
870 
871    return &dctx->base;
872 
873 fail:
874    FREE(dctx);
875    pipe->destroy(pipe);
876    return NULL;
877 }
878