4423e904dc1bf17b91cd89f06679be072dccb2cf
[mesa.git] / src / gallium / drivers / ddebug / dd_context.c
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
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 *
49 dd_query(struct pipe_query *query)
50 {
51 return (struct dd_query *)query;
52 }
53
54 static struct pipe_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 *
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 *
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
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
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
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
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
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
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
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, unsigned shader,
234 unsigned start, unsigned count, void **states)
235 {
236 struct dd_context *dctx = dd_context(_pipe);
237 struct pipe_context *pipe = dctx->pipe;
238
239 memcpy(&dctx->draw_state.sampler_states[shader][start], states,
240 sizeof(void*) * count);
241
242 if (states) {
243 void *samp[PIPE_MAX_SAMPLERS];
244 int i;
245
246 for (i = 0; i < count; i++) {
247 struct dd_state *s = states[i];
248 samp[i] = s ? s->cso : NULL;
249 }
250
251 pipe->bind_sampler_states(pipe, shader, start, count, samp);
252 }
253 else
254 pipe->bind_sampler_states(pipe, shader, start, count, NULL);
255 }
256
257 static void *
258 dd_context_create_vertex_elements_state(struct pipe_context *_pipe,
259 unsigned num_elems,
260 const struct pipe_vertex_element *elems)
261 {
262 struct pipe_context *pipe = dd_context(_pipe)->pipe;
263 struct dd_state *hstate = CALLOC_STRUCT(dd_state);
264
265 if (!hstate)
266 return NULL;
267 hstate->cso = pipe->create_vertex_elements_state(pipe, num_elems, elems);
268 memcpy(hstate->state.velems.velems, elems, sizeof(elems[0]) * num_elems);
269 hstate->state.velems.count = num_elems;
270 return hstate;
271 }
272
273 DD_CSO_BIND(vertex_elements, velems)
274 DD_CSO_DELETE(vertex_elements)
275
276
277 /********************************************************************
278 * shaders
279 */
280
281 #define DD_SHADER_NOCREATE(NAME, name) \
282 static void \
283 dd_context_bind_##name##_state(struct pipe_context *_pipe, void *state) \
284 { \
285 struct dd_context *dctx = dd_context(_pipe); \
286 struct pipe_context *pipe = dctx->pipe; \
287 struct dd_state *hstate = state; \
288 \
289 dctx->draw_state.shaders[PIPE_SHADER_##NAME] = hstate; \
290 pipe->bind_##name##_state(pipe, hstate ? hstate->cso : NULL); \
291 } \
292 \
293 static void \
294 dd_context_delete_##name##_state(struct pipe_context *_pipe, void *state) \
295 { \
296 struct dd_context *dctx = dd_context(_pipe); \
297 struct pipe_context *pipe = dctx->pipe; \
298 struct dd_state *hstate = state; \
299 \
300 pipe->delete_##name##_state(pipe, hstate->cso); \
301 tgsi_free_tokens(hstate->state.shader.tokens); \
302 FREE(hstate); \
303 }
304
305 #define DD_SHADER(NAME, name) \
306 static void * \
307 dd_context_create_##name##_state(struct pipe_context *_pipe, \
308 const struct pipe_shader_state *state) \
309 { \
310 struct pipe_context *pipe = dd_context(_pipe)->pipe; \
311 struct dd_state *hstate = CALLOC_STRUCT(dd_state); \
312 \
313 if (!hstate) \
314 return NULL; \
315 hstate->cso = pipe->create_##name##_state(pipe, state); \
316 hstate->state.shader = *state; \
317 hstate->state.shader.tokens = tgsi_dup_tokens(state->tokens); \
318 return hstate; \
319 } \
320 \
321 DD_SHADER_NOCREATE(NAME, name)
322
323 DD_SHADER(FRAGMENT, fs)
324 DD_SHADER(VERTEX, vs)
325 DD_SHADER(GEOMETRY, gs)
326 DD_SHADER(TESS_CTRL, tcs)
327 DD_SHADER(TESS_EVAL, tes)
328
329 static void * \
330 dd_context_create_compute_state(struct pipe_context *_pipe,
331 const struct pipe_compute_state *state)
332 {
333 struct pipe_context *pipe = dd_context(_pipe)->pipe;
334 struct dd_state *hstate = CALLOC_STRUCT(dd_state);
335
336 if (!hstate)
337 return NULL;
338 hstate->cso = pipe->create_compute_state(pipe, state);
339
340 if (state->ir_type == PIPE_SHADER_IR_TGSI)
341 hstate->state.shader.tokens = tgsi_dup_tokens(state->prog);
342
343 return hstate;
344 }
345
346 DD_SHADER_NOCREATE(COMPUTE, compute)
347
348 /********************************************************************
349 * immediate states
350 */
351
352 #define DD_IMM_STATE(name, type, deref, ref) \
353 static void \
354 dd_context_set_##name(struct pipe_context *_pipe, type deref) \
355 { \
356 struct dd_context *dctx = dd_context(_pipe); \
357 struct pipe_context *pipe = dctx->pipe; \
358 \
359 dctx->draw_state.name = deref; \
360 pipe->set_##name(pipe, ref); \
361 }
362
363 DD_IMM_STATE(blend_color, const struct pipe_blend_color, *state, state)
364 DD_IMM_STATE(stencil_ref, const struct pipe_stencil_ref, *state, state)
365 DD_IMM_STATE(clip_state, const struct pipe_clip_state, *state, state)
366 DD_IMM_STATE(sample_mask, unsigned, sample_mask, sample_mask)
367 DD_IMM_STATE(min_samples, unsigned, min_samples, min_samples)
368 DD_IMM_STATE(framebuffer_state, const struct pipe_framebuffer_state, *state, state)
369 DD_IMM_STATE(polygon_stipple, const struct pipe_poly_stipple, *state, state)
370
371 static void
372 dd_context_set_constant_buffer(struct pipe_context *_pipe,
373 uint shader, uint index,
374 const struct pipe_constant_buffer *constant_buffer)
375 {
376 struct dd_context *dctx = dd_context(_pipe);
377 struct pipe_context *pipe = dctx->pipe;
378
379 safe_memcpy(&dctx->draw_state.constant_buffers[shader][index],
380 constant_buffer, sizeof(*constant_buffer));
381 pipe->set_constant_buffer(pipe, shader, index, constant_buffer);
382 }
383
384 static void
385 dd_context_set_scissor_states(struct pipe_context *_pipe,
386 unsigned start_slot, unsigned num_scissors,
387 const struct pipe_scissor_state *states)
388 {
389 struct dd_context *dctx = dd_context(_pipe);
390 struct pipe_context *pipe = dctx->pipe;
391
392 safe_memcpy(&dctx->draw_state.scissors[start_slot], states,
393 sizeof(*states) * num_scissors);
394 pipe->set_scissor_states(pipe, start_slot, num_scissors, states);
395 }
396
397 static void
398 dd_context_set_viewport_states(struct pipe_context *_pipe,
399 unsigned start_slot, unsigned num_viewports,
400 const struct pipe_viewport_state *states)
401 {
402 struct dd_context *dctx = dd_context(_pipe);
403 struct pipe_context *pipe = dctx->pipe;
404
405 safe_memcpy(&dctx->draw_state.viewports[start_slot], states,
406 sizeof(*states) * num_viewports);
407 pipe->set_viewport_states(pipe, start_slot, num_viewports, states);
408 }
409
410 static void dd_context_set_tess_state(struct pipe_context *_pipe,
411 const float default_outer_level[4],
412 const float default_inner_level[2])
413 {
414 struct dd_context *dctx = dd_context(_pipe);
415 struct pipe_context *pipe = dctx->pipe;
416
417 memcpy(dctx->draw_state.tess_default_levels, default_outer_level,
418 sizeof(float) * 4);
419 memcpy(dctx->draw_state.tess_default_levels+4, default_inner_level,
420 sizeof(float) * 2);
421 pipe->set_tess_state(pipe, default_outer_level, default_inner_level);
422 }
423
424
425 /********************************************************************
426 * views
427 */
428
429 static struct pipe_surface *
430 dd_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
444 static void
445 dd_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
453 static struct pipe_sampler_view *
454 dd_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
468 static void
469 dd_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
477 static struct pipe_stream_output_target *
478 dd_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
494 static void
495 dd_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
508 static void
509 dd_context_set_sampler_views(struct pipe_context *_pipe, unsigned shader,
510 unsigned start, unsigned num,
511 struct pipe_sampler_view **views)
512 {
513 struct dd_context *dctx = dd_context(_pipe);
514 struct pipe_context *pipe = dctx->pipe;
515
516 safe_memcpy(&dctx->draw_state.sampler_views[shader][start], views,
517 sizeof(views[0]) * num);
518 pipe->set_sampler_views(pipe, shader, start, num, views);
519 }
520
521 static void
522 dd_context_set_shader_images(struct pipe_context *_pipe, unsigned shader,
523 unsigned start, unsigned num,
524 const struct pipe_image_view *views)
525 {
526 struct dd_context *dctx = dd_context(_pipe);
527 struct pipe_context *pipe = dctx->pipe;
528
529 safe_memcpy(&dctx->draw_state.shader_images[shader][start], views,
530 sizeof(views[0]) * num);
531 pipe->set_shader_images(pipe, shader, start, num, views);
532 }
533
534 static void
535 dd_context_set_shader_buffers(struct pipe_context *_pipe, unsigned shader,
536 unsigned start, unsigned num_buffers,
537 const struct pipe_shader_buffer *buffers)
538 {
539 struct dd_context *dctx = dd_context(_pipe);
540 struct pipe_context *pipe = dctx->pipe;
541
542 safe_memcpy(&dctx->draw_state.shader_buffers[shader][start], buffers,
543 sizeof(buffers[0]) * num_buffers);
544 pipe->set_shader_buffers(pipe, shader, start, num_buffers, buffers);
545 }
546
547 static void
548 dd_context_set_vertex_buffers(struct pipe_context *_pipe,
549 unsigned start, unsigned num_buffers,
550 const struct pipe_vertex_buffer *buffers)
551 {
552 struct dd_context *dctx = dd_context(_pipe);
553 struct pipe_context *pipe = dctx->pipe;
554
555 safe_memcpy(&dctx->draw_state.vertex_buffers[start], buffers,
556 sizeof(buffers[0]) * num_buffers);
557 pipe->set_vertex_buffers(pipe, start, num_buffers, buffers);
558 }
559
560 static void
561 dd_context_set_index_buffer(struct pipe_context *_pipe,
562 const struct pipe_index_buffer *ib)
563 {
564 struct dd_context *dctx = dd_context(_pipe);
565 struct pipe_context *pipe = dctx->pipe;
566
567 safe_memcpy(&dctx->draw_state.index_buffer, ib, sizeof(*ib));
568 pipe->set_index_buffer(pipe, ib);
569 }
570
571 static void
572 dd_context_set_stream_output_targets(struct pipe_context *_pipe,
573 unsigned num_targets,
574 struct pipe_stream_output_target **tgs,
575 const unsigned *offsets)
576 {
577 struct dd_context *dctx = dd_context(_pipe);
578 struct pipe_context *pipe = dctx->pipe;
579 struct dd_draw_state *dstate = &dctx->draw_state;
580
581 dstate->num_so_targets = num_targets;
582 safe_memcpy(dstate->so_targets, tgs, sizeof(*tgs) * num_targets);
583 safe_memcpy(dstate->so_offsets, offsets, sizeof(*offsets) * num_targets);
584 pipe->set_stream_output_targets(pipe, num_targets, tgs, offsets);
585 }
586
587 static void
588 dd_context_destroy(struct pipe_context *_pipe)
589 {
590 struct dd_context *dctx = dd_context(_pipe);
591 struct pipe_context *pipe = dctx->pipe;
592
593 if (dctx->thread) {
594 pipe_mutex_lock(dctx->mutex);
595 dctx->kill_thread = 1;
596 pipe_mutex_unlock(dctx->mutex);
597 pipe_thread_wait(dctx->thread);
598 pipe_mutex_destroy(dctx->mutex);
599 assert(!dctx->records);
600 }
601
602 if (dctx->fence) {
603 pipe->transfer_unmap(pipe, dctx->fence_transfer);
604 pipe_resource_reference(&dctx->fence, NULL);
605 }
606 pipe->destroy(pipe);
607 FREE(dctx);
608 }
609
610
611 /********************************************************************
612 * transfer
613 */
614
615 static void *
616 dd_context_transfer_map(struct pipe_context *_pipe,
617 struct pipe_resource *resource, unsigned level,
618 unsigned usage, const struct pipe_box *box,
619 struct pipe_transfer **transfer)
620 {
621 struct pipe_context *pipe = dd_context(_pipe)->pipe;
622
623 return pipe->transfer_map(pipe, resource, level, usage, box, transfer);
624 }
625
626 static void
627 dd_context_transfer_flush_region(struct pipe_context *_pipe,
628 struct pipe_transfer *transfer,
629 const struct pipe_box *box)
630 {
631 struct pipe_context *pipe = dd_context(_pipe)->pipe;
632
633 pipe->transfer_flush_region(pipe, transfer, box);
634 }
635
636 static void
637 dd_context_transfer_unmap(struct pipe_context *_pipe,
638 struct pipe_transfer *transfer)
639 {
640 struct pipe_context *pipe = dd_context(_pipe)->pipe;
641
642 pipe->transfer_unmap(pipe, transfer);
643 }
644
645 static void
646 dd_context_buffer_subdata(struct pipe_context *_pipe,
647 struct pipe_resource *resource,
648 unsigned usage, unsigned offset,
649 unsigned size, const void *data)
650 {
651 struct pipe_context *pipe = dd_context(_pipe)->pipe;
652
653 pipe->buffer_subdata(pipe, resource, usage, offset, size, data);
654 }
655
656 static void
657 dd_context_texture_subdata(struct pipe_context *_pipe,
658 struct pipe_resource *resource,
659 unsigned level, unsigned usage,
660 const struct pipe_box *box,
661 const void *data, unsigned stride,
662 unsigned layer_stride)
663 {
664 struct pipe_context *pipe = dd_context(_pipe)->pipe;
665
666 pipe->texture_subdata(pipe, resource, level, usage, box, data,
667 stride, layer_stride);
668 }
669
670
671 /********************************************************************
672 * miscellaneous
673 */
674
675 static void
676 dd_context_texture_barrier(struct pipe_context *_pipe)
677 {
678 struct pipe_context *pipe = dd_context(_pipe)->pipe;
679
680 pipe->texture_barrier(pipe);
681 }
682
683 static void
684 dd_context_memory_barrier(struct pipe_context *_pipe, unsigned flags)
685 {
686 struct pipe_context *pipe = dd_context(_pipe)->pipe;
687
688 pipe->memory_barrier(pipe, flags);
689 }
690
691 static void
692 dd_context_get_sample_position(struct pipe_context *_pipe,
693 unsigned sample_count, unsigned sample_index,
694 float *out_value)
695 {
696 struct pipe_context *pipe = dd_context(_pipe)->pipe;
697
698 return pipe->get_sample_position(pipe, sample_count, sample_index,
699 out_value);
700 }
701
702 static void
703 dd_context_invalidate_resource(struct pipe_context *_pipe,
704 struct pipe_resource *resource)
705 {
706 struct pipe_context *pipe = dd_context(_pipe)->pipe;
707
708 pipe->invalidate_resource(pipe, resource);
709 }
710
711 static enum pipe_reset_status
712 dd_context_get_device_reset_status(struct pipe_context *_pipe)
713 {
714 struct pipe_context *pipe = dd_context(_pipe)->pipe;
715
716 return pipe->get_device_reset_status(pipe);
717 }
718
719 static void
720 dd_context_emit_string_marker(struct pipe_context *_pipe,
721 const char *string, int len)
722 {
723 struct dd_context *dctx = dd_context(_pipe);
724 struct pipe_context *pipe = dctx->pipe;
725
726 pipe->emit_string_marker(pipe, string, len);
727 dd_parse_apitrace_marker(string, len, &dctx->draw_state.apitrace_call_number);
728 }
729
730 static void
731 dd_context_dump_debug_state(struct pipe_context *_pipe, FILE *stream,
732 unsigned flags)
733 {
734 struct pipe_context *pipe = dd_context(_pipe)->pipe;
735
736 return pipe->dump_debug_state(pipe, stream, flags);
737 }
738
739 struct pipe_context *
740 dd_context_create(struct dd_screen *dscreen, struct pipe_context *pipe)
741 {
742 struct dd_context *dctx;
743
744 if (!pipe)
745 return NULL;
746
747 dctx = CALLOC_STRUCT(dd_context);
748 if (!dctx)
749 goto fail;
750
751 dctx->pipe = pipe;
752 dctx->base.priv = pipe->priv; /* expose wrapped priv data */
753 dctx->base.screen = &dscreen->base;
754
755 dctx->base.destroy = dd_context_destroy;
756
757 CTX_INIT(render_condition);
758 CTX_INIT(create_query);
759 CTX_INIT(create_batch_query);
760 CTX_INIT(destroy_query);
761 CTX_INIT(begin_query);
762 CTX_INIT(end_query);
763 CTX_INIT(get_query_result);
764 CTX_INIT(set_active_query_state);
765 CTX_INIT(create_blend_state);
766 CTX_INIT(bind_blend_state);
767 CTX_INIT(delete_blend_state);
768 CTX_INIT(create_sampler_state);
769 CTX_INIT(bind_sampler_states);
770 CTX_INIT(delete_sampler_state);
771 CTX_INIT(create_rasterizer_state);
772 CTX_INIT(bind_rasterizer_state);
773 CTX_INIT(delete_rasterizer_state);
774 CTX_INIT(create_depth_stencil_alpha_state);
775 CTX_INIT(bind_depth_stencil_alpha_state);
776 CTX_INIT(delete_depth_stencil_alpha_state);
777 CTX_INIT(create_fs_state);
778 CTX_INIT(bind_fs_state);
779 CTX_INIT(delete_fs_state);
780 CTX_INIT(create_vs_state);
781 CTX_INIT(bind_vs_state);
782 CTX_INIT(delete_vs_state);
783 CTX_INIT(create_gs_state);
784 CTX_INIT(bind_gs_state);
785 CTX_INIT(delete_gs_state);
786 CTX_INIT(create_tcs_state);
787 CTX_INIT(bind_tcs_state);
788 CTX_INIT(delete_tcs_state);
789 CTX_INIT(create_tes_state);
790 CTX_INIT(bind_tes_state);
791 CTX_INIT(delete_tes_state);
792 CTX_INIT(create_compute_state);
793 CTX_INIT(bind_compute_state);
794 CTX_INIT(delete_compute_state);
795 CTX_INIT(create_vertex_elements_state);
796 CTX_INIT(bind_vertex_elements_state);
797 CTX_INIT(delete_vertex_elements_state);
798 CTX_INIT(set_blend_color);
799 CTX_INIT(set_stencil_ref);
800 CTX_INIT(set_sample_mask);
801 CTX_INIT(set_min_samples);
802 CTX_INIT(set_clip_state);
803 CTX_INIT(set_constant_buffer);
804 CTX_INIT(set_framebuffer_state);
805 CTX_INIT(set_polygon_stipple);
806 CTX_INIT(set_scissor_states);
807 CTX_INIT(set_viewport_states);
808 CTX_INIT(set_sampler_views);
809 CTX_INIT(set_tess_state);
810 CTX_INIT(set_shader_buffers);
811 CTX_INIT(set_shader_images);
812 CTX_INIT(set_vertex_buffers);
813 CTX_INIT(set_index_buffer);
814 CTX_INIT(create_stream_output_target);
815 CTX_INIT(stream_output_target_destroy);
816 CTX_INIT(set_stream_output_targets);
817 CTX_INIT(create_sampler_view);
818 CTX_INIT(sampler_view_destroy);
819 CTX_INIT(create_surface);
820 CTX_INIT(surface_destroy);
821 CTX_INIT(transfer_map);
822 CTX_INIT(transfer_flush_region);
823 CTX_INIT(transfer_unmap);
824 CTX_INIT(buffer_subdata);
825 CTX_INIT(texture_subdata);
826 CTX_INIT(texture_barrier);
827 CTX_INIT(memory_barrier);
828 /* create_video_codec */
829 /* create_video_buffer */
830 /* set_compute_resources */
831 /* set_global_binding */
832 CTX_INIT(get_sample_position);
833 CTX_INIT(invalidate_resource);
834 CTX_INIT(get_device_reset_status);
835 CTX_INIT(dump_debug_state);
836 CTX_INIT(emit_string_marker);
837
838 dd_init_draw_functions(dctx);
839
840 dctx->draw_state.sample_mask = ~0;
841
842 if (dscreen->mode == DD_DETECT_HANGS_PIPELINED) {
843 dctx->fence = pipe_buffer_create(dscreen->screen, PIPE_BIND_CUSTOM,
844 PIPE_USAGE_STAGING, 4);
845 if (!dctx->fence)
846 goto fail;
847
848 dctx->mapped_fence = pipe_buffer_map(pipe, dctx->fence,
849 PIPE_TRANSFER_READ_WRITE |
850 PIPE_TRANSFER_PERSISTENT |
851 PIPE_TRANSFER_COHERENT,
852 &dctx->fence_transfer);
853 if (!dctx->mapped_fence)
854 goto fail;
855
856 *dctx->mapped_fence = 0;
857
858 pipe_mutex_init(dctx->mutex);
859 dctx->thread = pipe_thread_create(dd_thread_pipelined_hang_detect, dctx);
860 if (!dctx->thread) {
861 pipe_mutex_destroy(dctx->mutex);
862 goto fail;
863 }
864 }
865
866 return &dctx->base;
867
868 fail:
869 if (dctx) {
870 if (dctx->mapped_fence)
871 pipe_transfer_unmap(pipe, dctx->fence_transfer);
872 pipe_resource_reference(&dctx->fence, NULL);
873 FREE(dctx);
874 }
875 pipe->destroy(pipe);
876 return NULL;
877 }