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