Fixes for Vulkan backend after recent changes
This commit is contained in:
@@ -651,14 +651,14 @@ void GPUContextVulkan::OnDrawCall()
|
||||
}
|
||||
|
||||
// Bind any missing vertex buffers to null if required by the current state
|
||||
GPUVertexLayoutVulkan* vertexLayout = _vertexLayout ? _vertexLayout : pipelineState->VertexShaderLayout;
|
||||
GPUVertexLayoutVulkan* vertexLayout = _vertexLayout ? _vertexLayout : pipelineState->VertexBufferLayout;
|
||||
#if GPU_ENABLE_ASSERTION_LOW_LAYERS
|
||||
if (!vertexLayout && pipelineState && !pipelineState->VertexShaderLayout && (pipelineState->UsedStagesMask & (1 << (int32)DescriptorSet::Vertex)) != 0 && !_vertexLayout && _vbCount)
|
||||
if (!vertexLayout && pipelineState && !pipelineState->VertexBufferLayout && (pipelineState->UsedStagesMask & (1 << (int32)DescriptorSet::Vertex)) != 0 && !_vertexLayout && _vbCount)
|
||||
{
|
||||
LOG(Error, "Missing Vertex Layout (not assigned to GPUBuffer). Vertex Shader won't read valid data resulting incorrect visuals.");
|
||||
}
|
||||
#endif
|
||||
const int32 missingVBs = vertexLayout ? (int32)vertexLayout->CreateInfo.vertexBindingDescriptionCount - _vbCount : 0;
|
||||
const int32 missingVBs = vertexLayout ? vertexLayout->MaxSlot + 1 - _vbCount : 0;
|
||||
if (missingVBs > 0)
|
||||
{
|
||||
VkBuffer buffers[GPU_MAX_VB_BINDED];
|
||||
@@ -1034,7 +1034,13 @@ void GPUContextVulkan::BindUA(int32 slot, GPUResourceView* view)
|
||||
void GPUContextVulkan::BindVB(const Span<GPUBuffer*>& vertexBuffers, const uint32* vertexBuffersOffsets, GPUVertexLayout* vertexLayout)
|
||||
{
|
||||
_vbCount = vertexBuffers.Length();
|
||||
_vertexLayout = (GPUVertexLayoutVulkan*)(vertexLayout ? vertexLayout : GPUVertexLayout::Get(vertexBuffers));
|
||||
if (!vertexLayout)
|
||||
vertexLayout = GPUVertexLayout::Get(vertexBuffers);
|
||||
if (_vertexLayout != vertexLayout)
|
||||
{
|
||||
_vertexLayout = (GPUVertexLayoutVulkan*)vertexLayout;
|
||||
_psDirtyFlag = true;
|
||||
}
|
||||
if (vertexBuffers.Length() == 0)
|
||||
return;
|
||||
const auto cmdBuffer = _cmdBufferManager->GetCmdBuffer();
|
||||
|
||||
@@ -453,39 +453,12 @@ GPUVertexLayoutVulkan::GPUVertexLayoutVulkan(GPUDeviceVulkan* device, const Elem
|
||||
: GPUResourceVulkan<GPUVertexLayout>(device, StringView::Empty)
|
||||
{
|
||||
SetElements(elements, explicitOffsets);
|
||||
for (int32 i = 0; i < GPU_MAX_VB_BINDED; i++)
|
||||
{
|
||||
VkVertexInputBindingDescription& binding = Bindings[i];
|
||||
binding.binding = i;
|
||||
binding.stride = 0;
|
||||
binding.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
|
||||
}
|
||||
uint32 bindingsCount = 0;
|
||||
MaxSlot = 0;
|
||||
for (int32 i = 0; i < elements.Count(); i++)
|
||||
{
|
||||
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)(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 = src.Offset;
|
||||
|
||||
bindingsCount = Math::Max(bindingsCount, (uint32)src.Slot + 1);
|
||||
MaxSlot = Math::Max(MaxSlot, (int32)src.Slot);
|
||||
}
|
||||
|
||||
RenderToolsVulkan::ZeroStruct(CreateInfo, VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO);
|
||||
CreateInfo.vertexBindingDescriptionCount = bindingsCount;
|
||||
CreateInfo.pVertexBindingDescriptions = Bindings;
|
||||
CreateInfo.vertexAttributeDescriptionCount = elements.Count();
|
||||
CreateInfo.pVertexAttributeDescriptions = Attributes;
|
||||
}
|
||||
|
||||
FramebufferVulkan::FramebufferVulkan(GPUDeviceVulkan* device, const Key& key, const VkExtent2D& extent, uint32 layers)
|
||||
@@ -936,7 +909,8 @@ GPUBufferVulkan* HelperResourcesVulkan::GetDummyVertexBuffer()
|
||||
if (!_dummyVB)
|
||||
{
|
||||
_dummyVB = (GPUBufferVulkan*)_device->CreateBuffer(TEXT("DummyVertexBuffer"));
|
||||
_dummyVB->Init(GPUBufferDescription::Vertex(nullptr, sizeof(Color32), 1, &Color32::Transparent));
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "Engine/Core/Log.h"
|
||||
#include "Engine/Core/Types/Pair.h"
|
||||
#include "Engine/Profiler/ProfilerCPU.h"
|
||||
#include "Engine/Graphics/PixelFormatExtensions.h"
|
||||
|
||||
static VkStencilOp ToVulkanStencilOp(const StencilOperation value)
|
||||
{
|
||||
@@ -222,8 +223,54 @@ VkPipeline GPUPipelineStateVulkan::GetState(RenderPassVulkan* renderPass, GPUVer
|
||||
PROFILE_CPU_NAMED("Create Pipeline");
|
||||
|
||||
// Bind vertex input
|
||||
vertexLayout = (GPUVertexLayoutVulkan*)GPUVertexLayout::Merge(vertexLayout, VertexShaderLayout);
|
||||
_desc.pVertexInputState = vertexLayout ? &vertexLayout->CreateInfo : nullptr;
|
||||
VkPipelineVertexInputStateCreateInfo vertexInputCreateInfo;
|
||||
VkVertexInputBindingDescription vertexInputBindings[GPU_MAX_VB_BINDED];
|
||||
VkVertexInputAttributeDescription vertexInputAttributes[GPU_MAX_VS_ELEMENTS];
|
||||
_desc.pVertexInputState = nullptr;
|
||||
if (!vertexLayout)
|
||||
vertexLayout = VertexBufferLayout; // Fallback to shader-specified layout (if using old APIs)
|
||||
if (vertexLayout)
|
||||
{
|
||||
// Vertex bindings based on vertex buffers assigned
|
||||
for (int32 i = 0; i < GPU_MAX_VB_BINDED; i++)
|
||||
{
|
||||
VkVertexInputBindingDescription& binding = vertexInputBindings[i];
|
||||
binding.binding = i;
|
||||
binding.stride = 0;
|
||||
binding.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
|
||||
}
|
||||
uint32 bindingsCount = 0;
|
||||
for (int32 i = 0; i < vertexLayout->GetElements().Count(); i++)
|
||||
{
|
||||
const VertexElement& src = vertexLayout->GetElements().Get()[i];
|
||||
const int32 size = PixelFormatExtensions::SizeInBytes(src.Format);
|
||||
ASSERT_LOW_LAYER(src.Slot < GPU_MAX_VB_BINDED);
|
||||
VkVertexInputBindingDescription& binding = vertexInputBindings[src.Slot];
|
||||
binding.binding = src.Slot;
|
||||
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;
|
||||
bindingsCount = Math::Max(bindingsCount, (uint32)src.Slot + 1);
|
||||
}
|
||||
|
||||
// Vertex elements (including any merged elements from reference layout from shader reflection)
|
||||
vertexLayout = (GPUVertexLayoutVulkan*)GPUVertexLayout::Merge(vertexLayout, VertexInputLayout, true, true);
|
||||
for (int32 i = 0; i < vertexLayout->GetElements().Count(); i++)
|
||||
{
|
||||
const VertexElement& src = vertexLayout->GetElements().Get()[i];
|
||||
VkVertexInputAttributeDescription& attribute = vertexInputAttributes[i];
|
||||
attribute.location = i;
|
||||
attribute.binding = src.Slot;
|
||||
attribute.format = RenderToolsVulkan::ToVulkanFormat(src.Format);
|
||||
attribute.offset = src.Offset;
|
||||
}
|
||||
|
||||
RenderToolsVulkan::ZeroStruct(vertexInputCreateInfo, VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO);
|
||||
vertexInputCreateInfo.vertexBindingDescriptionCount = bindingsCount;
|
||||
vertexInputCreateInfo.pVertexBindingDescriptions = vertexInputBindings;
|
||||
vertexInputCreateInfo.vertexAttributeDescriptionCount = vertexLayout->GetElements().Count();
|
||||
vertexInputCreateInfo.pVertexAttributeDescriptions = vertexInputAttributes;
|
||||
_desc.pVertexInputState = &vertexInputCreateInfo;
|
||||
}
|
||||
|
||||
// Update description to match the pipeline
|
||||
_descColorBlend.attachmentCount = renderPass->Layout.RTsCount;
|
||||
@@ -320,7 +367,11 @@ bool GPUPipelineStateVulkan::Init(const Description& desc)
|
||||
_desc.pStages = _shaderStages;
|
||||
|
||||
// Input Assembly
|
||||
VertexShaderLayout = desc.VS ? (GPUVertexLayoutVulkan*)(desc.VS->Layout ? desc.VS->Layout : desc.VS->InputLayout) : nullptr;
|
||||
if (desc.VS)
|
||||
{
|
||||
VertexInputLayout = (GPUVertexLayoutVulkan*)desc.VS->InputLayout;
|
||||
VertexBufferLayout = (GPUVertexLayoutVulkan*)desc.VS->Layout;
|
||||
}
|
||||
RenderToolsVulkan::ZeroStruct(_descInputAssembly, VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO);;
|
||||
switch (desc.PrimitiveTopology)
|
||||
{
|
||||
|
||||
@@ -146,7 +146,8 @@ public:
|
||||
|
||||
const DescriptorSetLayoutVulkan* DescriptorSetsLayout = nullptr;
|
||||
TypedDescriptorPoolSetVulkan* CurrentTypedDescriptorPoolSet = nullptr;
|
||||
GPUVertexLayoutVulkan* VertexShaderLayout = nullptr;
|
||||
GPUVertexLayoutVulkan* VertexInputLayout = nullptr;
|
||||
GPUVertexLayoutVulkan* VertexBufferLayout = nullptr;
|
||||
Array<VkDescriptorSet> DescriptorSetHandles;
|
||||
Array<uint32> DynamicOffsets;
|
||||
|
||||
|
||||
@@ -15,9 +15,7 @@ class GPUVertexLayoutVulkan : public GPUResourceVulkan<GPUVertexLayout>
|
||||
public:
|
||||
GPUVertexLayoutVulkan(GPUDeviceVulkan* device, const Elements& elements, bool explicitOffsets);
|
||||
|
||||
VkPipelineVertexInputStateCreateInfo CreateInfo;
|
||||
VkVertexInputBindingDescription Bindings[GPU_MAX_VB_BINDED];
|
||||
VkVertexInputAttributeDescription Attributes[GPU_MAX_VS_ELEMENTS];
|
||||
int32 MaxSlot;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user