Improve GPU vertex layout binding in case of missing element from the mesh
This commit is contained in:
@@ -148,27 +148,22 @@ static bool TryCreateDevice(IDXGIAdapter* adapter, D3D_FEATURE_LEVEL maxFeatureL
|
||||
return false;
|
||||
}
|
||||
|
||||
GPUVertexLayoutDX11::GPUVertexLayoutDX11(GPUDeviceDX11* device, const Elements& elements)
|
||||
GPUVertexLayoutDX11::GPUVertexLayoutDX11(GPUDeviceDX11* device, const Elements& elements, bool explicitOffsets)
|
||||
: GPUResourceBase<GPUDeviceDX11, GPUVertexLayout>(device, StringView::Empty)
|
||||
, InputElementsCount(elements.Count())
|
||||
{
|
||||
uint32 offsets[GPU_MAX_VB_BINDED] = {};
|
||||
SetElements(elements, explicitOffsets);
|
||||
for (int32 i = 0; i < elements.Count(); i++)
|
||||
{
|
||||
const VertexElement& src = elements.Get()[i];
|
||||
const VertexElement& src = GetElements().Get()[i];
|
||||
D3D11_INPUT_ELEMENT_DESC& dst = InputElements[i];
|
||||
uint32& offset = offsets[src.Slot];
|
||||
if (src.Offset != 0)
|
||||
offset = src.Offset;
|
||||
dst.SemanticName = RenderToolsDX::GetVertexInputSemantic(src.Type, dst.SemanticIndex);
|
||||
dst.Format = RenderToolsDX::ToDxgiFormat(src.Format);
|
||||
dst.InputSlot = src.Slot;
|
||||
dst.AlignedByteOffset = offset;
|
||||
dst.AlignedByteOffset = src.Offset;
|
||||
dst.InputSlotClass = src.PerInstance ? D3D11_INPUT_PER_INSTANCE_DATA : D3D11_INPUT_PER_VERTEX_DATA;
|
||||
dst.InstanceDataStepRate = src.PerInstance ? 1 : 0;
|
||||
offset += PixelFormatExtensions::SizeInBytes(src.Format);
|
||||
}
|
||||
SetElements(elements, offsets);
|
||||
}
|
||||
|
||||
GPUDevice* GPUDeviceDX11::Create()
|
||||
@@ -832,9 +827,9 @@ GPUSampler* GPUDeviceDX11::CreateSampler()
|
||||
return New<GPUSamplerDX11>(this);
|
||||
}
|
||||
|
||||
GPUVertexLayout* GPUDeviceDX11::CreateVertexLayout(const VertexElements& elements)
|
||||
GPUVertexLayout* GPUDeviceDX11::CreateVertexLayout(const VertexElements& elements, bool explicitOffsets)
|
||||
{
|
||||
return New<GPUVertexLayoutDX11>(this, elements);
|
||||
return New<GPUVertexLayoutDX11>(this, elements, explicitOffsets);
|
||||
}
|
||||
|
||||
GPUSwapChain* GPUDeviceDX11::CreateSwapChain(Window* window)
|
||||
|
||||
@@ -128,7 +128,7 @@ public:
|
||||
GPUTimerQuery* CreateTimerQuery() override;
|
||||
GPUBuffer* CreateBuffer(const StringView& name) override;
|
||||
GPUSampler* CreateSampler() override;
|
||||
GPUVertexLayout* CreateVertexLayout(const VertexElements& elements) override;
|
||||
GPUVertexLayout* CreateVertexLayout(const VertexElements& elements, bool explicitOffsets) override;
|
||||
GPUSwapChain* CreateSwapChain(Window* window) override;
|
||||
GPUConstantBuffer* CreateConstantBuffer(uint32 size, const StringView& name) override;
|
||||
};
|
||||
|
||||
@@ -11,19 +11,23 @@
|
||||
GPUShaderProgramVSDX11::~GPUShaderProgramVSDX11()
|
||||
{
|
||||
for (const auto& e : _cache)
|
||||
e.Value->Release();
|
||||
{
|
||||
if (e.Value)
|
||||
e.Value->Release();
|
||||
}
|
||||
}
|
||||
|
||||
ID3D11InputLayout* GPUShaderProgramVSDX11::GetInputLayout(GPUVertexLayoutDX11* vertexLayout)
|
||||
{
|
||||
if (!vertexLayout)
|
||||
vertexLayout = (GPUVertexLayoutDX11*)Layout;
|
||||
ID3D11InputLayout* inputLayout = nullptr;
|
||||
if (!_cache.TryGet(vertexLayout, inputLayout))
|
||||
{
|
||||
if (!vertexLayout)
|
||||
vertexLayout = (GPUVertexLayoutDX11*)Layout;
|
||||
if (vertexLayout && vertexLayout->InputElementsCount)
|
||||
{
|
||||
VALIDATE_DIRECTX_CALL(vertexLayout->GetDevice()->GetDevice()->CreateInputLayout(vertexLayout->InputElements, vertexLayout->InputElementsCount, Bytecode.Get(), Bytecode.Length(), &inputLayout));
|
||||
auto actualLayout = (GPUVertexLayoutDX11*)GPUVertexLayout::Merge(vertexLayout, Layout);
|
||||
LOG_DIRECTX_RESULT(vertexLayout->GetDevice()->GetDevice()->CreateInputLayout(actualLayout->InputElements, actualLayout->InputElementsCount, Bytecode.Get(), Bytecode.Length(), &inputLayout));
|
||||
}
|
||||
_cache.Add(vertexLayout, inputLayout);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
class GPUVertexLayoutDX11 : public GPUResourceBase<GPUDeviceDX11, GPUVertexLayout>
|
||||
{
|
||||
public:
|
||||
GPUVertexLayoutDX11(GPUDeviceDX11* device, const Elements& elements);
|
||||
GPUVertexLayoutDX11(GPUDeviceDX11* device, const Elements& elements, bool explicitOffsets);
|
||||
|
||||
uint32 InputElementsCount;
|
||||
D3D11_INPUT_ELEMENT_DESC InputElements[GPU_MAX_VS_ELEMENTS];
|
||||
|
||||
@@ -36,27 +36,22 @@ static bool CheckDX12Support(IDXGIAdapter* adapter)
|
||||
return false;
|
||||
}
|
||||
|
||||
GPUVertexLayoutDX12::GPUVertexLayoutDX12(GPUDeviceDX12* device, const Elements& elements)
|
||||
GPUVertexLayoutDX12::GPUVertexLayoutDX12(GPUDeviceDX12* device, const Elements& elements, bool explicitOffsets)
|
||||
: GPUResourceDX12<GPUVertexLayout>(device, StringView::Empty)
|
||||
, InputElementsCount(elements.Count())
|
||||
{
|
||||
uint32 offsets[GPU_MAX_VB_BINDED] = {};
|
||||
SetElements(elements, explicitOffsets);
|
||||
for (int32 i = 0; i < elements.Count(); i++)
|
||||
{
|
||||
const VertexElement& src = elements.Get()[i];
|
||||
const VertexElement& src = GetElements().Get()[i];
|
||||
D3D12_INPUT_ELEMENT_DESC& dst = InputElements[i];
|
||||
uint32& offset = offsets[src.Slot];
|
||||
if (src.Offset != 0)
|
||||
offset = src.Offset;
|
||||
dst.SemanticName = RenderToolsDX::GetVertexInputSemantic(src.Type, dst.SemanticIndex);
|
||||
dst.Format = RenderToolsDX::ToDxgiFormat(src.Format);
|
||||
dst.InputSlot = src.Slot;
|
||||
dst.AlignedByteOffset = offset;
|
||||
dst.AlignedByteOffset = src.Offset;
|
||||
dst.InputSlotClass = src.PerInstance ? D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA : D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA;
|
||||
dst.InstanceDataStepRate = src.PerInstance ? 1 : 0;
|
||||
offset += PixelFormatExtensions::SizeInBytes(src.Format);
|
||||
}
|
||||
SetElements(elements, offsets);
|
||||
}
|
||||
|
||||
GPUDevice* GPUDeviceDX12::Create()
|
||||
@@ -868,9 +863,9 @@ GPUSampler* GPUDeviceDX12::CreateSampler()
|
||||
return New<GPUSamplerDX12>(this);
|
||||
}
|
||||
|
||||
GPUVertexLayout* GPUDeviceDX12::CreateVertexLayout(const VertexElements& elements)
|
||||
GPUVertexLayout* GPUDeviceDX12::CreateVertexLayout(const VertexElements& elements, bool explicitOffsets)
|
||||
{
|
||||
return New<GPUVertexLayoutDX12>(this, elements);
|
||||
return New<GPUVertexLayoutDX12>(this, elements, explicitOffsets);
|
||||
}
|
||||
|
||||
GPUSwapChain* GPUDeviceDX12::CreateSwapChain(Window* window)
|
||||
|
||||
@@ -196,7 +196,7 @@ public:
|
||||
GPUTimerQuery* CreateTimerQuery() override;
|
||||
GPUBuffer* CreateBuffer(const StringView& name) override;
|
||||
GPUSampler* CreateSampler() override;
|
||||
GPUVertexLayout* CreateVertexLayout(const VertexElements& elements) override;
|
||||
GPUVertexLayout* CreateVertexLayout(const VertexElements& elements, bool explicitOffsets) override;
|
||||
GPUSwapChain* CreateSwapChain(Window* window) override;
|
||||
GPUConstantBuffer* CreateConstantBuffer(uint32 size, const StringView& name) override;
|
||||
};
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
class GPUVertexLayoutDX12 : public GPUResourceDX12<GPUVertexLayout>
|
||||
{
|
||||
public:
|
||||
GPUVertexLayoutDX12(GPUDeviceDX12* device, const Elements& elements);
|
||||
GPUVertexLayoutDX12(GPUDeviceDX12* device, const Elements& elements, bool explicitOffsets);
|
||||
|
||||
uint32 InputElementsCount;
|
||||
D3D12_INPUT_ELEMENT_DESC InputElements[GPU_MAX_VS_ELEMENTS];
|
||||
|
||||
@@ -173,7 +173,7 @@ GPUSampler* GPUDeviceNull::CreateSampler()
|
||||
return New<GPUSamplerNull>();
|
||||
}
|
||||
|
||||
GPUVertexLayout* GPUDeviceNull::CreateVertexLayout(const VertexElements& elements)
|
||||
GPUVertexLayout* GPUDeviceNull::CreateVertexLayout(const VertexElements& elements, bool explicitOffsets)
|
||||
{
|
||||
return New<GPUVertexLayoutNull>(elements);
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ public:
|
||||
GPUTimerQuery* CreateTimerQuery() override;
|
||||
GPUBuffer* CreateBuffer(const StringView& name) override;
|
||||
GPUSampler* CreateSampler() override;
|
||||
GPUVertexLayout* CreateVertexLayout(const VertexElements& elements) override;
|
||||
GPUVertexLayout* CreateVertexLayout(const VertexElements& elements, bool explicitOffsets) override;
|
||||
GPUSwapChain* CreateSwapChain(Window* window) override;
|
||||
GPUConstantBuffer* CreateConstantBuffer(uint32 size, const StringView& name) override;
|
||||
};
|
||||
|
||||
@@ -15,7 +15,7 @@ public:
|
||||
GPUVertexLayoutNull(const Elements& elements)
|
||||
: GPUVertexLayout()
|
||||
{
|
||||
SetElements(elements, {});
|
||||
SetElements(elements, false);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -449,10 +449,10 @@ uint32 GetHash(const FramebufferVulkan::Key& key)
|
||||
return hash;
|
||||
}
|
||||
|
||||
GPUVertexLayoutVulkan::GPUVertexLayoutVulkan(GPUDeviceVulkan* device, const Elements& elements)
|
||||
GPUVertexLayoutVulkan::GPUVertexLayoutVulkan(GPUDeviceVulkan* device, const Elements& elements, bool explicitOffsets)
|
||||
: GPUResourceVulkan<GPUVertexLayout>(device, StringView::Empty)
|
||||
{
|
||||
uint32 offsets[GPU_MAX_VB_BINDED] = {};
|
||||
SetElements(elements, explicitOffsets);
|
||||
for (int32 i = 0; i < GPU_MAX_VB_BINDED; i++)
|
||||
{
|
||||
VkVertexInputBindingDescription& binding = Bindings[i];
|
||||
@@ -463,28 +463,23 @@ GPUVertexLayoutVulkan::GPUVertexLayoutVulkan(GPUDeviceVulkan* device, const Elem
|
||||
uint32 bindingsCount = 0;
|
||||
for (int32 i = 0; i < elements.Count(); i++)
|
||||
{
|
||||
const VertexElement& src = elements.Get()[i];
|
||||
uint32& offset = offsets[src.Slot];
|
||||
if (src.Offset != 0)
|
||||
offset = src.Offset;
|
||||
const VertexElement& src = GetElements().Get()[i];
|
||||
const int32 size = PixelFormatExtensions::SizeInBytes(src.Format);
|
||||
|
||||
ASSERT_LOW_LAYER(src.Slot < GPU_MAX_VB_BINDED);
|
||||
VkVertexInputBindingDescription& binding = Bindings[src.Slot];
|
||||
binding.binding = src.Slot;
|
||||
binding.stride = Math::Max(binding.stride, (uint32_t)(offset + size));
|
||||
binding.stride = Math::Max(binding.stride, (uint32_t)(src.Offset + size));
|
||||
binding.inputRate = src.PerInstance ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX;
|
||||
|
||||
VkVertexInputAttributeDescription& attribute = Attributes[i];
|
||||
attribute.location = i;
|
||||
attribute.binding = src.Slot;
|
||||
attribute.format = RenderToolsVulkan::ToVulkanFormat(src.Format);
|
||||
attribute.offset = offset;
|
||||
attribute.offset = src.Offset;
|
||||
|
||||
bindingsCount = Math::Max(bindingsCount, (uint32)src.Slot + 1);
|
||||
offset += size;
|
||||
}
|
||||
SetElements(elements, offsets);
|
||||
|
||||
RenderToolsVulkan::ZeroStruct(CreateInfo, VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO);
|
||||
CreateInfo.vertexBindingDescriptionCount = bindingsCount;
|
||||
@@ -2129,9 +2124,9 @@ GPUSampler* GPUDeviceVulkan::CreateSampler()
|
||||
return New<GPUSamplerVulkan>(this);
|
||||
}
|
||||
|
||||
GPUVertexLayout* GPUDeviceVulkan::CreateVertexLayout(const VertexElements& elements)
|
||||
GPUVertexLayout* GPUDeviceVulkan::CreateVertexLayout(const VertexElements& elements, bool explicitOffsets)
|
||||
{
|
||||
return New<GPUVertexLayoutVulkan>(this, elements);
|
||||
return New<GPUVertexLayoutVulkan>(this, elements, explicitOffsets);
|
||||
}
|
||||
|
||||
GPUSwapChain* GPUDeviceVulkan::CreateSwapChain(Window* window)
|
||||
|
||||
@@ -610,7 +610,7 @@ public:
|
||||
GPUTimerQuery* CreateTimerQuery() override;
|
||||
GPUBuffer* CreateBuffer(const StringView& name) override;
|
||||
GPUSampler* CreateSampler() override;
|
||||
GPUVertexLayout* CreateVertexLayout(const VertexElements& elements) override;
|
||||
GPUVertexLayout* CreateVertexLayout(const VertexElements& elements, bool explicitOffsets) override;
|
||||
GPUSwapChain* CreateSwapChain(Window* window) override;
|
||||
GPUConstantBuffer* CreateConstantBuffer(uint32 size, const StringView& name) override;
|
||||
};
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
class GPUVertexLayoutVulkan : public GPUResourceVulkan<GPUVertexLayout>
|
||||
{
|
||||
public:
|
||||
GPUVertexLayoutVulkan(GPUDeviceVulkan* device, const Elements& elements);
|
||||
GPUVertexLayoutVulkan(GPUDeviceVulkan* device, const Elements& elements, bool explicitOffsets);
|
||||
|
||||
VkPipelineVertexInputStateCreateInfo CreateInfo;
|
||||
VkVertexInputBindingDescription Bindings[GPU_MAX_VB_BINDED];
|
||||
|
||||
Reference in New Issue
Block a user