summaryrefslogtreecommitdiffstats
path: root/src/video_core/engines
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/video_core/engines/maxwell_3d.cpp37
-rw-r--r--src/video_core/engines/maxwell_3d.h51
2 files changed, 82 insertions, 6 deletions
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index d79c50919..6de07ea56 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -37,6 +37,35 @@ void Maxwell3D::InitializeRegisterDefaults() {
regs.viewport[viewport].depth_range_near = 0.0f;
regs.viewport[viewport].depth_range_far = 1.0f;
}
+ // Doom and Bomberman seems to use the uninitialized registers and just enable blend
+ // so initialize blend registers with sane values
+ regs.blend.equation_rgb = Regs::Blend::Equation::Add;
+ regs.blend.factor_source_rgb = Regs::Blend::Factor::One;
+ regs.blend.factor_dest_rgb = Regs::Blend::Factor::Zero;
+ regs.blend.equation_a = Regs::Blend::Equation::Add;
+ regs.blend.factor_source_a = Regs::Blend::Factor::One;
+ regs.blend.factor_dest_a = Regs::Blend::Factor::Zero;
+ for (std::size_t blend_index = 0; blend_index < Regs::NumRenderTargets; blend_index++) {
+ regs.independent_blend[blend_index].equation_rgb = Regs::Blend::Equation::Add;
+ regs.independent_blend[blend_index].factor_source_rgb = Regs::Blend::Factor::One;
+ regs.independent_blend[blend_index].factor_dest_rgb = Regs::Blend::Factor::Zero;
+ regs.independent_blend[blend_index].equation_a = Regs::Blend::Equation::Add;
+ regs.independent_blend[blend_index].factor_source_a = Regs::Blend::Factor::One;
+ regs.independent_blend[blend_index].factor_dest_a = Regs::Blend::Factor::Zero;
+ }
+ regs.stencil_front_op_fail = Regs::StencilOp::Keep;
+ regs.stencil_front_op_zfail = Regs::StencilOp::Keep;
+ regs.stencil_front_op_zpass = Regs::StencilOp::Keep;
+ regs.stencil_front_func_func = Regs::ComparisonOp::Always;
+ regs.stencil_front_func_mask = 0xFFFFFFFF;
+ regs.stencil_front_mask = 0xFFFFFFFF;
+ regs.stencil_two_side_enable = 1;
+ regs.stencil_back_op_fail = Regs::StencilOp::Keep;
+ regs.stencil_back_op_zfail = Regs::StencilOp::Keep;
+ regs.stencil_back_op_zpass = Regs::StencilOp::Keep;
+ regs.stencil_back_func_func = Regs::ComparisonOp::Always;
+ regs.stencil_back_func_mask = 0xFFFFFFFF;
+ regs.stencil_back_mask = 0xFFFFFFFF;
}
void Maxwell3D::CallMacroMethod(u32 method, std::vector<u32> parameters) {
@@ -92,7 +121,13 @@ void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) {
debug_context->OnEvent(Tegra::DebugContext::Event::MaxwellCommandLoaded, nullptr);
}
- regs.reg_array[method] = value;
+ if (regs.reg_array[method] != value) {
+ regs.reg_array[method] = value;
+ if (method >= MAXWELL3D_REG_INDEX(vertex_attrib_format) &&
+ method < MAXWELL3D_REG_INDEX(vertex_attrib_format) + regs.vertex_attrib_format.size()) {
+ dirty_flags.vertex_attrib_format = true;
+ }
+ }
switch (method) {
case MAXWELL3D_REG_INDEX(macros.data): {
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index 50873813e..91ca57883 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -345,6 +345,14 @@ public:
Invert = 6,
IncrWrap = 7,
DecrWrap = 8,
+ KeepOGL = 0x1E00,
+ ZeroOGL = 0,
+ ReplaceOGL = 0x1E01,
+ IncrOGL = 0x1E02,
+ DecrOGL = 0x1E03,
+ InvertOGL = 0x150A,
+ IncrWrapOGL = 0x8507,
+ DecrWrapOGL = 0x8508,
};
enum class MemoryLayout : u32 {
@@ -462,6 +470,16 @@ public:
}
};
+ struct ColorMask {
+ union {
+ u32 raw;
+ BitField<0, 4, u32> R;
+ BitField<4, 4, u32> G;
+ BitField<8, 4, u32> B;
+ BitField<12, 4, u32> A;
+ };
+ };
+
bool IsShaderConfigEnabled(std::size_t index) const {
// The VertexB is always enabled.
if (index == static_cast<std::size_t>(Regs::ShaderProgram::VertexB)) {
@@ -571,7 +589,11 @@ public:
u32 stencil_back_mask;
u32 stencil_back_func_mask;
- INSERT_PADDING_WORDS(0x13);
+ INSERT_PADDING_WORDS(0xC);
+
+ u32 color_mask_common;
+
+ INSERT_PADDING_WORDS(0x6);
u32 rt_separate_frag_data;
@@ -646,8 +668,14 @@ public:
ComparisonOp depth_test_func;
float alpha_test_ref;
ComparisonOp alpha_test_func;
-
- INSERT_PADDING_WORDS(0x9);
+ u32 draw_tfb_stride;
+ struct {
+ float r;
+ float g;
+ float b;
+ float a;
+ } blend_color;
+ INSERT_PADDING_WORDS(0x4);
struct {
u32 separate_alpha;
@@ -841,8 +869,9 @@ public:
BitField<6, 4, u32> RT;
BitField<10, 11, u32> layer;
} clear_buffers;
-
- INSERT_PADDING_WORDS(0x4B);
+ INSERT_PADDING_WORDS(0xB);
+ std::array<ColorMask, NumRenderTargets> color_mask;
+ INSERT_PADDING_WORDS(0x38);
struct {
u32 query_address_high;
@@ -983,6 +1012,12 @@ public:
State state{};
MemoryManager& memory_manager;
+ struct DirtyFlags {
+ bool vertex_attrib_format = true;
+ };
+
+ DirtyFlags dirty_flags;
+
/// Reads a register value located at the input method address
u32 GetRegisterValue(u32 method) const;
@@ -1075,6 +1110,7 @@ ASSERT_REG_POSITION(scissor_test, 0x380);
ASSERT_REG_POSITION(stencil_back_func_ref, 0x3D5);
ASSERT_REG_POSITION(stencil_back_mask, 0x3D6);
ASSERT_REG_POSITION(stencil_back_func_mask, 0x3D7);
+ASSERT_REG_POSITION(color_mask_common, 0x3E4);
ASSERT_REG_POSITION(rt_separate_frag_data, 0x3EB);
ASSERT_REG_POSITION(zeta, 0x3F8);
ASSERT_REG_POSITION(vertex_attrib_format, 0x458);
@@ -1087,6 +1123,10 @@ ASSERT_REG_POSITION(depth_write_enabled, 0x4BA);
ASSERT_REG_POSITION(alpha_test_enabled, 0x4BB);
ASSERT_REG_POSITION(d3d_cull_mode, 0x4C2);
ASSERT_REG_POSITION(depth_test_func, 0x4C3);
+ASSERT_REG_POSITION(alpha_test_ref, 0x4C4);
+ASSERT_REG_POSITION(alpha_test_func, 0x4C5);
+ASSERT_REG_POSITION(draw_tfb_stride, 0x4C6);
+ASSERT_REG_POSITION(blend_color, 0x4C7);
ASSERT_REG_POSITION(blend, 0x4CF);
ASSERT_REG_POSITION(stencil_enable, 0x4E0);
ASSERT_REG_POSITION(stencil_front_op_fail, 0x4E1);
@@ -1117,6 +1157,7 @@ ASSERT_REG_POSITION(instanced_arrays, 0x620);
ASSERT_REG_POSITION(cull, 0x646);
ASSERT_REG_POSITION(logic_op, 0x671);
ASSERT_REG_POSITION(clear_buffers, 0x674);
+ASSERT_REG_POSITION(color_mask, 0x680);
ASSERT_REG_POSITION(query, 0x6C0);
ASSERT_REG_POSITION(vertex_array[0], 0x700);
ASSERT_REG_POSITION(independent_blend, 0x780);