regs_shader.h
1 // Copyright 2017 Citra Emulator Project 2 // Licensed under GPLv2 or any later version 3 // Refer to the license.txt file included. 4 5 #pragma once 6 7 #include "common/bit_field.h" 8 #include "common/common_funcs.h" 9 #include "common/common_types.h" 10 #include "common/vector_math.h" 11 12 namespace Pica { 13 14 struct ShaderRegs { 15 BitField<0, 16, u32> bool_uniforms; 16 17 union { 18 BitField<0, 8, u32> x; 19 BitField<8, 8, u32> y; 20 BitField<16, 8, u32> z; 21 BitField<24, 8, u32> w; 22 } int_uniforms[4]; 23 24 Common::Vec4<u8> GetIntUniform(u32 index) const { 25 const auto& values = int_uniforms[index]; 26 return Common::MakeVec<u8>(values.x, values.y, values.z, values.w); 27 } 28 29 INSERT_PADDING_WORDS(0x4); 30 31 enum ShaderMode { 32 GS = 0x08, 33 VS = 0xA0, 34 }; 35 36 union { 37 // Number of input attributes to shader unit - 1 38 u32 input_buffer_config; 39 BitField<0, 4, u32> max_input_attribute_index; 40 BitField<8, 8, u32> input_to_uniform; 41 BitField<24, 8, ShaderMode> shader_mode; 42 }; 43 44 // Offset to shader program entry point (in words) 45 BitField<0, 16, u32> main_offset; 46 47 /// Maps input attributes to registers. 4-bits per attribute, specifying a register index 48 u32 input_attribute_to_register_map_low; 49 u32 input_attribute_to_register_map_high; 50 51 u32 GetRegisterForAttribute(std::size_t attribute_index) const { 52 const u64 map = (static_cast<u64>(input_attribute_to_register_map_high) << 32) | 53 static_cast<u64>(input_attribute_to_register_map_low); 54 return static_cast<u32>((map >> (attribute_index * 4)) & 0b1111); 55 } 56 57 BitField<0, 16, u32> output_mask; 58 59 // 0x28E, CODETRANSFER_END 60 INSERT_PADDING_WORDS(0x2); 61 62 struct { 63 enum class Format : u32 { 64 Float24 = 0, 65 Float32 = 1, 66 }; 67 68 bool IsFloat32() const { 69 return format == Format::Float32; 70 } 71 72 union { 73 // Index of the next uniform to write to 74 // TODO: ctrulib uses 8 bits for this, however that seems to yield lots of invalid 75 // indices 76 // TODO: Maybe the uppermost index is for the geometry shader? Investigate! 77 BitField<0, 7, u32> index; 78 BitField<31, 1, Format> format; 79 }; 80 81 // Writing to these registers sets the current uniform. 82 u32 set_value[8]; 83 84 } uniform_setup; 85 86 INSERT_PADDING_WORDS(0x2); 87 88 struct { 89 // Offset of the next instruction to write code to. 90 // Incremented with each instruction write. 91 u32 offset; 92 93 // Writing to these registers sets the "current" word in the shader program. 94 u32 set_word[8]; 95 } program; 96 97 INSERT_PADDING_WORDS(0x1); 98 99 // This register group is used to load an internal table of swizzling patterns, 100 // which are indexed by each shader instruction to specify vector component swizzling. 101 struct { 102 // Offset of the next swizzle pattern to write code to. 103 // Incremented with each instruction write. 104 u32 offset; 105 106 // Writing to these registers sets the current swizzle pattern in the table. 107 u32 set_word[8]; 108 } swizzle_patterns; 109 110 INSERT_PADDING_WORDS(0x2); 111 }; 112 113 static_assert(sizeof(ShaderRegs) == 0x30 * sizeof(u32), "ShaderRegs struct has incorrect size"); 114 115 } // namespace Pica