1/* 2 * Copyright 2010 Red Hat Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * on the rights to use, copy, modify, merge, publish, distribute, sub 8 * license, and/or sell copies of the Software, and to permit persons to whom 9 * the Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21 * USE OR OTHER DEALINGS IN THE SOFTWARE. 22 */ 23#include <stdio.h> 24#include <errno.h> 25#include "pipe/p_defines.h" 26#include "pipe/p_state.h" 27#include "pipe/p_context.h" 28#include "pipe/p_screen.h" 29#include "util/u_memory.h" 30#include "util/u_inlines.h" 31#include "util/format/u_format.h" 32#include "util/u_helpers.h" 33#include "util/u_upload_mgr.h" 34#include "util/u_threaded_context.h" 35#include "noop_public.h" 36 37DEBUG_GET_ONCE_BOOL_OPTION(noop, "GALLIUM_NOOP", false) 38 39void noop_init_state_functions(struct pipe_context *ctx); 40 41struct noop_pipe_screen { 42 struct pipe_screen pscreen; 43 struct pipe_screen *oscreen; 44 struct slab_parent_pool pool_transfers; 45}; 46 47/* 48 * query 49 */ 50struct noop_query { 51 struct threaded_query b; 52 unsigned query; 53}; 54static struct pipe_query *noop_create_query(struct pipe_context *ctx, unsigned query_type, unsigned index) 55{ 56 struct noop_query *query = CALLOC_STRUCT(noop_query); 57 58 return (struct pipe_query *)query; 59} 60 61static void noop_destroy_query(struct pipe_context *ctx, struct pipe_query *query) 62{ 63 FREE(query); 64} 65 66static bool noop_begin_query(struct pipe_context *ctx, struct pipe_query *query) 67{ 68 return true; 69} 70 71static bool noop_end_query(struct pipe_context *ctx, struct pipe_query *query) 72{ 73 return true; 74} 75 76static bool noop_get_query_result(struct pipe_context *ctx, 77 struct pipe_query *query, 78 bool wait, 79 union pipe_query_result *vresult) 80{ 81 uint64_t *result = (uint64_t*)vresult; 82 83 *result = 0; 84 return true; 85} 86 87static void 88noop_set_active_query_state(struct pipe_context *pipe, bool enable) 89{ 90} 91 92 93/* 94 * resource 95 */ 96struct noop_resource { 97 struct threaded_resource b; 98 unsigned size; 99 char *data; 100 struct sw_displaytarget *dt; 101}; 102 103static struct pipe_resource *noop_resource_create(struct pipe_screen *screen, 104 const struct pipe_resource *templ) 105{ 106 struct noop_resource *nresource; 107 unsigned stride; 108 109 nresource = CALLOC_STRUCT(noop_resource); 110 if (!nresource) 111 return NULL; 112 113 stride = util_format_get_stride(templ->format, templ->width0); 114 nresource->b.b = *templ; 115 nresource->b.b.screen = screen; 116 nresource->size = stride * templ->height0 * templ->depth0; 117 nresource->data = MALLOC(nresource->size); 118 pipe_reference_init(&nresource->b.b.reference, 1); 119 if (nresource->data == NULL) { 120 FREE(nresource); 121 return NULL; 122 } 123 threaded_resource_init(&nresource->b.b, false); 124 return &nresource->b.b; 125} 126 127static struct pipe_resource * 128noop_resource_create_with_modifiers(struct pipe_screen *screen, 129 const struct pipe_resource *templ, 130 const uint64_t *modifiers, int count) 131{ 132 struct noop_pipe_screen *noop_screen = (struct noop_pipe_screen*)screen; 133 struct pipe_screen *oscreen = noop_screen->oscreen; 134 struct pipe_resource *result; 135 struct pipe_resource *noop_resource; 136 137 result = oscreen->resource_create_with_modifiers(oscreen, templ, 138 modifiers, count); 139 noop_resource = noop_resource_create(screen, result); 140 pipe_resource_reference(&result, NULL); 141 return noop_resource; 142} 143 144static struct pipe_resource *noop_resource_from_handle(struct pipe_screen *screen, 145 const struct pipe_resource *templ, 146 struct winsys_handle *handle, 147 unsigned usage) 148{ 149 struct noop_pipe_screen *noop_screen = (struct noop_pipe_screen*)screen; 150 struct pipe_screen *oscreen = noop_screen->oscreen; 151 struct pipe_resource *result; 152 struct pipe_resource *noop_resource; 153 154 result = oscreen->resource_from_handle(oscreen, templ, handle, usage); 155 noop_resource = noop_resource_create(screen, result); 156 pipe_resource_reference(&result, NULL); 157 return noop_resource; 158} 159 160static bool noop_resource_get_handle(struct pipe_screen *pscreen, 161 struct pipe_context *ctx, 162 struct pipe_resource *resource, 163 struct winsys_handle *handle, 164 unsigned usage) 165{ 166 struct noop_pipe_screen *noop_screen = (struct noop_pipe_screen*)pscreen; 167 struct pipe_screen *screen = noop_screen->oscreen; 168 struct pipe_resource *tex; 169 bool result; 170 171 /* resource_get_handle musn't fail. Just create something and return it. */ 172 tex = screen->resource_create(screen, resource); 173 if (!tex) 174 return false; 175 176 result = screen->resource_get_handle(screen, NULL, tex, handle, usage); 177 pipe_resource_reference(&tex, NULL); 178 return result; 179} 180 181static bool noop_resource_get_param(struct pipe_screen *pscreen, 182 struct pipe_context *ctx, 183 struct pipe_resource *resource, 184 unsigned plane, 185 unsigned layer, 186 unsigned level, 187 enum pipe_resource_param param, 188 unsigned handle_usage, 189 uint64_t *value) 190{ 191 struct noop_pipe_screen *noop_screen = (struct noop_pipe_screen*)pscreen; 192 struct pipe_screen *screen = noop_screen->oscreen; 193 struct pipe_resource *tex; 194 bool result; 195 196 /* resource_get_param mustn't fail. Just create something and return it. */ 197 tex = screen->resource_create(screen, resource); 198 if (!tex) 199 return false; 200 201 result = screen->resource_get_param(screen, NULL, tex, 0, 0, 0, param, 202 handle_usage, value); 203 pipe_resource_reference(&tex, NULL); 204 return result; 205} 206 207static void noop_resource_destroy(struct pipe_screen *screen, 208 struct pipe_resource *resource) 209{ 210 struct noop_resource *nresource = (struct noop_resource *)resource; 211 212 threaded_resource_deinit(resource); 213 FREE(nresource->data); 214 FREE(resource); 215} 216 217 218/* 219 * transfer 220 */ 221static void *noop_transfer_map(struct pipe_context *pipe, 222 struct pipe_resource *resource, 223 unsigned level, 224 unsigned usage, 225 const struct pipe_box *box, 226 struct pipe_transfer **ptransfer) 227{ 228 struct pipe_transfer *transfer; 229 struct noop_resource *nresource = (struct noop_resource *)resource; 230 231 transfer = (struct pipe_transfer*)CALLOC_STRUCT(threaded_transfer); 232 if (!transfer) 233 return NULL; 234 pipe_resource_reference(&transfer->resource, resource); 235 transfer->level = level; 236 transfer->usage = usage; 237 transfer->box = *box; 238 transfer->stride = 1; 239 transfer->layer_stride = 1; 240 *ptransfer = transfer; 241 242 return nresource->data; 243} 244 245static void noop_transfer_flush_region(struct pipe_context *pipe, 246 struct pipe_transfer *transfer, 247 const struct pipe_box *box) 248{ 249} 250 251static void noop_transfer_unmap(struct pipe_context *pipe, 252 struct pipe_transfer *transfer) 253{ 254 pipe_resource_reference(&transfer->resource, NULL); 255 FREE(transfer); 256} 257 258static void noop_buffer_subdata(struct pipe_context *pipe, 259 struct pipe_resource *resource, 260 unsigned usage, unsigned offset, 261 unsigned size, const void *data) 262{ 263} 264 265static void noop_texture_subdata(struct pipe_context *pipe, 266 struct pipe_resource *resource, 267 unsigned level, 268 unsigned usage, 269 const struct pipe_box *box, 270 const void *data, 271 unsigned stride, 272 unsigned layer_stride) 273{ 274} 275 276 277/* 278 * clear/copy 279 */ 280static void noop_clear(struct pipe_context *ctx, unsigned buffers, const struct pipe_scissor_state *scissor_state, 281 const union pipe_color_union *color, double depth, unsigned stencil) 282{ 283} 284 285static void noop_clear_render_target(struct pipe_context *ctx, 286 struct pipe_surface *dst, 287 const union pipe_color_union *color, 288 unsigned dstx, unsigned dsty, 289 unsigned width, unsigned height, 290 bool render_condition_enabled) 291{ 292} 293 294static void noop_clear_depth_stencil(struct pipe_context *ctx, 295 struct pipe_surface *dst, 296 unsigned clear_flags, 297 double depth, 298 unsigned stencil, 299 unsigned dstx, unsigned dsty, 300 unsigned width, unsigned height, 301 bool render_condition_enabled) 302{ 303} 304 305static void noop_resource_copy_region(struct pipe_context *ctx, 306 struct pipe_resource *dst, 307 unsigned dst_level, 308 unsigned dstx, unsigned dsty, unsigned dstz, 309 struct pipe_resource *src, 310 unsigned src_level, 311 const struct pipe_box *src_box) 312{ 313} 314 315 316static void noop_blit(struct pipe_context *ctx, 317 const struct pipe_blit_info *info) 318{ 319} 320 321 322static void 323noop_flush_resource(struct pipe_context *ctx, 324 struct pipe_resource *resource) 325{ 326} 327 328 329/* 330 * context 331 */ 332static void noop_flush(struct pipe_context *ctx, 333 struct pipe_fence_handle **fence, 334 unsigned flags) 335{ 336 if (fence) { 337 struct pipe_reference *f = MALLOC_STRUCT(pipe_reference); 338 f->count = 1; 339 340 ctx->screen->fence_reference(ctx->screen, fence, NULL); 341 *fence = (struct pipe_fence_handle*)f; 342 } 343} 344 345static void noop_destroy_context(struct pipe_context *ctx) 346{ 347 if (ctx->stream_uploader) 348 u_upload_destroy(ctx->stream_uploader); 349 350 p_atomic_dec(&ctx->screen->num_contexts); 351 FREE(ctx); 352} 353 354static bool noop_generate_mipmap(struct pipe_context *ctx, 355 struct pipe_resource *resource, 356 enum pipe_format format, 357 unsigned base_level, 358 unsigned last_level, 359 unsigned first_layer, 360 unsigned last_layer) 361{ 362 return true; 363} 364 365static void noop_invalidate_resource(struct pipe_context *ctx, 366 struct pipe_resource *resource) 367{ 368} 369 370static void noop_set_context_param(struct pipe_context *ctx, 371 enum pipe_context_param param, 372 unsigned value) 373{ 374} 375 376static void noop_set_frontend_noop(struct pipe_context *ctx, bool enable) 377{ 378} 379 380static void noop_replace_buffer_storage(struct pipe_context *ctx, 381 struct pipe_resource *dst, 382 struct pipe_resource *src, 383 unsigned num_rebinds, 384 uint32_t rebind_mask, 385 uint32_t delete_buffer_id) 386{ 387} 388 389static struct pipe_fence_handle * 390noop_create_fence(struct pipe_context *ctx, 391 struct tc_unflushed_batch_token *tc_token) 392{ 393 struct pipe_reference *f = MALLOC_STRUCT(pipe_reference); 394 395 f->count = 1; 396 return (struct pipe_fence_handle*)f; 397} 398 399static bool noop_is_resource_busy(struct pipe_screen *screen, 400 struct pipe_resource *resource, 401 unsigned usage) 402{ 403 return false; 404} 405 406static struct pipe_context *noop_create_context(struct pipe_screen *screen, 407 void *priv, unsigned flags) 408{ 409 struct pipe_context *ctx = CALLOC_STRUCT(pipe_context); 410 411 if (!ctx) 412 return NULL; 413 414 ctx->screen = screen; 415 ctx->priv = priv; 416 417 ctx->stream_uploader = u_upload_create_default(ctx); 418 if (!ctx->stream_uploader) { 419 FREE(ctx); 420 return NULL; 421 } 422 ctx->const_uploader = ctx->stream_uploader; 423 424 ctx->destroy = noop_destroy_context; 425 ctx->flush = noop_flush; 426 ctx->clear = noop_clear; 427 ctx->clear_render_target = noop_clear_render_target; 428 ctx->clear_depth_stencil = noop_clear_depth_stencil; 429 ctx->resource_copy_region = noop_resource_copy_region; 430 ctx->generate_mipmap = noop_generate_mipmap; 431 ctx->blit = noop_blit; 432 ctx->flush_resource = noop_flush_resource; 433 ctx->create_query = noop_create_query; 434 ctx->destroy_query = noop_destroy_query; 435 ctx->begin_query = noop_begin_query; 436 ctx->end_query = noop_end_query; 437 ctx->get_query_result = noop_get_query_result; 438 ctx->set_active_query_state = noop_set_active_query_state; 439 ctx->buffer_map = noop_transfer_map; 440 ctx->texture_map = noop_transfer_map; 441 ctx->transfer_flush_region = noop_transfer_flush_region; 442 ctx->buffer_unmap = noop_transfer_unmap; 443 ctx->texture_unmap = noop_transfer_unmap; 444 ctx->buffer_subdata = noop_buffer_subdata; 445 ctx->texture_subdata = noop_texture_subdata; 446 ctx->invalidate_resource = noop_invalidate_resource; 447 ctx->set_context_param = noop_set_context_param; 448 ctx->set_frontend_noop = noop_set_frontend_noop; 449 noop_init_state_functions(ctx); 450 451 p_atomic_inc(&screen->num_contexts); 452 453 if (!(flags & PIPE_CONTEXT_PREFER_THREADED)) 454 return ctx; 455 456 struct pipe_context *tc = 457 threaded_context_create(ctx, 458 &((struct noop_pipe_screen*)screen)->pool_transfers, 459 noop_replace_buffer_storage, 460 &(struct threaded_context_options) { 461 .create_fence = noop_create_fence, 462 .is_resource_busy = noop_is_resource_busy, 463 }, 464 NULL); 465 466 if (tc && tc != ctx) 467 threaded_context_init_bytes_mapped_limit((struct threaded_context *)tc, 4); 468 469 return tc; 470} 471 472 473/* 474 * pipe_screen 475 */ 476static void noop_flush_frontbuffer(struct pipe_screen *_screen, 477 struct pipe_context *ctx, 478 struct pipe_resource *resource, 479 unsigned level, unsigned layer, 480 void *context_private, struct pipe_box *box) 481{ 482} 483 484static const char *noop_get_vendor(struct pipe_screen* pscreen) 485{ 486 return "X.Org"; 487} 488 489static const char *noop_get_device_vendor(struct pipe_screen* pscreen) 490{ 491 return "NONE"; 492} 493 494static const char *noop_get_name(struct pipe_screen* pscreen) 495{ 496 return "NOOP"; 497} 498 499static int noop_get_param(struct pipe_screen* pscreen, enum pipe_cap param) 500{ 501 struct pipe_screen *screen = ((struct noop_pipe_screen*)pscreen)->oscreen; 502 503 return screen->get_param(screen, param); 504} 505 506static float noop_get_paramf(struct pipe_screen* pscreen, 507 enum pipe_capf param) 508{ 509 struct pipe_screen *screen = ((struct noop_pipe_screen*)pscreen)->oscreen; 510 511 return screen->get_paramf(screen, param); 512} 513 514static int noop_get_shader_param(struct pipe_screen* pscreen, 515 enum pipe_shader_type shader, 516 enum pipe_shader_cap param) 517{ 518 struct pipe_screen *screen = ((struct noop_pipe_screen*)pscreen)->oscreen; 519 520 return screen->get_shader_param(screen, shader, param); 521} 522 523static int noop_get_compute_param(struct pipe_screen *pscreen, 524 enum pipe_shader_ir ir_type, 525 enum pipe_compute_cap param, 526 void *ret) 527{ 528 struct pipe_screen *screen = ((struct noop_pipe_screen*)pscreen)->oscreen; 529 530 return screen->get_compute_param(screen, ir_type, param, ret); 531} 532 533static bool noop_is_format_supported(struct pipe_screen* pscreen, 534 enum pipe_format format, 535 enum pipe_texture_target target, 536 unsigned sample_count, 537 unsigned storage_sample_count, 538 unsigned usage) 539{ 540 struct pipe_screen *screen = ((struct noop_pipe_screen*)pscreen)->oscreen; 541 542 return screen->is_format_supported(screen, format, target, sample_count, 543 storage_sample_count, usage); 544} 545 546static uint64_t noop_get_timestamp(struct pipe_screen *pscreen) 547{ 548 return 0; 549} 550 551static void noop_destroy_screen(struct pipe_screen *screen) 552{ 553 struct noop_pipe_screen *noop_screen = (struct noop_pipe_screen*)screen; 554 struct pipe_screen *oscreen = noop_screen->oscreen; 555 556 oscreen->destroy(oscreen); 557 slab_destroy_parent(&noop_screen->pool_transfers); 558 FREE(screen); 559} 560 561static void noop_fence_reference(struct pipe_screen *screen, 562 struct pipe_fence_handle **ptr, 563 struct pipe_fence_handle *fence) 564{ 565 if (pipe_reference((struct pipe_reference*)*ptr, 566 (struct pipe_reference*)fence)) 567 FREE(*ptr); 568 569 *ptr = fence; 570} 571 572static bool noop_fence_finish(struct pipe_screen *screen, 573 struct pipe_context *ctx, 574 struct pipe_fence_handle *fence, 575 uint64_t timeout) 576{ 577 return true; 578} 579 580static void noop_query_memory_info(struct pipe_screen *pscreen, 581 struct pipe_memory_info *info) 582{ 583 struct noop_pipe_screen *noop_screen = (struct noop_pipe_screen*)pscreen; 584 struct pipe_screen *screen = noop_screen->oscreen; 585 586 screen->query_memory_info(screen, info); 587} 588 589static struct disk_cache *noop_get_disk_shader_cache(struct pipe_screen *pscreen) 590{ 591 struct pipe_screen *screen = ((struct noop_pipe_screen*)pscreen)->oscreen; 592 593 return screen->get_disk_shader_cache(screen); 594} 595 596static const void *noop_get_compiler_options(struct pipe_screen *pscreen, 597 enum pipe_shader_ir ir, 598 enum pipe_shader_type shader) 599{ 600 struct pipe_screen *screen = ((struct noop_pipe_screen*)pscreen)->oscreen; 601 602 return screen->get_compiler_options(screen, ir, shader); 603} 604 605static char *noop_finalize_nir(struct pipe_screen *pscreen, void *nir) 606{ 607 struct pipe_screen *screen = ((struct noop_pipe_screen*)pscreen)->oscreen; 608 609 return screen->finalize_nir(screen, nir); 610} 611 612static bool noop_check_resource_capability(struct pipe_screen *screen, 613 struct pipe_resource *resource, 614 unsigned bind) 615{ 616 return true; 617} 618 619static void noop_create_fence_win32(struct pipe_screen *screen, 620 struct pipe_fence_handle **fence, 621 void *handle, 622 const void *name, 623 enum pipe_fd_type type) 624{ 625 struct noop_pipe_screen *noop_screen = (struct noop_pipe_screen *)screen; 626 struct pipe_screen *oscreen = noop_screen->oscreen; 627 oscreen->create_fence_win32(oscreen, fence, handle, name, type); 628} 629 630static void noop_set_max_shader_compiler_threads(struct pipe_screen *screen, 631 unsigned max_threads) 632{ 633} 634 635static bool noop_is_parallel_shader_compilation_finished(struct pipe_screen *screen, 636 void *shader, 637 unsigned shader_type) 638{ 639 return true; 640} 641 642static bool noop_is_dmabuf_modifier_supported(struct pipe_screen *screen, 643 uint64_t modifier, enum pipe_format format, 644 bool *external_only) 645{ 646 struct noop_pipe_screen *noop_screen = (struct noop_pipe_screen*)screen; 647 struct pipe_screen *oscreen = noop_screen->oscreen; 648 649 return oscreen->is_dmabuf_modifier_supported(oscreen, modifier, format, external_only); 650} 651 652static unsigned int noop_get_dmabuf_modifier_planes(struct pipe_screen *screen, 653 uint64_t modifier, 654 enum pipe_format format) 655{ 656 struct noop_pipe_screen *noop_screen = (struct noop_pipe_screen*)screen; 657 struct pipe_screen *oscreen = noop_screen->oscreen; 658 659 return oscreen->get_dmabuf_modifier_planes(oscreen, modifier, format); 660} 661 662static void noop_get_driver_uuid(struct pipe_screen *screen, char *uuid) 663{ 664 struct noop_pipe_screen *noop_screen = (struct noop_pipe_screen*)screen; 665 struct pipe_screen *oscreen = noop_screen->oscreen; 666 667 oscreen->get_driver_uuid(oscreen, uuid); 668} 669 670static void noop_get_device_uuid(struct pipe_screen *screen, char *uuid) 671{ 672 struct noop_pipe_screen *noop_screen = (struct noop_pipe_screen*)screen; 673 struct pipe_screen *oscreen = noop_screen->oscreen; 674 675 oscreen->get_device_uuid(oscreen, uuid); 676} 677 678static void noop_get_device_luid(struct pipe_screen *screen, char *luid) 679{ 680 struct noop_pipe_screen *noop_screen = (struct noop_pipe_screen*)screen; 681 struct pipe_screen *oscreen = noop_screen->oscreen; 682 683 oscreen->get_device_luid(oscreen, luid); 684} 685 686static uint32_t noop_get_device_node_mask(struct pipe_screen *screen) 687{ 688 struct noop_pipe_screen *noop_screen = (struct noop_pipe_screen*)screen; 689 struct pipe_screen *oscreen = noop_screen->oscreen; 690 691 return oscreen->get_device_node_mask(oscreen); 692} 693 694static int noop_get_sparse_texture_virtual_page_size(struct pipe_screen *screen, 695 enum pipe_texture_target target, 696 bool multi_sample, 697 enum pipe_format format, 698 unsigned offset, unsigned size, 699 int *x, int *y, int *z) 700{ 701 struct noop_pipe_screen *noop_screen = (struct noop_pipe_screen*)screen; 702 struct pipe_screen *oscreen = noop_screen->oscreen; 703 704 return oscreen->get_sparse_texture_virtual_page_size(screen, target, multi_sample, 705 format, offset, size, x, y, z); 706} 707 708static void noop_query_dmabuf_modifiers(struct pipe_screen *screen, 709 enum pipe_format format, int max, 710 uint64_t *modifiers, 711 unsigned int *external_only, int *count) 712{ 713 struct noop_pipe_screen *noop_screen = (struct noop_pipe_screen*)screen; 714 struct pipe_screen *oscreen = noop_screen->oscreen; 715 716 oscreen->query_dmabuf_modifiers(oscreen, format, max, modifiers, 717 external_only, count); 718} 719 720static struct pipe_vertex_state * 721noop_create_vertex_state(struct pipe_screen *screen, 722 struct pipe_vertex_buffer *buffer, 723 const struct pipe_vertex_element *elements, 724 unsigned num_elements, 725 struct pipe_resource *indexbuf, 726 uint32_t full_velem_mask) 727{ 728 struct pipe_vertex_state *state = CALLOC_STRUCT(pipe_vertex_state); 729 730 if (!state) 731 return NULL; 732 733 util_init_pipe_vertex_state(screen, buffer, elements, num_elements, indexbuf, 734 full_velem_mask, state); 735 return state; 736} 737 738static void noop_vertex_state_destroy(struct pipe_screen *screen, 739 struct pipe_vertex_state *state) 740{ 741 pipe_vertex_buffer_unreference(&state->input.vbuffer); 742 pipe_resource_reference(&state->input.indexbuf, NULL); 743 FREE(state); 744} 745 746static void noop_set_fence_timeline_value(struct pipe_screen *screen, 747 struct pipe_fence_handle *fence, 748 uint64_t value) 749{ 750 struct noop_pipe_screen *noop_screen = (struct noop_pipe_screen *)screen; 751 struct pipe_screen *oscreen = noop_screen->oscreen; 752 oscreen->set_fence_timeline_value(oscreen, fence, value); 753} 754 755struct pipe_screen *noop_screen_create(struct pipe_screen *oscreen) 756{ 757 struct noop_pipe_screen *noop_screen; 758 struct pipe_screen *screen; 759 760 if (!debug_get_option_noop()) { 761 return oscreen; 762 } 763 764 noop_screen = CALLOC_STRUCT(noop_pipe_screen); 765 if (!noop_screen) { 766 return NULL; 767 } 768 noop_screen->oscreen = oscreen; 769 screen = &noop_screen->pscreen; 770 771 screen->destroy = noop_destroy_screen; 772 screen->get_name = noop_get_name; 773 screen->get_vendor = noop_get_vendor; 774 screen->get_device_vendor = noop_get_device_vendor; 775 screen->get_param = noop_get_param; 776 screen->get_shader_param = noop_get_shader_param; 777 screen->get_compute_param = noop_get_compute_param; 778 screen->get_paramf = noop_get_paramf; 779 screen->is_format_supported = noop_is_format_supported; 780 screen->context_create = noop_create_context; 781 screen->resource_create = noop_resource_create; 782 screen->resource_from_handle = noop_resource_from_handle; 783 screen->resource_get_handle = noop_resource_get_handle; 784 if (oscreen->resource_get_param) 785 screen->resource_get_param = noop_resource_get_param; 786 screen->resource_destroy = noop_resource_destroy; 787 screen->flush_frontbuffer = noop_flush_frontbuffer; 788 screen->get_timestamp = noop_get_timestamp; 789 screen->fence_reference = noop_fence_reference; 790 screen->fence_finish = noop_fence_finish; 791 screen->query_memory_info = noop_query_memory_info; 792 screen->get_disk_shader_cache = noop_get_disk_shader_cache; 793 screen->get_compiler_options = noop_get_compiler_options; 794 screen->finalize_nir = noop_finalize_nir; 795 if (screen->create_fence_win32) 796 screen->create_fence_win32 = noop_create_fence_win32; 797 screen->check_resource_capability = noop_check_resource_capability; 798 screen->set_max_shader_compiler_threads = noop_set_max_shader_compiler_threads; 799 screen->is_parallel_shader_compilation_finished = noop_is_parallel_shader_compilation_finished; 800 screen->is_dmabuf_modifier_supported = noop_is_dmabuf_modifier_supported; 801 screen->get_dmabuf_modifier_planes = noop_get_dmabuf_modifier_planes; 802 screen->get_driver_uuid = noop_get_driver_uuid; 803 screen->get_device_uuid = noop_get_device_uuid; 804 screen->get_device_luid = noop_get_device_luid; 805 screen->get_device_node_mask = noop_get_device_node_mask; 806 screen->query_dmabuf_modifiers = noop_query_dmabuf_modifiers; 807 screen->resource_create_with_modifiers = noop_resource_create_with_modifiers; 808 screen->create_vertex_state = noop_create_vertex_state; 809 screen->vertex_state_destroy = noop_vertex_state_destroy; 810 if (oscreen->get_sparse_texture_virtual_page_size) 811 screen->get_sparse_texture_virtual_page_size = noop_get_sparse_texture_virtual_page_size; 812 if (oscreen->set_fence_timeline_value) 813 screen->set_fence_timeline_value = noop_set_fence_timeline_value; 814 815 slab_create_parent(&noop_screen->pool_transfers, 816 sizeof(struct pipe_transfer), 64); 817 818 return screen; 819} 820