diff --git a/Source/Engine/Graphics/GPUDevice.cpp b/Source/Engine/Graphics/GPUDevice.cpp index 74ea99920..da0e2f07c 100644 --- a/Source/Engine/Graphics/GPUDevice.cpp +++ b/Source/Engine/Graphics/GPUDevice.cpp @@ -112,15 +112,13 @@ bool GPUPipelineState::Init(const Description& desc) #endif // Cache shader stages usage flags for pipeline state - _meta.InstructionsCount = 0; - _meta.UsedCBsMask = 0; - _meta.UsedSRsMask = 0; - _meta.UsedUAsMask = 0; + Platform::MemoryClear(&_meta, sizeof(_meta)); #define CHECK_STAGE(stage) \ if (desc.stage) { \ _meta.UsedCBsMask |= desc.stage->GetBindings().UsedCBsMask; \ _meta.UsedSRsMask |= desc.stage->GetBindings().UsedSRsMask; \ _meta.UsedUAsMask |= desc.stage->GetBindings().UsedUAsMask; \ + _meta.UsedSamplersMask |= desc.stage->GetBindings().UsedSamplersMask; \ } CHECK_STAGE(VS); CHECK_STAGE(HS); diff --git a/Source/Engine/Graphics/GPUPipelineState.h b/Source/Engine/Graphics/GPUPipelineState.h index 97b546b69..d02e911a4 100644 --- a/Source/Engine/Graphics/GPUPipelineState.h +++ b/Source/Engine/Graphics/GPUPipelineState.h @@ -215,6 +215,14 @@ public: return _meta.UsedUAsMask; } + /// + /// Gets texture samplers mask (each set bit marks usage of the sampler slot at the bit index slot). Combined from all the used shader stages. + /// + FORCE_INLINE uint32 GetUsedSamplersMask() const + { + return _meta.UsedSamplersMask; + } + public: /// /// Returns true if pipeline state is valid and ready to use diff --git a/Source/Engine/Graphics/Shaders/GPUShader.h b/Source/Engine/Graphics/Shaders/GPUShader.h index 7c4e52e53..236c7aa16 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 12 +#define GPU_SHADER_CACHE_VERSION 13 /// /// 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. diff --git a/Source/Engine/Graphics/Shaders/GPUShaderProgram.h b/Source/Engine/Graphics/Shaders/GPUShaderProgram.h index 43a62065b..2023b74a3 100644 --- a/Source/Engine/Graphics/Shaders/GPUShaderProgram.h +++ b/Source/Engine/Graphics/Shaders/GPUShaderProgram.h @@ -21,6 +21,9 @@ struct FLAXENGINE_API ShaderBindings uint32 UsedCBsMask; uint32 UsedSRsMask; uint32 UsedUAsMask; + uint32 UsedSamplersMask; + uint16 InputsCount; + uint16 OutputsCount; FORCE_INLINE bool IsUsingCB(uint32 slotIndex) const { @@ -36,6 +39,11 @@ struct FLAXENGINE_API ShaderBindings { return (UsedUAsMask & (1u << slotIndex)) != 0u; } + + FORCE_INLINE bool IsUsingSampler(uint32 slotIndex) const + { + return (UsedSamplersMask & (1u << slotIndex)) != 0u; + } }; struct GPUShaderProgramInitializer diff --git a/Source/Engine/ShadersCompilation/DirectX/ShaderCompilerD3D.cpp b/Source/Engine/ShadersCompilation/DirectX/ShaderCompilerD3D.cpp index 01ce8faef..f2b08ea04 100644 --- a/Source/Engine/ShadersCompilation/DirectX/ShaderCompilerD3D.cpp +++ b/Source/Engine/ShadersCompilation/DirectX/ShaderCompilerD3D.cpp @@ -79,6 +79,9 @@ namespace { bool ProcessShader(ShaderCompilationContext* context, Array& constantBuffers, ID3D11ShaderReflection* reflector, D3D11_SHADER_DESC& desc, ShaderBindings& bindings) { + bindings.InputsCount = desc.InputParameters; + bindings.OutputsCount = desc.OutputParameters; + // Extract constant buffers usage information for (uint32 a = 0; a < desc.ConstantBuffers; a++) { @@ -131,13 +134,12 @@ namespace { // Sampler case D3D_SIT_SAMPLER: + bindings.UsedSamplersMask |= 1 << resDesc.BindPoint; break; - // Constant Buffer case D3D_SIT_CBUFFER: case D3D_SIT_TBUFFER: break; - // Shader Resource case D3D_SIT_TEXTURE: case D3D_SIT_STRUCTURED: @@ -145,7 +147,6 @@ namespace for (UINT shift = 0; shift < resDesc.BindCount; shift++) bindings.UsedSRsMask |= 1 << (resDesc.BindPoint + shift); break; - // Unordered Access case D3D_SIT_UAV_RWTYPED: case D3D_SIT_UAV_RWSTRUCTURED: @@ -316,7 +317,7 @@ bool ShaderCompilerD3D::CompileShader(ShaderFunctionMeta& meta, WritePermutation additionalDataVS.Inputs.Add({ ParseVertexElementType(inputDesc.SemanticName, inputDesc.SemanticIndex), 0, 0, 0, format }); } } - ShaderBindings bindings = { desc.InstructionCount, 0, 0, 0 }; + ShaderBindings bindings = { desc.InstructionCount }; if (ProcessShader(_context, _constantBuffers, reflector.Get(), desc, bindings)) return true; diff --git a/Source/Engine/ShadersCompilation/DirectX/ShaderCompilerDX.cpp b/Source/Engine/ShadersCompilation/DirectX/ShaderCompilerDX.cpp index 7dd7182cf..64e486dca 100644 --- a/Source/Engine/ShadersCompilation/DirectX/ShaderCompilerDX.cpp +++ b/Source/Engine/ShadersCompilation/DirectX/ShaderCompilerDX.cpp @@ -372,7 +372,9 @@ bool ShaderCompilerDX::CompileShader(ShaderFunctionMeta& meta, WritePermutationD } DxShaderHeader header; Platform::MemoryClear(&header, sizeof(header)); - ShaderBindings bindings = { desc.InstructionCount, 0, 0, 0 }; + ShaderBindings bindings = { desc.InstructionCount }; + bindings.InputsCount = desc.InputParameters; + bindings.OutputsCount = desc.OutputParameters; for (uint32 a = 0; a < desc.ConstantBuffers; a++) { auto cb = shaderReflection->GetConstantBufferByIndex(a); @@ -422,13 +424,12 @@ bool ShaderCompilerDX::CompileShader(ShaderFunctionMeta& meta, WritePermutationD { // Sampler case D3D_SIT_SAMPLER: + bindings.UsedSamplersMask |= 1 << resDesc.BindPoint; break; - // Constant Buffer case D3D_SIT_CBUFFER: case D3D_SIT_TBUFFER: break; - // Shader Resource case D3D_SIT_TEXTURE: for (UINT shift = 0; shift < resDesc.BindCount; shift++) @@ -445,7 +446,6 @@ bool ShaderCompilerDX::CompileShader(ShaderFunctionMeta& meta, WritePermutationD header.SrDimensions[resDesc.BindPoint + shift] = D3D_SRV_DIMENSION_BUFFER; } break; - // Unordered Access case D3D_SIT_UAV_RWTYPED: case D3D_SIT_UAV_RWSTRUCTURED: diff --git a/Source/Engine/ShadersCompilation/Vulkan/ShaderCompilerVulkan.cpp b/Source/Engine/ShadersCompilation/Vulkan/ShaderCompilerVulkan.cpp index 495d93a20..f76246623 100644 --- a/Source/Engine/ShadersCompilation/Vulkan/ShaderCompilerVulkan.cpp +++ b/Source/Engine/ShadersCompilation/Vulkan/ShaderCompilerVulkan.cpp @@ -728,7 +728,9 @@ bool ShaderCompilerVulkan::CompileShader(ShaderFunctionMeta& meta, WritePermutat void* additionalData = nullptr; SpirvShaderHeader header; Platform::MemoryClear(&header, sizeof(header)); - ShaderBindings bindings = { 0, 0, 0, 0 }; + ShaderBindings bindings = {}; + bindings.InputsCount = program.getNumPipeInputs(); + bindings.OutputsCount = program.getNumPipeOutputs(); if (type == ShaderStage::Vertex) { additionalData = &additionalDataVS; @@ -822,6 +824,10 @@ bool ShaderCompilerVulkan::CompileShader(ShaderFunctionMeta& meta, WritePermutat switch (descriptor.BindingType) { + case SpirvShaderResourceBindingType::SAMPLER: + ASSERT_LOW_LAYER(descriptor.Slot >= 0 && descriptor.Slot < GPU_MAX_SAMPLER_BINDED); + bindings.UsedSamplersMask |= 1 << descriptor.Slot; + break; case SpirvShaderResourceBindingType::CB: ASSERT_LOW_LAYER(descriptor.Slot >= 0 && descriptor.Slot < GPU_MAX_CB_BINDED); bindings.UsedCBsMask |= 1 << descriptor.Slot;