mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-28 21:38:01 +03:00
RSX: Added legacy non-array vertex attributes support (if count of elements > 1)
Fixed ps1ght games
This commit is contained in:
parent
bf8a20c4b9
commit
6ae54ae27b
7 changed files with 112 additions and 74 deletions
|
@ -64,12 +64,6 @@ void GLGSRender::begin()
|
||||||
{
|
{
|
||||||
rsx::thread::begin();
|
rsx::thread::begin();
|
||||||
|
|
||||||
if (!load_program())
|
|
||||||
{
|
|
||||||
//no program - no drawing
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
init_buffers();
|
init_buffers();
|
||||||
|
|
||||||
std::chrono::time_point<std::chrono::system_clock> then = std::chrono::system_clock::now();
|
std::chrono::time_point<std::chrono::system_clock> then = std::chrono::system_clock::now();
|
||||||
|
@ -207,51 +201,6 @@ void GLGSRender::begin()
|
||||||
//NV4097_SET_FLAT_SHADE_OP
|
//NV4097_SET_FLAT_SHADE_OP
|
||||||
//NV4097_SET_EDGE_FLAG
|
//NV4097_SET_EDGE_FLAG
|
||||||
|
|
||||||
u32 clip_plane_control = rsx::method_registers[NV4097_SET_USER_CLIP_PLANE_CONTROL];
|
|
||||||
u8 clip_plane_0 = clip_plane_control & 0xf;
|
|
||||||
u8 clip_plane_1 = (clip_plane_control >> 4) & 0xf;
|
|
||||||
u8 clip_plane_2 = (clip_plane_control >> 8) & 0xf;
|
|
||||||
u8 clip_plane_3 = (clip_plane_control >> 12) & 0xf;
|
|
||||||
u8 clip_plane_4 = (clip_plane_control >> 16) & 0xf;
|
|
||||||
u8 clip_plane_5 = (clip_plane_control >> 20) & 0xf;
|
|
||||||
|
|
||||||
auto set_clip_plane_control = [&](int index, u8 control)
|
|
||||||
{
|
|
||||||
int value = 0;
|
|
||||||
int location;
|
|
||||||
if (m_program->uniforms.has_location("uc_m" + std::to_string(index), &location))
|
|
||||||
{
|
|
||||||
switch (control)
|
|
||||||
{
|
|
||||||
default:
|
|
||||||
LOG_ERROR(RSX, "bad clip plane control (0x%x)", control);
|
|
||||||
|
|
||||||
case CELL_GCM_USER_CLIP_PLANE_DISABLE:
|
|
||||||
value = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CELL_GCM_USER_CLIP_PLANE_ENABLE_GE:
|
|
||||||
value = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CELL_GCM_USER_CLIP_PLANE_ENABLE_LT:
|
|
||||||
value = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
__glcheck m_program->uniforms[location] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
__glcheck enable(value, GL_CLIP_DISTANCE0 + index);
|
|
||||||
};
|
|
||||||
|
|
||||||
set_clip_plane_control(0, clip_plane_0);
|
|
||||||
set_clip_plane_control(1, clip_plane_1);
|
|
||||||
set_clip_plane_control(2, clip_plane_2);
|
|
||||||
set_clip_plane_control(3, clip_plane_3);
|
|
||||||
set_clip_plane_control(4, clip_plane_4);
|
|
||||||
set_clip_plane_control(5, clip_plane_5);
|
|
||||||
|
|
||||||
__glcheck enable(rsx::method_registers[NV4097_SET_POLY_OFFSET_FILL_ENABLE], GL_POLYGON_OFFSET_FILL);
|
__glcheck enable(rsx::method_registers[NV4097_SET_POLY_OFFSET_FILL_ENABLE], GL_POLYGON_OFFSET_FILL);
|
||||||
|
|
||||||
if (__glcheck enable(rsx::method_registers[NV4097_SET_CULL_FACE_ENABLE], GL_CULL_FACE))
|
if (__glcheck enable(rsx::method_registers[NV4097_SET_CULL_FACE_ENABLE], GL_CULL_FACE))
|
||||||
|
@ -296,12 +245,57 @@ namespace
|
||||||
|
|
||||||
void GLGSRender::end()
|
void GLGSRender::end()
|
||||||
{
|
{
|
||||||
if (!draw_fbo)
|
if (!draw_fbo || !load_program())
|
||||||
{
|
{
|
||||||
rsx::thread::end();
|
rsx::thread::end();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 clip_plane_control = rsx::method_registers[NV4097_SET_USER_CLIP_PLANE_CONTROL];
|
||||||
|
u8 clip_plane_0 = clip_plane_control & 0xf;
|
||||||
|
u8 clip_plane_1 = (clip_plane_control >> 4) & 0xf;
|
||||||
|
u8 clip_plane_2 = (clip_plane_control >> 8) & 0xf;
|
||||||
|
u8 clip_plane_3 = (clip_plane_control >> 12) & 0xf;
|
||||||
|
u8 clip_plane_4 = (clip_plane_control >> 16) & 0xf;
|
||||||
|
u8 clip_plane_5 = (clip_plane_control >> 20) & 0xf;
|
||||||
|
|
||||||
|
auto set_clip_plane_control = [&](int index, u8 control)
|
||||||
|
{
|
||||||
|
int value = 0;
|
||||||
|
int location;
|
||||||
|
if (m_program->uniforms.has_location("uc_m" + std::to_string(index), &location))
|
||||||
|
{
|
||||||
|
switch (control)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
LOG_ERROR(RSX, "bad clip plane control (0x%x)", control);
|
||||||
|
|
||||||
|
case CELL_GCM_USER_CLIP_PLANE_DISABLE:
|
||||||
|
value = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CELL_GCM_USER_CLIP_PLANE_ENABLE_GE:
|
||||||
|
value = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CELL_GCM_USER_CLIP_PLANE_ENABLE_LT:
|
||||||
|
value = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
__glcheck m_program->uniforms[location] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
__glcheck enable(value, GL_CLIP_DISTANCE0 + index);
|
||||||
|
};
|
||||||
|
|
||||||
|
set_clip_plane_control(0, clip_plane_0);
|
||||||
|
set_clip_plane_control(1, clip_plane_1);
|
||||||
|
set_clip_plane_control(2, clip_plane_2);
|
||||||
|
set_clip_plane_control(3, clip_plane_3);
|
||||||
|
set_clip_plane_control(4, clip_plane_4);
|
||||||
|
set_clip_plane_control(5, clip_plane_5);
|
||||||
|
|
||||||
draw_fbo.bind();
|
draw_fbo.bind();
|
||||||
m_program->use();
|
m_program->use();
|
||||||
|
|
||||||
|
|
|
@ -463,11 +463,22 @@ rsx::complete_shader glsl_complete_shader(const rsx::decompiled_shader &shader,
|
||||||
|
|
||||||
std::string vertex_id;
|
std::string vertex_id;
|
||||||
|
|
||||||
if (state.is_array & (1 << index))
|
if (state.frequency[index] == 1)
|
||||||
|
{
|
||||||
|
if (state.divider_op & (1 << index))
|
||||||
|
{
|
||||||
|
vertex_id += "0";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vertex_id += "gl_VertexID";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
vertex_id = "gl_VertexID";
|
vertex_id = "gl_VertexID";
|
||||||
|
|
||||||
if (state.frequency[index] > 1)
|
if (state.frequency[index])
|
||||||
{
|
{
|
||||||
if (state.divider_op & (1 << index))
|
if (state.divider_op & (1 << index))
|
||||||
{
|
{
|
||||||
|
@ -481,10 +492,6 @@ rsx::complete_shader glsl_complete_shader(const rsx::decompiled_shader &shader,
|
||||||
vertex_id += std::to_string(state.frequency[index]);
|
vertex_id += std::to_string(state.frequency[index]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
vertex_id = "0";
|
|
||||||
}
|
|
||||||
|
|
||||||
prepare += '\t' + attrib_name + " = texelFetch(" + attrib_name + "_buffer, " + vertex_id + ");\n";
|
prepare += '\t' + attrib_name + " = texelFetch(" + attrib_name + "_buffer, " + vertex_id + ");\n";
|
||||||
}
|
}
|
||||||
|
|
|
@ -176,12 +176,10 @@ 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 || register_vertex_info[index].size)
|
||||||
{
|
{
|
||||||
continue;
|
max_vertex_attrib_size += 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
max_vertex_attrib_size += 16;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (draw_command == rsx::draw_command::indexed)
|
if (draw_command == rsx::draw_command::indexed)
|
||||||
|
@ -292,7 +290,7 @@ u32 GLGSRender::set_vertex_buffer()
|
||||||
if (draw_command == rsx::draw_command::array || draw_command == rsx::draw_command::indexed)
|
if (draw_command == rsx::draw_command::array || draw_command == rsx::draw_command::indexed)
|
||||||
{
|
{
|
||||||
u32 verts_allocated = std::max(vertex_draw_count, max_index + 1);
|
u32 verts_allocated = std::max(vertex_draw_count, max_index + 1);
|
||||||
m_attrib_ring_buffer.reserve_and_map(verts_allocated * max_vertex_attrib_size);
|
__glcheck m_attrib_ring_buffer.reserve_and_map(verts_allocated * max_vertex_attrib_size);
|
||||||
|
|
||||||
for (int index = 0; index < rsx::limits::vertex_count; ++index)
|
for (int index = 0; index < rsx::limits::vertex_count; ++index)
|
||||||
{
|
{
|
||||||
|
@ -365,7 +363,6 @@ u32 GLGSRender::set_vertex_buffer()
|
||||||
}
|
}
|
||||||
else if (register_vertex_info[index].size > 0)
|
else if (register_vertex_info[index].size > 0)
|
||||||
{
|
{
|
||||||
//Untested!
|
|
||||||
auto &vertex_data = register_vertex_data[index];
|
auto &vertex_data = register_vertex_data[index];
|
||||||
auto &vertex_info = register_vertex_info[index];
|
auto &vertex_info = register_vertex_info[index];
|
||||||
|
|
||||||
|
|
|
@ -342,18 +342,30 @@ namespace rsx
|
||||||
|
|
||||||
void thread::begin()
|
void thread::begin()
|
||||||
{
|
{
|
||||||
|
draw_inline_vertex_array = false;
|
||||||
|
inline_vertex_array.clear();
|
||||||
first_count_commands.clear();
|
first_count_commands.clear();
|
||||||
|
draw_command = rsx::draw_command::none;
|
||||||
draw_mode = to_primitive_type(method_registers[NV4097_SET_BEGIN_END]);
|
draw_mode = to_primitive_type(method_registers[NV4097_SET_BEGIN_END]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void thread::end()
|
void thread::end()
|
||||||
{
|
{
|
||||||
|
for (u8 index = 0; index < rsx::limits::vertex_count; ++index)
|
||||||
|
{
|
||||||
|
register_vertex_info[index].size = 0;
|
||||||
|
register_vertex_data[index].clear();
|
||||||
|
}
|
||||||
|
|
||||||
transform_constants.clear();
|
transform_constants.clear();
|
||||||
|
|
||||||
if (capture_current_frame)
|
if (capture_current_frame)
|
||||||
{
|
{
|
||||||
for (const auto &first_count : first_count_commands)
|
for (const auto &first_count : first_count_commands)
|
||||||
|
{
|
||||||
vertex_draw_count += first_count.second;
|
vertex_draw_count += first_count.second;
|
||||||
|
}
|
||||||
|
|
||||||
capture_frame("Draw " + std::to_string(vertex_draw_count));
|
capture_frame("Draw " + std::to_string(vertex_draw_count));
|
||||||
vertex_draw_count = 0;
|
vertex_draw_count = 0;
|
||||||
}
|
}
|
||||||
|
@ -755,8 +767,6 @@ namespace rsx
|
||||||
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.divider_op = rsx::method_registers[NV4097_SET_FREQUENCY_DIVIDER_OPERATION];
|
||||||
|
|
||||||
result.state.is_array = 0;
|
|
||||||
result.state.is_int = 0;
|
result.state.is_int = 0;
|
||||||
|
|
||||||
for (u8 index = 0; index < rsx::limits::vertex_count; ++index)
|
for (u8 index = 0; index < rsx::limits::vertex_count; ++index)
|
||||||
|
@ -765,7 +775,6 @@ namespace rsx
|
||||||
|
|
||||||
if (vertex_arrays_info[index].size > 0)
|
if (vertex_arrays_info[index].size > 0)
|
||||||
{
|
{
|
||||||
result.state.is_array |= 1 << index;
|
|
||||||
is_int = is_int_type(vertex_arrays_info[index].type);
|
is_int = is_int_type(vertex_arrays_info[index].type);
|
||||||
result.state.frequency[index] = vertex_arrays_info[index].frequency;
|
result.state.frequency[index] = vertex_arrays_info[index].frequency;
|
||||||
}
|
}
|
||||||
|
|
|
@ -197,6 +197,7 @@ namespace rsx
|
||||||
|
|
||||||
enum class draw_command
|
enum class draw_command
|
||||||
{
|
{
|
||||||
|
none,
|
||||||
array,
|
array,
|
||||||
inlined_array,
|
inlined_array,
|
||||||
indexed,
|
indexed,
|
||||||
|
|
|
@ -90,7 +90,7 @@ namespace rsx
|
||||||
//find begin of data
|
//find begin of data
|
||||||
size_t begin = id + index * element_size_in_words;
|
size_t begin = id + index * element_size_in_words;
|
||||||
|
|
||||||
size_t position = 0;//entry.size();
|
size_t position = entry.size();
|
||||||
entry.resize(position + element_size);
|
entry.resize(position + element_size);
|
||||||
|
|
||||||
memcpy(entry.data() + position, method_registers + begin, element_size);
|
memcpy(entry.data() + position, method_registers + begin, element_size);
|
||||||
|
@ -226,17 +226,47 @@ namespace rsx
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
force_inline void set_begin_end(thread* rsx, u32 arg)
|
force_inline void set_begin_end(thread* rsxthr, u32 arg)
|
||||||
{
|
{
|
||||||
if (arg)
|
if (arg)
|
||||||
{
|
{
|
||||||
rsx->draw_inline_vertex_array = false;
|
rsxthr->begin();
|
||||||
rsx->inline_vertex_array.clear();
|
|
||||||
rsx->begin();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
rsx->end();
|
u32 max_vertex_count = 0;
|
||||||
|
|
||||||
|
for (u8 index = 0; index < rsx::limits::vertex_count; ++index)
|
||||||
|
{
|
||||||
|
auto &vertex_info = rsxthr->register_vertex_info[index];
|
||||||
|
|
||||||
|
if (vertex_info.size > 0)
|
||||||
|
{
|
||||||
|
auto &vertex_data = rsxthr->register_vertex_data[index];
|
||||||
|
|
||||||
|
u32 element_size = rsx::get_vertex_type_size_on_host(vertex_info.type, vertex_info.size);
|
||||||
|
u32 element_count = vertex_data.size() / element_size;
|
||||||
|
|
||||||
|
vertex_info.frequency = element_count;
|
||||||
|
rsx::method_registers[NV4097_SET_FREQUENCY_DIVIDER_OPERATION] |= 1 << index;
|
||||||
|
|
||||||
|
if (rsxthr->draw_command == rsx::draw_command::none)
|
||||||
|
{
|
||||||
|
max_vertex_count = std::max<u32>(max_vertex_count, element_count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rsxthr->draw_command == rsx::draw_command::none && max_vertex_count)
|
||||||
|
{
|
||||||
|
rsxthr->draw_command = rsx::draw_command::array;
|
||||||
|
rsxthr->first_count_commands.push_back(std::make_pair(0, max_vertex_count));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rsxthr->first_count_commands.empty())
|
||||||
|
{
|
||||||
|
rsxthr->end();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
force_inline void get_report(thread* rsx, u32 arg)
|
force_inline void get_report(thread* rsx, u32 arg)
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 9f2d4c3c61b38d24c166398bd4f9c6d2b2e6fcb9
|
Subproject commit a9e8d5ac4b718e247759f97615dde8759b1f0419
|
Loading…
Add table
Add a link
Reference in a new issue