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;