mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-05-11 21:52:40 +00:00
VideoBackends: Use VideoCommon shader generators for efb2tex copies.
This will generate one shader per copy format. For now, it is the same shader with the colmat hard coded. So it should already improve the GPU performance a bit, but a rewrite of the shader generator is suggested. Half of the patch is done by linkmauve1: VideoCommon: Reorganise the shader writes.
This commit is contained in:
parent
2b2941d0c9
commit
491c10ec96
15 changed files with 468 additions and 211 deletions
|
@ -26,11 +26,44 @@
|
|||
|
||||
#include "VideoCommon/ImageWrite.h"
|
||||
#include "VideoCommon/TextureConversionShader.h"
|
||||
#include "VideoCommon/TextureConverterShaderGen.h"
|
||||
#include "VideoCommon/TextureDecoder.h"
|
||||
#include "VideoCommon/VideoCommon.h"
|
||||
#include "VideoCommon/VideoConfig.h"
|
||||
|
||||
namespace OGL
|
||||
{
|
||||
constexpr const char* vertex_program =
|
||||
"out vec3 %c_uv0;\n"
|
||||
"SAMPLER_BINDING(9) uniform sampler2DArray samp9;\n"
|
||||
"uniform vec4 copy_position;\n" // left, top, right, bottom
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" vec2 rawpos = vec2(gl_VertexID&1, gl_VertexID&2);\n"
|
||||
" %c_uv0 = vec3(mix(copy_position.xy, copy_position.zw, rawpos) / vec2(textureSize(samp9, "
|
||||
"0).xy), 0.0);\n"
|
||||
" gl_Position = vec4(rawpos*2.0-1.0, 0.0, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
constexpr const char* geometry_program = "layout(triangles) in;\n"
|
||||
"layout(triangle_strip, max_vertices = 6) out;\n"
|
||||
"in vec3 v_uv0[3];\n"
|
||||
"out vec3 f_uv0;\n"
|
||||
"SAMPLER_BINDING(9) uniform sampler2DArray samp9;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" int layers = textureSize(samp9, 0).z;\n"
|
||||
" for (int layer = 0; layer < layers; ++layer) {\n"
|
||||
" for (int i = 0; i < 3; ++i) {\n"
|
||||
" f_uv0 = vec3(v_uv0[i].xy, layer);\n"
|
||||
" gl_Position = gl_in[i].gl_Position;\n"
|
||||
" gl_Layer = layer;\n"
|
||||
" EmitVertex();\n"
|
||||
" }\n"
|
||||
" EndPrimitive();\n"
|
||||
" }\n"
|
||||
"}\n";
|
||||
|
||||
//#define TIME_TEXTURE_DECODING 1
|
||||
|
||||
void TextureCache::CopyEFB(u8* dst, const EFBCopyParams& params, u32 native_width,
|
||||
|
@ -124,101 +157,22 @@ bool TextureCache::CompileShaders()
|
|||
" ocol0 = texcol;\n"
|
||||
"}\n";
|
||||
|
||||
constexpr const char* color_matrix_program =
|
||||
"SAMPLER_BINDING(9) uniform sampler2DArray samp9;\n"
|
||||
"uniform vec4 colmat[7];\n"
|
||||
"in vec3 f_uv0;\n"
|
||||
"out vec4 ocol0;\n"
|
||||
"\n"
|
||||
"void main(){\n"
|
||||
" vec4 texcol = texture(samp9, f_uv0);\n"
|
||||
" texcol = floor(texcol * colmat[5]) * colmat[6];\n"
|
||||
" ocol0 = texcol * mat4(colmat[0], colmat[1], colmat[2], colmat[3]) + colmat[4];\n"
|
||||
"}\n";
|
||||
|
||||
constexpr const char* depth_matrix_program =
|
||||
"SAMPLER_BINDING(9) uniform sampler2DArray samp9;\n"
|
||||
"uniform vec4 colmat[5];\n"
|
||||
"in vec3 f_uv0;\n"
|
||||
"out vec4 ocol0;\n"
|
||||
"\n"
|
||||
"void main(){\n"
|
||||
" vec4 texcol = texture(samp9, vec3(f_uv0.xy, %s));\n"
|
||||
" int depth = int(texcol.x * 16777216.0);\n"
|
||||
|
||||
// Convert to Z24 format
|
||||
" ivec4 workspace;\n"
|
||||
" workspace.r = (depth >> 16) & 255;\n"
|
||||
" workspace.g = (depth >> 8) & 255;\n"
|
||||
" workspace.b = depth & 255;\n"
|
||||
|
||||
// Convert to Z4 format
|
||||
" workspace.a = (depth >> 16) & 0xF0;\n"
|
||||
|
||||
// Normalize components to [0.0..1.0]
|
||||
" texcol = vec4(workspace) / 255.0;\n"
|
||||
|
||||
" ocol0 = texcol * mat4(colmat[0], colmat[1], colmat[2], colmat[3]) + colmat[4];\n"
|
||||
"}\n";
|
||||
|
||||
constexpr const char* vertex_program =
|
||||
"out vec3 %s_uv0;\n"
|
||||
"SAMPLER_BINDING(9) uniform sampler2DArray samp9;\n"
|
||||
"uniform vec4 copy_position;\n" // left, top, right, bottom
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" vec2 rawpos = vec2(gl_VertexID&1, gl_VertexID&2);\n"
|
||||
" %s_uv0 = vec3(mix(copy_position.xy, copy_position.zw, rawpos) / vec2(textureSize(samp9, "
|
||||
"0).xy), 0.0);\n"
|
||||
" gl_Position = vec4(rawpos*2.0-1.0, 0.0, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
const std::string geo_program = g_ActiveConfig.stereo_mode != StereoMode::Off ?
|
||||
"layout(triangles) in;\n"
|
||||
"layout(triangle_strip, max_vertices = 6) out;\n"
|
||||
"in vec3 v_uv0[3];\n"
|
||||
"out vec3 f_uv0;\n"
|
||||
"SAMPLER_BINDING(9) uniform sampler2DArray samp9;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" int layers = textureSize(samp9, 0).z;\n"
|
||||
" for (int layer = 0; layer < layers; ++layer) {\n"
|
||||
" for (int i = 0; i < 3; ++i) {\n"
|
||||
" f_uv0 = vec3(v_uv0[i].xy, layer);\n"
|
||||
" gl_Position = gl_in[i].gl_Position;\n"
|
||||
" gl_Layer = layer;\n"
|
||||
" EmitVertex();\n"
|
||||
" }\n"
|
||||
" EndPrimitive();\n"
|
||||
" }\n"
|
||||
"}\n" :
|
||||
"";
|
||||
|
||||
const char* prefix = geo_program.empty() ? "f" : "v";
|
||||
const char* depth_layer = g_ActiveConfig.bStereoEFBMonoDepth ? "0.0" : "f_uv0.z";
|
||||
std::string geo_program = "";
|
||||
char prefix = 'f';
|
||||
if (g_ActiveConfig.stereo_mode != StereoMode::Off)
|
||||
{
|
||||
geo_program = geometry_program;
|
||||
prefix = 'v';
|
||||
}
|
||||
|
||||
if (!ProgramShaderCache::CompileShader(m_colorCopyProgram,
|
||||
StringFromFormat(vertex_program, prefix, prefix),
|
||||
color_copy_program, geo_program) ||
|
||||
!ProgramShaderCache::CompileShader(m_colorMatrixProgram,
|
||||
StringFromFormat(vertex_program, prefix, prefix),
|
||||
color_matrix_program, geo_program) ||
|
||||
!ProgramShaderCache::CompileShader(
|
||||
m_depthMatrixProgram, StringFromFormat(vertex_program, prefix, prefix),
|
||||
StringFromFormat(depth_matrix_program, depth_layer), geo_program))
|
||||
color_copy_program, geo_program))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m_colorMatrixUniform = glGetUniformLocation(m_colorMatrixProgram.glprogid, "colmat");
|
||||
m_depthMatrixUniform = glGetUniformLocation(m_depthMatrixProgram.glprogid, "colmat");
|
||||
m_color_cbuf_id = UINT_MAX;
|
||||
m_depth_cbuf_id = UINT_MAX;
|
||||
|
||||
m_colorCopyPositionUniform = glGetUniformLocation(m_colorCopyProgram.glprogid, "copy_position");
|
||||
m_colorMatrixPositionUniform =
|
||||
glGetUniformLocation(m_colorMatrixProgram.glprogid, "copy_position");
|
||||
m_depthCopyPositionUniform = glGetUniformLocation(m_depthMatrixProgram.glprogid, "copy_position");
|
||||
|
||||
std::string palette_shader =
|
||||
R"GLSL(
|
||||
|
@ -320,8 +274,9 @@ bool TextureCache::CompileShaders()
|
|||
|
||||
void TextureCache::DeleteShaders()
|
||||
{
|
||||
m_colorMatrixProgram.Destroy();
|
||||
m_depthMatrixProgram.Destroy();
|
||||
for (auto& it : m_efb_copy_programs)
|
||||
it.second.shader.Destroy();
|
||||
m_efb_copy_programs.clear();
|
||||
|
||||
if (g_ActiveConfig.backend_info.bSupportsPaletteConversion)
|
||||
for (auto& shader : m_palette_shaders)
|
||||
|
@ -531,7 +486,8 @@ void TextureCache::DecodeTextureOnGPU(TCacheEntry* entry, u32 dst_level, const u
|
|||
|
||||
void TextureCache::CopyEFBToCacheEntry(TCacheEntry* entry, bool is_depth_copy,
|
||||
const EFBRectangle& src_rect, bool scale_by_half,
|
||||
unsigned int cbuf_id, const float* colmat)
|
||||
unsigned int cbuf_id, const float* colmat,
|
||||
EFBCopyFormat dst_format, bool is_intensity)
|
||||
{
|
||||
auto* destination_texture = static_cast<OGLTexture*>(entry->texture.get());
|
||||
g_renderer->ResetAPIState(); // reset any game specific settings
|
||||
|
@ -554,26 +510,35 @@ void TextureCache::CopyEFBToCacheEntry(TCacheEntry* entry, bool is_depth_copy,
|
|||
|
||||
glViewport(0, 0, destination_texture->GetConfig().width, destination_texture->GetConfig().height);
|
||||
|
||||
GLuint uniform_location;
|
||||
if (is_depth_copy)
|
||||
auto uid = GetTextureConverterShaderUid(dst_format, is_depth_copy, is_intensity, scale_by_half);
|
||||
|
||||
auto it = m_efb_copy_programs.emplace(uid, EFBCopyShader());
|
||||
EFBCopyShader& shader = it.first->second;
|
||||
bool created = it.second;
|
||||
|
||||
if (created)
|
||||
{
|
||||
m_depthMatrixProgram.Bind();
|
||||
if (m_depth_cbuf_id != cbuf_id)
|
||||
glUniform4fv(m_depthMatrixUniform, 5, colmat);
|
||||
m_depth_cbuf_id = cbuf_id;
|
||||
uniform_location = m_depthCopyPositionUniform;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_colorMatrixProgram.Bind();
|
||||
if (m_color_cbuf_id != cbuf_id)
|
||||
glUniform4fv(m_colorMatrixUniform, 7, colmat);
|
||||
m_color_cbuf_id = cbuf_id;
|
||||
uniform_location = m_colorMatrixPositionUniform;
|
||||
ShaderCode code = GenerateTextureConverterShaderCode(APIType::OpenGL, uid.GetUidData());
|
||||
|
||||
std::string geo_program = "";
|
||||
char prefix = 'f';
|
||||
if (g_ActiveConfig.stereo_mode != StereoMode::Off)
|
||||
{
|
||||
geo_program = geometry_program;
|
||||
prefix = 'v';
|
||||
}
|
||||
|
||||
ProgramShaderCache::CompileShader(shader.shader,
|
||||
StringFromFormat(vertex_program, prefix, prefix),
|
||||
code.GetBuffer(), geo_program);
|
||||
|
||||
shader.position_uniform = glGetUniformLocation(shader.shader.glprogid, "copy_position");
|
||||
}
|
||||
|
||||
shader.shader.Bind();
|
||||
|
||||
TargetRectangle R = g_renderer->ConvertEFBRectangle(src_rect);
|
||||
glUniform4f(uniform_location, static_cast<float>(R.left), static_cast<float>(R.top),
|
||||
glUniform4f(shader.position_uniform, static_cast<float>(R.left), static_cast<float>(R.top),
|
||||
static_cast<float>(R.right), static_cast<float>(R.bottom));
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue