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