mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-16 23:17:29 +00:00
Shaders decompiler: support non 2D textures
Do not validate programs with undefined textures uniforms Minor fix
This commit is contained in:
parent
d69a4173fa
commit
e296f81a37
@ -311,7 +311,7 @@ void GLGSRender::end()
|
|||||||
for (int i = 0; i < rsx::limits::textures_count; ++i)
|
for (int i = 0; i < rsx::limits::textures_count; ++i)
|
||||||
{
|
{
|
||||||
int location;
|
int location;
|
||||||
if (m_program->uniforms.has_location("texture" + std::to_string(i), &location))
|
if (m_program->uniforms.has_location("ftexture" + std::to_string(i), &location))
|
||||||
{
|
{
|
||||||
if (!textures[i].enabled())
|
if (!textures[i].enabled())
|
||||||
{
|
{
|
||||||
@ -330,7 +330,7 @@ void GLGSRender::end()
|
|||||||
|
|
||||||
//texture_index++;
|
//texture_index++;
|
||||||
|
|
||||||
if (m_program->uniforms.has_location("texture" + std::to_string(i) + "_cm", &location))
|
if (m_program->uniforms.has_location("ftexture" + std::to_string(i) + "_cm", &location))
|
||||||
{
|
{
|
||||||
if (textures[i].format() & CELL_GCM_TEXTURE_UN)
|
if (textures[i].format() & CELL_GCM_TEXTURE_UN)
|
||||||
{
|
{
|
||||||
@ -657,6 +657,15 @@ static void fill_matrix_buffer(glsl_matrix_buffer *buffer)
|
|||||||
|
|
||||||
bool GLGSRender::load_program()
|
bool GLGSRender::load_program()
|
||||||
{
|
{
|
||||||
|
if (0)
|
||||||
|
{
|
||||||
|
RSXVertexProgram vertex_program = get_current_vertex_program();
|
||||||
|
RSXFragmentProgram fragment_program = get_current_fragment_program();
|
||||||
|
|
||||||
|
GLProgramBuffer prog_buffer;
|
||||||
|
__glcheck prog_buffer.getGraphicPipelineState(vertex_program, fragment_program, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
rsx::program_info info = programs_cache.get(get_raw_program(), rsx::decompile_language::glsl);
|
rsx::program_info info = programs_cache.get(get_raw_program(), rsx::decompile_language::glsl);
|
||||||
m_program = (gl::glsl::program*)info.program;
|
m_program = (gl::glsl::program*)info.program;
|
||||||
m_program->use();
|
m_program->use();
|
||||||
|
@ -3,6 +3,162 @@
|
|||||||
#include "gl_helpers.h"
|
#include "gl_helpers.h"
|
||||||
#include "../GCM.h"
|
#include "../GCM.h"
|
||||||
|
|
||||||
|
static void insert_texture_fetch_function(std::string &dst, const rsx::decompiled_shader &shader, const rsx::program_state &state)
|
||||||
|
{
|
||||||
|
if (shader.textures.empty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dst += "vec4 texture_fetch(int index, vec4 coord)\n{\n";
|
||||||
|
dst += "\tswitch (index)\n\t{\n";
|
||||||
|
|
||||||
|
for (auto &texture : shader.textures)
|
||||||
|
{
|
||||||
|
dst += "\tcase " + std::to_string(texture.id) + ": return ";
|
||||||
|
|
||||||
|
switch (state.textures[texture.id])
|
||||||
|
{
|
||||||
|
case rsx::texture_target::none: dst += "vec4(0.0)"; break;
|
||||||
|
case rsx::texture_target::_1: dst += "texture(" + texture.name + ", coord.x)"; break;
|
||||||
|
case rsx::texture_target::_2: dst += "texture(" + texture.name + ", coord.xy)"; break;
|
||||||
|
|
||||||
|
case rsx::texture_target::cube:
|
||||||
|
case rsx::texture_target::_3: dst += "texture(" + texture.name + ", coord.xyz)"; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
dst += ";\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
dst += "\t}\n";
|
||||||
|
dst += "}\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
static void insert_texture_bias_fetch_function(std::string &dst, const rsx::decompiled_shader &shader, const rsx::program_state &state)
|
||||||
|
{
|
||||||
|
if (shader.textures.empty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dst += "vec4 texture_bias_fetch(int index, vec4 coord, float bias)\n{\n";
|
||||||
|
dst += "\tswitch (index)\n\t{\n";
|
||||||
|
|
||||||
|
for (auto &texture : shader.textures)
|
||||||
|
{
|
||||||
|
dst += "\tcase " + std::to_string(texture.id) + ": return ";
|
||||||
|
|
||||||
|
switch (state.textures[texture.id])
|
||||||
|
{
|
||||||
|
case rsx::texture_target::none: dst += "vec4(0.0)"; break;
|
||||||
|
case rsx::texture_target::_1: dst += "texture(" + texture.name + ", coord.x, bias)"; break;
|
||||||
|
case rsx::texture_target::_2: dst += "texture(" + texture.name + ", coord.xy, bias)"; break;
|
||||||
|
|
||||||
|
case rsx::texture_target::cube:
|
||||||
|
case rsx::texture_target::_3: dst += "texture(" + texture.name + ", coord.xyz, bias)"; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
dst += ";\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
dst += "\t}\n";
|
||||||
|
dst += "}\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
static void insert_texture_grad_fetch_function(std::string &dst, const rsx::decompiled_shader &shader, const rsx::program_state &state)
|
||||||
|
{
|
||||||
|
if (shader.textures.empty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dst += "vec4 texture_grad_fetch(int index, vec4 coord, vec4 dPdx, vec4 dPdy)\n{\n";
|
||||||
|
dst += "\tswitch (index)\n\t{\n";
|
||||||
|
|
||||||
|
for (auto &texture : shader.textures)
|
||||||
|
{
|
||||||
|
dst += "\tcase " + std::to_string(texture.id) + ": return ";
|
||||||
|
|
||||||
|
switch (state.textures[texture.id])
|
||||||
|
{
|
||||||
|
case rsx::texture_target::none: dst += "vec4(0.0)"; break;
|
||||||
|
case rsx::texture_target::_1: dst += "textureGrad(" + texture.name + ", coord.x, dPdx.x, dPdy.x)"; break;
|
||||||
|
case rsx::texture_target::_2: dst += "textureGrad(" + texture.name + ", coord.xy, dPdx.xy, dPdy.xy)"; break;
|
||||||
|
|
||||||
|
case rsx::texture_target::cube:
|
||||||
|
case rsx::texture_target::_3: dst += "textureGrad(" + texture.name + ", coord.xyz, dPdx.xyz, dPdy.xyz)"; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
dst += ";\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
dst += "\t}\n";
|
||||||
|
dst += "}\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
static void insert_texture_lod_fetch_function(std::string &dst, const rsx::decompiled_shader &shader, const rsx::program_state &state)
|
||||||
|
{
|
||||||
|
if (shader.textures.empty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dst += "vec4 texture_lod_fetch(int index, vec4 coord, float lod)\n{\n";
|
||||||
|
dst += "\tswitch (index)\n\t{\n";
|
||||||
|
|
||||||
|
for (auto &texture : shader.textures)
|
||||||
|
{
|
||||||
|
dst += "\tcase " + std::to_string(texture.id) + ": return ";
|
||||||
|
|
||||||
|
switch (state.textures[texture.id])
|
||||||
|
{
|
||||||
|
case rsx::texture_target::none: dst += "vec4(0.0)"; break;
|
||||||
|
case rsx::texture_target::_1: dst += "textureLod(" + texture.name + ", coord.x, lod)"; break;
|
||||||
|
case rsx::texture_target::_2: dst += "textureLod(" + texture.name + ", coord.xy, lod)"; break;
|
||||||
|
|
||||||
|
case rsx::texture_target::cube:
|
||||||
|
case rsx::texture_target::_3: dst += "textureLod(" + texture.name + ", coord.xyz, lod)"; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
dst += ";\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
dst += "\t}\n";
|
||||||
|
dst += "}\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void insert_texture_proj_fetch_function(std::string &dst, const rsx::decompiled_shader &shader, const rsx::program_state &state)
|
||||||
|
{
|
||||||
|
if (shader.textures.empty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dst += "vec4 texture_proj_fetch(int index, vec4 coord, float bias)\n{\n";
|
||||||
|
dst += "\tswitch (index)\n\t{\n";
|
||||||
|
|
||||||
|
for (auto &texture : shader.textures)
|
||||||
|
{
|
||||||
|
dst += "\tcase " + std::to_string(texture.id) + ": return ";
|
||||||
|
|
||||||
|
switch (state.textures[texture.id])
|
||||||
|
{
|
||||||
|
case rsx::texture_target::cube:
|
||||||
|
case rsx::texture_target::none: dst += "vec4(0.0)"; break;
|
||||||
|
case rsx::texture_target::_1: dst += "textureProj(" + texture.name + ", coord.xy, bias)"; break;
|
||||||
|
case rsx::texture_target::_2: dst += "textureProj(" + texture.name + ", coord.xyz, bias)"; break;
|
||||||
|
case rsx::texture_target::_3: dst += "textureProj(" + texture.name + ", coord, bias)"; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
dst += ";\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
dst += "\t}\n";
|
||||||
|
dst += "}\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
rsx::complete_shader glsl_complete_shader(const rsx::decompiled_shader &shader, rsx::program_state state)
|
rsx::complete_shader glsl_complete_shader(const rsx::decompiled_shader &shader, rsx::program_state state)
|
||||||
{
|
{
|
||||||
rsx::complete_shader result;
|
rsx::complete_shader result;
|
||||||
@ -75,7 +231,21 @@ rsx::complete_shader glsl_complete_shader(const rsx::decompiled_shader &shader,
|
|||||||
for (const rsx::texture_info& texture : shader.textures)
|
for (const rsx::texture_info& texture : shader.textures)
|
||||||
{
|
{
|
||||||
result.code += "uniform vec4 " + texture.name + "_cm = vec4(1.0);\n";
|
result.code += "uniform vec4 " + texture.name + "_cm = vec4(1.0);\n";
|
||||||
result.code += "uniform sampler2D " + texture.name + ";\n";
|
|
||||||
|
rsx::texture_target target = state.textures[texture.id];
|
||||||
|
|
||||||
|
|
||||||
|
result.code += "uniform sampler";
|
||||||
|
|
||||||
|
switch (target)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case rsx::texture_target::_1: result.code += "1D"; break;
|
||||||
|
case rsx::texture_target::_2: result.code += "2D"; break;
|
||||||
|
case rsx::texture_target::_3: result.code += "3D"; break;
|
||||||
|
case rsx::texture_target::cube: result.code += "Cube"; break;
|
||||||
|
}
|
||||||
|
result.code += " " + texture.name + ";\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string prepare;
|
std::string prepare;
|
||||||
@ -85,6 +255,13 @@ rsx::complete_shader glsl_complete_shader(const rsx::decompiled_shader &shader,
|
|||||||
switch (shader.raw->type)
|
switch (shader.raw->type)
|
||||||
{
|
{
|
||||||
case rsx::program_type::fragment:
|
case rsx::program_type::fragment:
|
||||||
|
insert_texture_fetch_function(result.code, shader, state);
|
||||||
|
insert_texture_bias_fetch_function(result.code, shader, state);
|
||||||
|
insert_texture_grad_fetch_function(result.code, shader, state);
|
||||||
|
insert_texture_lod_fetch_function(result.code, shader, state);
|
||||||
|
insert_texture_proj_fetch_function(result.code, shader, state);
|
||||||
|
|
||||||
|
result.code += "\n";
|
||||||
result.code += "layout(location = 0) out vec4 ocol;\n";
|
result.code += "layout(location = 0) out vec4 ocol;\n";
|
||||||
|
|
||||||
if (state.ctrl & CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS)
|
if (state.ctrl & CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS)
|
||||||
@ -243,7 +420,6 @@ rsx::complete_shader glsl_complete_shader(const rsx::decompiled_shader &shader,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case rsx::program_type::vertex:
|
case rsx::program_type::vertex:
|
||||||
|
|
||||||
result.code += "out vec4 wpos;\n";
|
result.code += "out vec4 wpos;\n";
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
@ -266,9 +442,6 @@ rsx::complete_shader glsl_complete_shader(const rsx::decompiled_shader &shader,
|
|||||||
{
|
{
|
||||||
if (shader.input_attributes & (1 << index))
|
if (shader.input_attributes & (1 << index))
|
||||||
{
|
{
|
||||||
// result.code += "in vec4 " + rsx::vertex_program::input_attrib_names[index] + ";\n";
|
|
||||||
|
|
||||||
// TODO: use actual information about vertex inputs
|
|
||||||
const std::string &attrib_name = rsx::vertex_program::input_attrib_names[index];
|
const std::string &attrib_name = rsx::vertex_program::input_attrib_names[index];
|
||||||
|
|
||||||
result.code += "uniform ";
|
result.code += "uniform ";
|
||||||
@ -446,7 +619,6 @@ void* glsl_make_program(const void *vertex_shader, const void *fragment_shader)
|
|||||||
result->attach(*(gl::glsl::shader*)fragment_shader);
|
result->attach(*(gl::glsl::shader*)fragment_shader);
|
||||||
|
|
||||||
result->link();
|
result->link();
|
||||||
result->validate();
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -747,7 +747,7 @@ namespace rsx
|
|||||||
|
|
||||||
raw_program thread::get_raw_program() const
|
raw_program thread::get_raw_program() const
|
||||||
{
|
{
|
||||||
raw_program result;
|
raw_program result{};
|
||||||
|
|
||||||
u32 fp_info = rsx::method_registers[NV4097_SET_SHADER_PROGRAM];
|
u32 fp_info = rsx::method_registers[NV4097_SET_SHADER_PROGRAM];
|
||||||
|
|
||||||
@ -785,6 +785,27 @@ namespace rsx
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (u8 index = 0; index < rsx::limits::textures_count; ++index)
|
||||||
|
{
|
||||||
|
if (!textures[index].enabled())
|
||||||
|
{
|
||||||
|
result.state.textures[index] = rsx::texture_target::none;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (textures[index].get_extended_texture_dimension())
|
||||||
|
{
|
||||||
|
case rsx::texture_dimension_extended::texture_dimension_1d: result.state.textures[index] = rsx::texture_target::_1; break;
|
||||||
|
case rsx::texture_dimension_extended::texture_dimension_2d: result.state.textures[index] = rsx::texture_target::_2; break;
|
||||||
|
case rsx::texture_dimension_extended::texture_dimension_3d: result.state.textures[index] = rsx::texture_target::_3; break;
|
||||||
|
case rsx::texture_dimension_extended::texture_dimension_cubemap: result.state.textures[index] = rsx::texture_target::cube; break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
result.state.textures[index] = rsx::texture_target::none;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
result.vertex_shader.ucode_ptr = transform_program;
|
result.vertex_shader.ucode_ptr = transform_program;
|
||||||
result.vertex_shader.offset = rsx::method_registers[NV4097_SET_TRANSFORM_PROGRAM_START];
|
result.vertex_shader.offset = rsx::method_registers[NV4097_SET_TRANSFORM_PROGRAM_START];
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ namespace rsx
|
|||||||
program_info result;
|
program_info result;
|
||||||
|
|
||||||
result.vertex_shader = m_vertex_shaders_cache.get(context, raw_program_.vertex_shader, raw_program_.state);
|
result.vertex_shader = m_vertex_shaders_cache.get(context, raw_program_.vertex_shader, raw_program_.state);
|
||||||
result.fragment_shader = m_vertex_shaders_cache.get(context, raw_program_.fragment_shader, raw_program_.state);
|
result.fragment_shader = m_fragment_shader_cache.get(context, raw_program_.fragment_shader, raw_program_.state);
|
||||||
result.program = context.make_program(result.vertex_shader.complete->user_data, result.fragment_shader.complete->user_data);
|
result.program = context.make_program(result.vertex_shader.complete->user_data, result.fragment_shader.complete->user_data);
|
||||||
m_program_cache.insert({ raw_program_, result });
|
m_program_cache.insert({ raw_program_, result });
|
||||||
|
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 9f8814af57264c82b7e063c1df5d71dc32c7a951
|
Subproject commit 9f2d4c3c61b38d24c166398bd4f9c6d2b2e6fcb9
|
Loading…
Reference in New Issue
Block a user