From 9485fe2693b6695b6e41e077e42fc15b37d4d41c Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Fri, 25 Mar 2016 17:44:03 +0100 Subject: [PATCH] rsx/common/gl/d3d12/vulkan: Use exact mimap counts. Fix invalid textures in gl backend. --- rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp | 18 +++++------ rpcs3/Emu/RSX/GL/gl_texture_cache.h | 4 +-- rpcs3/Emu/RSX/GL/rsx_gl_texture.cpp | 6 ++-- rpcs3/Emu/RSX/RSXTexture.cpp | 6 ++++ rpcs3/Emu/RSX/RSXTexture.h | 5 +++ rpcs3/Emu/RSX/VK/VKGSRender.cpp | 23 +++++++------- rpcs3/Emu/RSX/VK/VKHelpers.cpp | 5 +-- rpcs3/Emu/RSX/VK/VKHelpers.h | 4 +-- rpcs3/Emu/RSX/VK/VKRenderTargets.h | 17 ++++------ rpcs3/Emu/RSX/VK/VKTexture.cpp | 46 ++++++++++++++-------------- rpcs3/Emu/RSX/VK/VKTextureCache.h | 18 ++++++----- 11 files changed, 78 insertions(+), 74 deletions(-) diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp index 3de878cc01..006dd55b4d 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp @@ -49,17 +49,17 @@ namespace if (texture.dimension() == 1) // 1D texture or cubemap { - return CD3DX12_RESOURCE_DESC::Tex1D(dxgi_format, texture.width(), 1, texture.mipmap()); + return CD3DX12_RESOURCE_DESC::Tex1D(dxgi_format, texture.width(), 1, texture.get_exact_mipmap_count()); } else if (texture.dimension() == 2) // 2D texture or cubemap { // if (texture.depth() < 2); size_t depth = (texture.cubemap()) ? 6 : 1; - return CD3DX12_RESOURCE_DESC::Tex2D(dxgi_format, texture.width(), texture.height(), (UINT)depth, texture.mipmap()); + return CD3DX12_RESOURCE_DESC::Tex2D(dxgi_format, texture.width(), texture.height(), (UINT)depth, texture.get_exact_mipmap_count()); } else if (texture.dimension() == 3) // 3d texture { - return CD3DX12_RESOURCE_DESC::Tex3D(dxgi_format, texture.width(), texture.height(), texture.depth(), texture.mipmap()); + return CD3DX12_RESOURCE_DESC::Tex3D(dxgi_format, texture.width(), texture.height(), texture.depth(), texture.get_exact_mipmap_count()); } throw EXCEPTION("Unknow texture dimension"); } @@ -182,7 +182,7 @@ D3D12_SHADER_RESOURCE_VIEW_DESC get_srv_descriptor_with_dimensions(const rsx::te if (tex.dimension() == 1) { shared_resource_view_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE1D; - shared_resource_view_desc.Texture1D.MipLevels = tex.mipmap(); + shared_resource_view_desc.Texture1D.MipLevels = tex.get_exact_mipmap_count(); return shared_resource_view_desc; } if (tex.dimension() == 2) @@ -190,17 +190,17 @@ D3D12_SHADER_RESOURCE_VIEW_DESC get_srv_descriptor_with_dimensions(const rsx::te if (tex.cubemap()) { shared_resource_view_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBE; - shared_resource_view_desc.TextureCube.MipLevels = tex.mipmap(); + shared_resource_view_desc.TextureCube.MipLevels = tex.get_exact_mipmap_count(); return shared_resource_view_desc; } shared_resource_view_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; - shared_resource_view_desc.Texture2D.MipLevels = tex.mipmap(); + shared_resource_view_desc.Texture2D.MipLevels = tex.get_exact_mipmap_count(); return shared_resource_view_desc; } if (tex.dimension() == 3) { shared_resource_view_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE3D; - shared_resource_view_desc.Texture3D.MipLevels = tex.mipmap(); + shared_resource_view_desc.Texture3D.MipLevels = tex.get_exact_mipmap_count(); return shared_resource_view_desc; } throw EXCEPTION("Wrong texture dimension %d", tex.dimension()); @@ -266,7 +266,7 @@ void D3D12GSRender::upload_textures(ID3D12GraphicsCommandList *command_list, siz { is_depth_stencil_texture = true; } - else if (cached_texture != nullptr && (cached_texture->first == texture_entry(format, w, h, textures[i].depth(), textures[i].mipmap()))) + else if (cached_texture != nullptr && (cached_texture->first == texture_entry(format, w, h, textures[i].depth(), textures[i].get_exact_mipmap_count()))) { if (cached_texture->first.m_is_dirty) { @@ -283,7 +283,7 @@ void D3D12GSRender::upload_textures(ID3D12GraphicsCommandList *command_list, siz std::wstring name = L"texture_@" + std::to_wstring(texaddr); tex->SetName(name.c_str()); vram_texture = tex.Get(); - m_texture_cache.store_and_protect_data(texaddr, texaddr, get_texture_size(textures[i]), format, w, h, textures[i].depth(), textures[i].mipmap(), tex); + m_texture_cache.store_and_protect_data(texaddr, texaddr, get_texture_size(textures[i]), format, w, h, textures[i].depth(), textures[i].get_exact_mipmap_count(), tex); } D3D12_SHADER_RESOURCE_VIEW_DESC shared_resource_view_desc = get_srv_descriptor_with_dimensions(textures[i]); diff --git a/rpcs3/Emu/RSX/GL/gl_texture_cache.h b/rpcs3/Emu/RSX/GL/gl_texture_cache.h index 94c267a8fc..fb596c0751 100644 --- a/rpcs3/Emu/RSX/GL/gl_texture_cache.h +++ b/rpcs3/Emu/RSX/GL/gl_texture_cache.h @@ -470,7 +470,7 @@ namespace gl gl_cached_texture *obj = nullptr; if (!rtt) - obj = find_obj_for_params(texaddr, tex.width(), tex.height(), tex.mipmap()); + obj = find_obj_for_params(texaddr, tex.width(), tex.height(), tex.get_exact_mipmap_count()); if (obj && !obj->deleted) { @@ -497,7 +497,7 @@ namespace gl } __glcheck gl_texture.init(index, tex); - gl_cached_texture &_obj = create_obj_for_params(gl_texture.id(), texaddr, tex.width(), tex.height(), tex.mipmap()); + gl_cached_texture &_obj = create_obj_for_params(gl_texture.id(), texaddr, tex.width(), tex.height(), tex.get_exact_mipmap_count()); _obj.block_sz = (u32)get_texture_size(tex); lock_gl_object(_obj); diff --git a/rpcs3/Emu/RSX/GL/rsx_gl_texture.cpp b/rpcs3/Emu/RSX/GL/rsx_gl_texture.cpp index 7ccf7509eb..679ecba6d9 100644 --- a/rpcs3/Emu/RSX/GL/rsx_gl_texture.cpp +++ b/rpcs3/Emu/RSX/GL/rsx_gl_texture.cpp @@ -320,7 +320,7 @@ namespace rsx const std::vector &input_layouts = get_subresources_layout(tex); glPixelStorei(GL_UNPACK_ALIGNMENT, 4); - glTexStorage2D(m_target, tex.mipmap(), get_sized_internal_format(format), tex.width(), tex.height()); + glTexStorage2D(m_target, tex.get_exact_mipmap_count(), get_sized_internal_format(format), tex.width(), tex.height()); if (!is_compressed_format(format)) { @@ -345,7 +345,7 @@ namespace rsx const std::array& glRemap = get_swizzle_remap(format); - glTexParameteri(m_target, GL_TEXTURE_MAX_LEVEL, tex.mipmap() - 1); + glTexParameteri(m_target, GL_TEXTURE_MAX_LEVEL, tex.get_exact_mipmap_count() - 1); if (format != CELL_GCM_TEXTURE_B8 && format != CELL_GCM_TEXTURE_X16 && format != CELL_GCM_TEXTURE_X32_FLOAT) { @@ -382,7 +382,7 @@ namespace rsx if (min_filter != GL_LINEAR && min_filter != GL_NEAREST) { - if (tex.mipmap() <= 1 || m_target == GL_TEXTURE_RECTANGLE) + if (tex.get_exact_mipmap_count() <= 1 || m_target == GL_TEXTURE_RECTANGLE) { LOG_WARNING(RSX, "Texture %d, target 0x%X, requesting mipmap filtering without any mipmaps set!", m_id, m_target); min_filter = GL_LINEAR; diff --git a/rpcs3/Emu/RSX/RSXTexture.cpp b/rpcs3/Emu/RSX/RSXTexture.cpp index dd4bfba429..9a4ba54355 100644 --- a/rpcs3/Emu/RSX/RSXTexture.cpp +++ b/rpcs3/Emu/RSX/RSXTexture.cpp @@ -75,6 +75,12 @@ namespace rsx return ((method_registers[NV4097_SET_TEXTURE_FORMAT + (m_index * 8)] >> 16) & 0xffff); } + u16 texture::get_exact_mipmap_count() const + { + u16 max_mipmap_count = static_cast(floor(log2(std::max(width(), height()))) + 1); + return std::min(mipmap(), max_mipmap_count); + } + u8 texture::wrap_s() const { return ((method_registers[NV4097_SET_TEXTURE_ADDRESS + (m_index * 8)]) & 0xf); diff --git a/rpcs3/Emu/RSX/RSXTexture.h b/rpcs3/Emu/RSX/RSXTexture.h index a258006c95..d1bc8c719c 100644 --- a/rpcs3/Emu/RSX/RSXTexture.h +++ b/rpcs3/Emu/RSX/RSXTexture.h @@ -21,6 +21,11 @@ namespace rsx u8 dimension() const; u8 format() const; u16 mipmap() const; + /** + * mipmap() returns value from register which can be higher than the actual number of mipmap level. + * This function clamp the result with the mipmap count allowed by texture size. + */ + u16 get_exact_mipmap_count() const; // Address u8 wrap_s() const; diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index 612c2715db..b9297d89a2 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -395,14 +395,14 @@ VKGSRender::VKGSRender() : GSRender(frame_type::Vulkan) { vk::change_image_layout(m_command_buffer, m_swap_chain->get_swap_chain_image(i), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, - VK_IMAGE_ASPECT_COLOR_BIT); + vk::get_image_subresource_range(0, 0, 1, 1, VK_IMAGE_ASPECT_COLOR_BIT)); VkClearColorValue clear_color{}; - auto range = vk::default_image_subresource_range(); + auto range = vk::get_image_subresource_range(0, 0, 1, 1, VK_IMAGE_ASPECT_COLOR_BIT); vkCmdClearColorImage(m_command_buffer, m_swap_chain->get_swap_chain_image(i), VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1, &range); vk::change_image_layout(m_command_buffer, m_swap_chain->get_swap_chain_image(i), VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, - VK_IMAGE_ASPECT_COLOR_BIT); + vk::get_image_subresource_range(0, 0, 1, 1, VK_IMAGE_ASPECT_COLOR_BIT)); } @@ -690,8 +690,7 @@ void VKGSRender::clear_surface(u32 mask) u32 stencil_clear = 0; VkClearValue depth_stencil_clear_values, color_clear_values; - VkImageSubresourceRange depth_range = vk::default_image_subresource_range(); - depth_range.aspectMask = 0; + VkImageSubresourceRange depth_range = vk::get_image_subresource_range(0, 0, 1, 1, 0); if (mask & 0x1) { @@ -735,25 +734,25 @@ void VKGSRender::clear_surface(u32 mask) color_clear_values.color.float32[2] = (float)clear_b / 255; color_clear_values.color.float32[3] = (float)clear_a / 255; - VkImageSubresourceRange range = vk::default_image_subresource_range(); - for (u32 i = 0; i < m_rtts.m_bound_render_targets.size(); ++i) { + VkImageSubresourceRange range = vk::get_image_subresource_range(0, 0, 1, 1, VK_IMAGE_ASPECT_COLOR_BIT); if (std::get<1>(m_rtts.m_bound_render_targets[i]) == nullptr) continue; VkImage color_image = std::get<1>(m_rtts.m_bound_render_targets[i])->value; - change_image_layout(m_command_buffer, color_image, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_ASPECT_COLOR_BIT); + change_image_layout(m_command_buffer, color_image, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, range); vkCmdClearColorImage(m_command_buffer, color_image, VK_IMAGE_LAYOUT_GENERAL, &color_clear_values.color, 1, &range); - change_image_layout(m_command_buffer, color_image, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_ASPECT_COLOR_BIT); + change_image_layout(m_command_buffer, color_image, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, range); } } if (mask & 0x3) { + VkImageSubresourceRange range = vk::get_image_subresource_range(0, 0, 1, 1, VK_IMAGE_ASPECT_DEPTH_BIT); VkImage depth_stencil_image = std::get<1>(m_rtts.m_bound_depth_stencil)->value; - change_image_layout(m_command_buffer, depth_stencil_image, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_ASPECT_DEPTH_BIT); + change_image_layout(m_command_buffer, depth_stencil_image, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, range); vkCmdClearDepthStencilImage(m_command_buffer, std::get<1>(m_rtts.m_bound_depth_stencil)->value, VK_IMAGE_LAYOUT_GENERAL, &depth_stencil_clear_values.depthStencil, 1, &depth_range); - change_image_layout(m_command_buffer, depth_stencil_image, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_ASPECT_DEPTH_BIT); + change_image_layout(m_command_buffer, depth_stencil_image, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, range); } if (!was_recording) @@ -1209,7 +1208,7 @@ void VKGSRender::flip(int buffer) //TODO: Properly clear the background to rsx value m_swap_chain->acquireNextImageKHR((*m_device), (*m_swap_chain), ~0ULL, VK_NULL_HANDLE, VK_NULL_HANDLE, &next_image_temp); - VkImageSubresourceRange range = vk::default_image_subresource_range(); + VkImageSubresourceRange range = vk::get_image_subresource_range(0, 0, 1, 1, VK_IMAGE_ASPECT_COLOR_BIT); VkClearColorValue clear_black = { 0 }; vkCmdClearColorImage(m_command_buffer, m_swap_chain->get_swap_chain_image(next_image_temp), VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, &clear_black, 1, &range); diff --git a/rpcs3/Emu/RSX/VK/VKHelpers.cpp b/rpcs3/Emu/RSX/VK/VKHelpers.cpp index 0acde2d1a3..4dd58e794f 100644 --- a/rpcs3/Emu/RSX/VK/VKHelpers.cpp +++ b/rpcs3/Emu/RSX/VK/VKHelpers.cpp @@ -168,12 +168,9 @@ namespace vk g_current_renderer = device; } - void change_image_layout(VkCommandBuffer cmd, VkImage image, VkImageLayout current_layout, VkImageLayout new_layout, VkImageAspectFlags aspect_flags) + void change_image_layout(VkCommandBuffer cmd, VkImage image, VkImageLayout current_layout, VkImageLayout new_layout, VkImageSubresourceRange range) { //Prepare an image to match the new layout.. - VkImageSubresourceRange range = default_image_subresource_range(); - range.aspectMask = aspect_flags; - VkImageMemoryBarrier barrier = {}; barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; barrier.newLayout = new_layout; diff --git a/rpcs3/Emu/RSX/VK/VKHelpers.h b/rpcs3/Emu/RSX/VK/VKHelpers.h index 4498178a52..974be13c2b 100644 --- a/rpcs3/Emu/RSX/VK/VKHelpers.h +++ b/rpcs3/Emu/RSX/VK/VKHelpers.h @@ -54,14 +54,14 @@ namespace vk VkComponentMapping default_component_map(); VkImageSubresource default_image_subresource(); - VkImageSubresourceRange default_image_subresource_range(); + VkImageSubresourceRange get_image_subresource_range(uint32_t base_layer, uint32_t base_mip, uint32_t layer_count, uint32_t level_count, VkImageAspectFlags aspect); VkSampler null_sampler(); VkImageView null_image_view(); void destroy_global_resources(); - void change_image_layout(VkCommandBuffer cmd, VkImage image, VkImageLayout current_layout, VkImageLayout new_layout, VkImageAspectFlags aspect_flags); + void change_image_layout(VkCommandBuffer cmd, VkImage image, VkImageLayout current_layout, VkImageLayout new_layout, VkImageSubresourceRange range); void copy_image(VkCommandBuffer cmd, VkImage &src, VkImage &dst, VkImageLayout srcLayout, VkImageLayout dstLayout, u32 width, u32 height, u32 mipmaps, VkImageAspectFlagBits aspect); void copy_scaled_image(VkCommandBuffer cmd, VkImage &src, VkImage &dst, VkImageLayout srcLayout, VkImageLayout dstLayout, u32 src_width, u32 src_height, u32 dst_width, u32 dst_height, u32 mipmaps, VkImageAspectFlagBits aspect); diff --git a/rpcs3/Emu/RSX/VK/VKRenderTargets.h b/rpcs3/Emu/RSX/VK/VKRenderTargets.h index 327169a8f8..9f8477a0be 100644 --- a/rpcs3/Emu/RSX/VK/VKRenderTargets.h +++ b/rpcs3/Emu/RSX/VK/VKRenderTargets.h @@ -29,10 +29,10 @@ namespace rsx VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_SAMPLED_BIT, 0)); - change_image_layout(*cmd, rtt->value, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_ASPECT_COLOR_BIT); + change_image_layout(*cmd, rtt->value, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, vk::get_image_subresource_range(0, 0, 1, 1, VK_IMAGE_ASPECT_COLOR_BIT)); //Clear new surface VkClearColorValue clear_color; - VkImageSubresourceRange range = vk::default_image_subresource_range(); + VkImageSubresourceRange range = vk::get_image_subresource_range(0,0, 1, 1, VK_IMAGE_ASPECT_COLOR_BIT); clear_color.float32[0] = 0.f; clear_color.float32[1] = 0.f; @@ -40,7 +40,7 @@ namespace rsx clear_color.float32[3] = 0.f; vkCmdClearColorImage(*cmd, rtt->value, VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1, &range); - change_image_layout(*cmd, rtt->value, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_ASPECT_COLOR_BIT); + change_image_layout(*cmd, rtt->value, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, vk::get_image_subresource_range(0, 0, 1, 1, VK_IMAGE_ASPECT_COLOR_BIT)); return rtt; } @@ -52,16 +52,11 @@ namespace rsx std::unique_ptr ds; ds.reset(new vk::image(device, mem_mapping.device_local, VK_IMAGE_TYPE_2D, requested_format, width, height, 1, 1, 1, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT|VK_IMAGE_USAGE_SAMPLED_BIT, 0)); - change_image_layout(*cmd, ds->value, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT); + change_image_layout(*cmd, ds->value, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, vk::get_image_subresource_range(0, 0, 1, 1, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)); //Clear new surface.. VkClearDepthStencilValue clear_depth = {}; - VkImageSubresourceRange range = {}; - range.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; - range.baseArrayLayer = 0; - range.baseMipLevel = 0; - range.layerCount = 1; - range.levelCount = 1; + VkImageSubresourceRange range = vk::get_image_subresource_range(0, 0, 1, 1, VK_IMAGE_ASPECT_DEPTH_BIT); if (requested_format != VK_FORMAT_D16_UNORM) range.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT; @@ -70,7 +65,7 @@ namespace rsx clear_depth.stencil = 0; vkCmdClearDepthStencilImage(*cmd, ds->value, VK_IMAGE_LAYOUT_GENERAL, &clear_depth, 1, &range); - change_image_layout(*cmd, ds->value, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT); + change_image_layout(*cmd, ds->value, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, vk::get_image_subresource_range(0, 0, 1, 1, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)); return ds; } diff --git a/rpcs3/Emu/RSX/VK/VKTexture.cpp b/rpcs3/Emu/RSX/VK/VKTexture.cpp index d857f6384a..7fcfd74b67 100644 --- a/rpcs3/Emu/RSX/VK/VKTexture.cpp +++ b/rpcs3/Emu/RSX/VK/VKTexture.cpp @@ -29,14 +29,14 @@ namespace vk return subres; } - VkImageSubresourceRange default_image_subresource_range() + VkImageSubresourceRange get_image_subresource_range(uint32_t base_layer, uint32_t base_mip, uint32_t layer_count, uint32_t level_count, VkImageAspectFlags aspect) { VkImageSubresourceRange subres = {}; - subres.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - subres.baseArrayLayer = 0; - subres.baseMipLevel = 0; - subres.layerCount = 100; - subres.levelCount = 100; + subres.aspectMask = aspect; + subres.baseArrayLayer = base_layer; + subres.baseMipLevel = base_mip; + subres.layerCount = layer_count; + subres.levelCount = level_count; return subres; } @@ -61,10 +61,10 @@ namespace vk rgn.dstSubresource = a_dst; if (srcLayout != VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) - change_image_layout(cmd, src, srcLayout, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, aspect); + change_image_layout(cmd, src, srcLayout, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, vk::get_image_subresource_range(0, 0, 1, 1, aspect)); if (dstLayout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) - change_image_layout(cmd, dst, dstLayout, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, aspect); + change_image_layout(cmd, dst, dstLayout, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, vk::get_image_subresource_range(0, 0, 1, 1, aspect)); for (u32 mip_level = 0; mip_level < mipmaps; ++mip_level) { @@ -75,10 +75,10 @@ namespace vk } if (srcLayout != VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) - change_image_layout(cmd, src, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, srcLayout, aspect); + change_image_layout(cmd, src, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, srcLayout, vk::get_image_subresource_range(0, 0, 1, 1, aspect)); if (dstLayout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) - change_image_layout(cmd, dst, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, dstLayout, aspect); + change_image_layout(cmd, dst, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, dstLayout, vk::get_image_subresource_range(0, 0, 1, 1, aspect)); } void copy_scaled_image(VkCommandBuffer cmd, VkImage & src, VkImage & dst, VkImageLayout srcLayout, VkImageLayout dstLayout, u32 src_width, u32 src_height, u32 dst_width, u32 dst_height, u32 mipmaps, VkImageAspectFlagBits aspect) @@ -100,10 +100,10 @@ namespace vk rgn.srcSubresource = a_src; if (srcLayout != VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) - change_image_layout(cmd, src, srcLayout, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, aspect); + change_image_layout(cmd, src, srcLayout, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, vk::get_image_subresource_range(0, 0, 1, 1, aspect)); if (dstLayout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) - change_image_layout(cmd, dst, dstLayout, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, aspect); + change_image_layout(cmd, dst, dstLayout, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, vk::get_image_subresource_range(0, 0, 1, 1, aspect)); for (u32 mip_level = 0; mip_level < mipmaps; ++mip_level) { @@ -114,10 +114,10 @@ namespace vk } if (srcLayout != VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) - change_image_layout(cmd, src, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, srcLayout, aspect); + change_image_layout(cmd, src, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, srcLayout, vk::get_image_subresource_range(0, 0, 1, 1, aspect)); if (dstLayout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) - change_image_layout(cmd, dst, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, dstLayout, aspect); + change_image_layout(cmd, dst, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, dstLayout, vk::get_image_subresource_range(0, 0, 1, 1, aspect)); } void copy_texture(VkCommandBuffer cmd, texture &src, texture &dst, VkImageLayout srcLayout, VkImageLayout dstLayout, u32 width, u32 height, u32 mipmaps, VkImageAspectFlagBits aspect) @@ -202,7 +202,7 @@ namespace vk view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; view_info.viewType = view_type; view_info.components = swizzle; - view_info.subresourceRange = default_image_subresource_range(); + view_info.subresourceRange = get_image_subresource_range(0, 0, 1, mipmaps, VK_IMAGE_ASPECT_COLOR_BIT); if (usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { @@ -286,7 +286,7 @@ namespace vk VkImageTiling tiling = m_tiling; destroy(); - create(dev, format, VK_IMAGE_TYPE_2D, VK_IMAGE_VIEW_TYPE_CUBE, VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, usage, tiling, tex.width(), tex.height(), tex.mipmap(), false, default_component_map()); + create(dev, format, VK_IMAGE_TYPE_2D, VK_IMAGE_VIEW_TYPE_CUBE, VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, usage, tiling, tex.width(), tex.height(), tex.get_exact_mipmap_count(), false, default_component_map()); } if (!tex.cubemap() && tex.depth() > 1 && m_view_type != VK_IMAGE_VIEW_TYPE_3D) @@ -299,7 +299,7 @@ namespace vk VkImageTiling tiling = m_tiling; destroy(); - create(dev, format, VK_IMAGE_TYPE_3D, VK_IMAGE_VIEW_TYPE_3D, 0, usage, tiling, tex.width(), tex.height(), tex.mipmap(), false, default_component_map()); + create(dev, format, VK_IMAGE_TYPE_3D, VK_IMAGE_VIEW_TYPE_3D, 0, usage, tiling, tex.width(), tex.height(), tex.get_exact_mipmap_count(), false, default_component_map()); } VkImageSubresource subres = {}; @@ -315,9 +315,9 @@ namespace vk if (ignore_checks || props.linearTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) { - std::vector> layout_alignment(tex.mipmap()); + std::vector> layout_alignment(tex.get_exact_mipmap_count()); - for (u32 i = 0; i < tex.mipmap(); ++i) + for (u32 i = 0; i < tex.get_exact_mipmap_count(); ++i) { layout_alignment[i].first = 4096; vkGetImageSubresourceLayout((*owner), m_image_contents, &subres, &layout_alignment[i].second); @@ -337,7 +337,7 @@ namespace vk subres.mipLevel++; } - if (tex.mipmap() == 1) + if (tex.get_exact_mipmap_count() == 1) { u64 buffer_size = get_placed_texture_storage_size(tex, layout_alignment[0].first, layout_alignment[0].first); if (buffer_size != layout_alignment[0].second.size) @@ -382,7 +382,7 @@ namespace vk } int index= 0; - std::vector> layout_offset_info(tex.mipmap()); + std::vector> layout_offset_info(tex.get_exact_mipmap_count()); for (auto &mip_info : layout_offset_info) { @@ -410,7 +410,7 @@ namespace vk if (!staging_texture) { staging_texture = new texture(); - staging_texture->create((*owner), m_internal_format, VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_LINEAR, m_width, m_height, tex.mipmap(), false, default_component_map()); + staging_texture->create((*owner), m_internal_format, VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_LINEAR, m_width, m_height, tex.get_exact_mipmap_count(), false, default_component_map()); } staging_texture->init(tex, cmd, true); @@ -442,7 +442,7 @@ namespace vk { if (m_layout == new_layout) return; - vk::change_image_layout(cmd, m_image_contents, m_layout, new_layout, m_image_aspect); + vk::change_image_layout(cmd, m_image_contents, m_layout, new_layout, vk::get_image_subresource_range(0, 0, 1, 1, m_image_aspect)); m_layout = new_layout; } diff --git a/rpcs3/Emu/RSX/VK/VKTextureCache.h b/rpcs3/Emu/RSX/VK/VKTextureCache.h index 161093bd67..25c1044225 100644 --- a/rpcs3/Emu/RSX/VK/VKTextureCache.h +++ b/rpcs3/Emu/RSX/VK/VKTextureCache.h @@ -172,7 +172,7 @@ namespace vk { m_temporary_image_view.push_back(std::make_unique(*vk::get_current_renderer(), rtt_texture->value, VK_IMAGE_VIEW_TYPE_2D, rtt_texture->info.format, vk::default_component_map(), - vk::default_image_subresource_range())); + vk::get_image_subresource_range(0, 0, 1, 1, VK_IMAGE_ASPECT_COLOR_BIT))); return m_temporary_image_view.back().get(); } @@ -180,11 +180,11 @@ namespace vk { m_temporary_image_view.push_back(std::make_unique(*vk::get_current_renderer(), rtt_texture->value, VK_IMAGE_VIEW_TYPE_2D, rtt_texture->info.format, vk::default_component_map(), - vk::default_image_subresource_range())); + vk::get_image_subresource_range(0, 0, 1, 1, VK_IMAGE_ASPECT_DEPTH_BIT))); return m_temporary_image_view.back().get(); } - cached_texture_object& cto = find_cached_texture(texaddr, range, true, tex.width(), tex.height(), tex.mipmap()); + cached_texture_object& cto = find_cached_texture(texaddr, range, true, tex.width(), tex.height(), tex.get_exact_mipmap_count()); if (cto.exists && !cto.dirty) { return cto.uploaded_image_view.get(); @@ -196,20 +196,22 @@ namespace vk VkComponentMapping mapping = vk::get_component_mapping(format, tex.remap()); VkFormat vk_format = get_compatible_sampler_format(format); + VkImageSubresourceRange subresource_range = vk::get_image_subresource_range(0, 0, 1, tex.get_exact_mipmap_count(), VK_IMAGE_ASPECT_COLOR_BIT); + cto.uploaded_texture = std::make_unique(*vk::get_current_renderer(), memory_type_mapping.device_local, VK_IMAGE_TYPE_2D, vk_format, - tex.width(), tex.height(), 1, tex.mipmap(), 1, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_LAYOUT_UNDEFINED, + tex.width(), tex.height(), 1, tex.get_exact_mipmap_count(), 1, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, 0); - change_image_layout(cmd, cto.uploaded_texture->value, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_ASPECT_COLOR_BIT); + change_image_layout(cmd, cto.uploaded_texture->value, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, subresource_range); cto.uploaded_image_view = std::make_unique(*vk::get_current_renderer(), cto.uploaded_texture->value, VK_IMAGE_VIEW_TYPE_2D, vk_format, vk::get_component_mapping(tex.format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN), tex.remap()), - vk::default_image_subresource_range()); + subresource_range); copy_mipmaped_image_using_buffer(cmd, cto.uploaded_texture->value, get_subresources_layout(tex), format, !(tex.format() & CELL_GCM_TEXTURE_LN), upload_heap, upload_buffer); - change_image_layout(cmd, cto.uploaded_texture->value, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_ASPECT_COLOR_BIT); + change_image_layout(cmd, cto.uploaded_texture->value, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, subresource_range); cto.exists = true; cto.dirty = false; @@ -217,7 +219,7 @@ namespace vk cto.native_rsx_size = range; cto.width = tex.width(); cto.height = tex.height(); - cto.mipmaps = tex.mipmap(); + cto.mipmaps = tex.get_exact_mipmap_count(); lock_object(cto);