shader: Fix render targets with null attachments

This commit is contained in:
ReinUsesLisp 2021-04-22 21:05:10 -03:00 committed by ameerj
parent 155be4a8d3
commit 7a1f296cda
2 changed files with 34 additions and 26 deletions

View file

@ -105,6 +105,17 @@ RenderPassKey MakeRenderPassKey(const FixedPipelineState& state) {
key.samples = MaxwellToVK::MsaaMode(state.msaa_mode); key.samples = MaxwellToVK::MsaaMode(state.msaa_mode);
return key; return key;
} }
size_t NumAttachments(const FixedPipelineState& state) {
size_t num{};
for (size_t index = 0; index < Maxwell::NumRenderTargets; ++index) {
const auto format{static_cast<Tegra::RenderTargetFormat>(state.color_formats[index])};
if (format != Tegra::RenderTargetFormat::NONE) {
num = index + 1;
}
}
return num;
}
} // Anonymous namespace } // Anonymous namespace
GraphicsPipeline::GraphicsPipeline(Tegra::Engines::Maxwell3D& maxwell3d_, GraphicsPipeline::GraphicsPipeline(Tegra::Engines::Maxwell3D& maxwell3d_,
@ -418,17 +429,14 @@ void GraphicsPipeline::MakePipeline(const Device& device, VkRenderPass render_pa
.maxDepthBounds = 0.0f, .maxDepthBounds = 0.0f,
}; };
static_vector<VkPipelineColorBlendAttachmentState, Maxwell::NumRenderTargets> cb_attachments; static_vector<VkPipelineColorBlendAttachmentState, Maxwell::NumRenderTargets> cb_attachments;
for (size_t index = 0; index < Maxwell::NumRenderTargets; ++index) { const size_t num_attachments{NumAttachments(state)};
for (size_t index = 0; index < num_attachments; ++index) {
static constexpr std::array mask_table{ static constexpr std::array mask_table{
VK_COLOR_COMPONENT_R_BIT, VK_COLOR_COMPONENT_R_BIT,
VK_COLOR_COMPONENT_G_BIT, VK_COLOR_COMPONENT_G_BIT,
VK_COLOR_COMPONENT_B_BIT, VK_COLOR_COMPONENT_B_BIT,
VK_COLOR_COMPONENT_A_BIT, VK_COLOR_COMPONENT_A_BIT,
}; };
const auto format{static_cast<Tegra::RenderTargetFormat>(state.color_formats[index])};
if (format == Tegra::RenderTargetFormat::NONE) {
continue;
}
const auto& blend{state.attachments[index]}; const auto& blend{state.attachments[index]};
const std::array mask{blend.Mask()}; const std::array mask{blend.Mask()};
VkColorComponentFlags write_mask{}; VkColorComponentFlags write_mask{};

View file

@ -16,18 +16,6 @@ namespace Vulkan {
namespace { namespace {
using VideoCore::Surface::PixelFormat; using VideoCore::Surface::PixelFormat;
constexpr std::array ATTACHMENT_REFERENCES{
VkAttachmentReference{0, VK_IMAGE_LAYOUT_GENERAL},
VkAttachmentReference{1, VK_IMAGE_LAYOUT_GENERAL},
VkAttachmentReference{2, VK_IMAGE_LAYOUT_GENERAL},
VkAttachmentReference{3, VK_IMAGE_LAYOUT_GENERAL},
VkAttachmentReference{4, VK_IMAGE_LAYOUT_GENERAL},
VkAttachmentReference{5, VK_IMAGE_LAYOUT_GENERAL},
VkAttachmentReference{6, VK_IMAGE_LAYOUT_GENERAL},
VkAttachmentReference{7, VK_IMAGE_LAYOUT_GENERAL},
VkAttachmentReference{8, VK_IMAGE_LAYOUT_GENERAL},
};
VkAttachmentDescription AttachmentDescription(const Device& device, PixelFormat format, VkAttachmentDescription AttachmentDescription(const Device& device, PixelFormat format,
VkSampleCountFlagBits samples) { VkSampleCountFlagBits samples) {
using MaxwellToVK::SurfaceFormat; using MaxwellToVK::SurfaceFormat;
@ -54,17 +42,29 @@ VkRenderPass RenderPassCache::Get(const RenderPassKey& key) {
return *pair->second; return *pair->second;
} }
boost::container::static_vector<VkAttachmentDescription, 9> descriptions; boost::container::static_vector<VkAttachmentDescription, 9> descriptions;
std::array<VkAttachmentReference, 8> references{};
u32 num_attachments{};
u32 num_colors{};
for (size_t index = 0; index < key.color_formats.size(); ++index) { for (size_t index = 0; index < key.color_formats.size(); ++index) {
const PixelFormat format{key.color_formats[index]}; const PixelFormat format{key.color_formats[index]};
if (format == PixelFormat::Invalid) { const bool is_valid{format != PixelFormat::Invalid};
continue; references[index] = VkAttachmentReference{
} .attachment = is_valid ? num_colors : VK_ATTACHMENT_UNUSED,
.layout = VK_IMAGE_LAYOUT_GENERAL,
};
if (is_valid) {
descriptions.push_back(AttachmentDescription(*device, format, key.samples)); descriptions.push_back(AttachmentDescription(*device, format, key.samples));
num_attachments = static_cast<u32>(index + 1);
++num_colors;
} }
const size_t num_colors{descriptions.size()}; }
const VkAttachmentReference* depth_attachment{}; const bool has_depth{key.depth_format != PixelFormat::Invalid};
VkAttachmentReference depth_reference{};
if (key.depth_format != PixelFormat::Invalid) { if (key.depth_format != PixelFormat::Invalid) {
depth_attachment = &ATTACHMENT_REFERENCES[num_colors]; depth_reference = VkAttachmentReference{
.attachment = num_colors,
.layout = VK_IMAGE_LAYOUT_GENERAL,
};
descriptions.push_back(AttachmentDescription(*device, key.depth_format, key.samples)); descriptions.push_back(AttachmentDescription(*device, key.depth_format, key.samples));
} }
const VkSubpassDescription subpass{ const VkSubpassDescription subpass{
@ -72,10 +72,10 @@ VkRenderPass RenderPassCache::Get(const RenderPassKey& key) {
.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
.inputAttachmentCount = 0, .inputAttachmentCount = 0,
.pInputAttachments = nullptr, .pInputAttachments = nullptr,
.colorAttachmentCount = static_cast<u32>(num_colors), .colorAttachmentCount = num_attachments,
.pColorAttachments = num_colors != 0 ? ATTACHMENT_REFERENCES.data() : nullptr, .pColorAttachments = references.data(),
.pResolveAttachments = nullptr, .pResolveAttachments = nullptr,
.pDepthStencilAttachment = depth_attachment, .pDepthStencilAttachment = has_depth ? &depth_reference : nullptr,
.preserveAttachmentCount = 0, .preserveAttachmentCount = 0,
.pPreserveAttachments = nullptr, .pPreserveAttachments = nullptr,
}; };