gl: Implement MSAA resolve/unresolve for color images

This commit is contained in:
kd-11 2025-02-05 01:47:09 +03:00 committed by kd-11
parent 2a4bd6a7fc
commit 8249b5dbfa
7 changed files with 157 additions and 10 deletions

View file

@ -1,15 +1,105 @@
#include "stdafx.h"
#include "GLResolveHelper.h"
#include <unordered_map>
namespace gl
{
std::unordered_map<texture::internal_format, std::unique_ptr<cs_resolve_task>> g_resolve_helpers;
std::unordered_map<texture::internal_format, std::unique_ptr<cs_unresolve_task>> g_unresolve_helpers;
static const char* get_format_string(gl::texture::internal_format format)
{
switch (format)
{
case texture::internal_format::rgb565:
return "r16";
case texture::internal_format::rgba8:
case texture::internal_format::bgra8:
return "rgba8";
case texture::internal_format::rgba16f:
return "rgba16f";
case texture::internal_format::rgba32f:
return "rgba32f";
case texture::internal_format::bgr5a1:
return "r16";
case texture::internal_format::r8:
return "r8";
case texture::internal_format::rg8:
return "rg8";
case texture::internal_format::r32f:
return "r32f";
default:
fmt::throw_exception("Unhandled internal format 0x%x", u32(format));
}
}
void resolve_image(gl::command_context& cmd, gl::viewable_image* dst, gl::viewable_image* src)
{
// TODO
ensure(src->format_class() == RSX_FORMAT_CLASS_COLOR); // TODO
{
auto& job = g_resolve_helpers[src->get_internal_format()];
if (!job)
{
const auto fmt = get_format_string(src->get_internal_format());
job.reset(new cs_resolve_task(fmt));
}
job->run(cmd, src, dst);
}
}
void unresolve_image(gl::command_context& cmd, gl::viewable_image* dst, gl::viewable_image* src)
{
// TODO
ensure(src->format_class() == RSX_FORMAT_CLASS_COLOR); // TODO
{
auto& job = g_unresolve_helpers[src->get_internal_format()];
if (!job)
{
const auto fmt = get_format_string(src->get_internal_format());
job.reset(new cs_unresolve_task(fmt));
}
job->run(cmd, dst, src);
}
}
void cs_resolve_base::build(const std::string& format_prefix, bool unresolve)
{
create();
switch (optimal_group_size)
{
default:
case 64:
cs_wave_x = 8;
cs_wave_y = 8;
break;
case 32:
cs_wave_x = 8;
cs_wave_y = 4;
break;
}
static const char* resolve_kernel =
#include "Emu/RSX/Program/MSAA/ColorResolvePass.glsl"
;
static const char* unresolve_kernel =
#include "Emu/RSX/Program/MSAA/ColorResolvePass.glsl"
;
const std::pair<std::string_view, std::string> syntax_replace[] =
{
{ "%WORKGROUP_SIZE_X", std::to_string(cs_wave_x) },
{ "%WORKGROUP_SIZE_Y", std::to_string(cs_wave_y) },
{ "%IMAGE_FORMAT", format_prefix },
{ "%BGRA_SWAP", "0" }
};
m_src = unresolve ? unresolve_kernel : resolve_kernel;
m_src = fmt::replace_all(m_src, syntax_replace);
rsx_log.notice("Resolve shader:\n%s", m_src);
}
}

View file

@ -7,4 +7,60 @@ namespace gl
{
void resolve_image(gl::command_context& cmd, gl::viewable_image* dst, gl::viewable_image* src);
void unresolve_image(gl::command_context& cmd, gl::viewable_image* dst, gl::viewable_image* src);
struct cs_resolve_base : compute_task
{
gl::viewable_image* multisampled = nullptr;
gl::viewable_image* resolve = nullptr;
u32 cs_wave_x = 1;
u32 cs_wave_y = 1;
cs_resolve_base()
{}
virtual ~cs_resolve_base()
{}
void build(const std::string& format_prefix, bool unresolve);
void bind_resources() override
{
auto msaa_view = multisampled->get_view(rsx::default_remap_vector.with_encoding(GL_REMAP_VIEW_MULTISAMPLED));
auto resolved_view = resolve->get_view(rsx::default_remap_vector.with_encoding(GL_REMAP_IDENTITY));
glBindImageTexture(GL_COMPUTE_IMAGE_SLOT(0), msaa_view->id(), 0, GL_FALSE, 0, GL_WRITE_ONLY, msaa_view->view_format());
glBindImageTexture(GL_COMPUTE_IMAGE_SLOT(1), resolved_view->id(), 0, GL_FALSE, 0, GL_WRITE_ONLY, resolved_view->view_format());
}
void run(gl::command_context& cmd, gl::viewable_image* msaa_image, gl::viewable_image* resolve_image)
{
ensure(msaa_image->samples() > 1);
ensure(resolve_image->samples() == 1);
multisampled = msaa_image;
resolve = resolve_image;
const u32 invocations_x = utils::align(resolve_image->width(), cs_wave_x) / cs_wave_x;
const u32 invocations_y = utils::align(resolve_image->height(), cs_wave_y) / cs_wave_y;
compute_task::run(cmd, invocations_x, invocations_y);
}
};
struct cs_resolve_task : cs_resolve_base
{
cs_resolve_task(const std::string& format_prefix)
{
build(format_prefix, false);
}
};
struct cs_unresolve_task : cs_resolve_base
{
cs_unresolve_task(const std::string& format_prefix)
{
build(format_prefix, true);
}
};
}

View file

@ -45,7 +45,8 @@ namespace gl
enum remap_constants : u32
{
GL_REMAP_IDENTITY = 0xCAFEBABE,
GL_REMAP_BGRA = 0x0000AA6C
GL_REMAP_BGRA = 0x0000AA6C,
GL_REMAP_VIEW_MULTISAMPLED = 0xDEADBEEF
};
struct subresource_range

View file

@ -7,8 +7,8 @@ layout(local_size_x=%WORKGROUP_SIZE_X, local_size_y=%WORKGROUP_SIZE_Y, local_siz
layout(set=0, binding=0) uniform writeonly restrict image2DMS multisampled;
layout(set=0, binding=1, %IMAGE_FORMAT) uniform readonly restrict image2D resolve;
#else
layout(binding=30) uniform readonly restrict image2DMS multisampled;
layout(binding=31, %IMAGE_FORMAT) uniform readonly restrict image2D resolve;
layout(binding=0) uniform readonly restrict image2DMS multisampled;
layout(binding=1, %IMAGE_FORMAT) uniform readonly restrict image2D resolve;
#endif
#if %BGRA_SWAP

View file

@ -998,7 +998,7 @@ namespace vk
return;
}
// Memory transfers
// Memory transfers
vk::image* target_image = (samples() > 1) ? get_resolve_target_safe(cmd) : this;
vk::blitter hw_blitter;
const auto dst_bpp = get_bpp();

View file

@ -60,7 +60,7 @@
<ClInclude Include="Emu\RSX\GL\GLGSRender.h" />
<ClInclude Include="Emu\RSX\GL\GLProcTable.h" />
<ClInclude Include="Emu\RSX\GL\GLProgramBuffer.h" />
<ClInclude Include="Emu\RSX\GL\GLResolveHelpers.h" />
<ClInclude Include="Emu\RSX\GL\GLResolveHelper.h" />
<ClInclude Include="Emu\RSX\GL\glutils\blitter.h" />
<ClInclude Include="Emu\RSX\GL\glutils\buffer_object.h" />
<ClInclude Include="Emu\RSX\GL\glutils\capabilities.h" />
@ -96,7 +96,7 @@
<ClCompile Include="Emu\RSX\GL\GLGSRender.cpp" />
<ClCompile Include="Emu\RSX\GL\GLOverlays.cpp" />
<ClCompile Include="Emu\RSX\GL\GLPipelineCompiler.cpp" />
<ClCompile Include="Emu\RSX\GL\GLResolveHelpers.cpp" />
<ClCompile Include="Emu\RSX\GL\GLResolveHelper.cpp" />
<ClCompile Include="Emu\RSX\GL\glutils\blitter.cpp" />
<ClCompile Include="Emu\RSX\GL\glutils\buffer_object.cpp" />
<ClCompile Include="Emu\RSX\GL\glutils\capabilities.cpp" />

View file

@ -48,7 +48,7 @@
<Filter>upscalers\fsr1</Filter>
</ClCompile>
<ClCompile Include="Emu\RSX\GL\GLDMA.cpp" />
<ClCompile Include="Emu\RSX\GL\GLResolveHelpers.cpp" />
<ClCompile Include="Emu\RSX\GL\GLResolveHelper.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="Emu\RSX\GL\GLTexture.h" />
@ -121,7 +121,7 @@
<Filter>upscalers</Filter>
</ClInclude>
<ClInclude Include="Emu\RSX\GL\GLDMA.h" />
<ClInclude Include="Emu\RSX\GL\GLResolveHelpers.h" />
<ClInclude Include="Emu\RSX\GL\GLResolveHelper.h" />
</ItemGroup>
<ItemGroup>
<Filter Include="glutils">