diff options
| author | ReinUsesLisp <reinuseslisp@airmail.cc> | 2020-04-22 20:14:35 -0300 | 
|---|---|---|
| committer | ReinUsesLisp <reinuseslisp@airmail.cc> | 2020-04-23 17:34:16 -0300 | 
| commit | f665c921144264ba2ed0fef37d9db28d552a5511 (patch) | |
| tree | 27004ef3a0f66ded1364e916822174f57d3b7616 | |
| parent | 26f2820ae3f0c85cf4a6a2eb7ddcca70cdbd0a20 (diff) | |
vk_renderpass_cache: Pack renderpass cache key to 12 bytes
4 files changed, 59 insertions, 84 deletions
| diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 8332b42aa..45bd1fc6c 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -288,7 +288,7 @@ vk::Pipeline VKGraphicsPipeline::CreatePipeline(const RenderPassParams& renderpa      depth_stencil_ci.maxDepthBounds = 0.0f;      std::array<VkPipelineColorBlendAttachmentState, Maxwell::NumRenderTargets> cb_attachments; -    const std::size_t num_attachments = renderpass_params.color_attachments.size(); +    const auto num_attachments = static_cast<std::size_t>(renderpass_params.num_color_attachments);      for (std::size_t index = 0; index < num_attachments; ++index) {          static constexpr std::array COMPONENT_TABLE = {              VK_COLOR_COMPONENT_R_BIT, VK_COLOR_COMPONENT_G_BIT, VK_COLOR_COMPONENT_B_BIT, diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 8a1f57891..ef21b186b 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -1245,28 +1245,15 @@ std::size_t RasterizerVulkan::CalculateConstBufferSize(  }  RenderPassParams RasterizerVulkan::GetRenderPassParams(Texceptions texceptions) const { -    using namespace VideoCore::Surface; -      const auto& regs = system.GPU().Maxwell3D().regs; -    RenderPassParams renderpass_params; - -    for (std::size_t rt = 0; rt < static_cast<std::size_t>(regs.rt_control.count); ++rt) { -        const auto& rendertarget = regs.rt[rt]; -        if (rendertarget.Address() == 0 || rendertarget.format == Tegra::RenderTargetFormat::NONE) { -            continue; -        } -        renderpass_params.color_attachments.push_back(RenderPassParams::ColorAttachment{ -            static_cast<u32>(rt), PixelFormatFromRenderTargetFormat(rendertarget.format), -            texceptions[rt]}); -    } - -    renderpass_params.has_zeta = regs.zeta_enable; -    if (renderpass_params.has_zeta) { -        renderpass_params.zeta_pixel_format = PixelFormatFromDepthFormat(regs.zeta.format); -        renderpass_params.zeta_texception = texceptions[ZETA_TEXCEPTION_INDEX]; -    } - -    return renderpass_params; +    RenderPassParams params; +    params.num_color_attachments = static_cast<u8>(regs.rt_control.count); +    std::transform(regs.rt.begin(), regs.rt.end(), params.color_formats.begin(), +                   [](const auto& rt) { return static_cast<u8>(rt.format); }); +    params.texceptions = static_cast<u8>(texceptions.to_ullong()); +    params.zeta_format = regs.zeta_enable ? static_cast<u8>(regs.zeta.format) : 0; +    params.zeta_texception = texceptions[ZETA_TEXCEPTION_INDEX]; +    return params;  }  } // namespace Vulkan diff --git a/src/video_core/renderer_vulkan/vk_renderpass_cache.cpp b/src/video_core/renderer_vulkan/vk_renderpass_cache.cpp index 4e5286a69..3f71d005e 100644 --- a/src/video_core/renderer_vulkan/vk_renderpass_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_renderpass_cache.cpp @@ -2,9 +2,11 @@  // Licensed under GPLv2 or any later version  // Refer to the license.txt file included. +#include <cstring>  #include <memory>  #include <vector> +#include "common/cityhash.h"  #include "video_core/engines/maxwell_3d.h"  #include "video_core/renderer_vulkan/maxwell_to_vk.h"  #include "video_core/renderer_vulkan/vk_device.h" @@ -13,6 +15,15 @@  namespace Vulkan { +std::size_t RenderPassParams::Hash() const noexcept { +    const u64 hash = Common::CityHash64(reinterpret_cast<const char*>(this), sizeof *this); +    return static_cast<std::size_t>(hash); +} + +bool RenderPassParams::operator==(const RenderPassParams& rhs) const noexcept { +    return std::memcmp(&rhs, this, sizeof *this) == 0; +} +  VKRenderPassCache::VKRenderPassCache(const VKDevice& device) : device{device} {}  VKRenderPassCache::~VKRenderPassCache() = default; @@ -27,20 +38,22 @@ VkRenderPass VKRenderPassCache::GetRenderPass(const RenderPassParams& params) {  }  vk::RenderPass VKRenderPassCache::CreateRenderPass(const RenderPassParams& params) const { +    using namespace VideoCore::Surface;      std::vector<VkAttachmentDescription> descriptors;      std::vector<VkAttachmentReference> color_references; -    for (std::size_t rt = 0; rt < params.color_attachments.size(); ++rt) { -        const auto attachment = params.color_attachments[rt]; -        const auto format = -            MaxwellToVK::SurfaceFormat(device, FormatType::Optimal, attachment.pixel_format); +    const std::size_t num_attachments = static_cast<std::size_t>(params.num_color_attachments); +    for (std::size_t rt = 0; rt < num_attachments; ++rt) { +        const auto guest_format = static_cast<Tegra::RenderTargetFormat>(params.color_formats[rt]); +        const PixelFormat pixel_format = PixelFormatFromRenderTargetFormat(guest_format); +        const auto format = MaxwellToVK::SurfaceFormat(device, FormatType::Optimal, pixel_format);          ASSERT_MSG(format.attachable, "Trying to attach a non-attachable format with format={}", -                   static_cast<u32>(attachment.pixel_format)); +                   static_cast<int>(pixel_format)); -        // TODO(Rodrigo): Add eMayAlias when it's needed. -        const auto color_layout = attachment.is_texception -                                      ? VK_IMAGE_LAYOUT_GENERAL -                                      : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; +        // TODO(Rodrigo): Add MAY_ALIAS_BIT when it's needed. +        const VkImageLayout color_layout = ((params.texceptions >> rt) & 1) != 0 +                                               ? VK_IMAGE_LAYOUT_GENERAL +                                               : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;          VkAttachmentDescription& descriptor = descriptors.emplace_back();          descriptor.flags = VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT;          descriptor.format = format.format; @@ -58,15 +71,17 @@ vk::RenderPass VKRenderPassCache::CreateRenderPass(const RenderPassParams& param      }      VkAttachmentReference zeta_attachment_ref; -    if (params.has_zeta) { -        const auto format = -            MaxwellToVK::SurfaceFormat(device, FormatType::Optimal, params.zeta_pixel_format); +    const bool has_zeta = params.zeta_format != 0; +    if (has_zeta) { +        const auto guest_format = static_cast<Tegra::DepthFormat>(params.zeta_format); +        const PixelFormat pixel_format = PixelFormatFromDepthFormat(guest_format); +        const auto format = MaxwellToVK::SurfaceFormat(device, FormatType::Optimal, pixel_format);          ASSERT_MSG(format.attachable, "Trying to attach a non-attachable format with format={}", -                   static_cast<u32>(params.zeta_pixel_format)); +                   static_cast<int>(pixel_format)); -        const auto zeta_layout = params.zeta_texception -                                     ? VK_IMAGE_LAYOUT_GENERAL -                                     : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; +        const VkImageLayout zeta_layout = params.zeta_texception != 0 +                                              ? VK_IMAGE_LAYOUT_GENERAL +                                              : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;          VkAttachmentDescription& descriptor = descriptors.emplace_back();          descriptor.flags = 0;          descriptor.format = format.format; @@ -78,7 +93,7 @@ vk::RenderPass VKRenderPassCache::CreateRenderPass(const RenderPassParams& param          descriptor.initialLayout = zeta_layout;          descriptor.finalLayout = zeta_layout; -        zeta_attachment_ref.attachment = static_cast<u32>(params.color_attachments.size()); +        zeta_attachment_ref.attachment = static_cast<u32>(num_attachments);          zeta_attachment_ref.layout = zeta_layout;      } @@ -90,7 +105,7 @@ vk::RenderPass VKRenderPassCache::CreateRenderPass(const RenderPassParams& param      subpass_description.colorAttachmentCount = static_cast<u32>(color_references.size());      subpass_description.pColorAttachments = color_references.data();      subpass_description.pResolveAttachments = nullptr; -    subpass_description.pDepthStencilAttachment = params.has_zeta ? &zeta_attachment_ref : nullptr; +    subpass_description.pDepthStencilAttachment = has_zeta ? &zeta_attachment_ref : nullptr;      subpass_description.preserveAttachmentCount = 0;      subpass_description.pPreserveAttachments = nullptr; @@ -101,7 +116,7 @@ vk::RenderPass VKRenderPassCache::CreateRenderPass(const RenderPassParams& param          stage |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;      } -    if (params.has_zeta) { +    if (has_zeta) {          access |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |                    VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;          stage |= VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; diff --git a/src/video_core/renderer_vulkan/vk_renderpass_cache.h b/src/video_core/renderer_vulkan/vk_renderpass_cache.h index 921b6efb5..0e988b26b 100644 --- a/src/video_core/renderer_vulkan/vk_renderpass_cache.h +++ b/src/video_core/renderer_vulkan/vk_renderpass_cache.h @@ -4,8 +4,7 @@  #pragma once -#include <memory> -#include <tuple> +#include <type_traits>  #include <unordered_map>  #include <boost/container/static_vector.hpp> @@ -19,51 +18,25 @@ namespace Vulkan {  class VKDevice; -// TODO(Rodrigo): Optimize this structure for faster hashing -  struct RenderPassParams { -    struct ColorAttachment { -        u32 index = 0; -        VideoCore::Surface::PixelFormat pixel_format = VideoCore::Surface::PixelFormat::Invalid; -        bool is_texception = false; - -        std::size_t Hash() const noexcept { -            return static_cast<std::size_t>(pixel_format) | -                   static_cast<std::size_t>(is_texception) << 6 | -                   static_cast<std::size_t>(index) << 7; -        } - -        bool operator==(const ColorAttachment& rhs) const noexcept { -            return std::tie(index, pixel_format, is_texception) == -                   std::tie(rhs.index, rhs.pixel_format, rhs.is_texception); -        } -    }; - -    boost::container::static_vector<ColorAttachment, -                                    Tegra::Engines::Maxwell3D::Regs::NumRenderTargets> -        color_attachments{}; -    // TODO(Rodrigo): Unify has_zeta into zeta_pixel_format and zeta_component_type. -    VideoCore::Surface::PixelFormat zeta_pixel_format = VideoCore::Surface::PixelFormat::Invalid; -    bool has_zeta = false; -    bool zeta_texception = false; - -    std::size_t Hash() const noexcept { -        std::size_t hash = 0; -        for (const auto& rt : color_attachments) { -            boost::hash_combine(hash, rt.Hash()); -        } -        boost::hash_combine(hash, zeta_pixel_format); -        boost::hash_combine(hash, has_zeta); -        boost::hash_combine(hash, zeta_texception); -        return hash; -    } +    u8 num_color_attachments; +    std::array<u8, Tegra::Engines::Maxwell3D::Regs::NumRenderTargets> color_formats; +    u8 texceptions; + +    u8 zeta_format; +    u8 zeta_texception; + +    std::size_t Hash() const noexcept; + +    bool operator==(const RenderPassParams& rhs) const noexcept; -    bool operator==(const RenderPassParams& rhs) const { -        return std::tie(color_attachments, zeta_pixel_format, has_zeta, zeta_texception) == -               std::tie(rhs.color_attachments, rhs.zeta_pixel_format, rhs.has_zeta, -                        rhs.zeta_texception); +    bool operator!=(const RenderPassParams& rhs) const noexcept { +        return !operator==(rhs);      }  }; +static_assert(std::has_unique_object_representations_v<RenderPassParams>); +static_assert(std::is_trivially_copyable_v<RenderPassParams>); +static_assert(std::is_trivially_constructible_v<RenderPassParams>);  } // namespace Vulkan | 
