/ src / video_core / pica / regs_shader.h
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