VideoCore: Split shader regs from Regs struct
This commit is contained in:
parent
8fca90b5d5
commit
f7c7f422c6
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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
|
|
@ -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];
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Reference in New Issue