vulkan: Limit multisampling to supported sample counts. (#828)

This commit is contained in:
squidbus 2024-09-12 12:59:23 -07:00 committed by GitHub
parent bc66fe8fb5
commit fc90f279e2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 29 additions and 6 deletions

View file

@ -718,7 +718,7 @@ vk::ClearValue ColorBufferClearValue(const AmdGpu::Liverpool::ColorBuffer& color
return {.color = color}; return {.color = color};
} }
vk::SampleCountFlagBits NumSamples(u32 num_samples) { vk::SampleCountFlagBits RawNumSamples(u32 num_samples) {
switch (num_samples) { switch (num_samples) {
case 1: case 1:
return vk::SampleCountFlagBits::e1; return vk::SampleCountFlagBits::e1;
@ -735,4 +735,14 @@ vk::SampleCountFlagBits NumSamples(u32 num_samples) {
} }
} }
vk::SampleCountFlagBits NumSamples(u32 num_samples, vk::SampleCountFlags supported_flags) {
vk::SampleCountFlagBits flags = RawNumSamples(num_samples);
// Half sample counts until supported, with a minimum of 1.
while (!(supported_flags & flags) && num_samples > 1) {
num_samples /= 2;
flags = RawNumSamples(num_samples);
}
return flags;
}
} // namespace Vulkan::LiverpoolToVK } // namespace Vulkan::LiverpoolToVK

View file

@ -51,7 +51,7 @@ vk::Format DepthFormat(Liverpool::DepthBuffer::ZFormat z_format,
vk::ClearValue ColorBufferClearValue(const AmdGpu::Liverpool::ColorBuffer& color_buffer); vk::ClearValue ColorBufferClearValue(const AmdGpu::Liverpool::ColorBuffer& color_buffer);
vk::SampleCountFlagBits NumSamples(u32 num_samples); vk::SampleCountFlagBits NumSamples(u32 num_samples, vk::SampleCountFlags supported_flags);
void EmitQuadToTriangleListIndices(u8* out_indices, u32 num_vertices); void EmitQuadToTriangleListIndices(u8* out_indices, u32 num_vertices);

View file

@ -102,7 +102,8 @@ GraphicsPipeline::GraphicsPipeline(const Instance& instance_, Scheduler& schedul
}; };
const vk::PipelineMultisampleStateCreateInfo multisampling = { const vk::PipelineMultisampleStateCreateInfo multisampling = {
.rasterizationSamples = LiverpoolToVK::NumSamples(key.num_samples), .rasterizationSamples =
LiverpoolToVK::NumSamples(key.num_samples, instance.GetFramebufferSampleCounts()),
.sampleShadingEnable = false, .sampleShadingEnable = false,
}; };

View file

@ -222,6 +222,13 @@ public:
return min_imported_host_pointer_alignment; return min_imported_host_pointer_alignment;
} }
/// Returns the sample count flags supported by framebuffers.
vk::SampleCountFlags GetFramebufferSampleCounts() const {
return properties.limits.framebufferColorSampleCounts &
properties.limits.framebufferDepthSampleCounts &
properties.limits.framebufferStencilSampleCounts;
}
private: private:
/// Creates the logical device opportunistically enabling extensions /// Creates the logical device opportunistically enabling extensions
bool CreateDevice(); bool CreateDevice();

View file

@ -146,10 +146,15 @@ Image::Image(const Vulkan::Instance& instance_, Vulkan::Scheduler& scheduler_,
break; break;
} }
constexpr auto tiling = vk::ImageTiling::eOptimal;
const auto supported_format = instance->GetSupportedFormat(info.pixel_format);
const auto properties = instance->GetPhysicalDevice().getImageFormatProperties(
supported_format, info.type, tiling, usage, flags);
const vk::ImageCreateInfo image_ci = { const vk::ImageCreateInfo image_ci = {
.flags = flags, .flags = flags,
.imageType = info.type, .imageType = info.type,
.format = instance->GetSupportedFormat(info.pixel_format), .format = supported_format,
.extent{ .extent{
.width = info.size.width, .width = info.size.width,
.height = info.size.height, .height = info.size.height,
@ -157,8 +162,8 @@ Image::Image(const Vulkan::Instance& instance_, Vulkan::Scheduler& scheduler_,
}, },
.mipLevels = static_cast<u32>(info.resources.levels), .mipLevels = static_cast<u32>(info.resources.levels),
.arrayLayers = static_cast<u32>(info.resources.layers), .arrayLayers = static_cast<u32>(info.resources.layers),
.samples = LiverpoolToVK::NumSamples(info.num_samples), .samples = LiverpoolToVK::NumSamples(info.num_samples, properties.sampleCounts),
.tiling = vk::ImageTiling::eOptimal, .tiling = tiling,
.usage = usage, .usage = usage,
.initialLayout = vk::ImageLayout::eUndefined, .initialLayout = vk::ImageLayout::eUndefined,
}; };