1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-23 03:02:53 +01:00

rsx: Fixes for cubemap reconstruction

- Do not abort generation if sides are missing, replace with blank surfaces instead
- Make cubemaps scale with res scaling
This commit is contained in:
kd-11 2017-11-03 15:48:27 +03:00
parent 60c7a508a7
commit 300a36d3d6
3 changed files with 50 additions and 27 deletions

View File

@ -347,6 +347,7 @@ namespace rsx
u32 last_dirty_block = UINT32_MAX;
std::pair<u32, u32> 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_resource_type, 6> 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);

View File

@ -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);

View File

@ -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, &copy_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, &copy_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;