diff options
| author | 2020-06-09 21:52:15 -0400 | |
|---|---|---|
| committer | 2020-06-09 21:52:15 -0400 | |
| commit | 83e3b77ed7eaa12ec497fd7d978c2e889c5d14db (patch) | |
| tree | 2940fc6a036c7b1f5ecc13aca6248ba657ed48f4 /src/video_core/renderer_vulkan | |
| parent | Merge pull request #4040 from ReinUsesLisp/nv-transform-feedback (diff) | |
| parent | texture_cache: Port original code management for 2D vs 3D textures (diff) | |
| download | yuzu-83e3b77ed7eaa12ec497fd7d978c2e889c5d14db.tar.gz yuzu-83e3b77ed7eaa12ec497fd7d978c2e889c5d14db.tar.xz yuzu-83e3b77ed7eaa12ec497fd7d978c2e889c5d14db.zip | |
Merge pull request #4027 from ReinUsesLisp/3d-slices
texture_cache: Implement rendering to 3D textures
Diffstat (limited to 'src/video_core/renderer_vulkan')
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_rasterizer.cpp | 9 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_texture_cache.cpp | 76 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_texture_cache.h | 33 |
3 files changed, 79 insertions, 39 deletions
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index d86c46412..19b8f9da3 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp | |||
| @@ -716,7 +716,7 @@ std::tuple<VkFramebuffer, VkExtent2D> RasterizerVulkan::ConfigureFramebuffers( | |||
| 716 | if (!view) { | 716 | if (!view) { |
| 717 | return false; | 717 | return false; |
| 718 | } | 718 | } |
| 719 | key.views.push_back(view->GetHandle()); | 719 | key.views.push_back(view->GetAttachment()); |
| 720 | key.width = std::min(key.width, view->GetWidth()); | 720 | key.width = std::min(key.width, view->GetWidth()); |
| 721 | key.height = std::min(key.height, view->GetHeight()); | 721 | key.height = std::min(key.height, view->GetHeight()); |
| 722 | key.layers = std::min(key.layers, view->GetNumLayers()); | 722 | key.layers = std::min(key.layers, view->GetNumLayers()); |
| @@ -1137,8 +1137,8 @@ void RasterizerVulkan::SetupTexture(const Tegra::Texture::FullTextureInfo& textu | |||
| 1137 | auto view = texture_cache.GetTextureSurface(texture.tic, entry); | 1137 | auto view = texture_cache.GetTextureSurface(texture.tic, entry); |
| 1138 | ASSERT(!view->IsBufferView()); | 1138 | ASSERT(!view->IsBufferView()); |
| 1139 | 1139 | ||
| 1140 | const auto image_view = view->GetHandle(texture.tic.x_source, texture.tic.y_source, | 1140 | const VkImageView image_view = view->GetImageView(texture.tic.x_source, texture.tic.y_source, |
| 1141 | texture.tic.z_source, texture.tic.w_source); | 1141 | texture.tic.z_source, texture.tic.w_source); |
| 1142 | const auto sampler = sampler_cache.GetSampler(texture.tsc); | 1142 | const auto sampler = sampler_cache.GetSampler(texture.tsc); |
| 1143 | update_descriptor_queue.AddSampledImage(sampler, image_view); | 1143 | update_descriptor_queue.AddSampledImage(sampler, image_view); |
| 1144 | 1144 | ||
| @@ -1164,7 +1164,8 @@ void RasterizerVulkan::SetupImage(const Tegra::Texture::TICEntry& tic, const Ima | |||
| 1164 | 1164 | ||
| 1165 | UNIMPLEMENTED_IF(tic.IsBuffer()); | 1165 | UNIMPLEMENTED_IF(tic.IsBuffer()); |
| 1166 | 1166 | ||
| 1167 | const auto image_view = view->GetHandle(tic.x_source, tic.y_source, tic.z_source, tic.w_source); | 1167 | const VkImageView image_view = |
| 1168 | view->GetImageView(tic.x_source, tic.y_source, tic.z_source, tic.w_source); | ||
| 1168 | update_descriptor_queue.AddImage(image_view); | 1169 | update_descriptor_queue.AddImage(image_view); |
| 1169 | 1170 | ||
| 1170 | const auto image_layout = update_descriptor_queue.GetLastImageLayout(); | 1171 | const auto image_layout = update_descriptor_queue.GetLastImageLayout(); |
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index ea487b770..430031665 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp | |||
| @@ -167,6 +167,7 @@ VkImageCreateInfo GenerateImageCreateInfo(const VKDevice& device, const SurfaceP | |||
| 167 | ci.extent = {params.width, params.height, 1}; | 167 | ci.extent = {params.width, params.height, 1}; |
| 168 | break; | 168 | break; |
| 169 | case SurfaceTarget::Texture3D: | 169 | case SurfaceTarget::Texture3D: |
| 170 | ci.flags |= VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT; | ||
| 170 | ci.extent = {params.width, params.height, params.depth}; | 171 | ci.extent = {params.width, params.height, params.depth}; |
| 171 | break; | 172 | break; |
| 172 | case SurfaceTarget::TextureBuffer: | 173 | case SurfaceTarget::TextureBuffer: |
| @@ -176,6 +177,12 @@ VkImageCreateInfo GenerateImageCreateInfo(const VKDevice& device, const SurfaceP | |||
| 176 | return ci; | 177 | return ci; |
| 177 | } | 178 | } |
| 178 | 179 | ||
| 180 | u32 EncodeSwizzle(Tegra::Texture::SwizzleSource x_source, Tegra::Texture::SwizzleSource y_source, | ||
| 181 | Tegra::Texture::SwizzleSource z_source, Tegra::Texture::SwizzleSource w_source) { | ||
| 182 | return (static_cast<u32>(x_source) << 24) | (static_cast<u32>(y_source) << 16) | | ||
| 183 | (static_cast<u32>(z_source) << 8) | static_cast<u32>(w_source); | ||
| 184 | } | ||
| 185 | |||
| 179 | } // Anonymous namespace | 186 | } // Anonymous namespace |
| 180 | 187 | ||
| 181 | CachedSurface::CachedSurface(Core::System& system, const VKDevice& device, | 188 | CachedSurface::CachedSurface(Core::System& system, const VKDevice& device, |
| @@ -203,9 +210,11 @@ CachedSurface::CachedSurface(Core::System& system, const VKDevice& device, | |||
| 203 | } | 210 | } |
| 204 | 211 | ||
| 205 | // TODO(Rodrigo): Move this to a virtual function. | 212 | // TODO(Rodrigo): Move this to a virtual function. |
| 206 | main_view = CreateViewInner( | 213 | u32 num_layers = 1; |
| 207 | ViewParams(params.target, 0, static_cast<u32>(params.GetNumLayers()), 0, params.num_levels), | 214 | if (params.is_layered || params.target == SurfaceTarget::Texture3D) { |
| 208 | true); | 215 | num_layers = params.depth; |
| 216 | } | ||
| 217 | main_view = CreateView(ViewParams(params.target, 0, num_layers, 0, params.num_levels)); | ||
| 209 | } | 218 | } |
| 210 | 219 | ||
| 211 | CachedSurface::~CachedSurface() = default; | 220 | CachedSurface::~CachedSurface() = default; |
| @@ -253,12 +262,8 @@ void CachedSurface::DecorateSurfaceName() { | |||
| 253 | } | 262 | } |
| 254 | 263 | ||
| 255 | View CachedSurface::CreateView(const ViewParams& params) { | 264 | View CachedSurface::CreateView(const ViewParams& params) { |
| 256 | return CreateViewInner(params, false); | ||
| 257 | } | ||
| 258 | |||
| 259 | View CachedSurface::CreateViewInner(const ViewParams& params, bool is_proxy) { | ||
| 260 | // TODO(Rodrigo): Add name decorations | 265 | // TODO(Rodrigo): Add name decorations |
| 261 | return views[params] = std::make_shared<CachedSurfaceView>(device, *this, params, is_proxy); | 266 | return views[params] = std::make_shared<CachedSurfaceView>(device, *this, params); |
| 262 | } | 267 | } |
| 263 | 268 | ||
| 264 | void CachedSurface::UploadBuffer(const std::vector<u8>& staging_buffer) { | 269 | void CachedSurface::UploadBuffer(const std::vector<u8>& staging_buffer) { |
| @@ -342,18 +347,27 @@ VkImageSubresourceRange CachedSurface::GetImageSubresourceRange() const { | |||
| 342 | } | 347 | } |
| 343 | 348 | ||
| 344 | CachedSurfaceView::CachedSurfaceView(const VKDevice& device, CachedSurface& surface, | 349 | CachedSurfaceView::CachedSurfaceView(const VKDevice& device, CachedSurface& surface, |
| 345 | const ViewParams& params, bool is_proxy) | 350 | const ViewParams& params) |
| 346 | : VideoCommon::ViewBase{params}, params{surface.GetSurfaceParams()}, | 351 | : VideoCommon::ViewBase{params}, params{surface.GetSurfaceParams()}, |
| 347 | image{surface.GetImageHandle()}, buffer_view{surface.GetBufferViewHandle()}, | 352 | image{surface.GetImageHandle()}, buffer_view{surface.GetBufferViewHandle()}, |
| 348 | aspect_mask{surface.GetAspectMask()}, device{device}, surface{surface}, | 353 | aspect_mask{surface.GetAspectMask()}, device{device}, surface{surface}, |
| 349 | base_layer{params.base_layer}, num_layers{params.num_layers}, base_level{params.base_level}, | 354 | base_level{params.base_level}, num_levels{params.num_levels}, |
| 350 | num_levels{params.num_levels}, image_view_type{image ? GetImageViewType(params.target) | 355 | image_view_type{image ? GetImageViewType(params.target) : VK_IMAGE_VIEW_TYPE_1D} { |
| 351 | : VK_IMAGE_VIEW_TYPE_1D} {} | 356 | if (image_view_type == VK_IMAGE_VIEW_TYPE_3D) { |
| 357 | base_layer = 0; | ||
| 358 | num_layers = 1; | ||
| 359 | base_slice = params.base_layer; | ||
| 360 | num_slices = params.num_layers; | ||
| 361 | } else { | ||
| 362 | base_layer = params.base_layer; | ||
| 363 | num_layers = params.num_layers; | ||
| 364 | } | ||
| 365 | } | ||
| 352 | 366 | ||
| 353 | CachedSurfaceView::~CachedSurfaceView() = default; | 367 | CachedSurfaceView::~CachedSurfaceView() = default; |
| 354 | 368 | ||
| 355 | VkImageView CachedSurfaceView::GetHandle(SwizzleSource x_source, SwizzleSource y_source, | 369 | VkImageView CachedSurfaceView::GetImageView(SwizzleSource x_source, SwizzleSource y_source, |
| 356 | SwizzleSource z_source, SwizzleSource w_source) { | 370 | SwizzleSource z_source, SwizzleSource w_source) { |
| 357 | const u32 new_swizzle = EncodeSwizzle(x_source, y_source, z_source, w_source); | 371 | const u32 new_swizzle = EncodeSwizzle(x_source, y_source, z_source, w_source); |
| 358 | if (last_image_view && last_swizzle == new_swizzle) { | 372 | if (last_image_view && last_swizzle == new_swizzle) { |
| 359 | return last_image_view; | 373 | return last_image_view; |
| @@ -399,6 +413,11 @@ VkImageView CachedSurfaceView::GetHandle(SwizzleSource x_source, SwizzleSource y | |||
| 399 | }); | 413 | }); |
| 400 | } | 414 | } |
| 401 | 415 | ||
| 416 | if (image_view_type == VK_IMAGE_VIEW_TYPE_3D) { | ||
| 417 | ASSERT(base_slice == 0); | ||
| 418 | ASSERT(num_slices == params.depth); | ||
| 419 | } | ||
| 420 | |||
| 402 | VkImageViewCreateInfo ci; | 421 | VkImageViewCreateInfo ci; |
| 403 | ci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; | 422 | ci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; |
| 404 | ci.pNext = nullptr; | 423 | ci.pNext = nullptr; |
| @@ -417,6 +436,35 @@ VkImageView CachedSurfaceView::GetHandle(SwizzleSource x_source, SwizzleSource y | |||
| 417 | return last_image_view = *image_view; | 436 | return last_image_view = *image_view; |
| 418 | } | 437 | } |
| 419 | 438 | ||
| 439 | VkImageView CachedSurfaceView::GetAttachment() { | ||
| 440 | if (render_target) { | ||
| 441 | return *render_target; | ||
| 442 | } | ||
| 443 | |||
| 444 | VkImageViewCreateInfo ci; | ||
| 445 | ci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; | ||
| 446 | ci.pNext = nullptr; | ||
| 447 | ci.flags = 0; | ||
| 448 | ci.image = surface.GetImageHandle(); | ||
| 449 | ci.format = surface.GetImage().GetFormat(); | ||
| 450 | ci.components = {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, | ||
| 451 | VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY}; | ||
| 452 | ci.subresourceRange.aspectMask = aspect_mask; | ||
| 453 | ci.subresourceRange.baseMipLevel = base_level; | ||
| 454 | ci.subresourceRange.levelCount = num_levels; | ||
| 455 | if (image_view_type == VK_IMAGE_VIEW_TYPE_3D) { | ||
| 456 | ci.viewType = num_slices > 1 ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D; | ||
| 457 | ci.subresourceRange.baseArrayLayer = base_slice; | ||
| 458 | ci.subresourceRange.layerCount = num_slices; | ||
| 459 | } else { | ||
| 460 | ci.viewType = image_view_type; | ||
| 461 | ci.subresourceRange.baseArrayLayer = base_layer; | ||
| 462 | ci.subresourceRange.layerCount = num_layers; | ||
| 463 | } | ||
| 464 | render_target = device.GetLogical().CreateImageView(ci); | ||
| 465 | return *render_target; | ||
| 466 | } | ||
| 467 | |||
| 420 | VKTextureCache::VKTextureCache(Core::System& system, VideoCore::RasterizerInterface& rasterizer, | 468 | VKTextureCache::VKTextureCache(Core::System& system, VideoCore::RasterizerInterface& rasterizer, |
| 421 | const VKDevice& device, VKResourceManager& resource_manager, | 469 | const VKDevice& device, VKResourceManager& resource_manager, |
| 422 | VKMemoryManager& memory_manager, VKScheduler& scheduler, | 470 | VKMemoryManager& memory_manager, VKScheduler& scheduler, |
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h index f211ccb1e..807e26c8a 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.h +++ b/src/video_core/renderer_vulkan/vk_texture_cache.h | |||
| @@ -91,7 +91,6 @@ protected: | |||
| 91 | void DecorateSurfaceName(); | 91 | void DecorateSurfaceName(); |
| 92 | 92 | ||
| 93 | View CreateView(const ViewParams& params) override; | 93 | View CreateView(const ViewParams& params) override; |
| 94 | View CreateViewInner(const ViewParams& params, bool is_proxy); | ||
| 95 | 94 | ||
| 96 | private: | 95 | private: |
| 97 | void UploadBuffer(const std::vector<u8>& staging_buffer); | 96 | void UploadBuffer(const std::vector<u8>& staging_buffer); |
| @@ -120,23 +119,20 @@ private: | |||
| 120 | class CachedSurfaceView final : public VideoCommon::ViewBase { | 119 | class CachedSurfaceView final : public VideoCommon::ViewBase { |
| 121 | public: | 120 | public: |
| 122 | explicit CachedSurfaceView(const VKDevice& device, CachedSurface& surface, | 121 | explicit CachedSurfaceView(const VKDevice& device, CachedSurface& surface, |
| 123 | const ViewParams& params, bool is_proxy); | 122 | const ViewParams& params); |
| 124 | ~CachedSurfaceView(); | 123 | ~CachedSurfaceView(); |
| 125 | 124 | ||
| 126 | VkImageView GetHandle(Tegra::Texture::SwizzleSource x_source, | 125 | VkImageView GetImageView(Tegra::Texture::SwizzleSource x_source, |
| 127 | Tegra::Texture::SwizzleSource y_source, | 126 | Tegra::Texture::SwizzleSource y_source, |
| 128 | Tegra::Texture::SwizzleSource z_source, | 127 | Tegra::Texture::SwizzleSource z_source, |
| 129 | Tegra::Texture::SwizzleSource w_source); | 128 | Tegra::Texture::SwizzleSource w_source); |
| 129 | |||
| 130 | VkImageView GetAttachment(); | ||
| 130 | 131 | ||
| 131 | bool IsSameSurface(const CachedSurfaceView& rhs) const { | 132 | bool IsSameSurface(const CachedSurfaceView& rhs) const { |
| 132 | return &surface == &rhs.surface; | 133 | return &surface == &rhs.surface; |
| 133 | } | 134 | } |
| 134 | 135 | ||
| 135 | VkImageView GetHandle() { | ||
| 136 | return GetHandle(Tegra::Texture::SwizzleSource::R, Tegra::Texture::SwizzleSource::G, | ||
| 137 | Tegra::Texture::SwizzleSource::B, Tegra::Texture::SwizzleSource::A); | ||
| 138 | } | ||
| 139 | |||
| 140 | u32 GetWidth() const { | 136 | u32 GetWidth() const { |
| 141 | return params.GetMipWidth(base_level); | 137 | return params.GetMipWidth(base_level); |
| 142 | } | 138 | } |
| @@ -180,14 +176,6 @@ public: | |||
| 180 | } | 176 | } |
| 181 | 177 | ||
| 182 | private: | 178 | private: |
| 183 | static u32 EncodeSwizzle(Tegra::Texture::SwizzleSource x_source, | ||
| 184 | Tegra::Texture::SwizzleSource y_source, | ||
| 185 | Tegra::Texture::SwizzleSource z_source, | ||
| 186 | Tegra::Texture::SwizzleSource w_source) { | ||
| 187 | return (static_cast<u32>(x_source) << 24) | (static_cast<u32>(y_source) << 16) | | ||
| 188 | (static_cast<u32>(z_source) << 8) | static_cast<u32>(w_source); | ||
| 189 | } | ||
| 190 | |||
| 191 | // Store a copy of these values to avoid double dereference when reading them | 179 | // Store a copy of these values to avoid double dereference when reading them |
| 192 | const SurfaceParams params; | 180 | const SurfaceParams params; |
| 193 | const VkImage image; | 181 | const VkImage image; |
| @@ -196,15 +184,18 @@ private: | |||
| 196 | 184 | ||
| 197 | const VKDevice& device; | 185 | const VKDevice& device; |
| 198 | CachedSurface& surface; | 186 | CachedSurface& surface; |
| 199 | const u32 base_layer; | ||
| 200 | const u32 num_layers; | ||
| 201 | const u32 base_level; | 187 | const u32 base_level; |
| 202 | const u32 num_levels; | 188 | const u32 num_levels; |
| 203 | const VkImageViewType image_view_type; | 189 | const VkImageViewType image_view_type; |
| 190 | u32 base_layer = 0; | ||
| 191 | u32 num_layers = 0; | ||
| 192 | u32 base_slice = 0; | ||
| 193 | u32 num_slices = 0; | ||
| 204 | 194 | ||
| 205 | VkImageView last_image_view = nullptr; | 195 | VkImageView last_image_view = nullptr; |
| 206 | u32 last_swizzle = 0; | 196 | u32 last_swizzle = 0; |
| 207 | 197 | ||
| 198 | vk::ImageView render_target; | ||
| 208 | std::unordered_map<u32, vk::ImageView> view_cache; | 199 | std::unordered_map<u32, vk::ImageView> view_cache; |
| 209 | }; | 200 | }; |
| 210 | 201 | ||