renderer_vulkan: Only update dynamic state when changed. (#2751)

This commit is contained in:
squidbus 2025-04-08 07:22:16 -07:00 committed by GitHub
parent 08731303d8
commit 03b1fef331
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 414 additions and 86 deletions

View file

@ -946,19 +946,19 @@ void Rasterizer::UnmapMemory(VAddr addr, u64 size) {
mapped_ranges -= boost::icl::interval<VAddr>::right_open(addr, addr + size); mapped_ranges -= boost::icl::interval<VAddr>::right_open(addr, addr + size);
} }
void Rasterizer::UpdateDynamicState(const GraphicsPipeline& pipeline) { void Rasterizer::UpdateDynamicState(const GraphicsPipeline& pipeline) const {
UpdateViewportScissorState(); UpdateViewportScissorState();
UpdateDepthStencilState(); UpdateDepthStencilState();
const auto& regs = liverpool->regs; auto& dynamic_state = scheduler.GetDynamicState();
const auto cmdbuf = scheduler.CommandBuffer(); dynamic_state.SetBlendConstants(&liverpool->regs.blend_constants.red);
cmdbuf.setBlendConstants(&regs.blend_constants.red); dynamic_state.SetColorWriteMasks(pipeline.GetWriteMasks());
if (instance.IsDynamicColorWriteMaskSupported()) {
cmdbuf.setColorWriteMaskEXT(0, pipeline.GetWriteMasks()); // Commit new dynamic state to the command buffer.
} dynamic_state.Commit(instance, scheduler.CommandBuffer());
} }
void Rasterizer::UpdateViewportScissorState() { void Rasterizer::UpdateViewportScissorState() const {
const auto& regs = liverpool->regs; const auto& regs = liverpool->regs;
const auto combined_scissor_value_tl = [](s16 scr, s16 win, s16 gen, s16 win_offset) { const auto combined_scissor_value_tl = [](s16 scr, s16 win, s16 gen, s16 win_offset) {
@ -1071,92 +1071,65 @@ void Rasterizer::UpdateViewportScissorState() {
scissors.push_back(empty_scissor); scissors.push_back(empty_scissor);
} }
const auto cmdbuf = scheduler.CommandBuffer(); auto& dynamic_state = scheduler.GetDynamicState();
cmdbuf.setViewportWithCountEXT(viewports); dynamic_state.SetViewports(viewports);
cmdbuf.setScissorWithCountEXT(scissors); dynamic_state.SetScissors(scissors);
} }
void Rasterizer::UpdateDepthStencilState() { void Rasterizer::UpdateDepthStencilState() const {
auto& regs = liverpool->regs; const auto& regs = liverpool->regs;
const auto cmdbuf = scheduler.CommandBuffer(); auto& dynamic_state = scheduler.GetDynamicState();
bool depth_test = regs.depth_control.depth_enable && regs.depth_buffer.DepthValid(); const auto depth_test_enabled =
cmdbuf.setDepthTestEnableEXT(depth_test); regs.depth_control.depth_enable && regs.depth_buffer.DepthValid();
cmdbuf.setDepthWriteEnableEXT(regs.depth_control.depth_write_enable && dynamic_state.SetDepthTestEnabled(depth_test_enabled);
!regs.depth_render_control.depth_clear_enable); if (depth_test_enabled) {
if (depth_test) { dynamic_state.SetDepthWriteEnabled(regs.depth_control.depth_write_enable &&
cmdbuf.setDepthCompareOpEXT(LiverpoolToVK::CompareOp(regs.depth_control.depth_func)); !regs.depth_render_control.depth_clear_enable);
dynamic_state.SetDepthCompareOp(LiverpoolToVK::CompareOp(regs.depth_control.depth_func));
} }
if (instance.IsDepthBoundsSupported()) { const auto depth_bounds_test_enabled = regs.depth_control.depth_bounds_enable;
cmdbuf.setDepthBoundsTestEnableEXT(regs.depth_control.depth_bounds_enable); dynamic_state.SetDepthBoundsTestEnabled(depth_bounds_test_enabled);
if (regs.depth_control.depth_bounds_enable) { if (depth_bounds_test_enabled) {
cmdbuf.setDepthBounds(regs.depth_bounds_min, regs.depth_bounds_max); dynamic_state.SetDepthBounds(regs.depth_bounds_min, regs.depth_bounds_max);
}
} }
cmdbuf.setDepthBiasEnableEXT(regs.polygon_control.NeedsBias()); const auto depth_bias_enabled = regs.polygon_control.NeedsBias();
if (regs.polygon_control.enable_polygon_offset_front) { if (depth_bias_enabled) {
cmdbuf.setDepthBias(regs.poly_offset.front_offset, regs.poly_offset.depth_bias, dynamic_state.SetDepthBias(
regs.poly_offset.front_scale / 16.f); regs.polygon_control.enable_polygon_offset_front ? regs.poly_offset.front_offset
} else if (regs.polygon_control.enable_polygon_offset_back) { : regs.poly_offset.back_offset,
cmdbuf.setDepthBias(regs.poly_offset.back_offset, regs.poly_offset.depth_bias, regs.poly_offset.depth_bias,
regs.poly_offset.back_scale / 16.f); (regs.polygon_control.enable_polygon_offset_front ? regs.poly_offset.front_scale
: regs.poly_offset.back_scale) /
16.f);
} }
cmdbuf.setStencilTestEnableEXT(regs.depth_control.stencil_enable && const auto stencil_test_enabled =
regs.depth_buffer.StencilValid()); regs.depth_control.stencil_enable && regs.depth_buffer.StencilValid();
if (regs.depth_control.stencil_enable) { dynamic_state.SetStencilTestEnabled(stencil_test_enabled);
const auto front_fail_op = if (stencil_test_enabled) {
LiverpoolToVK::StencilOp(regs.stencil_control.stencil_fail_front); const StencilOps front_ops{
const auto front_pass_op = .fail_op = LiverpoolToVK::StencilOp(regs.stencil_control.stencil_fail_front),
LiverpoolToVK::StencilOp(regs.stencil_control.stencil_zpass_front); .pass_op = LiverpoolToVK::StencilOp(regs.stencil_control.stencil_zpass_front),
const auto front_depth_fail_op = .depth_fail_op = LiverpoolToVK::StencilOp(regs.stencil_control.stencil_zfail_front),
LiverpoolToVK::StencilOp(regs.stencil_control.stencil_zfail_front); .compare_op = LiverpoolToVK::CompareOp(regs.depth_control.stencil_ref_func),
const auto front_compare_op = LiverpoolToVK::CompareOp(regs.depth_control.stencil_ref_func); };
if (regs.depth_control.backface_enable) { const StencilOps back_ops = regs.depth_control.backface_enable ? StencilOps{
const auto back_fail_op = .fail_op = LiverpoolToVK::StencilOp(regs.stencil_control.stencil_fail_back),
LiverpoolToVK::StencilOp(regs.stencil_control.stencil_fail_back); .pass_op = LiverpoolToVK::StencilOp(regs.stencil_control.stencil_zpass_back),
const auto back_pass_op = .depth_fail_op = LiverpoolToVK::StencilOp(regs.stencil_control.stencil_zfail_back),
LiverpoolToVK::StencilOp(regs.stencil_control.stencil_zpass_back); .compare_op = LiverpoolToVK::CompareOp(regs.depth_control.stencil_bf_func),
const auto back_depth_fail_op = } : front_ops;
LiverpoolToVK::StencilOp(regs.stencil_control.stencil_zfail_back); dynamic_state.SetStencilOps(front_ops, back_ops);
const auto back_compare_op =
LiverpoolToVK::CompareOp(regs.depth_control.stencil_bf_func);
cmdbuf.setStencilOpEXT(vk::StencilFaceFlagBits::eFront, front_fail_op, front_pass_op,
front_depth_fail_op, front_compare_op);
cmdbuf.setStencilOpEXT(vk::StencilFaceFlagBits::eBack, back_fail_op, back_pass_op,
back_depth_fail_op, back_compare_op);
} else {
cmdbuf.setStencilOpEXT(vk::StencilFaceFlagBits::eFrontAndBack, front_fail_op,
front_pass_op, front_depth_fail_op, front_compare_op);
}
const auto front = regs.stencil_ref_front; const auto front = regs.stencil_ref_front;
const auto back = regs.stencil_ref_back; const auto back =
if (front.stencil_test_val == back.stencil_test_val) { regs.depth_control.backface_enable ? regs.stencil_ref_back : regs.stencil_ref_front;
cmdbuf.setStencilReference(vk::StencilFaceFlagBits::eFrontAndBack, dynamic_state.SetStencilReferences(front.stencil_test_val, back.stencil_test_val);
front.stencil_test_val); dynamic_state.SetStencilWriteMasks(front.stencil_write_mask, back.stencil_write_mask);
} else { dynamic_state.SetStencilCompareMasks(front.stencil_mask, back.stencil_mask);
cmdbuf.setStencilReference(vk::StencilFaceFlagBits::eFront, front.stencil_test_val);
cmdbuf.setStencilReference(vk::StencilFaceFlagBits::eBack, back.stencil_test_val);
}
if (front.stencil_write_mask == back.stencil_write_mask) {
cmdbuf.setStencilWriteMask(vk::StencilFaceFlagBits::eFrontAndBack,
front.stencil_write_mask);
} else {
cmdbuf.setStencilWriteMask(vk::StencilFaceFlagBits::eFront, front.stencil_write_mask);
cmdbuf.setStencilWriteMask(vk::StencilFaceFlagBits::eBack, back.stencil_write_mask);
}
if (front.stencil_mask == back.stencil_mask) {
cmdbuf.setStencilCompareMask(vk::StencilFaceFlagBits::eFrontAndBack,
front.stencil_mask);
} else {
cmdbuf.setStencilCompareMask(vk::StencilFaceFlagBits::eFront, front.stencil_mask);
cmdbuf.setStencilCompareMask(vk::StencilFaceFlagBits::eBack, back.stencil_mask);
}
} }
} }

View file

@ -75,9 +75,9 @@ private:
void DepthStencilCopy(bool is_depth, bool is_stencil); void DepthStencilCopy(bool is_depth, bool is_stencil);
void EliminateFastClear(); void EliminateFastClear();
void UpdateDynamicState(const GraphicsPipeline& pipeline); void UpdateDynamicState(const GraphicsPipeline& pipeline) const;
void UpdateViewportScissorState(); void UpdateViewportScissorState() const;
void UpdateDepthStencilState(); void UpdateDepthStencilState() const;
bool FilterDraw(); bool FilterDraw();

View file

@ -97,6 +97,9 @@ void Scheduler::AllocateWorkerCommandBuffers() {
ASSERT_MSG(begin_result == vk::Result::eSuccess, "Failed to begin command buffer: {}", ASSERT_MSG(begin_result == vk::Result::eSuccess, "Failed to begin command buffer: {}",
vk::to_string(begin_result)); vk::to_string(begin_result));
// Invalidate dynamic state so it gets applied to the new command buffer.
dynamic_state.Invalidate();
#if TRACY_GPU_ENABLED #if TRACY_GPU_ENABLED
auto* profiler_ctx = instance.GetProfilerContext(); auto* profiler_ctx = instance.GetProfilerContext();
if (profiler_ctx) { if (profiler_ctx) {
@ -164,4 +167,137 @@ void Scheduler::SubmitExecution(SubmitInfo& info) {
} }
} }
void DynamicState::Commit(const Instance& instance, const vk::CommandBuffer& cmdbuf) {
if (dirty_state.viewports) {
dirty_state.viewports = false;
cmdbuf.setViewportWithCountEXT(viewports);
}
if (dirty_state.scissors) {
dirty_state.scissors = false;
cmdbuf.setScissorWithCountEXT(scissors);
}
if (dirty_state.depth_test_enabled) {
dirty_state.depth_test_enabled = false;
cmdbuf.setDepthTestEnableEXT(depth_test_enabled);
}
if (dirty_state.depth_write_enabled) {
dirty_state.depth_write_enabled = false;
// Note that this must be set in a command buffer even if depth test is disabled.
cmdbuf.setDepthWriteEnableEXT(depth_write_enabled);
}
if (depth_test_enabled && dirty_state.depth_compare_op) {
dirty_state.depth_compare_op = false;
cmdbuf.setDepthCompareOpEXT(depth_compare_op);
}
if (dirty_state.depth_bounds_test_enabled) {
dirty_state.depth_bounds_test_enabled = false;
if (instance.IsDepthBoundsSupported()) {
cmdbuf.setDepthBoundsTestEnableEXT(depth_bounds_test_enabled);
}
}
if (depth_bounds_test_enabled && dirty_state.depth_bounds) {
dirty_state.depth_bounds = false;
if (instance.IsDepthBoundsSupported()) {
cmdbuf.setDepthBounds(depth_bounds_min, depth_bounds_max);
}
}
if (dirty_state.depth_bias_enabled) {
dirty_state.depth_bias_enabled = false;
cmdbuf.setDepthBiasEnableEXT(depth_bias_enabled);
}
if (depth_bias_enabled && dirty_state.depth_bias) {
dirty_state.depth_bias = false;
cmdbuf.setDepthBias(depth_bias_constant, depth_bias_clamp, depth_bias_slope);
}
if (dirty_state.stencil_test_enabled) {
dirty_state.stencil_test_enabled = false;
cmdbuf.setStencilTestEnableEXT(stencil_test_enabled);
}
if (stencil_test_enabled) {
if (dirty_state.stencil_front_ops && dirty_state.stencil_back_ops &&
stencil_front_ops == stencil_back_ops) {
dirty_state.stencil_front_ops = false;
dirty_state.stencil_back_ops = false;
cmdbuf.setStencilOpEXT(vk::StencilFaceFlagBits::eFrontAndBack,
stencil_front_ops.fail_op, stencil_front_ops.pass_op,
stencil_front_ops.depth_fail_op, stencil_front_ops.compare_op);
} else {
if (dirty_state.stencil_front_ops) {
dirty_state.stencil_front_ops = false;
cmdbuf.setStencilOpEXT(vk::StencilFaceFlagBits::eFront, stencil_front_ops.fail_op,
stencil_front_ops.pass_op, stencil_front_ops.depth_fail_op,
stencil_front_ops.compare_op);
}
if (dirty_state.stencil_back_ops) {
dirty_state.stencil_back_ops = false;
cmdbuf.setStencilOpEXT(vk::StencilFaceFlagBits::eBack, stencil_back_ops.fail_op,
stencil_back_ops.pass_op, stencil_back_ops.depth_fail_op,
stencil_back_ops.compare_op);
}
}
if (dirty_state.stencil_front_reference && dirty_state.stencil_back_reference &&
stencil_front_reference == stencil_back_reference) {
dirty_state.stencil_front_reference = false;
dirty_state.stencil_back_reference = false;
cmdbuf.setStencilReference(vk::StencilFaceFlagBits::eFrontAndBack,
stencil_front_reference);
} else {
if (dirty_state.stencil_front_reference) {
dirty_state.stencil_front_reference = false;
cmdbuf.setStencilReference(vk::StencilFaceFlagBits::eFront,
stencil_front_reference);
}
if (dirty_state.stencil_back_reference) {
dirty_state.stencil_back_reference = false;
cmdbuf.setStencilReference(vk::StencilFaceFlagBits::eBack, stencil_back_reference);
}
}
if (dirty_state.stencil_front_write_mask && dirty_state.stencil_back_write_mask &&
stencil_front_write_mask == stencil_back_write_mask) {
dirty_state.stencil_front_write_mask = false;
dirty_state.stencil_back_write_mask = false;
cmdbuf.setStencilWriteMask(vk::StencilFaceFlagBits::eFrontAndBack,
stencil_front_write_mask);
} else {
if (dirty_state.stencil_front_write_mask) {
dirty_state.stencil_front_write_mask = false;
cmdbuf.setStencilWriteMask(vk::StencilFaceFlagBits::eFront,
stencil_front_write_mask);
}
if (dirty_state.stencil_back_write_mask) {
dirty_state.stencil_back_write_mask = false;
cmdbuf.setStencilWriteMask(vk::StencilFaceFlagBits::eBack, stencil_back_write_mask);
}
}
if (dirty_state.stencil_front_compare_mask && dirty_state.stencil_back_compare_mask &&
stencil_front_compare_mask == stencil_back_compare_mask) {
dirty_state.stencil_front_compare_mask = false;
dirty_state.stencil_back_compare_mask = false;
cmdbuf.setStencilCompareMask(vk::StencilFaceFlagBits::eFrontAndBack,
stencil_front_compare_mask);
} else {
if (dirty_state.stencil_front_compare_mask) {
dirty_state.stencil_front_compare_mask = false;
cmdbuf.setStencilCompareMask(vk::StencilFaceFlagBits::eFront,
stencil_front_compare_mask);
}
if (dirty_state.stencil_back_compare_mask) {
dirty_state.stencil_back_compare_mask = false;
cmdbuf.setStencilCompareMask(vk::StencilFaceFlagBits::eBack,
stencil_back_compare_mask);
}
}
}
if (dirty_state.blend_constants) {
dirty_state.blend_constants = false;
cmdbuf.setBlendConstants(blend_constants);
}
if (dirty_state.color_write_masks) {
dirty_state.color_write_masks = false;
if (instance.IsDynamicColorWriteMaskSupported()) {
cmdbuf.setColorWriteMaskEXT(0, color_write_masks);
}
}
}
} // namespace Vulkan } // namespace Vulkan

View file

@ -7,6 +7,7 @@
#include <boost/container/static_vector.hpp> #include <boost/container/static_vector.hpp>
#include "common/types.h" #include "common/types.h"
#include "common/unique_function.h" #include "common/unique_function.h"
#include "video_core/amdgpu/liverpool.h"
#include "video_core/renderer_vulkan/vk_master_semaphore.h" #include "video_core/renderer_vulkan/vk_master_semaphore.h"
#include "video_core/renderer_vulkan/vk_resource_pool.h" #include "video_core/renderer_vulkan/vk_resource_pool.h"
@ -55,6 +56,219 @@ struct SubmitInfo {
} }
}; };
using Viewports = boost::container::static_vector<vk::Viewport, AmdGpu::Liverpool::NumViewports>;
using Scissors = boost::container::static_vector<vk::Rect2D, AmdGpu::Liverpool::NumViewports>;
using ColorWriteMasks = std::array<vk::ColorComponentFlags, AmdGpu::Liverpool::NumColorBuffers>;
struct StencilOps {
vk::StencilOp fail_op{};
vk::StencilOp pass_op{};
vk::StencilOp depth_fail_op{};
vk::CompareOp compare_op{};
bool operator==(const StencilOps& other) const {
return fail_op == other.fail_op && pass_op == other.pass_op &&
depth_fail_op == other.depth_fail_op && compare_op == other.compare_op;
}
};
struct DynamicState {
struct {
bool viewports : 1;
bool scissors : 1;
bool depth_test_enabled : 1;
bool depth_write_enabled : 1;
bool depth_compare_op : 1;
bool depth_bounds_test_enabled : 1;
bool depth_bounds : 1;
bool depth_bias_enabled : 1;
bool depth_bias : 1;
bool stencil_test_enabled : 1;
bool stencil_front_ops : 1;
bool stencil_front_reference : 1;
bool stencil_front_write_mask : 1;
bool stencil_front_compare_mask : 1;
bool stencil_back_ops : 1;
bool stencil_back_reference : 1;
bool stencil_back_write_mask : 1;
bool stencil_back_compare_mask : 1;
bool blend_constants : 1;
bool color_write_masks : 1;
} dirty_state{};
Viewports viewports{};
Scissors scissors{};
bool depth_test_enabled{};
bool depth_write_enabled{};
vk::CompareOp depth_compare_op{};
bool depth_bounds_test_enabled{};
float depth_bounds_min{};
float depth_bounds_max{};
bool depth_bias_enabled{};
float depth_bias_constant{};
float depth_bias_clamp{};
float depth_bias_slope{};
bool stencil_test_enabled{};
StencilOps stencil_front_ops{};
u32 stencil_front_reference{};
u32 stencil_front_write_mask{};
u32 stencil_front_compare_mask{};
StencilOps stencil_back_ops{};
u32 stencil_back_reference{};
u32 stencil_back_write_mask{};
u32 stencil_back_compare_mask{};
float blend_constants[4]{};
ColorWriteMasks color_write_masks{};
/// Commits the dynamic state to the provided command buffer.
void Commit(const Instance& instance, const vk::CommandBuffer& cmdbuf);
/// Invalidates all dynamic state to be flushed into the next command buffer.
void Invalidate() {
std::memset(&dirty_state, 0xFF, sizeof(dirty_state));
}
void SetViewports(const Viewports& viewports_) {
if (!std::ranges::equal(viewports, viewports_)) {
viewports = viewports_;
dirty_state.viewports = true;
}
}
void SetScissors(const Scissors& scissors_) {
if (!std::ranges::equal(scissors, scissors_)) {
scissors = scissors_;
dirty_state.scissors = true;
}
}
void SetDepthTestEnabled(const bool enabled) {
if (depth_test_enabled != enabled) {
depth_test_enabled = enabled;
dirty_state.depth_test_enabled = true;
}
}
void SetDepthWriteEnabled(const bool enabled) {
if (depth_write_enabled != enabled) {
depth_write_enabled = enabled;
dirty_state.depth_write_enabled = true;
}
}
void SetDepthCompareOp(const vk::CompareOp compare_op) {
if (depth_compare_op != compare_op) {
depth_compare_op = compare_op;
dirty_state.depth_compare_op = true;
}
}
void SetDepthBoundsTestEnabled(const bool enabled) {
if (depth_bounds_test_enabled != enabled) {
depth_bounds_test_enabled = enabled;
dirty_state.depth_bounds_test_enabled = true;
}
}
void SetDepthBounds(const float min, const float max) {
if (depth_bounds_min != min || depth_bounds_max != max) {
depth_bounds_min = min;
depth_bounds_max = max;
dirty_state.depth_bounds = true;
}
}
void SetDepthBiasEnabled(const bool enabled) {
if (depth_bias_enabled != enabled) {
depth_bias_enabled = enabled;
dirty_state.depth_bias_enabled = true;
}
}
void SetDepthBias(const float constant, const float clamp, const float slope) {
if (depth_bias_constant != constant || depth_bias_clamp != clamp ||
depth_bias_slope != slope) {
depth_bias_constant = constant;
depth_bias_clamp = clamp;
depth_bias_slope = slope;
dirty_state.depth_bias = true;
}
}
void SetStencilTestEnabled(const bool enabled) {
if (stencil_test_enabled != enabled) {
stencil_test_enabled = enabled;
dirty_state.stencil_test_enabled = true;
}
}
void SetStencilOps(const StencilOps& front_ops, const StencilOps& back_ops) {
if (stencil_front_ops != front_ops) {
stencil_front_ops = front_ops;
dirty_state.stencil_front_ops = true;
}
if (stencil_back_ops != back_ops) {
stencil_back_ops = back_ops;
dirty_state.stencil_back_ops = true;
}
}
void SetStencilReferences(const u32 front_reference, const u32 back_reference) {
if (stencil_front_reference != front_reference) {
stencil_front_reference = front_reference;
dirty_state.stencil_front_reference = true;
}
if (stencil_back_reference != back_reference) {
stencil_back_reference = back_reference;
dirty_state.stencil_back_reference = true;
}
}
void SetStencilWriteMasks(const u32 front_write_mask, const u32 back_write_mask) {
if (stencil_front_write_mask != front_write_mask) {
stencil_front_write_mask = front_write_mask;
dirty_state.stencil_front_write_mask = true;
}
if (stencil_back_write_mask != back_write_mask) {
stencil_back_write_mask = back_write_mask;
dirty_state.stencil_back_write_mask = true;
}
}
void SetStencilCompareMasks(const u32 front_compare_mask, const u32 back_compare_mask) {
if (stencil_front_compare_mask != front_compare_mask) {
stencil_front_compare_mask = front_compare_mask;
dirty_state.stencil_front_compare_mask = true;
}
if (stencil_back_compare_mask != back_compare_mask) {
stencil_back_compare_mask = back_compare_mask;
dirty_state.stencil_back_compare_mask = true;
}
}
void SetBlendConstants(const float blend_constants_[4]) {
if (!std::equal(blend_constants, std::end(blend_constants), blend_constants_)) {
std::memcpy(blend_constants, blend_constants_, sizeof(blend_constants));
dirty_state.blend_constants = true;
}
}
void SetColorWriteMasks(const ColorWriteMasks& color_write_masks_) {
if (!std::ranges::equal(color_write_masks, color_write_masks_)) {
color_write_masks = color_write_masks_;
dirty_state.color_write_masks = true;
}
}
};
class Scheduler { class Scheduler {
public: public:
explicit Scheduler(const Instance& instance); explicit Scheduler(const Instance& instance);
@ -81,6 +295,10 @@ public:
return render_state; return render_state;
} }
DynamicState& GetDynamicState() {
return dynamic_state;
}
/// Returns the current command buffer. /// Returns the current command buffer.
vk::CommandBuffer CommandBuffer() const { vk::CommandBuffer CommandBuffer() const {
return current_cmdbuf; return current_cmdbuf;
@ -125,6 +343,7 @@ private:
}; };
std::queue<PendingOp> pending_ops; std::queue<PendingOp> pending_ops;
RenderState render_state; RenderState render_state;
DynamicState dynamic_state;
bool is_rendering = false; bool is_rendering = false;
tracy::VkCtxScope* profiler_scope{}; tracy::VkCtxScope* profiler_scope{};
}; };