diff options
author | Yuri Kunde Schlesner <yuriks@yuriks.net> | 2016-12-17 05:45:57 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-12-17 05:45:57 +0100 |
commit | 2ca548bbe52bb72cdd269893571b92ad185107a5 (patch) | |
tree | 3200dcfb8b0f3afe4010a141f33f7693b9f7c938 /src/video_core/shader/shader.h | |
parent | Merge pull request #2303 from freiro/citra-qt_missing_sdl2_dll (diff) | |
parent | VideoCore/Shader: Extract DebugData out from UnitState (diff) | |
download | yuzu-2ca548bbe52bb72cdd269893571b92ad185107a5.tar yuzu-2ca548bbe52bb72cdd269893571b92ad185107a5.tar.gz yuzu-2ca548bbe52bb72cdd269893571b92ad185107a5.tar.bz2 yuzu-2ca548bbe52bb72cdd269893571b92ad185107a5.tar.lz yuzu-2ca548bbe52bb72cdd269893571b92ad185107a5.tar.xz yuzu-2ca548bbe52bb72cdd269893571b92ad185107a5.tar.zst yuzu-2ca548bbe52bb72cdd269893571b92ad185107a5.zip |
Diffstat (limited to 'src/video_core/shader/shader.h')
-rw-r--r-- | src/video_core/shader/shader.h | 199 |
1 files changed, 10 insertions, 189 deletions
diff --git a/src/video_core/shader/shader.h b/src/video_core/shader/shader.h index 0111d8c0f..2b07759b9 100644 --- a/src/video_core/shader/shader.h +++ b/src/video_core/shader/shader.h @@ -8,8 +8,6 @@ #include <cstddef> #include <memory> #include <type_traits> -#include <vector> -#include <boost/container/static_vector.hpp> #include <nihstro/shader_bytecode.h> #include "common/assert.h" #include "common/common_funcs.h" @@ -17,6 +15,7 @@ #include "common/vector_math.h" #include "video_core/pica.h" #include "video_core/pica_types.h" +#include "video_core/shader/debug_data.h" using nihstro::RegisterType; using nihstro::SourceRegister; @@ -89,183 +88,12 @@ struct OutputRegisters { }; static_assert(std::is_pod<OutputRegisters>::value, "Structure is not POD"); -// Helper structure used to keep track of data useful for inspection of shader emulation -template <bool full_debugging> -struct DebugData; - -template <> -struct DebugData<false> { - // TODO: Hide these behind and interface and move them to DebugData<true> - u32 max_offset; // maximum program counter ever reached - u32 max_opdesc_id; // maximum swizzle pattern index ever used -}; - -template <> -struct DebugData<true> { - // Records store the input and output operands of a particular instruction. - struct Record { - enum Type { - // Floating point arithmetic operands - SRC1 = 0x1, - SRC2 = 0x2, - SRC3 = 0x4, - - // Initial and final output operand value - DEST_IN = 0x8, - DEST_OUT = 0x10, - - // Current and next instruction offset (in words) - CUR_INSTR = 0x20, - NEXT_INSTR = 0x40, - - // Output address register value - ADDR_REG_OUT = 0x80, - - // Result of a comparison instruction - CMP_RESULT = 0x100, - - // Input values for conditional flow control instructions - COND_BOOL_IN = 0x200, - COND_CMP_IN = 0x400, - - // Input values for a loop - LOOP_INT_IN = 0x800, - }; - - Math::Vec4<float24> src1; - Math::Vec4<float24> src2; - Math::Vec4<float24> src3; - - Math::Vec4<float24> dest_in; - Math::Vec4<float24> dest_out; - - s32 address_registers[2]; - bool conditional_code[2]; - bool cond_bool; - bool cond_cmp[2]; - Math::Vec4<u8> loop_int; - - u32 instruction_offset; - u32 next_instruction; - - // set of enabled fields (as a combination of Type flags) - unsigned mask = 0; - }; - - u32 max_offset; // maximum program counter ever reached - u32 max_opdesc_id; // maximum swizzle pattern index ever used - - // List of records for each executed shader instruction - std::vector<DebugData<true>::Record> records; -}; - -// Type alias for better readability -using DebugDataRecord = DebugData<true>::Record; - -// Helper function to set a DebugData<true>::Record field based on the template enum parameter. -template <DebugDataRecord::Type type, typename ValueType> -inline void SetField(DebugDataRecord& record, ValueType value); - -template <> -inline void SetField<DebugDataRecord::SRC1>(DebugDataRecord& record, float24* value) { - record.src1.x = value[0]; - record.src1.y = value[1]; - record.src1.z = value[2]; - record.src1.w = value[3]; -} - -template <> -inline void SetField<DebugDataRecord::SRC2>(DebugDataRecord& record, float24* value) { - record.src2.x = value[0]; - record.src2.y = value[1]; - record.src2.z = value[2]; - record.src2.w = value[3]; -} - -template <> -inline void SetField<DebugDataRecord::SRC3>(DebugDataRecord& record, float24* value) { - record.src3.x = value[0]; - record.src3.y = value[1]; - record.src3.z = value[2]; - record.src3.w = value[3]; -} - -template <> -inline void SetField<DebugDataRecord::DEST_IN>(DebugDataRecord& record, float24* value) { - record.dest_in.x = value[0]; - record.dest_in.y = value[1]; - record.dest_in.z = value[2]; - record.dest_in.w = value[3]; -} - -template <> -inline void SetField<DebugDataRecord::DEST_OUT>(DebugDataRecord& record, float24* value) { - record.dest_out.x = value[0]; - record.dest_out.y = value[1]; - record.dest_out.z = value[2]; - record.dest_out.w = value[3]; -} - -template <> -inline void SetField<DebugDataRecord::ADDR_REG_OUT>(DebugDataRecord& record, s32* value) { - record.address_registers[0] = value[0]; - record.address_registers[1] = value[1]; -} - -template <> -inline void SetField<DebugDataRecord::CMP_RESULT>(DebugDataRecord& record, bool* value) { - record.conditional_code[0] = value[0]; - record.conditional_code[1] = value[1]; -} - -template <> -inline void SetField<DebugDataRecord::COND_BOOL_IN>(DebugDataRecord& record, bool value) { - record.cond_bool = value; -} - -template <> -inline void SetField<DebugDataRecord::COND_CMP_IN>(DebugDataRecord& record, bool* value) { - record.cond_cmp[0] = value[0]; - record.cond_cmp[1] = value[1]; -} - -template <> -inline void SetField<DebugDataRecord::LOOP_INT_IN>(DebugDataRecord& record, Math::Vec4<u8> value) { - record.loop_int = value; -} - -template <> -inline void SetField<DebugDataRecord::CUR_INSTR>(DebugDataRecord& record, u32 value) { - record.instruction_offset = value; -} - -template <> -inline void SetField<DebugDataRecord::NEXT_INSTR>(DebugDataRecord& record, u32 value) { - record.next_instruction = value; -} - -// Helper function to set debug information on the current shader iteration. -template <DebugDataRecord::Type type, typename ValueType> -inline void Record(DebugData<false>& debug_data, u32 offset, ValueType value) { - // Debugging disabled => nothing to do -} - -template <DebugDataRecord::Type type, typename ValueType> -inline void Record(DebugData<true>& debug_data, u32 offset, ValueType value) { - if (offset >= debug_data.records.size()) - debug_data.records.resize(offset + 1); - - SetField<type, ValueType>(debug_data.records[offset], value); - debug_data.records[offset].mask |= type; -} - /** * This structure contains the state information that needs to be unique for a shader unit. The 3DS * has four shader units that process shaders in parallel. At the present, Citra only implements a * single shader unit that processes all shaders serially. Putting the state information in a struct * here will make it easier for us to parallelize the shader processing later. */ -template <bool Debug> struct UnitState { struct Registers { // The registers are accessed by the shader JIT using SSE instructions, and are therefore @@ -283,8 +111,6 @@ struct UnitState { // TODO: How many bits do these actually have? s32 address_registers[3]; - DebugData<Debug> debug; - static size_t InputOffset(const SourceRegister& reg) { switch (reg.GetRegisterType()) { case RegisterType::Input: @@ -332,21 +158,16 @@ struct ShaderSetup { std::array<Math::Vec4<u8>, 4> i; } uniforms; - static size_t UniformOffset(RegisterType type, unsigned index) { - switch (type) { - case RegisterType::FloatUniform: - return offsetof(ShaderSetup, uniforms.f) + index * sizeof(Math::Vec4<float24>); - - case RegisterType::BoolUniform: - return offsetof(ShaderSetup, uniforms.b) + index * sizeof(bool); + static size_t GetFloatUniformOffset(unsigned index) { + return offsetof(ShaderSetup, uniforms.f) + index * sizeof(Math::Vec4<float24>); + } - case RegisterType::IntUniform: - return offsetof(ShaderSetup, uniforms.i) + index * sizeof(Math::Vec4<u8>); + static size_t GetBoolUniformOffset(unsigned index) { + return offsetof(ShaderSetup, uniforms.b) + index * sizeof(bool); + } - default: - UNREACHABLE(); - return 0; - } + static size_t GetIntUniformOffset(unsigned index) { + return offsetof(ShaderSetup, uniforms.i) + index * sizeof(Math::Vec4<u8>); } std::array<u32, 1024> program_code; @@ -364,7 +185,7 @@ struct ShaderSetup { * @param input Input vertex into the shader * @param num_attributes The number of vertex shader attributes */ - void Run(UnitState<false>& state, const InputVertex& input, int num_attributes); + void Run(UnitState& state, const InputVertex& input, int num_attributes); /** * Produce debug information based on the given shader and input vertex |