1 /**************************************************************************
2 *
3 * Copyright 2015 Advanced Micro Devices, Inc.
4 * Copyright 2008 VMware, Inc.
5 * All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * on the rights to use, copy, modify, merge, publish, distribute, sub
11 * license, and/or sell copies of the Software, and to permit persons to whom
12 * the Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
16 * Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
22 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24 * USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28 #include "dd_pipe.h"
29 #include "tgsi/tgsi_parse.h"
30 #include "util/u_inlines.h"
31 #include "util/u_memory.h"
32
33
34 static void
safe_memcpy(void * dst,const void * src,size_t size)35 safe_memcpy(void *dst, const void *src, size_t size)
36 {
37 if (src)
38 memcpy(dst, src, size);
39 else
40 memset(dst, 0, size);
41 }
42
43
44 /********************************************************************
45 * queries
46 */
47
48 static struct pipe_query *
dd_context_create_query(struct pipe_context * _pipe,unsigned query_type,unsigned index)49 dd_context_create_query(struct pipe_context *_pipe, unsigned query_type,
50 unsigned index)
51 {
52 struct pipe_context *pipe = dd_context(_pipe)->pipe;
53 struct pipe_query *query;
54
55 query = pipe->create_query(pipe, query_type, index);
56
57 /* Wrap query object. */
58 if (query) {
59 struct dd_query *dd_query = CALLOC_STRUCT(dd_query);
60 if (dd_query) {
61 dd_query->type = query_type;
62 dd_query->query = query;
63 query = (struct pipe_query *)dd_query;
64 } else {
65 pipe->destroy_query(pipe, query);
66 query = NULL;
67 }
68 }
69
70 return query;
71 }
72
73 static struct pipe_query *
dd_context_create_batch_query(struct pipe_context * _pipe,unsigned num_queries,unsigned * query_types)74 dd_context_create_batch_query(struct pipe_context *_pipe, unsigned num_queries,
75 unsigned *query_types)
76 {
77 struct pipe_context *pipe = dd_context(_pipe)->pipe;
78 struct pipe_query *query;
79
80 query = pipe->create_batch_query(pipe, num_queries, query_types);
81
82 /* Wrap query object. */
83 if (query) {
84 struct dd_query *dd_query = CALLOC_STRUCT(dd_query);
85 if (dd_query) {
86 /* no special handling for batch queries yet */
87 dd_query->type = query_types[0];
88 dd_query->query = query;
89 query = (struct pipe_query *)dd_query;
90 } else {
91 pipe->destroy_query(pipe, query);
92 query = NULL;
93 }
94 }
95
96 return query;
97 }
98
99 static void
dd_context_destroy_query(struct pipe_context * _pipe,struct pipe_query * query)100 dd_context_destroy_query(struct pipe_context *_pipe,
101 struct pipe_query *query)
102 {
103 struct pipe_context *pipe = dd_context(_pipe)->pipe;
104
105 pipe->destroy_query(pipe, dd_query_unwrap(query));
106 FREE(query);
107 }
108
109 static bool
dd_context_begin_query(struct pipe_context * _pipe,struct pipe_query * query)110 dd_context_begin_query(struct pipe_context *_pipe, struct pipe_query *query)
111 {
112 struct dd_context *dctx = dd_context(_pipe);
113 struct pipe_context *pipe = dctx->pipe;
114
115 return pipe->begin_query(pipe, dd_query_unwrap(query));
116 }
117
118 static bool
dd_context_end_query(struct pipe_context * _pipe,struct pipe_query * query)119 dd_context_end_query(struct pipe_context *_pipe, struct pipe_query *query)
120 {
121 struct dd_context *dctx = dd_context(_pipe);
122 struct pipe_context *pipe = dctx->pipe;
123
124 return pipe->end_query(pipe, dd_query_unwrap(query));
125 }
126
127 static bool
dd_context_get_query_result(struct pipe_context * _pipe,struct pipe_query * query,bool wait,union pipe_query_result * result)128 dd_context_get_query_result(struct pipe_context *_pipe,
129 struct pipe_query *query, bool wait,
130 union pipe_query_result *result)
131 {
132 struct pipe_context *pipe = dd_context(_pipe)->pipe;
133
134 return pipe->get_query_result(pipe, dd_query_unwrap(query), wait, result);
135 }
136
137 static void
dd_context_set_active_query_state(struct pipe_context * _pipe,bool enable)138 dd_context_set_active_query_state(struct pipe_context *_pipe, bool enable)
139 {
140 struct pipe_context *pipe = dd_context(_pipe)->pipe;
141
142 pipe->set_active_query_state(pipe, enable);
143 }
144
145 static void
dd_context_render_condition(struct pipe_context * _pipe,struct pipe_query * query,bool condition,enum pipe_render_cond_flag mode)146 dd_context_render_condition(struct pipe_context *_pipe,
147 struct pipe_query *query, bool condition,
148 enum pipe_render_cond_flag mode)
149 {
150 struct dd_context *dctx = dd_context(_pipe);
151 struct pipe_context *pipe = dctx->pipe;
152 struct dd_draw_state *dstate = &dctx->draw_state;
153
154 pipe->render_condition(pipe, dd_query_unwrap(query), condition, mode);
155 dstate->render_cond.query = dd_query(query);
156 dstate->render_cond.condition = condition;
157 dstate->render_cond.mode = mode;
158 }
159
160
161 /********************************************************************
162 * constant (immutable) non-shader states
163 */
164
165 #define DD_CSO_CREATE(name, shortname) \
166 static void * \
167 dd_context_create_##name##_state(struct pipe_context *_pipe, \
168 const struct pipe_##name##_state *state) \
169 { \
170 struct pipe_context *pipe = dd_context(_pipe)->pipe; \
171 struct dd_state *hstate = CALLOC_STRUCT(dd_state); \
172 \
173 if (!hstate) \
174 return NULL; \
175 hstate->cso = pipe->create_##name##_state(pipe, state); \
176 hstate->state.shortname = *state; \
177 return hstate; \
178 }
179
180 #define DD_CSO_BIND(name, shortname) \
181 static void \
182 dd_context_bind_##name##_state(struct pipe_context *_pipe, void *state) \
183 { \
184 struct dd_context *dctx = dd_context(_pipe); \
185 struct pipe_context *pipe = dctx->pipe; \
186 struct dd_state *hstate = state; \
187 \
188 dctx->draw_state.shortname = hstate; \
189 pipe->bind_##name##_state(pipe, hstate ? hstate->cso : NULL); \
190 }
191
192 #define DD_CSO_DELETE(name) \
193 static void \
194 dd_context_delete_##name##_state(struct pipe_context *_pipe, void *state) \
195 { \
196 struct dd_context *dctx = dd_context(_pipe); \
197 struct pipe_context *pipe = dctx->pipe; \
198 struct dd_state *hstate = state; \
199 \
200 pipe->delete_##name##_state(pipe, hstate->cso); \
201 FREE(hstate); \
202 }
203
204 #define DD_CSO_WHOLE(name, shortname) \
205 DD_CSO_CREATE(name, shortname) \
206 DD_CSO_BIND(name, shortname) \
207 DD_CSO_DELETE(name)
208
DD_CSO_WHOLE(blend,blend)209 DD_CSO_WHOLE(blend, blend)
210 DD_CSO_WHOLE(rasterizer, rs)
211 DD_CSO_WHOLE(depth_stencil_alpha, dsa)
212
213 DD_CSO_CREATE(sampler, sampler)
214 DD_CSO_DELETE(sampler)
215
216 static void
217 dd_context_bind_sampler_states(struct pipe_context *_pipe,
218 enum pipe_shader_type shader,
219 unsigned start, unsigned count, void **states)
220 {
221 struct dd_context *dctx = dd_context(_pipe);
222 struct pipe_context *pipe = dctx->pipe;
223
224 safe_memcpy(&dctx->draw_state.sampler_states[shader][start], states,
225 sizeof(void*) * count);
226
227 if (states) {
228 void *samp[PIPE_MAX_SAMPLERS];
229 int i;
230
231 for (i = 0; i < count; i++) {
232 struct dd_state *s = states[i];
233 samp[i] = s ? s->cso : NULL;
234 }
235
236 pipe->bind_sampler_states(pipe, shader, start, count, samp);
237 }
238 else
239 pipe->bind_sampler_states(pipe, shader, start, count, NULL);
240 }
241
242 static void *
dd_context_create_vertex_elements_state(struct pipe_context * _pipe,unsigned num_elems,const struct pipe_vertex_element * elems)243 dd_context_create_vertex_elements_state(struct pipe_context *_pipe,
244 unsigned num_elems,
245 const struct pipe_vertex_element *elems)
246 {
247 struct pipe_context *pipe = dd_context(_pipe)->pipe;
248 struct dd_state *hstate = CALLOC_STRUCT(dd_state);
249
250 if (!hstate)
251 return NULL;
252 hstate->cso = pipe->create_vertex_elements_state(pipe, num_elems, elems);
253 memcpy(hstate->state.velems.velems, elems, sizeof(elems[0]) * num_elems);
254 hstate->state.velems.count = num_elems;
255 return hstate;
256 }
257
DD_CSO_BIND(vertex_elements,velems)258 DD_CSO_BIND(vertex_elements, velems)
259 DD_CSO_DELETE(vertex_elements)
260
261
262 /********************************************************************
263 * shaders
264 */
265
266 #define DD_SHADER_NOCREATE(NAME, name) \
267 static void \
268 dd_context_bind_##name##_state(struct pipe_context *_pipe, void *state) \
269 { \
270 struct dd_context *dctx = dd_context(_pipe); \
271 struct pipe_context *pipe = dctx->pipe; \
272 struct dd_state *hstate = state; \
273 \
274 dctx->draw_state.shaders[PIPE_SHADER_##NAME] = hstate; \
275 pipe->bind_##name##_state(pipe, hstate ? hstate->cso : NULL); \
276 } \
277 \
278 static void \
279 dd_context_delete_##name##_state(struct pipe_context *_pipe, void *state) \
280 { \
281 struct dd_context *dctx = dd_context(_pipe); \
282 struct pipe_context *pipe = dctx->pipe; \
283 struct dd_state *hstate = state; \
284 \
285 pipe->delete_##name##_state(pipe, hstate->cso); \
286 if (hstate->state.shader.type == PIPE_SHADER_IR_TGSI) \
287 tgsi_free_tokens(hstate->state.shader.tokens); \
288 FREE(hstate); \
289 }
290
291 #define DD_SHADER(NAME, name) \
292 static void * \
293 dd_context_create_##name##_state(struct pipe_context *_pipe, \
294 const struct pipe_shader_state *state) \
295 { \
296 struct pipe_context *pipe = dd_context(_pipe)->pipe; \
297 struct dd_state *hstate = CALLOC_STRUCT(dd_state); \
298 \
299 if (!hstate) \
300 return NULL; \
301 hstate->cso = pipe->create_##name##_state(pipe, state); \
302 hstate->state.shader = *state; \
303 if (hstate->state.shader.type == PIPE_SHADER_IR_TGSI) \
304 hstate->state.shader.tokens = tgsi_dup_tokens(state->tokens); \
305 return hstate; \
306 } \
307 \
308 DD_SHADER_NOCREATE(NAME, name)
309
310 DD_SHADER(FRAGMENT, fs)
311 DD_SHADER(VERTEX, vs)
312 DD_SHADER(GEOMETRY, gs)
313 DD_SHADER(TESS_CTRL, tcs)
314 DD_SHADER(TESS_EVAL, tes)
315
316 static void * \
317 dd_context_create_compute_state(struct pipe_context *_pipe,
318 const struct pipe_compute_state *state)
319 {
320 struct pipe_context *pipe = dd_context(_pipe)->pipe;
321 struct dd_state *hstate = CALLOC_STRUCT(dd_state);
322
323 if (!hstate)
324 return NULL;
325 hstate->cso = pipe->create_compute_state(pipe, state);
326
327 hstate->state.shader.type = state->ir_type;
328
329 if (state->ir_type == PIPE_SHADER_IR_TGSI)
330 hstate->state.shader.tokens = tgsi_dup_tokens(state->prog);
331
332 return hstate;
333 }
334
DD_SHADER_NOCREATE(COMPUTE,compute)335 DD_SHADER_NOCREATE(COMPUTE, compute)
336
337 /********************************************************************
338 * immediate states
339 */
340
341 #define DD_IMM_STATE(name, type, deref, ref) \
342 static void \
343 dd_context_set_##name(struct pipe_context *_pipe, type deref) \
344 { \
345 struct dd_context *dctx = dd_context(_pipe); \
346 struct pipe_context *pipe = dctx->pipe; \
347 \
348 dctx->draw_state.name = deref; \
349 pipe->set_##name(pipe, ref); \
350 }
351
352 DD_IMM_STATE(blend_color, const struct pipe_blend_color, *state, state)
353 DD_IMM_STATE(stencil_ref, const struct pipe_stencil_ref, state, state)
354 DD_IMM_STATE(clip_state, const struct pipe_clip_state, *state, state)
355 DD_IMM_STATE(sample_mask, unsigned, sample_mask, sample_mask)
356 DD_IMM_STATE(min_samples, unsigned, min_samples, min_samples)
357 DD_IMM_STATE(framebuffer_state, const struct pipe_framebuffer_state, *state, state)
358 DD_IMM_STATE(polygon_stipple, const struct pipe_poly_stipple, *state, state)
359
360 static void
361 dd_context_set_constant_buffer(struct pipe_context *_pipe,
362 enum pipe_shader_type shader, uint index,
363 bool take_ownership,
364 const struct pipe_constant_buffer *constant_buffer)
365 {
366 struct dd_context *dctx = dd_context(_pipe);
367 struct pipe_context *pipe = dctx->pipe;
368
369 safe_memcpy(&dctx->draw_state.constant_buffers[shader][index],
370 constant_buffer, sizeof(*constant_buffer));
371 pipe->set_constant_buffer(pipe, shader, index, take_ownership, constant_buffer);
372 }
373
374 static void
dd_context_set_scissor_states(struct pipe_context * _pipe,unsigned start_slot,unsigned num_scissors,const struct pipe_scissor_state * states)375 dd_context_set_scissor_states(struct pipe_context *_pipe,
376 unsigned start_slot, unsigned num_scissors,
377 const struct pipe_scissor_state *states)
378 {
379 struct dd_context *dctx = dd_context(_pipe);
380 struct pipe_context *pipe = dctx->pipe;
381
382 safe_memcpy(&dctx->draw_state.scissors[start_slot], states,
383 sizeof(*states) * num_scissors);
384 pipe->set_scissor_states(pipe, start_slot, num_scissors, states);
385 }
386
387 static void
dd_context_set_viewport_states(struct pipe_context * _pipe,unsigned start_slot,unsigned num_viewports,const struct pipe_viewport_state * states)388 dd_context_set_viewport_states(struct pipe_context *_pipe,
389 unsigned start_slot, unsigned num_viewports,
390 const struct pipe_viewport_state *states)
391 {
392 struct dd_context *dctx = dd_context(_pipe);
393 struct pipe_context *pipe = dctx->pipe;
394
395 safe_memcpy(&dctx->draw_state.viewports[start_slot], states,
396 sizeof(*states) * num_viewports);
397 pipe->set_viewport_states(pipe, start_slot, num_viewports, states);
398 }
399
dd_context_set_tess_state(struct pipe_context * _pipe,const float default_outer_level[4],const float default_inner_level[2])400 static void dd_context_set_tess_state(struct pipe_context *_pipe,
401 const float default_outer_level[4],
402 const float default_inner_level[2])
403 {
404 struct dd_context *dctx = dd_context(_pipe);
405 struct pipe_context *pipe = dctx->pipe;
406
407 memcpy(dctx->draw_state.tess_default_levels, default_outer_level,
408 sizeof(float) * 4);
409 memcpy(dctx->draw_state.tess_default_levels+4, default_inner_level,
410 sizeof(float) * 2);
411 pipe->set_tess_state(pipe, default_outer_level, default_inner_level);
412 }
413
dd_context_set_patch_vertices(struct pipe_context * _pipe,uint8_t patch_vertices)414 static void dd_context_set_patch_vertices(struct pipe_context *_pipe,
415 uint8_t patch_vertices)
416 {
417 struct dd_context *dctx = dd_context(_pipe);
418 struct pipe_context *pipe = dctx->pipe;
419
420 pipe->set_patch_vertices(pipe, patch_vertices);
421 }
422
dd_context_set_window_rectangles(struct pipe_context * _pipe,bool include,unsigned num_rectangles,const struct pipe_scissor_state * rects)423 static void dd_context_set_window_rectangles(struct pipe_context *_pipe,
424 bool include,
425 unsigned num_rectangles,
426 const struct pipe_scissor_state *rects)
427 {
428 struct dd_context *dctx = dd_context(_pipe);
429 struct pipe_context *pipe = dctx->pipe;
430
431 pipe->set_window_rectangles(pipe, include, num_rectangles, rects);
432 }
433
434
435 /********************************************************************
436 * views
437 */
438
439 static struct pipe_surface *
dd_context_create_surface(struct pipe_context * _pipe,struct pipe_resource * resource,const struct pipe_surface * surf_tmpl)440 dd_context_create_surface(struct pipe_context *_pipe,
441 struct pipe_resource *resource,
442 const struct pipe_surface *surf_tmpl)
443 {
444 struct pipe_context *pipe = dd_context(_pipe)->pipe;
445 struct pipe_surface *view =
446 pipe->create_surface(pipe, resource, surf_tmpl);
447
448 if (!view)
449 return NULL;
450 view->context = _pipe;
451 return view;
452 }
453
454 static void
dd_context_surface_destroy(struct pipe_context * _pipe,struct pipe_surface * surf)455 dd_context_surface_destroy(struct pipe_context *_pipe,
456 struct pipe_surface *surf)
457 {
458 struct pipe_context *pipe = dd_context(_pipe)->pipe;
459
460 pipe->surface_destroy(pipe, surf);
461 }
462
463 static struct pipe_sampler_view *
dd_context_create_sampler_view(struct pipe_context * _pipe,struct pipe_resource * resource,const struct pipe_sampler_view * templ)464 dd_context_create_sampler_view(struct pipe_context *_pipe,
465 struct pipe_resource *resource,
466 const struct pipe_sampler_view *templ)
467 {
468 struct pipe_context *pipe = dd_context(_pipe)->pipe;
469 struct pipe_sampler_view *view =
470 pipe->create_sampler_view(pipe, resource, templ);
471
472 if (!view)
473 return NULL;
474 view->context = _pipe;
475 return view;
476 }
477
478 static void
dd_context_sampler_view_destroy(struct pipe_context * _pipe,struct pipe_sampler_view * view)479 dd_context_sampler_view_destroy(struct pipe_context *_pipe,
480 struct pipe_sampler_view *view)
481 {
482 struct pipe_context *pipe = dd_context(_pipe)->pipe;
483
484 pipe->sampler_view_destroy(pipe, view);
485 }
486
487 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)488 dd_context_create_stream_output_target(struct pipe_context *_pipe,
489 struct pipe_resource *res,
490 unsigned buffer_offset,
491 unsigned buffer_size)
492 {
493 struct pipe_context *pipe = dd_context(_pipe)->pipe;
494 struct pipe_stream_output_target *view =
495 pipe->create_stream_output_target(pipe, res, buffer_offset,
496 buffer_size);
497
498 if (!view)
499 return NULL;
500 view->context = _pipe;
501 return view;
502 }
503
504 static void
dd_context_stream_output_target_destroy(struct pipe_context * _pipe,struct pipe_stream_output_target * target)505 dd_context_stream_output_target_destroy(struct pipe_context *_pipe,
506 struct pipe_stream_output_target *target)
507 {
508 struct pipe_context *pipe = dd_context(_pipe)->pipe;
509
510 pipe->stream_output_target_destroy(pipe, target);
511 }
512
513
514 /********************************************************************
515 * set states
516 */
517
518 static void
dd_context_set_sampler_views(struct pipe_context * _pipe,enum pipe_shader_type shader,unsigned start,unsigned num,unsigned unbind_num_trailing_slots,bool take_ownership,struct pipe_sampler_view ** views)519 dd_context_set_sampler_views(struct pipe_context *_pipe,
520 enum pipe_shader_type shader,
521 unsigned start, unsigned num,
522 unsigned unbind_num_trailing_slots,
523 bool take_ownership,
524 struct pipe_sampler_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.sampler_views[shader][start], views,
530 sizeof(views[0]) * num);
531 safe_memcpy(&dctx->draw_state.sampler_views[shader][start + num], NULL,
532 sizeof(views[0]) * unbind_num_trailing_slots);
533 pipe->set_sampler_views(pipe, shader, start, num, take_ownership,
534 unbind_num_trailing_slots, views);
535 }
536
537 static void
dd_context_set_shader_images(struct pipe_context * _pipe,enum pipe_shader_type shader,unsigned start,unsigned num,unsigned unbind_num_trailing_slots,const struct pipe_image_view * views)538 dd_context_set_shader_images(struct pipe_context *_pipe,
539 enum pipe_shader_type shader,
540 unsigned start, unsigned num,
541 unsigned unbind_num_trailing_slots,
542 const struct pipe_image_view *views)
543 {
544 struct dd_context *dctx = dd_context(_pipe);
545 struct pipe_context *pipe = dctx->pipe;
546
547 safe_memcpy(&dctx->draw_state.shader_images[shader][start], views,
548 sizeof(views[0]) * num);
549 safe_memcpy(&dctx->draw_state.shader_images[shader][start + num], NULL,
550 sizeof(views[0]) * unbind_num_trailing_slots);
551 pipe->set_shader_images(pipe, shader, start, num,
552 unbind_num_trailing_slots, views);
553 }
554
555 static void
dd_context_set_shader_buffers(struct pipe_context * _pipe,enum pipe_shader_type shader,unsigned start,unsigned num_buffers,const struct pipe_shader_buffer * buffers,unsigned writable_bitmask)556 dd_context_set_shader_buffers(struct pipe_context *_pipe,
557 enum pipe_shader_type shader,
558 unsigned start, unsigned num_buffers,
559 const struct pipe_shader_buffer *buffers,
560 unsigned writable_bitmask)
561 {
562 struct dd_context *dctx = dd_context(_pipe);
563 struct pipe_context *pipe = dctx->pipe;
564
565 safe_memcpy(&dctx->draw_state.shader_buffers[shader][start], buffers,
566 sizeof(buffers[0]) * num_buffers);
567 pipe->set_shader_buffers(pipe, shader, start, num_buffers, buffers,
568 writable_bitmask);
569 }
570
571 static void
dd_context_set_vertex_buffers(struct pipe_context * _pipe,unsigned num_buffers,const struct pipe_vertex_buffer * buffers)572 dd_context_set_vertex_buffers(struct pipe_context *_pipe,
573 unsigned num_buffers,
574 const struct pipe_vertex_buffer *buffers)
575 {
576 struct dd_context *dctx = dd_context(_pipe);
577 struct pipe_context *pipe = dctx->pipe;
578
579 safe_memcpy(&dctx->draw_state.vertex_buffers[0], buffers,
580 sizeof(buffers[0]) * num_buffers);
581 if (dctx->num_vertex_buffers > num_buffers) {
582 safe_memcpy(&dctx->draw_state.vertex_buffers[num_buffers], NULL,
583 sizeof(buffers[0]) * (dctx->num_vertex_buffers - num_buffers));
584 }
585 pipe->set_vertex_buffers(pipe, num_buffers, buffers);
586 dctx->num_vertex_buffers = num_buffers;
587 }
588
589 static void
dd_context_set_stream_output_targets(struct pipe_context * _pipe,unsigned num_targets,struct pipe_stream_output_target ** tgs,const unsigned * offsets)590 dd_context_set_stream_output_targets(struct pipe_context *_pipe,
591 unsigned num_targets,
592 struct pipe_stream_output_target **tgs,
593 const unsigned *offsets)
594 {
595 struct dd_context *dctx = dd_context(_pipe);
596 struct pipe_context *pipe = dctx->pipe;
597 struct dd_draw_state *dstate = &dctx->draw_state;
598
599 dstate->num_so_targets = num_targets;
600 safe_memcpy(dstate->so_targets, tgs, sizeof(*tgs) * num_targets);
601 safe_memcpy(dstate->so_offsets, offsets, sizeof(*offsets) * num_targets);
602 pipe->set_stream_output_targets(pipe, num_targets, tgs, offsets);
603 }
604
605
606 static void
dd_context_fence_server_sync(struct pipe_context * _pipe,struct pipe_fence_handle * fence)607 dd_context_fence_server_sync(struct pipe_context *_pipe,
608 struct pipe_fence_handle *fence)
609 {
610 struct dd_context *dctx = dd_context(_pipe);
611 struct pipe_context *pipe = dctx->pipe;
612
613 pipe->fence_server_sync(pipe, fence);
614 }
615
616
617 static void
dd_context_create_fence_fd(struct pipe_context * _pipe,struct pipe_fence_handle ** fence,int fd,enum pipe_fd_type type)618 dd_context_create_fence_fd(struct pipe_context *_pipe,
619 struct pipe_fence_handle **fence,
620 int fd,
621 enum pipe_fd_type type)
622 {
623 struct dd_context *dctx = dd_context(_pipe);
624 struct pipe_context *pipe = dctx->pipe;
625
626 pipe->create_fence_fd(pipe, fence, fd, type);
627 }
628
629
630 void
dd_thread_join(struct dd_context * dctx)631 dd_thread_join(struct dd_context *dctx)
632 {
633 mtx_lock(&dctx->mutex);
634 dctx->kill_thread = true;
635 cnd_signal(&dctx->cond);
636 mtx_unlock(&dctx->mutex);
637 thrd_join(dctx->thread, NULL);
638 }
639
640 static void
dd_context_destroy(struct pipe_context * _pipe)641 dd_context_destroy(struct pipe_context *_pipe)
642 {
643 struct dd_context *dctx = dd_context(_pipe);
644 struct pipe_context *pipe = dctx->pipe;
645
646 dd_thread_join(dctx);
647 mtx_destroy(&dctx->mutex);
648 cnd_destroy(&dctx->cond);
649
650 assert(list_is_empty(&dctx->records));
651
652 if (pipe->set_log_context) {
653 pipe->set_log_context(pipe, NULL);
654
655 if (dd_screen(dctx->base.screen)->dump_mode == DD_DUMP_ALL_CALLS) {
656 FILE *f = dd_get_file_stream(dd_screen(dctx->base.screen), 0);
657 if (f) {
658 fprintf(f, "Remainder of driver log:\n\n");
659 }
660
661 u_log_new_page_print(&dctx->log, f);
662 fclose(f);
663 }
664 }
665 u_log_context_destroy(&dctx->log);
666
667 pipe->destroy(pipe);
668 FREE(dctx);
669 }
670
671
672 /********************************************************************
673 * miscellaneous
674 */
675
676 static void
dd_context_texture_barrier(struct pipe_context * _pipe,unsigned flags)677 dd_context_texture_barrier(struct pipe_context *_pipe, unsigned flags)
678 {
679 struct pipe_context *pipe = dd_context(_pipe)->pipe;
680
681 pipe->texture_barrier(pipe, flags);
682 }
683
684 static void
dd_context_memory_barrier(struct pipe_context * _pipe,unsigned flags)685 dd_context_memory_barrier(struct pipe_context *_pipe, unsigned flags)
686 {
687 struct pipe_context *pipe = dd_context(_pipe)->pipe;
688
689 pipe->memory_barrier(pipe, flags);
690 }
691
692 static bool
dd_context_resource_commit(struct pipe_context * _pipe,struct pipe_resource * resource,unsigned level,struct pipe_box * box,bool commit)693 dd_context_resource_commit(struct pipe_context *_pipe,
694 struct pipe_resource *resource,
695 unsigned level, struct pipe_box *box, bool commit)
696 {
697 struct pipe_context *pipe = dd_context(_pipe)->pipe;
698
699 return pipe->resource_commit(pipe, resource, level, box, commit);
700 }
701
702 static void
dd_context_set_compute_resources(struct pipe_context * _pipe,unsigned start,unsigned count,struct pipe_surface ** resources)703 dd_context_set_compute_resources(struct pipe_context *_pipe,
704 unsigned start, unsigned count,
705 struct pipe_surface **resources)
706 {
707 struct pipe_context *pipe = dd_context(_pipe)->pipe;
708 pipe->set_compute_resources(pipe, start, count, resources);
709 }
710
711 static void
dd_context_set_global_binding(struct pipe_context * _pipe,unsigned first,unsigned count,struct pipe_resource ** resources,uint32_t ** handles)712 dd_context_set_global_binding(struct pipe_context *_pipe,
713 unsigned first, unsigned count,
714 struct pipe_resource **resources,
715 uint32_t **handles)
716 {
717 struct pipe_context *pipe = dd_context(_pipe)->pipe;
718 pipe->set_global_binding(pipe, first, count, resources, handles);
719 }
720
721 static void
dd_context_get_sample_position(struct pipe_context * _pipe,unsigned sample_count,unsigned sample_index,float * out_value)722 dd_context_get_sample_position(struct pipe_context *_pipe,
723 unsigned sample_count, unsigned sample_index,
724 float *out_value)
725 {
726 struct pipe_context *pipe = dd_context(_pipe)->pipe;
727
728 pipe->get_sample_position(pipe, sample_count, sample_index,
729 out_value);
730 }
731
732 static void
dd_context_invalidate_resource(struct pipe_context * _pipe,struct pipe_resource * resource)733 dd_context_invalidate_resource(struct pipe_context *_pipe,
734 struct pipe_resource *resource)
735 {
736 struct pipe_context *pipe = dd_context(_pipe)->pipe;
737
738 pipe->invalidate_resource(pipe, resource);
739 }
740
741 static enum pipe_reset_status
dd_context_get_device_reset_status(struct pipe_context * _pipe)742 dd_context_get_device_reset_status(struct pipe_context *_pipe)
743 {
744 struct pipe_context *pipe = dd_context(_pipe)->pipe;
745
746 return pipe->get_device_reset_status(pipe);
747 }
748
749 static void
dd_context_set_device_reset_callback(struct pipe_context * _pipe,const struct pipe_device_reset_callback * cb)750 dd_context_set_device_reset_callback(struct pipe_context *_pipe,
751 const struct pipe_device_reset_callback *cb)
752 {
753 struct pipe_context *pipe = dd_context(_pipe)->pipe;
754
755 pipe->set_device_reset_callback(pipe, cb);
756 }
757
758 static void
dd_context_emit_string_marker(struct pipe_context * _pipe,const char * string,int len)759 dd_context_emit_string_marker(struct pipe_context *_pipe,
760 const char *string, int len)
761 {
762 struct dd_context *dctx = dd_context(_pipe);
763 struct pipe_context *pipe = dctx->pipe;
764
765 pipe->emit_string_marker(pipe, string, len);
766 dd_parse_apitrace_marker(string, len, &dctx->draw_state.apitrace_call_number);
767 }
768
769 static void
dd_context_dump_debug_state(struct pipe_context * _pipe,FILE * stream,unsigned flags)770 dd_context_dump_debug_state(struct pipe_context *_pipe, FILE *stream,
771 unsigned flags)
772 {
773 struct pipe_context *pipe = dd_context(_pipe)->pipe;
774
775 pipe->dump_debug_state(pipe, stream, flags);
776 }
777
778 static uint64_t
dd_context_create_texture_handle(struct pipe_context * _pipe,struct pipe_sampler_view * view,const struct pipe_sampler_state * state)779 dd_context_create_texture_handle(struct pipe_context *_pipe,
780 struct pipe_sampler_view *view,
781 const struct pipe_sampler_state *state)
782 {
783 struct pipe_context *pipe = dd_context(_pipe)->pipe;
784
785 return pipe->create_texture_handle(pipe, view, state);
786 }
787
788 static void
dd_context_delete_texture_handle(struct pipe_context * _pipe,uint64_t handle)789 dd_context_delete_texture_handle(struct pipe_context *_pipe, uint64_t handle)
790 {
791 struct pipe_context *pipe = dd_context(_pipe)->pipe;
792
793 pipe->delete_texture_handle(pipe, handle);
794 }
795
796 static void
dd_context_make_texture_handle_resident(struct pipe_context * _pipe,uint64_t handle,bool resident)797 dd_context_make_texture_handle_resident(struct pipe_context *_pipe,
798 uint64_t handle, bool resident)
799 {
800 struct pipe_context *pipe = dd_context(_pipe)->pipe;
801
802 pipe->make_texture_handle_resident(pipe, handle, resident);
803 }
804
805 static uint64_t
dd_context_create_image_handle(struct pipe_context * _pipe,const struct pipe_image_view * image)806 dd_context_create_image_handle(struct pipe_context *_pipe,
807 const struct pipe_image_view *image)
808 {
809 struct pipe_context *pipe = dd_context(_pipe)->pipe;
810
811 return pipe->create_image_handle(pipe, image);
812 }
813
814 static void
dd_context_delete_image_handle(struct pipe_context * _pipe,uint64_t handle)815 dd_context_delete_image_handle(struct pipe_context *_pipe, uint64_t handle)
816 {
817 struct pipe_context *pipe = dd_context(_pipe)->pipe;
818
819 pipe->delete_image_handle(pipe, handle);
820 }
821
822 static void
dd_context_make_image_handle_resident(struct pipe_context * _pipe,uint64_t handle,unsigned access,bool resident)823 dd_context_make_image_handle_resident(struct pipe_context *_pipe,
824 uint64_t handle, unsigned access,
825 bool resident)
826 {
827 struct pipe_context *pipe = dd_context(_pipe)->pipe;
828
829 pipe->make_image_handle_resident(pipe, handle, access, resident);
830 }
831
832 static void
dd_context_set_context_param(struct pipe_context * _pipe,enum pipe_context_param param,unsigned value)833 dd_context_set_context_param(struct pipe_context *_pipe,
834 enum pipe_context_param param,
835 unsigned value)
836 {
837 struct pipe_context *pipe = dd_context(_pipe)->pipe;
838
839 pipe->set_context_param(pipe, param, value);
840 }
841
842 static void
dd_context_set_inlinable_constants(struct pipe_context * _pipe,enum pipe_shader_type shader,uint num_values,uint32_t * values)843 dd_context_set_inlinable_constants(struct pipe_context *_pipe,
844 enum pipe_shader_type shader,
845 uint num_values, uint32_t *values)
846 {
847 struct pipe_context *pipe = dd_context(_pipe)->pipe;
848
849 pipe->set_inlinable_constants(pipe, shader, num_values, values);
850 }
851
852 struct pipe_context *
dd_context_create(struct dd_screen * dscreen,struct pipe_context * pipe)853 dd_context_create(struct dd_screen *dscreen, struct pipe_context *pipe)
854 {
855 struct dd_context *dctx;
856
857 if (!pipe)
858 return NULL;
859
860 dctx = CALLOC_STRUCT(dd_context);
861 if (!dctx)
862 goto fail;
863
864 dctx->pipe = pipe;
865 dctx->base.priv = pipe->priv; /* expose wrapped priv data */
866 dctx->base.screen = &dscreen->base;
867 dctx->base.stream_uploader = pipe->stream_uploader;
868 dctx->base.const_uploader = pipe->const_uploader;
869
870 dctx->base.destroy = dd_context_destroy;
871
872 CTX_INIT(render_condition);
873 CTX_INIT(create_query);
874 CTX_INIT(create_batch_query);
875 CTX_INIT(destroy_query);
876 CTX_INIT(begin_query);
877 CTX_INIT(end_query);
878 CTX_INIT(get_query_result);
879 CTX_INIT(set_active_query_state);
880 CTX_INIT(create_blend_state);
881 CTX_INIT(bind_blend_state);
882 CTX_INIT(delete_blend_state);
883 CTX_INIT(create_sampler_state);
884 CTX_INIT(bind_sampler_states);
885 CTX_INIT(delete_sampler_state);
886 CTX_INIT(create_rasterizer_state);
887 CTX_INIT(bind_rasterizer_state);
888 CTX_INIT(delete_rasterizer_state);
889 CTX_INIT(create_depth_stencil_alpha_state);
890 CTX_INIT(bind_depth_stencil_alpha_state);
891 CTX_INIT(delete_depth_stencil_alpha_state);
892 CTX_INIT(create_fs_state);
893 CTX_INIT(bind_fs_state);
894 CTX_INIT(delete_fs_state);
895 CTX_INIT(create_vs_state);
896 CTX_INIT(bind_vs_state);
897 CTX_INIT(delete_vs_state);
898 CTX_INIT(create_gs_state);
899 CTX_INIT(bind_gs_state);
900 CTX_INIT(delete_gs_state);
901 CTX_INIT(create_tcs_state);
902 CTX_INIT(bind_tcs_state);
903 CTX_INIT(delete_tcs_state);
904 CTX_INIT(create_tes_state);
905 CTX_INIT(bind_tes_state);
906 CTX_INIT(delete_tes_state);
907 CTX_INIT(create_compute_state);
908 CTX_INIT(bind_compute_state);
909 CTX_INIT(delete_compute_state);
910 CTX_INIT(create_vertex_elements_state);
911 CTX_INIT(bind_vertex_elements_state);
912 CTX_INIT(delete_vertex_elements_state);
913 CTX_INIT(set_blend_color);
914 CTX_INIT(set_stencil_ref);
915 CTX_INIT(set_sample_mask);
916 CTX_INIT(set_min_samples);
917 CTX_INIT(set_clip_state);
918 CTX_INIT(set_constant_buffer);
919 CTX_INIT(set_framebuffer_state);
920 CTX_INIT(set_polygon_stipple);
921 CTX_INIT(set_scissor_states);
922 CTX_INIT(set_viewport_states);
923 CTX_INIT(set_sampler_views);
924 CTX_INIT(set_tess_state);
925 CTX_INIT(set_patch_vertices);
926 CTX_INIT(set_shader_buffers);
927 CTX_INIT(set_shader_images);
928 CTX_INIT(set_vertex_buffers);
929 CTX_INIT(set_window_rectangles);
930 CTX_INIT(create_stream_output_target);
931 CTX_INIT(stream_output_target_destroy);
932 CTX_INIT(set_stream_output_targets);
933 CTX_INIT(create_fence_fd);
934 CTX_INIT(fence_server_sync);
935 CTX_INIT(create_sampler_view);
936 CTX_INIT(sampler_view_destroy);
937 CTX_INIT(create_surface);
938 CTX_INIT(surface_destroy);
939 CTX_INIT(texture_barrier);
940 CTX_INIT(memory_barrier);
941 CTX_INIT(resource_commit);
942 CTX_INIT(set_compute_resources);
943 CTX_INIT(set_global_binding);
944 /* create_video_codec */
945 /* create_video_buffer */
946 CTX_INIT(get_sample_position);
947 CTX_INIT(invalidate_resource);
948 CTX_INIT(get_device_reset_status);
949 CTX_INIT(set_device_reset_callback);
950 CTX_INIT(dump_debug_state);
951 CTX_INIT(emit_string_marker);
952 CTX_INIT(create_texture_handle);
953 CTX_INIT(delete_texture_handle);
954 CTX_INIT(make_texture_handle_resident);
955 CTX_INIT(create_image_handle);
956 CTX_INIT(delete_image_handle);
957 CTX_INIT(make_image_handle_resident);
958 CTX_INIT(set_context_param);
959 CTX_INIT(set_inlinable_constants);
960
961 dd_init_draw_functions(dctx);
962
963 u_log_context_init(&dctx->log);
964 if (pipe->set_log_context)
965 pipe->set_log_context(pipe, &dctx->log);
966
967 dctx->draw_state.sample_mask = ~0;
968
969 list_inithead(&dctx->records);
970 (void) mtx_init(&dctx->mutex, mtx_plain);
971 (void) cnd_init(&dctx->cond);
972 if (thrd_success != u_thread_create(&dctx->thread,dd_thread_main, dctx)) {
973 mtx_destroy(&dctx->mutex);
974 goto fail;
975 }
976
977 return &dctx->base;
978
979 fail:
980 FREE(dctx);
981 pipe->destroy(pipe);
982 return NULL;
983 }
984