/**************************************************************************/ /* rendering_shader_container_d3d12.h */ /**************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /**************************************************************************/ /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ /* "Software"), to deal in the Software without restriction, including */ /* without limitation the rights to use, copy, modify, merge, publish, */ /* distribute, sublicense, and/or sell copies of the Software, and to */ /* permit persons to whom the Software is furnished to do so, subject to */ /* the following conditions: */ /* */ /* The above copyright notice and this permission notice shall be */ /* included in all copies or substantial portions of the Software. */ /* */ /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ #pragma once #include "servers/rendering/rendering_shader_container.h" #define NIR_ENABLED 1 #ifdef SHADER_BAKER_RUNTIME_ENABLED #undef NIR_ENABLED #endif #include "d3d12_godot_nir_bridge.h" #define D3D12_BITCODE_OFFSETS_NUM_STAGES 3 #if NIR_ENABLED struct nir_shader; struct nir_shader_compiler_options; #endif enum RootSignatureLocationType { RS_LOC_TYPE_RESOURCE, RS_LOC_TYPE_SAMPLER, }; enum ResourceClass { RES_CLASS_INVALID, RES_CLASS_CBV, RES_CLASS_SRV, RES_CLASS_UAV, }; struct RenderingDXIL { static uint32_t patch_specialization_constant( RenderingDeviceCommons::PipelineSpecializationConstantType p_type, const void *p_value, const uint64_t (&p_stages_bit_offsets)[D3D12_BITCODE_OFFSETS_NUM_STAGES], HashMap> &r_stages_bytecodes, bool p_is_first_patch); static void sign_bytecode(RenderingDeviceCommons::ShaderStage p_stage, Vector &r_dxil_blob); }; class RenderingShaderContainerD3D12 : public RenderingShaderContainer { GDSOFTCLASS(RenderingShaderContainerD3D12, RenderingShaderContainer); public: static constexpr uint32_t REQUIRED_SHADER_MODEL = 0x62; // D3D_SHADER_MODEL_6_2 static constexpr uint32_t ROOT_CONSTANT_REGISTER = GODOT_NIR_DESCRIPTOR_SET_MULTIPLIER * (RenderingDeviceCommons::MAX_UNIFORM_SETS + 1); static constexpr uint32_t RUNTIME_DATA_REGISTER = GODOT_NIR_DESCRIPTOR_SET_MULTIPLIER * (RenderingDeviceCommons::MAX_UNIFORM_SETS + 2); static constexpr uint32_t FORMAT_VERSION = 1; static constexpr uint32_t SHADER_STAGES_BIT_OFFSET_INDICES[RenderingDeviceCommons::SHADER_STAGE_MAX] = { 0, // SHADER_STAGE_VERTEX 1, // SHADER_STAGE_FRAGMENT UINT32_MAX, // SHADER_STAGE_TESSELATION_CONTROL UINT32_MAX, // SHADER_STAGE_TESSELATION_EVALUATION 2, // SHADER_STAGE_COMPUTE }; struct RootSignatureLocation { uint32_t root_param_index = UINT32_MAX; uint32_t range_index = UINT32_MAX; }; struct ReflectionBindingDataD3D12 { uint32_t resource_class = 0; uint32_t has_sampler = 0; uint32_t dxil_stages = 0; RootSignatureLocation root_signature_locations[2]; }; struct ReflectionSpecializationDataD3D12 { uint64_t stages_bit_offsets[D3D12_BITCODE_OFFSETS_NUM_STAGES] = {}; }; protected: struct ReflectionDataD3D12 { uint32_t spirv_specialization_constants_ids_mask = 0; uint32_t dxil_push_constant_stages = 0; uint32_t nir_runtime_data_root_param_idx = 0; }; struct ContainerFooterD3D12 { uint32_t root_signature_length = 0; uint32_t root_signature_crc = 0; }; void *lib_d3d12 = nullptr; ReflectionDataD3D12 reflection_data_d3d12; Vector reflection_binding_set_uniforms_data_d3d12; Vector reflection_specialization_data_d3d12; Vector root_signature_bytes; uint32_t root_signature_crc = 0; #if NIR_ENABLED bool _convert_spirv_to_nir(const Vector &p_spirv, const nir_shader_compiler_options *p_compiler_options, HashMap &r_stages_nir_shaders, Vector &r_stages, BitField &r_stages_processed); bool _convert_nir_to_dxil(const HashMap &p_stages_nir_shaders, BitField p_stages_processed, HashMap> &r_dxil_blobs); bool _convert_spirv_to_dxil(const Vector &p_spirv, HashMap> &r_dxil_blobs, Vector &r_stages, BitField &r_stages_processed); bool _generate_root_signature(BitField p_stages_processed); // GodotNirCallbacks. static void _nir_report_resource(uint32_t p_register, uint32_t p_space, uint32_t p_dxil_type, void *p_data); static void _nir_report_sc_bit_offset(uint32_t p_sc_id, uint64_t p_bit_offset, void *p_data); static void _nir_report_bitcode_bit_offset(uint64_t p_bit_offset, void *p_data); #endif // RenderingShaderContainer overrides. virtual uint32_t _format() const override; virtual uint32_t _format_version() const override; virtual uint32_t _from_bytes_reflection_extra_data(const uint8_t *p_bytes) override; virtual uint32_t _from_bytes_reflection_binding_uniform_extra_data_start(const uint8_t *p_bytes) override; virtual uint32_t _from_bytes_reflection_binding_uniform_extra_data(const uint8_t *p_bytes, uint32_t p_index) override; virtual uint32_t _from_bytes_reflection_specialization_extra_data_start(const uint8_t *p_bytes) override; virtual uint32_t _from_bytes_reflection_specialization_extra_data(const uint8_t *p_bytes, uint32_t p_index) override; virtual uint32_t _from_bytes_footer_extra_data(const uint8_t *p_bytes) override; virtual uint32_t _to_bytes_reflection_extra_data(uint8_t *p_bytes) const override; virtual uint32_t _to_bytes_reflection_binding_uniform_extra_data(uint8_t *p_bytes, uint32_t p_index) const override; virtual uint32_t _to_bytes_reflection_specialization_extra_data(uint8_t *p_bytes, uint32_t p_index) const override; virtual uint32_t _to_bytes_footer_extra_data(uint8_t *p_bytes) const override; virtual void _set_from_shader_reflection_post(const String &p_shader_name, const RenderingDeviceCommons::ShaderReflection &p_reflection) override; virtual bool _set_code_from_spirv(const Vector &p_spirv) override; public: struct ShaderReflectionD3D12 { uint32_t spirv_specialization_constants_ids_mask = 0; uint32_t dxil_push_constant_stages = 0; uint32_t nir_runtime_data_root_param_idx = 0; Vector> reflection_binding_set_uniforms_d3d12; Vector reflection_specialization_data_d3d12; Vector root_signature_bytes; uint32_t root_signature_crc = 0; }; RenderingShaderContainerD3D12(); RenderingShaderContainerD3D12(void *p_lib_d3d12); ShaderReflectionD3D12 get_shader_reflection_d3d12() const; }; class RenderingShaderContainerFormatD3D12 : public RenderingShaderContainerFormat { protected: void *lib_d3d12 = nullptr; public: void set_lib_d3d12(void *p_lib_d3d12); virtual Ref create_container() const override; virtual ShaderLanguageVersion get_shader_language_version() const override; virtual ShaderSpirvVersion get_shader_spirv_version() const override; RenderingShaderContainerFormatD3D12(); virtual ~RenderingShaderContainerFormatD3D12(); };