Merge pull request #1522 from vlj/rsx

Rsx: Fix for hitman 2
This commit is contained in:
vlj 2016-02-29 18:24:00 +01:00
commit 19257b3121
11 changed files with 155 additions and 12 deletions

View File

@ -252,11 +252,11 @@ bool is_primitive_native(rsx::primitive_type draw_mode)
case rsx::primitive_type::line_strip:
case rsx::primitive_type::triangles:
case rsx::primitive_type::triangle_strip:
case rsx::primitive_type::quad_strip:
return true;
case rsx::primitive_type::polygon:
case rsx::primitive_type::triangle_fan:
case rsx::primitive_type::quads:
case rsx::primitive_type::quad_strip:
return false;
}
throw new EXCEPTION("Wrong primitive type");
@ -280,6 +280,8 @@ size_t get_index_count(rsx::primitive_type draw_mode, unsigned initial_index_cou
return (initial_index_count - 2) * 3;
case rsx::primitive_type::quads:
return (6 * initial_index_count) / 4;
case rsx::primitive_type::quad_strip:
return (6 * (initial_index_count - 2)) / 2;
default:
return 0;
}
@ -322,14 +324,26 @@ void write_index_array_for_non_indexed_non_native_primitive_to_buffer(char* dst,
typedDst[6 * i + 5] = 4 * i + first;
}
return;
case rsx::primitive_type::quad_strip:
for (unsigned i = 0; i < (count - 2) / 2; i++)
{
// First triangle
typedDst[6 * i] = 2 * i + first;
typedDst[6 * i + 1] = 2 * i + 1 + first;
typedDst[6 * i + 2] = 2 * i + 2 + first;
// Second triangle
typedDst[6 * i + 3] = 2 * i + 2 + first;
typedDst[6 * i + 4] = 2 * i + 3 + first;
typedDst[6 * i + 5] = 2 * i + 1 + first;
}
return;
case rsx::primitive_type::points:
case rsx::primitive_type::lines:
case rsx::primitive_type::line_loop:
case rsx::primitive_type::line_strip:
case rsx::primitive_type::triangles:
case rsx::primitive_type::triangle_strip:
case rsx::primitive_type::quad_strip:
throw new EXCEPTION("Native primitive type doesn't require expansion");
throw EXCEPTION("Native primitive type doesn't require expansion");
}
}

View File

@ -229,6 +229,9 @@ void D3D12GSRender::upload_and_bind_scale_offset_matrix(size_t descriptorIndex)
float alpha_ref = alpha_ref_raw / 255.f;
memcpy((char*)mapped_buffer + 16 * sizeof(float), &is_alpha_tested, sizeof(int));
memcpy((char*)mapped_buffer + 17 * sizeof(float), &alpha_ref, sizeof(float));
memcpy((char*)mapped_buffer + 18 * sizeof(float), &rsx::method_registers[NV4097_SET_FOG_PARAMS], sizeof(float));
memcpy((char*)mapped_buffer + 19 * sizeof(float), &rsx::method_registers[NV4097_SET_FOG_PARAMS + 1], sizeof(float));
m_buffer_data.unmap(CD3DX12_RANGE(heap_offset, heap_offset + 256));
D3D12_CONSTANT_BUFFER_VIEW_DESC constant_buffer_view_desc = {

View File

@ -39,6 +39,8 @@ void D3D12FragmentDecompiler::insertHeader(std::stringstream & OS)
OS << " float4x4 scaleOffsetMat;" << std::endl;
OS << " int isAlphaTested;" << std::endl;
OS << " float alphaRef;" << std::endl;
OS << " float fog_param0;\n";
OS << " float fog_param1;\n";
OS << "};" << std::endl;
}
@ -141,6 +143,36 @@ void D3D12FragmentDecompiler::insertConstants(std::stringstream & OS)
}
}
namespace
{
// Note: It's not clear whether fog is computed per pixel or per vertex.
// But it makes more sense to compute exp of interpoled value than to interpolate exp values.
void insert_fog_declaration(std::stringstream & OS, rsx::fog_mode mode)
{
switch (mode)
{
case rsx::fog_mode::linear:
OS << " float4 fogc = fog_param1 * In.fogc + (fog_param0 - 1.);\n";
return;
case rsx::fog_mode::exponential:
OS << " float4 fogc = exp(11.084 * (fog_param1 * In.fogc + fog_param0 - 1.5));\n";
return;
case rsx::fog_mode::exponential2:
OS << " float4 fogc = exp(-pow(4.709 * (fog_param1 * In.fogc + fog_param0 - 1.5)), 2.);\n";
return;
case rsx::fog_mode::linear_abs:
OS << " float4 fogc = fog_param1 * abs(In.fogc) + (fog_param0 - 1.);\n";
return;
case rsx::fog_mode::exponential_abs:
OS << " float4 fogc = exp(11.084 * (fog_param1 * abs(In.fogc) + fog_param0 - 1.5));\n";
return;
case rsx::fog_mode::exponential2_abs:
OS << " float4 fogc = exp(-pow(4.709 * (fog_param1 * abs(In.fogc) + fog_param0 - 1.5)), 2.);\n";
return;
}
}
}
void D3D12FragmentDecompiler::insertMainStart(std::stringstream & OS)
{
insert_d3d12_legacy_function(OS);
@ -169,6 +201,11 @@ void D3D12FragmentDecompiler::insertMainStart(std::stringstream & OS)
continue;
}
}
if (PI.name == "fogc")
{
insert_fog_declaration(OS, m_prog.fog_equation);
continue;
}
if (PI.name == "ssa")
continue;
OS << " " << PT.type << " " << PI.name << " = In." << PI.name << ";" << std::endl;
@ -179,6 +216,7 @@ void D3D12FragmentDecompiler::insertMainStart(std::stringstream & OS)
if (m_prog.origin_mode == rsx::window_origin::bottom)
OS << " gl_FragCoord.y = (" << std::to_string(m_prog.height) << " - gl_FragCoord.y);\n";
OS << " float4 ssa = is_front_face ? float4(1., 1., 1., 1.) : float4(-1., -1., -1., -1.);\n";
// Declare output
for (const ParamType &PT : m_parr.params[PF_PARAM_NONE])
{

View File

@ -33,6 +33,8 @@ void D3D12VertexProgramDecompiler::insertHeader(std::stringstream &OS)
OS << " float4x4 scaleOffsetMat;" << std::endl;
OS << " int isAlphaTested;" << std::endl;
OS << " float alphaRef;" << std::endl;
OS << " float fog_param0;\n";
OS << " float fog_param1;\n";
OS << "};" << std::endl;
}

View File

@ -806,6 +806,30 @@ rsx::comparaison_function rsx::to_comparaison_function(u16 in)
throw EXCEPTION("Wrong comparaison function %x", in);
}
enum
{
CELL_GCM_FOG_MODE_LINEAR = 0x2601,
CELL_GCM_FOG_MODE_EXP = 0x0800,
CELL_GCM_FOG_MODE_EXP2 = 0x0801,
CELL_GCM_FOG_MODE_EXP_ABS = 0x0802,
CELL_GCM_FOG_MODE_EXP2_ABS = 0x0803,
CELL_GCM_FOG_MODE_LINEAR_ABS = 0x0804,
};
rsx::fog_mode rsx::to_fog_mode(u32 in)
{
switch (in)
{
case CELL_GCM_FOG_MODE_LINEAR: return rsx::fog_mode::linear;
case CELL_GCM_FOG_MODE_EXP: return rsx::fog_mode::exponential;
case CELL_GCM_FOG_MODE_EXP2: return rsx::fog_mode::exponential2;
case CELL_GCM_FOG_MODE_EXP_ABS: return rsx::fog_mode::exponential_abs;
case CELL_GCM_FOG_MODE_EXP2_ABS: return rsx::fog_mode::exponential2_abs;
case CELL_GCM_FOG_MODE_LINEAR_ABS: return rsx::fog_mode::linear_abs;
}
throw EXCEPTION("Wrong fog mode %x", in);
}
enum
{

View File

@ -141,6 +141,18 @@ namespace rsx
};
comparaison_function to_comparaison_function(u16 in);
enum class fog_mode : u8
{
linear,
exponential,
exponential2,
exponential_abs,
exponential2_abs,
linear_abs
};
fog_mode to_fog_mode(u32 in);
}
enum
@ -497,13 +509,6 @@ enum
CELL_GCM_ATTRIB_OUTPUT_MASK_TEX6 = 1 << 20,
CELL_GCM_ATTRIB_OUTPUT_MASK_TEX7 = 1 << 21,
CELL_GCM_FOG_MODE_LINEAR = 0x2601,
CELL_GCM_FOG_MODE_EXP = 0x0800,
CELL_GCM_FOG_MODE_EXP2 = 0x0801,
CELL_GCM_FOG_MODE_EXP_ABS = 0x0802,
CELL_GCM_FOG_MODE_EXP2_ABS = 0x0803,
CELL_GCM_FOG_MODE_LINEAR_ABS = 0x0804,
CELL_GCM_POLYGON_MODE_POINT = 0x1B00,
CELL_GCM_POLYGON_MODE_LINE = 0x1B01,
CELL_GCM_POLYGON_MODE_FILL = 0x1B02,

View File

@ -29,6 +29,13 @@ std::string GLFragmentDecompilerThread::compareFunction(COMPARE f, const std::st
void GLFragmentDecompilerThread::insertHeader(std::stringstream & OS)
{
OS << "#version 420" << std::endl;
OS << "layout(std140, binding = 0) uniform ScaleOffsetBuffer\n";
OS << "{\n";
OS << " mat4 scaleOffsetMat;\n";
OS << " float fog_param0;\n";
OS << " float fog_param1;\n";
OS << "};\n";
}
void GLFragmentDecompilerThread::insertIntputs(std::stringstream & OS)
@ -99,6 +106,37 @@ void GLFragmentDecompilerThread::insertConstants(std::stringstream & OS)
OS << "};" << std::endl;
}
namespace
{
// Note: It's not clear whether fog is computed per pixel or per vertex.
// But it makes more sense to compute exp of interpoled value than to interpolate exp values.
void insert_fog_declaration(std::stringstream & OS, rsx::fog_mode mode)
{
switch (mode)
{
case rsx::fog_mode::linear:
OS << " vec4 fogc = fog_param1 * fogc + (fog_param0 - 1.);\n";
return;
case rsx::fog_mode::exponential:
OS << " vec4 fogc = exp(11.084 * (fog_param1 * fogc + fog_param0 - 1.5));\n";
return;
case rsx::fog_mode::exponential2:
OS << " vec4 fogc = exp(-pow(4.709 * (fog_param1 * fogc + fog_param0 - 1.5)), 2.);\n";
return;
case rsx::fog_mode::linear_abs:
OS << " vec4 fogc = fog_param1 * abs(fogc) + (fog_param0 - 1.);\n";
return;
case rsx::fog_mode::exponential_abs:
OS << " vec4 fogc = exp(11.084 * (fog_param1 * abs(fogc) + fog_param0 - 1.5));\n";
return;
case rsx::fog_mode::exponential2_abs:
OS << " vec4 fogc = exp(-pow(4.709 * (fog_param1 * abs(fogc) + fog_param0 - 1.5)), 2.);\n";
return;
}
}
}
void GLFragmentDecompilerThread::insertMainStart(std::stringstream & OS)
{
insert_glsl_legacy_function(OS);
@ -118,6 +156,19 @@ void GLFragmentDecompilerThread::insertMainStart(std::stringstream & OS)
}
OS << " vec4 ssa = gl_FrontFacing ? vec4(1.) : vec4(-1.);\n";
// search if there is fogc in inputs
for (const ParamType& PT : m_parr.params[PF_PARAM_IN])
{
for (const ParamItem& PI : PT.items)
{
if (PI.name == "fogc")
{
insert_fog_declaration(OS, m_prog.fog_equation);
return;
}
}
}
}
void GLFragmentDecompilerThread::insertMainEnd(std::stringstream & OS)

View File

@ -729,7 +729,7 @@ void GLGSRender::on_init_thread()
m_vao.create();
m_vbo.create();
m_ebo.create();
m_scale_offset_buffer.create(16 * sizeof(float));
m_scale_offset_buffer.create(18 * sizeof(float));
m_vertex_constants_buffer.create(512 * 4 * sizeof(float));
m_fragment_constants_buffer.create();
@ -945,6 +945,8 @@ bool GLGSRender::load_program()
std::vector<u8> client_side_buf(max_buffer_sz);
fill_scale_offset_data(client_side_buf.data(), false);
memcpy(client_side_buf.data() + 16 * sizeof(float), &rsx::method_registers[NV4097_SET_FOG_PARAMS], sizeof(float));
memcpy(client_side_buf.data() + 17 * sizeof(float), &rsx::method_registers[NV4097_SET_FOG_PARAMS + 1], sizeof(float));
m_scale_offset_buffer.data(m_scale_offset_buffer.size(), nullptr);
m_scale_offset_buffer.sub_data(0, m_scale_offset_buffer.size(), client_side_buf.data());

View File

@ -31,6 +31,8 @@ void GLVertexDecompilerThread::insertHeader(std::stringstream &OS)
OS << "layout(std140, binding = 0) uniform ScaleOffsetBuffer" << std::endl;
OS << "{" << std::endl;
OS << " mat4 scaleOffsetMat;" << std::endl;
OS << " float fog_param0;\n";
OS << " float fog_param1;\n";
OS << "};" << std::endl;
}

View File

@ -227,6 +227,7 @@ struct RSXFragmentProgram
u32 texture_dimensions;
rsx::window_origin origin_mode;
rsx::window_pixel_center pixel_center_mode;
rsx::fog_mode fog_equation;
u16 height;
texture_dimension get_texture_dimension(u8 id) const

View File

@ -690,6 +690,7 @@ namespace rsx
result.back_color_diffuse_output = !!(rsx::method_registers[NV4097_SET_VERTEX_ATTRIB_OUTPUT_MASK] & CELL_GCM_ATTRIB_OUTPUT_MASK_BACKDIFFUSE);
result.back_color_specular_output = !!(rsx::method_registers[NV4097_SET_VERTEX_ATTRIB_OUTPUT_MASK] & CELL_GCM_ATTRIB_OUTPUT_MASK_BACKSPECULAR);
result.alpha_func = to_comparaison_function(rsx::method_registers[NV4097_SET_ALPHA_FUNC]);
result.fog_equation = rsx::to_fog_mode(rsx::method_registers[NV4097_SET_FOG_MODE]);
u32 shader_window = rsx::method_registers[NV4097_SET_SHADER_WINDOW];
result.origin_mode = rsx::to_window_origin((shader_window >> 12) & 0xF);
result.pixel_center_mode = rsx::to_window_pixel_center((shader_window >> 16) & 0xF);
@ -767,7 +768,7 @@ namespace rsx
method_registers[NV4097_SET_LINE_WIDTH] = 1 << 3;
method_registers[NV4097_SET_FOG_MODE] = CELL_GCM_FOG_MODE_EXP;
method_registers[NV4097_SET_FOG_MODE] = 0x0800; // rsx::fog_mode::exponential;
method_registers[NV4097_SET_DEPTH_FUNC] = CELL_GCM_LESS;
method_registers[NV4097_SET_DEPTH_MASK] = CELL_GCM_TRUE;