- move most push constants to dynamic uniform buffers

This commit is contained in:
Magnus Norddahl 2019-02-26 16:50:54 +01:00
parent d958c4fec5
commit 19f4133768
7 changed files with 64 additions and 37 deletions

View file

@ -58,6 +58,9 @@ void VkRenderPassManager::CreateDynamicSetLayout()
DescriptorSetLayoutBuilder builder;
builder.addBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
builder.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
builder.addBinding(2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
builder.addBinding(3, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
builder.addBinding(4, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
DynamicSetLayout = builder.create(GetVulkanFrameBuffer()->device);
}
@ -87,7 +90,7 @@ void VkRenderPassManager::CreatePipelineLayout()
void VkRenderPassManager::CreateDescriptorPool()
{
DescriptorPoolBuilder builder;
builder.addPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1);
builder.addPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 4);
builder.addPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1);
builder.addPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 512 * 6);
builder.setMaxSets(512);
@ -102,6 +105,9 @@ void VkRenderPassManager::CreateDynamicSet()
WriteDescriptors update;
update.addBuffer(DynamicSet.get(), 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->ViewpointUBO->mBuffer.get(), 0, sizeof(HWViewpointUniforms));
update.addBuffer(DynamicSet.get(), 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, fb->LightBufferSSO->mBuffer.get(), 0, 4096);
update.addBuffer(DynamicSet.get(), 2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->MatricesUBO->mBuffer.get(), 0, sizeof(MatricesUBO));
update.addBuffer(DynamicSet.get(), 3, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->ColorsUBO->mBuffer.get(), 0, sizeof(ColorsUBO));
update.addBuffer(DynamicSet.get(), 4, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->GlowingWallsUBO->mBuffer.get(), 0, sizeof(GlowingWallsUBO));
update.updateSets(fb->device);
}

View file

@ -42,7 +42,7 @@ void VkRenderState::Draw(int dt, int index, int count, bool apply)
BindDescriptorSets();
drawcalls.Clock();
//mCommandBuffer->draw(count, 1, index, 0);
mCommandBuffer->draw(count, 1, index, 0);
drawcalls.Unclock();
}
@ -54,7 +54,7 @@ void VkRenderState::DrawIndexed(int dt, int index, int count, bool apply)
BindDescriptorSets();
drawcalls.Clock();
//mCommandBuffer->drawIndexed(count, 1, 0, index * (int)sizeof(uint32_t), 0);
mCommandBuffer->drawIndexed(count, 1, 0, index * (int)sizeof(uint32_t), 0);
drawcalls.Unclock();
}
@ -155,9 +155,7 @@ void VkRenderState::Apply(int dt)
mCommandBuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, passSetup->Pipeline.get());
}
// To do: maybe only push the subset that changed?
static_assert(sizeof(PushConstants) % 16 == 0, "std140 layouts must be 16 byte aligned");
//mCommandBuffer->pushConstants(passManager->PipelineLayout.get(), VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, (uint32_t)sizeof(PushConstants), &mPushConstants);
mCommandBuffer->pushConstants(passManager->PipelineLayout.get(), VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, (uint32_t)sizeof(PushConstants), &mPushConstants);
VkBuffer vertexBuffers[] = { static_cast<VKVertexBuffer*>(mVertexBuffer)->mBuffer->buffer };
VkDeviceSize offsets[] = { 0 };
@ -196,8 +194,8 @@ void VkRenderState::BindDescriptorSets()
auto fb = GetVulkanFrameBuffer();
auto passManager = fb->GetRenderPassManager();
uint32_t offsets[2] = { mViewpointOffset, mLightBufferOffset };
mCommandBuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, passManager->PipelineLayout.get(), 0, passManager->DynamicSet.get(), 2, offsets);
uint32_t offsets[5] = { mViewpointOffset, mLightBufferOffset, mMatricesOffset, mColorsOffset, mGlowingWallsOffset };
mCommandBuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, passManager->PipelineLayout.get(), 0, passManager->DynamicSet.get(), 5, offsets);
mDescriptorsChanged = false;
}

View file

@ -50,6 +50,9 @@ private:
PushConstants mPushConstants;
bool mDescriptorsChanged = true;
uint32_t mViewpointOffset = 0, mLastViewpointOffset = 0;
uint32_t mLightBufferOffset = 0, mLastLightBufferOffset = 0;
uint32_t mViewpointOffset = 0;
uint32_t mLightBufferOffset = 0;
uint32_t mMatricesOffset = 0;
uint32_t mColorsOffset = 0;
uint32_t mGlowingWallsOffset = 0;
};

View file

@ -46,28 +46,13 @@ static const char *shaderBindings = R"(
vec4 lights[];
};
// textures
layout(set = 1, binding = 0) uniform sampler2D tex;
// layout(set = 1, binding = 1) uniform sampler2D texture2;
// layout(set = 1, binding = 2) uniform sampler2D texture3;
// layout(set = 1, binding = 3) uniform sampler2D texture4;
// layout(set = 1, binding = 4) uniform sampler2D texture5;
// layout(set = 1, binding = 5) uniform sampler2D texture6;
// layout(set = 1, binding = 16) uniform sampler2D ShadowMap;
// This must match the PushConstants struct
layout(push_constant, std140) uniform PushConstants
{
// matrices
layout(set = 0, binding = 2, std140) uniform MatricesUBO {
mat4 ModelMatrix;
mat4 NormalModelMatrix;
mat4 TextureMatrix;
};
int uTextureMode;
float uAlphaThreshold;
vec2 uClipSplit;
// colors
layout(set = 0, binding = 3, std140) uniform ColorsUBO {
vec4 uObjectColor;
vec4 uObjectColor2;
vec4 uDynLightColor;
@ -76,8 +61,9 @@ static const char *shaderBindings = R"(
float uDesaturationFactor;
float uInterpolationFactor;
float padding0, padding1;
};
// Glowing walls stuff
layout(set = 0, binding = 4, std140) uniform GlowingWallsUBO {
vec4 uGlowTopPlane;
vec4 uGlowTopColor;
vec4 uGlowBottomPlane;
@ -88,6 +74,23 @@ static const char *shaderBindings = R"(
vec4 uSplitTopPlane;
vec4 uSplitBottomPlane;
};
// textures
layout(set = 1, binding = 0) uniform sampler2D tex;
// layout(set = 1, binding = 1) uniform sampler2D texture2;
// layout(set = 1, binding = 2) uniform sampler2D texture3;
// layout(set = 1, binding = 3) uniform sampler2D texture4;
// layout(set = 1, binding = 4) uniform sampler2D texture5;
// layout(set = 1, binding = 5) uniform sampler2D texture6;
// layout(set = 1, binding = 16) uniform sampler2D ShadowMap;
// This must match the PushConstants struct
layout(push_constant) uniform PushConstants
{
int uTextureMode;
float uAlphaThreshold;
vec2 uClipSplit;
// Lighting + Fog
float uLightLevel;

View file

@ -8,18 +8,15 @@
class VulkanDevice;
class VulkanShader;
struct PushConstants
struct MatricesUBO
{
// matrices
VSMatrix ModelMatrix;
VSMatrix NormalModelMatrix;
VSMatrix TextureMatrix;
};
int uTextureMode;
float uAlphaThreshold;
FVector2 uClipSplit;
// colors
struct ColorsUBO
{
FVector4 uObjectColor;
FVector4 uObjectColor2;
FVector4 uDynLightColor;
@ -28,8 +25,10 @@ struct PushConstants
float uDesaturationFactor;
float uInterpolationFactor;
float padding0, padding1;
};
// Glowing walls stuff
struct GlowingWallsUBO
{
FVector4 uGlowTopPlane;
FVector4 uGlowTopColor;
FVector4 uGlowBottomPlane;
@ -40,6 +39,13 @@ struct PushConstants
FVector4 uSplitTopPlane;
FVector4 uSplitBottomPlane;
};
struct PushConstants
{
int uTextureMode;
float uAlphaThreshold;
FVector2 uClipSplit;
// Lighting + Fog
float uLightLevel;

View file

@ -77,6 +77,14 @@ void VulkanFrameBuffer::InitializeState()
mViewpoints = new GLViewpointBuffer;
mLights = new FLightBuffer();
// To do: move this to HW renderer interface maybe?
MatricesUBO = (VKDataBuffer*)CreateDataBuffer(1234, false);
ColorsUBO = (VKDataBuffer*)CreateDataBuffer(1234, false);
GlowingWallsUBO = (VKDataBuffer*)CreateDataBuffer(1234, false);
MatricesUBO->SetData(sizeof(MatricesUBO) * 128, 0, false);
ColorsUBO->SetData(sizeof(ColorsUBO) * 128, 0, false);
GlowingWallsUBO->SetData(sizeof(GlowingWallsUBO) * 128, 0, false);
mShaderManager.reset(new VkShaderManager(device));
mSamplerManager.reset(new VkSamplerManager(device));
mRenderPassManager.reset(new VkRenderPassManager());

View file

@ -28,6 +28,9 @@ public:
VKDataBuffer *ViewpointUBO = nullptr;
VKDataBuffer *LightBufferSSO = nullptr;
VKDataBuffer *MatricesUBO = nullptr;
VKDataBuffer *ColorsUBO = nullptr;
VKDataBuffer *GlowingWallsUBO = nullptr;
VulkanFrameBuffer(void *hMonitor, bool fullscreen, VulkanDevice *dev);
~VulkanFrameBuffer();