rsx: Fix handling of ARGB8 memory

- Load into memory as straightforward BGRA
- Fixes a bug in vulkan caused by byte shuffling in blit engine vs shader access
- Removes the need for memory shuffling when transferring into a rendertarget
This commit is contained in:
kd-11 2019-08-19 22:40:24 +03:00 committed by kd-11
parent 9cd5325962
commit 141072023b
6 changed files with 7 additions and 72 deletions

View file

@ -533,6 +533,8 @@ void upload_texture_subresource(gsl::span<gsl::byte> dst_buffer, const rsx_subre
break;
}
case CELL_GCM_TEXTURE_A8R8G8B8:
case CELL_GCM_TEXTURE_D8R8G8B8:
case CELL_GCM_TEXTURE_DEPTH24_D8:
case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT: // Untested
{
@ -543,16 +545,6 @@ void upload_texture_subresource(gsl::span<gsl::byte> dst_buffer, const rsx_subre
break;
}
case CELL_GCM_TEXTURE_A8R8G8B8:
case CELL_GCM_TEXTURE_D8R8G8B8:
{
if (is_swizzled)
copy_unmodified_block_swizzled::copy_mipmap_level(as_span_workaround<u32>(dst_buffer), as_const_span<const u32>(src_layout.data), 1, w, h, depth, src_layout.border, get_row_pitch_in_block<u32>(w, dst_row_pitch_multiple_of));
else
copy_unmodified_block::copy_mipmap_level(as_span_workaround<u32>(dst_buffer), as_const_span<const u32>(src_layout.data), 1, w, h, depth, src_layout.border, get_row_pitch_in_block<u32>(w, dst_row_pitch_multiple_of), src_layout.pitch_in_block);
break;
}
// NOTE: Textures with WZYX notations refer to arbitrary data and not color swizzles as in common GPU lang
// WZYX actually maps directly as a RGBA16 format in Cell memory! R=W, not R=X

View file

@ -63,7 +63,7 @@ namespace gl
case CELL_GCM_TEXTURE_A1R5G5B5: return std::make_tuple(GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV);
case CELL_GCM_TEXTURE_A4R4G4B4: return std::make_tuple(GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4);
case CELL_GCM_TEXTURE_R5G6B5: return std::make_tuple(GL_RGB, GL_UNSIGNED_SHORT_5_6_5);
case CELL_GCM_TEXTURE_A8R8G8B8: return std::make_tuple(GL_BGRA, GL_UNSIGNED_INT_8_8_8_8);
case CELL_GCM_TEXTURE_A8R8G8B8: return std::make_tuple(GL_BGRA, GL_UNSIGNED_BYTE);
case CELL_GCM_TEXTURE_G8B8: return std::make_tuple(GL_RG, GL_UNSIGNED_BYTE);
case CELL_GCM_TEXTURE_R6G5B5: return std::make_tuple(GL_RGB, GL_UNSIGNED_SHORT_5_6_5);
case CELL_GCM_TEXTURE_DEPTH24_D8: return std::make_tuple(GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8);

View file

@ -204,7 +204,7 @@ namespace vk
mapping = { VK_COMPONENT_SWIZZLE_A, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B }; break;
case CELL_GCM_TEXTURE_D8R8G8B8:
mapping = { VK_COMPONENT_SWIZZLE_ONE, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_A }; break;
mapping = { VK_COMPONENT_SWIZZLE_ONE, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B }; break;
case CELL_GCM_TEXTURE_D1R5G5B5:
mapping = { VK_COMPONENT_SWIZZLE_ONE, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B }; break;
@ -218,7 +218,7 @@ namespace vk
mapping = { VK_COMPONENT_SWIZZLE_A, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B }; break;
case CELL_GCM_TEXTURE_A8R8G8B8:
mapping = { VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_A }; break;
mapping = { VK_COMPONENT_SWIZZLE_A, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B }; break;
default:
fmt::throw_exception("Invalid or unsupported component mapping for texture format (0x%x)" HERE, format);

View file

@ -237,25 +237,7 @@ namespace vk
}
else
{
auto fmt = get_compatible_gcm_format(format_info.gcm_color_format);
if (fmt.second)
{
switch (fmt.first)
{
case CELL_GCM_TEXTURE_A8R8G8B8:
case CELL_GCM_TEXTURE_D8R8G8B8:
//Hack
gcm_format = CELL_GCM_TEXTURE_X32_FLOAT;
break;
default:
gcm_format = fmt.first;
break;
}
}
else
{
gcm_format = fmt.first;
}
gcm_format = get_compatible_gcm_format(format_info.gcm_color_format).first;
}
rsx_subresource_layout subres{};

View file

@ -640,45 +640,6 @@ namespace vk
dst_area.x1 = (u16)(dst_area.x1 * xfer_info.dst_scaling_hint);
dst_area.x2 = (u16)(dst_area.x2 * xfer_info.dst_scaling_hint);
}
else if (xfer_info.dst_context == rsx::texture_upload_context::framebuffer_storage)
{
if (xfer_info.src_context != rsx::texture_upload_context::blit_engine_dst &&
xfer_info.src_context != rsx::texture_upload_context::framebuffer_storage)
{
// Data moving to rendertarget, where byte ordering has to be preserved
// NOTE: This is a workaround, true accuracy would require all RTT<->cache transfers to invoke this step but thats too slow
// Sampling is ok; image view swizzle will work around it
if (dst->info.format == VK_FORMAT_B8G8R8A8_UNORM)
{
// For this specific format, channel ordering is faked via custom remap, undo this before transfer
VkBufferImageCopy copy{};
copy.imageExtent = src->info.extent;
copy.imageOffset = { 0, 0, 0 };
copy.imageSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
const auto scratch_buf = vk::get_scratch_buffer();
const auto data_length = src->info.extent.width * src->info.extent.height * 4;
src->push_layout(cmd, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
vkCmdCopyImageToBuffer(cmd, src->value, src->current_layout, scratch_buf->value, 1, &copy);
src->pop_layout(cmd);
vk::insert_buffer_memory_barrier(cmd, scratch_buf->value, 0, data_length,
VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT);
vk::get_compute_task<vk::cs_shuffle_32>()->run(cmd, scratch_buf, data_length);
vk::insert_buffer_memory_barrier(cmd, scratch_buf->value, 0, data_length,
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT);
real_src = vk::get_typeless_helper(src->info.format, src->width(), src->height());
real_src->change_layout(cmd, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
vkCmdCopyBufferToImage(cmd, scratch_buf->value, real_src->value, real_src->current_layout, 1, &copy);
}
}
}
// Checks
if (src_area.x2 <= src_area.x1 || src_area.y2 <= src_area.y1 || dst_area.x2 <= dst_area.x1 || dst_area.y2 <= dst_area.y1)

View file

@ -1072,7 +1072,7 @@ namespace vk
bool input_swizzled = swizzled;
if (context == rsx::texture_upload_context::blit_engine_src)
{
//Swizzling is ignored for blit engine copy and emulated using remapping
// Swizzling is ignored for blit engine copy and emulated using remapping
input_swizzled = false;
}