diff --git a/app/src/main/cpp/skyline/gpu/cache/graphics_pipeline_cache.cpp b/app/src/main/cpp/skyline/gpu/cache/graphics_pipeline_cache.cpp index db682dc5..bb0cd105 100644 --- a/app/src/main/cpp/skyline/gpu/cache/graphics_pipeline_cache.cpp +++ b/app/src/main/cpp/skyline/gpu/cache/graphics_pipeline_cache.cpp @@ -36,8 +36,13 @@ namespace skyline::gpu::cache { colorBlendState.pAttachments = colorBlendAttachments.data(); - for (auto &colorAttachment : state.colorAttachments) - colorAttachments.emplace_back(AttachmentMetadata{colorAttachment->format->vkFormat, colorAttachment->texture->sampleCount}); + for (auto &colorAttachment : state.colorAttachments) { + if (colorAttachment) + colorAttachments.emplace_back(AttachmentMetadata{colorAttachment->format->vkFormat, colorAttachment->texture->sampleCount}); + else + colorAttachments.emplace_back(AttachmentMetadata{vk::Format::eUndefined, vk::SampleCountFlagBits::e1}); + } + if (state.depthStencilAttachment) depthStencilAttachment.emplace(AttachmentMetadata{state.depthStencilAttachment->format->vkFormat, state.depthStencilAttachment->texture->sampleCount}); } @@ -171,8 +176,10 @@ namespace skyline::gpu::cache { HASH(key.colorAttachments.size()); for (const auto &attachment : key.colorAttachments) { - HASH(attachment->format->vkFormat); - HASH(attachment->texture->sampleCount); + if (attachment) { + HASH(attachment->format->vkFormat); + HASH(attachment->texture->sampleCount); + } } HASH(key.depthStencilAttachment != nullptr); @@ -342,21 +349,28 @@ namespace skyline::gpu::cache { boost::container::small_vector attachmentDescriptions; boost::container::small_vector attachmentReferences; - auto pushAttachment{[&](const TextureView &view) { - attachmentDescriptions.push_back(vk::AttachmentDescription{ - .format = view.format->vkFormat, - .samples = view.texture->sampleCount, - .loadOp = vk::AttachmentLoadOp::eLoad, - .storeOp = vk::AttachmentStoreOp::eStore, - .stencilLoadOp = vk::AttachmentLoadOp::eLoad, - .stencilStoreOp = vk::AttachmentStoreOp::eStore, - .initialLayout = view.texture->layout, - .finalLayout = view.texture->layout, - }); - attachmentReferences.push_back(vk::AttachmentReference{ - .attachment = static_cast(attachmentDescriptions.size() - 1), - .layout = view.texture->layout, - }); + auto pushAttachment{[&](TextureView *view) { + if (view) { + attachmentDescriptions.push_back(vk::AttachmentDescription{ + .format = view->format->vkFormat, + .samples = view->texture->sampleCount, + .loadOp = vk::AttachmentLoadOp::eLoad, + .storeOp = vk::AttachmentStoreOp::eStore, + .stencilLoadOp = vk::AttachmentLoadOp::eLoad, + .stencilStoreOp = vk::AttachmentStoreOp::eStore, + .initialLayout = view->texture->layout, + .finalLayout = view->texture->layout, + }); + attachmentReferences.push_back(vk::AttachmentReference{ + .attachment = static_cast(attachmentDescriptions.size() - 1), + .layout = view->texture->layout, + }); + } else { + attachmentReferences.push_back(vk::AttachmentReference{ + .attachment = VK_ATTACHMENT_UNUSED, + .layout = vk::ImageLayout::eUndefined, + }); + } }}; vk::SubpassDescription subpassDescription{ @@ -364,10 +378,10 @@ namespace skyline::gpu::cache { }; for (auto &colorAttachment : state.colorAttachments) - pushAttachment(*colorAttachment); + pushAttachment(colorAttachment); if (state.depthStencilAttachment) { - pushAttachment(*state.depthStencilAttachment); + pushAttachment(state.depthStencilAttachment); subpassDescription.pColorAttachments = attachmentReferences.data(); subpassDescription.colorAttachmentCount = static_cast(attachmentReferences.size() - 1); diff --git a/app/src/main/cpp/skyline/gpu/interconnect/command_nodes.cpp b/app/src/main/cpp/skyline/gpu/interconnect/command_nodes.cpp index 93018375..d3b0ac5b 100644 --- a/app/src/main/cpp/skyline/gpu/interconnect/command_nodes.cpp +++ b/app/src/main/cpp/skyline/gpu/interconnect/command_nodes.cpp @@ -128,10 +128,16 @@ namespace skyline::gpu::interconnect::node { auto colorAttachmentsOffset{attachmentReferences.size() * sizeof(vk::AttachmentReference)}; // Calculate new base offset as it has changed since we pushed the input attachments for (auto &attachment : colorAttachments) { - attachmentReferences.push_back(vk::AttachmentReference{ - .attachment = AddAttachment(attachment, gpu), - .layout = attachment->texture->layout, - }); + if (attachment) + attachmentReferences.push_back(vk::AttachmentReference{ + .attachment = AddAttachment(attachment, gpu), + .layout = attachment->texture->layout, + }); + else + attachmentReferences.push_back(vk::AttachmentReference{ + .attachment = VK_ATTACHMENT_UNUSED, + .layout = vk::ImageLayout::eUndefined, + }); } auto depthStencilAttachmentOffset{attachmentReferences.size() * sizeof(vk::AttachmentReference)}; diff --git a/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/pipeline_state.cpp b/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/pipeline_state.cpp index 91b2a018..a48190bb 100644 --- a/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/pipeline_state.cpp +++ b/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/pipeline_state.cpp @@ -470,6 +470,7 @@ namespace skyline::gpu::interconnect::maxwell3d { bindFunc(depthStencilRegisters); bindFunc(colorBlendRegisters); bindFunc(globalShaderConfigRegisters); + manager.Bind(handle, ctSelect); } PipelineState::PipelineState(dirty::Handle dirtyHandle, DirtyManager &manager, const EngineRegisters &engine) @@ -483,7 +484,8 @@ namespace skyline::gpu::interconnect::maxwell3d { depthStencil{manager, engine.depthStencilRegisters}, colorBlend{manager, engine.colorBlendRegisters}, directState{engine.inputAssemblyRegisters}, - globalShaderConfig{engine.globalShaderConfigRegisters} {} + globalShaderConfig{engine.globalShaderConfigRegisters}, + ctSelect{engine.ctSelect} {} void PipelineState::Flush(InterconnectContext &ctx, StateUpdateBuilder &builder) { std::array shaderBinaries; @@ -494,11 +496,17 @@ namespace skyline::gpu::interconnect::maxwell3d { } colorAttachments.clear(); - for (auto &colorRenderTarget : colorRenderTargets) - if (auto view{colorRenderTarget.UpdateGet(ctx, packedState).view}) - colorAttachments.push_back(view.get()); + for (size_t i{}; i < ctSelect.count; i++) { + const auto &view{colorRenderTargets[ctSelect[i]].UpdateGet(ctx, packedState).view.get()}; + colorAttachments.push_back(view); + + if (view) + ctx.executor.AttachTexture(view); + } depthAttachment = depthRenderTarget.UpdateGet(ctx, packedState).view.get(); + if (depthAttachment) + ctx.executor.AttachTexture(depthAttachment); vertexInput.Update(packedState); directState.inputAssembly.Update(packedState); diff --git a/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/pipeline_state.h b/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/pipeline_state.h index 3135140a..862692a3 100644 --- a/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/pipeline_state.h +++ b/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/pipeline_state.h @@ -284,6 +284,7 @@ namespace skyline::gpu::interconnect::maxwell3d { DepthStencilState::EngineRegisters depthStencilRegisters; ColorBlendState::EngineRegisters colorBlendRegisters; GlobalShaderConfigState::EngineRegisters globalShaderConfigRegisters; + const engine::CtSelect &ctSelect; void DirtyBind(DirtyManager &manager, dirty::Handle handle) const; }; @@ -304,6 +305,7 @@ namespace skyline::gpu::interconnect::maxwell3d { dirty::ManualDirtyState depthStencil; dirty::ManualDirtyState colorBlend; GlobalShaderConfigState globalShaderConfig; + const engine::CtSelect &ctSelect; public: DirectPipelineState directState; diff --git a/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell/types.h b/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell/types.h index ed3033ff..b7c1d76e 100644 --- a/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell/types.h +++ b/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell/types.h @@ -451,7 +451,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d::type { u8 target6 : 3; u8 target7 : 3; - size_t operator[](size_t index) { + size_t operator[](size_t index) const { switch (index) { case 0: return target0; diff --git a/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell_3d.cpp b/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell_3d.cpp index 90fa51eb..c8496e43 100644 --- a/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell_3d.cpp +++ b/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell_3d.cpp @@ -23,7 +23,8 @@ 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, *registers.pointSize, *registers.zClipRange}, .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, *registers.apiMandatedEarlyZEnable} + .globalShaderConfigRegisters = {*registers.postVtgShaderAttributeSkipMask, *registers.bindlessTexture, *registers.apiMandatedEarlyZEnable}, + .ctSelect = *registers.ctSelect }; }