Improve GPU vertex layout binding in case of missing element from the mesh

This commit is contained in:
Wojtek Figat
2025-01-03 01:09:25 +01:00
parent 348f17479d
commit 7b7dd9d142
17 changed files with 168 additions and 92 deletions

View File

@@ -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)

View File

@@ -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;
};

View File

@@ -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);
}

View File

@@ -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];

View File

@@ -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)

View File

@@ -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;
};

View File

@@ -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];