Shrink VkRenderData from 88 to 64 bytes.

This commit is contained in:
Henrik Rydgård 2022-09-01 14:21:34 +02:00
parent 1cd34f9d2b
commit 9097fdaae6
5 changed files with 39 additions and 30 deletions

View file

@ -347,6 +347,7 @@ void VulkanQueueRunner::RunSteps(VkCommandBuffer cmd, std::vector<VKRStep *> &st
profile->cpuStartTime = time_now_d();
bool emitLabels = vulkan_->Extensions().EXT_debug_utils;
for (size_t i = 0; i < steps.size(); i++) {
const VKRStep &step = *steps[i];
@ -1152,6 +1153,8 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c
// The stencil ones are very commonly mostly redundant so let's eliminate them where possible.
// Might also want to consider scissor and viewport.
VkPipeline lastPipeline = VK_NULL_HANDLE;
VkPipelineLayout pipelineLayout = VK_NULL_HANDLE;
int lastStencilWriteMask = -1;
int lastStencilCompareMask = -1;
int lastStencilReference = -1;
@ -1167,6 +1170,7 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c
VkPipeline pipeline = c.pipeline.pipeline;
if (pipeline != lastGraphicsPipeline) {
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
pipelineLayout = c.pipeline.pipelineLayout;
lastGraphicsPipeline = pipeline;
// Reset dynamic state so it gets refreshed with the new pipeline.
lastStencilWriteMask = -1;
@ -1188,6 +1192,7 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c
}
if (pipeline->pipeline != lastGraphicsPipeline && pipeline->pipeline != VK_NULL_HANDLE) {
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->pipeline);
pipelineLayout = c.pipeline.pipelineLayout;
lastGraphicsPipeline = pipeline->pipeline;
// Reset dynamic state so it gets refreshed with the new pipeline.
lastStencilWriteMask = -1;
@ -1209,6 +1214,7 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c
}
if (pipeline->pipeline != lastComputePipeline && pipeline->pipeline != VK_NULL_HANDLE) {
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline->pipeline);
pipelineLayout = c.pipeline.pipelineLayout;
lastComputePipeline = pipeline->pipeline;
}
break;
@ -1258,7 +1264,7 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c
}
case VKRRenderCommand::PUSH_CONSTANTS:
vkCmdPushConstants(cmd, c.push.pipelineLayout, c.push.stages, c.push.offset, c.push.size, c.push.data);
vkCmdPushConstants(cmd, pipelineLayout, c.push.stages, c.push.offset, c.push.size, c.push.data);
break;
case VKRRenderCommand::STENCIL:
@ -1277,14 +1283,17 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c
break;
case VKRRenderCommand::DRAW_INDEXED:
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, c.drawIndexed.pipelineLayout, 0, 1, &c.drawIndexed.ds, c.drawIndexed.numUboOffsets, c.drawIndexed.uboOffsets);
vkCmdBindIndexBuffer(cmd, c.drawIndexed.ibuffer, c.drawIndexed.ioffset, c.drawIndexed.indexType);
vkCmdBindVertexBuffers(cmd, 0, 1, &c.drawIndexed.vbuffer, &c.drawIndexed.voffset);
{
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &c.drawIndexed.ds, c.drawIndexed.numUboOffsets, c.drawIndexed.uboOffsets);
vkCmdBindIndexBuffer(cmd, c.drawIndexed.ibuffer, c.drawIndexed.ioffset, (VkIndexType)c.drawIndexed.indexType);
VkDeviceSize voffset = c.drawIndexed.voffset;
vkCmdBindVertexBuffers(cmd, 0, 1, &c.drawIndexed.vbuffer, &voffset);
vkCmdDrawIndexed(cmd, c.drawIndexed.count, c.drawIndexed.instances, 0, 0, 0);
break;
}
case VKRRenderCommand::DRAW:
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, c.draw.pipelineLayout, 0, 1, &c.draw.ds, c.draw.numUboOffsets, c.draw.uboOffsets);
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &c.draw.ds, c.draw.numUboOffsets, c.draw.uboOffsets);
if (c.draw.vbuffer) {
vkCmdBindVertexBuffers(cmd, 0, 1, &c.draw.vbuffer, &c.draw.voffset);
}

View file

@ -52,15 +52,17 @@ struct VkRenderData {
union {
struct {
VkPipeline pipeline;
VkPipelineLayout pipelineLayout;
} pipeline;
struct {
VKRGraphicsPipeline *pipeline;
VkPipelineLayout pipelineLayout;
} graphics_pipeline;
struct {
VKRComputePipeline *pipeline;
VkPipelineLayout pipelineLayout;
} compute_pipeline;
struct {
VkPipelineLayout pipelineLayout;
VkDescriptorSet ds;
int numUboOffsets;
uint32_t uboOffsets[3];
@ -70,17 +72,16 @@ struct VkRenderData {
uint32_t offset;
} draw;
struct {
VkPipelineLayout pipelineLayout;
VkDescriptorSet ds;
int numUboOffsets;
uint32_t uboOffsets[3];
VkBuffer vbuffer; // might need to increase at some point
VkDeviceSize voffset;
VkBuffer ibuffer;
VkDeviceSize ioffset;
uint32_t voffset;
uint32_t ioffset;
uint32_t count;
int16_t instances;
VkIndexType indexType;
int16_t indexType;
} drawIndexed;
struct {
uint32_t clearColor;
@ -103,7 +104,6 @@ struct VkRenderData {
uint32_t color;
} blendColor;
struct {
VkPipelineLayout pipelineLayout;
VkShaderStageFlags stages;
uint8_t offset;
uint8_t size;

View file

@ -242,29 +242,32 @@ public:
return pipeline;
}
void BindPipeline(VkPipeline pipeline, PipelineFlags flags) {
void BindPipeline(VkPipeline pipeline, PipelineFlags flags, VkPipelineLayout pipelineLayout) {
_dbg_assert_(curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER);
_dbg_assert_(pipeline != VK_NULL_HANDLE);
VkRenderData data{ VKRRenderCommand::BIND_PIPELINE };
data.pipeline.pipeline = pipeline;
data.pipeline.pipelineLayout = pipelineLayout;
curPipelineFlags_ |= flags;
curRenderStep_->commands.push_back(data);
}
void BindPipeline(VKRGraphicsPipeline *pipeline, PipelineFlags flags) {
void BindPipeline(VKRGraphicsPipeline *pipeline, PipelineFlags flags, VkPipelineLayout pipelineLayout) {
_dbg_assert_(curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER);
_dbg_assert_(pipeline != nullptr);
VkRenderData data{ VKRRenderCommand::BIND_GRAPHICS_PIPELINE };
data.graphics_pipeline.pipeline = pipeline;
data.graphics_pipeline.pipelineLayout = pipelineLayout;
curPipelineFlags_ |= flags;
curRenderStep_->commands.push_back(data);
}
void BindPipeline(VKRComputePipeline *pipeline, PipelineFlags flags) {
void BindPipeline(VKRComputePipeline *pipeline, PipelineFlags flags, VkPipelineLayout pipelineLayout) {
_dbg_assert_(curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER);
_dbg_assert_(pipeline != nullptr);
VkRenderData data{ VKRRenderCommand::BIND_COMPUTE_PIPELINE };
data.compute_pipeline.pipeline = pipeline;
data.compute_pipeline.pipelineLayout = pipelineLayout;
curPipelineFlags_ |= flags;
curRenderStep_->commands.push_back(data);
}
@ -351,7 +354,6 @@ public:
_dbg_assert_(curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER);
_dbg_assert_(size + offset < 40);
VkRenderData data{ VKRRenderCommand::PUSH_CONSTANTS };
data.push.pipelineLayout = pipelineLayout;
data.push.stages = stages;
data.push.offset = offset;
data.push.size = size;
@ -386,12 +388,11 @@ public:
curRenderStep_->render.stencilStore = VKRRenderPassStoreAction::DONT_CARE;
}
void Draw(VkPipelineLayout layout, VkDescriptorSet descSet, int numUboOffsets, const uint32_t *uboOffsets, VkBuffer vbuffer, int voffset, int count, int offset = 0) {
void Draw(VkDescriptorSet descSet, int numUboOffsets, const uint32_t *uboOffsets, VkBuffer vbuffer, int voffset, int count, int offset = 0) {
_dbg_assert_(curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER && curStepHasViewport_ && curStepHasScissor_);
VkRenderData data{ VKRRenderCommand::DRAW };
data.draw.count = count;
data.draw.offset = offset;
data.draw.pipelineLayout = layout;
data.draw.ds = descSet;
data.draw.vbuffer = vbuffer;
data.draw.voffset = voffset;
@ -403,12 +404,11 @@ public:
curRenderStep_->render.numDraws++;
}
void DrawIndexed(VkPipelineLayout layout, VkDescriptorSet descSet, int numUboOffsets, const uint32_t *uboOffsets, VkBuffer vbuffer, int voffset, VkBuffer ibuffer, int ioffset, int count, int numInstances, VkIndexType indexType) {
void DrawIndexed(VkDescriptorSet descSet, int numUboOffsets, const uint32_t *uboOffsets, VkBuffer vbuffer, int voffset, VkBuffer ibuffer, int ioffset, int count, int numInstances, VkIndexType indexType) {
_dbg_assert_(curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER && curStepHasViewport_ && curStepHasScissor_);
VkRenderData data{ VKRRenderCommand::DRAW_INDEXED };
data.drawIndexed.count = count;
data.drawIndexed.instances = numInstances;
data.drawIndexed.pipelineLayout = layout;
data.drawIndexed.ds = descSet;
data.drawIndexed.vbuffer = vbuffer;
data.drawIndexed.voffset = voffset;

View file

@ -1339,7 +1339,7 @@ void VKContext::Draw(int vertexCount, int offset) {
BindCompatiblePipeline();
ApplyDynamicState();
renderManager_.Draw(pipelineLayout_, descSet, 1, &ubo_offset, vulkanVbuf, (int)vbBindOffset + curVBufferOffsets_[0], vertexCount, offset);
renderManager_.Draw(descSet, 1, &ubo_offset, vulkanVbuf, (int)vbBindOffset + curVBufferOffsets_[0], vertexCount, offset);
}
void VKContext::DrawIndexed(int vertexCount, int offset) {
@ -1359,7 +1359,7 @@ void VKContext::DrawIndexed(int vertexCount, int offset) {
BindCompatiblePipeline();
ApplyDynamicState();
renderManager_.DrawIndexed(pipelineLayout_, descSet, 1, &ubo_offset, vulkanVbuf, (int)vbBindOffset + curVBufferOffsets_[0], vulkanIbuf, (int)ibBindOffset + offset * sizeof(uint32_t), vertexCount, 1, VK_INDEX_TYPE_UINT16);
renderManager_.DrawIndexed(descSet, 1, &ubo_offset, vulkanVbuf, (int)vbBindOffset + curVBufferOffsets_[0], vulkanIbuf, (int)ibBindOffset + offset * sizeof(uint32_t), vertexCount, 1, VK_INDEX_TYPE_UINT16);
}
void VKContext::DrawUP(const void *vdata, int vertexCount) {
@ -1375,15 +1375,15 @@ void VKContext::DrawUP(const void *vdata, int vertexCount) {
BindCompatiblePipeline();
ApplyDynamicState();
renderManager_.Draw(pipelineLayout_, descSet, 1, &ubo_offset, vulkanVbuf, (int)vbBindOffset + curVBufferOffsets_[0], vertexCount);
renderManager_.Draw(descSet, 1, &ubo_offset, vulkanVbuf, (int)vbBindOffset + curVBufferOffsets_[0], vertexCount);
}
void VKContext::BindCompatiblePipeline() {
VkRenderPass renderPass = renderManager_.GetCompatibleRenderPass();
if (renderPass == renderManager_.GetBackbufferRenderPass()) {
renderManager_.BindPipeline(curPipeline_->backbufferPipeline, curPipeline_->flags);
renderManager_.BindPipeline(curPipeline_->backbufferPipeline, curPipeline_->flags, pipelineLayout_);
} else {
renderManager_.BindPipeline(curPipeline_->framebufferPipeline, curPipeline_->flags);
renderManager_.BindPipeline(curPipeline_->framebufferPipeline, curPipeline_->flags, pipelineLayout_);
}
}

View file

@ -787,7 +787,7 @@ void DrawEngineVulkan::DoFlush() {
lastRenderStepId_ = curRenderStepId;
}
renderManager->BindPipeline(pipeline->pipeline, (PipelineFlags)pipeline->flags);
renderManager->BindPipeline(pipeline->pipeline, (PipelineFlags)pipeline->flags, pipelineLayout_);
if (pipeline != lastPipeline_) {
if (lastPipeline_ && !(lastPipeline_->UsesBlendConstant() && pipeline->UsesBlendConstant())) {
gstate_c.Dirty(DIRTY_BLEND_STATE);
@ -814,9 +814,9 @@ void DrawEngineVulkan::DoFlush() {
if (!ibuf) {
ibOffset = (uint32_t)frameData.pushIndex->Push(decIndex, sizeof(uint16_t) * indexGen.VertexCount(), &ibuf);
}
renderManager->DrawIndexed(pipelineLayout_, ds, ARRAY_SIZE(dynamicUBOOffsets), dynamicUBOOffsets, vbuf, vbOffset, ibuf, ibOffset, vertexCount, 1, VK_INDEX_TYPE_UINT16);
renderManager->DrawIndexed(ds, ARRAY_SIZE(dynamicUBOOffsets), dynamicUBOOffsets, vbuf, vbOffset, ibuf, ibOffset, vertexCount, 1, VK_INDEX_TYPE_UINT16);
} else {
renderManager->Draw(pipelineLayout_, ds, ARRAY_SIZE(dynamicUBOOffsets), dynamicUBOOffsets, vbuf, vbOffset, vertexCount);
renderManager->Draw(ds, ARRAY_SIZE(dynamicUBOOffsets), dynamicUBOOffsets, vbuf, vbOffset, vertexCount);
}
} else {
PROFILE_THIS_SCOPE("soft");
@ -917,7 +917,7 @@ void DrawEngineVulkan::DoFlush() {
lastRenderStepId_ = curRenderStepId;
}
renderManager->BindPipeline(pipeline->pipeline, (PipelineFlags)pipeline->flags);
renderManager->BindPipeline(pipeline->pipeline, (PipelineFlags)pipeline->flags, pipelineLayout_);
if (pipeline != lastPipeline_) {
if (lastPipeline_ && !lastPipeline_->UsesBlendConstant() && pipeline->UsesBlendConstant()) {
gstate_c.Dirty(DIRTY_BLEND_STATE);
@ -949,11 +949,11 @@ void DrawEngineVulkan::DoFlush() {
VkBuffer vbuf, ibuf;
vbOffset = (uint32_t)frameData.pushVertex->Push(result.drawBuffer, maxIndex * sizeof(TransformedVertex), &vbuf);
ibOffset = (uint32_t)frameData.pushIndex->Push(inds, sizeof(short) * result.drawNumTrans, &ibuf);
renderManager->DrawIndexed(pipelineLayout_, ds, ARRAY_SIZE(dynamicUBOOffsets), dynamicUBOOffsets, vbuf, vbOffset, ibuf, ibOffset, result.drawNumTrans, 1, VK_INDEX_TYPE_UINT16);
renderManager->DrawIndexed(ds, ARRAY_SIZE(dynamicUBOOffsets), dynamicUBOOffsets, vbuf, vbOffset, ibuf, ibOffset, result.drawNumTrans, 1, VK_INDEX_TYPE_UINT16);
} else {
VkBuffer vbuf;
vbOffset = (uint32_t)frameData.pushVertex->Push(result.drawBuffer, result.drawNumTrans * sizeof(TransformedVertex), &vbuf);
renderManager->Draw(pipelineLayout_, ds, ARRAY_SIZE(dynamicUBOOffsets), dynamicUBOOffsets, vbuf, vbOffset, result.drawNumTrans);
renderManager->Draw(ds, ARRAY_SIZE(dynamicUBOOffsets), dynamicUBOOffsets, vbuf, vbOffset, result.drawNumTrans);
}
} else if (result.action == SW_CLEAR) {
// Note: we won't get here if the clear is alpha but not color, or color but not alpha.