mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-11-26 21:34:16 +01:00
Use ctSelect register for colour targets and impl null color attachments
Some games have invalid colour attachments sandwiched inbetween valid ones, these need to be skipped in Vulkan with UNUSED_ATTACHMENT
This commit is contained in:
parent
38aad21d29
commit
f42a0df72c
@ -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<vk::AttachmentDescription, 8> attachmentDescriptions;
|
||||
boost::container::small_vector<vk::AttachmentReference, 8> 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<u32>(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<u32>(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<u32>(attachmentReferences.size() - 1);
|
||||
|
@ -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)};
|
||||
|
@ -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<ShaderBinary, engine::PipelineCount> 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);
|
||||
|
@ -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<DepthStencilState> depthStencil;
|
||||
dirty::ManualDirtyState<ColorBlendState> colorBlend;
|
||||
GlobalShaderConfigState globalShaderConfig;
|
||||
const engine::CtSelect &ctSelect;
|
||||
|
||||
public:
|
||||
DirectPipelineState directState;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
};
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user