Path: blob/21.2-virgl/src/gallium/drivers/d3d12/d3d12_root_signature.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_root_signature.h"24#include "d3d12_compiler.h"25#include "d3d12_screen.h"2627#include "util/u_memory.h"2829#include <dxguids/dxguids.h>3031#include <wrl/client.h>32using Microsoft::WRL::ComPtr;3334struct d3d12_root_signature {35struct d3d12_root_signature_key key;36ID3D12RootSignature *sig;37};3839static D3D12_SHADER_VISIBILITY40get_shader_visibility(enum pipe_shader_type stage)41{42switch (stage) {43case PIPE_SHADER_VERTEX:44return D3D12_SHADER_VISIBILITY_VERTEX;45case PIPE_SHADER_FRAGMENT:46return D3D12_SHADER_VISIBILITY_PIXEL;47case PIPE_SHADER_GEOMETRY:48return D3D12_SHADER_VISIBILITY_GEOMETRY;49case PIPE_SHADER_TESS_CTRL:50return D3D12_SHADER_VISIBILITY_HULL;51case PIPE_SHADER_TESS_EVAL:52return D3D12_SHADER_VISIBILITY_DOMAIN;53default:54unreachable("unknown shader stage");55}56}5758static inline void59init_constant_root_param(D3D12_ROOT_PARAMETER1 *param,60unsigned reg,61unsigned size,62D3D12_SHADER_VISIBILITY visibility)63{64param->ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;65param->ShaderVisibility = visibility;66param->Constants.RegisterSpace = 0;67param->Constants.ShaderRegister = reg;68param->Constants.Num32BitValues = size;69}7071static inline void72init_range_root_param(D3D12_ROOT_PARAMETER1 *param,73D3D12_DESCRIPTOR_RANGE1 *range,74D3D12_DESCRIPTOR_RANGE_TYPE type,75uint32_t num_descs,76D3D12_SHADER_VISIBILITY visibility,77uint32_t base_shader_register)78{79range->RangeType = type;80range->NumDescriptors = num_descs;81range->BaseShaderRegister = base_shader_register;82range->RegisterSpace = 0;83if (type == D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER)84range->Flags = D3D12_DESCRIPTOR_RANGE_FLAG_NONE;85else86range->Flags = D3D12_DESCRIPTOR_RANGE_FLAG_DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS;87range->OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;8889param->ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;90param->DescriptorTable.NumDescriptorRanges = 1;91param->DescriptorTable.pDescriptorRanges = range;92param->ShaderVisibility = visibility;93}9495static ID3D12RootSignature *96create_root_signature(struct d3d12_context *ctx, struct d3d12_root_signature_key *key)97{98struct d3d12_screen *screen = d3d12_screen(ctx->base.screen);99D3D12_ROOT_PARAMETER1 root_params[D3D12_GFX_SHADER_STAGES * D3D12_NUM_BINDING_TYPES];100D3D12_DESCRIPTOR_RANGE1 desc_ranges[D3D12_GFX_SHADER_STAGES * D3D12_NUM_BINDING_TYPES];101unsigned num_params = 0;102103for (unsigned i = 0; i < D3D12_GFX_SHADER_STAGES; ++i) {104D3D12_SHADER_VISIBILITY visibility = get_shader_visibility((enum pipe_shader_type)i);105106if (key->stages[i].num_cb_bindings > 0) {107assert(num_params < PIPE_SHADER_TYPES * D3D12_NUM_BINDING_TYPES);108init_range_root_param(&root_params[num_params],109&desc_ranges[num_params],110D3D12_DESCRIPTOR_RANGE_TYPE_CBV,111key->stages[i].num_cb_bindings,112visibility,113key->stages[i].has_default_ubo0 ? 0 : 1);114num_params++;115}116117if (key->stages[i].end_srv_binding > 0) {118init_range_root_param(&root_params[num_params],119&desc_ranges[num_params],120D3D12_DESCRIPTOR_RANGE_TYPE_SRV,121key->stages[i].end_srv_binding - key->stages[i].begin_srv_binding,122visibility,123key->stages[i].begin_srv_binding);124num_params++;125}126127if (key->stages[i].end_srv_binding > 0) {128init_range_root_param(&root_params[num_params],129&desc_ranges[num_params],130D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER,131key->stages[i].end_srv_binding - key->stages[i].begin_srv_binding,132visibility,133key->stages[i].begin_srv_binding);134num_params++;135}136137if (key->stages[i].state_vars_size > 0) {138init_constant_root_param(&root_params[num_params],139key->stages[i].num_cb_bindings + (key->stages[i].has_default_ubo0 ? 0 : 1),140key->stages[i].state_vars_size,141visibility);142num_params++;143}144}145146D3D12_VERSIONED_ROOT_SIGNATURE_DESC root_sig_desc;147root_sig_desc.Version = D3D_ROOT_SIGNATURE_VERSION_1_1;148root_sig_desc.Desc_1_1.NumParameters = num_params;149root_sig_desc.Desc_1_1.pParameters = (num_params > 0) ? root_params : NULL;150root_sig_desc.Desc_1_1.NumStaticSamplers = 0;151root_sig_desc.Desc_1_1.pStaticSamplers = NULL;152root_sig_desc.Desc_1_1.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;153154/* TODO Only enable this flag when needed (optimization) */155root_sig_desc.Desc_1_1.Flags |= D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT;156157if (key->has_stream_output)158root_sig_desc.Desc_1_1.Flags |= D3D12_ROOT_SIGNATURE_FLAG_ALLOW_STREAM_OUTPUT;159160ComPtr<ID3DBlob> sig, error;161if (FAILED(ctx->D3D12SerializeVersionedRootSignature(&root_sig_desc,162&sig, &error))) {163debug_printf("D3D12SerializeRootSignature failed\n");164return NULL;165}166167ID3D12RootSignature *ret;168if (FAILED(screen->dev->CreateRootSignature(0,169sig->GetBufferPointer(),170sig->GetBufferSize(),171IID_PPV_ARGS(&ret)))) {172debug_printf("CreateRootSignature failed\n");173return NULL;174}175return ret;176}177178static void179fill_key(struct d3d12_context *ctx, struct d3d12_root_signature_key *key)180{181memset(key, 0, sizeof(struct d3d12_root_signature_key));182183for (unsigned i = 0; i < D3D12_GFX_SHADER_STAGES; ++i) {184struct d3d12_shader *shader = ctx->gfx_pipeline_state.stages[i];185186if (shader) {187key->stages[i].num_cb_bindings = shader->num_cb_bindings;188key->stages[i].end_srv_binding = shader->end_srv_binding;189key->stages[i].begin_srv_binding = shader->begin_srv_binding;190key->stages[i].state_vars_size = shader->state_vars_size;191key->stages[i].has_default_ubo0 = shader->has_default_ubo0;192193if (ctx->gfx_stages[i]->so_info.num_outputs > 0)194key->has_stream_output = true;195}196}197}198199ID3D12RootSignature *200d3d12_get_root_signature(struct d3d12_context *ctx)201{202struct d3d12_root_signature_key key;203204fill_key(ctx, &key);205struct hash_entry *entry = _mesa_hash_table_search(ctx->root_signature_cache, &key);206if (!entry) {207struct d3d12_root_signature *data =208(struct d3d12_root_signature *)MALLOC(sizeof(struct d3d12_root_signature));209if (!data)210return NULL;211212data->key = key;213data->sig = create_root_signature(ctx, &key);214if (!data->sig) {215FREE(data);216return NULL;217}218219entry = _mesa_hash_table_insert(ctx->root_signature_cache, &data->key, data);220assert(entry);221}222223return ((struct d3d12_root_signature *)entry->data)->sig;224}225226static uint32_t227hash_root_signature_key(const void *key)228{229return _mesa_hash_data(key, sizeof(struct d3d12_root_signature_key));230}231232static bool233equals_root_signature_key(const void *a, const void *b)234{235return memcmp(a, b, sizeof(struct d3d12_root_signature_key)) == 0;236}237238void239d3d12_root_signature_cache_init(struct d3d12_context *ctx)240{241ctx->root_signature_cache = _mesa_hash_table_create(NULL,242hash_root_signature_key,243equals_root_signature_key);244}245246static void247delete_entry(struct hash_entry *entry)248{249struct d3d12_root_signature *data = (struct d3d12_root_signature *)entry->data;250data->sig->Release();251FREE(data);252}253254void255d3d12_root_signature_cache_destroy(struct d3d12_context *ctx)256{257_mesa_hash_table_destroy(ctx->root_signature_cache, delete_entry);258}259260261