Fix the second vertex buffer binding bug

This commit is contained in:
Magnus Norddahl 2023-10-23 21:48:20 +02:00
commit f1b15c5000
8 changed files with 38 additions and 40 deletions

View file

@ -73,7 +73,9 @@ void VkBufferManager::RemoveBuffer(VkHardwareBuffer* buffer)
IBuffer* VkBufferManager::CreateVertexBuffer(int numBindingPoints, int numAttributes, size_t stride, const FVertexBufferAttribute* attrs)
{
return new VkHardwareVertexBuffer(fb, fb->GetRenderPassManager()->GetVertexFormat(numBindingPoints, numAttributes, stride, attrs));
std::vector<size_t> bufferStrides;
bufferStrides.resize(numBindingPoints, stride);
return new VkHardwareVertexBuffer(fb, fb->GetRenderPassManager()->GetVertexFormat(bufferStrides, std::vector<FVertexBufferAttribute>(attrs, attrs + numAttributes)));
}
IBuffer* VkBufferManager::CreateIndexBuffer()

View file

@ -30,14 +30,15 @@
VkRSBuffers::VkRSBuffers(VulkanRenderDevice* fb)
{
static const FVertexBufferAttribute format[] =
static std::vector<FVertexBufferAttribute> format =
{
{ 0, VATTR_VERTEX, VFmt_Float4, (int)myoffsetof(FFlatVertex, x) },
{ 0, VATTR_TEXCOORD, VFmt_Float2, (int)myoffsetof(FFlatVertex, u) },
{ 0, VATTR_LIGHTMAP, VFmt_Float2, (int)myoffsetof(FFlatVertex, lu) },
};
static std::vector<size_t> bufferStrides = { sizeof(FFlatVertex), sizeof(FFlatVertex) };
Flatbuffer.VertexFormat = fb->GetRenderPassManager()->GetVertexFormat(1, 3, sizeof(FFlatVertex), format);
Flatbuffer.VertexFormat = fb->GetRenderPassManager()->GetVertexFormat(bufferStrides, format);
Flatbuffer.VertexBuffer = BufferBuilder()
.Usage(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VMA_MEMORY_USAGE_UNKNOWN, VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT)

View file

@ -94,39 +94,30 @@ VkRenderPassSetup *VkRenderPassManager::GetRenderPass(const VkRenderPassKey &key
return item.get();
}
int VkRenderPassManager::GetVertexFormat(int numBindingPoints, int numAttributes, size_t stride, const FVertexBufferAttribute *attrs)
int VkRenderPassManager::GetVertexFormat(const std::vector<size_t>& bufferStrides, const std::vector<FVertexBufferAttribute>& attrs)
{
for (size_t i = 0; i < VertexFormats.size(); i++)
{
const auto &f = VertexFormats[i];
if (f.Attrs.size() == (size_t)numAttributes && f.NumBindingPoints == numBindingPoints && f.Stride == stride)
if (f.BufferStrides.size() == bufferStrides.size() &&
f.Attrs.size() == attrs.size() &&
memcmp(f.BufferStrides.data(), bufferStrides.data(), bufferStrides.size() * sizeof(size_t)) == 0 &&
memcmp(f.Attrs.data(), attrs.data(), attrs.size() * sizeof(FVertexBufferAttribute)) == 0)
{
bool matches = true;
for (int j = 0; j < numAttributes; j++)
{
if (memcmp(&f.Attrs[j], &attrs[j], sizeof(FVertexBufferAttribute)) != 0)
{
matches = false;
break;
}
}
if (matches)
return (int)i;
return (int)i;
}
}
VkVertexFormat fmt;
fmt.NumBindingPoints = numBindingPoints;
fmt.Stride = stride;
fmt.BufferStrides = bufferStrides;
fmt.Attrs = attrs;
fmt.UseVertexData = 0;
for (int j = 0; j < numAttributes; j++)
for (const FVertexBufferAttribute& attr : fmt.Attrs)
{
if (attrs[j].location == VATTR_COLOR)
if (attr.location == VATTR_COLOR)
fmt.UseVertexData |= 1;
else if (attrs[j].location == VATTR_NORMAL)
else if (attr.location == VATTR_NORMAL)
fmt.UseVertexData |= 2;
fmt.Attrs.push_back(attrs[j]);
}
VertexFormats.push_back(fmt);
return (int)VertexFormats.size() - 1;
@ -253,8 +244,8 @@ std::unique_ptr<VulkanPipeline> VkRenderPassSetup::CreatePipeline(const VkPipeli
const VkVertexFormat &vfmt = *fb->GetRenderPassManager()->GetVertexFormat(key.VertexFormat);
for (int i = 0; i < vfmt.NumBindingPoints; i++)
builder.AddVertexBufferBinding(i, vfmt.Stride);
for (int i = 0; i < vfmt.BufferStrides.size(); i++)
builder.AddVertexBufferBinding(i, vfmt.BufferStrides[i]);
const static VkFormat vkfmts[] = {
VK_FORMAT_R32G32B32A32_SFLOAT,

View file

@ -90,8 +90,7 @@ private:
class VkVertexFormat
{
public:
int NumBindingPoints;
size_t Stride;
std::vector<size_t> BufferStrides;
std::vector<FVertexBufferAttribute> Attrs;
int UseVertexData;
};
@ -107,7 +106,7 @@ public:
void RenderBuffersReset();
VkRenderPassSetup *GetRenderPass(const VkRenderPassKey &key);
int GetVertexFormat(int numBindingPoints, int numAttributes, size_t stride, const FVertexBufferAttribute *attrs);
int GetVertexFormat(const std::vector<size_t>& bufferStrides, const std::vector<FVertexBufferAttribute>& attrs);
VkVertexFormat *GetVertexFormat(int index);
VulkanPipelineLayout* GetPipelineLayout(int numLayers, bool levelmesh);

View file

@ -658,14 +658,14 @@ void VulkanRenderDevice::DrawLevelMesh(const HWViewpointUniforms& viewpoint)
cmdbuffer->setStencilReference(VK_STENCIL_FRONT_AND_BACK, 0);
cmdbuffer->setDepthBias(0.0f, 0.0f, 0.0f);
static const FVertexBufferAttribute format[] =
static const std::vector<FVertexBufferAttribute> format =
{
{ 0, VATTR_VERTEX, VFmt_Float4, (int)myoffsetof(FFlatVertex, x) },
{ 0, VATTR_TEXCOORD, VFmt_Float2, (int)myoffsetof(FFlatVertex, u) },
{ 0, VATTR_LIGHTMAP, VFmt_Float2, (int)myoffsetof(FFlatVertex, lu) },
{ 1, VATTR_UNIFORM_INDEXES, VFmt_Int, 0 }
};
int vertexFormatIndex = GetRenderPassManager()->GetVertexFormat(2, 4, sizeof(FFlatVertex), format);
int vertexFormatIndex = GetRenderPassManager()->GetVertexFormat({ sizeof(FFlatVertex), sizeof(int32_t) }, format);
VkBuffer vertexBuffers[2] = { GetRaytrace()->GetVertexBuffer()->buffer, GetRaytrace()->GetUniformIndexBuffer()->buffer };
VkDeviceSize vertexBufferOffsets[] = { 0, 0 };
cmdbuffer->bindVertexBuffers(0, 2, vertexBuffers, vertexBufferOffsets);

View file

@ -443,19 +443,20 @@ void VkRenderState::ApplyVertexBuffers()
{
if ((mVertexBuffer != mLastVertexBuffer || mVertexOffsets[0] != mLastVertexOffsets[0] || mVertexOffsets[1] != mLastVertexOffsets[1]))
{
// Note: second [0] for BufferStrides is not a typo. Not all the vertex formats have a second buffer and the entire thing assumes they have the same stride anyway.
if (mVertexBuffer)
{
auto vkbuf = static_cast<VkHardwareVertexBuffer*>(mVertexBuffer);
const VkVertexFormat* format = fb->GetRenderPassManager()->GetVertexFormat(vkbuf->VertexFormat);
VkBuffer vertexBuffers[2] = { vkbuf->mBuffer->buffer, vkbuf->mBuffer->buffer };
VkDeviceSize offsets[] = { mVertexOffsets[0] * format->Stride, mVertexOffsets[1] * format->Stride };
VkDeviceSize offsets[] = { mVertexOffsets[0] * format->BufferStrides[0], mVertexOffsets[1] * format->BufferStrides[0]};
mCommandBuffer->bindVertexBuffers(0, 2, vertexBuffers, offsets);
}
else
{
const VkVertexFormat* format = fb->GetRenderPassManager()->GetVertexFormat(mRSBuffers->Flatbuffer.VertexFormat);
VkBuffer vertexBuffers[2] = { mRSBuffers->Flatbuffer.VertexBuffer->buffer, mRSBuffers->Flatbuffer.VertexBuffer->buffer };
VkDeviceSize offsets[] = { mVertexOffsets[0] * format->Stride, mVertexOffsets[1] * format->Stride };
VkDeviceSize offsets[] = { mVertexOffsets[0] * format->BufferStrides[0], mVertexOffsets[1] * format->BufferStrides[0]};
mCommandBuffer->bindVertexBuffers(0, 2, vertexBuffers, offsets);
}

View file

@ -1231,6 +1231,8 @@ void DoomLevelSubmesh::CreateFloorSurface(FLevelLocals &doomMap, subsector_t *su
float h = txt->GetDisplayHeight();
VSMatrix mat = GetPlaneTextureRotationMatrix(txt, sector, sector_t::floor);
int surfaceIndex = Surfaces.Size();
MeshVertices.Resize(surf.startVertIndex + surf.numVerts);
FFlatVertex* verts = &MeshVertices[surf.startVertIndex];
@ -1246,6 +1248,8 @@ void DoomLevelSubmesh::CreateFloorSurface(FLevelLocals &doomMap, subsector_t *su
verts[j].z = (float)plane.ZatPoint(v1);
verts[j].u = uv.X;
verts[j].v = uv.Y;
MeshUniformIndexes.Push(surfaceIndex);
}
surf.Type = ST_FLOOR;
@ -1291,6 +1295,8 @@ void DoomLevelSubmesh::CreateCeilingSurface(FLevelLocals& doomMap, subsector_t*
float h = txt->GetDisplayHeight();
VSMatrix mat = GetPlaneTextureRotationMatrix(txt, sector, sector_t::ceiling);
int surfaceIndex = Surfaces.Size();
MeshVertices.Resize(surf.startVertIndex + surf.numVerts);
FFlatVertex* verts = &MeshVertices[surf.startVertIndex];
@ -1306,6 +1312,8 @@ void DoomLevelSubmesh::CreateCeilingSurface(FLevelLocals& doomMap, subsector_t*
verts[j].z = (float)plane.ZatPoint(v1);
verts[j].u = uv.X;
verts[j].v = uv.Y;
MeshUniformIndexes.Push(surfaceIndex);
}
surf.Type = ST_CEILING;

View file

@ -2,16 +2,12 @@
void main()
{
#ifdef USE_LEVELMESH
/*if (vLightmap.z >= 0.0)
{
FragColor = vec4(texture(LightMap, vLightmap).rgb, 1.0);
}
else
{
FragColor = vec4(vec3(pixelpos.w / 1000), 1.0);
}*/
FragColor.rgb = texture(tex, vTexCoord.st).rgb * (uLightLevel / 255.0);
FragColor.a = 1.0;
if (vLightmap.z >= 0.0)
{
FragColor.rgb *= texture(LightMap, vLightmap).rgb;
}
#else
#ifdef NO_CLIPDISTANCE_SUPPORT