mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-11-23 07:59:18 +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 <vulkan/vulkan_core.h>
|
||||
#include "pipeline_state.h"
|
||||
#include "shader_state.h"
|
||||
#include "soc/gm20b/engines/maxwell/types.h"
|
||||
|
||||
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 */
|
||||
void PipelineState::EngineRegisters::DirtyBind(DirtyManager &manager, dirty::Handle handle) const {
|
||||
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)
|
||||
: 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>{})},
|
||||
depthRenderTarget{manager, engine.depthRenderTargetRegisters},
|
||||
vertexInput{manager, engine.vertexInputRegisters},
|
||||
@ -771,7 +785,8 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
rasterization{manager, engine.rasterizationRegisters},
|
||||
depthStencil{manager, engine.depthStencilRegisters},
|
||||
colorBlend{manager, engine.colorBlendRegisters},
|
||||
directState{engine.inputAssemblyRegisters} {}
|
||||
directState{engine.inputAssemblyRegisters},
|
||||
globalShaderConfig{engine.globalShaderConfigRegisters} {}
|
||||
|
||||
void PipelineState::Flush(InterconnectContext &ctx, StateUpdateBuilder &builder) {
|
||||
boost::container::static_vector<TextureView *, engine::ColorTargetCount> colorAttachments;
|
||||
@ -790,6 +805,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
}; */
|
||||
depthStencil.Update(packedState);
|
||||
colorBlend.Update(packedState);
|
||||
globalShaderConfig.Update(packedState);
|
||||
|
||||
constexpr std::array<vk::DynamicState, 9> dynamicStates{
|
||||
vk::DynamicState::eViewport,
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include <boost/container/static_vector.hpp>
|
||||
#include <gpu/texture/texture.h>
|
||||
#include "common.h"
|
||||
#include "soc/gm20b/engines/maxwell/types.h"
|
||||
#include "shader_state.h"
|
||||
|
||||
namespace skyline::gpu::interconnect::maxwell3d {
|
||||
/**
|
||||
@ -47,11 +47,13 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
bool stencilTestEnable : 1;
|
||||
bool logicOpEnable : 1;
|
||||
vk::LogicOp logicOp : 4; //!< Use {Set, Get}LogicOp
|
||||
u8 bindlessTextureConstantBufferSlotSelect : 5;
|
||||
};
|
||||
|
||||
u32 patchSize;
|
||||
std::array<engine::VertexAttribute, engine::VertexAttributeCount> vertexAttributes;
|
||||
std::array<u8, engine::ColorTargetCount> colorRenderTargetFormats; //!< Use {Set, Get}ColorRenderTargetFormat
|
||||
std::array<u32, 8> postVtgShaderAttributeSkipMask;
|
||||
|
||||
struct VertexBinding {
|
||||
u16 stride : 12;
|
||||
@ -287,12 +289,31 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
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
|
||||
*/
|
||||
class PipelineState : dirty::ManualDirty {
|
||||
public:
|
||||
struct EngineRegisters {
|
||||
std::array<IndividualShaderState::EngineRegisters, engine::PipelineCount> shadersRegisters;
|
||||
std::array<ColorRenderTargetState::EngineRegisters, engine::ColorTargetCount> colorRenderTargetsRegisters;
|
||||
DepthRenderTargetState::EngineRegisters depthRenderTargetRegisters;
|
||||
VertexInputState::EngineRegisters vertexInputRegisters;
|
||||
@ -301,6 +322,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
RasterizationState::EngineRegisters rasterizationRegisters;
|
||||
DepthStencilState::EngineRegisters depthStencilRegisters;
|
||||
ColorBlendState::EngineRegisters colorBlendRegisters;
|
||||
GlobalShaderConfigState::EngineRegisters globalShaderConfigRegisters;
|
||||
|
||||
void DirtyBind(DirtyManager &manager, dirty::Handle handle) const;
|
||||
};
|
||||
@ -310,6 +332,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
|
||||
dirty::BoundSubresource<EngineRegisters> engine;
|
||||
|
||||
std::array<dirty::ManualDirtyState<IndividualShaderState>, engine::PipelineCount> shaders;
|
||||
std::array<dirty::ManualDirtyState<ColorRenderTargetState>, engine::ColorTargetCount> colorRenderTargets;
|
||||
dirty::ManualDirtyState<DepthRenderTargetState> depthRenderTarget;
|
||||
dirty::ManualDirtyState<VertexInputState> vertexInput;
|
||||
@ -317,7 +340,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
dirty::ManualDirtyState<RasterizationState> rasterization;
|
||||
dirty::ManualDirtyState<DepthStencilState> depthStencil;
|
||||
dirty::ManualDirtyState<ColorBlendState> colorBlend;
|
||||
|
||||
GlobalShaderConfigState globalShaderConfig;
|
||||
|
||||
public:
|
||||
DirectPipelineState directState;
|
||||
|
@ -858,9 +858,15 @@ namespace skyline::soc::gm20b::engine::maxwell3d::type {
|
||||
};
|
||||
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 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
|
||||
@ -879,19 +885,31 @@ namespace skyline::soc::gm20b::engine::maxwell3d::type {
|
||||
/**
|
||||
* @brief The arguments to set a shader program for a pipeline stage
|
||||
*/
|
||||
struct SetProgramInfo {
|
||||
struct {
|
||||
struct Pipeline {
|
||||
struct Shader {
|
||||
enum class Type : u8 {
|
||||
VertexCullBeforeFetch = 0,
|
||||
Vertex = 1,
|
||||
TessellationInit = 2,
|
||||
Tessellation = 3,
|
||||
Geometry = 4,
|
||||
Pixel = 5,
|
||||
};
|
||||
|
||||
bool enable : 1;
|
||||
u8 _pad0_ : 3;
|
||||
ShaderStage stage : 4;
|
||||
Type type : 4;
|
||||
u32 _pad1_ : 24;
|
||||
} info;
|
||||
u32 offset; //!< Offset from the base shader memory IOVA
|
||||
} shader;
|
||||
u32 programOffset; //!< Offset from the base shader memory IOVA
|
||||
u32 _pad2_;
|
||||
u32 gprCount; //!< Amount of GPRs used by the shader program
|
||||
u32 _pad3_[12];
|
||||
u8 registerCount; //!< Amount of GPRs used by the shader program
|
||||
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 {
|
||||
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) {
|
||||
return {
|
||||
.shadersRegisters = util::MergeInto<REGTYPE(IndividualShaderState), type::PipelineCount>(*registers.pipelines, *registers.programRegion),
|
||||
.colorRenderTargetsRegisters = util::MergeInto<REGTYPE(ColorRenderTargetState), type::ColorTargetCount>(*registers.colorTargets),
|
||||
.depthRenderTargetRegisters = {*registers.ztSize, *registers.ztOffset, *registers.ztFormat, *registers.ztBlockSize, *registers.ztArrayPitch, *registers.ztSelect, *registers.ztLayer},
|
||||
.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},
|
||||
.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},
|
||||
.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<0x490, std::array<u32, 8>> postVtgShaderAttributeSkipMask;
|
||||
|
||||
Register<0x4B3, u32> depthTestEnable;
|
||||
Register<0x4B9, u32> blendStatePerTargetEnable;
|
||||
Register<0x4BA, u32> depthWriteEnable;
|
||||
@ -253,7 +255,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
||||
Register<0x56F, float> depthBias;
|
||||
|
||||
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
|
||||
|
||||
@ -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<0x800, std::array<type::SetProgramInfo, type::ShaderStageCount>> setProgram;
|
||||
Register<0x800, std::array<type::Pipeline, type::PipelineCount>> pipelines;
|
||||
|
||||
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<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;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user