diff options
Diffstat (limited to 'src/video_core/engines')
-rw-r--r-- | src/video_core/engines/maxwell_3d.cpp | 16 | ||||
-rw-r--r-- | src/video_core/engines/maxwell_3d.h | 192 | ||||
-rw-r--r-- | src/video_core/engines/shader_bytecode.h | 27 | ||||
-rw-r--r-- | src/video_core/engines/shader_header.h | 11 |
4 files changed, 171 insertions, 75 deletions
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 1772882b2..f0a5470b9 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -34,8 +34,8 @@ void Maxwell3D::InitializeRegisterDefaults() { // Depth range near/far is not always set, but is expected to be the default 0.0f, 1.0f. This is // needed for ARMS. for (std::size_t viewport{}; viewport < Regs::NumViewports; ++viewport) { - regs.viewport[viewport].depth_range_near = 0.0f; - regs.viewport[viewport].depth_range_far = 1.0f; + regs.viewports[viewport].depth_range_near = 0.0f; + regs.viewports[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 @@ -66,6 +66,18 @@ void Maxwell3D::InitializeRegisterDefaults() { regs.stencil_back_func_func = Regs::ComparisonOp::Always; regs.stencil_back_func_mask = 0xFFFFFFFF; regs.stencil_back_mask = 0xFFFFFFFF; + // TODO(Rodrigo): Most games do not set a point size. I think this is a case of a + // register carrying a default value. Assume it's OpenGL's default (1). + regs.point_size = 1.0f; + + // TODO(bunnei): Some games do not initialize the color masks (e.g. Sonic Mania). Assuming a + // default of enabled fixes rendering here. + for (std::size_t color_mask = 0; color_mask < Regs::NumRenderTargets; color_mask++) { + regs.color_mask[color_mask].R.Assign(1); + regs.color_mask[color_mask].G.Assign(1); + regs.color_mask[color_mask].B.Assign(1); + regs.color_mask[color_mask].A.Assign(1); + } } void Maxwell3D::CallMacroMethod(u32 method, std::vector<u32> parameters) { diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 0848b7121..e44a23135 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h @@ -389,6 +389,13 @@ public: ReverseSubtract = 3, Min = 4, Max = 5, + + // These values are used by Nouveau and some games. + AddGL = 0x8006, + SubtractGL = 0x8007, + ReverseSubtractGL = 0x8008, + MinGL = 0x800a, + MaxGL = 0x800b }; enum class Factor : u32 { @@ -480,6 +487,67 @@ public: }; }; + struct ViewportTransform { + f32 scale_x; + f32 scale_y; + f32 scale_z; + f32 translate_x; + f32 translate_y; + f32 translate_z; + INSERT_PADDING_WORDS(2); + + MathUtil::Rectangle<s32> GetRect() const { + return { + GetX(), // left + GetY() + GetHeight(), // top + GetX() + GetWidth(), // right + GetY() // bottom + }; + }; + + s32 GetX() const { + return static_cast<s32>(std::max(0.0f, translate_x - std::fabs(scale_x))); + } + + s32 GetY() const { + return static_cast<s32>(std::max(0.0f, translate_y - std::fabs(scale_y))); + } + + s32 GetWidth() const { + return static_cast<s32>(translate_x + std::fabs(scale_x)) - GetX(); + } + + s32 GetHeight() const { + return static_cast<s32>(translate_y + std::fabs(scale_y)) - GetY(); + } + }; + + struct ScissorTest { + u32 enable; + union { + BitField<0, 16, u32> min_x; + BitField<16, 16, u32> max_x; + }; + union { + BitField<0, 16, u32> min_y; + BitField<16, 16, u32> max_y; + }; + u32 fill; + }; + + struct ViewPort { + union { + BitField<0, 16, u32> x; + BitField<16, 16, u32> width; + }; + union { + BitField<0, 16, u32> y; + BitField<16, 16, u32> height; + }; + float depth_range_near; + float depth_range_far; + }; + bool IsShaderConfigEnabled(std::size_t index) const { // The VertexB is always enabled. if (index == static_cast<std::size_t>(Regs::ShaderProgram::VertexB)) { @@ -505,55 +573,11 @@ public: INSERT_PADDING_WORDS(0x2E); - RenderTargetConfig rt[NumRenderTargets]; - - struct { - f32 scale_x; - f32 scale_y; - f32 scale_z; - f32 translate_x; - f32 translate_y; - f32 translate_z; - INSERT_PADDING_WORDS(2); - - MathUtil::Rectangle<s32> GetRect() const { - return { - GetX(), // left - GetY() + GetHeight(), // top - GetX() + GetWidth(), // right - GetY() // bottom - }; - }; - - s32 GetX() const { - return static_cast<s32>(std::max(0.0f, translate_x - std::fabs(scale_x))); - } - - s32 GetY() const { - return static_cast<s32>(std::max(0.0f, translate_y - std::fabs(scale_y))); - } - - s32 GetWidth() const { - return static_cast<s32>(translate_x + std::fabs(scale_x)) - GetX(); - } + std::array<RenderTargetConfig, NumRenderTargets> rt; - s32 GetHeight() const { - return static_cast<s32>(translate_y + std::fabs(scale_y)) - GetY(); - } - } viewport_transform[NumViewports]; + std::array<ViewportTransform, NumViewports> viewport_transform; - struct { - union { - BitField<0, 16, u32> x; - BitField<16, 16, u32> width; - }; - union { - BitField<0, 16, u32> y; - BitField<16, 16, u32> height; - }; - float depth_range_near; - float depth_range_far; - } viewport[NumViewports]; + std::array<ViewPort, NumViewports> viewports; INSERT_PADDING_WORDS(0x1D); @@ -566,24 +590,22 @@ public: float clear_color[4]; float clear_depth; + INSERT_PADDING_WORDS(0x3); + s32 clear_stencil; - INSERT_PADDING_WORDS(0x17); + INSERT_PADDING_WORDS(0x7); - struct { - u32 enable; - union { - BitField<0, 16, u32> min_x; - BitField<16, 16, u32> max_x; - }; - union { - BitField<0, 16, u32> min_y; - BitField<16, 16, u32> max_y; - }; - } scissor_test; + u32 polygon_offset_point_enable; + u32 polygon_offset_line_enable; + u32 polygon_offset_fill_enable; + + INSERT_PADDING_WORDS(0xD); + + std::array<ScissorTest, NumViewports> scissor_test; - INSERT_PADDING_WORDS(0x52); + INSERT_PADDING_WORDS(0x15); s32 stencil_back_func_ref; u32 stencil_back_mask; @@ -617,7 +639,16 @@ public: } } zeta; - INSERT_PADDING_WORDS(0x5B); + INSERT_PADDING_WORDS(0x41); + + union { + BitField<0, 4, u32> stencil; + BitField<4, 4, u32> unknown; + BitField<8, 4, u32> scissor; + BitField<12, 4, u32> viewport; + } clear_flags; + + INSERT_PADDING_WORDS(0x19); std::array<VertexAttribute, NumVertexAttributes> vertex_attrib_format; @@ -700,9 +731,12 @@ public: u32 stencil_front_func_mask; u32 stencil_front_mask; - INSERT_PADDING_WORDS(0x3); + INSERT_PADDING_WORDS(0x2); + + u32 frag_color_clamp; union { + BitField<0, 1, u32> y_negate; BitField<4, 1, u32> triangle_rast_flip; } screen_y_control; @@ -718,7 +752,12 @@ public: u32 zeta_enable; - INSERT_PADDING_WORDS(0x8); + union { + BitField<0, 1, u32> alpha_to_coverage; + BitField<4, 1, u32> alpha_to_one; + } multisample_control; + + INSERT_PADDING_WORDS(0x7); struct { u32 tsc_address_high; @@ -731,7 +770,11 @@ public: } } tsc; - INSERT_PADDING_WORDS(0x3); + INSERT_PADDING_WORDS(0x1); + + float polygon_offset_factor; + + INSERT_PADDING_WORDS(0x1); struct { u32 tic_address_high; @@ -756,7 +799,9 @@ public: u32 framebuffer_srgb; - INSERT_PADDING_WORDS(0x12); + float polygon_offset_units; + + INSERT_PADDING_WORDS(0x11); union { BitField<2, 1, u32> coord_origin; @@ -833,7 +878,9 @@ public: INSERT_PADDING_WORDS(0x7); - INSERT_PADDING_WORDS(0x20); + INSERT_PADDING_WORDS(0x1F); + + float polygon_offset_clamp; struct { u32 is_instanced[NumVertexArrays]; @@ -1105,12 +1152,15 @@ private: ASSERT_REG_POSITION(macros, 0x45); ASSERT_REG_POSITION(tfb_enabled, 0x1D1); ASSERT_REG_POSITION(rt, 0x200); -ASSERT_REG_POSITION(viewport_transform[0], 0x280); -ASSERT_REG_POSITION(viewport, 0x300); +ASSERT_REG_POSITION(viewport_transform, 0x280); +ASSERT_REG_POSITION(viewports, 0x300); ASSERT_REG_POSITION(vertex_buffer, 0x35D); ASSERT_REG_POSITION(clear_color[0], 0x360); ASSERT_REG_POSITION(clear_depth, 0x364); ASSERT_REG_POSITION(clear_stencil, 0x368); +ASSERT_REG_POSITION(polygon_offset_point_enable, 0x370); +ASSERT_REG_POSITION(polygon_offset_line_enable, 0x371); +ASSERT_REG_POSITION(polygon_offset_fill_enable, 0x372); ASSERT_REG_POSITION(scissor_test, 0x380); ASSERT_REG_POSITION(stencil_back_func_ref, 0x3D5); ASSERT_REG_POSITION(stencil_back_mask, 0x3D6); @@ -1118,6 +1168,7 @@ 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(clear_flags, 0x43E); ASSERT_REG_POSITION(vertex_attrib_format, 0x458); ASSERT_REG_POSITION(rt_control, 0x487); ASSERT_REG_POSITION(zeta_width, 0x48a); @@ -1141,11 +1192,14 @@ ASSERT_REG_POSITION(stencil_front_func_func, 0x4E4); ASSERT_REG_POSITION(stencil_front_func_ref, 0x4E5); ASSERT_REG_POSITION(stencil_front_func_mask, 0x4E6); ASSERT_REG_POSITION(stencil_front_mask, 0x4E7); +ASSERT_REG_POSITION(frag_color_clamp, 0x4EA); ASSERT_REG_POSITION(screen_y_control, 0x4EB); ASSERT_REG_POSITION(vb_element_base, 0x50D); ASSERT_REG_POSITION(point_size, 0x546); ASSERT_REG_POSITION(zeta_enable, 0x54E); +ASSERT_REG_POSITION(multisample_control, 0x54F); ASSERT_REG_POSITION(tsc, 0x557); +ASSERT_REG_POSITION(polygon_offset_factor, 0x55b); ASSERT_REG_POSITION(tic, 0x55D); ASSERT_REG_POSITION(stencil_two_side_enable, 0x565); ASSERT_REG_POSITION(stencil_back_op_fail, 0x566); @@ -1153,11 +1207,13 @@ ASSERT_REG_POSITION(stencil_back_op_zfail, 0x567); ASSERT_REG_POSITION(stencil_back_op_zpass, 0x568); ASSERT_REG_POSITION(stencil_back_func_func, 0x569); ASSERT_REG_POSITION(framebuffer_srgb, 0x56E); +ASSERT_REG_POSITION(polygon_offset_units, 0x56F); ASSERT_REG_POSITION(point_coord_replace, 0x581); ASSERT_REG_POSITION(code_address, 0x582); ASSERT_REG_POSITION(draw, 0x585); ASSERT_REG_POSITION(primitive_restart, 0x591); ASSERT_REG_POSITION(index_array, 0x5F2); +ASSERT_REG_POSITION(polygon_offset_clamp, 0x61F); ASSERT_REG_POSITION(instanced_arrays, 0x620); ASSERT_REG_POSITION(cull, 0x646); ASSERT_REG_POSITION(logic_op, 0x671); diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index 83a6fd875..b9faaf8e0 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h @@ -82,6 +82,8 @@ union Attribute { Position = 7, Attribute_0 = 8, Attribute_31 = 39, + ClipDistances0123 = 44, + ClipDistances4567 = 45, PointCoord = 46, // This attribute contains a tuple of (~, ~, InstanceId, VertexId) when inside a vertex // shader, and a tuple of (TessCoord.x, TessCoord.y, TessCoord.z, ~) when inside a Tess Eval @@ -153,6 +155,7 @@ enum class PredCondition : u64 { NotEqual = 5, GreaterEqual = 6, LessThanWithNan = 9, + LessEqualWithNan = 11, GreaterThanWithNan = 12, NotEqualWithNan = 13, GreaterEqualWithNan = 14, @@ -261,7 +264,7 @@ enum class FlowCondition : u64 { Fcsm_Tr = 0x1C, // TODO(bunnei): What is this used for? }; -enum class ControlCode : u64 { +enum class ConditionCode : u64 { F = 0, LT = 1, EQ = 2, @@ -365,6 +368,11 @@ enum class HalfPrecision : u64 { FMZ = 2, }; +enum class R2pMode : u64 { + Pr = 0, + Cc = 1, +}; + enum class IpaInterpMode : u64 { Linear = 0, Perspective = 1, @@ -569,7 +577,6 @@ union Instruction { BitField<39, 2, u64> tab5cb8_2; BitField<41, 3, u64> tab5c68_1; BitField<44, 2, u64> tab5c68_0; - BitField<47, 1, u64> cc; BitField<48, 1, u64> negate_b; } fmul; @@ -831,7 +838,7 @@ union Instruction { union { BitField<0, 3, u64> pred0; BitField<3, 3, u64> pred3; - BitField<8, 5, ControlCode> cc; // flag in cc + BitField<8, 5, ConditionCode> cc; // flag in cc BitField<39, 3, u64> pred39; BitField<42, 1, u64> neg_pred39; BitField<45, 4, PredOperation> op; // op with pred39 @@ -855,6 +862,12 @@ union Instruction { } hsetp2; union { + BitField<40, 1, R2pMode> mode; + BitField<41, 2, u64> byte; + BitField<20, 7, u64> immediate_mask; + } r2p; + + union { BitField<39, 3, u64> pred39; BitField<42, 1, u64> neg_pred; BitField<43, 1, u64> neg_a; @@ -1235,7 +1248,7 @@ union Instruction { BitField<60, 1, u64> is_b_gpr; BitField<59, 1, u64> is_c_gpr; BitField<20, 24, s64> smem_imm; - BitField<0, 5, ControlCode> flow_control_code; + BitField<0, 5, ConditionCode> flow_condition_code; Attribute attribute; Sampler sampler; @@ -1256,6 +1269,7 @@ public: BFE_C, BFE_R, BFE_IMM, + BFI_IMM_R, BRA, PBK, LD_A, @@ -1381,6 +1395,7 @@ public: PSETP, PSET, CSETP, + R2P_IMM, XMAD_IMM, XMAD_CR, XMAD_RC, @@ -1396,6 +1411,7 @@ public: ArithmeticHalf, ArithmeticHalfImmediate, Bfe, + Bfi, Shift, Ffma, Hfma2, @@ -1410,6 +1426,7 @@ public: HalfSetPredicate, PredicateSetPredicate, PredicateSetRegister, + RegisterSetPredicate, Conversion, Xmad, Unknown, @@ -1613,6 +1630,7 @@ private: INST("0100110000000---", Id::BFE_C, Type::Bfe, "BFE_C"), INST("0101110000000---", Id::BFE_R, Type::Bfe, "BFE_R"), INST("0011100-00000---", Id::BFE_IMM, Type::Bfe, "BFE_IMM"), + INST("0011011-11110---", Id::BFI_IMM_R, Type::Bfi, "BFI_IMM_R"), INST("0100110001000---", Id::LOP_C, Type::ArithmeticInteger, "LOP_C"), INST("0101110001000---", Id::LOP_R, Type::ArithmeticInteger, "LOP_R"), INST("0011100001000---", Id::LOP_IMM, Type::ArithmeticInteger, "LOP_IMM"), @@ -1647,6 +1665,7 @@ private: INST("0101000010001---", Id::PSET, Type::PredicateSetRegister, "PSET"), INST("0101000010010---", Id::PSETP, Type::PredicateSetPredicate, "PSETP"), INST("010100001010----", Id::CSETP, Type::PredicateSetPredicate, "CSETP"), + INST("0011100-11110---", Id::R2P_IMM, Type::RegisterSetPredicate, "R2P_IMM"), INST("0011011-00------", Id::XMAD_IMM, Type::Xmad, "XMAD_IMM"), INST("0100111---------", Id::XMAD_CR, Type::Xmad, "XMAD_CR"), INST("010100010-------", Id::XMAD_RC, Type::Xmad, "XMAD_RC"), diff --git a/src/video_core/engines/shader_header.h b/src/video_core/engines/shader_header.h index a0e015c4b..99c34649f 100644 --- a/src/video_core/engines/shader_header.h +++ b/src/video_core/engines/shader_header.h @@ -62,7 +62,16 @@ struct Header { INSERT_PADDING_BYTES(1); // ImapSystemValuesB INSERT_PADDING_BYTES(16); // ImapGenericVector[32] INSERT_PADDING_BYTES(2); // ImapColor - INSERT_PADDING_BYTES(2); // ImapSystemValuesC + union { + BitField<0, 8, u16> clip_distances; + BitField<8, 1, u16> point_sprite_s; + BitField<9, 1, u16> point_sprite_t; + BitField<10, 1, u16> fog_coordinate; + BitField<12, 1, u16> tessellation_eval_point_u; + BitField<13, 1, u16> tessellation_eval_point_v; + BitField<14, 1, u16> instance_id; + BitField<15, 1, u16> vertex_id; + }; INSERT_PADDING_BYTES(5); // ImapFixedFncTexture[10] INSERT_PADDING_BYTES(1); // ImapReserved INSERT_PADDING_BYTES(3); // OmapSystemValuesA |