citra-emu
/
citra
Archived
1
0
Fork 0

VideoCore: Split shader regs from Regs struct

This commit is contained in:
Yuri Kunde Schlesner 2017-01-28 13:03:13 -08:00
parent 8fca90b5d5
commit f7c7f422c6
9 changed files with 116 additions and 102 deletions

View File

@ -36,6 +36,7 @@ set(HEADERS
regs_lighting.h regs_lighting.h
regs_pipeline.h regs_pipeline.h
regs_rasterizer.h regs_rasterizer.h
regs_shader.h
regs_texturing.h regs_texturing.h
renderer_base.h renderer_base.h
renderer_opengl/gl_rasterizer.h renderer_opengl/gl_rasterizer.h

View File

@ -88,7 +88,7 @@ std::shared_ptr<DebugContext> g_debug_context; // TODO: Get rid of this global
namespace DebugUtils { namespace DebugUtils {
void DumpShader(const std::string& filename, const Regs::ShaderConfig& config, void DumpShader(const std::string& filename, const ShaderRegs& config,
const Shader::ShaderSetup& setup, const Shader::ShaderSetup& setup,
const RasterizerRegs::VSOutputAttributes* output_attributes) { const RasterizerRegs::VSOutputAttributes* output_attributes) {
struct StuffToWrite { struct StuffToWrite {

View File

@ -182,7 +182,7 @@ namespace DebugUtils {
#define PICA_DUMP_TEXTURES 0 #define PICA_DUMP_TEXTURES 0
#define PICA_LOG_TEV 0 #define PICA_LOG_TEV 0
void DumpShader(const std::string& filename, const Regs::ShaderConfig& config, void DumpShader(const std::string& filename, const ShaderRegs& config,
const Shader::ShaderSetup& setup, const Shader::ShaderSetup& setup,
const RasterizerRegs::VSOutputAttributes* output_attributes); const RasterizerRegs::VSOutputAttributes* output_attributes);

View File

@ -22,6 +22,7 @@
#include "video_core/regs_lighting.h" #include "video_core/regs_lighting.h"
#include "video_core/regs_pipeline.h" #include "video_core/regs_pipeline.h"
#include "video_core/regs_rasterizer.h" #include "video_core/regs_rasterizer.h"
#include "video_core/regs_shader.h"
#include "video_core/regs_texturing.h" #include "video_core/regs_texturing.h"
namespace Pica { namespace Pica {
@ -57,97 +58,8 @@ struct Regs {
FramebufferRegs framebuffer; FramebufferRegs framebuffer;
LightingRegs lighting; LightingRegs lighting;
PipelineRegs pipeline; PipelineRegs pipeline;
ShaderRegs gs;
struct ShaderConfig { ShaderRegs vs;
BitField<0, 16, u32> bool_uniforms;
union {
BitField<0, 8, u32> x;
BitField<8, 8, u32> y;
BitField<16, 8, u32> z;
BitField<24, 8, u32> w;
} int_uniforms[4];
INSERT_PADDING_WORDS(0x4);
union {
// Number of input attributes to shader unit - 1
BitField<0, 4, u32> max_input_attribute_index;
};
// Offset to shader program entry point (in words)
BitField<0, 16, u32> main_offset;
/// Maps input attributes to registers. 4-bits per attribute, specifying a register index
u32 input_attribute_to_register_map_low;
u32 input_attribute_to_register_map_high;
unsigned int GetRegisterForAttribute(unsigned int attribute_index) const {
u64 map = ((u64)input_attribute_to_register_map_high << 32) |
(u64)input_attribute_to_register_map_low;
return (map >> (attribute_index * 4)) & 0b1111;
}
BitField<0, 16, u32> output_mask;
// 0x28E, CODETRANSFER_END
INSERT_PADDING_WORDS(0x2);
struct {
enum Format : u32 {
FLOAT24 = 0,
FLOAT32 = 1,
};
bool IsFloat32() const {
return format == FLOAT32;
}
union {
// Index of the next uniform to write to
// TODO: ctrulib uses 8 bits for this, however that seems to yield lots of invalid
// indices
// TODO: Maybe the uppermost index is for the geometry shader? Investigate!
BitField<0, 7, u32> index;
BitField<31, 1, Format> format;
};
// Writing to these registers sets the current uniform.
u32 set_value[8];
} uniform_setup;
INSERT_PADDING_WORDS(0x2);
struct {
// Offset of the next instruction to write code to.
// Incremented with each instruction write.
u32 offset;
// Writing to these registers sets the "current" word in the shader program.
u32 set_word[8];
} program;
INSERT_PADDING_WORDS(0x1);
// This register group is used to load an internal table of swizzling patterns,
// which are indexed by each shader instruction to specify vector component swizzling.
struct {
// Offset of the next swizzle pattern to write code to.
// Incremented with each instruction write.
u32 offset;
// Writing to these registers sets the current swizzle pattern in the table.
u32 set_word[8];
} swizzle_patterns;
INSERT_PADDING_WORDS(0x2);
};
ShaderConfig gs;
ShaderConfig vs;
INSERT_PADDING_WORDS(0x20); INSERT_PADDING_WORDS(0x20);
// Map register indices to names readable by humans // Map register indices to names readable by humans
@ -247,9 +159,6 @@ ASSERT_REG_POSITION(vs, 0x2b0);
#undef ASSERT_REG_POSITION #undef ASSERT_REG_POSITION
#endif // !defined(_MSC_VER) #endif // !defined(_MSC_VER)
static_assert(sizeof(Regs::ShaderConfig) == 0x30 * sizeof(u32),
"ShaderConfig structure has incorrect size");
// The total number of registers is chosen arbitrarily, but let's make sure it's not some odd value // The total number of registers is chosen arbitrarily, but let's make sure it's not some odd value
// anyway. // anyway.
static_assert(sizeof(Regs) <= 0x300 * sizeof(u32), static_assert(sizeof(Regs) <= 0x300 * sizeof(u32),

View File

@ -0,0 +1,104 @@
// Copyright 2017 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <array>
#include "common/bit_field.h"
#include "common/common_funcs.h"
#include "common/common_types.h"
namespace Pica {
struct ShaderRegs {
BitField<0, 16, u32> bool_uniforms;
union {
BitField<0, 8, u32> x;
BitField<8, 8, u32> y;
BitField<16, 8, u32> z;
BitField<24, 8, u32> w;
} int_uniforms[4];
INSERT_PADDING_WORDS(0x4);
union {
// Number of input attributes to shader unit - 1
BitField<0, 4, u32> max_input_attribute_index;
};
// Offset to shader program entry point (in words)
BitField<0, 16, u32> main_offset;
/// Maps input attributes to registers. 4-bits per attribute, specifying a register index
u32 input_attribute_to_register_map_low;
u32 input_attribute_to_register_map_high;
unsigned int GetRegisterForAttribute(unsigned int attribute_index) const {
u64 map = ((u64)input_attribute_to_register_map_high << 32) |
(u64)input_attribute_to_register_map_low;
return (map >> (attribute_index * 4)) & 0b1111;
}
BitField<0, 16, u32> output_mask;
// 0x28E, CODETRANSFER_END
INSERT_PADDING_WORDS(0x2);
struct {
enum Format : u32 {
FLOAT24 = 0,
FLOAT32 = 1,
};
bool IsFloat32() const {
return format == FLOAT32;
}
union {
// Index of the next uniform to write to
// TODO: ctrulib uses 8 bits for this, however that seems to yield lots of invalid
// indices
// TODO: Maybe the uppermost index is for the geometry shader? Investigate!
BitField<0, 7, u32> index;
BitField<31, 1, Format> format;
};
// Writing to these registers sets the current uniform.
u32 set_value[8];
} uniform_setup;
INSERT_PADDING_WORDS(0x2);
struct {
// Offset of the next instruction to write code to.
// Incremented with each instruction write.
u32 offset;
// Writing to these registers sets the "current" word in the shader program.
u32 set_word[8];
} program;
INSERT_PADDING_WORDS(0x1);
// This register group is used to load an internal table of swizzling patterns,
// which are indexed by each shader instruction to specify vector component swizzling.
struct {
// Offset of the next swizzle pattern to write code to.
// Incremented with each instruction write.
u32 offset;
// Writing to these registers sets the current swizzle pattern in the table.
u32 set_word[8];
} swizzle_patterns;
INSERT_PADDING_WORDS(0x2);
};
static_assert(sizeof(ShaderRegs) == 0x30 * sizeof(u32), "ShaderRegs struct has incorrect size");
} // namespace Pica

View File

@ -66,7 +66,7 @@ OutputVertex OutputVertex::FromAttributeBuffer(const RasterizerRegs& regs, Attri
return ret; return ret;
} }
void UnitState::LoadInput(const Regs::ShaderConfig& config, const AttributeBuffer& input) { void UnitState::LoadInput(const ShaderRegs& config, const AttributeBuffer& input) {
const unsigned max_attribute = config.max_input_attribute_index; const unsigned max_attribute = config.max_input_attribute_index;
for (unsigned attr = 0; attr <= max_attribute; ++attr) { for (unsigned attr = 0; attr <= max_attribute; ++attr) {
@ -75,7 +75,7 @@ void UnitState::LoadInput(const Regs::ShaderConfig& config, const AttributeBuffe
} }
} }
void UnitState::WriteOutput(const Regs::ShaderConfig& config, AttributeBuffer& output) { void UnitState::WriteOutput(const ShaderRegs& config, AttributeBuffer& output) {
unsigned int output_i = 0; unsigned int output_i = 0;
for (unsigned int reg : Common::BitSet<u32>(config.output_mask)) { for (unsigned int reg : Common::BitSet<u32>(config.output_mask)) {
output.attr[output_i++] = registers.output[reg]; output.attr[output_i++] = registers.output[reg];

View File

@ -116,9 +116,9 @@ struct UnitState {
* @param config Shader configuration registers corresponding to the unit. * @param config Shader configuration registers corresponding to the unit.
* @param input Attribute buffer to load into the input registers. * @param input Attribute buffer to load into the input registers.
*/ */
void LoadInput(const Regs::ShaderConfig& config, const AttributeBuffer& input); void LoadInput(const ShaderRegs& config, const AttributeBuffer& input);
void WriteOutput(const Regs::ShaderConfig& config, AttributeBuffer& output); void WriteOutput(const ShaderRegs& config, AttributeBuffer& output);
}; };
struct ShaderSetup { struct ShaderSetup {

View File

@ -669,7 +669,7 @@ void InterpreterEngine::Run(const ShaderSetup& setup, UnitState& state) const {
DebugData<true> InterpreterEngine::ProduceDebugInfo(const ShaderSetup& setup, DebugData<true> InterpreterEngine::ProduceDebugInfo(const ShaderSetup& setup,
const AttributeBuffer& input, const AttributeBuffer& input,
const Regs::ShaderConfig& config) const { const ShaderRegs& config) const {
UnitState state; UnitState state;
DebugData<true> debug_data; DebugData<true> debug_data;

View File

@ -23,7 +23,7 @@ public:
* @return Debug information for this shader with regards to the given vertex * @return Debug information for this shader with regards to the given vertex
*/ */
DebugData<true> ProduceDebugInfo(const ShaderSetup& setup, const AttributeBuffer& input, DebugData<true> ProduceDebugInfo(const ShaderSetup& setup, const AttributeBuffer& input,
const Regs::ShaderConfig& config) const; const ShaderRegs& config) const;
}; };
} // namespace } // namespace