- bind the vertex inputs as specified by its vertex buffer format

This commit is contained in:
Magnus Norddahl 2019-03-01 15:37:13 +01:00
parent b0fd5db616
commit c691a8fe64
6 changed files with 78 additions and 27 deletions

View file

@ -9,6 +9,10 @@
#include "rendering/2d/v_2ddrawer.h"
VkRenderPassManager::VkRenderPassManager()
{
}
void VkRenderPassManager::Init()
{
CreateDynamicSetLayout();
CreateTextureSetLayout();
@ -60,6 +64,37 @@ VkRenderPassSetup *VkRenderPassManager::GetRenderPass(const VkRenderPassKey &key
return item.get();
}
int VkRenderPassManager::GetVertexFormat(int numBindingPoints, int numAttributes, size_t stride, const FVertexBufferAttribute *attrs)
{
for (size_t i = 0; i < VertexFormats.size(); i++)
{
const auto &f = VertexFormats[i];
if (f.Attrs.size() == numAttributes && f.NumBindingPoints == numBindingPoints && f.Stride == stride)
{
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;
}
}
VkVertexFormat fmt;
fmt.NumBindingPoints = numBindingPoints;
fmt.Stride = stride;
for (int j = 0; j < numAttributes; j++)
fmt.Attrs.push_back(attrs[j]);
VertexFormats.push_back(fmt);
return (int)VertexFormats.size() - 1;
}
void VkRenderPassManager::CreateDynamicSetLayout()
{
DescriptorSetLayoutBuilder builder;
@ -151,24 +186,25 @@ void VkRenderPassSetup::CreatePipeline(const VkRenderPassKey &key)
builder.addVertexShader(program->vert.get());
builder.addFragmentShader(program->frag.get());
builder.addVertexBufferBinding(0, sizeof(F2DDrawer::TwoDVertex));
builder.addVertexAttribute(0, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(F2DDrawer::TwoDVertex, x));
builder.addVertexAttribute(1, 0, VK_FORMAT_R32G32_SFLOAT, offsetof(F2DDrawer::TwoDVertex, u));
builder.addVertexAttribute(2, 0, VK_FORMAT_R8G8B8A8_UNORM, offsetof(F2DDrawer::TwoDVertex, color0));
builder.addVertexAttribute(3, 0, VK_FORMAT_R32G32B32A32_SFLOAT, offsetof(F2DDrawer::TwoDVertex, x));
builder.addVertexAttribute(4, 0, VK_FORMAT_R32G32B32A32_SFLOAT, offsetof(F2DDrawer::TwoDVertex, x));
builder.addVertexAttribute(5, 0, VK_FORMAT_R32G32B32A32_SFLOAT, offsetof(F2DDrawer::TwoDVertex, x));
const VkVertexFormat &vfmt = fb->GetRenderPassManager()->VertexFormats[key.VertexFormat];
#if 0
builder.addVertexBufferBinding(0, sizeof(FFlatVertex));
builder.addVertexAttribute(0, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(FFlatVertex, x));
builder.addVertexAttribute(1, 0, VK_FORMAT_R32G32_SFLOAT, offsetof(FFlatVertex, u));
// To do: not all vertex formats has all the data..
builder.addVertexAttribute(2, 0, VK_FORMAT_R32G32B32A32_SFLOAT, offsetof(FFlatVertex, x));
builder.addVertexAttribute(3, 0, VK_FORMAT_R32G32B32A32_SFLOAT, offsetof(FFlatVertex, x));
builder.addVertexAttribute(4, 0, VK_FORMAT_R32G32B32A32_SFLOAT, offsetof(FFlatVertex, x));
builder.addVertexAttribute(5, 0, VK_FORMAT_R32G32B32A32_SFLOAT, offsetof(FFlatVertex, x));
#endif
for (int i = 0; i < vfmt.NumBindingPoints; i++)
builder.addVertexBufferBinding(i, vfmt.Stride);
const static VkFormat vkfmts[] = {
VK_FORMAT_R32G32B32A32_SFLOAT,
VK_FORMAT_R32G32B32_SFLOAT,
VK_FORMAT_R32G32_SFLOAT,
VK_FORMAT_R32_SFLOAT,
VK_FORMAT_R8G8B8A8_UNORM,
VK_FORMAT_A2R10G10B10_SNORM_PACK32
};
for (size_t i = 0; i < vfmt.Attrs.size(); i++)
{
const auto &attr = vfmt.Attrs[i];
builder.addVertexAttribute(attr.location, attr.binding, vkfmts[attr.format], attr.offset);
}
builder.addDynamicState(VK_DYNAMIC_STATE_VIEWPORT);
builder.addDynamicState(VK_DYNAMIC_STATE_SCISSOR);

View file

@ -3,6 +3,7 @@
#include "vulkan/system/vk_objects.h"
#include "r_data/renderstyle.h"
#include "hwrenderer/data/buffers.h"
#include <map>
class VKDataBuffer;
@ -14,11 +15,12 @@ public:
int SpecialEffect;
int EffectState;
bool AlphaTest;
int VertexFormat;
bool operator<(const VkRenderPassKey &other) const
{
uint64_t a = RenderStyle.AsDWORD | (static_cast<uint64_t>(SpecialEffect) << 32) | (static_cast<uint64_t>(EffectState) << 40) | (static_cast<uint64_t>(AlphaTest) << 48);
uint64_t b = other.RenderStyle.AsDWORD | (static_cast<uint64_t>(other.SpecialEffect) << 32) | (static_cast<uint64_t>(other.EffectState) << 40) | (static_cast<uint64_t>(other.AlphaTest) << 48);
uint64_t a = RenderStyle.AsDWORD | (static_cast<uint64_t>(SpecialEffect) << 32) | (static_cast<uint64_t>(EffectState) << 40) | (static_cast<uint64_t>(AlphaTest) << 48) | (static_cast<uint64_t>(VertexFormat) << 56);
uint64_t b = other.RenderStyle.AsDWORD | (static_cast<uint64_t>(other.SpecialEffect) << 32) | (static_cast<uint64_t>(other.EffectState) << 40) | (static_cast<uint64_t>(other.AlphaTest) << 48) | (static_cast<uint64_t>(other.VertexFormat) << 56);
return a < b;
}
};
@ -38,14 +40,25 @@ private:
void CreateFramebuffer();
};
class VkVertexFormat
{
public:
int NumBindingPoints;
size_t Stride;
std::vector<FVertexBufferAttribute> Attrs;
};
class VkRenderPassManager
{
public:
VkRenderPassManager();
void Init();
void BeginFrame();
VkRenderPassSetup *GetRenderPass(const VkRenderPassKey &key);
int GetVertexFormat(int numBindingPoints, int numAttributes, size_t stride, const FVertexBufferAttribute *attrs);
std::unique_ptr<VulkanDescriptorSetLayout> DynamicSetLayout;
std::unique_ptr<VulkanDescriptorSetLayout> TextureSetLayout;
std::unique_ptr<VulkanPipelineLayout> PipelineLayout;
@ -60,6 +73,8 @@ public:
std::unique_ptr<VulkanDescriptorSet> DynamicSet;
std::vector<VkVertexFormat> VertexFormats;
private:
void CreateDynamicSetLayout();
void CreateTextureSetLayout();

View file

@ -26,13 +26,7 @@ void VkRenderState::ClearScreen()
screen->mViewpoints->Set2D(*this, SCREENWIDTH, SCREENHEIGHT);
SetColor(0, 0, 0);
Apply(DT_TriangleStrip);
/*
glDisable(GL_MULTISAMPLE);
glDisable(GL_DEPTH_TEST);
mCommandBuffer->draw(4, 1, FFlatVertexBuffer::FULLSCREEN_INDEX, 0);
glEnable(GL_DEPTH_TEST);
*/
}
void VkRenderState::Draw(int dt, int index, int count, bool apply)
@ -55,7 +49,6 @@ void VkRenderState::DrawIndexed(int dt, int index, int count, bool apply)
BindDescriptorSets();
drawcalls.Clock();
if (mMaterial.mMaterial)
mCommandBuffer->drawIndexed(count, 1, index, 0, 0);
drawcalls.Unclock();
}
@ -147,6 +140,7 @@ void VkRenderState::Apply(int dt)
// Find a render pass that matches our state
VkRenderPassKey passKey;
passKey.VertexFormat = static_cast<VKVertexBuffer*>(mVertexBuffer)->VertexFormat;
passKey.RenderStyle = mRenderStyle;
if (mSpecialEffect > EFF_NONE)
{

View file

@ -3,6 +3,7 @@
#include "vk_builders.h"
#include "vk_framebuffer.h"
#include "vulkan/renderer/vk_renderstate.h"
#include "vulkan/renderer/vk_renderpass.h"
#include "doomerrors.h"
VKBuffer::~VKBuffer()
@ -119,6 +120,7 @@ void VKBuffer::Unlock()
void VKVertexBuffer::SetFormat(int numBindingPoints, int numAttributes, size_t stride, const FVertexBufferAttribute *attrs)
{
VertexFormat = GetVulkanFrameBuffer()->GetRenderPassManager()->GetVertexFormat(numBindingPoints, numAttributes, stride, attrs);
}
/////////////////////////////////////////////////////////////////////////////

View file

@ -35,6 +35,8 @@ class VKVertexBuffer : public IVertexBuffer, public VKBuffer
public:
VKVertexBuffer() { mBufferType = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; }
void SetFormat(int numBindingPoints, int numAttributes, size_t stride, const FVertexBufferAttribute *attrs) override;
int VertexFormat = -1;
};
class VKIndexBuffer : public IIndexBuffer, public VKBuffer

View file

@ -85,6 +85,8 @@ void VulkanFrameBuffer::InitializeState()
mUploadSemaphore.reset(new VulkanSemaphore(device));
mGraphicsCommandPool.reset(new VulkanCommandPool(device, device->graphicsFamily));
mRenderPassManager.reset(new VkRenderPassManager());
mVertexData = new FFlatVertexBuffer(GetWidth(), GetHeight());
mSkyData = new FSkyVertexBuffer;
mViewpoints = new GLViewpointBuffer;
@ -100,7 +102,7 @@ void VulkanFrameBuffer::InitializeState()
mShaderManager.reset(new VkShaderManager(device));
mSamplerManager.reset(new VkSamplerManager(device));
mRenderPassManager.reset(new VkRenderPassManager());
mRenderPassManager->Init();
mRenderState.reset(new VkRenderState());
}