mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-12 04:35:56 +00:00
Handle mixed samples attachments during draws
This commit is contained in:
parent
4bfa8c9fc7
commit
8095cd493c
9 changed files with 107 additions and 18 deletions
|
@ -108,6 +108,7 @@ GraphicsPipeline::GraphicsPipeline(
|
||||||
};
|
};
|
||||||
|
|
||||||
const vk::PipelineMultisampleStateCreateInfo multisampling = {
|
const vk::PipelineMultisampleStateCreateInfo multisampling = {
|
||||||
|
// if dynamic rasterization samples state is enabled, this field is ignored
|
||||||
.rasterizationSamples =
|
.rasterizationSamples =
|
||||||
LiverpoolToVK::NumSamples(key.num_samples, instance.GetFramebufferSampleCounts()),
|
LiverpoolToVK::NumSamples(key.num_samples, instance.GetFramebufferSampleCounts()),
|
||||||
.sampleShadingEnable = false,
|
.sampleShadingEnable = false,
|
||||||
|
@ -121,7 +122,7 @@ GraphicsPipeline::GraphicsPipeline(
|
||||||
.pNext = instance.IsDepthClipControlSupported() ? &clip_control : nullptr,
|
.pNext = instance.IsDepthClipControlSupported() ? &clip_control : nullptr,
|
||||||
};
|
};
|
||||||
|
|
||||||
boost::container::static_vector<vk::DynamicState, 20> dynamic_states = {
|
boost::container::static_vector<vk::DynamicState, 22> dynamic_states = {
|
||||||
vk::DynamicState::eViewportWithCount, vk::DynamicState::eScissorWithCount,
|
vk::DynamicState::eViewportWithCount, vk::DynamicState::eScissorWithCount,
|
||||||
vk::DynamicState::eBlendConstants, vk::DynamicState::eDepthTestEnable,
|
vk::DynamicState::eBlendConstants, vk::DynamicState::eDepthTestEnable,
|
||||||
vk::DynamicState::eDepthWriteEnable, vk::DynamicState::eDepthCompareOp,
|
vk::DynamicState::eDepthWriteEnable, vk::DynamicState::eDepthCompareOp,
|
||||||
|
@ -147,6 +148,9 @@ GraphicsPipeline::GraphicsPipeline(
|
||||||
} else if (!vertex_bindings.empty()) {
|
} else if (!vertex_bindings.empty()) {
|
||||||
dynamic_states.push_back(vk::DynamicState::eVertexInputBindingStride);
|
dynamic_states.push_back(vk::DynamicState::eVertexInputBindingStride);
|
||||||
}
|
}
|
||||||
|
if (instance.IsDynamicRasterizationSamplesSupported()) {
|
||||||
|
dynamic_states.push_back(vk::DynamicState::eRasterizationSamplesEXT);
|
||||||
|
}
|
||||||
|
|
||||||
const vk::PipelineDynamicStateCreateInfo dynamic_info = {
|
const vk::PipelineDynamicStateCreateInfo dynamic_info = {
|
||||||
.dynamicStateCount = static_cast<u32>(dynamic_states.size()),
|
.dynamicStateCount = static_cast<u32>(dynamic_states.size()),
|
||||||
|
|
|
@ -39,7 +39,7 @@ struct GraphicsPipelineKey {
|
||||||
vk::Format depth_format;
|
vk::Format depth_format;
|
||||||
vk::Format stencil_format;
|
vk::Format stencil_format;
|
||||||
|
|
||||||
u32 num_samples;
|
u32 num_samples{};
|
||||||
u32 mrt_mask;
|
u32 mrt_mask;
|
||||||
AmdGpu::PrimitiveType prim_type;
|
AmdGpu::PrimitiveType prim_type;
|
||||||
Liverpool::PolygonMode polygon_mode;
|
Liverpool::PolygonMode polygon_mode;
|
||||||
|
|
|
@ -213,7 +213,8 @@ bool Instance::CreateDevice() {
|
||||||
vk::PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT,
|
vk::PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT,
|
||||||
vk::PhysicalDevicePortabilitySubsetFeaturesKHR,
|
vk::PhysicalDevicePortabilitySubsetFeaturesKHR,
|
||||||
vk::PhysicalDeviceShaderAtomicFloat2FeaturesEXT,
|
vk::PhysicalDeviceShaderAtomicFloat2FeaturesEXT,
|
||||||
vk::PhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR>();
|
vk::PhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR,
|
||||||
|
vk::PhysicalDeviceDynamicRenderingUnusedAttachmentsFeaturesEXT>();
|
||||||
features = feature_chain.get().features;
|
features = feature_chain.get().features;
|
||||||
|
|
||||||
const vk::StructureChain properties_chain = physical_device.getProperties2<
|
const vk::StructureChain properties_chain = physical_device.getProperties2<
|
||||||
|
@ -257,6 +258,8 @@ bool Instance::CreateDevice() {
|
||||||
feature_chain.get<vk::PhysicalDeviceExtendedDynamicState3FeaturesEXT>();
|
feature_chain.get<vk::PhysicalDeviceExtendedDynamicState3FeaturesEXT>();
|
||||||
LOG_INFO(Render_Vulkan, "- extendedDynamicState3ColorWriteMask: {}",
|
LOG_INFO(Render_Vulkan, "- extendedDynamicState3ColorWriteMask: {}",
|
||||||
dynamic_state_3_features.extendedDynamicState3ColorWriteMask);
|
dynamic_state_3_features.extendedDynamicState3ColorWriteMask);
|
||||||
|
LOG_INFO(Render_Vulkan, "- extendedDynamicState3RasterizationSamples: {}",
|
||||||
|
dynamic_state_3_features.extendedDynamicState3RasterizationSamples);
|
||||||
}
|
}
|
||||||
robustness2 = add_extension(VK_EXT_ROBUSTNESS_2_EXTENSION_NAME);
|
robustness2 = add_extension(VK_EXT_ROBUSTNESS_2_EXTENSION_NAME);
|
||||||
if (robustness2) {
|
if (robustness2) {
|
||||||
|
@ -300,6 +303,8 @@ bool Instance::CreateDevice() {
|
||||||
Render_Vulkan, "- workgroupMemoryExplicitLayout16BitAccess: {}",
|
Render_Vulkan, "- workgroupMemoryExplicitLayout16BitAccess: {}",
|
||||||
workgroup_memory_explicit_layout_features.workgroupMemoryExplicitLayout16BitAccess);
|
workgroup_memory_explicit_layout_features.workgroupMemoryExplicitLayout16BitAccess);
|
||||||
}
|
}
|
||||||
|
dynamic_rendering_unused_attachments =
|
||||||
|
add_extension(VK_EXT_DYNAMIC_RENDERING_UNUSED_ATTACHMENTS_EXTENSION_NAME);
|
||||||
const bool calibrated_timestamps =
|
const bool calibrated_timestamps =
|
||||||
TRACY_GPU_ENABLED ? add_extension(VK_EXT_CALIBRATED_TIMESTAMPS_EXTENSION_NAME) : false;
|
TRACY_GPU_ENABLED ? add_extension(VK_EXT_CALIBRATED_TIMESTAMPS_EXTENSION_NAME) : false;
|
||||||
|
|
||||||
|
@ -409,6 +414,8 @@ bool Instance::CreateDevice() {
|
||||||
.customBorderColorWithoutFormat = true,
|
.customBorderColorWithoutFormat = true,
|
||||||
},
|
},
|
||||||
vk::PhysicalDeviceExtendedDynamicState3FeaturesEXT{
|
vk::PhysicalDeviceExtendedDynamicState3FeaturesEXT{
|
||||||
|
.extendedDynamicState3RasterizationSamples =
|
||||||
|
dynamic_state_3_features.extendedDynamicState3RasterizationSamples,
|
||||||
.extendedDynamicState3ColorWriteMask =
|
.extendedDynamicState3ColorWriteMask =
|
||||||
dynamic_state_3_features.extendedDynamicState3ColorWriteMask,
|
dynamic_state_3_features.extendedDynamicState3ColorWriteMask,
|
||||||
},
|
},
|
||||||
|
@ -449,6 +456,9 @@ bool Instance::CreateDevice() {
|
||||||
.workgroupMemoryExplicitLayout16BitAccess =
|
.workgroupMemoryExplicitLayout16BitAccess =
|
||||||
workgroup_memory_explicit_layout_features.workgroupMemoryExplicitLayout16BitAccess,
|
workgroup_memory_explicit_layout_features.workgroupMemoryExplicitLayout16BitAccess,
|
||||||
},
|
},
|
||||||
|
vk::PhysicalDeviceDynamicRenderingUnusedAttachmentsFeaturesEXT{
|
||||||
|
.dynamicRenderingUnusedAttachments = true,
|
||||||
|
},
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
vk::PhysicalDevicePortabilitySubsetFeaturesKHR{
|
vk::PhysicalDevicePortabilitySubsetFeaturesKHR{
|
||||||
.constantAlphaColorBlendFactors = portability_features.constantAlphaColorBlendFactors,
|
.constantAlphaColorBlendFactors = portability_features.constantAlphaColorBlendFactors,
|
||||||
|
@ -502,6 +512,9 @@ bool Instance::CreateDevice() {
|
||||||
if (!workgroup_memory_explicit_layout) {
|
if (!workgroup_memory_explicit_layout) {
|
||||||
device_chain.unlink<vk::PhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR>();
|
device_chain.unlink<vk::PhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR>();
|
||||||
}
|
}
|
||||||
|
if (!dynamic_rendering_unused_attachments) {
|
||||||
|
device_chain.unlink<vk::PhysicalDeviceDynamicRenderingUnusedAttachmentsFeaturesEXT>();
|
||||||
|
}
|
||||||
|
|
||||||
auto [device_result, dev] = physical_device.createDeviceUnique(device_chain.get());
|
auto [device_result, dev] = physical_device.createDeviceUnique(device_chain.get());
|
||||||
if (device_result != vk::Result::eSuccess) {
|
if (device_result != vk::Result::eSuccess) {
|
||||||
|
|
|
@ -114,6 +114,13 @@ public:
|
||||||
return depth_range_unrestricted;
|
return depth_range_unrestricted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true when the extendedDynamicState3RasterizationSamples feature of
|
||||||
|
/// VK_EXT_extended_dynamic_state3 is supported.
|
||||||
|
bool IsDynamicRasterizationSamplesSupported() const {
|
||||||
|
return dynamic_state_3 &&
|
||||||
|
dynamic_state_3_features.extendedDynamicState3RasterizationSamples;
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns true when the extendedDynamicState3ColorWriteMask feature of
|
/// Returns true when the extendedDynamicState3ColorWriteMask feature of
|
||||||
/// VK_EXT_extended_dynamic_state3 is supported.
|
/// VK_EXT_extended_dynamic_state3 is supported.
|
||||||
bool IsDynamicColorWriteMaskSupported() const {
|
bool IsDynamicColorWriteMaskSupported() const {
|
||||||
|
@ -390,6 +397,7 @@ private:
|
||||||
bool amd_shader_trinary_minmax{};
|
bool amd_shader_trinary_minmax{};
|
||||||
bool shader_atomic_float2{};
|
bool shader_atomic_float2{};
|
||||||
bool workgroup_memory_explicit_layout{};
|
bool workgroup_memory_explicit_layout{};
|
||||||
|
bool dynamic_rendering_unused_attachments{};
|
||||||
bool portability_subset{};
|
bool portability_subset{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -303,7 +303,7 @@ bool PipelineCache::RefreshGraphicsKey() {
|
||||||
key.prim_type = regs.primitive_type;
|
key.prim_type = regs.primitive_type;
|
||||||
key.polygon_mode = regs.polygon_control.PolyMode();
|
key.polygon_mode = regs.polygon_control.PolyMode();
|
||||||
key.clip_space = regs.clipper_control.clip_space;
|
key.clip_space = regs.clipper_control.clip_space;
|
||||||
key.num_samples = regs.NumSamples();
|
key.num_samples = instance.IsDynamicRasterizationSamplesSupported() ? 1 : regs.NumSamples();
|
||||||
|
|
||||||
const bool skip_cb_binding =
|
const bool skip_cb_binding =
|
||||||
regs.color_control.mode == AmdGpu::Liverpool::ColorControl::OperationMode::Disable;
|
regs.color_control.mode == AmdGpu::Liverpool::ColorControl::OperationMode::Disable;
|
||||||
|
|
|
@ -269,6 +269,34 @@ void Rasterizer::EliminateFastClear() {
|
||||||
ScopeMarkerEnd();
|
ScopeMarkerEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<u32> Rasterizer::UniqueSampleCounts() const {
|
||||||
|
const auto& regs = liverpool->regs;
|
||||||
|
using Liverpool = AmdGpu::Liverpool;
|
||||||
|
std::vector<u32> result{};
|
||||||
|
|
||||||
|
if (!regs.mode_control.msaa_enable) {
|
||||||
|
result.push_back(1);
|
||||||
|
return std::move(result);
|
||||||
|
}
|
||||||
|
std::vector<u32> samples{};
|
||||||
|
if (regs.color_control.mode != Liverpool::ColorControl::OperationMode::Disable) {
|
||||||
|
for (auto cb = 0u; cb < Liverpool::NumColorBuffers; ++cb) {
|
||||||
|
const auto& col_buf = regs.color_buffers[cb];
|
||||||
|
if (!col_buf) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
samples.push_back(col_buf.NumSamples());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (regs.depth_buffer.DepthValid() || regs.depth_buffer.StencilValid()) {
|
||||||
|
samples.push_back(regs.depth_buffer.NumSamples());
|
||||||
|
}
|
||||||
|
std::ranges::unique_copy(samples, std::back_inserter(result));
|
||||||
|
std::ranges::sort(result, std::ranges::greater());
|
||||||
|
|
||||||
|
return std::move(result);
|
||||||
|
}
|
||||||
|
|
||||||
void Rasterizer::Draw(bool is_indexed, u32 index_offset) {
|
void Rasterizer::Draw(bool is_indexed, u32 index_offset) {
|
||||||
RENDERER_TRACE;
|
RENDERER_TRACE;
|
||||||
|
|
||||||
|
@ -282,7 +310,7 @@ void Rasterizer::Draw(bool is_indexed, u32 index_offset) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto state = PrepareRenderState(pipeline->GetMrtMask());
|
auto full_state = PrepareRenderState(pipeline->GetMrtMask());
|
||||||
if (!BindResources(pipeline)) {
|
if (!BindResources(pipeline)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -291,10 +319,6 @@ void Rasterizer::Draw(bool is_indexed, u32 index_offset) {
|
||||||
if (is_indexed) {
|
if (is_indexed) {
|
||||||
buffer_cache.BindIndexBuffer(index_offset);
|
buffer_cache.BindIndexBuffer(index_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
BeginRendering(*pipeline, state);
|
|
||||||
UpdateDynamicState(*pipeline);
|
|
||||||
|
|
||||||
const auto& vs_info = pipeline->GetStage(Shader::LogicalStage::Vertex);
|
const auto& vs_info = pipeline->GetStage(Shader::LogicalStage::Vertex);
|
||||||
const auto& fetch_shader = pipeline->GetFetchShader();
|
const auto& fetch_shader = pipeline->GetFetchShader();
|
||||||
const auto [vertex_offset, instance_offset] = GetDrawOffsets(regs, vs_info, fetch_shader);
|
const auto [vertex_offset, instance_offset] = GetDrawOffsets(regs, vs_info, fetch_shader);
|
||||||
|
@ -302,6 +326,24 @@ void Rasterizer::Draw(bool is_indexed, u32 index_offset) {
|
||||||
const auto cmdbuf = scheduler.CommandBuffer();
|
const auto cmdbuf = scheduler.CommandBuffer();
|
||||||
cmdbuf.bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline->Handle());
|
cmdbuf.bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline->Handle());
|
||||||
|
|
||||||
|
for (auto samples : UniqueSampleCounts()) {
|
||||||
|
auto state = full_state;
|
||||||
|
auto sample_count =
|
||||||
|
LiverpoolToVK::NumSamples(samples, instance.GetFramebufferSampleCounts());
|
||||||
|
for (auto i = 0; i < AmdGpu::Liverpool::NumColorBuffers; ++i) {
|
||||||
|
if (regs.color_buffers[i] && regs.color_buffers[i].NumSamples() != u32(sample_count)) {
|
||||||
|
state.color_attachments[i].imageView = VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (state.has_depth && regs.depth_buffer.NumSamples() != u32(sample_count)) {
|
||||||
|
state.depth_attachment.imageView = VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
if (state.has_stencil && regs.depth_buffer.NumSamples() != u32(sample_count)) {
|
||||||
|
state.stencil_attachment.imageView = VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
BeginRendering(*pipeline, state);
|
||||||
|
UpdateDynamicState(*pipeline, sample_count);
|
||||||
|
|
||||||
if (is_indexed) {
|
if (is_indexed) {
|
||||||
cmdbuf.drawIndexed(regs.num_indices, regs.num_instances.NumInstances(), 0,
|
cmdbuf.drawIndexed(regs.num_indices, regs.num_instances.NumInstances(), 0,
|
||||||
s32(vertex_offset), instance_offset);
|
s32(vertex_offset), instance_offset);
|
||||||
|
@ -309,6 +351,7 @@ void Rasterizer::Draw(bool is_indexed, u32 index_offset) {
|
||||||
cmdbuf.draw(regs.num_indices, regs.num_instances.NumInstances(), vertex_offset,
|
cmdbuf.draw(regs.num_indices, regs.num_instances.NumInstances(), vertex_offset,
|
||||||
instance_offset);
|
instance_offset);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ResetBindings();
|
ResetBindings();
|
||||||
}
|
}
|
||||||
|
@ -321,6 +364,7 @@ void Rasterizer::DrawIndirect(bool is_indexed, VAddr arg_address, u32 offset, u3
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto& regs = liverpool->regs;
|
||||||
const GraphicsPipeline* pipeline = pipeline_cache.GetGraphicsPipeline();
|
const GraphicsPipeline* pipeline = pipeline_cache.GetGraphicsPipeline();
|
||||||
if (!pipeline) {
|
if (!pipeline) {
|
||||||
return;
|
return;
|
||||||
|
@ -346,7 +390,8 @@ void Rasterizer::DrawIndirect(bool is_indexed, VAddr arg_address, u32 offset, u3
|
||||||
}
|
}
|
||||||
|
|
||||||
BeginRendering(*pipeline, state);
|
BeginRendering(*pipeline, state);
|
||||||
UpdateDynamicState(*pipeline);
|
UpdateDynamicState(*pipeline, LiverpoolToVK::NumSamples(regs.NumSamples(),
|
||||||
|
instance.GetFramebufferSampleCounts()));
|
||||||
|
|
||||||
// We can safely ignore both SGPR UD indices and results of fetch shader parsing, as vertex and
|
// We can safely ignore both SGPR UD indices and results of fetch shader parsing, as vertex and
|
||||||
// instance offsets will be automatically applied by Vulkan from indirect args buffer.
|
// instance offsets will be automatically applied by Vulkan from indirect args buffer.
|
||||||
|
@ -993,7 +1038,8 @@ void Rasterizer::UnmapMemory(VAddr addr, u64 size) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Rasterizer::UpdateDynamicState(const GraphicsPipeline& pipeline) const {
|
void Rasterizer::UpdateDynamicState(const GraphicsPipeline& pipeline,
|
||||||
|
vk::SampleCountFlagBits sample_count) const {
|
||||||
UpdateViewportScissorState();
|
UpdateViewportScissorState();
|
||||||
UpdateDepthStencilState();
|
UpdateDepthStencilState();
|
||||||
UpdatePrimitiveState();
|
UpdatePrimitiveState();
|
||||||
|
@ -1001,6 +1047,7 @@ void Rasterizer::UpdateDynamicState(const GraphicsPipeline& pipeline) const {
|
||||||
auto& dynamic_state = scheduler.GetDynamicState();
|
auto& dynamic_state = scheduler.GetDynamicState();
|
||||||
dynamic_state.SetBlendConstants(&liverpool->regs.blend_constants.red);
|
dynamic_state.SetBlendConstants(&liverpool->regs.blend_constants.red);
|
||||||
dynamic_state.SetColorWriteMasks(pipeline.GetWriteMasks());
|
dynamic_state.SetColorWriteMasks(pipeline.GetWriteMasks());
|
||||||
|
dynamic_state.SetRasterizationSamples(sample_count);
|
||||||
|
|
||||||
// Commit new dynamic state to the command buffer.
|
// Commit new dynamic state to the command buffer.
|
||||||
dynamic_state.Commit(instance, scheduler.CommandBuffer());
|
dynamic_state.Commit(instance, scheduler.CommandBuffer());
|
||||||
|
|
|
@ -86,8 +86,10 @@ private:
|
||||||
void Resolve();
|
void Resolve();
|
||||||
void DepthStencilCopy(bool is_depth, bool is_stencil);
|
void DepthStencilCopy(bool is_depth, bool is_stencil);
|
||||||
void EliminateFastClear();
|
void EliminateFastClear();
|
||||||
|
std::vector<u32> UniqueSampleCounts() const;
|
||||||
|
|
||||||
void UpdateDynamicState(const GraphicsPipeline& pipeline) const;
|
void UpdateDynamicState(const GraphicsPipeline& pipeline,
|
||||||
|
vk::SampleCountFlagBits sample_count) const;
|
||||||
void UpdateViewportScissorState() const;
|
void UpdateViewportScissorState() const;
|
||||||
void UpdateDepthStencilState() const;
|
void UpdateDepthStencilState() const;
|
||||||
void UpdatePrimitiveState() const;
|
void UpdatePrimitiveState() const;
|
||||||
|
|
|
@ -326,6 +326,12 @@ void DynamicState::Commit(const Instance& instance, const vk::CommandBuffer& cmd
|
||||||
cmdbuf.setColorWriteMaskEXT(0, color_write_masks);
|
cmdbuf.setColorWriteMaskEXT(0, color_write_masks);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (dirty_state.rasterization_samples) {
|
||||||
|
dirty_state.rasterization_samples = false;
|
||||||
|
if (instance.IsDynamicRasterizationSamplesSupported()) {
|
||||||
|
cmdbuf.setRasterizationSamplesEXT(rasterization_samples);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Vulkan
|
} // namespace Vulkan
|
||||||
|
|
|
@ -101,6 +101,7 @@ struct DynamicState {
|
||||||
|
|
||||||
bool blend_constants : 1;
|
bool blend_constants : 1;
|
||||||
bool color_write_masks : 1;
|
bool color_write_masks : 1;
|
||||||
|
bool rasterization_samples : 1;
|
||||||
} dirty_state{};
|
} dirty_state{};
|
||||||
|
|
||||||
Viewports viewports{};
|
Viewports viewports{};
|
||||||
|
@ -135,6 +136,7 @@ struct DynamicState {
|
||||||
|
|
||||||
float blend_constants[4]{};
|
float blend_constants[4]{};
|
||||||
ColorWriteMasks color_write_masks{};
|
ColorWriteMasks color_write_masks{};
|
||||||
|
vk::SampleCountFlagBits rasterization_samples{};
|
||||||
|
|
||||||
/// Commits the dynamic state to the provided command buffer.
|
/// Commits the dynamic state to the provided command buffer.
|
||||||
void Commit(const Instance& instance, const vk::CommandBuffer& cmdbuf);
|
void Commit(const Instance& instance, const vk::CommandBuffer& cmdbuf);
|
||||||
|
@ -296,6 +298,13 @@ struct DynamicState {
|
||||||
dirty_state.color_write_masks = true;
|
dirty_state.color_write_masks = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetRasterizationSamples(const vk::SampleCountFlagBits rasterization_samples_) {
|
||||||
|
if (rasterization_samples != rasterization_samples_) {
|
||||||
|
rasterization_samples = rasterization_samples_;
|
||||||
|
dirty_state.rasterization_samples = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class Scheduler {
|
class Scheduler {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue