Merge pull request #1816 from RPCS3/WIP

OpenGL renderer: improved vertex attributes setup
This commit is contained in:
DHrpcs3 2016-06-23 02:55:40 +03:00 committed by GitHub
commit d0442e140b
7 changed files with 139 additions and 53 deletions

View File

@ -307,27 +307,38 @@ void GLGSRender::end()
//setup textures //setup textures
{ {
int texture_index = 0; //int texture_index = 0;
for (int i = 0; i < rsx::limits::textures_count; ++i) for (int i = 0; i < rsx::limits::textures_count; ++i)
{ {
if (!textures[i].enabled())
{
continue;
}
int location; int location;
if (m_program->uniforms.has_location("texture" + std::to_string(i), &location)) if (m_program->uniforms.has_location("texture" + std::to_string(i), &location))
{ {
__glcheck glProgramUniform1i(m_program->id(), location, texture_index); if (!textures[i].enabled())
__glcheck m_gl_textures[i].init(texture_index, textures[i]); {
glActiveTexture(GL_TEXTURE0 + i);
glBindTexture(GL_TEXTURE_2D, 0);
glProgramUniform1i(m_program->id(), location, i);
texture_index++; continue;
}
m_gl_textures[i].set_target(get_gl_target_for_texture(textures[i]));
__glcheck m_gl_texture_cache.upload_texture(i, textures[i], m_gl_textures[i], m_rtts);
__glcheck glProgramUniform1i(m_program->id(), location, i);
//__glcheck m_gl_textures[i].init(i, textures[i]);
//texture_index++;
if (m_program->uniforms.has_location("texture" + std::to_string(i) + "_cm", &location)) if (m_program->uniforms.has_location("texture" + std::to_string(i) + "_cm", &location))
{ {
if (textures[i].format() & CELL_GCM_TEXTURE_UN) if (textures[i].format() & CELL_GCM_TEXTURE_UN)
{ {
//glProgramUniform4f(m_program->id(), location, textures[i].width(), textures[i].height(), textures[i].depth(), 1.0f); u32 width = std::max<u32>(textures[i].width(), 1);
u32 height = std::max<u32>(textures[i].height(), 1);
u32 depth = std::max<u32>(textures[i].depth(), 1);
glProgramUniform4f(m_program->id(), location, 1.f / width, 1.f / height, 1.f / depth, 1.0f);
} }
} }
} }
@ -349,8 +360,6 @@ void GLGSRender::end()
*/ */
} }
__glcheck 0;
u32 offset_in_index_buffer = set_vertex_buffer(); u32 offset_in_index_buffer = set_vertex_buffer();
m_vao.bind(); m_vao.bind();
@ -430,8 +439,6 @@ void GLGSRender::set_viewport()
} }
glEnable(GL_SCISSOR_TEST); glEnable(GL_SCISSOR_TEST);
__glcheck 0;
} }
void GLGSRender::on_init_thread() void GLGSRender::on_init_thread()
@ -685,8 +692,6 @@ bool GLGSRender::load_program()
auto mapping = m_uniform_ring_buffer.alloc_from_reserve(fragment_constants_size, m_uniform_buffer_offset_align); auto mapping = m_uniform_ring_buffer.alloc_from_reserve(fragment_constants_size, m_uniform_buffer_offset_align);
fragment_constants_offset = mapping.second; fragment_constants_offset = mapping.second;
u32 buffer_offset = 0;
static const __m128i mask = _mm_set_epi8( static const __m128i mask = _mm_set_epi8(
0xE, 0xF, 0xC, 0xD, 0xE, 0xF, 0xC, 0xD,
0xA, 0xB, 0x8, 0x9, 0xA, 0xB, 0x8, 0x9,
@ -695,20 +700,23 @@ bool GLGSRender::load_program()
auto ucode = (const rsx::fragment_program::ucode_instr *)info.fragment_shader.decompiled->raw->ucode_ptr; auto ucode = (const rsx::fragment_program::ucode_instr *)info.fragment_shader.decompiled->raw->ucode_ptr;
auto dst = (const rsx::fragment_program::ucode_instr *)mapping.first;
for (const auto& constant : info.fragment_shader.decompiled->constants) for (const auto& constant : info.fragment_shader.decompiled->constants)
{ {
const void *data = ucode + u32(constant.id / sizeof(rsx::fragment_program::ucode_instr)); const void *src = ucode + u32(constant.id / sizeof(*ucode));
const __m128i &vector = _mm_loadu_si128((const __m128i*)data);
const __m128i &shuffled_vector = _mm_shuffle_epi8(vector, mask);
_mm_stream_si128((__m128i*)((char*)mapping.first + buffer_offset), shuffled_vector);
//float x = ((float*)((char*)mapping.first + buffer_offset))[0]; const __m128i &vector = _mm_loadu_si128((const __m128i*)src);
//float y = ((float*)((char*)mapping.first + buffer_offset))[1]; const __m128i &shuffled_vector = _mm_shuffle_epi8(vector, mask);
//float z = ((float*)((char*)mapping.first + buffer_offset))[2]; _mm_stream_si128((__m128i*)dst, shuffled_vector);
//float w = ((float*)((char*)mapping.first + buffer_offset))[3];
float x = ((float*)dst)[0];
float y = ((float*)dst)[1];
float z = ((float*)dst)[2];
float w = ((float*)dst)[3];
//LOG_WARNING(RSX, "fc%u = {%g, %g, %g, %g}", constant.id, x, y, z, w); //LOG_WARNING(RSX, "fc%u = {%g, %g, %g, %g}", constant.id, x, y, z, w);
buffer_offset += 4 * sizeof(f32); ++dst;
} }
} }

View File

@ -259,6 +259,9 @@ rsx::complete_shader glsl_complete_shader(const rsx::decompiled_shader &shader,
" gl_Position.w = o0.w;\n"; " gl_Position.w = o0.w;\n";
} }
{
std::string code_end;
for (std::size_t index = 0; index < 16; ++index) for (std::size_t index = 0; index < 16; ++index)
{ {
if (shader.input_attributes & (1 << index)) if (shader.input_attributes & (1 << index))
@ -266,10 +269,55 @@ rsx::complete_shader glsl_complete_shader(const rsx::decompiled_shader &shader,
// result.code += "in vec4 " + rsx::vertex_program::input_attrib_names[index] + ";\n"; // result.code += "in vec4 " + rsx::vertex_program::input_attrib_names[index] + ";\n";
// TODO: use actual information about vertex inputs // TODO: use actual information about vertex inputs
result.code += "layout(location=" + std::to_string(location++) + ") uniform samplerBuffer " + rsx::vertex_program::input_attrib_names[index] + "_buffer" + ";\n"; const std::string &attrib_name = rsx::vertex_program::input_attrib_names[index];
result.code += "vec4 " + rsx::vertex_program::input_attrib_names[index]
+ " = texelFetch(" + rsx::vertex_program::input_attrib_names[index] + "_buffer, gl_VertexID).rgba;\n"; result.code += "uniform ";
if (state.is_int & (1 << index))
{
result.code += "isamplerBuffer ";
code_end += "ivec4 ";
} }
else
{
result.code += "samplerBuffer ";
code_end += "vec4 ";
}
result.code += attrib_name + "_buffer" + ";\n";
code_end += attrib_name + ";\n";
std::string vertex_id;
if (state.is_array & (1 << index))
{
vertex_id = "gl_VertexID";
if (state.frequency[index] > 1)
{
if (state.divider_op & (1 << index))
{
vertex_id += " % ";
}
else
{
vertex_id += " / ";
}
vertex_id += std::to_string(state.frequency[index]);
}
}
else
{
vertex_id = "0";
}
prepare += '\t' + attrib_name + " = texelFetch(" + attrib_name + "_buffer, " + vertex_id + ");\n";
}
}
result.code += code_end;
} }
{ {

View File

@ -160,17 +160,9 @@ u32 GLGSRender::set_vertex_buffer()
//initialize vertex attributes //initialize vertex attributes
//merge all vertex arrays //merge all vertex arrays
std::chrono::time_point<std::chrono::system_clock> then = std::chrono::system_clock::now(); static const u32 texture_index_offset = rsx::limits::textures_count + rsx::limits::vertex_textures_count;
const std::string reg_table[] = std::chrono::time_point<std::chrono::system_clock> then = std::chrono::system_clock::now();
{
"in_pos", "in_weight", "in_normal",
"in_diff_color", "in_spec_color",
"in_fog",
"in_point_size", "in_7",
"in_tc0", "in_tc1", "in_tc2", "in_tc3",
"in_tc4", "in_tc5", "in_tc6", "in_tc7"
};
u32 input_mask = rsx::method_registers[NV4097_SET_VERTEX_ATTRIB_INPUT_MASK]; u32 input_mask = rsx::method_registers[NV4097_SET_VERTEX_ATTRIB_INPUT_MASK];
u32 min_index = 0, max_index = 0; u32 min_index = 0, max_index = 0;
@ -185,7 +177,9 @@ u32 GLGSRender::set_vertex_buffer()
for (u8 index = 0; index < rsx::limits::vertex_count; ++index) for (u8 index = 0; index < rsx::limits::vertex_count; ++index)
{ {
if (vertex_arrays_info[index].size == 0) if (vertex_arrays_info[index].size == 0)
{
continue; continue;
}
max_vertex_attrib_size += 16; max_vertex_attrib_size += 16;
} }
@ -240,9 +234,9 @@ u32 GLGSRender::set_vertex_buffer()
if (!vertex_info.size) // disabled, bind a null sampler if (!vertex_info.size) // disabled, bind a null sampler
{ {
glActiveTexture(GL_TEXTURE0 + index + rsx::limits::textures_count); glActiveTexture(GL_TEXTURE0 + index + texture_index_offset);
glBindTexture(GL_TEXTURE_BUFFER, 0); glBindTexture(GL_TEXTURE_BUFFER, 0);
glProgramUniform1i(m_program->id(), location, index + rsx::limits::textures_count); glProgramUniform1i(m_program->id(), location, index + texture_index_offset);
continue; continue;
} }
@ -279,7 +273,7 @@ u32 GLGSRender::set_vertex_buffer()
texture.copy_from(m_attrib_ring_buffer, gl_type, mapping.second, data_size); texture.copy_from(m_attrib_ring_buffer, gl_type, mapping.second, data_size);
//Link texture to uniform //Link texture to uniform
m_program->uniforms.texture(location, index + rsx::limits::textures_count, texture); m_program->uniforms.texture(location, index + texture_index_offset, texture);
if (!is_primitive_native(draw_mode)) if (!is_primitive_native(draw_mode))
{ {
std::tie(vertex_draw_count, offset_in_index_buffer) = get_index_array_for_emulated_non_indexed_draw({ { 0, vertex_draw_count } }, draw_mode, m_index_ring_buffer); std::tie(vertex_draw_count, offset_in_index_buffer) = get_index_array_for_emulated_non_indexed_draw({ { 0, vertex_draw_count } }, draw_mode, m_index_ring_buffer);
@ -309,9 +303,9 @@ u32 GLGSRender::set_vertex_buffer()
bool enabled = !!(input_mask & (1 << index)); bool enabled = !!(input_mask & (1 << index));
if (!enabled) if (!enabled)
{ {
glActiveTexture(GL_TEXTURE0 + index + rsx::limits::textures_count); glActiveTexture(GL_TEXTURE0 + index + texture_index_offset);
glBindTexture(GL_TEXTURE_BUFFER, 0); glBindTexture(GL_TEXTURE_BUFFER, 0);
glProgramUniform1i(m_program->id(), location, index + rsx::limits::textures_count); glProgramUniform1i(m_program->id(), location, index + texture_index_offset);
continue; continue;
} }
@ -367,7 +361,7 @@ u32 GLGSRender::set_vertex_buffer()
texture.copy_from(m_attrib_ring_buffer, gl_type, buffer_offset, data_size); texture.copy_from(m_attrib_ring_buffer, gl_type, buffer_offset, data_size);
//Link texture to uniform //Link texture to uniform
m_program->uniforms.texture(location, index + rsx::limits::textures_count, texture); m_program->uniforms.texture(location, index + texture_index_offset, texture);
} }
else if (register_vertex_info[index].size > 0) else if (register_vertex_info[index].size > 0)
{ {
@ -392,7 +386,7 @@ u32 GLGSRender::set_vertex_buffer()
texture.copy_from(m_attrib_ring_buffer, gl_type, mapping.second, data_size); texture.copy_from(m_attrib_ring_buffer, gl_type, mapping.second, data_size);
//Link texture to uniform //Link texture to uniform
m_program->uniforms.texture(location, index + rsx::limits::textures_count, texture); m_program->uniforms.texture(location, index + texture_index_offset, texture);
break; break;
} }
default: default:
@ -402,9 +396,9 @@ u32 GLGSRender::set_vertex_buffer()
} }
else else
{ {
glActiveTexture(GL_TEXTURE0 + index + rsx::limits::textures_count); glActiveTexture(GL_TEXTURE0 + index + texture_index_offset);
glBindTexture(GL_TEXTURE_BUFFER, 0); glBindTexture(GL_TEXTURE_BUFFER, 0);
glProgramUniform1i(m_program->id(), location, index + rsx::limits::textures_count); glProgramUniform1i(m_program->id(), location, index + texture_index_offset);
continue; continue;
} }
} }

View File

@ -72,6 +72,8 @@ namespace rsx
case rsx::texture_dimension::dimension1d: return rsx::texture_dimension_extended::texture_dimension_1d; case rsx::texture_dimension::dimension1d: return rsx::texture_dimension_extended::texture_dimension_1d;
case rsx::texture_dimension::dimension3d: return rsx::texture_dimension_extended::texture_dimension_2d; case rsx::texture_dimension::dimension3d: return rsx::texture_dimension_extended::texture_dimension_2d;
case rsx::texture_dimension::dimension2d: return cubemap() ? rsx::texture_dimension_extended::texture_dimension_cubemap : rsx::texture_dimension_extended::texture_dimension_2d; case rsx::texture_dimension::dimension2d: return cubemap() ? rsx::texture_dimension_extended::texture_dimension_cubemap : rsx::texture_dimension_extended::texture_dimension_2d;
default: ASSUME(0);
} }
} }

View File

@ -751,8 +751,39 @@ namespace rsx
u32 fp_info = rsx::method_registers[NV4097_SET_SHADER_PROGRAM]; u32 fp_info = rsx::method_registers[NV4097_SET_SHADER_PROGRAM];
result.state.input_attributes = rsx::method_registers[NV4097_SET_VERTEX_ATTRIB_INPUT_MASK];
result.state.output_attributes = rsx::method_registers[NV4097_SET_VERTEX_ATTRIB_OUTPUT_MASK]; result.state.output_attributes = rsx::method_registers[NV4097_SET_VERTEX_ATTRIB_OUTPUT_MASK];
result.state.ctrl = rsx::method_registers[NV4097_SET_SHADER_CONTROL]; result.state.ctrl = rsx::method_registers[NV4097_SET_SHADER_CONTROL];
result.state.divider_op = rsx::method_registers[NV4097_SET_FREQUENCY_DIVIDER_OPERATION];
result.state.is_array = 0;
result.state.is_int = 0;
for (u8 index = 0; index < rsx::limits::vertex_count; ++index)
{
bool is_int = false;
if (vertex_arrays_info[index].size > 0)
{
result.state.is_array |= 1 << index;
is_int = is_int_type(vertex_arrays_info[index].type);
result.state.frequency[index] = vertex_arrays_info[index].frequency;
}
else if (register_vertex_info[index].size > 0)
{
is_int = is_int_type(register_vertex_info[index].type);
result.state.frequency[index] = register_vertex_info[index].frequency;
}
else
{
result.state.frequency[index] = 0;
}
if (is_int)
{
result.state.is_int |= 1 << index;
}
}
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];

View File

@ -67,10 +67,12 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">
<OutDir>$(SolutionDir)bin\</OutDir> <OutDir>$(SolutionDir)bin\</OutDir>
<TargetName>$(ProjectName)-dbg</TargetName> <TargetName>$(ProjectName)-dbg</TargetName>
<LibraryPath>$(SolutionDir)lib\Debug-$(Platform)\;$(LibraryPath)</LibraryPath>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug - MemLeak|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug - MemLeak|x64'">
<OutDir>$(SolutionDir)bin\</OutDir> <OutDir>$(SolutionDir)bin\</OutDir>
<TargetName>$(ProjectName)-dbg</TargetName> <TargetName>$(ProjectName)-dbg</TargetName>
<LibraryPath>$(SolutionDir)lib\Debug-$(Platform)\;$(LibraryPath)</LibraryPath>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>$(SolutionDir)bin\</OutDir> <OutDir>$(SolutionDir)bin\</OutDir>
@ -81,6 +83,7 @@
<OutDir>$(SolutionDir)bin\</OutDir> <OutDir>$(SolutionDir)bin\</OutDir>
<LinkIncremental>false</LinkIncremental> <LinkIncremental>false</LinkIncremental>
<RunCodeAnalysis>false</RunCodeAnalysis> <RunCodeAnalysis>false</RunCodeAnalysis>
<LibraryPath>$(SolutionDir)lib\Release-$(Platform)\;$(LibraryPath)</LibraryPath>
</PropertyGroup> </PropertyGroup>
<ItemDefinitionGroup> <ItemDefinitionGroup>
<PreBuildEvent> <PreBuildEvent>

@ -1 +1 @@
Subproject commit e4d938c76850549acd837326e2fe0890d5b4be03 Subproject commit 9f8814af57264c82b7e063c1df5d71dc32c7a951