mirror of
https://github.com/azahar-emu/azahar.git
synced 2026-06-05 18:23:39 -04:00
renderer_gl: Implement multisample Convert{DS24S8ToRGBA8,RGBA4ToRGB5A1}
This commit is contained in:
parent
9fd44f99d6
commit
15be844ed8
6 changed files with 118 additions and 23 deletions
|
|
@ -4,7 +4,9 @@
|
|||
|
||||
set(SHADER_FILES
|
||||
format_reinterpreter/d24s8_to_rgba8.frag
|
||||
format_reinterpreter/d24s8_to_rgba8_ms.frag
|
||||
format_reinterpreter/rgba4_to_rgb5a1.frag
|
||||
format_reinterpreter/rgba4_to_rgb5a1_ms.frag
|
||||
format_reinterpreter/vulkan_d24s8_to_rgba8.comp
|
||||
format_reinterpreter/vulkan_d24s8_to_rgba8_ms.comp
|
||||
texture_filtering/bicubic.frag
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
//? #version 430 core
|
||||
|
||||
precision highp int;
|
||||
precision highp float;
|
||||
|
||||
layout(location = 0) in mediump vec2 tex_coord;
|
||||
layout(location = 0) out lowp vec4 frag_color;
|
||||
|
||||
layout(binding = 0) uniform highp sampler2DMS depth;
|
||||
layout(binding = 1) uniform lowp usampler2DMS stencil;
|
||||
|
||||
void main() {
|
||||
mediump vec2 coord = tex_coord * vec2(textureSize(depth));
|
||||
mediump ivec2 tex_icoord = ivec2(coord);
|
||||
highp uint depth_val =
|
||||
uint(texelFetch(depth, tex_icoord, gl_SampleID).x * (exp2(32.0) - 1.0));
|
||||
lowp uint stencil_val = texelFetch(stencil, tex_icoord, gl_SampleID).x;
|
||||
highp uvec4 components =
|
||||
uvec4(stencil_val, (uvec3(depth_val) >> uvec3(24u, 16u, 8u)) & 0x000000FFu);
|
||||
frag_color = vec4(components) / (exp2(8.0) - 1.0);
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
// Copyright 2023 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
//? #version 430 core
|
||||
|
||||
precision highp int;
|
||||
precision highp float;
|
||||
|
||||
layout(location = 0) in mediump vec2 tex_coord;
|
||||
layout(location = 0) out lowp vec4 frag_color;
|
||||
|
||||
layout(binding = 0) uniform lowp sampler2D source;
|
||||
|
||||
void main() {
|
||||
mediump vec2 coord = tex_coord * vec2(textureSize(source, 0));
|
||||
mediump ivec2 tex_icoord = ivec2(coord);
|
||||
lowp ivec4 rgba4 = ivec4(texelFetch(source, tex_icoord, 0) * (exp2(4.0) - 1.0));
|
||||
lowp ivec3 rgb5 =
|
||||
((rgba4.rgb << ivec3(1, 2, 3)) | (rgba4.gba >> ivec3(3, 2, 1))) & 0x1F;
|
||||
frag_color = vec4(vec3(rgb5) / (exp2(5.0) - 1.0), rgba4.a & 0x01);
|
||||
}
|
||||
|
|
@ -11,7 +11,9 @@
|
|||
#include "video_core/renderer_opengl/gl_texture_runtime.h"
|
||||
|
||||
#include "video_core/host_shaders/format_reinterpreter/d24s8_to_rgba8_frag.h"
|
||||
#include "video_core/host_shaders/format_reinterpreter/d24s8_to_rgba8_ms_frag.h"
|
||||
#include "video_core/host_shaders/format_reinterpreter/rgba4_to_rgb5a1_frag.h"
|
||||
#include "video_core/host_shaders/format_reinterpreter/rgba4_to_rgb5a1_ms_frag.h"
|
||||
#include "video_core/host_shaders/full_screen_triangle_vert.h"
|
||||
#include "video_core/host_shaders/texture_filtering/bicubic_frag.h"
|
||||
#include "video_core/host_shaders/texture_filtering/mmpx_frag.h"
|
||||
|
|
@ -65,7 +67,11 @@ BlitHelper::BlitHelper(const Driver& driver_)
|
|||
gradient_y_program{CreateProgram(HostShaders::Y_GRADIENT_FRAG, "Y_GRADIENT_FRAG")},
|
||||
refine_program{CreateProgram(HostShaders::REFINE_FRAG, "REFINE_FRAG")},
|
||||
d24s8_to_rgba8{CreateProgram(HostShaders::D24S8_TO_RGBA8_FRAG, "D24S8_TO_RGBA8_FRAG")},
|
||||
rgba4_to_rgb5a1{CreateProgram(HostShaders::RGBA4_TO_RGB5A1_FRAG, "RGBA4_TO_RGB5A1_FRAG")} {
|
||||
d24s8_to_rgba8_ms{
|
||||
CreateProgram(HostShaders::D24S8_TO_RGBA8_MS_FRAG, "D24S8_TO_RGBA8_MS_FRAG")},
|
||||
rgba4_to_rgb5a1{CreateProgram(HostShaders::RGBA4_TO_RGB5A1_FRAG, "RGBA4_TO_RGB5A1_FRAG")},
|
||||
rgba4_to_rgb5a1_ms{
|
||||
CreateProgram(HostShaders::RGBA4_TO_RGB5A1_MS_FRAG, "RGBA4_TO_RGB5A1_MS_FRAG")} {
|
||||
vao.Create();
|
||||
read_fbo.Create();
|
||||
draw_fbo.Create();
|
||||
|
|
@ -88,46 +94,63 @@ bool BlitHelper::ConvertDS24S8ToRGBA8(Surface& source, Surface& dest,
|
|||
OpenGLState prev_state = OpenGLState::GetCurState();
|
||||
SCOPE_EXIT({ prev_state.Apply(); });
|
||||
|
||||
state.texture_units[0].texture_2d = source.Handle();
|
||||
const bool multisample = (source.sample_count > 1) && (dest.sample_count > 1);
|
||||
const GLuint textarget = multisample ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D;
|
||||
|
||||
state.texture_units[0].texture_2d = source.Handle(multisample ? 3 : 1);
|
||||
state.texture_units[0].target = textarget;
|
||||
state.texture_units[0].sampler = 0;
|
||||
state.texture_units[1].sampler = 0;
|
||||
|
||||
if (use_texture_view) {
|
||||
temp_tex.Create();
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glTextureView(temp_tex.handle, GL_TEXTURE_2D, source.Handle(), GL_DEPTH24_STENCIL8, 0, 1, 0,
|
||||
1);
|
||||
glTextureView(temp_tex.handle, textarget, source.Handle(multisample ? 3 : 1),
|
||||
GL_DEPTH24_STENCIL8, 0, 1, 0, 1);
|
||||
if (!multisample) {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
}
|
||||
} else if (copy.extent.width > temp_extent.width || copy.extent.height > temp_extent.height) {
|
||||
temp_extent = copy.extent;
|
||||
temp_tex.Release();
|
||||
temp_tex.Create();
|
||||
state.texture_units[1].texture_2d = temp_tex.handle;
|
||||
state.texture_units[1].target = textarget;
|
||||
state.Apply();
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, temp_extent.width,
|
||||
|
||||
if (multisample) {
|
||||
glTexStorage2DMultisample(textarget, source.sample_count, GL_DEPTH24_STENCIL8,
|
||||
temp_extent.width, temp_extent.height, true);
|
||||
|
||||
} else {
|
||||
glTexStorage2D(textarget, 1, GL_DEPTH24_STENCIL8, temp_extent.width,
|
||||
temp_extent.height);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(textarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(textarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
}
|
||||
}
|
||||
state.texture_units[1].texture_2d = temp_tex.handle;
|
||||
state.texture_units[1].target = textarget;
|
||||
state.Apply();
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
if (!use_texture_view) {
|
||||
glCopyImageSubData(source.Handle(), GL_TEXTURE_2D, 0, copy.src_offset.x, copy.src_offset.y,
|
||||
0, temp_tex.handle, GL_TEXTURE_2D, 0, copy.src_offset.x,
|
||||
glCopyImageSubData(source.Handle(multisample ? 3 : 1), textarget, 0, copy.src_offset.x,
|
||||
copy.src_offset.y, 0, temp_tex.handle, textarget, 0, copy.src_offset.x,
|
||||
copy.src_offset.y, 0, copy.extent.width, copy.extent.height, 1);
|
||||
}
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX);
|
||||
glTexParameteri(textarget, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX);
|
||||
|
||||
const Common::Rectangle src_rect{copy.src_offset.x, copy.src_offset.y + copy.extent.height,
|
||||
copy.src_offset.x + copy.extent.width, copy.src_offset.x};
|
||||
const Common::Rectangle dst_rect{copy.dst_offset.x, copy.dst_offset.y + copy.extent.height,
|
||||
copy.dst_offset.x + copy.extent.width, copy.dst_offset.x};
|
||||
SetParams(d24s8_to_rgba8, source.RealExtent(), src_rect);
|
||||
Draw(d24s8_to_rgba8, dest.Handle(), draw_fbo.handle, 0, dst_rect);
|
||||
|
||||
OGLProgram& blit_program = multisample ? d24s8_to_rgba8_ms : d24s8_to_rgba8;
|
||||
SetParams(blit_program, source.RealExtent(), src_rect);
|
||||
Draw(blit_program, dest.Handle(multisample ? 3 : 1), draw_fbo.handle, 0, dst_rect, multisample);
|
||||
|
||||
if (use_texture_view) {
|
||||
temp_tex.Release();
|
||||
|
|
@ -137,6 +160,11 @@ bool BlitHelper::ConvertDS24S8ToRGBA8(Surface& source, Surface& dest,
|
|||
state.texture_units[0].sampler = linear_sampler.handle;
|
||||
state.texture_units[1].sampler = linear_sampler.handle;
|
||||
|
||||
if (multisample) {
|
||||
// Resolve the destination image if needed
|
||||
ResolveTexture(dest);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -145,22 +173,36 @@ bool BlitHelper::ConvertRGBA4ToRGB5A1(Surface& source, Surface& dest,
|
|||
OpenGLState prev_state = OpenGLState::GetCurState();
|
||||
SCOPE_EXIT({ prev_state.Apply(); });
|
||||
|
||||
state.texture_units[0].texture_2d = source.Handle();
|
||||
const bool multisample = (source.sample_count > 1) && (dest.sample_count > 1);
|
||||
|
||||
state.texture_units[0].texture_2d = source.Handle(multisample ? 3 : 1);
|
||||
|
||||
const Common::Rectangle src_rect{copy.src_offset.x, copy.src_offset.y + copy.extent.height,
|
||||
copy.src_offset.x + copy.extent.width, copy.src_offset.x};
|
||||
const Common::Rectangle dst_rect{copy.dst_offset.x, copy.dst_offset.y + copy.extent.height,
|
||||
copy.dst_offset.x + copy.extent.width, copy.dst_offset.x};
|
||||
SetParams(rgba4_to_rgb5a1, source.RealExtent(), src_rect);
|
||||
Draw(rgba4_to_rgb5a1, dest.Handle(), draw_fbo.handle, 0, dst_rect);
|
||||
|
||||
OGLProgram& blit_program = multisample ? rgba4_to_rgb5a1_ms : rgba4_to_rgb5a1;
|
||||
SetParams(blit_program, source.RealExtent(), src_rect);
|
||||
Draw(blit_program, dest.Handle(multisample ? 3 : 1), draw_fbo.handle, 0, dst_rect, multisample);
|
||||
|
||||
if (multisample) {
|
||||
// Resolve the destination image if needed
|
||||
ResolveTexture(dest);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BlitHelper::ResolveTexture(Surface& surface) {
|
||||
OpenGLState prev_state = OpenGLState::GetCurState();
|
||||
SCOPE_EXIT({ prev_state.Apply(); });
|
||||
|
||||
state.draw.read_framebuffer = read_fbo.handle;
|
||||
state.draw.draw_framebuffer = draw_fbo.handle;
|
||||
state.texture_units[0].texture_2d = 0;
|
||||
state.texture_units[1].texture_2d = 0;
|
||||
state.texture_units[2].texture_2d = 0;
|
||||
state.Apply();
|
||||
|
||||
surface.Attach(GL_READ_FRAMEBUFFER, 0, 0, 3);
|
||||
|
|
@ -307,7 +349,7 @@ void BlitHelper::SetParams(OGLProgram& program, const VideoCore::Extent& src_ext
|
|||
}
|
||||
|
||||
void BlitHelper::Draw(OGLProgram& program, GLuint dst_tex, GLuint dst_fbo, u32 dst_level,
|
||||
Common::Rectangle<u32> dst_rect) {
|
||||
Common::Rectangle<u32> dst_rect, bool multisample) {
|
||||
state.draw.draw_framebuffer = dst_fbo;
|
||||
state.draw.shader_program = program.handle;
|
||||
state.viewport.x = dst_rect.left;
|
||||
|
|
@ -316,9 +358,11 @@ void BlitHelper::Draw(OGLProgram& program, GLuint dst_tex, GLuint dst_fbo, u32 d
|
|||
state.viewport.height = dst_rect.GetHeight();
|
||||
state.Apply();
|
||||
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dst_tex,
|
||||
const GLuint textarget = multisample ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D;
|
||||
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, textarget, dst_tex,
|
||||
dst_level);
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, textarget, 0, 0);
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ private:
|
|||
void SetParams(OGLProgram& program, const VideoCore::Extent& src_extent,
|
||||
Common::Rectangle<u32> src_rect);
|
||||
void Draw(OGLProgram& program, GLuint dst_tex, GLuint dst_fbo, u32 dst_level,
|
||||
Common::Rectangle<u32> dst_rect);
|
||||
Common::Rectangle<u32> dst_rect, bool multisample = false);
|
||||
|
||||
private:
|
||||
const Driver& driver;
|
||||
|
|
@ -62,7 +62,9 @@ private:
|
|||
OGLProgram gradient_y_program;
|
||||
OGLProgram refine_program;
|
||||
OGLProgram d24s8_to_rgba8;
|
||||
OGLProgram d24s8_to_rgba8_ms;
|
||||
OGLProgram rgba4_to_rgb5a1;
|
||||
OGLProgram rgba4_to_rgb5a1_ms;
|
||||
|
||||
OGLTexture temp_tex;
|
||||
VideoCore::Extent temp_extent{};
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ static constexpr std::array<FormatTuple, 8> CUSTOM_TUPLES = {{
|
|||
ASSERT(target == GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, texture.handle);
|
||||
glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, tuple.internal_format, width,
|
||||
height, false);
|
||||
height, true);
|
||||
} else {
|
||||
glBindTexture(target, texture.handle);
|
||||
glTexStorage2D(target, levels, tuple.internal_format, width, height);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue