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 34static void 35safe_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 48static struct dd_query * 49dd_query(struct pipe_query *query) 50{ 51 return (struct dd_query *)query; 52} 53 54static struct pipe_query * 55dd_query_unwrap(struct pipe_query *query) 56{ 57 if (query) { 58 return dd_query(query)->query; 59 } else { 60 return NULL; 61 } 62} 63 64static struct pipe_query * 65dd_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 89static struct pipe_query * 90dd_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 115static void 116dd_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 125static boolean 126dd_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 134static bool 135dd_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 143static boolean 144dd_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 153static void 154dd_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 161static void 162dd_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 225DD_CSO_WHOLE(blend, blend) 226DD_CSO_WHOLE(rasterizer, rs) 227DD_CSO_WHOLE(depth_stencil_alpha, dsa) 228 229DD_CSO_CREATE(sampler, sampler) 230DD_CSO_DELETE(sampler) 231 232static void 233dd_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 258static void * 259dd_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 274DD_CSO_BIND(vertex_elements, velems) 275DD_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 324DD_SHADER(FRAGMENT, fs) 325DD_SHADER(VERTEX, vs) 326DD_SHADER(GEOMETRY, gs) 327DD_SHADER(TESS_CTRL, tcs) 328DD_SHADER(TESS_EVAL, tes) 329 330static void * \ 331dd_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 347DD_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 364DD_IMM_STATE(blend_color, const struct pipe_blend_color, *state, state) 365DD_IMM_STATE(stencil_ref, const struct pipe_stencil_ref, *state, state) 366DD_IMM_STATE(clip_state, const struct pipe_clip_state, *state, state) 367DD_IMM_STATE(sample_mask, unsigned, sample_mask, sample_mask) 368DD_IMM_STATE(min_samples, unsigned, min_samples, min_samples) 369DD_IMM_STATE(framebuffer_state, const struct pipe_framebuffer_state, *state, state) 370DD_IMM_STATE(polygon_stipple, const struct pipe_poly_stipple, *state, state) 371 372static void 373dd_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 385static void 386dd_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 398static void 399dd_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 411static 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 430static struct pipe_surface * 431dd_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 445static void 446dd_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 454static struct pipe_sampler_view * 455dd_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 469static void 470dd_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 478static struct pipe_stream_output_target * 479dd_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 495static void 496dd_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 509static void 510dd_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 523static void 524dd_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 537static void 538dd_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 550static void 551dd_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 563static void 564dd_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 574static void 575dd_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 590static void 591dd_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 618static void * 619dd_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 629static void 630dd_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 639static void 640dd_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 648static void 649dd_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 659static void 660dd_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 678static void 679dd_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 686static void 687dd_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 694static void 695dd_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 705static void 706dd_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 714static enum pipe_reset_status 715dd_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 722static void 723dd_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 731static void 732dd_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 742static void 743dd_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 751struct pipe_context * 752dd_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 881fail: 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