mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-11-23 11:39:17 +01:00
Introduce Maxwell 3D shader state
Simple state holder that hashes the stored shader and reads it into a buffer
This commit is contained in:
parent
6865f0bdaf
commit
405d26fc22
@ -12,6 +12,7 @@
|
|||||||
#include <gpu.h>
|
#include <gpu.h>
|
||||||
#include <vulkan/vulkan_core.h>
|
#include <vulkan/vulkan_core.h>
|
||||||
#include "pipeline_state.h"
|
#include "pipeline_state.h"
|
||||||
|
#include "shader_state.h"
|
||||||
#include "soc/gm20b/engines/maxwell/types.h"
|
#include "soc/gm20b/engines/maxwell/types.h"
|
||||||
|
|
||||||
namespace skyline::gpu::interconnect::maxwell3d {
|
namespace skyline::gpu::interconnect::maxwell3d {
|
||||||
@ -753,6 +754,18 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Global Shader Config State */
|
||||||
|
void GlobalShaderConfigState::EngineRegisters::DirtyBind(DirtyManager &manager, dirty::Handle handle) const {
|
||||||
|
manager.Bind(handle, postVtgShaderAttributeSkipMask, bindlessTexture);
|
||||||
|
}
|
||||||
|
|
||||||
|
GlobalShaderConfigState::GlobalShaderConfigState(const EngineRegisters &engine) : engine{engine} {}
|
||||||
|
|
||||||
|
void GlobalShaderConfigState::Update(PackedPipelineState &packedState) {
|
||||||
|
packedState.postVtgShaderAttributeSkipMask = engine.postVtgShaderAttributeSkipMask;
|
||||||
|
packedState.bindlessTextureConstantBufferSlotSelect = engine.bindlessTexture.constantBufferSlotSelect;
|
||||||
|
}
|
||||||
|
|
||||||
/* Pipeline State */
|
/* Pipeline State */
|
||||||
void PipelineState::EngineRegisters::DirtyBind(DirtyManager &manager, dirty::Handle handle) const {
|
void PipelineState::EngineRegisters::DirtyBind(DirtyManager &manager, dirty::Handle handle) const {
|
||||||
auto bindFunc{[&](auto ®s) { regs.DirtyBind(manager, handle); }};
|
auto bindFunc{[&](auto ®s) { regs.DirtyBind(manager, handle); }};
|
||||||
@ -764,6 +777,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
|||||||
|
|
||||||
PipelineState::PipelineState(dirty::Handle dirtyHandle, DirtyManager &manager, const EngineRegisters &engine)
|
PipelineState::PipelineState(dirty::Handle dirtyHandle, DirtyManager &manager, const EngineRegisters &engine)
|
||||||
: engine{manager, dirtyHandle, engine},
|
: engine{manager, dirtyHandle, engine},
|
||||||
|
shaders{util::MergeInto<dirty::ManualDirtyState<IndividualShaderState>, engine::PipelineCount>(manager, engine.shadersRegisters, util::IncrementingT<u8>{})},
|
||||||
colorRenderTargets{util::MergeInto<dirty::ManualDirtyState<ColorRenderTargetState>, engine::ColorTargetCount>(manager, engine.colorRenderTargetsRegisters, util::IncrementingT<size_t>{})},
|
colorRenderTargets{util::MergeInto<dirty::ManualDirtyState<ColorRenderTargetState>, engine::ColorTargetCount>(manager, engine.colorRenderTargetsRegisters, util::IncrementingT<size_t>{})},
|
||||||
depthRenderTarget{manager, engine.depthRenderTargetRegisters},
|
depthRenderTarget{manager, engine.depthRenderTargetRegisters},
|
||||||
vertexInput{manager, engine.vertexInputRegisters},
|
vertexInput{manager, engine.vertexInputRegisters},
|
||||||
@ -771,7 +785,8 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
|||||||
rasterization{manager, engine.rasterizationRegisters},
|
rasterization{manager, engine.rasterizationRegisters},
|
||||||
depthStencil{manager, engine.depthStencilRegisters},
|
depthStencil{manager, engine.depthStencilRegisters},
|
||||||
colorBlend{manager, engine.colorBlendRegisters},
|
colorBlend{manager, engine.colorBlendRegisters},
|
||||||
directState{engine.inputAssemblyRegisters} {}
|
directState{engine.inputAssemblyRegisters},
|
||||||
|
globalShaderConfig{engine.globalShaderConfigRegisters} {}
|
||||||
|
|
||||||
void PipelineState::Flush(InterconnectContext &ctx, StateUpdateBuilder &builder) {
|
void PipelineState::Flush(InterconnectContext &ctx, StateUpdateBuilder &builder) {
|
||||||
boost::container::static_vector<TextureView *, engine::ColorTargetCount> colorAttachments;
|
boost::container::static_vector<TextureView *, engine::ColorTargetCount> colorAttachments;
|
||||||
@ -790,6 +805,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
|||||||
}; */
|
}; */
|
||||||
depthStencil.Update(packedState);
|
depthStencil.Update(packedState);
|
||||||
colorBlend.Update(packedState);
|
colorBlend.Update(packedState);
|
||||||
|
globalShaderConfig.Update(packedState);
|
||||||
|
|
||||||
constexpr std::array<vk::DynamicState, 9> dynamicStates{
|
constexpr std::array<vk::DynamicState, 9> dynamicStates{
|
||||||
vk::DynamicState::eViewport,
|
vk::DynamicState::eViewport,
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#include <boost/container/static_vector.hpp>
|
#include <boost/container/static_vector.hpp>
|
||||||
#include <gpu/texture/texture.h>
|
#include <gpu/texture/texture.h>
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "soc/gm20b/engines/maxwell/types.h"
|
#include "shader_state.h"
|
||||||
|
|
||||||
namespace skyline::gpu::interconnect::maxwell3d {
|
namespace skyline::gpu::interconnect::maxwell3d {
|
||||||
/**
|
/**
|
||||||
@ -47,11 +47,13 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
|||||||
bool stencilTestEnable : 1;
|
bool stencilTestEnable : 1;
|
||||||
bool logicOpEnable : 1;
|
bool logicOpEnable : 1;
|
||||||
vk::LogicOp logicOp : 4; //!< Use {Set, Get}LogicOp
|
vk::LogicOp logicOp : 4; //!< Use {Set, Get}LogicOp
|
||||||
|
u8 bindlessTextureConstantBufferSlotSelect : 5;
|
||||||
};
|
};
|
||||||
|
|
||||||
u32 patchSize;
|
u32 patchSize;
|
||||||
std::array<engine::VertexAttribute, engine::VertexAttributeCount> vertexAttributes;
|
std::array<engine::VertexAttribute, engine::VertexAttributeCount> vertexAttributes;
|
||||||
std::array<u8, engine::ColorTargetCount> colorRenderTargetFormats; //!< Use {Set, Get}ColorRenderTargetFormat
|
std::array<u8, engine::ColorTargetCount> colorRenderTargetFormats; //!< Use {Set, Get}ColorRenderTargetFormat
|
||||||
|
std::array<u32, 8> postVtgShaderAttributeSkipMask;
|
||||||
|
|
||||||
struct VertexBinding {
|
struct VertexBinding {
|
||||||
u16 stride : 12;
|
u16 stride : 12;
|
||||||
@ -287,12 +289,31 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
|||||||
void Flush(PackedPipelineState &packedState);
|
void Flush(PackedPipelineState &packedState);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class GlobalShaderConfigState {
|
||||||
|
public:
|
||||||
|
struct EngineRegisters {
|
||||||
|
const std::array<u32, 8> &postVtgShaderAttributeSkipMask;
|
||||||
|
const engine::BindlessTexture &bindlessTexture;
|
||||||
|
|
||||||
|
void DirtyBind(DirtyManager &manager, dirty::Handle handle) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
EngineRegisters engine;
|
||||||
|
|
||||||
|
public:
|
||||||
|
GlobalShaderConfigState(const EngineRegisters &engine);
|
||||||
|
|
||||||
|
void Update(PackedPipelineState &packedState);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Holds all GPU state for a pipeline, any changes to this will result in a pipeline cache lookup
|
* @brief Holds all GPU state for a pipeline, any changes to this will result in a pipeline cache lookup
|
||||||
*/
|
*/
|
||||||
class PipelineState : dirty::ManualDirty {
|
class PipelineState : dirty::ManualDirty {
|
||||||
public:
|
public:
|
||||||
struct EngineRegisters {
|
struct EngineRegisters {
|
||||||
|
std::array<IndividualShaderState::EngineRegisters, engine::PipelineCount> shadersRegisters;
|
||||||
std::array<ColorRenderTargetState::EngineRegisters, engine::ColorTargetCount> colorRenderTargetsRegisters;
|
std::array<ColorRenderTargetState::EngineRegisters, engine::ColorTargetCount> colorRenderTargetsRegisters;
|
||||||
DepthRenderTargetState::EngineRegisters depthRenderTargetRegisters;
|
DepthRenderTargetState::EngineRegisters depthRenderTargetRegisters;
|
||||||
VertexInputState::EngineRegisters vertexInputRegisters;
|
VertexInputState::EngineRegisters vertexInputRegisters;
|
||||||
@ -301,6 +322,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
|||||||
RasterizationState::EngineRegisters rasterizationRegisters;
|
RasterizationState::EngineRegisters rasterizationRegisters;
|
||||||
DepthStencilState::EngineRegisters depthStencilRegisters;
|
DepthStencilState::EngineRegisters depthStencilRegisters;
|
||||||
ColorBlendState::EngineRegisters colorBlendRegisters;
|
ColorBlendState::EngineRegisters colorBlendRegisters;
|
||||||
|
GlobalShaderConfigState::EngineRegisters globalShaderConfigRegisters;
|
||||||
|
|
||||||
void DirtyBind(DirtyManager &manager, dirty::Handle handle) const;
|
void DirtyBind(DirtyManager &manager, dirty::Handle handle) const;
|
||||||
};
|
};
|
||||||
@ -310,6 +332,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
|||||||
|
|
||||||
dirty::BoundSubresource<EngineRegisters> engine;
|
dirty::BoundSubresource<EngineRegisters> engine;
|
||||||
|
|
||||||
|
std::array<dirty::ManualDirtyState<IndividualShaderState>, engine::PipelineCount> shaders;
|
||||||
std::array<dirty::ManualDirtyState<ColorRenderTargetState>, engine::ColorTargetCount> colorRenderTargets;
|
std::array<dirty::ManualDirtyState<ColorRenderTargetState>, engine::ColorTargetCount> colorRenderTargets;
|
||||||
dirty::ManualDirtyState<DepthRenderTargetState> depthRenderTarget;
|
dirty::ManualDirtyState<DepthRenderTargetState> depthRenderTarget;
|
||||||
dirty::ManualDirtyState<VertexInputState> vertexInput;
|
dirty::ManualDirtyState<VertexInputState> vertexInput;
|
||||||
@ -317,7 +340,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
|||||||
dirty::ManualDirtyState<RasterizationState> rasterization;
|
dirty::ManualDirtyState<RasterizationState> rasterization;
|
||||||
dirty::ManualDirtyState<DepthStencilState> depthStencil;
|
dirty::ManualDirtyState<DepthStencilState> depthStencil;
|
||||||
dirty::ManualDirtyState<ColorBlendState> colorBlend;
|
dirty::ManualDirtyState<ColorBlendState> colorBlend;
|
||||||
|
GlobalShaderConfigState globalShaderConfig;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DirectPipelineState directState;
|
DirectPipelineState directState;
|
||||||
|
@ -858,9 +858,15 @@ namespace skyline::soc::gm20b::engine::maxwell3d::type {
|
|||||||
};
|
};
|
||||||
static_assert(sizeof(BindGroup) == (sizeof(u32) * 8));
|
static_assert(sizeof(BindGroup) == (sizeof(u32) * 8));
|
||||||
|
|
||||||
|
struct BindlessTexture {
|
||||||
|
u8 constantBufferSlotSelect : 5;
|
||||||
|
u32 _pad0_ : 27;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(BindlessTexture) == sizeof(u32));
|
||||||
|
|
||||||
constexpr static size_t PipelineStageConstantBufferCount{18}; //!< Maximum amount of constant buffers that can be bound to a single pipeline stage
|
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
|
constexpr static size_t PipelineCount{6}; //!< Amount of shader stages on Maxwell 3D
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief All the shader programs stages that Maxwell3D supports for draws
|
* @brief All the shader programs stages that Maxwell3D supports for draws
|
||||||
@ -879,19 +885,31 @@ namespace skyline::soc::gm20b::engine::maxwell3d::type {
|
|||||||
/**
|
/**
|
||||||
* @brief The arguments to set a shader program for a pipeline stage
|
* @brief The arguments to set a shader program for a pipeline stage
|
||||||
*/
|
*/
|
||||||
struct SetProgramInfo {
|
struct Pipeline {
|
||||||
struct {
|
struct Shader {
|
||||||
|
enum class Type : u8 {
|
||||||
|
VertexCullBeforeFetch = 0,
|
||||||
|
Vertex = 1,
|
||||||
|
TessellationInit = 2,
|
||||||
|
Tessellation = 3,
|
||||||
|
Geometry = 4,
|
||||||
|
Pixel = 5,
|
||||||
|
};
|
||||||
|
|
||||||
bool enable : 1;
|
bool enable : 1;
|
||||||
u8 _pad0_ : 3;
|
u8 _pad0_ : 3;
|
||||||
ShaderStage stage : 4;
|
Type type : 4;
|
||||||
u32 _pad1_ : 24;
|
u32 _pad1_ : 24;
|
||||||
} info;
|
} shader;
|
||||||
u32 offset; //!< Offset from the base shader memory IOVA
|
u32 programOffset; //!< Offset from the base shader memory IOVA
|
||||||
u32 _pad2_;
|
u32 _pad2_;
|
||||||
u32 gprCount; //!< Amount of GPRs used by the shader program
|
u8 registerCount; //!< Amount of GPRs used by the shader program
|
||||||
u32 _pad3_[12];
|
u32 _pad3_ : 24;
|
||||||
|
u8 bindingGroup : 3;
|
||||||
|
u32 _pad4_ : 29;
|
||||||
|
u32 _pad5_[11];
|
||||||
};
|
};
|
||||||
static_assert(sizeof(SetProgramInfo) == (sizeof(u32) * 0x10));
|
static_assert(sizeof(Pipeline) == (sizeof(u32) * 0x10));
|
||||||
|
|
||||||
struct ProvokingVertex {
|
struct ProvokingVertex {
|
||||||
enum class Value : u8 {
|
enum class Value : u8 {
|
||||||
|
@ -14,6 +14,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
|
|
||||||
static gpu::interconnect::maxwell3d::PipelineState::EngineRegisters MakePipelineStateRegisters(const Maxwell3D::Registers ®isters) {
|
static gpu::interconnect::maxwell3d::PipelineState::EngineRegisters MakePipelineStateRegisters(const Maxwell3D::Registers ®isters) {
|
||||||
return {
|
return {
|
||||||
|
.shadersRegisters = util::MergeInto<REGTYPE(IndividualShaderState), type::PipelineCount>(*registers.pipelines, *registers.programRegion),
|
||||||
.colorRenderTargetsRegisters = util::MergeInto<REGTYPE(ColorRenderTargetState), type::ColorTargetCount>(*registers.colorTargets),
|
.colorRenderTargetsRegisters = util::MergeInto<REGTYPE(ColorRenderTargetState), type::ColorTargetCount>(*registers.colorTargets),
|
||||||
.depthRenderTargetRegisters = {*registers.ztSize, *registers.ztOffset, *registers.ztFormat, *registers.ztBlockSize, *registers.ztArrayPitch, *registers.ztSelect, *registers.ztLayer},
|
.depthRenderTargetRegisters = {*registers.ztSize, *registers.ztOffset, *registers.ztFormat, *registers.ztBlockSize, *registers.ztArrayPitch, *registers.ztSelect, *registers.ztLayer},
|
||||||
.vertexInputRegisters = {*registers.vertexStreams, *registers.vertexStreamInstance, *registers.vertexAttributes},
|
.vertexInputRegisters = {*registers.vertexStreams, *registers.vertexStreamInstance, *registers.vertexAttributes},
|
||||||
@ -22,6 +23,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
.rasterizationRegisters = {*registers.rasterEnable, *registers.frontPolygonMode, *registers.backPolygonMode, *registers.oglCullEnable, *registers.oglCullFace, *registers.windowOrigin, *registers.oglFrontFace, *registers.viewportClipControl, *registers.polyOffset, *registers.provokingVertex},
|
.rasterizationRegisters = {*registers.rasterEnable, *registers.frontPolygonMode, *registers.backPolygonMode, *registers.oglCullEnable, *registers.oglCullFace, *registers.windowOrigin, *registers.oglFrontFace, *registers.viewportClipControl, *registers.polyOffset, *registers.provokingVertex},
|
||||||
.depthStencilRegisters = {*registers.depthTestEnable, *registers.depthWriteEnable, *registers.depthFunc, *registers.depthBoundsTestEnable, *registers.stencilTestEnable, *registers.twoSidedStencilTestEnable, *registers.stencilOps, *registers.stencilBack},
|
.depthStencilRegisters = {*registers.depthTestEnable, *registers.depthWriteEnable, *registers.depthFunc, *registers.depthBoundsTestEnable, *registers.stencilTestEnable, *registers.twoSidedStencilTestEnable, *registers.stencilOps, *registers.stencilBack},
|
||||||
.colorBlendRegisters = {*registers.logicOp, *registers.singleCtWriteControl, *registers.ctWrites, *registers.blendStatePerTargetEnable, *registers.blendPerTargets, *registers.blend},
|
.colorBlendRegisters = {*registers.logicOp, *registers.singleCtWriteControl, *registers.ctWrites, *registers.blendStatePerTargetEnable, *registers.blendPerTargets, *registers.blend},
|
||||||
|
.globalShaderConfigRegisters = {*registers.postVtgShaderAttributeSkipMask, *registers.bindlessTexture}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,6 +189,8 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
|
|
||||||
Register<0x48D, bool> linkedTscHandle; //!< If enabled, the TSC index in a bindless texture handle is ignored and the TIC index is used as the TSC index, otherwise the TSC index from the bindless texture handle is used
|
Register<0x48D, bool> linkedTscHandle; //!< If enabled, the TSC index in a bindless texture handle is ignored and the TIC index is used as the TSC index, otherwise the TSC index from the bindless texture handle is used
|
||||||
|
|
||||||
|
Register<0x490, std::array<u32, 8>> postVtgShaderAttributeSkipMask;
|
||||||
|
|
||||||
Register<0x4B3, u32> depthTestEnable;
|
Register<0x4B3, u32> depthTestEnable;
|
||||||
Register<0x4B9, u32> blendStatePerTargetEnable;
|
Register<0x4B9, u32> blendStatePerTargetEnable;
|
||||||
Register<0x4BA, u32> depthWriteEnable;
|
Register<0x4BA, u32> depthWriteEnable;
|
||||||
@ -253,7 +255,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
Register<0x56F, float> depthBias;
|
Register<0x56F, float> depthBias;
|
||||||
|
|
||||||
Register<0x581, type::PointCoordReplace> pointCoordReplace;
|
Register<0x581, type::PointCoordReplace> pointCoordReplace;
|
||||||
Register<0x582, Address> setProgramRegion;
|
Register<0x582, Address> programRegion;
|
||||||
|
|
||||||
Register<0x585, u32> end; //!< Method-only register with no real value, used after calling vertexBeginGl to invoke the draw
|
Register<0x585, u32> end; //!< Method-only register with no real value, used after calling vertexBeginGl to invoke the draw
|
||||||
|
|
||||||
@ -339,7 +341,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
|
|
||||||
Register<0x7C0, std::array<Address, type::VertexStreamCount>> vertexStreamLimits; //!< A per-VBO IOVA denoting the end of the vertex buffer
|
Register<0x7C0, std::array<Address, type::VertexStreamCount>> vertexStreamLimits; //!< A per-VBO IOVA denoting the end of the vertex buffer
|
||||||
|
|
||||||
Register<0x800, std::array<type::SetProgramInfo, type::ShaderStageCount>> setProgram;
|
Register<0x800, std::array<type::Pipeline, type::PipelineCount>> pipelines;
|
||||||
|
|
||||||
Register<0x8C0, u32[0x20]> firmwareCall;
|
Register<0x8C0, u32[0x20]> firmwareCall;
|
||||||
|
|
||||||
@ -357,7 +359,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
|
|
||||||
Register<0x900, std::array<type::BindGroup, type::PipelineStageCount>> bindGroups; //!< Binds constant buffers to pipeline stages
|
Register<0x900, std::array<type::BindGroup, type::PipelineStageCount>> bindGroups; //!< Binds constant buffers to pipeline stages
|
||||||
|
|
||||||
Register<0x982, u32> bindlessTextureConstantBufferIndex; //!< The index of the constant buffer containing bindless texture descriptors
|
Register<0x982, type::BindlessTexture> bindlessTexture; //!< The index of the constant buffer containing bindless texture descriptors
|
||||||
|
|
||||||
Register<0xA00, std::array<u32, (type::TransformFeedbackVaryingCount / sizeof(u32)) * type::StreamOutBufferCount>> transformFeedbackVaryings;
|
Register<0xA00, std::array<u32, (type::TransformFeedbackVaryingCount / sizeof(u32)) * type::StreamOutBufferCount>> transformFeedbackVaryings;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user