diff options
| author | Tony Wasserka <NeoBrainX@gmail.com> | 2014-12-16 00:32:49 +0100 | 
|---|---|---|
| committer | Tony Wasserka <NeoBrainX@gmail.com> | 2014-12-20 18:06:55 +0100 | 
| commit | 8ce1d324602001e1102648319a9281ee08a1af95 (patch) | |
| tree | acabdc7c8614235b283e6e48e13dc17a0a1a85dd /src/video_core | |
| parent | 056a8f9dfa5f3da3bc3dfc0b032283db0ff6ab15 (diff) | |
Pica/VertexShader: Remove (now) duplicated shader bytecode definitions in favor of nihstro's ones.
Diffstat (limited to 'src/video_core')
| -rw-r--r-- | src/video_core/vertex_shader.cpp | 43 | ||||
| -rw-r--r-- | src/video_core/vertex_shader.h | 209 | 
2 files changed, 30 insertions, 222 deletions
| diff --git a/src/video_core/vertex_shader.cpp b/src/video_core/vertex_shader.cpp index 477e78cfe..064a703eb 100644 --- a/src/video_core/vertex_shader.cpp +++ b/src/video_core/vertex_shader.cpp @@ -8,11 +8,18 @@  #include <core/mem_map.h> +#include <nihstro/shader_bytecode.h> +  #include "debug_utils/debug_utils.h"  #include "pica.h"  #include "vertex_shader.h" +using nihstro::Instruction; +using nihstro::RegisterType; +using nihstro::SourceRegister; +using nihstro::SwizzlePattern; +  namespace Pica {  namespace VertexShader { @@ -70,19 +77,28 @@ static void ProcessShaderCode(VertexShaderState& state) {          const Instruction& instr = *(const Instruction*)state.program_counter;          state.debug.max_offset = std::max<u32>(state.debug.max_offset, 1 + (state.program_counter - shader_memory)); -        const float24* src1_ = (instr.common.src1 < 0x10) ? state.input_register_table[instr.common.src1.GetIndex()] -                             : (instr.common.src1 < 0x20) ? &state.temporary_registers[instr.common.src1.GetIndex()].x -                             : (instr.common.src1 < 0x80) ? &shader_uniforms.f[instr.common.src1.GetIndex()].x -                             : nullptr; -        const float24* src2_ = (instr.common.src2 < 0x10) ? state.input_register_table[instr.common.src2.GetIndex()] -                             : &state.temporary_registers[instr.common.src2.GetIndex()].x; +        auto LookupSourceRegister = [&](const SourceRegister& source_reg) -> const float24* { +            switch (source_reg.GetRegisterType()) { +            case RegisterType::Input: +                return state.input_register_table[source_reg.GetIndex()]; + +            case RegisterType::Temporary: +                return &state.temporary_registers[source_reg.GetIndex()].x; + +            case RegisterType::FloatUniform: +                return &shader_uniforms.f[source_reg.GetIndex()].x; +            } +        }; +        bool is_inverted = 0 != (instr.opcode.GetInfo().subtype & Instruction::OpCodeInfo::SrcInversed); +        const float24* src1_ = LookupSourceRegister(instr.common.GetSrc1(is_inverted)); +        const float24* src2_ = LookupSourceRegister(instr.common.GetSrc2(is_inverted));          float24* dest = (instr.common.dest < 0x08) ? state.output_register_table[4*instr.common.dest.GetIndex()]                        : (instr.common.dest < 0x10) ? nullptr                        : (instr.common.dest < 0x20) ? &state.temporary_registers[instr.common.dest.GetIndex()][0]                        : nullptr;          const SwizzlePattern& swizzle = *(SwizzlePattern*)&swizzle_data[instr.common.operand_desc_id]; -        const bool negate_src1 = (swizzle.negate != 0); +        const bool negate_src1 = (swizzle.negate_src1 != 0);          float24 src1[4] = {              src1_[(int)swizzle.GetSelectorSrc1(0)], @@ -192,7 +208,9 @@ static void ProcessShaderCode(VertexShaderState& state) {                  break;              } -            case Instruction::OpCode::RET: +            // NOP is currently used as a heuristic for leaving from a function. +            // TODO: This is completely incorrect. +            case Instruction::OpCode::NOP:                  if (*state.call_stack_pointer == VertexShaderState::INVALID_ADDRESS) {                      exit_loop = true;                  } else { @@ -209,17 +227,16 @@ static void ProcessShaderCode(VertexShaderState& state) {                  _dbg_assert_(HW_GPU, state.call_stack_pointer - state.call_stack < sizeof(state.call_stack));                  *++state.call_stack_pointer = state.program_counter - shader_memory; -                // TODO: Does this offset refer to the beginning of shader memory? -                state.program_counter = &shader_memory[instr.flow_control.offset_words]; +                state.program_counter = &shader_memory[instr.flow_control.dest_offset];                  break; -            case Instruction::OpCode::FLS: -                // TODO: Do whatever needs to be done here? +            case Instruction::OpCode::END: +                // TODO                  break;              default:                  LOG_ERROR(HW_GPU, "Unhandled instruction: 0x%02x (%s): 0x%08x", -                          (int)instr.opcode.Value(), instr.GetOpCodeName().c_str(), instr.hex); +                          (int)instr.opcode.Value(), instr.opcode.GetInfo().name, instr.hex);                  break;          } diff --git a/src/video_core/vertex_shader.h b/src/video_core/vertex_shader.h index c1292fc2d..131769808 100644 --- a/src/video_core/vertex_shader.h +++ b/src/video_core/vertex_shader.h @@ -66,215 +66,6 @@ struct OutputVertex {  static_assert(std::is_pod<OutputVertex>::value, "Structure is not POD");  static_assert(sizeof(OutputVertex) == 32 * sizeof(float), "OutputVertex has invalid size"); -union Instruction { -    enum class OpCode : u32 { -        ADD = 0x0, -        DP3 = 0x1, -        DP4 = 0x2, - -        MUL = 0x8, - -        MAX = 0xC, -        MIN = 0xD, -        RCP = 0xE, -        RSQ = 0xF, - -        MOV = 0x13, - -        RET = 0x21, -        FLS = 0x22, // Flush -        CALL = 0x24, -    }; - -    std::string GetOpCodeName() const { -        std::map<OpCode, std::string> map = { -            { OpCode::ADD, "ADD" }, -            { OpCode::DP3, "DP3" }, -            { OpCode::DP4, "DP4" }, -            { OpCode::MUL, "MUL" }, -            { OpCode::MAX, "MAX" }, -            { OpCode::MIN, "MIN" }, -            { OpCode::RCP, "RCP" }, -            { OpCode::RSQ, "RSQ" }, -            { OpCode::MOV, "MOV" }, -            { OpCode::RET, "RET" }, -            { OpCode::FLS, "FLS" }, -        }; -        auto it = map.find(opcode); -        if (it == map.end()) -            return "UNK"; -        else -            return it->second; -    } - -    u32 hex; - -    BitField<0x1a, 0x6, OpCode> opcode; - -    // General notes: -    // -    // When two input registers are used, one of them uses a 5-bit index while the other -    // one uses a 7-bit index. This is because at most one floating point uniform may be used -    // as an input. - - -    // Format used e.g. by arithmetic instructions and comparisons -    // "src1" and "src2" specify register indices (i.e. indices referring to groups of 4 floats), -    // while "dest" addresses individual floats. -    union { -        BitField<0x00, 0x5, u32> operand_desc_id; - -        template<class BitFieldType> -        struct SourceRegister : BitFieldType { -            enum RegisterType { -                Input, -                Temporary, -                FloatUniform -            }; - -            RegisterType GetRegisterType() const { -                if (BitFieldType::Value() < 0x10) -                    return Input; -                else if (BitFieldType::Value() < 0x20) -                    return Temporary; -                else -                    return FloatUniform; -            } - -            int GetIndex() const { -                if (GetRegisterType() == Input) -                    return BitFieldType::Value(); -                else if (GetRegisterType() == Temporary) -                    return BitFieldType::Value() - 0x10; -                else // if (GetRegisterType() == FloatUniform) -                    return BitFieldType::Value() - 0x20; -            } - -            std::string GetRegisterName() const { -                std::map<RegisterType, std::string> type = { -                    { Input, "i" }, -                    { Temporary, "t" }, -                    { FloatUniform, "f" }, -                }; -                return type[GetRegisterType()] + std::to_string(GetIndex()); -            } -        }; - -        SourceRegister<BitField<0x07, 0x5, u32>> src2; -        SourceRegister<BitField<0x0c, 0x7, u32>> src1; - -        struct : BitField<0x15, 0x5, u32> -        { -            enum RegisterType { -                Output, -                Temporary, -                Unknown -            }; -            RegisterType GetRegisterType() const { -                if (Value() < 0x8) -                    return Output; -                else if (Value() < 0x10) -                    return Unknown; -                else -                    return Temporary; -            } -            int GetIndex() const { -                if (GetRegisterType() == Output) -                    return Value(); -                else if (GetRegisterType() == Temporary) -                    return Value() - 0x10; -                else -                    return Value(); -            } -            std::string GetRegisterName() const { -                std::map<RegisterType, std::string> type = { -                    { Output, "o" }, -                    { Temporary, "t" }, -                    { Unknown, "u" } -                }; -                return type[GetRegisterType()] + std::to_string(GetIndex()); -            } -        } dest; -    } common; - -    // Format used for flow control instructions ("if") -    union { -        BitField<0x00, 0x8, u32> num_instructions; -        BitField<0x0a, 0xc, u32> offset_words; -    } flow_control; -}; -static_assert(std::is_standard_layout<Instruction>::value, "Structure is not using standard layout!"); - -union SwizzlePattern { -    u32 hex; - -    enum class Selector : u32 { -        x = 0, -        y = 1, -        z = 2, -        w = 3 -    }; - -    Selector GetSelectorSrc1(int comp) const { -        Selector selectors[] = { -            src1_selector_0, src1_selector_1, src1_selector_2, src1_selector_3 -        }; -        return selectors[comp]; -    } - -    Selector GetSelectorSrc2(int comp) const { -        Selector selectors[] = { -            src2_selector_0, src2_selector_1, src2_selector_2, src2_selector_3 -        }; -        return selectors[comp]; -    } - -    bool DestComponentEnabled(int i) const { -        return (dest_mask & (0x8 >> i)) != 0; -    } - -    std::string SelectorToString(bool src2) const { -        std::map<Selector, std::string> map = { -            { Selector::x, "x" }, -            { Selector::y, "y" }, -            { Selector::z, "z" }, -            { Selector::w, "w" } -        }; -        std::string ret; -        for (int i = 0; i < 4; ++i) { -            ret += map.at(src2 ? GetSelectorSrc2(i) : GetSelectorSrc1(i)); -        } -        return ret; -    } - -    std::string DestMaskToString() const { -        std::string ret; -        for (int i = 0; i < 4; ++i) { -            if (!DestComponentEnabled(i)) -                ret += "_"; -            else -                ret += "xyzw"[i]; -        } -        return ret; -    } - -    // Components of "dest" that should be written to: LSB=dest.w, MSB=dest.x -    BitField< 0, 4, u32> dest_mask; - -    BitField< 4, 1, u32> negate; // negates src1 - -    BitField< 5, 2, Selector> src1_selector_3; -    BitField< 7, 2, Selector> src1_selector_2; -    BitField< 9, 2, Selector> src1_selector_1; -    BitField<11, 2, Selector> src1_selector_0; - -    BitField<14, 2, Selector> src2_selector_3; -    BitField<16, 2, Selector> src2_selector_2; -    BitField<18, 2, Selector> src2_selector_1; -    BitField<20, 2, Selector> src2_selector_0; - -    BitField<31, 1, u32> flag; // not sure what this means, maybe it's the sign? -};  void SubmitShaderMemoryChange(u32 addr, u32 value);  void SubmitSwizzleDataChange(u32 addr, u32 value); | 
