mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-11-30 00:34:15 +01:00
Seperate Maxwell3D Stages into Shader/Pipeline
We need this to make the distinction between a shader and pipeline stage in as shader programs are bound at a different rate than that of pipeline stage resources such as UBO.
This commit is contained in:
parent
492dd47218
commit
055d315048
@ -568,7 +568,7 @@ namespace skyline::gpu::interconnect {
|
|||||||
};
|
};
|
||||||
|
|
||||||
IOVA shaderBaseIova{}; //!< The base IOVA that shaders are located at an offset from
|
IOVA shaderBaseIova{}; //!< The base IOVA that shaders are located at an offset from
|
||||||
std::array<Shader, maxwell3d::StageCount> shaders{
|
std::array<Shader, maxwell3d::ShaderStageCount> shaders{
|
||||||
Shader{ShaderCompiler::Stage::VertexA, vk::ShaderStageFlagBits::eVertex},
|
Shader{ShaderCompiler::Stage::VertexA, vk::ShaderStageFlagBits::eVertex},
|
||||||
Shader{ShaderCompiler::Stage::VertexB, vk::ShaderStageFlagBits::eVertex},
|
Shader{ShaderCompiler::Stage::VertexB, vk::ShaderStageFlagBits::eVertex},
|
||||||
Shader{ShaderCompiler::Stage::TessellationControl, vk::ShaderStageFlagBits::eTessellationControl},
|
Shader{ShaderCompiler::Stage::TessellationControl, vk::ShaderStageFlagBits::eTessellationControl},
|
||||||
@ -662,13 +662,13 @@ namespace skyline::gpu::interconnect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetShaderEnabled(maxwell3d::StageId stage, bool enabled) {
|
void SetShaderEnabled(maxwell3d::ShaderStage stage, bool enabled) {
|
||||||
auto &shader{shaders[static_cast<size_t>(stage)]};
|
auto &shader{shaders[static_cast<size_t>(stage)]};
|
||||||
shader.enabled = enabled;
|
shader.enabled = enabled;
|
||||||
shader.invalidated = true;
|
shader.invalidated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetShaderOffset(maxwell3d::StageId stage, u32 offset) {
|
void SetShaderOffset(maxwell3d::ShaderStage stage, u32 offset) {
|
||||||
auto &shader{shaders[static_cast<size_t>(stage)]};
|
auto &shader{shaders[static_cast<size_t>(stage)]};
|
||||||
shader.offset = offset;
|
shader.offset = offset;
|
||||||
shader.invalidated = true;
|
shader.invalidated = true;
|
||||||
|
@ -652,12 +652,43 @@ namespace skyline::soc::gm20b::engine::maxwell3d::type {
|
|||||||
Set = 0x150F,
|
Set = 0x150F,
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr static size_t StageCount{6}; //!< Amount of pipeline stages on Maxwell 3D
|
constexpr static size_t PipelineStageCount{5}; //!< Amount of pipeline stages on Maxwell 3D
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief All the pipeline stages that Maxwell3D supports for draws
|
* @brief All the pipeline stages that Maxwell3D supports for draws
|
||||||
*/
|
*/
|
||||||
enum class StageId {
|
enum class PipelineStage {
|
||||||
|
Vertex = 0,
|
||||||
|
TessellationControl = 1,
|
||||||
|
TessellationEvaluation = 2,
|
||||||
|
Geometry = 3,
|
||||||
|
Fragment = 4,
|
||||||
|
};
|
||||||
|
static_assert(static_cast<size_t>(PipelineStage::Fragment) + 1 == PipelineStageCount);
|
||||||
|
|
||||||
|
struct Bind {
|
||||||
|
u32 _pad0_[4];
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
u32 valid : 1;
|
||||||
|
u32 _pad1_ : 3;
|
||||||
|
u32 index : 5; //!< The index of the constant buffer in the pipeline stage to bind to
|
||||||
|
};
|
||||||
|
u32 raw;
|
||||||
|
} constantBuffer;
|
||||||
|
u32 _pad2_[3];
|
||||||
|
};
|
||||||
|
static_assert(sizeof(Bind) == (sizeof(u32) * 8));
|
||||||
|
|
||||||
|
constexpr static size_t PipelineStageConstantBufferCount{18}; //!< Maximum amount of constant buffers that can be bound to a single pipeline stage
|
||||||
|
|
||||||
|
constexpr static size_t ShaderStageCount{6}; //!< Amount of shader stages on Maxwell 3D
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief All the shader programs stages that Maxwell3D supports for draws
|
||||||
|
* @note As opposed to pipeline stages, there are two shader programs for the vertex stage
|
||||||
|
*/
|
||||||
|
enum class ShaderStage {
|
||||||
VertexA = 0,
|
VertexA = 0,
|
||||||
VertexB = 1,
|
VertexB = 1,
|
||||||
TessellationControl = 2,
|
TessellationControl = 2,
|
||||||
@ -665,7 +696,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d::type {
|
|||||||
Geometry = 4,
|
Geometry = 4,
|
||||||
Fragment = 5,
|
Fragment = 5,
|
||||||
};
|
};
|
||||||
static_assert(static_cast<size_t>(StageId::Fragment) + 1 == StageCount);
|
static_assert(static_cast<size_t>(ShaderStage::Fragment) + 1 == ShaderStageCount);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The arguments to set a shader program for a pipeline stage
|
* @brief The arguments to set a shader program for a pipeline stage
|
||||||
@ -674,7 +705,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d::type {
|
|||||||
struct {
|
struct {
|
||||||
bool enable : 1;
|
bool enable : 1;
|
||||||
u8 _pad0_ : 3;
|
u8 _pad0_ : 3;
|
||||||
StageId stage : 4;
|
ShaderStage stage : 4;
|
||||||
u32 _pad1_ : 24;
|
u32 _pad1_ : 24;
|
||||||
} info;
|
} info;
|
||||||
u32 offset; //!< Offset from the base shader memory IOVA
|
u32 offset; //!< Offset from the base shader memory IOVA
|
||||||
|
@ -428,7 +428,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
})
|
})
|
||||||
|
|
||||||
BOOST_PP_REPEAT(6, SET_SHADER_ENABLE_CALLBACK, 0)
|
BOOST_PP_REPEAT(6, SET_SHADER_ENABLE_CALLBACK, 0)
|
||||||
static_assert(type::StageCount == 6 && type::StageCount < BOOST_PP_LIMIT_REPEAT);
|
static_assert(type::ShaderStageCount == 6 && type::ShaderStageCount < BOOST_PP_LIMIT_REPEAT);
|
||||||
#undef SET_SHADER_ENABLE_CALLBACK
|
#undef SET_SHADER_ENABLE_CALLBACK
|
||||||
|
|
||||||
MAXWELL3D_CASE(vertexBeginGl, {
|
MAXWELL3D_CASE(vertexBeginGl, {
|
||||||
@ -509,13 +509,14 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
#define SET_SHADER_OFFSET_CALLBACK(z, index, data) \
|
#define SHADER_CALLBACKS(z, index, data) \
|
||||||
MAXWELL3D_ARRAY_STRUCT_CASE(setProgram, index, offset, { \
|
MAXWELL3D_ARRAY_STRUCT_CASE(setProgram, index, offset, { \
|
||||||
context.SetShaderOffset(registers.setProgram[index].info.stage, offset); \
|
context.SetShaderOffset(static_cast<type::ShaderStage>(index), offset); \
|
||||||
})
|
})
|
||||||
|
|
||||||
BOOST_PP_REPEAT(6, SET_SHADER_OFFSET_CALLBACK, 0)
|
BOOST_PP_REPEAT(6, SHADER_CALLBACKS, 0)
|
||||||
static_assert(type::StageCount == 6 && type::StageCount < BOOST_PP_LIMIT_REPEAT);
|
static_assert(type::ShaderStageCount == 6 && type::ShaderStageCount < BOOST_PP_LIMIT_REPEAT);
|
||||||
|
#undef SHADER_CALLBACKS
|
||||||
|
|
||||||
MAXWELL3D_ARRAY_CASE(firmwareCall, 4, {
|
MAXWELL3D_ARRAY_CASE(firmwareCall, 4, {
|
||||||
registers.raw[0xD00] = 1;
|
registers.raw[0xD00] = 1;
|
||||||
|
@ -278,7 +278,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
|
|
||||||
Register<0x7C0, std::array<type::Address, type::VertexBufferCount>> vertexBufferLimits; //!< A per-VBO IOVA denoting the end of the vertex buffer
|
Register<0x7C0, std::array<type::Address, type::VertexBufferCount>> vertexBufferLimits; //!< A per-VBO IOVA denoting the end of the vertex buffer
|
||||||
|
|
||||||
Register<0x800, std::array<type::SetProgramInfo, type::StageCount>> setProgram;
|
Register<0x800, std::array<type::SetProgramInfo, type::ShaderStageCount>> setProgram;
|
||||||
|
|
||||||
Register<0x8C0, u32[0x20]> firmwareCall;
|
Register<0x8C0, u32[0x20]> firmwareCall;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user