mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-24 04:01:50 +01:00
Implement color blend pipeline state
This commit is contained in:
parent
cb11662ea5
commit
6e55d4dcf4
@ -628,6 +628,182 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
|||||||
depthStencilState.back = ConvertStencilOpsState(stencilBack);
|
depthStencilState.back = ConvertStencilOpsState(stencilBack);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Color Blend State */
|
||||||
|
void ColorBlendState::EngineRegisters::DirtyBind(DirtyManager &manager, dirty::Handle handle) const {
|
||||||
|
manager.Bind(handle, logicOp, singleCtWriteControl, ctWrites, blendStatePerTargetEnable, blendPerTargets, blend);
|
||||||
|
}
|
||||||
|
|
||||||
|
ColorBlendState::ColorBlendState(dirty::Handle dirtyHandle, DirtyManager &manager, const EngineRegisters &engine) : engine{manager, dirtyHandle, engine} {}
|
||||||
|
|
||||||
|
vk::LogicOp ConvertLogicOpFunc(engine::LogicOp::Func func) {
|
||||||
|
switch (func) {
|
||||||
|
case engine::LogicOp::Func::Clear:
|
||||||
|
return vk::LogicOp::eClear;
|
||||||
|
case engine::LogicOp::Func::And:
|
||||||
|
return vk::LogicOp::eAnd;
|
||||||
|
case engine::LogicOp::Func::AndReverse:
|
||||||
|
return vk::LogicOp::eAndReverse;
|
||||||
|
case engine::LogicOp::Func::Copy:
|
||||||
|
return vk::LogicOp::eCopy;
|
||||||
|
case engine::LogicOp::Func::AndInverted:
|
||||||
|
return vk::LogicOp::eAndInverted;
|
||||||
|
case engine::LogicOp::Func::Noop:
|
||||||
|
return vk::LogicOp::eNoOp;
|
||||||
|
case engine::LogicOp::Func::Xor:
|
||||||
|
return vk::LogicOp::eXor;
|
||||||
|
case engine::LogicOp::Func::Or:
|
||||||
|
return vk::LogicOp::eOr;
|
||||||
|
case engine::LogicOp::Func::Nor:
|
||||||
|
return vk::LogicOp::eNor;
|
||||||
|
case engine::LogicOp::Func::Equiv:
|
||||||
|
return vk::LogicOp::eEquivalent;
|
||||||
|
case engine::LogicOp::Func::Invert:
|
||||||
|
return vk::LogicOp::eInvert;
|
||||||
|
case engine::LogicOp::Func::OrReverse:
|
||||||
|
return vk::LogicOp::eOrReverse;
|
||||||
|
case engine::LogicOp::Func::CopyInverted:
|
||||||
|
return vk::LogicOp::eCopyInverted;
|
||||||
|
case engine::LogicOp::Func::OrInverted:
|
||||||
|
return vk::LogicOp::eOrInverted;
|
||||||
|
case engine::LogicOp::Func::Nand:
|
||||||
|
return vk::LogicOp::eNand;
|
||||||
|
case engine::LogicOp::Func::Set:
|
||||||
|
return vk::LogicOp::eSet;
|
||||||
|
default:
|
||||||
|
throw exception("Invalid logical operation type: 0x{:X}", static_cast<u32>(func));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static vk::ColorComponentFlags ConvertColorWriteMask(engine::CtWrite write) {
|
||||||
|
return vk::ColorComponentFlags{
|
||||||
|
write.rEnable ? vk::ColorComponentFlagBits::eR : vk::ColorComponentFlags{} |
|
||||||
|
write.gEnable ? vk::ColorComponentFlagBits::eG : vk::ColorComponentFlags{} |
|
||||||
|
write.bEnable ? vk::ColorComponentFlagBits::eB : vk::ColorComponentFlags{} |
|
||||||
|
write.aEnable ? vk::ColorComponentFlagBits::eA : vk::ColorComponentFlags{}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static vk::BlendOp ConvertBlendOp(engine::BlendOp op) {
|
||||||
|
switch (op) {
|
||||||
|
case engine::BlendOp::D3DAdd:
|
||||||
|
case engine::BlendOp::OglFuncAdd:
|
||||||
|
return vk::BlendOp::eAdd;
|
||||||
|
case engine::BlendOp::D3DSubtract:
|
||||||
|
case engine::BlendOp::OglFuncSubtract:
|
||||||
|
return vk::BlendOp::eSubtract;
|
||||||
|
case engine::BlendOp::D3DRevSubtract:
|
||||||
|
case engine::BlendOp::OglFuncReverseSubtract:
|
||||||
|
return vk::BlendOp::eReverseSubtract;
|
||||||
|
case engine::BlendOp::D3DMin:
|
||||||
|
case engine::BlendOp::OglMin:
|
||||||
|
return vk::BlendOp::eMin;
|
||||||
|
case engine::BlendOp::D3DMax:
|
||||||
|
case engine::BlendOp::OglMax:
|
||||||
|
return vk::BlendOp::eMax;
|
||||||
|
default:
|
||||||
|
throw exception("Invalid blend operation: 0x{:X}", static_cast<u32>(op));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static vk::BlendFactor ConvertBlendFactor(engine::BlendCoeff coeff) {
|
||||||
|
switch (coeff) {
|
||||||
|
case engine::BlendCoeff::OglZero:
|
||||||
|
case engine::BlendCoeff::D3DZero:
|
||||||
|
return vk::BlendFactor::eZero;
|
||||||
|
case engine::BlendCoeff::OglOne:
|
||||||
|
case engine::BlendCoeff::D3DOne:
|
||||||
|
return vk::BlendFactor::eOne;
|
||||||
|
case engine::BlendCoeff::OglSrcColor:
|
||||||
|
case engine::BlendCoeff::D3DSrcColor:
|
||||||
|
return vk::BlendFactor::eSrcColor;
|
||||||
|
case engine::BlendCoeff::OglOneMinusSrcColor:
|
||||||
|
case engine::BlendCoeff::D3DInvSrcColor:
|
||||||
|
return vk::BlendFactor::eOneMinusSrcColor;
|
||||||
|
case engine::BlendCoeff::OglSrcAlpha:
|
||||||
|
case engine::BlendCoeff::D3DSrcAlpha:
|
||||||
|
return vk::BlendFactor::eSrcAlpha;
|
||||||
|
case engine::BlendCoeff::OglOneMinusSrcAlpha:
|
||||||
|
case engine::BlendCoeff::D3DInvSrcAlpha:
|
||||||
|
return vk::BlendFactor::eOneMinusSrcAlpha;
|
||||||
|
case engine::BlendCoeff::OglDstAlpha:
|
||||||
|
case engine::BlendCoeff::D3DDstAlpha:
|
||||||
|
return vk::BlendFactor::eDstAlpha;
|
||||||
|
case engine::BlendCoeff::OglOneMinusDstAlpha:
|
||||||
|
case engine::BlendCoeff::D3DInvDstAlpha:
|
||||||
|
return vk::BlendFactor::eOneMinusDstAlpha;
|
||||||
|
case engine::BlendCoeff::OglDstColor:
|
||||||
|
case engine::BlendCoeff::D3DDstColor:
|
||||||
|
return vk::BlendFactor::eDstColor;
|
||||||
|
case engine::BlendCoeff::OglOneMinusDstColor:
|
||||||
|
case engine::BlendCoeff::D3DInvDstColor:
|
||||||
|
return vk::BlendFactor::eOneMinusDstColor;
|
||||||
|
case engine::BlendCoeff::OglSrcAlphaSaturate:
|
||||||
|
case engine::BlendCoeff::D3DSrcAlphaSaturate:
|
||||||
|
return vk::BlendFactor::eSrcAlphaSaturate;
|
||||||
|
case engine::BlendCoeff::OglConstantColor:
|
||||||
|
case engine::BlendCoeff::D3DBlendCoeff:
|
||||||
|
return vk::BlendFactor::eConstantColor;
|
||||||
|
case engine::BlendCoeff::OglOneMinusConstantColor:
|
||||||
|
case engine::BlendCoeff::D3DInvBlendCoeff:
|
||||||
|
return vk::BlendFactor::eOneMinusConstantColor;
|
||||||
|
case engine::BlendCoeff::OglConstantAlpha:
|
||||||
|
return vk::BlendFactor::eConstantAlpha;
|
||||||
|
case engine::BlendCoeff::OglOneMinusConstantAlpha:
|
||||||
|
return vk::BlendFactor::eOneMinusConstantAlpha;
|
||||||
|
case engine::BlendCoeff::OglSrc1Color:
|
||||||
|
case engine::BlendCoeff::D3DSrc1Color:
|
||||||
|
return vk::BlendFactor::eSrc1Color;
|
||||||
|
case engine::BlendCoeff::OglInvSrc1Color:
|
||||||
|
case engine::BlendCoeff::D3DInvSrc1Color:
|
||||||
|
return vk::BlendFactor::eOneMinusSrc1Color;
|
||||||
|
case engine::BlendCoeff::OglSrc1Alpha:
|
||||||
|
case engine::BlendCoeff::D3DSrc1Alpha:
|
||||||
|
return vk::BlendFactor::eSrc1Alpha;
|
||||||
|
case engine::BlendCoeff::OglInvSrc1Alpha:
|
||||||
|
case engine::BlendCoeff::D3DInvSrc1Alpha:
|
||||||
|
return vk::BlendFactor::eOneMinusSrc1Alpha;
|
||||||
|
default:
|
||||||
|
throw exception("Invalid blend coefficient type: 0x{:X}", static_cast<u32>(coeff));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ColorBlendState::Flush(InterconnectContext &ctx, size_t attachmentCount) {
|
||||||
|
if (engine->logicOp.enable) {
|
||||||
|
if (ctx.gpu.traits.supportsLogicOp) {
|
||||||
|
colorBlendState.logicOpEnable = true;
|
||||||
|
colorBlendState.logicOp = ConvertLogicOpFunc(engine->logicOp.func);
|
||||||
|
} else {
|
||||||
|
Logger::Warn("Cannot enable framebuffer logical operation without host GPU support!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto convertBlendState{[](vk::PipelineColorBlendAttachmentState &attachmentBlendState, const auto &blend) {
|
||||||
|
attachmentBlendState.colorBlendOp = ConvertBlendOp(blend.colorOp);
|
||||||
|
attachmentBlendState.srcColorBlendFactor = ConvertBlendFactor(blend.colorSourceCoeff);
|
||||||
|
attachmentBlendState.dstColorBlendFactor = ConvertBlendFactor(blend.colorDestCoeff);
|
||||||
|
attachmentBlendState.alphaBlendOp = ConvertBlendOp(blend.alphaOp);
|
||||||
|
attachmentBlendState.srcAlphaBlendFactor = ConvertBlendFactor(blend.alphaSourceCoeff);
|
||||||
|
attachmentBlendState.dstAlphaBlendFactor = ConvertBlendFactor(blend.alphaDestCoeff);
|
||||||
|
}};
|
||||||
|
|
||||||
|
for (size_t i{}; i < engine::ColorTargetCount; i++) {
|
||||||
|
auto &attachmentBlendState{attachmentBlendStates[i]};
|
||||||
|
attachmentBlendState.blendEnable = engine->blend.enable[i];
|
||||||
|
attachmentBlendState.colorWriteMask = ConvertColorWriteMask(engine->singleCtWriteControl ? engine->ctWrites[0] : engine->ctWrites[i]);
|
||||||
|
if (engine->blendStatePerTargetEnable)
|
||||||
|
convertBlendState(attachmentBlendState, engine->blendPerTargets[i]);
|
||||||
|
else
|
||||||
|
convertBlendState(attachmentBlendState, engine->blend);
|
||||||
|
}
|
||||||
|
|
||||||
|
colorBlendState.attachmentCount = static_cast<u32>(attachmentCount);
|
||||||
|
colorBlendState.pAttachments = attachmentBlendStates.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ColorBlendState::Refresh(InterconnectContext &ctx, size_t attachmentCount) {
|
||||||
|
colorBlendState.attachmentCount = static_cast<u32>(attachmentCount);
|
||||||
|
}
|
||||||
|
|
||||||
/* 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); }};
|
||||||
@ -642,14 +818,18 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
|||||||
colorRenderTargets{util::MergeInto<dirty::ManualDirtyState<ColorRenderTargetState>, engine::ColorTargetCount>(manager, engine.colorRenderTargetsRegisters)},
|
colorRenderTargets{util::MergeInto<dirty::ManualDirtyState<ColorRenderTargetState>, engine::ColorTargetCount>(manager, engine.colorRenderTargetsRegisters)},
|
||||||
depthRenderTarget{manager, engine.depthRenderTargetRegisters},
|
depthRenderTarget{manager, engine.depthRenderTargetRegisters},
|
||||||
rasterization{manager, engine.rasterizationRegisters},
|
rasterization{manager, engine.rasterizationRegisters},
|
||||||
depthStencil{manager, engine.depthStencilRegisters} {}
|
depthStencil{manager, engine.depthStencilRegisters},
|
||||||
|
colorBlend{manager, engine.colorBlendRegisters} {}
|
||||||
|
|
||||||
void PipelineState::Flush(InterconnectContext &ctx, StateUpdateBuilder &builder) {
|
void PipelineState::Flush(InterconnectContext &ctx, StateUpdateBuilder &builder) {
|
||||||
auto updateFunc{[&](auto &stateElem, auto &&... args) { stateElem.Update(ctx, args...); }};
|
boost::container::static_vector<TextureView *, engine::ColorTargetCount> colorAttachments;
|
||||||
ranges::for_each(colorRenderTargets, updateFunc);
|
for (auto &colorRenderTarget : colorRenderTargets)
|
||||||
updateFunc(depthRenderTarget);
|
if (auto view{colorRenderTarget.UpdateGet(ctx).view}; view)
|
||||||
|
colorAttachments.push_back(view.get());
|
||||||
|
|
||||||
auto vertexState{directState.vertexInput.Build(ctx, engine->vertexInputRegisters)};
|
TextureView *depthAttachment{depthRenderTarget.UpdateGet(ctx).view.get()};
|
||||||
|
|
||||||
|
auto vertexInputState{directState.vertexInput.Build(ctx, engine->vertexInputRegisters)};
|
||||||
const auto &inputAssemblyState{directState.inputAssembly.Build()};
|
const auto &inputAssemblyState{directState.inputAssembly.Build()};
|
||||||
const auto &tessellationState{directState.tessellation.Build()};
|
const auto &tessellationState{directState.tessellation.Build()};
|
||||||
const auto &rasterizationState{rasterization.UpdateGet().rasterizationState};
|
const auto &rasterizationState{rasterization.UpdateGet().rasterizationState};
|
||||||
@ -657,8 +837,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
|||||||
.rasterizationSamples = vk::SampleCountFlagBits::e1
|
.rasterizationSamples = vk::SampleCountFlagBits::e1
|
||||||
};
|
};
|
||||||
const auto &depthStencilState{depthStencil.UpdateGet().depthStencilState};
|
const auto &depthStencilState{depthStencil.UpdateGet().depthStencilState};
|
||||||
|
const auto &colorBlendState{colorBlend.UpdateGet(ctx, colorAttachments.size()).colorBlendState};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<TextureView> PipelineState::GetColorRenderTargetForClear(InterconnectContext &ctx, size_t index) {
|
std::shared_ptr<TextureView> PipelineState::GetColorRenderTargetForClear(InterconnectContext &ctx, size_t index) {
|
||||||
|
@ -163,7 +163,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
|||||||
dirty::BoundSubresource<EngineRegisters> engine;
|
dirty::BoundSubresource<EngineRegisters> engine;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
vk::StructureChain<vk::PipelineRasterizationStateCreateInfo, vk::PipelineRasterizationProvokingVertexStateCreateInfoEXT> rasterizationState;
|
vk::StructureChain<vk::PipelineRasterizationStateCreateInfo, vk::PipelineRasterizationProvokingVertexStateCreateInfoEXT> rasterizationState{};
|
||||||
|
|
||||||
RasterizationState(dirty::Handle dirtyHandle, DirtyManager &manager, const EngineRegisters &engine);
|
RasterizationState(dirty::Handle dirtyHandle, DirtyManager &manager, const EngineRegisters &engine);
|
||||||
|
|
||||||
@ -189,13 +189,40 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
|||||||
dirty::BoundSubresource<EngineRegisters> engine;
|
dirty::BoundSubresource<EngineRegisters> engine;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
vk::PipelineDepthStencilStateCreateInfo depthStencilState;
|
vk::PipelineDepthStencilStateCreateInfo depthStencilState{};
|
||||||
|
|
||||||
DepthStencilState(dirty::Handle dirtyHandle, DirtyManager &manager, const EngineRegisters &engine);
|
DepthStencilState(dirty::Handle dirtyHandle, DirtyManager &manager, const EngineRegisters &engine);
|
||||||
|
|
||||||
void Flush();
|
void Flush();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ColorBlendState : dirty::RefreshableManualDirty {
|
||||||
|
public:
|
||||||
|
struct EngineRegisters {
|
||||||
|
const engine::LogicOp &logicOp;
|
||||||
|
const u32 &singleCtWriteControl;
|
||||||
|
const std::array<engine::CtWrite, engine::ColorTargetCount> &ctWrites;
|
||||||
|
const u32 &blendStatePerTargetEnable;
|
||||||
|
const std::array<engine::BlendPerTarget, engine::ColorTargetCount> &blendPerTargets;
|
||||||
|
const engine::Blend &blend;
|
||||||
|
|
||||||
|
void DirtyBind(DirtyManager &manager, dirty::Handle handle) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
dirty::BoundSubresource<EngineRegisters> engine;
|
||||||
|
std::array<vk::PipelineColorBlendAttachmentState, engine::ColorTargetCount> attachmentBlendStates;
|
||||||
|
|
||||||
|
public:
|
||||||
|
vk::PipelineColorBlendStateCreateInfo colorBlendState{};
|
||||||
|
|
||||||
|
ColorBlendState(dirty::Handle dirtyHandle, DirtyManager &manager, const EngineRegisters &engine);
|
||||||
|
|
||||||
|
void Flush(InterconnectContext &ctx, size_t attachmentCount);
|
||||||
|
|
||||||
|
void Refresh(InterconnectContext &ctx, size_t attachmentCount);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @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
|
||||||
*/
|
*/
|
||||||
@ -209,6 +236,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
|||||||
TessellationState::EngineRegisters tessellationRegisters;
|
TessellationState::EngineRegisters tessellationRegisters;
|
||||||
RasterizationState::EngineRegisters rasterizationRegisters;
|
RasterizationState::EngineRegisters rasterizationRegisters;
|
||||||
DepthStencilState::EngineRegisters depthStencilRegisters;
|
DepthStencilState::EngineRegisters depthStencilRegisters;
|
||||||
|
ColorBlendState::EngineRegisters colorBlendRegisters;
|
||||||
|
|
||||||
void DirtyBind(DirtyManager &manager, dirty::Handle handle) const;
|
void DirtyBind(DirtyManager &manager, dirty::Handle handle) const;
|
||||||
};
|
};
|
||||||
@ -220,6 +248,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
|||||||
dirty::ManualDirtyState<DepthRenderTargetState> depthRenderTarget;
|
dirty::ManualDirtyState<DepthRenderTargetState> depthRenderTarget;
|
||||||
dirty::ManualDirtyState<RasterizationState> rasterization;
|
dirty::ManualDirtyState<RasterizationState> rasterization;
|
||||||
dirty::ManualDirtyState<DepthStencilState> depthStencil;
|
dirty::ManualDirtyState<DepthStencilState> depthStencil;
|
||||||
|
dirty::ManualDirtyState<ColorBlendState> colorBlend;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -481,59 +481,55 @@ namespace skyline::soc::gm20b::engine::maxwell3d::type {
|
|||||||
constexpr static size_t BlendColorChannelCount{4}; //!< The amount of color channels in operations such as blending
|
constexpr static size_t BlendColorChannelCount{4}; //!< The amount of color channels in operations such as blending
|
||||||
|
|
||||||
enum class BlendOp : u32 {
|
enum class BlendOp : u32 {
|
||||||
Add = 1,
|
OglFuncSubtract = 0x0000800A,
|
||||||
Subtract = 2,
|
OglFuncReverseSubtract = 0x0000800B,
|
||||||
ReverseSubtract = 3,
|
OglFuncAdd = 0x00008006,
|
||||||
Minimum = 4,
|
OglMin = 0x00008007,
|
||||||
Maximum = 5,
|
OglMax = 0x00008008,
|
||||||
|
D3DAdd = 0x00000001,
|
||||||
AddGL = 0x8006,
|
D3DSubtract = 0x00000002,
|
||||||
MinimumGL = 0x8007,
|
D3DRevSubtract = 0x00000003,
|
||||||
MaximumGL = 0x8008,
|
D3DMin = 0x00000004,
|
||||||
SubtractGL = 0x800A,
|
D3DMax = 0x00000005,
|
||||||
ReverseSubtractGL = 0x800B,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class BlendFactor : u32 {
|
enum class BlendCoeff : u32 {
|
||||||
Zero = 0x1,
|
OglZero = 0x4000,
|
||||||
One = 0x2,
|
OglOne = 0x4001,
|
||||||
SourceColor = 0x3,
|
OglSrcColor = 0x4300,
|
||||||
OneMinusSourceColor = 0x4,
|
OglOneMinusSrcColor = 0x4301,
|
||||||
SourceAlpha = 0x5,
|
OglSrcAlpha = 0x4302,
|
||||||
OneMinusSourceAlpha = 0x6,
|
OglOneMinusSrcAlpha = 0x4303,
|
||||||
DestAlpha = 0x7,
|
OglDstAlpha = 0x4304,
|
||||||
OneMinusDestAlpha = 0x8,
|
OglOneMinusDstAlpha = 0x4305,
|
||||||
DestColor = 0x9,
|
OglDstColor = 0x4306,
|
||||||
OneMinusDestColor = 0xA,
|
OglOneMinusDstColor = 0x4307,
|
||||||
SourceAlphaSaturate = 0xB,
|
OglSrcAlphaSaturate = 0x4308,
|
||||||
Source1Color = 0x10,
|
OglConstantColor = 0xC001,
|
||||||
OneMinusSource1Color = 0x11,
|
OglOneMinusConstantColor = 0xC002,
|
||||||
Source1Alpha = 0x12,
|
OglConstantAlpha = 0xC003,
|
||||||
OneMinusSource1Alpha = 0x13,
|
OglOneMinusConstantAlpha = 0xC004,
|
||||||
ConstantColor = 0x61,
|
OglSrc1Color = 0xC900,
|
||||||
OneMinusConstantColor = 0x62,
|
OglInvSrc1Color = 0xC901,
|
||||||
ConstantAlpha = 0x63,
|
OglSrc1Alpha = 0xC902,
|
||||||
OneMinusConstantAlpha = 0x64,
|
OglInvSrc1Alpha = 0xC903,
|
||||||
|
D3DZero = 0x1,
|
||||||
ZeroGL = 0x4000,
|
D3DOne = 0x2,
|
||||||
OneGL = 0x4001,
|
D3DSrcColor = 0x3,
|
||||||
SourceColorGL = 0x4300,
|
D3DInvSrcColor = 0x4,
|
||||||
OneMinusSourceColorGL = 0x4301,
|
D3DSrcAlpha = 0x5,
|
||||||
SourceAlphaGL = 0x4302,
|
D3DInvSrcAlpha = 0x6,
|
||||||
OneMinusSourceAlphaGL = 0x4303,
|
D3DDstAlpha = 0x7,
|
||||||
DestAlphaGL = 0x4304,
|
D3DInvDstAlpha = 0x8,
|
||||||
OneMinusDestAlphaGL = 0x4305,
|
D3DDstColor = 0x9,
|
||||||
DestColorGL = 0x4306,
|
D3DInvDstColor = 0xA,
|
||||||
OneMinusDestColorGL = 0x4307,
|
D3DSrcAlphaSaturate = 0xB,
|
||||||
SourceAlphaSaturateGL = 0x4308,
|
D3DBlendCoeff = 0xE,
|
||||||
ConstantColorGL = 0xC001,
|
D3DInvBlendCoeff = 0xF,
|
||||||
OneMinusConstantColorGL = 0xC002,
|
D3DSrc1Color = 0x10,
|
||||||
ConstantAlphaGL = 0xC003,
|
D3DInvSrc1Color = 0x11,
|
||||||
OneMinusConstantAlphaGL = 0xC004,
|
D3DSrc1Alpha = 0x12,
|
||||||
Source1ColorGL = 0xC900,
|
D3DInvSrc1Alpha = 0x13,
|
||||||
OneMinusSource1ColorGL = 0xC901,
|
|
||||||
Source1AlphaGL = 0xC902,
|
|
||||||
OneMinusSource1AlphaGL = 0xC903,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ZtSelect {
|
struct ZtSelect {
|
||||||
@ -710,17 +706,21 @@ namespace skyline::soc::gm20b::engine::maxwell3d::type {
|
|||||||
};
|
};
|
||||||
static_assert(sizeof(ViewportClipControl) == sizeof(u32));
|
static_assert(sizeof(ViewportClipControl) == sizeof(u32));
|
||||||
|
|
||||||
union ColorWriteMask {
|
union CtWrite {
|
||||||
u32 raw;
|
u32 raw;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
u8 red : 4;
|
bool rEnable : 1;
|
||||||
u8 green : 4;
|
u8 _pad0_ : 3;
|
||||||
u8 blue : 4;
|
bool gEnable : 1;
|
||||||
u8 alpha : 4;
|
u8 _pad1_ : 3;
|
||||||
|
bool bEnable : 1;
|
||||||
|
u8 _pad2_ : 3;
|
||||||
|
bool aEnable : 1;
|
||||||
|
u32 _pad3_ : 19;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
static_assert(sizeof(ColorWriteMask) == sizeof(u32));
|
static_assert(sizeof(CtWrite) == sizeof(u32));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A method call which causes a layer of an RT to be cleared with a channel mask
|
* @brief A method call which causes a layer of an RT to be cleared with a channel mask
|
||||||
@ -823,28 +823,6 @@ namespace skyline::soc::gm20b::engine::maxwell3d::type {
|
|||||||
};
|
};
|
||||||
static_assert(sizeof(SemaphoreInfo) == sizeof(u32));
|
static_assert(sizeof(SemaphoreInfo) == sizeof(u32));
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief The logical operations that can be performed on the framebuffer after the fragment shader
|
|
||||||
*/
|
|
||||||
enum class ColorLogicOp : u32 {
|
|
||||||
Clear = 0x1500,
|
|
||||||
And = 0x1501,
|
|
||||||
AndReverse = 0x1502,
|
|
||||||
Copy = 0x1503,
|
|
||||||
AndInverted = 0x1504,
|
|
||||||
Noop = 0x1505,
|
|
||||||
Xor = 0x1506,
|
|
||||||
Or = 0x1507,
|
|
||||||
Nor = 0x1508,
|
|
||||||
Equiv = 0x1509,
|
|
||||||
Invert = 0x150A,
|
|
||||||
OrReverse = 0x150B,
|
|
||||||
CopyInverted = 0x150C,
|
|
||||||
OrInverted = 0x150D,
|
|
||||||
Nand = 0x150E,
|
|
||||||
Set = 0x150F,
|
|
||||||
};
|
|
||||||
|
|
||||||
constexpr static size_t PipelineStageCount{5}; //!< Amount of pipeline stages on Maxwell 3D
|
constexpr static size_t PipelineStageCount{5}; //!< Amount of pipeline stages on Maxwell 3D
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -978,6 +956,34 @@ namespace skyline::soc::gm20b::engine::maxwell3d::type {
|
|||||||
};
|
};
|
||||||
static_assert(sizeof(VertexStream) == sizeof(u32) * 4);
|
static_assert(sizeof(VertexStream) == sizeof(u32) * 4);
|
||||||
|
|
||||||
|
struct BlendPerTarget {
|
||||||
|
bool seperateForAlpha : 1;
|
||||||
|
u32 _pad0_ : 31;
|
||||||
|
BlendOp colorOp;
|
||||||
|
BlendCoeff colorSourceCoeff;
|
||||||
|
BlendCoeff colorDestCoeff;
|
||||||
|
BlendOp alphaOp;
|
||||||
|
BlendCoeff alphaSourceCoeff;
|
||||||
|
BlendCoeff alphaDestCoeff;
|
||||||
|
u32 _pad_;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Blend {
|
||||||
|
bool seperateForAlpha : 1;
|
||||||
|
u32 _pad0_ : 31;
|
||||||
|
BlendOp colorOp;
|
||||||
|
BlendCoeff colorSourceCoeff;
|
||||||
|
BlendCoeff colorDestCoeff;
|
||||||
|
BlendOp alphaOp;
|
||||||
|
BlendCoeff alphaSourceCoeff;
|
||||||
|
bool globalColorKeyEnable : 1;
|
||||||
|
u32 _pad1_ : 31;
|
||||||
|
BlendCoeff alphaDestCoeff;
|
||||||
|
bool singleRopControlEnable : 1;
|
||||||
|
u32 _pad2_ : 31;
|
||||||
|
std::array<u32, ColorTargetCount> enable;
|
||||||
|
};
|
||||||
|
|
||||||
struct WindowOrigin {
|
struct WindowOrigin {
|
||||||
bool lowerLeft : 1;
|
bool lowerLeft : 1;
|
||||||
u8 _pad0_ : 3;
|
u8 _pad0_ : 3;
|
||||||
@ -1119,5 +1125,28 @@ namespace skyline::soc::gm20b::engine::maxwell3d::type {
|
|||||||
};
|
};
|
||||||
static_assert(sizeof(TessellationParameters) == sizeof(u32));
|
static_assert(sizeof(TessellationParameters) == sizeof(u32));
|
||||||
|
|
||||||
|
struct LogicOp {
|
||||||
|
bool enable : 1;
|
||||||
|
u32 _pad0_ : 31;
|
||||||
|
enum class Func : u32 {
|
||||||
|
Clear = 0x1500,
|
||||||
|
And = 0x1501,
|
||||||
|
AndReverse = 0x1502,
|
||||||
|
Copy = 0x1503,
|
||||||
|
AndInverted = 0x1504,
|
||||||
|
Noop = 0x1505,
|
||||||
|
Xor = 0x1506,
|
||||||
|
Or = 0x1507,
|
||||||
|
Nor = 0x1508,
|
||||||
|
Equiv = 0x1509,
|
||||||
|
Invert = 0x150A,
|
||||||
|
OrReverse = 0x150B,
|
||||||
|
CopyInverted = 0x150C,
|
||||||
|
OrInverted = 0x150D,
|
||||||
|
Nand = 0x150E,
|
||||||
|
Set = 0x150F
|
||||||
|
} func;
|
||||||
|
};
|
||||||
|
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
.tessellationRegisters = {*registers.patchSize, *registers.tessellationParameters},
|
.tessellationRegisters = {*registers.patchSize, *registers.tessellationParameters},
|
||||||
.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},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,7 +190,7 @@ 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<0x4B3, u32> depthTestEnable;
|
Register<0x4B3, u32> depthTestEnable;
|
||||||
Register<0x4B9, u32> independentBlendEnable;
|
Register<0x4B9, u32> blendStatePerTargetEnable;
|
||||||
Register<0x4BA, u32> depthWriteEnable;
|
Register<0x4BA, u32> depthWriteEnable;
|
||||||
Register<0x4BB, u32> alphaTestEnable;
|
Register<0x4BB, u32> alphaTestEnable;
|
||||||
Register<0x4C3, type::CompareFunc> depthFunc;
|
Register<0x4C3, type::CompareFunc> depthFunc;
|
||||||
@ -206,22 +206,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
};
|
};
|
||||||
Register<0x4C7, std::array<float, type::BlendColorChannelCount>> blendConsts;
|
Register<0x4C7, std::array<float, type::BlendColorChannelCount>> blendConsts;
|
||||||
|
|
||||||
struct BlendStateCommon {
|
Register<0x4CF, type::Blend> blend;
|
||||||
u32 seperateAlpha; // 0x4CF
|
|
||||||
type::BlendOp colorOp; // 0x4D0
|
|
||||||
type::BlendFactor colorSrcFactor; // 0x4D1
|
|
||||||
type::BlendFactor colorDstFactor; // 0x4D2
|
|
||||||
type::BlendOp alphaOp; // 0x4D3
|
|
||||||
type::BlendFactor alphaSrcFactor; // 0x4D4
|
|
||||||
u32 pad; // 0x4D5
|
|
||||||
type::BlendFactor alphaDstFactor; // 0x4D6
|
|
||||||
|
|
||||||
u32 enable; // 0x4D7
|
|
||||||
};
|
|
||||||
Register<0x4CF, BlendStateCommon> blendStateCommon;
|
|
||||||
|
|
||||||
Register<0x4D8, std::array<u32, type::ColorTargetCount>> rtBlendEnable;
|
|
||||||
|
|
||||||
Register<0x4E0, u32> stencilTestEnable;
|
Register<0x4E0, u32> stencilTestEnable;
|
||||||
|
|
||||||
Register<0x4E1, type::StencilOps> stencilOps;
|
Register<0x4E1, type::StencilOps> stencilOps;
|
||||||
@ -336,14 +321,10 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
|
|
||||||
Register<0x66F, u32> depthBoundsTestEnable;
|
Register<0x66F, u32> depthBoundsTestEnable;
|
||||||
|
|
||||||
struct ColorLogicOp {
|
Register<0x671, type::LogicOp> logicOp;
|
||||||
u32 enable;
|
|
||||||
type::ColorLogicOp type;
|
|
||||||
};
|
|
||||||
Register<0x671, ColorLogicOp> colorLogicOp;
|
|
||||||
|
|
||||||
Register<0x674, type::ClearSurface> clearSurface;
|
Register<0x674, type::ClearSurface> clearSurface;
|
||||||
Register<0x680, std::array<type::ColorWriteMask, type::ColorTargetCount>> colorWriteMask;
|
Register<0x680, std::array<type::CtWrite, type::ColorTargetCount>> ctWrites;
|
||||||
|
|
||||||
struct Semaphore {
|
struct Semaphore {
|
||||||
Address address; // 0x6C0
|
Address address; // 0x6C0
|
||||||
@ -354,17 +335,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
|
|
||||||
Register<0x700, std::array<type::VertexStream, type::VertexStreamCount>> vertexStreams;
|
Register<0x700, std::array<type::VertexStream, type::VertexStreamCount>> vertexStreams;
|
||||||
|
|
||||||
struct IndependentBlend {
|
Register<0x780, std::array<type::BlendPerTarget, type::ColorTargetCount>> blendPerTargets;
|
||||||
u32 seperateAlpha;
|
|
||||||
type::BlendOp colorOp;
|
|
||||||
type::BlendFactor colorSrcFactor;
|
|
||||||
type::BlendFactor colorDstFactor;
|
|
||||||
type::BlendOp alphaOp;
|
|
||||||
type::BlendFactor alphaSrcFactor;
|
|
||||||
type::BlendFactor alphaDstFactor;
|
|
||||||
u32 _pad_;
|
|
||||||
};
|
|
||||||
Register<0x780, std::array<IndependentBlend, type::ColorTargetCount>> independentBlend;
|
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user