- 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; DescriptorSetLayoutBuilder builder;
builder.addBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT); 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(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); DynamicSetLayout = builder.create(GetVulkanFrameBuffer()->device);
} }
@ -87,7 +90,7 @@ void VkRenderPassManager::CreatePipelineLayout()
void VkRenderPassManager::CreateDescriptorPool() void VkRenderPassManager::CreateDescriptorPool()
{ {
DescriptorPoolBuilder builder; 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_STORAGE_BUFFER_DYNAMIC, 1);
builder.addPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 512 * 6); builder.addPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 512 * 6);
builder.setMaxSets(512); builder.setMaxSets(512);
@ -102,6 +105,9 @@ void VkRenderPassManager::CreateDynamicSet()
WriteDescriptors update; WriteDescriptors update;
update.addBuffer(DynamicSet.get(), 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->ViewpointUBO->mBuffer.get(), 0, sizeof(HWViewpointUniforms)); 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(), 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); update.updateSets(fb->device);
} }

View file

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

View file

@ -50,6 +50,9 @@ private:
PushConstants mPushConstants; PushConstants mPushConstants;
bool mDescriptorsChanged = true; bool mDescriptorsChanged = true;
uint32_t mViewpointOffset = 0, mLastViewpointOffset = 0; uint32_t mViewpointOffset = 0;
uint32_t mLightBufferOffset = 0, mLastLightBufferOffset = 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[]; vec4 lights[];
}; };
// textures layout(set = 0, binding = 2, std140) uniform MatricesUBO {
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
mat4 ModelMatrix; mat4 ModelMatrix;
mat4 NormalModelMatrix; mat4 NormalModelMatrix;
mat4 TextureMatrix; mat4 TextureMatrix;
};
int uTextureMode; layout(set = 0, binding = 3, std140) uniform ColorsUBO {
float uAlphaThreshold;
vec2 uClipSplit;
// colors
vec4 uObjectColor; vec4 uObjectColor;
vec4 uObjectColor2; vec4 uObjectColor2;
vec4 uDynLightColor; vec4 uDynLightColor;
@ -76,8 +61,9 @@ static const char *shaderBindings = R"(
float uDesaturationFactor; float uDesaturationFactor;
float uInterpolationFactor; float uInterpolationFactor;
float padding0, padding1; float padding0, padding1;
};
// Glowing walls stuff layout(set = 0, binding = 4, std140) uniform GlowingWallsUBO {
vec4 uGlowTopPlane; vec4 uGlowTopPlane;
vec4 uGlowTopColor; vec4 uGlowTopColor;
vec4 uGlowBottomPlane; vec4 uGlowBottomPlane;
@ -88,6 +74,23 @@ static const char *shaderBindings = R"(
vec4 uSplitTopPlane; vec4 uSplitTopPlane;
vec4 uSplitBottomPlane; 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 // Lighting + Fog
float uLightLevel; float uLightLevel;

View file

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

View file

@ -77,6 +77,14 @@ void VulkanFrameBuffer::InitializeState()
mViewpoints = new GLViewpointBuffer; mViewpoints = new GLViewpointBuffer;
mLights = new FLightBuffer(); 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)); mShaderManager.reset(new VkShaderManager(device));
mSamplerManager.reset(new VkSamplerManager(device)); mSamplerManager.reset(new VkSamplerManager(device));
mRenderPassManager.reset(new VkRenderPassManager()); mRenderPassManager.reset(new VkRenderPassManager());

View file

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