mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-16 23:17:29 +00:00
Merge pull request #1816 from RPCS3/WIP
OpenGL renderer: improved vertex attributes setup
This commit is contained in:
commit
d0442e140b
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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];
|
||||||
|
@ -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
|
Loading…
Reference in New Issue
Block a user