diff options
Diffstat (limited to 'src/video_core/engines')
-rw-r--r-- | src/video_core/engines/maxwell_3d.cpp | 32 | ||||
-rw-r--r-- | src/video_core/engines/maxwell_3d.h | 10 | ||||
-rw-r--r-- | src/video_core/engines/shader_bytecode.h | 26 | ||||
-rw-r--r-- | src/video_core/engines/shader_header.h | 2 |
4 files changed, 64 insertions, 6 deletions
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index b19b3a75a..a388b3944 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -37,6 +37,7 @@ void Maxwell3D::InitializeRegisterDefaults() { 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 regs.blend.equation_rgb = Regs::Blend::Equation::Add; @@ -66,6 +67,7 @@ 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; @@ -78,6 +80,9 @@ void Maxwell3D::InitializeRegisterDefaults() { regs.color_mask[color_mask].B.Assign(1); regs.color_mask[color_mask].A.Assign(1); } + + // Commercial games seem to assume this value is enabled and nouveau sets this value manually. + regs.rt_separate_frag_data = 1; } void Maxwell3D::CallMacroMethod(u32 method, std::vector<u32> parameters) { @@ -135,6 +140,33 @@ void Maxwell3D::CallMethod(const GPU::MethodCall& method_call) { if (regs.reg_array[method_call.method] != method_call.argument) { regs.reg_array[method_call.method] = method_call.argument; + // Color buffers + constexpr u32 first_rt_reg = MAXWELL3D_REG_INDEX(rt); + constexpr u32 registers_per_rt = sizeof(regs.rt[0]) / sizeof(u32); + if (method_call.method >= first_rt_reg && + method_call.method < first_rt_reg + registers_per_rt * Regs::NumRenderTargets) { + const std::size_t rt_index = (method_call.method - first_rt_reg) / registers_per_rt; + dirty_flags.color_buffer |= 1u << static_cast<u32>(rt_index); + } + + // Zeta buffer + constexpr u32 registers_in_zeta = sizeof(regs.zeta) / sizeof(u32); + if (method_call.method == MAXWELL3D_REG_INDEX(zeta_enable) || + method_call.method == MAXWELL3D_REG_INDEX(zeta_width) || + method_call.method == MAXWELL3D_REG_INDEX(zeta_height) || + (method_call.method >= MAXWELL3D_REG_INDEX(zeta) && + method_call.method < MAXWELL3D_REG_INDEX(zeta) + registers_in_zeta)) { + dirty_flags.zeta_buffer = true; + } + + // Shader + constexpr u32 shader_registers_count = + sizeof(regs.shader_config[0]) * Regs::MaxShaderProgram / sizeof(u32); + if (method_call.method >= MAXWELL3D_REG_INDEX(shader_config[0]) && + method_call.method < MAXWELL3D_REG_INDEX(shader_config[0]) + shader_registers_count) { + dirty_flags.shaders = true; + } + // Vertex format if (method_call.method >= MAXWELL3D_REG_INDEX(vertex_attrib_format) && method_call.method < diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 25bb7604a..1f76aa670 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h @@ -164,6 +164,7 @@ public: return 3; default: UNREACHABLE(); + return 1; } } @@ -871,6 +872,7 @@ public: return 4; } UNREACHABLE(); + return 1; } GPUVAddr StartAddress() const { @@ -1087,10 +1089,18 @@ public: MemoryManager& memory_manager; struct DirtyFlags { + u8 color_buffer = 0xFF; + bool zeta_buffer = true; + + bool shaders = true; + bool vertex_attrib_format = true; u32 vertex_array = 0xFFFFFFFF; void OnMemoryWrite() { + color_buffer = 0xFF; + zeta_buffer = true; + shaders = true; vertex_array = 0xFFFFFFFF; } }; diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index 5ea094e64..9989825f8 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h @@ -208,6 +208,8 @@ enum class UniformType : u64 { SignedShort = 3, Single = 4, Double = 5, + Quad = 6, + UnsignedQuad = 7, }; enum class StoreType : u64 { @@ -397,6 +399,10 @@ struct IpaMode { bool operator!=(const IpaMode& a) const { return !operator==(a); } + bool operator<(const IpaMode& a) const { + return std::tie(interpolation_mode, sampling_mode) < + std::tie(a.interpolation_mode, a.sampling_mode); + } }; enum class SystemVariable : u64 { @@ -575,7 +581,7 @@ union Instruction { union { BitField<39, 2, u64> tab5cb8_2; - BitField<41, 3, u64> tab5c68_1; + BitField<41, 3, u64> postfactor; BitField<44, 2, u64> tab5c68_0; BitField<48, 1, u64> negate_b; } fmul; @@ -609,7 +615,7 @@ union Instruction { BitField<31, 1, u64> negate_b; BitField<30, 1, u64> abs_b; - BitField<47, 2, HalfType> type_b; + BitField<28, 2, HalfType> type_b; BitField<35, 2, HalfType> type_c; } alu_half; @@ -644,6 +650,7 @@ union Instruction { BitField<37, 2, HalfPrecision> precision; BitField<32, 1, u64> saturate; + BitField<31, 1, u64> negate_b; BitField<30, 1, u64> negate_c; BitField<35, 2, HalfType> type_c; } rr; @@ -780,6 +787,12 @@ union Instruction { } st_l; union { + BitField<48, 3, UniformType> type; + BitField<46, 2, u64> cache_mode; + BitField<20, 24, s64> immediate_offset; + } ldg; + + union { BitField<0, 3, u64> pred0; BitField<3, 3, u64> pred3; BitField<7, 1, u64> abs_a; @@ -1049,7 +1062,7 @@ union Instruction { BitField<49, 1, u64> nodep_flag; BitField<50, 3, u64> component_mask_selector; BitField<53, 4, u64> texture_info; - BitField<60, 1, u64> fp32_flag; + BitField<59, 1, u64> fp32_flag; TextureType GetTextureType() const { // The TEXS instruction has a weird encoding for the texture type. @@ -1065,6 +1078,7 @@ union Instruction { LOG_CRITICAL(HW_GPU, "Unhandled texture_info: {}", static_cast<u32>(texture_info.Value())); UNREACHABLE(); + return TextureType::Texture1D; } TextureProcessMode GetTextureProcessMode() const { @@ -1145,6 +1159,7 @@ union Instruction { LOG_CRITICAL(HW_GPU, "Unhandled texture_info: {}", static_cast<u32>(texture_info.Value())); UNREACHABLE(); + return TextureType::Texture1D; } TextureProcessMode GetTextureProcessMode() const { @@ -1429,6 +1444,7 @@ public: PredicateSetRegister, RegisterSetPredicate, Conversion, + Video, Xmad, Unknown, }; @@ -1560,8 +1576,8 @@ private: INST("11100000--------", Id::IPA, Type::Trivial, "IPA"), INST("1111101111100---", Id::OUT_R, Type::Trivial, "OUT_R"), INST("1110111111010---", Id::ISBERD, Type::Trivial, "ISBERD"), - INST("01011111--------", Id::VMAD, Type::Trivial, "VMAD"), - INST("0101000011110---", Id::VSETP, Type::Trivial, "VSETP"), + INST("01011111--------", Id::VMAD, Type::Video, "VMAD"), + INST("0101000011110---", Id::VSETP, Type::Video, "VSETP"), INST("0011001-1-------", Id::FFMA_IMM, Type::Ffma, "FFMA_IMM"), INST("010010011-------", Id::FFMA_CR, Type::Ffma, "FFMA_CR"), INST("010100011-------", Id::FFMA_RC, Type::Ffma, "FFMA_RC"), diff --git a/src/video_core/engines/shader_header.h b/src/video_core/engines/shader_header.h index 99c34649f..cf2b76ff6 100644 --- a/src/video_core/engines/shader_header.h +++ b/src/video_core/engines/shader_header.h @@ -106,7 +106,7 @@ struct Header { } ps; }; - u64 GetLocalMemorySize() { + u64 GetLocalMemorySize() const { return (common1.shader_local_memory_low_size | (common2.shader_local_memory_high_size << 24)); } |