mirror of
https://github.com/azahar-emu/azahar.git
synced 2026-11-11 16:49:39 +01:00
renderer_vulkan: Gracefully handle lack of MSAA support (#2779)
* renderer_vulkan: Update `IsMultiSampleSupported` to check for `shaderStorageImageMultisample` `shaderStorageImageMultisample` is required for the reinterpretation compute shaders in particular and should be part of the main MSAA requirement for now. * renderer_vulkan: Conditionally create multisample compute shaders based on MSAA support These shaders should not be compiled on systems that do not support `shaderStorageImageMultisample`. Some systems, such as newer Intel iGPUs, seem to gracefully handle compiling these compute shaders despite not supporting `shaderStorageImageMultisample`. Other drivers such as Mobile GPUs, will have the entire compute pipeline compilation fail. * renderer_vulkan: Allow hardware-accelerated reinterpretations to fail Propagate blit-helper results to `TextureRuntime::Reinterpret` return value. Allows a slow-path reinterpretation to be done in the case of backend failure.
This commit is contained in:
4 files changed
+45
-42
No files matched your search
@@ -194,16 +194,15 @@ bool TextureRuntime::Reinterpret(Surface& source, Surface& dest,
|
||||
|
||||
ASSERT_MSG(src_format != dst_format, "Reinterpretation with the same format is invalid");
|
||||
if (src_format == PixelFormat::D24S8 && dst_format == PixelFormat::RGBA8) {
|
||||
blit_helper.ConvertDS24S8ToRGBA8(source, dest, copy);
|
||||
return blit_helper.ConvertDS24S8ToRGBA8(source, dest, copy);
|
||||
} else if (src_format == PixelFormat::RGBA4 && dst_format == PixelFormat::RGB5A1) {
|
||||
blit_helper.ConvertRGBA4ToRGB5A1(source, dest, copy);
|
||||
} else {
|
||||
LOG_WARNING(Render_OpenGL, "Unimplemented reinterpretation {}({:#x}) -> {}({:#x})",
|
||||
VideoCore::PixelFormatAsString(src_format), source.Tuple().internal_format,
|
||||
VideoCore::PixelFormatAsString(dst_format), dest.Tuple().internal_format);
|
||||
return false;
|
||||
return blit_helper.ConvertRGBA4ToRGB5A1(source, dest, copy);
|
||||
}
|
||||
return true;
|
||||
|
||||
LOG_WARNING(Render_OpenGL, "Unimplemented reinterpretation {}({:#x}) -> {}({:#x})",
|
||||
VideoCore::PixelFormatAsString(src_format), source.Tuple().internal_format,
|
||||
VideoCore::PixelFormatAsString(dst_format), dest.Tuple().internal_format);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TextureRuntime::ClearTextureWithoutFbo(Surface& surface,
|
||||
|
||||
@@ -249,10 +249,10 @@ BlitHelper::BlitHelper(const Instance& instance_, Scheduler& scheduler_,
|
||||
vk::ShaderStageFlagBits::eVertex, device)},
|
||||
d24s8_to_rgba8_comp{Compile(HostShaders::VULKAN_D24S8_TO_RGBA8_COMP,
|
||||
vk::ShaderStageFlagBits::eCompute, device)},
|
||||
#if !defined(__APPLE__)
|
||||
d24s8_to_rgba8_ms_comp{Compile(HostShaders::VULKAN_D24S8_TO_RGBA8_MS_COMP,
|
||||
vk::ShaderStageFlagBits::eCompute, device)},
|
||||
#endif
|
||||
d24s8_to_rgba8_ms_comp{instance_.IsMultiSampleSupported()
|
||||
? Compile(HostShaders::VULKAN_D24S8_TO_RGBA8_MS_COMP,
|
||||
vk::ShaderStageFlagBits::eCompute, device)
|
||||
: VK_NULL_HANDLE},
|
||||
depth_to_buffer_comp{Compile(HostShaders::VULKAN_DEPTH_TO_BUFFER_COMP,
|
||||
vk::ShaderStageFlagBits::eCompute, device)},
|
||||
blit_depth_stencil_frag{VK_NULL_HANDLE},
|
||||
@@ -265,10 +265,10 @@ BlitHelper::BlitHelper(const Instance& instance_, Scheduler& scheduler_,
|
||||
mmpx_frag{Compile(HostShaders::MMPX_FRAG, vk::ShaderStageFlagBits::eFragment, device)},
|
||||
refine_frag{Compile(HostShaders::REFINE_FRAG, vk::ShaderStageFlagBits::eFragment, device)},
|
||||
d24s8_to_rgba8_pipeline{MakeComputePipeline(d24s8_to_rgba8_comp, compute_pipeline_layout)},
|
||||
#if !defined(__APPLE__)
|
||||
d24s8_to_rgba8_ms_pipeline{
|
||||
MakeComputePipeline(d24s8_to_rgba8_ms_comp, compute_pipeline_layout)},
|
||||
#endif
|
||||
instance_.IsMultiSampleSupported()
|
||||
? MakeComputePipeline(d24s8_to_rgba8_ms_comp, compute_pipeline_layout)
|
||||
: VK_NULL_HANDLE},
|
||||
depth_to_buffer_pipeline{
|
||||
MakeComputePipeline(depth_to_buffer_comp, compute_buffer_pipeline_layout)},
|
||||
depth_blit_pipeline{VK_NULL_HANDLE},
|
||||
@@ -293,17 +293,18 @@ BlitHelper::BlitHelper(const Instance& instance_, Scheduler& scheduler_,
|
||||
"BlitHelper: three_textures_pipeline_layout");
|
||||
SetObjectName(device, full_screen_vert, "BlitHelper: full_screen_vert");
|
||||
SetObjectName(device, d24s8_to_rgba8_comp, "BlitHelper: d24s8_to_rgba8_comp");
|
||||
#if !defined(__APPLE__)
|
||||
SetObjectName(device, d24s8_to_rgba8_ms_comp, "BlitHelper: d24s8_to_rgba8_ms_comp");
|
||||
#endif
|
||||
if (d24s8_to_rgba8_ms_comp) {
|
||||
SetObjectName(device, d24s8_to_rgba8_ms_comp, "BlitHelper: d24s8_to_rgba8_ms_comp");
|
||||
}
|
||||
SetObjectName(device, depth_to_buffer_comp, "BlitHelper: depth_to_buffer_comp");
|
||||
if (blit_depth_stencil_frag) {
|
||||
SetObjectName(device, blit_depth_stencil_frag, "BlitHelper: blit_depth_stencil_frag");
|
||||
}
|
||||
SetObjectName(device, d24s8_to_rgba8_pipeline, "BlitHelper: d24s8_to_rgba8_pipeline");
|
||||
#if !defined(__APPLE__)
|
||||
SetObjectName(device, d24s8_to_rgba8_ms_pipeline, "BlitHelper: d24s8_to_rgba8_ms_pipeline");
|
||||
#endif
|
||||
if (d24s8_to_rgba8_ms_pipeline) {
|
||||
SetObjectName(device, d24s8_to_rgba8_ms_pipeline,
|
||||
"BlitHelper: d24s8_to_rgba8_ms_pipeline");
|
||||
}
|
||||
SetObjectName(device, depth_to_buffer_pipeline, "BlitHelper: depth_to_buffer_pipeline");
|
||||
if (depth_blit_pipeline) {
|
||||
SetObjectName(device, depth_blit_pipeline, "BlitHelper: depth_blit_pipeline");
|
||||
@@ -325,9 +326,9 @@ BlitHelper::~BlitHelper() {
|
||||
device.destroyPipelineLayout(three_textures_pipeline_layout);
|
||||
device.destroyShaderModule(full_screen_vert);
|
||||
device.destroyShaderModule(d24s8_to_rgba8_comp);
|
||||
#if !defined(__APPLE__)
|
||||
device.destroyShaderModule(d24s8_to_rgba8_ms_comp);
|
||||
#endif
|
||||
if (d24s8_to_rgba8_ms_comp) {
|
||||
device.destroyShaderModule(d24s8_to_rgba8_ms_comp);
|
||||
}
|
||||
device.destroyShaderModule(depth_to_buffer_comp);
|
||||
if (blit_depth_stencil_frag) {
|
||||
device.destroyShaderModule(blit_depth_stencil_frag);
|
||||
@@ -340,9 +341,9 @@ BlitHelper::~BlitHelper() {
|
||||
device.destroyShaderModule(refine_frag);
|
||||
device.destroyPipeline(depth_to_buffer_pipeline);
|
||||
device.destroyPipeline(d24s8_to_rgba8_pipeline);
|
||||
#if !defined(__APPLE__)
|
||||
device.destroyPipeline(d24s8_to_rgba8_ms_pipeline);
|
||||
#endif
|
||||
if (d24s8_to_rgba8_ms_pipeline) {
|
||||
device.destroyPipeline(d24s8_to_rgba8_ms_pipeline);
|
||||
}
|
||||
device.destroyPipeline(depth_blit_pipeline);
|
||||
device.destroySampler(linear_sampler);
|
||||
device.destroySampler(nearest_sampler);
|
||||
@@ -425,11 +426,13 @@ bool BlitHelper::ConvertDS24S8ToRGBA8(Surface& source, Surface& dest,
|
||||
|
||||
const bool multisample = (source.sample_count > 1) && (dest.sample_count > 1);
|
||||
const Type src_type = multisample ? Type::MultiSampled : Type::Current;
|
||||
#if !defined(__APPLE__)
|
||||
|
||||
if (multisample && !instance.IsMultiSampleSupported()) {
|
||||
LOG_ERROR(Render_Vulkan,
|
||||
"Multisampled DS24S8->RGBA8 conversion is not supported on this device");
|
||||
return false;
|
||||
}
|
||||
const auto pipeline = multisample ? d24s8_to_rgba8_ms_pipeline : d24s8_to_rgba8_pipeline;
|
||||
#else
|
||||
const auto pipeline = d24s8_to_rgba8_pipeline;
|
||||
#endif
|
||||
|
||||
const auto descriptor_set = compute_provider.Commit();
|
||||
update_queue.AddImageSampler(descriptor_set, 0, 0, source.ImageView(ViewType::Depth, src_type),
|
||||
@@ -917,8 +920,8 @@ void BlitHelper::FilterPass(Surface& surface, vk::Pipeline pipeline, vk::Pipelin
|
||||
FILTER_PUSH_CONSTANT_RANGE.offset, FILTER_PUSH_CONSTANT_RANGE.size,
|
||||
&push_constants);
|
||||
|
||||
// Set up viewport and scissor for filtering (don't use BindBlitState as it overwrites push
|
||||
// constants)
|
||||
// Set up viewport and scissor for filtering (don't use BindBlitState as it overwrites
|
||||
// push constants)
|
||||
const vk::Offset2D offset{
|
||||
.x = std::min<s32>(blit.dst_rect.left, blit.dst_rect.right),
|
||||
.y = std::min<s32>(blit.dst_rect.bottom, blit.dst_rect.top),
|
||||
|
||||
@@ -256,9 +256,11 @@ public:
|
||||
return triangle_fan_supported;
|
||||
}
|
||||
|
||||
// Returns true when sampleRateShading, VK_KHR_create_renderpass2, VK_KHR_depth_stencil_resolve
|
||||
// Returns true when shaderStorageImageMultisample, sampleRateShading,
|
||||
// VK_KHR_create_renderpass2, VK_KHR_depth_stencil_resolve
|
||||
bool IsMultiSampleSupported() const {
|
||||
return features.sampleRateShading && create_renderpass2 && depth_stencil_resolve;
|
||||
return features.shaderStorageImageMultisample && features.sampleRateShading &&
|
||||
create_renderpass2 && depth_stencil_resolve;
|
||||
}
|
||||
|
||||
/// Returns true if dynamic indices can be used inside shaders.
|
||||
|
||||
@@ -339,14 +339,13 @@ bool TextureRuntime::Reinterpret(Surface& source, Surface& dest,
|
||||
}
|
||||
|
||||
if (src_format == PixelFormat::D24S8 && dst_format == PixelFormat::RGBA8) {
|
||||
blit_helper.ConvertDS24S8ToRGBA8(source, dest, copy);
|
||||
} else {
|
||||
LOG_WARNING(Render_Vulkan, "Unimplemented reinterpretation {}({}) -> {}({})",
|
||||
VideoCore::PixelFormatAsString(src_format), vk::to_string(source.traits.native),
|
||||
VideoCore::PixelFormatAsString(dst_format), vk::to_string(dest.traits.native));
|
||||
return false;
|
||||
return blit_helper.ConvertDS24S8ToRGBA8(source, dest, copy);
|
||||
}
|
||||
return true;
|
||||
|
||||
LOG_WARNING(Render_Vulkan, "Unimplemented reinterpretation {}({}) -> {}({})",
|
||||
VideoCore::PixelFormatAsString(src_format), vk::to_string(source.traits.native),
|
||||
VideoCore::PixelFormatAsString(dst_format), vk::to_string(dest.traits.native));
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TextureRuntime::ClearTexture(Surface& surface, const VideoCore::TextureClear& clear) {
|
||||
|
||||
Reference in new issue
Block a user