renderer_vulkan: Add scissor and viewport to dynamic pipeline state (#7114)
Adds the current viewport and scissor to the dynamic pipeline state to reduce redundant viewport/scissor assignments in the command buffer. This greatly reduces the amount of API calls to `vkCmdSetViewport` and `vkCmdSetScissor` by only emitting the API call when the state actually changes.
This commit is contained in:
parent
1cf64ffaef
commit
3218af38d0
|
@ -89,6 +89,9 @@ struct DynamicState {
|
||||||
u8 stencil_compare_mask;
|
u8 stencil_compare_mask;
|
||||||
u8 stencil_write_mask;
|
u8 stencil_write_mask;
|
||||||
|
|
||||||
|
Common::Rectangle<u32> scissor;
|
||||||
|
Common::Rectangle<s32> viewport;
|
||||||
|
|
||||||
bool operator==(const DynamicState& other) const noexcept {
|
bool operator==(const DynamicState& other) const noexcept {
|
||||||
return std::memcmp(this, &other, sizeof(DynamicState)) == 0;
|
return std::memcmp(this, &other, sizeof(DynamicState)) == 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -206,6 +206,32 @@ bool PipelineCache::BindPipeline(const PipelineInfo& info, bool wait_built) {
|
||||||
current_depth_stencil = current_info.depth_stencil,
|
current_depth_stencil = current_info.depth_stencil,
|
||||||
rasterization = info.rasterization,
|
rasterization = info.rasterization,
|
||||||
depth_stencil = info.depth_stencil](vk::CommandBuffer cmdbuf) {
|
depth_stencil = info.depth_stencil](vk::CommandBuffer cmdbuf) {
|
||||||
|
if (dynamic.viewport != current_dynamic.viewport || is_dirty) {
|
||||||
|
const vk::Viewport vk_viewport = {
|
||||||
|
.x = static_cast<f32>(dynamic.viewport.left),
|
||||||
|
.y = static_cast<f32>(dynamic.viewport.top),
|
||||||
|
.width = static_cast<f32>(dynamic.viewport.GetWidth()),
|
||||||
|
.height = static_cast<f32>(dynamic.viewport.GetHeight()),
|
||||||
|
.minDepth = 0.f,
|
||||||
|
.maxDepth = 1.f,
|
||||||
|
};
|
||||||
|
cmdbuf.setViewport(0, vk_viewport);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dynamic.scissor != current_dynamic.scissor || is_dirty) {
|
||||||
|
const vk::Rect2D scissor = {
|
||||||
|
.offset{
|
||||||
|
.x = static_cast<s32>(dynamic.scissor.left),
|
||||||
|
.y = static_cast<s32>(dynamic.scissor.bottom),
|
||||||
|
},
|
||||||
|
.extent{
|
||||||
|
.width = dynamic.scissor.GetWidth(),
|
||||||
|
.height = dynamic.scissor.GetHeight(),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
cmdbuf.setScissor(0, scissor);
|
||||||
|
}
|
||||||
|
|
||||||
if (dynamic.stencil_compare_mask != current_dynamic.stencil_compare_mask || is_dirty) {
|
if (dynamic.stencil_compare_mask != current_dynamic.stencil_compare_mask || is_dirty) {
|
||||||
cmdbuf.setStencilCompareMask(vk::StencilFaceFlagBits::eFrontAndBack,
|
cmdbuf.setStencilCompareMask(vk::StencilFaceFlagBits::eFrontAndBack,
|
||||||
dynamic.stencil_compare_mask);
|
dynamic.stencil_compare_mask);
|
||||||
|
|
|
@ -512,30 +512,13 @@ bool RasterizerVulkan::Draw(bool accelerate, bool is_indexed) {
|
||||||
|
|
||||||
// Configure viewport and scissor
|
// Configure viewport and scissor
|
||||||
const auto viewport = fb_helper.Viewport();
|
const auto viewport = fb_helper.Viewport();
|
||||||
scheduler.Record([viewport, draw_rect](vk::CommandBuffer cmdbuf) {
|
pipeline_info.dynamic.viewport = Common::Rectangle<s32>{
|
||||||
const vk::Viewport vk_viewport = {
|
viewport.x,
|
||||||
.x = static_cast<f32>(viewport.x),
|
viewport.y,
|
||||||
.y = static_cast<f32>(viewport.y),
|
viewport.x + viewport.width,
|
||||||
.width = static_cast<f32>(viewport.width),
|
viewport.y + viewport.height,
|
||||||
.height = static_cast<f32>(viewport.height),
|
|
||||||
.minDepth = 0.f,
|
|
||||||
.maxDepth = 1.f,
|
|
||||||
};
|
};
|
||||||
|
pipeline_info.dynamic.scissor = draw_rect;
|
||||||
const vk::Rect2D scissor = {
|
|
||||||
.offset{
|
|
||||||
.x = static_cast<s32>(draw_rect.left),
|
|
||||||
.y = static_cast<s32>(draw_rect.bottom),
|
|
||||||
},
|
|
||||||
.extent{
|
|
||||||
.width = draw_rect.GetWidth(),
|
|
||||||
.height = draw_rect.GetHeight(),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
cmdbuf.setViewport(0, vk_viewport);
|
|
||||||
cmdbuf.setScissor(0, scissor);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Draw the vertex batch
|
// Draw the vertex batch
|
||||||
bool succeeded = true;
|
bool succeeded = true;
|
||||||
|
|
Reference in New Issue