Fix binding missing vertex buffer slots to zero data on D3D11 and D3D12
This commit is contained in:
@@ -114,6 +114,12 @@ void GPUContextDX11::FrameBegin()
|
||||
CurrentPrimitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED;
|
||||
CurrentStencilRef = 0;
|
||||
CurrentBlendFactor = Float4::One;
|
||||
|
||||
// Bind dummy vertex buffer (used by missing bindings)
|
||||
auto dummyVB = (GPUBufferDX11*)_device->GetDummyVB();
|
||||
ID3D11Buffer* dummyVBBuffer = dummyVB->GetBuffer();
|
||||
UINT stride = dummyVB->GetStride(), offset = 0;
|
||||
_context->IASetVertexBuffers(GPU_MAX_VB_BINDED, 1, &dummyVBBuffer, &stride, &offset);
|
||||
|
||||
// Bind static samplers
|
||||
ID3D11SamplerState* samplers[] =
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "GPUSwapChainDX11.h"
|
||||
#include "Engine/Core/Log.h"
|
||||
#include "Engine/Core/Utilities.h"
|
||||
#include "Engine/Core/Math/Color32.h"
|
||||
#include "Engine/Threading/Threading.h"
|
||||
#include "Engine/GraphicsDevice/DirectX/RenderToolsDX.h"
|
||||
#include "Engine/Graphics/PixelFormatExtensions.h"
|
||||
@@ -403,6 +404,17 @@ ID3D11BlendState* GPUDeviceDX11::GetBlendState(const BlendingMode& blending)
|
||||
return state;
|
||||
}
|
||||
|
||||
GPUBuffer* GPUDeviceDX11::GetDummyVB()
|
||||
{
|
||||
if (!_dummyVB)
|
||||
{
|
||||
_dummyVB = CreateBuffer(TEXT("DummyVertexBuffer"));
|
||||
auto* layout = GPUVertexLayout::Get({{ VertexElement::Types::Attribute3, 0, 0, 0, PixelFormat::R8G8B8A8_UNorm }});
|
||||
_dummyVB->Init(GPUBufferDescription::Vertex(layout, sizeof(Color32), 1, &Color32::Transparent));
|
||||
}
|
||||
return _dummyVB;
|
||||
}
|
||||
|
||||
bool GPUDeviceDX11::Init()
|
||||
{
|
||||
HRESULT result;
|
||||
@@ -560,6 +572,7 @@ bool GPUDeviceDX11::Init()
|
||||
D3D11_MESSAGE_ID_DEVICE_DRAW_INDEX_BUFFER_TOO_SMALL,
|
||||
D3D11_MESSAGE_ID_DEVICE_DRAW_RENDERTARGETVIEW_NOT_SET,
|
||||
D3D11_MESSAGE_ID_SETPRIVATEDATA_CHANGINGPARAMS,
|
||||
D3D11_MESSAGE_ID_DEVICE_DRAW_VERTEX_BUFFER_TOO_SMALL,
|
||||
};
|
||||
|
||||
filter.DenyList.NumIDs = ARRAY_COUNT(disabledMessages);
|
||||
|
||||
@@ -59,6 +59,7 @@ private:
|
||||
|
||||
GPUContextDX11* _mainContext = nullptr;
|
||||
bool _allowTearing = false;
|
||||
GPUBuffer* _dummyVB = nullptr;
|
||||
|
||||
// Static Samplers
|
||||
ID3D11SamplerState* _samplerLinearClamp = nullptr;
|
||||
@@ -106,6 +107,7 @@ public:
|
||||
|
||||
ID3D11DepthStencilState* GetDepthStencilState(const void* descriptionPtr);
|
||||
ID3D11BlendState* GetBlendState(const BlendingMode& blending);
|
||||
GPUBuffer* GetDummyVB();
|
||||
|
||||
public:
|
||||
|
||||
|
||||
@@ -29,8 +29,9 @@ ID3D11InputLayout* GPUShaderProgramVSDX11::GetInputLayout(GPUVertexLayoutDX11* v
|
||||
GPUVertexLayoutDX11* mergedVertexLayout = vertexLayout;
|
||||
if (!mergedVertexLayout)
|
||||
mergedVertexLayout = (GPUVertexLayoutDX11*)Layout; // Fallback to shader-specified layout (if using old APIs)
|
||||
int32 missingSlotOverride = GPU_MAX_VB_BINDED; // Use additional slot with empty VB
|
||||
if (InputLayout)
|
||||
mergedVertexLayout = (GPUVertexLayoutDX11*)GPUVertexLayout::Merge(mergedVertexLayout, InputLayout);
|
||||
mergedVertexLayout = (GPUVertexLayoutDX11*)GPUVertexLayout::Merge(mergedVertexLayout, InputLayout, false, true, missingSlotOverride);
|
||||
LOG_DIRECTX_RESULT(vertexLayout->GetDevice()->GetDevice()->CreateInputLayout(mergedVertexLayout->InputElements, mergedVertexLayout->InputElementsCount, Bytecode.Get(), Bytecode.Length(), &inputLayout));
|
||||
}
|
||||
_cache.Add(vertexLayout, inputLayout);
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
#include <d3d12.h>
|
||||
#include <ThirdParty/WinPixEventRuntime/pix3.h>
|
||||
#endif
|
||||
|
||||
#include "GPUContextDX12.h"
|
||||
#include "Engine/Core/Log.h"
|
||||
#include "Engine/Core/Math/Color32.h"
|
||||
#include "Engine/Core/Math/Viewport.h"
|
||||
#include "Engine/Core/Math/Rectangle.h"
|
||||
#include "GPUShaderDX12.h"
|
||||
@@ -250,6 +250,17 @@ void GPUContextDX12::Reset()
|
||||
Platform::MemoryClear(&_cbHandles, sizeof(_cbHandles));
|
||||
Platform::MemoryClear(&_samplers, sizeof(_samplers));
|
||||
_swapChainsUsed = 0;
|
||||
|
||||
// Bind dummy vertex buffer (used by missing bindings)
|
||||
D3D12_VERTEX_BUFFER_VIEW dummyVBView;
|
||||
if (!_device->DummyVB)
|
||||
{
|
||||
_device->DummyVB = _device->CreateBuffer(TEXT("DummyVertexBuffer"));
|
||||
auto* layout = GPUVertexLayout::Get({{ VertexElement::Types::Attribute3, 0, 0, 0, PixelFormat::R8G8B8A8_UNorm }});
|
||||
_device->DummyVB->Init(GPUBufferDescription::Vertex(layout, sizeof(Color32), 1, &Color32::Transparent));
|
||||
}
|
||||
((GPUBufferDX12*)_device->DummyVB)->GetVBView(dummyVBView);
|
||||
_commandList->IASetVertexBuffers(GPU_MAX_VB_BINDED, 1, &dummyVBView);
|
||||
|
||||
ForceRebindDescriptors();
|
||||
}
|
||||
|
||||
@@ -797,6 +797,7 @@ void GPUDeviceDX12::Dispose()
|
||||
updateRes2Dispose();
|
||||
|
||||
// Clear pipeline objects
|
||||
SAFE_DELETE_GPU_RESOURCE(DummyVB);
|
||||
for (auto& srv : _nullSrv)
|
||||
srv.Release();
|
||||
_nullUav.Release();
|
||||
|
||||
@@ -85,6 +85,7 @@ public:
|
||||
CommandSignatureDX12* DispatchIndirectCommandSignature = nullptr;
|
||||
CommandSignatureDX12* DrawIndexedIndirectCommandSignature = nullptr;
|
||||
CommandSignatureDX12* DrawIndirectCommandSignature = nullptr;
|
||||
GPUBuffer* DummyVB = nullptr;
|
||||
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE NullSRV(D3D12_SRV_DIMENSION dimension) const;
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE NullUAV() const;
|
||||
|
||||
@@ -87,8 +87,9 @@ ID3D12PipelineState* GPUPipelineStateDX12::GetState(GPUTextureViewDX12* depth, i
|
||||
vertexLayout = VertexBufferLayout; // Fallback to shader-specified layout (if using old APIs)
|
||||
if (vertexLayout)
|
||||
{
|
||||
int32 missingSlotOverride = GPU_MAX_VB_BINDED; // Use additional slot with empty VB
|
||||
if (VertexInputLayout)
|
||||
vertexLayout = (GPUVertexLayoutDX12*)GPUVertexLayout::Merge(vertexLayout, VertexInputLayout);
|
||||
vertexLayout = (GPUVertexLayoutDX12*)GPUVertexLayout::Merge(vertexLayout, VertexInputLayout, false, true, missingSlotOverride);
|
||||
_desc.InputLayout.pInputElementDescs = vertexLayout->InputElements;
|
||||
_desc.InputLayout.NumElements = vertexLayout->InputElementsCount;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user