mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-02-21 18:39:57 +00:00
rsx/common/d3d12/gl: Support for fog mode.
Fix hitman 2
This commit is contained in:
parent
9cdb74efc7
commit
32434dd848
@ -229,6 +229,9 @@ void D3D12GSRender::upload_and_bind_scale_offset_matrix(size_t descriptorIndex)
|
|||||||
float alpha_ref = alpha_ref_raw / 255.f;
|
float alpha_ref = alpha_ref_raw / 255.f;
|
||||||
memcpy((char*)mapped_buffer + 16 * sizeof(float), &is_alpha_tested, sizeof(int));
|
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 + 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));
|
m_buffer_data.unmap(CD3DX12_RANGE(heap_offset, heap_offset + 256));
|
||||||
|
|
||||||
D3D12_CONSTANT_BUFFER_VIEW_DESC constant_buffer_view_desc = {
|
D3D12_CONSTANT_BUFFER_VIEW_DESC constant_buffer_view_desc = {
|
||||||
|
@ -39,6 +39,8 @@ void D3D12FragmentDecompiler::insertHeader(std::stringstream & OS)
|
|||||||
OS << " float4x4 scaleOffsetMat;" << std::endl;
|
OS << " float4x4 scaleOffsetMat;" << std::endl;
|
||||||
OS << " int isAlphaTested;" << std::endl;
|
OS << " int isAlphaTested;" << std::endl;
|
||||||
OS << " float alphaRef;" << std::endl;
|
OS << " float alphaRef;" << std::endl;
|
||||||
|
OS << " float fog_param0;\n";
|
||||||
|
OS << " float fog_param1;\n";
|
||||||
OS << "};" << std::endl;
|
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)
|
void D3D12FragmentDecompiler::insertMainStart(std::stringstream & OS)
|
||||||
{
|
{
|
||||||
insert_d3d12_legacy_function(OS);
|
insert_d3d12_legacy_function(OS);
|
||||||
@ -169,6 +201,11 @@ void D3D12FragmentDecompiler::insertMainStart(std::stringstream & OS)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (PI.name == "fogc")
|
||||||
|
{
|
||||||
|
insert_fog_declaration(OS, m_prog.fog_equation);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (PI.name == "ssa")
|
if (PI.name == "ssa")
|
||||||
continue;
|
continue;
|
||||||
OS << " " << PT.type << " " << PI.name << " = In." << PI.name << ";" << std::endl;
|
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)
|
if (m_prog.origin_mode == rsx::window_origin::bottom)
|
||||||
OS << " gl_FragCoord.y = (" << std::to_string(m_prog.height) << " - gl_FragCoord.y);\n";
|
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";
|
OS << " float4 ssa = is_front_face ? float4(1., 1., 1., 1.) : float4(-1., -1., -1., -1.);\n";
|
||||||
|
|
||||||
// Declare output
|
// Declare output
|
||||||
for (const ParamType &PT : m_parr.params[PF_PARAM_NONE])
|
for (const ParamType &PT : m_parr.params[PF_PARAM_NONE])
|
||||||
{
|
{
|
||||||
|
@ -33,6 +33,8 @@ void D3D12VertexProgramDecompiler::insertHeader(std::stringstream &OS)
|
|||||||
OS << " float4x4 scaleOffsetMat;" << std::endl;
|
OS << " float4x4 scaleOffsetMat;" << std::endl;
|
||||||
OS << " int isAlphaTested;" << std::endl;
|
OS << " int isAlphaTested;" << std::endl;
|
||||||
OS << " float alphaRef;" << std::endl;
|
OS << " float alphaRef;" << std::endl;
|
||||||
|
OS << " float fog_param0;\n";
|
||||||
|
OS << " float fog_param1;\n";
|
||||||
OS << "};" << std::endl;
|
OS << "};" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -806,6 +806,30 @@ rsx::comparaison_function rsx::to_comparaison_function(u16 in)
|
|||||||
throw EXCEPTION("Wrong comparaison function %x", 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
|
enum
|
||||||
{
|
{
|
||||||
|
@ -141,6 +141,18 @@ namespace rsx
|
|||||||
};
|
};
|
||||||
|
|
||||||
comparaison_function to_comparaison_function(u16 in);
|
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
|
enum
|
||||||
@ -497,13 +509,6 @@ enum
|
|||||||
CELL_GCM_ATTRIB_OUTPUT_MASK_TEX6 = 1 << 20,
|
CELL_GCM_ATTRIB_OUTPUT_MASK_TEX6 = 1 << 20,
|
||||||
CELL_GCM_ATTRIB_OUTPUT_MASK_TEX7 = 1 << 21,
|
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_POINT = 0x1B00,
|
||||||
CELL_GCM_POLYGON_MODE_LINE = 0x1B01,
|
CELL_GCM_POLYGON_MODE_LINE = 0x1B01,
|
||||||
CELL_GCM_POLYGON_MODE_FILL = 0x1B02,
|
CELL_GCM_POLYGON_MODE_FILL = 0x1B02,
|
||||||
|
@ -29,6 +29,13 @@ std::string GLFragmentDecompilerThread::compareFunction(COMPARE f, const std::st
|
|||||||
void GLFragmentDecompilerThread::insertHeader(std::stringstream & OS)
|
void GLFragmentDecompilerThread::insertHeader(std::stringstream & OS)
|
||||||
{
|
{
|
||||||
OS << "#version 420" << std::endl;
|
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)
|
void GLFragmentDecompilerThread::insertIntputs(std::stringstream & OS)
|
||||||
@ -99,6 +106,37 @@ void GLFragmentDecompilerThread::insertConstants(std::stringstream & OS)
|
|||||||
OS << "};" << std::endl;
|
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)
|
void GLFragmentDecompilerThread::insertMainStart(std::stringstream & OS)
|
||||||
{
|
{
|
||||||
insert_glsl_legacy_function(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";
|
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)
|
void GLFragmentDecompilerThread::insertMainEnd(std::stringstream & OS)
|
||||||
|
@ -729,7 +729,7 @@ void GLGSRender::on_init_thread()
|
|||||||
m_vao.create();
|
m_vao.create();
|
||||||
m_vbo.create();
|
m_vbo.create();
|
||||||
m_ebo.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_vertex_constants_buffer.create(512 * 4 * sizeof(float));
|
||||||
m_fragment_constants_buffer.create();
|
m_fragment_constants_buffer.create();
|
||||||
|
|
||||||
@ -945,6 +945,8 @@ bool GLGSRender::load_program()
|
|||||||
std::vector<u8> client_side_buf(max_buffer_sz);
|
std::vector<u8> client_side_buf(max_buffer_sz);
|
||||||
|
|
||||||
fill_scale_offset_data(client_side_buf.data(), false);
|
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.data(m_scale_offset_buffer.size(), nullptr);
|
||||||
m_scale_offset_buffer.sub_data(0, m_scale_offset_buffer.size(), client_side_buf.data());
|
m_scale_offset_buffer.sub_data(0, m_scale_offset_buffer.size(), client_side_buf.data());
|
||||||
|
|
||||||
|
@ -31,6 +31,8 @@ void GLVertexDecompilerThread::insertHeader(std::stringstream &OS)
|
|||||||
OS << "layout(std140, binding = 0) uniform ScaleOffsetBuffer" << std::endl;
|
OS << "layout(std140, binding = 0) uniform ScaleOffsetBuffer" << std::endl;
|
||||||
OS << "{" << std::endl;
|
OS << "{" << std::endl;
|
||||||
OS << " mat4 scaleOffsetMat;" << std::endl;
|
OS << " mat4 scaleOffsetMat;" << std::endl;
|
||||||
|
OS << " float fog_param0;\n";
|
||||||
|
OS << " float fog_param1;\n";
|
||||||
OS << "};" << std::endl;
|
OS << "};" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,6 +227,7 @@ struct RSXFragmentProgram
|
|||||||
u32 texture_dimensions;
|
u32 texture_dimensions;
|
||||||
rsx::window_origin origin_mode;
|
rsx::window_origin origin_mode;
|
||||||
rsx::window_pixel_center pixel_center_mode;
|
rsx::window_pixel_center pixel_center_mode;
|
||||||
|
rsx::fog_mode fog_equation;
|
||||||
u16 height;
|
u16 height;
|
||||||
|
|
||||||
texture_dimension get_texture_dimension(u8 id) const
|
texture_dimension get_texture_dimension(u8 id) const
|
||||||
|
@ -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_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.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.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];
|
u32 shader_window = rsx::method_registers[NV4097_SET_SHADER_WINDOW];
|
||||||
result.origin_mode = rsx::to_window_origin((shader_window >> 12) & 0xF);
|
result.origin_mode = rsx::to_window_origin((shader_window >> 12) & 0xF);
|
||||||
result.pixel_center_mode = rsx::to_window_pixel_center((shader_window >> 16) & 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_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_FUNC] = CELL_GCM_LESS;
|
||||||
method_registers[NV4097_SET_DEPTH_MASK] = CELL_GCM_TRUE;
|
method_registers[NV4097_SET_DEPTH_MASK] = CELL_GCM_TRUE;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user