diff --git a/rpcs3/Emu/RSX/Common/texture_cache.h b/rpcs3/Emu/RSX/Common/texture_cache.h index a9f612ca8b..5de469baa3 100644 --- a/rpcs3/Emu/RSX/Common/texture_cache.h +++ b/rpcs3/Emu/RSX/Common/texture_cache.h @@ -347,6 +347,7 @@ namespace rsx u32 last_dirty_block = UINT32_MAX; std::pair trampled_range = std::make_pair(address, address + range); + const bool strict_range_check = g_cfg.video.write_color_buffers || g_cfg.video.write_depth_buffer; for (auto It = m_cache.begin(); It != m_cache.end(); It++) { @@ -370,7 +371,7 @@ namespace rsx if (tex.cache_tag == cache_tag) continue; //already processed if (!tex.is_locked()) continue; //flushable sections can be 'clean' but unlocked. TODO: Handle this better - auto overlapped = tex.overlaps_page(trampled_range, address, tex.is_flushable()); + auto overlapped = tex.overlaps_page(trampled_range, address, strict_range_check); if (std::get<0>(overlapped)) { auto &new_range = std::get<1>(overlapped); @@ -1051,7 +1052,7 @@ namespace rsx std::array image_array; image_array[0] = texptr->get_surface(); - bool can_cast = true; + bool safe_cast = true; u32 image_size = texptr->get_rsx_pitch() * texptr->get_surface_height(); u32 image_address = texaddr + image_size; @@ -1059,34 +1060,42 @@ namespace rsx for (int n = 1; n < 6; ++n) { render_target_type img = nullptr; + image_array[n] = 0; + if (!!(img = m_rtts.get_texture_from_render_target_if_applicable(image_address)) || !!(img = m_rtts.get_texture_from_depth_stencil_if_applicable(image_address))) { if (img->get_surface_width() != surface_width || img->get_surface_width() != img->get_surface_height()) { - can_cast = false; - break; + safe_cast = false; + } + else + { + image_array[n] = img->get_surface(); } - - image_address += image_size; - image_array[n] = img->get_surface(); } else { - can_cast = false; - break; + safe_cast = false; } + + image_address += image_size; } - if (can_cast) + if (!safe_cast) { - sampled_image_descriptor desc = { texptr->get_surface(), texaddr, format, 0, 0, surface_width, surface_height, texture_upload_context::framebuffer_storage, - is_depth, 1.f, 1.f, rsx::texture_dimension_extended::texture_dimension_cubemap }; - - desc.set_external_cubemap_resources(image_array); - return desc; + //TODO: Lower to warning + //TODO: Gather remaining sides from the texture cache or upload from cpu (too slow?) + LOG_ERROR(RSX, "Could not gather all required surfaces for cubemap generation"); } + + sampled_image_descriptor desc = { texptr->get_surface(), texaddr, format, 0, 0, rsx::apply_resolution_scale(surface_width, true), + rsx::apply_resolution_scale(surface_height, true), texture_upload_context::framebuffer_storage, is_depth, 1.f, 1.f, + rsx::texture_dimension_extended::texture_dimension_cubemap }; + + desc.set_external_cubemap_resources(image_array); + return desc; } LOG_ERROR(RSX, "Texture resides in render target memory, but requested type is not 2D (%d)", (u32)extended_dimension); diff --git a/rpcs3/Emu/RSX/GL/GLTextureCache.h b/rpcs3/Emu/RSX/GL/GLTextureCache.h index 4e5170a719..6e3cf9338f 100644 --- a/rpcs3/Emu/RSX/GL/GLTextureCache.h +++ b/rpcs3/Emu/RSX/GL/GLTextureCache.h @@ -664,8 +664,11 @@ namespace gl for (int i = 0; i < 6; ++i) { - glCopyImageSubData(sources[i], GL_TEXTURE_2D, 0, 0, 0, 0, - dst_id, GL_TEXTURE_CUBE_MAP, 0, 0, 0, i, size, size, 1); + if (sources[i] != 0) + { + glCopyImageSubData(sources[i], GL_TEXTURE_2D, 0, 0, 0, 0, + dst_id, GL_TEXTURE_CUBE_MAP, 0, 0, 0, i, size, size, 1); + } } m_temporary_surfaces.push_back(dst_id); diff --git a/rpcs3/Emu/RSX/VK/VKTextureCache.h b/rpcs3/Emu/RSX/VK/VKTextureCache.h index b4d2e004e0..7cd01d42aa 100644 --- a/rpcs3/Emu/RSX/VK/VKTextureCache.h +++ b/rpcs3/Emu/RSX/VK/VKTextureCache.h @@ -547,18 +547,29 @@ namespace vk subresource_range.layerCount = 1; } - VkImageLayout old_src_layout = sources[n]->current_layout; - vk::change_image_layout(cmd, sources[n], VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, subresource_range); + if (sources[n]) + { + VkImageLayout old_src_layout = sources[n]->current_layout; + vk::change_image_layout(cmd, sources[n], VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, subresource_range); - VkImageCopy copy_rgn; - copy_rgn.srcOffset = { 0, 0, 0 }; - copy_rgn.dstOffset = { 0, 0, 0 }; - copy_rgn.dstSubresource = { aspect, 0, n, 1 }; - copy_rgn.srcSubresource = { aspect, 0, 0, 1 }; - copy_rgn.extent = { size, size, 1 }; + VkImageCopy copy_rgn; + copy_rgn.srcOffset = { 0, 0, 0 }; + copy_rgn.dstOffset = { 0, 0, 0 }; + copy_rgn.dstSubresource = { aspect, 0, n, 1 }; + copy_rgn.srcSubresource = { aspect, 0, 0, 1 }; + copy_rgn.extent = { size, size, 1 }; - vkCmdCopyImage(cmd, sources[n]->value, sources[n]->current_layout, image->value, image->current_layout, 1, ©_rgn); - vk::change_image_layout(cmd, sources[n], old_src_layout, subresource_range); + vkCmdCopyImage(cmd, sources[n]->value, sources[n]->current_layout, image->value, image->current_layout, 1, ©_rgn); + vk::change_image_layout(cmd, sources[n], old_src_layout, subresource_range); + } + else + { + //Clear to black + VkClearColorValue clear_color{}; + auto range = subresource_range; + range.baseArrayLayer = n; + vkCmdClearColorImage(cmd, image->value, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_color, 1, &range); + } } subresource_range.layerCount = 6;