diff --git a/Source/Engine/Graphics/Shaders/GPUShader.cpp b/Source/Engine/Graphics/Shaders/GPUShader.cpp index 82983b1b9..8ede61fc6 100644 --- a/Source/Engine/Graphics/Shaders/GPUShader.cpp +++ b/Source/Engine/Graphics/Shaders/GPUShader.cpp @@ -177,22 +177,28 @@ GPUShaderProgram* GPUShader::GetShader(ShaderStage stage, const StringAnsiView& return shader; } -GPUVertexLayout* GPUShader::ReadVertexLayout(MemoryReadStream& stream) +void GPUShader::ReadVertexLayout(MemoryReadStream& stream, GPUVertexLayout*& inputLayout, GPUVertexLayout*& vertexLayout) { + inputLayout = vertexLayout = nullptr; + + // Read input layout (based on shader reflection) + GPUVertexLayout::Elements elements; + stream.Read(elements); + inputLayout = GPUVertexLayout::Get(elements); + // [Deprecated in v1.10] byte inputLayoutSize; stream.ReadByte(&inputLayoutSize); if (inputLayoutSize == 0) - return nullptr; + return; void* elementsData = stream.Move(sizeof(VertexElement) * inputLayoutSize); if (inputLayoutSize > GPU_MAX_VS_ELEMENTS) { LOG(Error, "Incorrect input layout size."); - return nullptr; + return; } - GPUVertexLayout::Elements elements; elements.Set((VertexElement*)elementsData, inputLayoutSize); - return GPUVertexLayout::Get(elements); + vertexLayout = GPUVertexLayout::Get(elements); } GPUResourceType GPUShader::GetResourceType() const diff --git a/Source/Engine/Graphics/Shaders/GPUShader.h b/Source/Engine/Graphics/Shaders/GPUShader.h index 6879c3d5b..97bc6fabf 100644 --- a/Source/Engine/Graphics/Shaders/GPUShader.h +++ b/Source/Engine/Graphics/Shaders/GPUShader.h @@ -12,7 +12,7 @@ class GPUShaderProgram; /// /// The runtime version of the shaders cache supported by the all graphics back-ends. The same for all the shader cache formats (easier to sync and validate). /// -#define GPU_SHADER_CACHE_VERSION 11 +#define GPU_SHADER_CACHE_VERSION 12 /// /// The GPU resource with shader programs that can run on the GPU and are able to perform rendering calculation using textures, vertices and other resources. @@ -135,7 +135,7 @@ public: protected: GPUShaderProgram* GetShader(ShaderStage stage, const StringAnsiView& name, int32 permutationIndex) const; virtual GPUShaderProgram* CreateGPUShaderProgram(ShaderStage type, const GPUShaderProgramInitializer& initializer, Span bytecode, MemoryReadStream& stream) = 0; - static GPUVertexLayout* ReadVertexLayout(MemoryReadStream& stream); + static void ReadVertexLayout(MemoryReadStream& stream, GPUVertexLayout*& inputLayout, GPUVertexLayout*& vertexLayout); public: // [GPUResource] diff --git a/Source/Engine/Graphics/Shaders/GPUShaderProgram.h b/Source/Engine/Graphics/Shaders/GPUShaderProgram.h index aa8368ea0..4ae6bd63f 100644 --- a/Source/Engine/Graphics/Shaders/GPUShaderProgram.h +++ b/Source/Engine/Graphics/Shaders/GPUShaderProgram.h @@ -136,6 +136,9 @@ public: // [Deprecated in v1.10] GPUVertexLayout* Layout = nullptr; + // Vertex shader inputs layout. Used to ensure that binded vertex buffers provide all required elements. + GPUVertexLayout* InputLayout = nullptr; + public: // [GPUShaderProgram] ShaderStage GetStage() const override diff --git a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUShaderDX11.cpp b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUShaderDX11.cpp index 7bb23de41..4251b3a55 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUShaderDX11.cpp +++ b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUShaderDX11.cpp @@ -26,7 +26,7 @@ ID3D11InputLayout* GPUShaderProgramVSDX11::GetInputLayout(GPUVertexLayoutDX11* v { if (vertexLayout && vertexLayout->InputElementsCount) { - auto mergedVertexLayout = (GPUVertexLayoutDX11*)GPUVertexLayout::Merge(vertexLayout, Layout); + auto mergedVertexLayout = (GPUVertexLayoutDX11*)GPUVertexLayout::Merge(vertexLayout, Layout ? Layout : InputLayout); LOG_DIRECTX_RESULT(vertexLayout->GetDevice()->GetDevice()->CreateInputLayout(mergedVertexLayout->InputElements, mergedVertexLayout->InputElementsCount, Bytecode.Get(), Bytecode.Length(), &inputLayout)); } _cache.Add(vertexLayout, inputLayout); @@ -42,42 +42,30 @@ GPUShaderProgram* GPUShaderDX11::CreateGPUShaderProgram(ShaderStage type, const { case ShaderStage::Vertex: { - // Load Input Layout - GPUVertexLayout* vertexLayout = ReadVertexLayout(stream); - - // Create shader + GPUVertexLayout* inputLayout, *vertexLayout; + ReadVertexLayout(stream, inputLayout, vertexLayout); ID3D11VertexShader* buffer = nullptr; result = _device->GetDevice()->CreateVertexShader(bytecode.Get(), bytecode.Length(), nullptr, &buffer); LOG_DIRECTX_RESULT_WITH_RETURN(result, nullptr); - - // Create object - shader = New(initializer, buffer, vertexLayout, bytecode); + shader = New(initializer, buffer, inputLayout, vertexLayout, bytecode); break; } #if GPU_ALLOW_TESSELLATION_SHADERS case ShaderStage::Hull: { - // Read control points int32 controlPointsCount; stream.ReadInt32(&controlPointsCount); - - // Create shader ID3D11HullShader* buffer = nullptr; result = _device->GetDevice()->CreateHullShader(bytecode.Get(), bytecode.Length(), nullptr, &buffer); LOG_DIRECTX_RESULT_WITH_RETURN(result, nullptr); - - // Create object shader = New(initializer, buffer, controlPointsCount); break; } case ShaderStage::Domain: { - // Create shader ID3D11DomainShader* buffer = nullptr; result = _device->GetDevice()->CreateDomainShader(bytecode.Get(), bytecode.Length(), nullptr, &buffer); LOG_DIRECTX_RESULT_WITH_RETURN(result, nullptr); - - // Create object shader = New(initializer, buffer); break; } @@ -92,35 +80,26 @@ GPUShaderProgram* GPUShaderDX11::CreateGPUShaderProgram(ShaderStage type, const #if GPU_ALLOW_GEOMETRY_SHADERS case ShaderStage::Geometry: { - // Create shader ID3D11GeometryShader* buffer = nullptr; result = _device->GetDevice()->CreateGeometryShader(bytecode.Get(), bytecode.Length(), nullptr, &buffer); LOG_DIRECTX_RESULT_WITH_RETURN(result, nullptr); - - // Create object shader = New(initializer, buffer); break; } #endif case ShaderStage::Pixel: { - // Create shader ID3D11PixelShader* buffer = nullptr; result = _device->GetDevice()->CreatePixelShader(bytecode.Get(), bytecode.Length(), nullptr, &buffer); LOG_DIRECTX_RESULT_WITH_RETURN(result, nullptr); - - // Create object shader = New(initializer, buffer); break; } case ShaderStage::Compute: { - // Create shader ID3D11ComputeShader* buffer = nullptr; result = _device->GetDevice()->CreateComputeShader(bytecode.Get(), bytecode.Length(), nullptr, &buffer); LOG_DIRECTX_RESULT_WITH_RETURN(result, nullptr); - - // Create object shader = New(initializer, buffer); break; } diff --git a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUShaderProgramDX11.h b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUShaderProgramDX11.h index d43e60b2d..6c87c1d0a 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUShaderProgramDX11.h +++ b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUShaderProgramDX11.h @@ -58,9 +58,10 @@ private: Dictionary _cache; public: - GPUShaderProgramVSDX11(const GPUShaderProgramInitializer& initializer, ID3D11VertexShader* buffer, GPUVertexLayout* vertexLayout, Span bytecode) + GPUShaderProgramVSDX11(const GPUShaderProgramInitializer& initializer, ID3D11VertexShader* buffer, GPUVertexLayout* inputLayout, GPUVertexLayout* vertexLayout, Span bytecode) : GPUShaderProgramDX11(initializer, buffer) { + InputLayout = inputLayout; Layout = vertexLayout; Bytecode.Copy(bytecode); } diff --git a/Source/Engine/GraphicsDevice/DirectX/DX12/DescriptorHeapDX12.cpp b/Source/Engine/GraphicsDevice/DirectX/DX12/DescriptorHeapDX12.cpp index 931def028..98e1630f9 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX12/DescriptorHeapDX12.cpp +++ b/Source/Engine/GraphicsDevice/DirectX/DX12/DescriptorHeapDX12.cpp @@ -124,7 +124,7 @@ void DescriptorHeapWithSlotsDX12::ReleaseSlot(uint32 index) { uint32& value = _usage[index / 32]; const uint32 mask = 1 << (index & 31); - ASSERT_LOW_LAYER((value & mask) == mask); + //ASSERT_LOW_LAYER((value & mask) == mask); value &= ~mask; } diff --git a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUPipelineStateDX12.cpp b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUPipelineStateDX12.cpp index 7653992ce..c68fda240 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUPipelineStateDX12.cpp +++ b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUPipelineStateDX12.cpp @@ -180,7 +180,7 @@ bool GPUPipelineStateDX12::Init(const Description& desc) INIT_SHADER_STAGE(PS, GPUShaderProgramPSDX12); // Input Assembly - VertexLayout = desc.VS ? (GPUVertexLayoutDX12*)desc.VS->Layout : nullptr; + VertexLayout = desc.VS ? (GPUVertexLayoutDX12*)(desc.VS->Layout ? desc.VS->Layout : desc.VS->InputLayout) : nullptr; const D3D12_PRIMITIVE_TOPOLOGY_TYPE primTypes1[] = { D3D12_PRIMITIVE_TOPOLOGY_TYPE_UNDEFINED, diff --git a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUShaderDX12.cpp b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUShaderDX12.cpp index 0fe07a466..a088a7840 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUShaderDX12.cpp +++ b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUShaderDX12.cpp @@ -19,8 +19,9 @@ GPUShaderProgram* GPUShaderDX12::CreateGPUShaderProgram(ShaderStage type, const { case ShaderStage::Vertex: { - GPUVertexLayout* vertexLayout = ReadVertexLayout(stream); - shader = New(initializer, header, bytecode, vertexLayout); + GPUVertexLayout* inputLayout, *vertexLayout; + ReadVertexLayout(stream, inputLayout, vertexLayout); + shader = New(initializer, header, bytecode, inputLayout, vertexLayout); break; } #if GPU_ALLOW_TESSELLATION_SHADERS diff --git a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUShaderProgramDX12.h b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUShaderProgramDX12.h index 01e21c4f2..48639abb4 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUShaderProgramDX12.h +++ b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUShaderProgramDX12.h @@ -46,9 +46,10 @@ public: class GPUShaderProgramVSDX12 : public GPUShaderProgramDX12 { public: - GPUShaderProgramVSDX12(const GPUShaderProgramInitializer& initializer, const DxShaderHeader* header, Span bytecode, GPUVertexLayout* vertexLayout) + GPUShaderProgramVSDX12(const GPUShaderProgramInitializer& initializer, const DxShaderHeader* header, Span bytecode, GPUVertexLayout* inputLayout, GPUVertexLayout* vertexLayout) : GPUShaderProgramDX12(initializer, header, bytecode) { + InputLayout = inputLayout; Layout = vertexLayout; } }; diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUPipelineStateVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/GPUPipelineStateVulkan.cpp index 7f3896038..32b34e4f6 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUPipelineStateVulkan.cpp +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUPipelineStateVulkan.cpp @@ -320,7 +320,7 @@ bool GPUPipelineStateVulkan::Init(const Description& desc) _desc.pStages = _shaderStages; // Input Assembly - VertexShaderLayout = desc.VS ? (GPUVertexLayoutVulkan*)desc.VS->Layout : nullptr; + VertexShaderLayout = desc.VS ? (GPUVertexLayoutVulkan*)(desc.VS->Layout ? desc.VS->Layout : desc.VS->InputLayout) : nullptr; RenderToolsVulkan::ZeroStruct(_descInputAssembly, VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO);; switch (desc.PrimitiveTopology) { diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUShaderProgramVulkan.h b/Source/Engine/GraphicsDevice/Vulkan/GPUShaderProgramVulkan.h index 9f6391265..79b0023f0 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUShaderProgramVulkan.h +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUShaderProgramVulkan.h @@ -66,9 +66,10 @@ public: class GPUShaderProgramVSVulkan : public GPUShaderProgramVulkan { public: - GPUShaderProgramVSVulkan(GPUDeviceVulkan* device, const GPUShaderProgramInitializer& initializer, const SpirvShaderDescriptorInfo& descriptorInfo, VkShaderModule shaderModule, GPUVertexLayout* vertexLayout) + GPUShaderProgramVSVulkan(GPUDeviceVulkan* device, const GPUShaderProgramInitializer& initializer, const SpirvShaderDescriptorInfo& descriptorInfo, VkShaderModule shaderModule, GPUVertexLayout* inputLayout, GPUVertexLayout* vertexLayout) : GPUShaderProgramVulkan(device, initializer, descriptorInfo, shaderModule) { + InputLayout = inputLayout; Layout = vertexLayout; } }; diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUShaderVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/GPUShaderVulkan.cpp index 9608d5207..b04f07c7d 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUShaderVulkan.cpp +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUShaderVulkan.cpp @@ -138,8 +138,9 @@ GPUShaderProgram* GPUShaderVulkan::CreateGPUShaderProgram(ShaderStage type, cons { case ShaderStage::Vertex: { - GPUVertexLayout* vertexLayout = ReadVertexLayout(stream); - shader = New(_device, initializer, header->DescriptorInfo, shaderModule, vertexLayout); + GPUVertexLayout* inputLayout, *vertexLayout; + ReadVertexLayout(stream, inputLayout, vertexLayout); + shader = New(_device, initializer, header->DescriptorInfo, shaderModule, inputLayout, vertexLayout); break; } #if GPU_ALLOW_TESSELLATION_SHADERS diff --git a/Source/Engine/ShadersCompilation/DirectX/ShaderCompilerD3D.cpp b/Source/Engine/ShadersCompilation/DirectX/ShaderCompilerD3D.cpp index 819e9e745..131d77033 100644 --- a/Source/Engine/ShadersCompilation/DirectX/ShaderCompilerD3D.cpp +++ b/Source/Engine/ShadersCompilation/DirectX/ShaderCompilerD3D.cpp @@ -16,11 +16,9 @@ class IncludeD3D : public ID3DInclude { private: - ShaderCompilationContext* _context; public: - IncludeD3D(ShaderCompilationContext* context) { _context = context; @@ -84,14 +82,9 @@ namespace // Extract constant buffers usage information for (uint32 a = 0; a < desc.ConstantBuffers; a++) { - // Get CB auto cb = reflector->GetConstantBufferByIndex(a); - - // Get CB description D3D11_SHADER_BUFFER_DESC cbDesc; cb->GetDesc(&cbDesc); - - // Check buffer type if (cbDesc.Type == D3D_CT_CBUFFER) { // Find CB slot index @@ -132,22 +125,20 @@ namespace // Extract resources usage for (uint32 i = 0; i < desc.BoundResources; i++) { - // Get resource description D3D11_SHADER_INPUT_BIND_DESC resDesc; reflector->GetResourceBindingDesc(i, &resDesc); - switch (resDesc.Type) { - // Sampler + // Sampler case D3D_SIT_SAMPLER: break; - // Constant Buffer + // Constant Buffer case D3D_SIT_CBUFFER: case D3D_SIT_TBUFFER: break; - // Shader Resource + // Shader Resource case D3D_SIT_TEXTURE: case D3D_SIT_STRUCTURED: case D3D_SIT_BYTEADDRESS: @@ -155,7 +146,7 @@ namespace bindings.UsedSRsMask |= 1 << (resDesc.BindPoint + shift); break; - // Unordered Access + // Unordered Access case D3D_SIT_UAV_RWTYPED: case D3D_SIT_UAV_RWSTRUCTURED: case D3D_SIT_UAV_RWBYTEADDRESS: @@ -212,7 +203,6 @@ bool ShaderCompilerD3D::CompileShader(ShaderFunctionMeta& meta, WritePermutation else { profileName += "_4_0"; - if (type == ShaderStage::Domain || type == ShaderStage::Hull) { _context->OnError("Tessellation is not supported on DirectX 10"); @@ -221,6 +211,7 @@ bool ShaderCompilerD3D::CompileShader(ShaderFunctionMeta& meta, WritePermutation } // Compile all shader function permutations + AdditionalDataVS additionalDataVS; for (int32 permutationIndex = 0; permutationIndex < meta.Permutations.Count(); permutationIndex++) { _macros.Clear(); @@ -253,8 +244,6 @@ bool ShaderCompilerD3D::CompileShader(ShaderFunctionMeta& meta, WritePermutation 0, &shader, &errors); - - // Check compilation result if (FAILED(result)) { const auto msg = static_cast(errors->GetBufferPointer()); @@ -279,24 +268,68 @@ bool ShaderCompilerD3D::CompileShader(ShaderFunctionMeta& meta, WritePermutation reflector->GetDesc(&desc); // Process shader reflection data + void* additionalData = nullptr; + if (type == ShaderStage::Vertex) + { + additionalData = &additionalDataVS; + additionalDataVS.Inputs.Clear(); + for (UINT inputIdx = 0; inputIdx < desc.InputParameters; inputIdx++) + { + D3D11_SIGNATURE_PARAMETER_DESC inputDesc; + reflector->GetInputParameterDesc(inputIdx, &inputDesc); + if (inputDesc.ReadWriteMask == 0 || inputDesc.SystemValueType != D3D10_NAME_UNDEFINED) + continue; + auto format = PixelFormat::Unknown; + switch (inputDesc.ComponentType) + { + case D3D_REGISTER_COMPONENT_UINT32: + if (inputDesc.Mask >= 0b1111) + format = PixelFormat::R32G32B32A32_UInt; + else if (inputDesc.Mask >= 0b111) + format = PixelFormat::R32G32B32_UInt; + else if (inputDesc.Mask >= 0b11) + format = PixelFormat::R32G32_UInt; + else + format = PixelFormat::R32_UInt; + break; + case D3D_REGISTER_COMPONENT_SINT32: + if (inputDesc.Mask >= 0b1111) + format = PixelFormat::R32G32B32A32_SInt; + else if (inputDesc.Mask >= 0b111) + format = PixelFormat::R32G32B32_SInt; + else if (inputDesc.Mask >= 0b11) + format = PixelFormat::R32G32_SInt; + else + format = PixelFormat::R32_SInt; + break; + case D3D_REGISTER_COMPONENT_FLOAT32: + if (inputDesc.Mask >= 0b1111) + format = PixelFormat::R32G32B32A32_Float; + else if (inputDesc.Mask >= 0b111) + format = PixelFormat::R32G32B32_Float; + else if (inputDesc.Mask >= 0b11) + format = PixelFormat::R32G32_Float; + else + format = PixelFormat::R32_Float; + break; + } + additionalDataVS.Inputs.Add({ ParseVertexElementType(inputDesc.SemanticName, inputDesc.SemanticIndex), 0, 0, 0, format }); + } + } ShaderBindings bindings = { desc.InstructionCount, 0, 0, 0 }; if (ProcessShader(_context, _constantBuffers, reflector.Get(), desc, bindings)) return true; #ifdef GPU_USE_SHADERS_DEBUG_LAYER - // Generate debug information if (ProcessDebugInfo(_context, meta, permutationIndex, shaderBuffer, shaderBufferSize)) return true; - #endif // Strip shader bytecode for an optimization ComPtr shaderStripped; if (!options->GenerateDebugData) { - //auto prevShaderBufferSize = shaderBufferSize; - // Strip shader bytes result = D3DStripShader( shaderBuffer, @@ -312,15 +345,12 @@ bool ShaderCompilerD3D::CompileShader(ShaderFunctionMeta& meta, WritePermutation // Set new buffer shaderBuffer = shaderStripped->GetBufferPointer(); shaderBufferSize = static_cast(shaderStripped->GetBufferSize()); - - //auto strippedBytes = prevShaderBufferSize - shaderBufferSize; - //auto strippedBytesPercentage = Math::FloorToInt(strippedBytes * 100.0f / prevShaderBufferSize); } if (WriteShaderFunctionPermutation(_context, meta, permutationIndex, bindings, shaderBuffer, shaderBufferSize)) return true; - if (customDataWrite && customDataWrite(_context, meta, permutationIndex, _macros)) + if (customDataWrite && customDataWrite(_context, meta, permutationIndex, _macros, additionalData)) return true; } diff --git a/Source/Engine/ShadersCompilation/DirectX/ShaderCompilerD3D.h b/Source/Engine/ShadersCompilation/DirectX/ShaderCompilerD3D.h index b78d04a37..b9d8952c5 100644 --- a/Source/Engine/ShadersCompilation/DirectX/ShaderCompilerD3D.h +++ b/Source/Engine/ShadersCompilation/DirectX/ShaderCompilerD3D.h @@ -12,12 +12,10 @@ class ShaderCompilerD3D : public ShaderCompiler { private: - Array _funcNameDefineBuffer; uint32 _flags; public: - /// /// Initializes a new instance of the class. /// @@ -25,7 +23,6 @@ public: ShaderCompilerD3D(ShaderProfile profile); protected: - // [ShaderCompiler] bool CompileShader(ShaderFunctionMeta& meta, WritePermutationData customDataWrite = nullptr) override; bool OnCompileBegin() override; diff --git a/Source/Engine/ShadersCompilation/DirectX/ShaderCompilerDX.cpp b/Source/Engine/ShadersCompilation/DirectX/ShaderCompilerDX.cpp index 9619d0548..c2431c485 100644 --- a/Source/Engine/ShadersCompilation/DirectX/ShaderCompilerDX.cpp +++ b/Source/Engine/ShadersCompilation/DirectX/ShaderCompilerDX.cpp @@ -4,7 +4,6 @@ #include "ShaderCompilerDX.h" #include "Engine/Core/Log.h" -#include "Engine/Threading/Threading.h" #include "Engine/Engine/Globals.h" #include "Engine/Graphics/Config.h" #include "Engine/GraphicsDevice/DirectX/DX12/Types.h" @@ -22,12 +21,10 @@ class IncludeDX : public IDxcIncludeHandler { private: - ShaderCompilationContext* _context; IDxcLibrary* _library; public: - IncludeDX(ShaderCompilationContext* context, IDxcLibrary* library) { _context = context; @@ -185,6 +182,7 @@ bool ShaderCompilerDX::CompileShader(ShaderFunctionMeta& meta, WritePermutationD } // Compile all shader function permutations + AdditionalDataVS additionalDataVS; for (int32 permutationIndex = 0; permutationIndex < meta.Permutations.Count(); permutationIndex++) { _macros.Clear(); @@ -320,6 +318,54 @@ bool ShaderCompilerDX::CompileShader(ShaderFunctionMeta& meta, WritePermutationD shaderReflection->GetDesc(&desc); // Process shader reflection data + void* additionalData = nullptr; + if (type == ShaderStage::Vertex) + { + additionalData = &additionalDataVS; + additionalDataVS.Inputs.Clear(); + for (UINT inputIdx = 0; inputIdx < desc.InputParameters; inputIdx++) + { + D3D12_SIGNATURE_PARAMETER_DESC inputDesc; + shaderReflection->GetInputParameterDesc(inputIdx, &inputDesc); + if (inputDesc.ReadWriteMask == 0 || inputDesc.SystemValueType != D3D10_NAME_UNDEFINED) + continue; + auto format = PixelFormat::Unknown; + switch (inputDesc.ComponentType) + { + case D3D_REGISTER_COMPONENT_UINT32: + if (inputDesc.Mask >= 0b1111) + format = PixelFormat::R32G32B32A32_UInt; + else if (inputDesc.Mask >= 0b111) + format = PixelFormat::R32G32B32_UInt; + else if (inputDesc.Mask >= 0b11) + format = PixelFormat::R32G32_UInt; + else + format = PixelFormat::R32_UInt; + break; + case D3D_REGISTER_COMPONENT_SINT32: + if (inputDesc.Mask >= 0b1111) + format = PixelFormat::R32G32B32A32_SInt; + else if (inputDesc.Mask >= 0b111) + format = PixelFormat::R32G32B32_SInt; + else if (inputDesc.Mask >= 0b11) + format = PixelFormat::R32G32_SInt; + else + format = PixelFormat::R32_SInt; + break; + case D3D_REGISTER_COMPONENT_FLOAT32: + if (inputDesc.Mask >= 0b1111) + format = PixelFormat::R32G32B32A32_Float; + else if (inputDesc.Mask >= 0b111) + format = PixelFormat::R32G32B32_Float; + else if (inputDesc.Mask >= 0b11) + format = PixelFormat::R32G32_Float; + else + format = PixelFormat::R32_Float; + break; + } + additionalDataVS.Inputs.Add({ ParseVertexElementType(inputDesc.SemanticName, inputDesc.SemanticIndex), 0, 0, 0, format }); + } + } DxShaderHeader header; Platform::MemoryClear(&header, sizeof(header)); ShaderBindings bindings = { desc.InstructionCount, 0, 0, 0 }; @@ -370,16 +416,16 @@ bool ShaderCompilerDX::CompileShader(ShaderFunctionMeta& meta, WritePermutationD shaderReflection->GetResourceBindingDesc(i, &resDesc); switch (resDesc.Type) { - // Sampler + // Sampler case D3D_SIT_SAMPLER: break; - // Constant Buffer + // Constant Buffer case D3D_SIT_CBUFFER: case D3D_SIT_TBUFFER: break; - // Shader Resource + // Shader Resource case D3D_SIT_TEXTURE: for (UINT shift = 0; shift < resDesc.BindCount; shift++) { @@ -396,7 +442,7 @@ bool ShaderCompilerDX::CompileShader(ShaderFunctionMeta& meta, WritePermutationD } break; - // Unordered Access + // Unordered Access case D3D_SIT_UAV_RWTYPED: case D3D_SIT_UAV_RWSTRUCTURED: case D3D_SIT_UAV_RWBYTEADDRESS: @@ -415,7 +461,7 @@ bool ShaderCompilerDX::CompileShader(ShaderFunctionMeta& meta, WritePermutationD if (WriteShaderFunctionPermutation(_context, meta, permutationIndex, bindings, &header, sizeof(header), shaderBuffer->GetBufferPointer(), (int32)shaderBuffer->GetBufferSize())) return true; - if (customDataWrite && customDataWrite(_context, meta, permutationIndex, _macros)) + if (customDataWrite && customDataWrite(_context, meta, permutationIndex, _macros, additionalData)) return true; } diff --git a/Source/Engine/ShadersCompilation/DirectX/ShaderCompilerDX.h b/Source/Engine/ShadersCompilation/DirectX/ShaderCompilerDX.h index 935f3ca87..30076db83 100644 --- a/Source/Engine/ShadersCompilation/DirectX/ShaderCompilerDX.h +++ b/Source/Engine/ShadersCompilation/DirectX/ShaderCompilerDX.h @@ -12,14 +12,12 @@ class ShaderCompilerDX : public ShaderCompiler { private: - Array _funcNameDefineBuffer; void* _compiler; void* _library; void* _containerReflection; public: - /// /// Initializes a new instance of the class. /// @@ -32,7 +30,6 @@ public: ~ShaderCompilerDX(); protected: - // [ShaderCompiler] bool CompileShader(ShaderFunctionMeta& meta, WritePermutationData customDataWrite = nullptr) override; bool OnCompileBegin() override; diff --git a/Source/Engine/ShadersCompilation/ShaderCompiler.cpp b/Source/Engine/ShadersCompilation/ShaderCompiler.cpp index 21b619b86..8e3ca2abf 100644 --- a/Source/Engine/ShadersCompilation/ShaderCompiler.cpp +++ b/Source/Engine/ShadersCompilation/ShaderCompiler.cpp @@ -271,7 +271,6 @@ bool ShaderCompiler::WriteShaderFunctionBegin(ShaderCompilationContext* context, bool ShaderCompiler::WriteShaderFunctionPermutation(ShaderCompilationContext* context, ShaderFunctionMeta& meta, int32 permutationIndex, const ShaderBindings& bindings, const void* header, int32 headerSize, const void* cache, int32 cacheSize) { auto output = context->Output; - output->Write((uint32)(cacheSize + headerSize)); output->WriteBytes(header, headerSize); output->WriteBytes(cache, cacheSize); @@ -293,18 +292,22 @@ bool ShaderCompiler::WriteShaderFunctionEnd(ShaderCompilationContext* context, S return false; } -bool ShaderCompiler::WriteCustomDataVS(ShaderCompilationContext* context, ShaderFunctionMeta& meta, int32 permutationIndex, const Array& macros) +bool ShaderCompiler::WriteCustomDataVS(ShaderCompilationContext* context, ShaderFunctionMeta& meta, int32 permutationIndex, const Array& macros, void* additionalData) { - // [Deprecated in v1.10] auto output = context->Output; + + // Write vertex shader inputs (based on compiled shader reflection) to bind any missing vertex buffer streaming at runtime (during drawing - see usage of GPUVertexLayout::Merge) + if (auto* additionalDataVS = (AdditionalDataVS*)additionalData) + output->Write(additionalDataVS->Inputs); + else + output->WriteInt32(0); + + // [Deprecated in v1.10] auto& metaVS = *(VertexShaderMeta*)&meta; auto& layout = metaVS.InputLayout; #if FLAXENGINE_VERSION_MAJOR > 2 || (FLAXENGINE_VERSION_MAJOR == 2 && FLAXENGINE_VERSION_MINOR >= 1) if (layout.HasItems()) LOG(Warning, "Vertex Shader '{}' (asset '{}') uses explicit vertex layout via 'META_VS_IN_ELEMENT' macros which has been deprecated. Remove this code and migrate to GPUVertexLayout with VertexElement array in code (assigned to vertex buffer).", String(meta.Name), context->Options->TargetName); -#elif FLAXENGINE_VERSION_MAJOR == 1 && FLAXENGINE_VERSION_MINOR >= 11 - if (layout.HasItems()) - LOG(Warning, "Vertex Shader '{}' (asset '{}') uses explicit vertex layout via 'META_VS_IN_ELEMENT' macros which has been deprecated. Remove this code and migrate to GPUVertexLayout with VertexElement array in code (assigned to vertex buffer).", String(meta.Name), context->Options->TargetName); #endif // Get visible entries (based on `visible` flag switch) @@ -443,7 +446,7 @@ bool ShaderCompiler::WriteCustomDataVS(ShaderCompilationContext* context, Shader return false; } -bool ShaderCompiler::WriteCustomDataHS(ShaderCompilationContext* context, ShaderFunctionMeta& meta, int32 permutationIndex, const Array& macros) +bool ShaderCompiler::WriteCustomDataHS(ShaderCompilationContext* context, ShaderFunctionMeta& meta, int32 permutationIndex, const Array& macros, void* additionalData) { auto output = context->Output; auto& metaHS = *(HullShaderMeta*)&meta; @@ -457,7 +460,7 @@ bool ShaderCompiler::WriteCustomDataHS(ShaderCompilationContext* context, Shader void ShaderCompiler::GetDefineForFunction(ShaderFunctionMeta& meta, Array& macros) { auto& functionName = meta.Name; - const int32 functionNameLength = static_cast(functionName.Length()); + const int32 functionNameLength = functionName.Length(); _funcNameDefineBuffer.Clear(); _funcNameDefineBuffer.EnsureCapacity(functionNameLength + 2); _funcNameDefineBuffer.Add('_'); @@ -466,4 +469,35 @@ void ShaderCompiler::GetDefineForFunction(ShaderFunctionMeta& meta, Array /// Base class for the objects that can compile shaders source code. @@ -14,7 +15,6 @@ class ShaderCompiler { public: - struct ShaderResourceBuffer { byte Slot; @@ -23,11 +23,9 @@ public: }; private: - Array _funcNameDefineBuffer; protected: - ShaderProfile _profile; ShaderCompilationContext* _context = nullptr; Array _globalMacros; @@ -35,7 +33,6 @@ protected: Array _constantBuffers; public: - /// /// Initializes a new instance of the class. /// @@ -51,7 +48,6 @@ public: virtual ~ShaderCompiler() = default; public: - /// /// Gets shader profile supported by this compiler. /// @@ -85,8 +81,13 @@ public: static void DisposeIncludedFilesCache(); protected: + // Input elements read from reflection after shader compilation. Rough approx or attributes without exact format nor bind slot (only semantics and value dimensions match). + struct AdditionalDataVS + { + GPUVertexLayout::Elements Inputs; + }; - typedef bool (*WritePermutationData)(ShaderCompilationContext*, ShaderFunctionMeta&, int32, const Array&); + typedef bool (*WritePermutationData)(ShaderCompilationContext*, ShaderFunctionMeta&, int32, const Array&, void*); virtual bool CompileShader(ShaderFunctionMeta& meta, WritePermutationData customDataWrite = nullptr) = 0; @@ -99,9 +100,11 @@ protected: static bool WriteShaderFunctionPermutation(ShaderCompilationContext* context, ShaderFunctionMeta& meta, int32 permutationIndex, const ShaderBindings& bindings, const void* header, int32 headerSize, const void* cache, int32 cacheSize); static bool WriteShaderFunctionPermutation(ShaderCompilationContext* context, ShaderFunctionMeta& meta, int32 permutationIndex, const ShaderBindings& bindings, const void* cache, int32 cacheSize); static bool WriteShaderFunctionEnd(ShaderCompilationContext* context, ShaderFunctionMeta& meta); - static bool WriteCustomDataVS(ShaderCompilationContext* context, ShaderFunctionMeta& meta, int32 permutationIndex, const Array& macros); - static bool WriteCustomDataHS(ShaderCompilationContext* context, ShaderFunctionMeta& meta, int32 permutationIndex, const Array& macros); + static bool WriteCustomDataVS(ShaderCompilationContext* context, ShaderFunctionMeta& meta, int32 permutationIndex, const Array& macros, void* additionalData); + static bool WriteCustomDataHS(ShaderCompilationContext* context, ShaderFunctionMeta& meta, int32 permutationIndex, const Array& macros, void* additionalData); void GetDefineForFunction(ShaderFunctionMeta& meta, Array& macros); + + static VertexElement::Types ParseVertexElementType(StringAnsiView semantic, uint32 index = 0); }; #endif diff --git a/Source/Engine/ShadersCompilation/Vulkan/ShaderCompilerVulkan.cpp b/Source/Engine/ShadersCompilation/Vulkan/ShaderCompilerVulkan.cpp index 5f509ef1e..c3fa1483d 100644 --- a/Source/Engine/ShadersCompilation/Vulkan/ShaderCompilerVulkan.cpp +++ b/Source/Engine/ShadersCompilation/Vulkan/ShaderCompilerVulkan.cpp @@ -234,14 +234,14 @@ SpirvShaderResourceType GetTextureType(const glslang::TSampler& sampler) } } -PixelFormat GetResourceFormat(const glslang::TSampler& sampler) +PixelFormat GetResourceFormat(glslang::TBasicType basicType, uint32 vectorSize) { - switch (sampler.type) + switch (basicType) { case glslang::EbtVoid: return PixelFormat::Unknown; case glslang::EbtFloat: - switch (sampler.vectorSize) + switch (vectorSize) { case 1: return PixelFormat::R32_Float; @@ -254,7 +254,7 @@ PixelFormat GetResourceFormat(const glslang::TSampler& sampler) } break; case glslang::EbtFloat16: - switch (sampler.vectorSize) + switch (vectorSize) { case 1: return PixelFormat::R16_Float; @@ -265,7 +265,7 @@ PixelFormat GetResourceFormat(const glslang::TSampler& sampler) } break; case glslang::EbtUint: - switch (sampler.vectorSize) + switch (vectorSize) { case 1: return PixelFormat::R32_UInt; @@ -278,7 +278,7 @@ PixelFormat GetResourceFormat(const glslang::TSampler& sampler) } break; case glslang::EbtInt: - switch (sampler.vectorSize) + switch (vectorSize) { case 1: return PixelFormat::R32_SInt; @@ -291,7 +291,7 @@ PixelFormat GetResourceFormat(const glslang::TSampler& sampler) } break; case glslang::EbtUint8: - switch (sampler.vectorSize) + switch (vectorSize) { case 1: return PixelFormat::R8_UInt; @@ -302,7 +302,7 @@ PixelFormat GetResourceFormat(const glslang::TSampler& sampler) } break; case glslang::EbtInt8: - switch (sampler.vectorSize) + switch (vectorSize) { case 1: return PixelFormat::R8_SInt; @@ -313,7 +313,7 @@ PixelFormat GetResourceFormat(const glslang::TSampler& sampler) } break; case glslang::EbtUint16: - switch (sampler.vectorSize) + switch (vectorSize) { case 1: return PixelFormat::R16_UInt; @@ -324,7 +324,7 @@ PixelFormat GetResourceFormat(const glslang::TSampler& sampler) } break; case glslang::EbtInt16: - switch (sampler.vectorSize) + switch (vectorSize) { case 1: return PixelFormat::R16_SInt; @@ -340,6 +340,16 @@ PixelFormat GetResourceFormat(const glslang::TSampler& sampler) return PixelFormat::Unknown; } +PixelFormat GetResourceFormat(const glslang::TSampler& sampler) +{ + return GetResourceFormat(sampler.type, sampler.vectorSize); +} + +PixelFormat GetResourceFormat(const glslang::TType& type) +{ + return GetResourceFormat(type.getBasicType(), type.getVectorSize()); +} + bool IsUavType(const glslang::TType& type) { if (type.getQualifier().isReadOnly()) @@ -611,6 +621,7 @@ bool ShaderCompilerVulkan::CompileShader(ShaderFunctionMeta& meta, WritePermutat EShMessages messages = (EShMessages)(EShMsgReadHlsl | EShMsgSpvRules | EShMsgVulkanRules); // Compile all shader function permutations + AdditionalDataVS additionalDataVS; for (int32 permutationIndex = 0; permutationIndex < meta.Permutations.Count(); permutationIndex++) { #if PRINT_DESCRIPTORS @@ -721,157 +732,167 @@ bool ShaderCompilerVulkan::CompileShader(ShaderFunctionMeta& meta, WritePermutat } // Process shader reflection data + void* additionalData = nullptr; SpirvShaderHeader header; Platform::MemoryClear(&header, sizeof(header)); ShaderBindings bindings = { 0, 0, 0, 0 }; + if (type == ShaderStage::Vertex) { - // Extract constant buffers usage information - for (int blockIndex = 0; blockIndex < program.getNumLiveUniformBlocks(); blockIndex++) + additionalData = &additionalDataVS; + additionalDataVS.Inputs.Clear(); + for (int inputIndex = 0; inputIndex < program.getNumPipeInputs(); inputIndex++) { - auto size = program.getUniformBlockSize(blockIndex); - auto uniform = program.getUniformBlockTType(blockIndex); - auto& qualifier = uniform->getQualifier(); - auto binding = (int32)qualifier.layoutBinding; - - if (!qualifier.hasBinding()) - { - // Each uniform must have a valid binding - //LOG(Warning, "Found a uniform block \'{0}\' without a binding qualifier. Each uniform block must have an explicitly defined binding number.", String(uniform->getTypeName().c_str())); + const glslang::TObjectReflection& input = program.getPipeInput(inputIndex); + if (!input.getType() || input.getType()->containsBuiltIn()) continue; - } + additionalDataVS.Inputs.Add({ ParseVertexElementType(input.getType()->getQualifier().semanticName), 0, 0, 0, GetResourceFormat(*input.getType()) }); + } + } + for (int blockIndex = 0; blockIndex < program.getNumLiveUniformBlocks(); blockIndex++) + { + auto size = program.getUniformBlockSize(blockIndex); + auto uniform = program.getUniformBlockTType(blockIndex); + auto& qualifier = uniform->getQualifier(); + auto binding = (int32)qualifier.layoutBinding; - // Shared storage buffer - if (qualifier.storage == glslang::EvqBuffer) + if (!qualifier.hasBinding()) + { + // Each uniform must have a valid binding + //LOG(Warning, "Found a uniform block \'{0}\' without a binding qualifier. Each uniform block must have an explicitly defined binding number.", String(uniform->getTypeName().c_str())); + continue; + } + + // Shared storage buffer + if (qualifier.storage == glslang::EvqBuffer) + { + // RWBuffer + } + else + { + // Uniform buffer + bool found = false; + for (int32 i = 0; i < descriptorsCollector.DescriptorsCount; i++) { - // RWBuffer + auto& descriptor = descriptorsCollector.Descriptors[i]; + if (descriptor.BindingType == SpirvShaderResourceBindingType::CB && descriptor.Binding == binding) + { + found = true; + descriptor.Size = size; + break; + } } - else + if (!found) { - // Uniform buffer - bool found = false; - for (int32 i = 0; i < descriptorsCollector.DescriptorsCount; i++) - { - auto& descriptor = descriptorsCollector.Descriptors[i]; - if (descriptor.BindingType == SpirvShaderResourceBindingType::CB && descriptor.Binding == binding) - { - found = true; - descriptor.Size = size; - break; - } - } - if (!found) - { - LOG(Warning, "Failed to find descriptor for the uniform block \'{0}\' of size {1} (bytes), binding: {2}.", String(uniform->getTypeName().c_str()), size, binding); - } + LOG(Warning, "Failed to find descriptor for the uniform block \'{0}\' of size {1} (bytes), binding: {2}.", String(uniform->getTypeName().c_str()), size, binding); } } + } #if PRINT_UNIFORMS - // Debug printing all uniforms - for (int32 index = 0; index < program.getNumLiveUniformVariables(); index++) - { - auto uniform = program.getUniformTType(index); - auto qualifier = uniform->getQualifier(); - if (!uniform->isArray()) - LOG(Warning, "Shader {0}:{1} - uniform: {2} {3} at binding {4}", - _context->TargetNameAnsi, - String(meta.Name), - uniform->getCompleteString().c_str(), - program.getUniformName(index), - qualifier.layoutBinding - ); - } + // Debug printing all uniforms + for (int32 index = 0; index < program.getNumLiveUniformVariables(); index++) + { + auto uniform = program.getUniformTType(index); + auto qualifier = uniform->getQualifier(); + if (!uniform->isArray()) + LOG(Warning, "Shader {0}:{1} - uniform: {2} {3} at binding {4}", + _context->TargetNameAnsi, + String(meta.Name), + uniform->getCompleteString().c_str(), + program.getUniformName(index), + qualifier.layoutBinding + ); + } #endif - // Process all descriptors - header.DescriptorInfo.ImageInfosCount = descriptorsCollector.Images; - header.DescriptorInfo.BufferInfosCount = descriptorsCollector.Buffers; - header.DescriptorInfo.TexelBufferViewsCount = descriptorsCollector.TexelBuffers; - for (int32 i = 0; i < descriptorsCollector.DescriptorsCount; i++) + // Process all descriptors + header.DescriptorInfo.ImageInfosCount = descriptorsCollector.Images; + header.DescriptorInfo.BufferInfosCount = descriptorsCollector.Buffers; + header.DescriptorInfo.TexelBufferViewsCount = descriptorsCollector.TexelBuffers; + for (int32 i = 0; i < descriptorsCollector.DescriptorsCount; i++) + { + auto& descriptor = descriptorsCollector.Descriptors[i]; + + // Skip cases (eg. AppendStructuredBuffer counter buffer) + if (descriptor.Slot == MAX_uint16) + continue; + + auto& d = header.DescriptorInfo.DescriptorTypes[header.DescriptorInfo.DescriptorTypesCount++]; + d.Binding = descriptor.Binding; + d.Set = stageSet; + d.Slot = descriptor.Slot; + d.BindingType = descriptor.BindingType; + d.DescriptorType = descriptor.DescriptorType; + d.ResourceType = descriptor.ResourceType; + d.ResourceFormat = descriptor.ResourceFormat; + d.Count = descriptor.Count; + + switch (descriptor.BindingType) { - auto& descriptor = descriptorsCollector.Descriptors[i]; + case SpirvShaderResourceBindingType::CB: + ASSERT_LOW_LAYER(descriptor.Slot >= 0 && descriptor.Slot < GPU_MAX_CB_BINDED); + bindings.UsedCBsMask |= 1 << descriptor.Slot; + break; + case SpirvShaderResourceBindingType::SRV: + ASSERT_LOW_LAYER(descriptor.Slot >= 0 && descriptor.Slot < GPU_MAX_SR_BINDED); + bindings.UsedSRsMask |= 1 << descriptor.Slot; + break; + case SpirvShaderResourceBindingType::UAV: + ASSERT_LOW_LAYER(descriptor.Slot >= 0 && descriptor.Slot < GPU_MAX_UA_BINDED); + bindings.UsedUAsMask |= 1 << descriptor.Slot; + break; + } - // Skip cases (eg. AppendStructuredBuffer counter buffer) - if (descriptor.Slot == MAX_uint16) + if (descriptor.BindingType == SpirvShaderResourceBindingType::CB) + { + if (descriptor.Size == -1) + { + // Skip unused constant buffers continue; - - auto& d = header.DescriptorInfo.DescriptorTypes[header.DescriptorInfo.DescriptorTypesCount++]; - d.Binding = descriptor.Binding; - d.Set = stageSet; - d.Slot = descriptor.Slot; - d.BindingType = descriptor.BindingType; - d.DescriptorType = descriptor.DescriptorType; - d.ResourceType = descriptor.ResourceType; - d.ResourceFormat = descriptor.ResourceFormat; - d.Count = descriptor.Count; - - switch (descriptor.BindingType) + } + if (descriptor.Size == 0) { - case SpirvShaderResourceBindingType::CB: - ASSERT_LOW_LAYER(descriptor.Slot >= 0 && descriptor.Slot < GPU_MAX_CB_BINDED); - bindings.UsedCBsMask |= 1 << descriptor.Slot; - break; - case SpirvShaderResourceBindingType::SRV: - ASSERT_LOW_LAYER(descriptor.Slot >= 0 && descriptor.Slot < GPU_MAX_SR_BINDED); - bindings.UsedSRsMask |= 1 << descriptor.Slot; - break; - case SpirvShaderResourceBindingType::UAV: - ASSERT_LOW_LAYER(descriptor.Slot >= 0 && descriptor.Slot < GPU_MAX_UA_BINDED); - bindings.UsedUAsMask |= 1 << descriptor.Slot; - break; + LOG(Warning, "Found constant buffer \'{1}\' at slot {0} but it's not used or has no valid size.", descriptor.Slot, String(descriptor.Name.c_str())); + continue; } - if (descriptor.BindingType == SpirvShaderResourceBindingType::CB) + for (int32 b = 0; b < _constantBuffers.Count(); b++) { - if (descriptor.Size == -1) + auto& cc = _constantBuffers[b]; + if (cc.Slot == descriptor.Slot) { - // Skip unused constant buffers - continue; - } - if (descriptor.Size == 0) - { - LOG(Warning, "Found constant buffer \'{1}\' at slot {0} but it's not used or has no valid size.", descriptor.Slot, String(descriptor.Name.c_str())); - continue; - } - - for (int32 b = 0; b < _constantBuffers.Count(); b++) - { - auto& cc = _constantBuffers[b]; - if (cc.Slot == descriptor.Slot) - { - // Mark as used and cache some data - cc.IsUsed = true; - cc.Size = descriptor.Size; - break; - } + // Mark as used and cache some data + cc.IsUsed = true; + cc.Size = descriptor.Size; + break; } } + } #if PRINT_DESCRIPTORS - String type; - switch (descriptor.BindingType) - { - case SpirvShaderResourceBindingType::INVALID: - type = TEXT("INVALID"); - break; - case SpirvShaderResourceBindingType::CB: - type = TEXT("CB"); - break; - case SpirvShaderResourceBindingType::SAMPLER: - type = TEXT("SAMPLER"); - break; - case SpirvShaderResourceBindingType::SRV: - type = TEXT("SRV"); - break; - case SpirvShaderResourceBindingType::UAV: - type = TEXT("UAV"); - break; - default: - type = TEXT("?"); - } - LOG(Warning, "VULKAN SHADER RESOURCE: slot: {1}, binding: {2}, name: {0}, type: {3}", String(descriptor.Name.c_str()), descriptor.Slot, descriptor.Binding, type); -#endif + String type; + switch (descriptor.BindingType) + { + case SpirvShaderResourceBindingType::INVALID: + type = TEXT("INVALID"); + break; + case SpirvShaderResourceBindingType::CB: + type = TEXT("CB"); + break; + case SpirvShaderResourceBindingType::SAMPLER: + type = TEXT("SAMPLER"); + break; + case SpirvShaderResourceBindingType::SRV: + type = TEXT("SRV"); + break; + case SpirvShaderResourceBindingType::UAV: + type = TEXT("UAV"); + break; + default: + type = TEXT("?"); } + LOG(Warning, "VULKAN SHADER RESOURCE: slot: {1}, binding: {2}, name: {0}, type: {3}", String(descriptor.Name.c_str()), descriptor.Slot, descriptor.Binding, type); +#endif } // Generate SPIR-V (optimize it at the same time) @@ -916,7 +937,7 @@ bool ShaderCompilerVulkan::CompileShader(ShaderFunctionMeta& meta, WritePermutat if (WriteShaderFunctionPermutation(_context, meta, permutationIndex, bindings, &header, sizeof(header), &spirv[0], spirvBytesCount)) return true; - if (customDataWrite && customDataWrite(_context, meta, permutationIndex, _macros)) + if (customDataWrite && customDataWrite(_context, meta, permutationIndex, _macros, additionalData)) return true; } diff --git a/Source/Engine/ShadersCompilation/Vulkan/ShaderCompilerVulkan.h b/Source/Engine/ShadersCompilation/Vulkan/ShaderCompilerVulkan.h index efac16a53..d82a5b8f1 100644 --- a/Source/Engine/ShadersCompilation/Vulkan/ShaderCompilerVulkan.h +++ b/Source/Engine/ShadersCompilation/Vulkan/ShaderCompilerVulkan.h @@ -12,11 +12,9 @@ class ShaderCompilerVulkan : public ShaderCompiler { private: - Array _funcNameDefineBuffer; public: - /// /// Initializes a new instance of the class. /// @@ -29,7 +27,6 @@ public: ~ShaderCompilerVulkan(); protected: - // [ShaderCompiler] bool CompileShader(ShaderFunctionMeta& meta, WritePermutationData customDataWrite = nullptr) override; bool OnCompileBegin() override;