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;