mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-16 23:17:29 +00:00
vk/dx12: Enable/fix separate back and front lighting (#1927)
* vk: separate specular color rsx: separate front color output from back color output re-enable front-back diffuse lighting vk: fix front face selection and actually enable face culling * dx12: Hide constant-key blended visuals (by common use of factor, 1-factor) * dx12: Fix 2 sided lighting when the shader does not compute both outputs * vk/dx12: confirm that src register exists before copying for 2-sided lighting
This commit is contained in:
parent
b2a7dac11b
commit
2337bf204c
@ -41,14 +41,14 @@ D3D12_BLEND get_blend_factor(rsx::blend_factor factor)
|
||||
case rsx::blend_factor::constant_color:
|
||||
case rsx::blend_factor::constant_alpha:
|
||||
{
|
||||
LOG_ERROR(RSX, "Constant blend factor not supported. Using ONE instead");
|
||||
return D3D12_BLEND_ONE;
|
||||
LOG_ERROR(RSX, "Constant blend factor not supported. Using ZERO instead");
|
||||
return D3D12_BLEND_ZERO;
|
||||
}
|
||||
case rsx::blend_factor::one_minus_constant_color:
|
||||
case rsx::blend_factor::one_minus_constant_alpha:
|
||||
{
|
||||
LOG_ERROR(RSX, "Inv Constant blend factor not supported. Using ZERO instead");
|
||||
return D3D12_BLEND_ZERO;
|
||||
LOG_ERROR(RSX, "Inv Constant blend factor not supported. Using ONE instead");
|
||||
return D3D12_BLEND_ONE;
|
||||
}
|
||||
}
|
||||
throw EXCEPTION("Invalid blend factor (0x%x)", factor);
|
||||
|
@ -210,12 +210,37 @@ void D3D12VertexProgramDecompiler::insertMainStart(std::stringstream & OS)
|
||||
void D3D12VertexProgramDecompiler::insertMainEnd(std::stringstream & OS)
|
||||
{
|
||||
OS << " PixelInput Out = (PixelInput)0;" << std::endl;
|
||||
|
||||
bool insert_front_diffuse = (rsx_vertex_program.output_mask & 1);
|
||||
bool insert_front_specular = (rsx_vertex_program.output_mask & 2);
|
||||
|
||||
bool insert_back_diffuse = (rsx_vertex_program.output_mask & 4);
|
||||
bool insert_back_specular = (rsx_vertex_program.output_mask & 8);
|
||||
|
||||
// Declare inside main function
|
||||
for (auto &i : reg_table)
|
||||
{
|
||||
if (m_parr.HasParam(PF_PARAM_NONE, "float4", i.src_reg))
|
||||
{
|
||||
if (i.name == "front_diff_color")
|
||||
insert_front_diffuse = false;
|
||||
|
||||
if (i.name == "front_spec_color")
|
||||
insert_front_specular = false;
|
||||
|
||||
OS << " Out." << i.src_reg << " = " << i.src_reg << ";" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
//If 2 sided lighting is active and only back is written, copy the value to the front side (Outrun online arcade)
|
||||
if (insert_front_diffuse && insert_back_diffuse)
|
||||
if (m_parr.HasParam(PF_PARAM_NONE, "float4", "dst_reg1"))
|
||||
OS << " Out.dst_reg3 = dst_reg1;\n";
|
||||
|
||||
if (insert_front_specular && insert_back_specular)
|
||||
if (m_parr.HasParam(PF_PARAM_NONE, "float4", "dst_reg2"))
|
||||
OS << " Out.dst_reg4 = dst_reg2;\n";
|
||||
|
||||
OS << " Out.dst_reg0 = mul(Out.dst_reg0, scaleOffsetMat);" << std::endl;
|
||||
OS << " return Out;" << std::endl;
|
||||
OS << "}" << std::endl;
|
||||
|
@ -225,6 +225,8 @@ struct RSXFragmentProgram
|
||||
bool front_back_color_enabled : 1;
|
||||
bool back_color_diffuse_output : 1;
|
||||
bool back_color_specular_output : 1;
|
||||
bool front_color_diffuse_output : 1;
|
||||
bool front_color_specular_output : 1;
|
||||
u32 texture_dimensions;
|
||||
rsx::window_origin origin_mode;
|
||||
rsx::window_pixel_center pixel_center_mode;
|
||||
|
@ -738,6 +738,8 @@ namespace rsx
|
||||
result.front_back_color_enabled = !rsx::method_registers.two_side_light_en();
|
||||
result.back_color_diffuse_output = !!(rsx::method_registers.vertex_attrib_output_mask() & CELL_GCM_ATTRIB_OUTPUT_MASK_BACKDIFFUSE);
|
||||
result.back_color_specular_output = !!(rsx::method_registers.vertex_attrib_output_mask() & CELL_GCM_ATTRIB_OUTPUT_MASK_BACKSPECULAR);
|
||||
result.front_color_diffuse_output = !!(rsx::method_registers.vertex_attrib_output_mask() & CELL_GCM_ATTRIB_OUTPUT_MASK_FRONTDIFFUSE);
|
||||
result.front_color_specular_output = !!(rsx::method_registers.vertex_attrib_output_mask() & CELL_GCM_ATTRIB_OUTPUT_MASK_FRONTSPECULAR);
|
||||
result.alpha_func = rsx::method_registers.alpha_func();
|
||||
result.fog_equation = rsx::method_registers.fog_equation();
|
||||
result.origin_mode = rsx::method_registers.shader_window_origin();
|
||||
|
@ -231,20 +231,22 @@ namespace vk
|
||||
|
||||
static const varying_register_t varying_regs[] =
|
||||
{
|
||||
{ "diff_color", 0 },
|
||||
{ "tc0", 1 },
|
||||
{ "tc1", 2 },
|
||||
{ "tc2", 3 },
|
||||
{ "tc3", 4 },
|
||||
{ "tc4", 5 },
|
||||
{ "tc5", 6 },
|
||||
{ "tc6", 7 },
|
||||
{ "tc7", 8 },
|
||||
{ "tc8", 9 },
|
||||
{ "tc9", 10 },
|
||||
{ "tc0", 0 },
|
||||
{ "tc1", 1 },
|
||||
{ "tc2", 2 },
|
||||
{ "tc3", 3 },
|
||||
{ "tc4", 4 },
|
||||
{ "tc5", 5 },
|
||||
{ "tc6", 6 },
|
||||
{ "tc7", 7 },
|
||||
{ "tc8", 8 },
|
||||
{ "tc9", 9 },
|
||||
{ "diff_color", 10 },
|
||||
{ "back_diff_color", 10 },
|
||||
{ "front_diff_color", 11 },
|
||||
{ "front_spec_color", 12 },
|
||||
{ "spec_color", 13 },
|
||||
{ "spec_color", 12 },
|
||||
{ "back_spec_color", 12 },
|
||||
{ "front_spec_color", 13 },
|
||||
{ "fog_c", 14 },
|
||||
{ "fogc", 14 }
|
||||
};
|
||||
|
@ -60,14 +60,38 @@ void VKFragmentDecompilerThread::insertIntputs(std::stringstream & OS)
|
||||
if (PI.name == "ssa") continue;
|
||||
|
||||
const vk::varying_register_t ® = vk::get_varying_register(PI.name);
|
||||
|
||||
std::string var_name = PI.name;
|
||||
|
||||
if (m_prog.front_back_color_enabled)
|
||||
{
|
||||
if (m_prog.back_color_diffuse_output && var_name == "diff_color")
|
||||
var_name = "back_diff_color";
|
||||
|
||||
if (m_prog.back_color_specular_output && var_name == "spec_color")
|
||||
var_name = "back_spec_color";
|
||||
}
|
||||
|
||||
if (var_name == "fogc")
|
||||
var_name = "fog_c";
|
||||
|
||||
OS << "layout(location=" << reg.reg_location << ") in " << PT.type << " " << var_name << ";" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_prog.front_back_color_enabled)
|
||||
{
|
||||
if (m_prog.front_color_diffuse_output)
|
||||
{
|
||||
const vk::varying_register_t ® = vk::get_varying_register("front_diff_color");
|
||||
OS << "layout(location=" << reg.reg_location << ") in vec4 front_diff_color;" << std::endl;
|
||||
}
|
||||
|
||||
if (m_prog.front_color_specular_output)
|
||||
{
|
||||
const vk::varying_register_t ® = vk::get_varying_register("front_spec_color");
|
||||
OS << "layout(location=" << reg.reg_location << ") in vec4 front_spec_color;" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VKFragmentDecompilerThread::insertOutputs(std::stringstream & OS)
|
||||
@ -202,6 +226,47 @@ void VKFragmentDecompilerThread::insertMainStart(std::stringstream & OS)
|
||||
{
|
||||
for (const ParamItem& PI : PT.items)
|
||||
{
|
||||
if (m_prog.front_back_color_enabled)
|
||||
{
|
||||
if (PI.name == "spec_color")
|
||||
{
|
||||
if (m_prog.back_color_specular_output || m_prog.front_color_specular_output)
|
||||
{
|
||||
if (m_prog.back_color_specular_output && m_prog.front_color_specular_output)
|
||||
{
|
||||
OS << " vec4 spec_color = gl_FrontFacing ? front_spec_color : back_spec_color;\n";
|
||||
}
|
||||
else if (m_prog.back_color_specular_output)
|
||||
{
|
||||
OS << " vec4 spec_color = back_spec_color;\n";
|
||||
}
|
||||
else
|
||||
OS << " vec4 spec_color = front_spec_color;\n";
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
else if (PI.name == "diff_color")
|
||||
{
|
||||
if (m_prog.back_color_diffuse_output || m_prog.front_color_diffuse_output)
|
||||
{
|
||||
if (m_prog.back_color_diffuse_output && m_prog.front_color_diffuse_output)
|
||||
{
|
||||
OS << " vec4 diff_color = gl_FrontFacing ? front_diff_color : back_diff_color;\n";
|
||||
}
|
||||
else if (m_prog.back_color_diffuse_output)
|
||||
{
|
||||
OS << " vec4 diff_color = back_diff_color;\n";
|
||||
}
|
||||
else
|
||||
OS << " vec4 diff_color = front_diff_color;\n";
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (PI.name == "fogc")
|
||||
{
|
||||
vk::insert_fog_declaration(OS, m_prog.fog_equation);
|
||||
|
@ -262,12 +262,17 @@ namespace vk
|
||||
}
|
||||
}
|
||||
|
||||
VkFrontFace get_front_face_ccw(rsx::front_face ffv)
|
||||
VkFrontFace get_front_face(rsx::front_face ffv)
|
||||
{
|
||||
u32 mask = 1;
|
||||
|
||||
if (rsx::to_window_origin((rsx::method_registers[NV4097_SET_SHADER_WINDOW] >> 12) & 0xf) == rsx::window_origin::bottom)
|
||||
mask = 0;
|
||||
|
||||
switch (ffv)
|
||||
{
|
||||
case rsx::front_face::cw: return VK_FRONT_FACE_CLOCKWISE;
|
||||
case rsx::front_face::ccw: return VK_FRONT_FACE_COUNTER_CLOCKWISE;
|
||||
case rsx::front_face::cw: return (VkFrontFace)(VK_FRONT_FACE_CLOCKWISE ^ mask);
|
||||
case rsx::front_face::ccw: return (VkFrontFace)(VK_FRONT_FACE_COUNTER_CLOCKWISE ^ mask);
|
||||
default:
|
||||
throw EXCEPTION("Unknown front face value: 0x%X", ffv);
|
||||
}
|
||||
@ -307,6 +312,7 @@ namespace
|
||||
color_attachement_description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||
color_attachement_description.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
color_attachement_description.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
|
||||
for (u32 i = 0; i < number_of_color_surface; ++i)
|
||||
{
|
||||
attachments.push_back(color_attachement_description);
|
||||
@ -867,7 +873,6 @@ bool VKGSRender::load_program()
|
||||
|
||||
vk::pipeline_props properties = {};
|
||||
|
||||
|
||||
properties.ia.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
|
||||
bool unused;
|
||||
properties.ia.topology = vk::get_appropriate_topology(draw_mode, unused);
|
||||
@ -986,6 +991,12 @@ bool VKGSRender::load_program()
|
||||
else
|
||||
properties.ds.depthTestEnable = VK_FALSE;
|
||||
|
||||
properties.rs.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
|
||||
properties.rs.polygonMode = VK_POLYGON_MODE_FILL;
|
||||
properties.rs.depthClampEnable = VK_FALSE;
|
||||
properties.rs.rasterizerDiscardEnable = VK_FALSE;
|
||||
properties.rs.depthBiasEnable = VK_FALSE;
|
||||
|
||||
if (rsx::method_registers.cull_face_enabled())
|
||||
{
|
||||
switch (rsx::method_registers.cull_face_mode())
|
||||
@ -1007,12 +1018,13 @@ bool VKGSRender::load_program()
|
||||
else
|
||||
properties.rs.cullMode = VK_CULL_MODE_NONE;
|
||||
|
||||
properties.rs.frontFace = vk::get_front_face_ccw(rsx::method_registers.front_face_mode());
|
||||
properties.rs.frontFace = vk::get_front_face(rsx::method_registers.front_face_mode());
|
||||
|
||||
size_t idx = vk::get_render_pass_location(
|
||||
vk::get_compatible_surface_format(rsx::method_registers.surface_color()).first,
|
||||
vk::get_compatible_depth_surface_format(m_optimal_tiling_supported_formats, rsx::method_registers.surface_depth_fmt()),
|
||||
(u8)vk::get_draw_buffers(rsx::method_registers.surface_color_target()).size());
|
||||
|
||||
properties.render_pass = m_render_passes[idx];
|
||||
|
||||
properties.num_targets = m_draw_buffers_count;
|
||||
|
@ -29,6 +29,7 @@ namespace vk
|
||||
return false;
|
||||
if (memcmp(&rs, &other.rs, sizeof(VkPipelineRasterizationStateCreateInfo)))
|
||||
return false;
|
||||
|
||||
return num_targets == other.num_targets;
|
||||
}
|
||||
};
|
||||
@ -55,6 +56,7 @@ namespace std
|
||||
size_t seed = hash<unsigned>()(pipelineProperties.num_targets);
|
||||
seed ^= hash_struct(pipelineProperties.ia);
|
||||
seed ^= hash_struct(pipelineProperties.ds);
|
||||
seed ^= hash_struct(pipelineProperties.rs);
|
||||
seed ^= hash_struct(pipelineProperties.att_state[0]);
|
||||
return hash<size_t>()(seed);
|
||||
}
|
||||
@ -125,21 +127,12 @@ struct VKTraits
|
||||
cb.attachmentCount = 1;
|
||||
cb.pAttachments = pipelineProperties.att_state;
|
||||
|
||||
VkPipelineRasterizationStateCreateInfo rs = {};
|
||||
rs.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
|
||||
rs.polygonMode = VK_POLYGON_MODE_FILL;
|
||||
rs.cullMode = VK_CULL_MODE_NONE;
|
||||
rs.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
|
||||
rs.depthClampEnable = VK_FALSE;
|
||||
rs.rasterizerDiscardEnable = VK_FALSE;
|
||||
rs.depthBiasEnable = VK_FALSE;
|
||||
|
||||
VkPipeline pipeline;
|
||||
VkGraphicsPipelineCreateInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
||||
info.pVertexInputState = &vi;
|
||||
info.pInputAssemblyState = &pipelineProperties.ia;
|
||||
info.pRasterizationState = &rs;
|
||||
info.pRasterizationState = &pipelineProperties.rs;
|
||||
info.pColorBlendState = &cb;
|
||||
info.pMultisampleState = &ms;
|
||||
info.pViewportState = &vp;
|
||||
|
@ -129,8 +129,8 @@ struct reg_info
|
||||
static const reg_info reg_table[] =
|
||||
{
|
||||
{ "gl_Position", false, "dst_reg0", "", false },
|
||||
{ "diff_color", true, "dst_reg1", "", false },
|
||||
{ "spec_color", true, "dst_reg2", "", false },
|
||||
{ "back_diff_color", true, "dst_reg1", "", false },
|
||||
{ "back_spec_color", true, "dst_reg2", "", false },
|
||||
{ "front_diff_color", true, "dst_reg3", "", false },
|
||||
{ "front_spec_color", true, "dst_reg4", "", false },
|
||||
{ "fog_c", true, "dst_reg5", ".xxxx", true },
|
||||
@ -159,18 +159,32 @@ static const reg_info reg_table[] =
|
||||
|
||||
void VKVertexDecompilerThread::insertOutputs(std::stringstream & OS, const std::vector<ParamType> & outputs)
|
||||
{
|
||||
bool insert_front_diffuse = (rsx_vertex_program.output_mask & 1);
|
||||
bool insert_back_diffuse = (rsx_vertex_program.output_mask & 4);
|
||||
|
||||
bool insert_front_specular = (rsx_vertex_program.output_mask & 2);
|
||||
bool insert_back_specular = (rsx_vertex_program.output_mask & 8);
|
||||
|
||||
for (auto &i : reg_table)
|
||||
{
|
||||
if (m_parr.HasParam(PF_PARAM_NONE, "vec4", i.src_reg) && i.need_declare)
|
||||
{
|
||||
if (i.name == "front_diff_color")
|
||||
insert_front_diffuse = false;
|
||||
|
||||
if (i.name == "front_spec_color")
|
||||
insert_front_specular = false;
|
||||
|
||||
const vk::varying_register_t ® = vk::get_varying_register(i.name);
|
||||
|
||||
// if (i.name == "fogc")
|
||||
// OS << "layout(location=" << reg.reg_location << ") out vec4 fog_c;" << std::endl;
|
||||
// else
|
||||
OS << "layout(location=" << reg.reg_location << ") out vec4 " << i.name << ";" << std::endl;
|
||||
OS << "layout(location=" << reg.reg_location << ") out vec4 " << i.name << ";" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (insert_back_diffuse && insert_front_diffuse)
|
||||
OS << "layout(location=" << vk::get_varying_register("front_diff_color").reg_location << ") out vec4 front_diff_color;" << std::endl;
|
||||
|
||||
if (insert_back_specular && insert_front_specular)
|
||||
OS << "layout(location=" << vk::get_varying_register("front_spec_color").reg_location << ") out vec4 front_spec_color;" << std::endl;
|
||||
}
|
||||
|
||||
namespace vk
|
||||
@ -240,12 +254,34 @@ void VKVertexDecompilerThread::insertMainStart(std::stringstream & OS)
|
||||
|
||||
void VKVertexDecompilerThread::insertMainEnd(std::stringstream & OS)
|
||||
{
|
||||
bool insert_front_diffuse = (rsx_vertex_program.output_mask & 1);
|
||||
bool insert_front_specular = (rsx_vertex_program.output_mask & 2);
|
||||
|
||||
bool insert_back_diffuse = (rsx_vertex_program.output_mask & 4);
|
||||
bool insert_back_specular = (rsx_vertex_program.output_mask & 8);
|
||||
|
||||
for (auto &i : reg_table)
|
||||
{
|
||||
if (m_parr.HasParam(PF_PARAM_NONE, "vec4", i.src_reg))
|
||||
{
|
||||
if (i.name == "front_spec_color")
|
||||
insert_front_diffuse = false;
|
||||
|
||||
if (i.name == "front_spec_color")
|
||||
insert_front_specular = false;
|
||||
|
||||
OS << " " << i.name << " = " << i.src_reg << i.src_reg_mask << ";" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (insert_back_diffuse && insert_front_diffuse)
|
||||
if (m_parr.HasParam(PF_PARAM_NONE, "vec4", "dst_reg1"))
|
||||
OS << " front_diff_color = dst_reg1;\n";
|
||||
|
||||
if (insert_back_specular && insert_front_specular)
|
||||
if (m_parr.HasParam(PF_PARAM_NONE, "vec4", "dst_reg2"))
|
||||
OS << " front_spec_color = dst_reg2;\n";
|
||||
|
||||
OS << " gl_Position = gl_Position * scaleOffsetMat;" << std::endl;
|
||||
OS << "}" << std::endl;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user