Path: blob/21.2-virgl/src/gallium/drivers/d3d12/d3d12_batch.cpp
4570 views
/*1* Copyright © Microsoft Corporation2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING19* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS20* IN THE SOFTWARE.21*/2223#include "d3d12_batch.h"24#include "d3d12_context.h"25#include "d3d12_fence.h"26#include "d3d12_query.h"27#include "d3d12_resource.h"28#include "d3d12_screen.h"29#include "d3d12_surface.h"3031#include "util/hash_table.h"32#include "util/set.h"33#include "util/u_inlines.h"3435#include <dxguids/dxguids.h>3637bool38d3d12_init_batch(struct d3d12_context *ctx, struct d3d12_batch *batch)39{40struct d3d12_screen *screen = d3d12_screen(ctx->base.screen);4142batch->bos = _mesa_set_create(NULL, _mesa_hash_pointer,43_mesa_key_pointer_equal);44batch->sampler_views = _mesa_set_create(NULL, _mesa_hash_pointer,45_mesa_key_pointer_equal);46batch->surfaces = _mesa_set_create(NULL, _mesa_hash_pointer,47_mesa_key_pointer_equal);48batch->objects = _mesa_set_create(NULL,49_mesa_hash_pointer,50_mesa_key_pointer_equal);5152if (!batch->bos || !batch->sampler_views || !batch->surfaces || !batch->objects)53return false;5455util_dynarray_init(&batch->zombie_samplers, NULL);5657if (FAILED(screen->dev->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT,58IID_PPV_ARGS(&batch->cmdalloc))))59return false;606162batch->sampler_heap =63d3d12_descriptor_heap_new(screen->dev,64D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER,65D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE,66128);6768batch->view_heap =69d3d12_descriptor_heap_new(screen->dev,70D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,71D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE,721024);7374if (!batch->sampler_heap && !batch->view_heap)75return false;7677return true;78}7980static void81delete_bo(set_entry *entry)82{83struct d3d12_bo *bo = (struct d3d12_bo *)entry->key;84d3d12_bo_unreference(bo);85}8687static void88delete_sampler_view(set_entry *entry)89{90struct pipe_sampler_view *pres = (struct pipe_sampler_view *)entry->key;91pipe_sampler_view_reference(&pres, NULL);92}9394static void95delete_surface(set_entry *entry)96{97struct pipe_surface *surf = (struct pipe_surface *)entry->key;98pipe_surface_reference(&surf, NULL);99}100101static void102delete_object(set_entry *entry)103{104ID3D12Object *object = (ID3D12Object *)entry->key;105object->Release();106}107108bool109d3d12_reset_batch(struct d3d12_context *ctx, struct d3d12_batch *batch, uint64_t timeout_ns)110{111// batch hasn't been submitted before112if (!batch->fence && !batch->has_errors)113return true;114115if (batch->fence) {116if (!d3d12_fence_finish(batch->fence, timeout_ns))117return false;118d3d12_fence_reference(&batch->fence, NULL);119}120121_mesa_set_clear(batch->bos, delete_bo);122_mesa_set_clear(batch->sampler_views, delete_sampler_view);123_mesa_set_clear(batch->surfaces, delete_surface);124_mesa_set_clear(batch->objects, delete_object);125126util_dynarray_foreach(&batch->zombie_samplers, d3d12_descriptor_handle, handle)127d3d12_descriptor_handle_free(handle);128util_dynarray_clear(&batch->zombie_samplers);129130d3d12_descriptor_heap_clear(batch->view_heap);131d3d12_descriptor_heap_clear(batch->sampler_heap);132133if (FAILED(batch->cmdalloc->Reset())) {134debug_printf("D3D12: resetting ID3D12CommandAllocator failed\n");135return false;136}137batch->has_errors = false;138return true;139}140141void142d3d12_destroy_batch(struct d3d12_context *ctx, struct d3d12_batch *batch)143{144d3d12_reset_batch(ctx, batch, PIPE_TIMEOUT_INFINITE);145batch->cmdalloc->Release();146d3d12_descriptor_heap_free(batch->sampler_heap);147d3d12_descriptor_heap_free(batch->view_heap);148_mesa_set_destroy(batch->bos, NULL);149_mesa_set_destroy(batch->sampler_views, NULL);150_mesa_set_destroy(batch->surfaces, NULL);151_mesa_set_destroy(batch->objects, NULL);152util_dynarray_fini(&batch->zombie_samplers);153}154155void156d3d12_start_batch(struct d3d12_context *ctx, struct d3d12_batch *batch)157{158struct d3d12_screen *screen = d3d12_screen(ctx->base.screen);159ID3D12DescriptorHeap* heaps[2] = { d3d12_descriptor_heap_get(batch->view_heap),160d3d12_descriptor_heap_get(batch->sampler_heap) };161162d3d12_reset_batch(ctx, batch, PIPE_TIMEOUT_INFINITE);163164/* Create or reset global command list */165if (ctx->cmdlist) {166if (FAILED(ctx->cmdlist->Reset(batch->cmdalloc, NULL))) {167debug_printf("D3D12: resetting ID3D12GraphicsCommandList failed\n");168batch->has_errors = true;169return;170}171} else {172if (FAILED(screen->dev->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT,173batch->cmdalloc, NULL,174IID_PPV_ARGS(&ctx->cmdlist)))) {175debug_printf("D3D12: creating ID3D12GraphicsCommandList failed\n");176batch->has_errors = true;177return;178}179}180181ctx->cmdlist->SetDescriptorHeaps(2, heaps);182ctx->cmdlist_dirty = ~0;183for (int i = 0; i < D3D12_GFX_SHADER_STAGES; ++i)184ctx->shader_dirty[i] = ~0;185186if (!ctx->queries_disabled)187d3d12_resume_queries(ctx);188}189190void191d3d12_end_batch(struct d3d12_context *ctx, struct d3d12_batch *batch)192{193struct d3d12_screen *screen = d3d12_screen(ctx->base.screen);194195if (!ctx->queries_disabled)196d3d12_suspend_queries(ctx);197198if (FAILED(ctx->cmdlist->Close())) {199debug_printf("D3D12: closing ID3D12GraphicsCommandList failed\n");200batch->has_errors = true;201return;202}203204ID3D12CommandList* cmdlists[] = { ctx->cmdlist };205screen->cmdqueue->ExecuteCommandLists(1, cmdlists);206batch->fence = d3d12_create_fence(screen, ctx);207}208209bool210d3d12_batch_has_references(struct d3d12_batch *batch,211struct d3d12_bo *bo)212{213return (_mesa_set_search(batch->bos, bo) != NULL);214}215216void217d3d12_batch_reference_resource(struct d3d12_batch *batch,218struct d3d12_resource *res)219{220bool found = false;221_mesa_set_search_and_add(batch->bos, res->bo, &found);222if (!found)223d3d12_bo_reference(res->bo);224}225226void227d3d12_batch_reference_sampler_view(struct d3d12_batch *batch,228struct d3d12_sampler_view *sv)229{230struct set_entry *entry = _mesa_set_search(batch->sampler_views, sv);231if (!entry) {232entry = _mesa_set_add(batch->sampler_views, sv);233pipe_reference(NULL, &sv->base.reference);234}235}236237void238d3d12_batch_reference_surface_texture(struct d3d12_batch *batch,239struct d3d12_surface *surf)240{241d3d12_batch_reference_resource(batch, d3d12_resource(surf->base.texture));242}243244void245d3d12_batch_reference_object(struct d3d12_batch *batch,246ID3D12Object *object)247{248struct set_entry *entry = _mesa_set_search(batch->objects, object);249if (!entry) {250entry = _mesa_set_add(batch->objects, object);251object->AddRef();252}253}254255256