renderer_vulkan: Pack PicaFSConfig
* Using bitfields the struct size was reduced from 420 to 190 bytes. which should speed up hashing and copying to the worker thread
This commit is contained in:
@@ -162,8 +162,7 @@ void PipelineCache::BindPipeline(const PipelineInfo& info) {
|
|||||||
|
|
||||||
const u64 info_hash_size = instance.IsExtendedDynamicStateSupported()
|
const u64 info_hash_size = instance.IsExtendedDynamicStateSupported()
|
||||||
? offsetof(PipelineInfo, rasterization)
|
? offsetof(PipelineInfo, rasterization)
|
||||||
: offsetof(PipelineInfo, depth_stencil) +
|
: offsetof(PipelineInfo, dynamic);
|
||||||
offsetof(DepthStencilState, stencil_reference);
|
|
||||||
|
|
||||||
u64 info_hash = Common::ComputeHash64(&info, info_hash_size);
|
u64 info_hash = Common::ComputeHash64(&info, info_hash_size);
|
||||||
u64 pipeline_hash = Common::HashCombine(shader_hash, info_hash);
|
u64 pipeline_hash = Common::HashCombine(shader_hash, info_hash);
|
||||||
@@ -234,7 +233,7 @@ void PipelineCache::UseTrivialGeometryShader() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PipelineCache::UseFragmentShader(const Pica::Regs& regs) {
|
void PipelineCache::UseFragmentShader(const Pica::Regs& regs) {
|
||||||
const PicaFSConfig config = PicaFSConfig::BuildFromRegs(regs);
|
const PicaFSConfig config{regs};
|
||||||
|
|
||||||
scheduler.Record([this, config](vk::CommandBuffer, vk::CommandBuffer) {
|
scheduler.Record([this, config](vk::CommandBuffer, vk::CommandBuffer) {
|
||||||
auto [handle, result] = fragment_shaders.Get(config, vk::ShaderStageFlagBits::eFragment,
|
auto [handle, result] = fragment_shaders.Get(config, vk::ShaderStageFlagBits::eFragment,
|
||||||
@@ -301,23 +300,28 @@ void PipelineCache::ApplyDynamic(const PipelineInfo& info) {
|
|||||||
|
|
||||||
PipelineInfo current = current_info;
|
PipelineInfo current = current_info;
|
||||||
scheduler.Record([this, info, is_dirty, current](vk::CommandBuffer render_cmdbuf, vk::CommandBuffer) {
|
scheduler.Record([this, info, is_dirty, current](vk::CommandBuffer render_cmdbuf, vk::CommandBuffer) {
|
||||||
if (info.depth_stencil.stencil_compare_mask !=
|
if (info.dynamic.stencil_compare_mask !=
|
||||||
current.depth_stencil.stencil_compare_mask ||
|
current.dynamic.stencil_compare_mask ||
|
||||||
is_dirty) {
|
is_dirty) {
|
||||||
render_cmdbuf.setStencilCompareMask(vk::StencilFaceFlagBits::eFrontAndBack,
|
render_cmdbuf.setStencilCompareMask(vk::StencilFaceFlagBits::eFrontAndBack,
|
||||||
info.depth_stencil.stencil_compare_mask);
|
info.dynamic.stencil_compare_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.depth_stencil.stencil_write_mask != current.depth_stencil.stencil_write_mask ||
|
if (info.dynamic.stencil_write_mask != current.dynamic.stencil_write_mask ||
|
||||||
is_dirty) {
|
is_dirty) {
|
||||||
render_cmdbuf.setStencilWriteMask(vk::StencilFaceFlagBits::eFrontAndBack,
|
render_cmdbuf.setStencilWriteMask(vk::StencilFaceFlagBits::eFrontAndBack,
|
||||||
info.depth_stencil.stencil_write_mask);
|
info.dynamic.stencil_write_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.depth_stencil.stencil_reference != current.depth_stencil.stencil_reference ||
|
if (info.dynamic.stencil_reference != current.dynamic.stencil_reference ||
|
||||||
is_dirty) {
|
is_dirty) {
|
||||||
render_cmdbuf.setStencilReference(vk::StencilFaceFlagBits::eFrontAndBack,
|
render_cmdbuf.setStencilReference(vk::StencilFaceFlagBits::eFrontAndBack,
|
||||||
info.depth_stencil.stencil_reference);
|
info.dynamic.stencil_reference);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.dynamic.blend_color != current.dynamic.blend_color || is_dirty) {
|
||||||
|
const Common::Vec4f color = PicaToVK::ColorRGBA8(info.dynamic.blend_color);
|
||||||
|
render_cmdbuf.setBlendConstants(color.AsArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (instance.IsExtendedDynamicStateSupported()) {
|
if (instance.IsExtendedDynamicStateSupported()) {
|
||||||
|
@@ -29,21 +29,16 @@ union RasterizationState {
|
|||||||
BitField<4, 2, Pica::RasterizerRegs::CullMode> cull_mode;
|
BitField<4, 2, Pica::RasterizerRegs::CullMode> cull_mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DepthStencilState {
|
union DepthStencilState {
|
||||||
union {
|
u32 value = 0;
|
||||||
u32 value = 0;
|
BitField<0, 1, u32> depth_test_enable;
|
||||||
BitField<0, 1, u32> depth_test_enable;
|
BitField<1, 1, u32> depth_write_enable;
|
||||||
BitField<1, 1, u32> depth_write_enable;
|
BitField<2, 1, u32> stencil_test_enable;
|
||||||
BitField<2, 1, u32> stencil_test_enable;
|
BitField<3, 3, Pica::FramebufferRegs::CompareFunc> depth_compare_op;
|
||||||
BitField<3, 3, Pica::FramebufferRegs::CompareFunc> depth_compare_op;
|
BitField<6, 3, Pica::FramebufferRegs::StencilAction> stencil_fail_op;
|
||||||
BitField<6, 3, Pica::FramebufferRegs::StencilAction> stencil_fail_op;
|
BitField<9, 3, Pica::FramebufferRegs::StencilAction> stencil_pass_op;
|
||||||
BitField<9, 3, Pica::FramebufferRegs::StencilAction> stencil_pass_op;
|
BitField<12, 3, Pica::FramebufferRegs::StencilAction> stencil_depth_fail_op;
|
||||||
BitField<12, 3, Pica::FramebufferRegs::StencilAction> stencil_depth_fail_op;
|
BitField<15, 3, Pica::FramebufferRegs::CompareFunc> stencil_compare_op;
|
||||||
BitField<15, 3, Pica::FramebufferRegs::CompareFunc> stencil_compare_op;
|
|
||||||
};
|
|
||||||
u8 stencil_reference;
|
|
||||||
u8 stencil_compare_mask;
|
|
||||||
u8 stencil_write_mask;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
union BlendingState {
|
union BlendingState {
|
||||||
@@ -59,6 +54,13 @@ union BlendingState {
|
|||||||
BitField<27, 4, Pica::FramebufferRegs::LogicOp> logic_op;
|
BitField<27, 4, Pica::FramebufferRegs::LogicOp> logic_op;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct DynamicState {
|
||||||
|
u32 blend_color = 0;
|
||||||
|
u8 stencil_reference;
|
||||||
|
u8 stencil_compare_mask;
|
||||||
|
u8 stencil_write_mask;
|
||||||
|
};
|
||||||
|
|
||||||
union VertexBinding {
|
union VertexBinding {
|
||||||
u16 value = 0;
|
u16 value = 0;
|
||||||
BitField<0, 4, u16> binding;
|
BitField<0, 4, u16> binding;
|
||||||
@@ -92,13 +94,14 @@ struct PipelineInfo {
|
|||||||
VideoCore::PixelFormat depth_attachment = VideoCore::PixelFormat::D24S8;
|
VideoCore::PixelFormat depth_attachment = VideoCore::PixelFormat::D24S8;
|
||||||
RasterizationState rasterization{};
|
RasterizationState rasterization{};
|
||||||
DepthStencilState depth_stencil{};
|
DepthStencilState depth_stencil{};
|
||||||
|
DynamicState dynamic;
|
||||||
|
|
||||||
[[nodiscard]] bool IsDepthWriteEnabled() const noexcept {
|
[[nodiscard]] bool IsDepthWriteEnabled() const noexcept {
|
||||||
const bool has_stencil = depth_attachment == VideoCore::PixelFormat::D24S8;
|
const bool has_stencil = depth_attachment == VideoCore::PixelFormat::D24S8;
|
||||||
const bool depth_write =
|
const bool depth_write =
|
||||||
depth_stencil.depth_test_enable && depth_stencil.depth_write_enable;
|
depth_stencil.depth_test_enable && depth_stencil.depth_write_enable;
|
||||||
const bool stencil_write = has_stencil && depth_stencil.stencil_test_enable &&
|
const bool stencil_write = has_stencil && depth_stencil.stencil_test_enable &&
|
||||||
depth_stencil.stencil_write_mask != 0;
|
dynamic.stencil_write_mask != 0;
|
||||||
|
|
||||||
return depth_write || stencil_write;
|
return depth_write || stencil_write;
|
||||||
}
|
}
|
||||||
|
@@ -304,6 +304,7 @@ void RasterizerVulkan::SetupVertexArray(u32 vs_input_size, u32 vs_input_index_mi
|
|||||||
binding.stride.Assign(offset);
|
binding.stride.Assign(offset);
|
||||||
|
|
||||||
binding_offsets[layout.binding_count++] = array_offset + buffer_offset;
|
binding_offsets[layout.binding_count++] = array_offset + buffer_offset;
|
||||||
|
ASSERT(buffer_offset + offset <= vertex_size);
|
||||||
vertex_buffer.Commit(buffer_offset + offset);
|
vertex_buffer.Commit(buffer_offset + offset);
|
||||||
|
|
||||||
// Update the pipeline vertex layout
|
// Update the pipeline vertex layout
|
||||||
@@ -1587,12 +1588,8 @@ void RasterizerVulkan::SyncBlendFuncs() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerVulkan::SyncBlendColor() {
|
void RasterizerVulkan::SyncBlendColor() {
|
||||||
const Common::Vec4f blend_color =
|
const auto& regs = Pica::g_state.regs;
|
||||||
PicaToVK::ColorRGBA8(Pica::g_state.regs.framebuffer.output_merger.blend_const.raw);
|
pipeline_info.dynamic.blend_color = regs.framebuffer.output_merger.blend_const.raw;
|
||||||
|
|
||||||
scheduler.Record([blend_color](vk::CommandBuffer render_cmdbuf, vk::CommandBuffer) {
|
|
||||||
render_cmdbuf.setBlendConstants(blend_color.AsArray());
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerVulkan::SyncLogicOp() {
|
void RasterizerVulkan::SyncLogicOp() {
|
||||||
@@ -1608,7 +1605,7 @@ void RasterizerVulkan::SyncColorWriteMask() {
|
|||||||
|
|
||||||
void RasterizerVulkan::SyncStencilWriteMask() {
|
void RasterizerVulkan::SyncStencilWriteMask() {
|
||||||
const auto& regs = Pica::g_state.regs;
|
const auto& regs = Pica::g_state.regs;
|
||||||
pipeline_info.depth_stencil.stencil_write_mask =
|
pipeline_info.dynamic.stencil_write_mask =
|
||||||
(regs.framebuffer.framebuffer.allow_depth_stencil_write != 0)
|
(regs.framebuffer.framebuffer.allow_depth_stencil_write != 0)
|
||||||
? static_cast<u32>(regs.framebuffer.output_merger.stencil_test.write_mask)
|
? static_cast<u32>(regs.framebuffer.output_merger.stencil_test.write_mask)
|
||||||
: 0;
|
: 0;
|
||||||
@@ -1634,8 +1631,8 @@ void RasterizerVulkan::SyncStencilTest() {
|
|||||||
pipeline_info.depth_stencil.stencil_pass_op.Assign(stencil_test.action_depth_pass);
|
pipeline_info.depth_stencil.stencil_pass_op.Assign(stencil_test.action_depth_pass);
|
||||||
pipeline_info.depth_stencil.stencil_depth_fail_op.Assign(stencil_test.action_depth_fail);
|
pipeline_info.depth_stencil.stencil_depth_fail_op.Assign(stencil_test.action_depth_fail);
|
||||||
pipeline_info.depth_stencil.stencil_compare_op.Assign(stencil_test.func);
|
pipeline_info.depth_stencil.stencil_compare_op.Assign(stencil_test.func);
|
||||||
pipeline_info.depth_stencil.stencil_reference = stencil_test.reference_value;
|
pipeline_info.dynamic.stencil_reference = stencil_test.reference_value;
|
||||||
pipeline_info.depth_stencil.stencil_compare_mask = stencil_test.input_mask;
|
pipeline_info.dynamic.stencil_compare_mask = stencil_test.input_mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerVulkan::SyncDepthTest() {
|
void RasterizerVulkan::SyncDepthTest() {
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "video_core/pica_state.h"
|
#include "video_core/pica_state.h"
|
||||||
|
#include "video_core/regs_framebuffer.h"
|
||||||
#include "video_core/renderer_opengl/gl_shader_decompiler.h"
|
#include "video_core/renderer_opengl/gl_shader_decompiler.h"
|
||||||
#include "video_core/renderer_vulkan/vk_shader_gen.h"
|
#include "video_core/renderer_vulkan/vk_shader_gen.h"
|
||||||
#include "video_core/video_core.h"
|
#include "video_core/video_core.h"
|
||||||
@@ -99,25 +100,21 @@ out gl_PerVertex {
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
PicaFSConfig PicaFSConfig::BuildFromRegs(const Pica::Regs& regs) {
|
PicaFSConfig::PicaFSConfig(const Pica::Regs& regs) {
|
||||||
PicaFSConfig res{};
|
state.scissor_test_mode.Assign(regs.rasterizer.scissor_test.mode);
|
||||||
|
|
||||||
auto& state = res.state;
|
state.depthmap_enable.Assign(regs.rasterizer.depthmap_enable);
|
||||||
|
|
||||||
state.scissor_test_mode = regs.rasterizer.scissor_test.mode;
|
state.alpha_test_func.Assign(regs.framebuffer.output_merger.alpha_test.enable
|
||||||
|
|
||||||
state.depthmap_enable = regs.rasterizer.depthmap_enable;
|
|
||||||
|
|
||||||
state.alpha_test_func = regs.framebuffer.output_merger.alpha_test.enable
|
|
||||||
? regs.framebuffer.output_merger.alpha_test.func.Value()
|
? regs.framebuffer.output_merger.alpha_test.func.Value()
|
||||||
: FramebufferRegs::CompareFunc::Always;
|
: FramebufferRegs::CompareFunc::Always);
|
||||||
|
|
||||||
state.texture0_type = regs.texturing.texture0.type;
|
state.texture0_type.Assign(regs.texturing.texture0.type);
|
||||||
|
|
||||||
state.texture2_use_coord1 = regs.texturing.main_config.texture2_use_coord1 != 0;
|
state.texture2_use_coord1.Assign(regs.texturing.main_config.texture2_use_coord1 != 0);
|
||||||
|
|
||||||
state.alphablend_enable = {};
|
state.alphablend_enable.Assign(0);
|
||||||
state.logic_op = {};
|
state.logic_op.Assign(Pica::FramebufferRegs::LogicOp::Clear);
|
||||||
|
|
||||||
// Copy relevant tev stages fields.
|
// Copy relevant tev stages fields.
|
||||||
// We don't sync const_color here because of the high variance, it is a
|
// We don't sync const_color here because of the high variance, it is a
|
||||||
@@ -132,95 +129,95 @@ PicaFSConfig PicaFSConfig::BuildFromRegs(const Pica::Regs& regs) {
|
|||||||
state.tev_stages[i].scales_raw = tev_stage.scales_raw;
|
state.tev_stages[i].scales_raw = tev_stage.scales_raw;
|
||||||
}
|
}
|
||||||
|
|
||||||
state.fog_mode = regs.texturing.fog_mode;
|
state.fog_mode.Assign(regs.texturing.fog_mode);
|
||||||
state.fog_flip = regs.texturing.fog_flip != 0;
|
state.fog_flip.Assign(regs.texturing.fog_flip != 0);
|
||||||
|
|
||||||
state.combiner_buffer_input = regs.texturing.tev_combiner_buffer_input.update_mask_rgb.Value() |
|
state.combiner_buffer_input.Assign(regs.texturing.tev_combiner_buffer_input.update_mask_rgb.Value() |
|
||||||
regs.texturing.tev_combiner_buffer_input.update_mask_a.Value()
|
regs.texturing.tev_combiner_buffer_input.update_mask_a.Value()
|
||||||
<< 4;
|
<< 4);
|
||||||
|
|
||||||
// Fragment lighting
|
// Fragment lighting
|
||||||
|
|
||||||
state.lighting.enable = !regs.lighting.disable;
|
state.lighting.enable.Assign(!regs.lighting.disable);
|
||||||
state.lighting.src_num = regs.lighting.max_light_index + 1;
|
state.lighting.src_num.Assign(regs.lighting.max_light_index + 1);
|
||||||
|
|
||||||
for (unsigned light_index = 0; light_index < state.lighting.src_num; ++light_index) {
|
for (u32 light_index = 0; light_index < state.lighting.src_num; ++light_index) {
|
||||||
unsigned num = regs.lighting.light_enable.GetNum(light_index);
|
u32 num = regs.lighting.light_enable.GetNum(light_index);
|
||||||
const auto& light = regs.lighting.light[num];
|
const auto& light = regs.lighting.light[num];
|
||||||
state.lighting.light[light_index].num = num;
|
state.lighting.light[light_index].num.Assign(num);
|
||||||
state.lighting.light[light_index].directional = light.config.directional != 0;
|
state.lighting.light[light_index].directional.Assign(light.config.directional != 0);
|
||||||
state.lighting.light[light_index].two_sided_diffuse = light.config.two_sided_diffuse != 0;
|
state.lighting.light[light_index].two_sided_diffuse.Assign(light.config.two_sided_diffuse != 0);
|
||||||
state.lighting.light[light_index].geometric_factor_0 = light.config.geometric_factor_0 != 0;
|
state.lighting.light[light_index].geometric_factor_0.Assign(light.config.geometric_factor_0 != 0);
|
||||||
state.lighting.light[light_index].geometric_factor_1 = light.config.geometric_factor_1 != 0;
|
state.lighting.light[light_index].geometric_factor_1.Assign(light.config.geometric_factor_1 != 0);
|
||||||
state.lighting.light[light_index].dist_atten_enable =
|
state.lighting.light[light_index].dist_atten_enable.Assign(
|
||||||
!regs.lighting.IsDistAttenDisabled(num);
|
!regs.lighting.IsDistAttenDisabled(num));
|
||||||
state.lighting.light[light_index].spot_atten_enable =
|
state.lighting.light[light_index].spot_atten_enable.Assign(
|
||||||
!regs.lighting.IsSpotAttenDisabled(num);
|
!regs.lighting.IsSpotAttenDisabled(num));
|
||||||
state.lighting.light[light_index].shadow_enable = !regs.lighting.IsShadowDisabled(num);
|
state.lighting.light[light_index].shadow_enable.Assign(!regs.lighting.IsShadowDisabled(num));
|
||||||
}
|
}
|
||||||
|
|
||||||
state.lighting.lut_d0.enable = regs.lighting.config1.disable_lut_d0 == 0;
|
state.lighting.lut_d0.enable.Assign(regs.lighting.config1.disable_lut_d0 == 0);
|
||||||
state.lighting.lut_d0.abs_input = regs.lighting.abs_lut_input.disable_d0 == 0;
|
state.lighting.lut_d0.abs_input.Assign(regs.lighting.abs_lut_input.disable_d0 == 0);
|
||||||
state.lighting.lut_d0.type = regs.lighting.lut_input.d0.Value();
|
state.lighting.lut_d0.type.Assign(regs.lighting.lut_input.d0.Value());
|
||||||
state.lighting.lut_d0.scale = regs.lighting.lut_scale.GetScale(regs.lighting.lut_scale.d0);
|
state.lighting.lut_d0.scale = regs.lighting.lut_scale.GetScale(regs.lighting.lut_scale.d0);
|
||||||
|
|
||||||
state.lighting.lut_d1.enable = regs.lighting.config1.disable_lut_d1 == 0;
|
state.lighting.lut_d1.enable.Assign(regs.lighting.config1.disable_lut_d1 == 0);
|
||||||
state.lighting.lut_d1.abs_input = regs.lighting.abs_lut_input.disable_d1 == 0;
|
state.lighting.lut_d1.abs_input.Assign(regs.lighting.abs_lut_input.disable_d1 == 0);
|
||||||
state.lighting.lut_d1.type = regs.lighting.lut_input.d1.Value();
|
state.lighting.lut_d1.type.Assign(regs.lighting.lut_input.d1.Value());
|
||||||
state.lighting.lut_d1.scale = regs.lighting.lut_scale.GetScale(regs.lighting.lut_scale.d1);
|
state.lighting.lut_d1.scale = regs.lighting.lut_scale.GetScale(regs.lighting.lut_scale.d1);
|
||||||
|
|
||||||
// this is a dummy field due to lack of the corresponding register
|
// this is a dummy field due to lack of the corresponding register
|
||||||
state.lighting.lut_sp.enable = true;
|
state.lighting.lut_sp.enable.Assign(1);
|
||||||
state.lighting.lut_sp.abs_input = regs.lighting.abs_lut_input.disable_sp == 0;
|
state.lighting.lut_sp.abs_input.Assign(regs.lighting.abs_lut_input.disable_sp == 0);
|
||||||
state.lighting.lut_sp.type = regs.lighting.lut_input.sp.Value();
|
state.lighting.lut_sp.type.Assign(regs.lighting.lut_input.sp.Value());
|
||||||
state.lighting.lut_sp.scale = regs.lighting.lut_scale.GetScale(regs.lighting.lut_scale.sp);
|
state.lighting.lut_sp.scale = regs.lighting.lut_scale.GetScale(regs.lighting.lut_scale.sp);
|
||||||
|
|
||||||
state.lighting.lut_fr.enable = regs.lighting.config1.disable_lut_fr == 0;
|
state.lighting.lut_fr.enable.Assign(regs.lighting.config1.disable_lut_fr == 0);
|
||||||
state.lighting.lut_fr.abs_input = regs.lighting.abs_lut_input.disable_fr == 0;
|
state.lighting.lut_fr.abs_input.Assign(regs.lighting.abs_lut_input.disable_fr == 0);
|
||||||
state.lighting.lut_fr.type = regs.lighting.lut_input.fr.Value();
|
state.lighting.lut_fr.type.Assign(regs.lighting.lut_input.fr.Value());
|
||||||
state.lighting.lut_fr.scale = regs.lighting.lut_scale.GetScale(regs.lighting.lut_scale.fr);
|
state.lighting.lut_fr.scale = regs.lighting.lut_scale.GetScale(regs.lighting.lut_scale.fr);
|
||||||
|
|
||||||
state.lighting.lut_rr.enable = regs.lighting.config1.disable_lut_rr == 0;
|
state.lighting.lut_rr.enable.Assign(regs.lighting.config1.disable_lut_rr == 0);
|
||||||
state.lighting.lut_rr.abs_input = regs.lighting.abs_lut_input.disable_rr == 0;
|
state.lighting.lut_rr.abs_input.Assign(regs.lighting.abs_lut_input.disable_rr == 0);
|
||||||
state.lighting.lut_rr.type = regs.lighting.lut_input.rr.Value();
|
state.lighting.lut_rr.type.Assign(regs.lighting.lut_input.rr.Value());
|
||||||
state.lighting.lut_rr.scale = regs.lighting.lut_scale.GetScale(regs.lighting.lut_scale.rr);
|
state.lighting.lut_rr.scale = regs.lighting.lut_scale.GetScale(regs.lighting.lut_scale.rr);
|
||||||
|
|
||||||
state.lighting.lut_rg.enable = regs.lighting.config1.disable_lut_rg == 0;
|
state.lighting.lut_rg.enable.Assign(regs.lighting.config1.disable_lut_rg == 0);
|
||||||
state.lighting.lut_rg.abs_input = regs.lighting.abs_lut_input.disable_rg == 0;
|
state.lighting.lut_rg.abs_input.Assign(regs.lighting.abs_lut_input.disable_rg == 0);
|
||||||
state.lighting.lut_rg.type = regs.lighting.lut_input.rg.Value();
|
state.lighting.lut_rg.type.Assign(regs.lighting.lut_input.rg.Value());
|
||||||
state.lighting.lut_rg.scale = regs.lighting.lut_scale.GetScale(regs.lighting.lut_scale.rg);
|
state.lighting.lut_rg.scale = regs.lighting.lut_scale.GetScale(regs.lighting.lut_scale.rg);
|
||||||
|
|
||||||
state.lighting.lut_rb.enable = regs.lighting.config1.disable_lut_rb == 0;
|
state.lighting.lut_rb.enable.Assign(regs.lighting.config1.disable_lut_rb == 0);
|
||||||
state.lighting.lut_rb.abs_input = regs.lighting.abs_lut_input.disable_rb == 0;
|
state.lighting.lut_rb.abs_input.Assign(regs.lighting.abs_lut_input.disable_rb == 0);
|
||||||
state.lighting.lut_rb.type = regs.lighting.lut_input.rb.Value();
|
state.lighting.lut_rb.type.Assign(regs.lighting.lut_input.rb.Value());
|
||||||
state.lighting.lut_rb.scale = regs.lighting.lut_scale.GetScale(regs.lighting.lut_scale.rb);
|
state.lighting.lut_rb.scale = regs.lighting.lut_scale.GetScale(regs.lighting.lut_scale.rb);
|
||||||
|
|
||||||
state.lighting.config = regs.lighting.config0.config;
|
state.lighting.config.Assign(regs.lighting.config0.config);
|
||||||
state.lighting.enable_primary_alpha = regs.lighting.config0.enable_primary_alpha;
|
state.lighting.enable_primary_alpha.Assign(regs.lighting.config0.enable_primary_alpha);
|
||||||
state.lighting.enable_secondary_alpha = regs.lighting.config0.enable_secondary_alpha;
|
state.lighting.enable_secondary_alpha.Assign(regs.lighting.config0.enable_secondary_alpha);
|
||||||
state.lighting.bump_mode = regs.lighting.config0.bump_mode;
|
state.lighting.bump_mode.Assign(regs.lighting.config0.bump_mode);
|
||||||
state.lighting.bump_selector = regs.lighting.config0.bump_selector;
|
state.lighting.bump_selector.Assign(regs.lighting.config0.bump_selector);
|
||||||
state.lighting.bump_renorm = regs.lighting.config0.disable_bump_renorm == 0;
|
state.lighting.bump_renorm.Assign(regs.lighting.config0.disable_bump_renorm == 0);
|
||||||
state.lighting.clamp_highlights = regs.lighting.config0.clamp_highlights != 0;
|
state.lighting.clamp_highlights.Assign(regs.lighting.config0.clamp_highlights != 0);
|
||||||
|
|
||||||
state.lighting.enable_shadow = regs.lighting.config0.enable_shadow != 0;
|
state.lighting.enable_shadow.Assign(regs.lighting.config0.enable_shadow != 0);
|
||||||
state.lighting.shadow_primary = regs.lighting.config0.shadow_primary != 0;
|
state.lighting.shadow_primary.Assign(regs.lighting.config0.shadow_primary != 0);
|
||||||
state.lighting.shadow_secondary = regs.lighting.config0.shadow_secondary != 0;
|
state.lighting.shadow_secondary.Assign(regs.lighting.config0.shadow_secondary != 0);
|
||||||
state.lighting.shadow_invert = regs.lighting.config0.shadow_invert != 0;
|
state.lighting.shadow_invert.Assign(regs.lighting.config0.shadow_invert != 0);
|
||||||
state.lighting.shadow_alpha = regs.lighting.config0.shadow_alpha != 0;
|
state.lighting.shadow_alpha.Assign(regs.lighting.config0.shadow_alpha != 0);
|
||||||
state.lighting.shadow_selector = regs.lighting.config0.shadow_selector;
|
state.lighting.shadow_selector.Assign(regs.lighting.config0.shadow_selector);
|
||||||
|
|
||||||
state.proctex.enable = regs.texturing.main_config.texture3_enable;
|
state.proctex.enable.Assign(regs.texturing.main_config.texture3_enable);
|
||||||
if (state.proctex.enable) {
|
if (state.proctex.enable) {
|
||||||
state.proctex.coord = regs.texturing.main_config.texture3_coordinates;
|
state.proctex.coord.Assign(regs.texturing.main_config.texture3_coordinates);
|
||||||
state.proctex.u_clamp = regs.texturing.proctex.u_clamp;
|
state.proctex.u_clamp.Assign(regs.texturing.proctex.u_clamp);
|
||||||
state.proctex.v_clamp = regs.texturing.proctex.v_clamp;
|
state.proctex.v_clamp.Assign(regs.texturing.proctex.v_clamp);
|
||||||
state.proctex.color_combiner = regs.texturing.proctex.color_combiner;
|
state.proctex.color_combiner.Assign(regs.texturing.proctex.color_combiner);
|
||||||
state.proctex.alpha_combiner = regs.texturing.proctex.alpha_combiner;
|
state.proctex.alpha_combiner.Assign(regs.texturing.proctex.alpha_combiner);
|
||||||
state.proctex.separate_alpha = regs.texturing.proctex.separate_alpha;
|
state.proctex.separate_alpha.Assign(regs.texturing.proctex.separate_alpha);
|
||||||
state.proctex.noise_enable = regs.texturing.proctex.noise_enable;
|
state.proctex.noise_enable.Assign(regs.texturing.proctex.noise_enable);
|
||||||
state.proctex.u_shift = regs.texturing.proctex.u_shift;
|
state.proctex.u_shift.Assign(regs.texturing.proctex.u_shift);
|
||||||
state.proctex.v_shift = regs.texturing.proctex.v_shift;
|
state.proctex.v_shift.Assign(regs.texturing.proctex.v_shift);
|
||||||
state.proctex.lut_width = regs.texturing.proctex_lut.width;
|
state.proctex.lut_width = regs.texturing.proctex_lut.width;
|
||||||
state.proctex.lut_offset0 = regs.texturing.proctex_lut_offset.level0;
|
state.proctex.lut_offset0 = regs.texturing.proctex_lut_offset.level0;
|
||||||
state.proctex.lut_offset1 = regs.texturing.proctex_lut_offset.level1;
|
state.proctex.lut_offset1 = regs.texturing.proctex_lut_offset.level1;
|
||||||
@@ -228,17 +225,16 @@ PicaFSConfig PicaFSConfig::BuildFromRegs(const Pica::Regs& regs) {
|
|||||||
state.proctex.lut_offset3 = regs.texturing.proctex_lut_offset.level3;
|
state.proctex.lut_offset3 = regs.texturing.proctex_lut_offset.level3;
|
||||||
state.proctex.lod_min = regs.texturing.proctex_lut.lod_min;
|
state.proctex.lod_min = regs.texturing.proctex_lut.lod_min;
|
||||||
state.proctex.lod_max = regs.texturing.proctex_lut.lod_max;
|
state.proctex.lod_max = regs.texturing.proctex_lut.lod_max;
|
||||||
state.proctex.lut_filter = regs.texturing.proctex_lut.filter;
|
state.proctex.lut_filter.Assign(regs.texturing.proctex_lut.filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
state.shadow_rendering = regs.framebuffer.output_merger.fragment_operation_mode ==
|
state.shadow_rendering.Assign(regs.framebuffer.output_merger.fragment_operation_mode ==
|
||||||
FramebufferRegs::FragmentOperationMode::Shadow;
|
FramebufferRegs::FragmentOperationMode::Shadow);
|
||||||
|
|
||||||
state.shadow_texture_orthographic = regs.texturing.shadow.orthographic != 0;
|
state.shadow_texture_orthographic.Assign(regs.texturing.shadow.orthographic != 0);
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PicaShaderConfigCommon::Init(const Pica::ShaderRegs& regs, Pica::Shader::ShaderSetup& setup) {
|
void PicaShaderConfigCommon::Init(const Pica::ShaderRegs& regs, Pica::Shader::ShaderSetup& setup) {
|
||||||
program_hash = setup.GetProgramCodeHash();
|
program_hash = setup.GetProgramCodeHash();
|
||||||
swizzle_hash = setup.GetSwizzleDataHash();
|
swizzle_hash = setup.GetSwizzleDataHash();
|
||||||
|
@@ -42,77 +42,85 @@ struct TevStageConfigRaw {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct PicaFSConfigState {
|
struct PicaFSConfigState {
|
||||||
Pica::FramebufferRegs::CompareFunc alpha_test_func;
|
union {
|
||||||
Pica::RasterizerRegs::ScissorMode scissor_test_mode;
|
BitField<0, 3, Pica::FramebufferRegs::CompareFunc> alpha_test_func;
|
||||||
Pica::TexturingRegs::TextureConfig::TextureType texture0_type;
|
BitField<3, 2, Pica::RasterizerRegs::ScissorMode> scissor_test_mode;
|
||||||
bool texture2_use_coord1;
|
BitField<5, 3, Pica::TexturingRegs::TextureConfig::TextureType> texture0_type;
|
||||||
std::array<TevStageConfigRaw, 6> tev_stages;
|
BitField<8, 1, u32> texture2_use_coord1;
|
||||||
u8 combiner_buffer_input;
|
BitField<9, 8, u32> combiner_buffer_input;
|
||||||
|
BitField<17, 1, Pica::RasterizerRegs::DepthBuffering> depthmap_enable;
|
||||||
|
BitField<18, 3, Pica::TexturingRegs::FogMode> fog_mode;
|
||||||
|
BitField<21, 1, u32> fog_flip;
|
||||||
|
BitField<22, 1, u32> alphablend_enable;
|
||||||
|
BitField<23, 4, Pica::FramebufferRegs::LogicOp> logic_op;
|
||||||
|
BitField<27, 1, u32> shadow_rendering;
|
||||||
|
BitField<28, 1, u32> shadow_texture_orthographic;
|
||||||
|
};
|
||||||
|
|
||||||
Pica::RasterizerRegs::DepthBuffering depthmap_enable;
|
std::array<TevStageConfigRaw, 6> tev_stages;
|
||||||
Pica::TexturingRegs::FogMode fog_mode;
|
|
||||||
bool fog_flip;
|
|
||||||
bool alphablend_enable;
|
|
||||||
Pica::FramebufferRegs::LogicOp logic_op;
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
struct {
|
union {
|
||||||
unsigned num;
|
BitField<0, 3, u16> num;
|
||||||
bool directional;
|
BitField<3, 1, u16> directional;
|
||||||
bool two_sided_diffuse;
|
BitField<4, 1, u16> two_sided_diffuse;
|
||||||
bool dist_atten_enable;
|
BitField<5, 1, u16> dist_atten_enable;
|
||||||
bool spot_atten_enable;
|
BitField<6, 1, u16> spot_atten_enable;
|
||||||
bool geometric_factor_0;
|
BitField<7, 1, u16> geometric_factor_0;
|
||||||
bool geometric_factor_1;
|
BitField<8, 1, u16> geometric_factor_1;
|
||||||
bool shadow_enable;
|
BitField<9, 1, u16> shadow_enable;
|
||||||
} light[8];
|
} light[8];
|
||||||
|
|
||||||
bool enable;
|
union {
|
||||||
unsigned src_num;
|
BitField<0, 1, u32> enable;
|
||||||
Pica::LightingRegs::LightingBumpMode bump_mode;
|
BitField<1, 4, u32> src_num;
|
||||||
unsigned bump_selector;
|
BitField<5, 2, Pica::LightingRegs::LightingBumpMode> bump_mode;
|
||||||
bool bump_renorm;
|
BitField<7, 2, u32> bump_selector;
|
||||||
bool clamp_highlights;
|
BitField<9, 1, u32> bump_renorm;
|
||||||
|
BitField<10, 1, u32> clamp_highlights;
|
||||||
Pica::LightingRegs::LightingConfig config;
|
BitField<11, 4, Pica::LightingRegs::LightingConfig> config;
|
||||||
bool enable_primary_alpha;
|
BitField<15, 1, u32> enable_primary_alpha;
|
||||||
bool enable_secondary_alpha;
|
BitField<16, 1, u32> enable_secondary_alpha;
|
||||||
|
BitField<17, 1, u32> enable_shadow;
|
||||||
bool enable_shadow;
|
BitField<18, 1, u32> shadow_primary;
|
||||||
bool shadow_primary;
|
BitField<19, 1, u32> shadow_secondary;
|
||||||
bool shadow_secondary;
|
BitField<20, 1, u32> shadow_invert;
|
||||||
bool shadow_invert;
|
BitField<21, 1, u32> shadow_alpha;
|
||||||
bool shadow_alpha;
|
BitField<22, 2, u32> shadow_selector;
|
||||||
unsigned shadow_selector;
|
};
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
bool enable;
|
union {
|
||||||
bool abs_input;
|
BitField<0, 1, u32> enable;
|
||||||
Pica::LightingRegs::LightingLutInput type;
|
BitField<1, 1, u32> abs_input;
|
||||||
|
BitField<2, 3, Pica::LightingRegs::LightingLutInput> type;
|
||||||
|
};
|
||||||
float scale;
|
float scale;
|
||||||
} lut_d0, lut_d1, lut_sp, lut_fr, lut_rr, lut_rg, lut_rb;
|
} lut_d0, lut_d1, lut_sp, lut_fr, lut_rr, lut_rg, lut_rb;
|
||||||
} lighting;
|
} lighting;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
bool enable;
|
union {
|
||||||
u32 coord;
|
BitField<0, 1, u32> enable;
|
||||||
Pica::TexturingRegs::ProcTexClamp u_clamp, v_clamp;
|
BitField<1, 2, u32> coord;
|
||||||
Pica::TexturingRegs::ProcTexCombiner color_combiner, alpha_combiner;
|
BitField<3, 3, Pica::TexturingRegs::ProcTexClamp> u_clamp;
|
||||||
bool separate_alpha;
|
BitField<6, 3, Pica::TexturingRegs::ProcTexClamp> v_clamp;
|
||||||
bool noise_enable;
|
BitField<9, 4, Pica::TexturingRegs::ProcTexCombiner> color_combiner;
|
||||||
Pica::TexturingRegs::ProcTexShift u_shift, v_shift;
|
BitField<13, 4, Pica::TexturingRegs::ProcTexCombiner> alpha_combiner;
|
||||||
u32 lut_width;
|
BitField<17, 3, Pica::TexturingRegs::ProcTexFilter> lut_filter;
|
||||||
u32 lut_offset0;
|
BitField<20, 1, u32> separate_alpha;
|
||||||
u32 lut_offset1;
|
BitField<21, 1, u32> noise_enable;
|
||||||
u32 lut_offset2;
|
BitField<22, 2, Pica::TexturingRegs::ProcTexShift> u_shift;
|
||||||
u32 lut_offset3;
|
BitField<24, 2, Pica::TexturingRegs::ProcTexShift> v_shift;
|
||||||
u32 lod_min;
|
};
|
||||||
u32 lod_max;
|
u8 lut_width;
|
||||||
Pica::TexturingRegs::ProcTexFilter lut_filter;
|
u8 lut_offset0;
|
||||||
|
u8 lut_offset1;
|
||||||
|
u8 lut_offset2;
|
||||||
|
u8 lut_offset3;
|
||||||
|
u8 lod_min;
|
||||||
|
u8 lod_max;
|
||||||
} proctex;
|
} proctex;
|
||||||
|
|
||||||
bool shadow_rendering;
|
|
||||||
bool shadow_texture_orthographic;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -124,9 +132,7 @@ struct PicaFSConfigState {
|
|||||||
* two separate shaders sharing the same key.
|
* two separate shaders sharing the same key.
|
||||||
*/
|
*/
|
||||||
struct PicaFSConfig : Common::HashableStruct<PicaFSConfigState> {
|
struct PicaFSConfig : Common::HashableStruct<PicaFSConfigState> {
|
||||||
|
PicaFSConfig(const Pica::Regs& regs);
|
||||||
/// Construct a PicaFSConfig with the given Pica register configuration.
|
|
||||||
static PicaFSConfig BuildFromRegs(const Pica::Regs& regs);
|
|
||||||
|
|
||||||
bool TevStageUpdatesCombinerBufferColor(unsigned stage_index) const {
|
bool TevStageUpdatesCombinerBufferColor(unsigned stage_index) const {
|
||||||
return (stage_index < 4) && (state.combiner_buffer_input & (1 << stage_index));
|
return (stage_index < 4) && (state.combiner_buffer_input & (1 << stage_index));
|
||||||
|
Reference in New Issue
Block a user