Don't populate colour targets with an empty write mask

Avoids breaking VK spec in BOTW, as it has the same colour attachment bound twice, but the former is masked out entirely.
This commit is contained in:
Billy Laws 2023-02-20 17:32:21 +00:00
parent 8baf06c9ab
commit 5e8cdfda92
3 changed files with 12 additions and 2 deletions

View File

@ -300,6 +300,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
void ColorBlendState::Flush(PackedPipelineState &packedState) { void ColorBlendState::Flush(PackedPipelineState &packedState) {
packedState.logicOpEnable = engine->logicOp.enable; packedState.logicOpEnable = engine->logicOp.enable;
packedState.SetLogicOp(engine->logicOp.func); packedState.SetLogicOp(engine->logicOp.func);
writtenCtMask.reset();
for (u32 i{}; i < engine::ColorTargetCount; i++) { for (u32 i{}; i < engine::ColorTargetCount; i++) {
auto ctWrite{[&]() { auto ctWrite{[&]() {
@ -315,6 +316,8 @@ namespace skyline::gpu::interconnect::maxwell3d {
packedState.SetAttachmentBlendState(i, enable, ctWrite, engine->blendPerTargets[i]); packedState.SetAttachmentBlendState(i, enable, ctWrite, engine->blendPerTargets[i]);
else else
packedState.SetAttachmentBlendState(i, enable, ctWrite, engine->blend); packedState.SetAttachmentBlendState(i, enable, ctWrite, engine->blend);
writtenCtMask.set(i, ctWrite.Any());
} }
} }
@ -392,10 +395,12 @@ namespace skyline::gpu::interconnect::maxwell3d {
shaderBinaries[i] = stage.binary; shaderBinaries[i] = stage.binary;
} }
colorBlend.Update(packedState);
colorAttachments.clear(); colorAttachments.clear();
packedState.colorRenderTargetFormats = {}; packedState.colorRenderTargetFormats = {};
for (size_t i{}; i < engine::ColorTargetCount; i++) { for (size_t i{}; i < engine::ColorTargetCount; i++) {
if (i < ctSelect.count) { if (i < ctSelect.count && colorBlend.Get().writtenCtMask.test(i)) {
const auto &rt{colorRenderTargets[ctSelect[i]].UpdateGet(ctx, packedState)}; const auto &rt{colorRenderTargets[ctSelect[i]].UpdateGet(ctx, packedState)};
const auto view{rt.view.get()}; const auto view{rt.view.get()};
packedState.SetColorRenderTargetFormat(ctSelect[i], rt.format); packedState.SetColorRenderTargetFormat(ctSelect[i], rt.format);
@ -417,7 +422,6 @@ namespace skyline::gpu::interconnect::maxwell3d {
tessellation.Update(packedState); tessellation.Update(packedState);
rasterization.Update(packedState); rasterization.Update(packedState);
depthStencil.Update(packedState); depthStencil.Update(packedState);
colorBlend.Update(packedState);
transformFeedback.Update(packedState); transformFeedback.Update(packedState);
globalShaderConfig.Update(packedState); globalShaderConfig.Update(packedState);

View File

@ -234,6 +234,8 @@ namespace skyline::gpu::interconnect::maxwell3d {
dirty::BoundSubresource<EngineRegisters> engine; dirty::BoundSubresource<EngineRegisters> engine;
public: public:
std::bitset<engine::ColorTargetCount> writtenCtMask{};
ColorBlendState(dirty::Handle dirtyHandle, DirtyManager &manager, const EngineRegisters &engine); ColorBlendState(dirty::Handle dirtyHandle, DirtyManager &manager, const EngineRegisters &engine);
void Flush(PackedPipelineState &packedState); void Flush(PackedPipelineState &packedState);

View File

@ -718,6 +718,10 @@ namespace skyline::soc::gm20b::engine::maxwell3d::type {
static_assert(sizeof(ViewportClipControl) == sizeof(u32)); static_assert(sizeof(ViewportClipControl) == sizeof(u32));
union CtWrite { union CtWrite {
bool Any() const {
return rEnable || gEnable || bEnable || aEnable;
}
u32 raw; u32 raw;
struct { struct {