rsx: Texture cache fixes

- Handle blit resources in a more consistent way
- TODO: Handle some corner cases (piyotama)
This commit is contained in:
kd-11 2017-12-07 15:08:11 +03:00
parent ac0022483a
commit 95966a467e
4 changed files with 104 additions and 66 deletions

View File

@ -155,11 +155,6 @@ namespace rsx
class texture_cache
{
private:
std::pair<std::array<u8, 4>, std::array<u8, 4>> default_remap_vector =
{
{ CELL_GCM_TEXTURE_REMAP_FROM_A, CELL_GCM_TEXTURE_REMAP_FROM_R, CELL_GCM_TEXTURE_REMAP_FROM_G, CELL_GCM_TEXTURE_REMAP_FROM_B },
{ CELL_GCM_TEXTURE_REMAP_REMAP, CELL_GCM_TEXTURE_REMAP_REMAP, CELL_GCM_TEXTURE_REMAP_REMAP, CELL_GCM_TEXTURE_REMAP_REMAP }
};
struct ranged_storage
{
@ -277,6 +272,12 @@ namespace rsx
};
protected:
std::pair<std::array<u8, 4>, std::array<u8, 4>> default_remap_vector =
{
{ CELL_GCM_TEXTURE_REMAP_FROM_A, CELL_GCM_TEXTURE_REMAP_FROM_R, CELL_GCM_TEXTURE_REMAP_FROM_G, CELL_GCM_TEXTURE_REMAP_FROM_B },
{ CELL_GCM_TEXTURE_REMAP_REMAP, CELL_GCM_TEXTURE_REMAP_REMAP, CELL_GCM_TEXTURE_REMAP_REMAP, CELL_GCM_TEXTURE_REMAP_REMAP }
};
shared_mutex m_cache_mutex;
std::unordered_map<u32, ranged_storage> m_cache;
std::unordered_multimap<u32, std::pair<deferred_subresource, image_view_type>> m_temporary_subresource_cache;
@ -304,7 +305,7 @@ namespace rsx
const rsx::texture_upload_context context, const rsx::texture_dimension_extended type, const texture_create_flags flags, std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap_vector) = 0;
virtual section_storage_type* upload_image_from_cpu(commandbuffer_type&, u32 rsx_address, u16 width, u16 height, u16 depth, u16 mipmaps, u16 pitch, const u32 gcm_format, const texture_upload_context context,
std::vector<rsx_subresource_layout>& subresource_layout, const rsx::texture_dimension_extended type, const bool swizzled, std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap_vector) = 0;
virtual void enforce_surface_creation_type(section_storage_type& section, const texture_create_flags expected) = 0;
virtual void enforce_surface_creation_type(section_storage_type& section, const u32 gcm_format, const texture_create_flags expected) = 0;
virtual void set_up_remap_vector(section_storage_type& section, std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap_vector) = 0;
virtual void insert_texture_barrier() = 0;
virtual image_view_type generate_cubemap_from_images(commandbuffer_type&, const u32 gcm_format, u16 size, std::array<image_resource_type, 6>& sources) = 0;
@ -1689,9 +1690,6 @@ namespace rsx
max_dst_width = cached_dest->get_width();
max_dst_height = cached_dest->get_height();
//Prep surface
enforce_surface_creation_type(*cached_dest, dst.swizzled ? rsx::texture_create_flags::swapped_native_component_order : rsx::texture_create_flags::native_component_order);
}
else if (overlapping_surfaces.size() > 0)
{
@ -1837,6 +1835,19 @@ namespace rsx
invalidate_range_impl_base(dst_address, dst.pitch * dst.height, true, false, false, true, std::forward<Args>(extras)...);
}
u32 gcm_format;
if (is_depth_blit)
gcm_format = (dst_is_argb8) ? CELL_GCM_TEXTURE_DEPTH24_D8 : CELL_GCM_TEXTURE_DEPTH16;
else
gcm_format = (dst_is_argb8) ? CELL_GCM_TEXTURE_A8R8G8B8 : CELL_GCM_TEXTURE_R5G6B5;
if (cached_dest)
{
//Prep surface
auto channel_order = src_is_render_target ? rsx::texture_create_flags::native_component_order : rsx::texture_create_flags::default_component_order;
enforce_surface_creation_type(*cached_dest, gcm_format, channel_order);
}
//Validate clipping region
if ((dst.offset_x + dst.clip_x + dst.clip_width) > max_dst_width) dst.clip_x = 0;
if ((dst.offset_y + dst.clip_y + dst.clip_height) > max_dst_height) dst.clip_y = 0;
@ -1855,18 +1866,12 @@ namespace rsx
if (dest_texture == 0)
{
u32 gcm_format;
if (is_depth_blit)
gcm_format = (dst_is_argb8) ? CELL_GCM_TEXTURE_DEPTH24_D8 : CELL_GCM_TEXTURE_DEPTH16;
else
gcm_format = (dst_is_argb8) ? CELL_GCM_TEXTURE_A8R8G8B8 : CELL_GCM_TEXTURE_R5G6B5;
lock.upgrade();
dest_texture = create_new_texture(cmd, dst.rsx_address, dst.pitch * dst_dimensions.height,
dst_dimensions.width, dst_dimensions.height, 1, 1,
gcm_format, rsx::texture_upload_context::blit_engine_dst, rsx::texture_dimension_extended::texture_dimension_2d,
dst.swizzled? rsx::texture_create_flags::swapped_native_component_order : rsx::texture_create_flags::native_component_order,
rsx::texture_create_flags::default_component_order,
default_remap_vector)->get_raw_texture();
m_texture_memory_in_use += dst.pitch * dst_dimensions.height;

View File

@ -14,6 +14,7 @@ namespace gl
std::tuple<GLenum, GLenum> get_format_type(u32 texture_format);
GLenum wrap_mode(rsx::texture_wrap_mode wrap);
float max_aniso(rsx::texture_max_anisotropy aniso);
std::array<GLenum, 4> get_swizzle_remap(u32 texture_format);
GLuint create_texture(u32 gcm_format, u16 width, u16 height, u16 depth, u16 mipmaps, rsx::texture_dimension_extended type);

View File

@ -666,6 +666,38 @@ namespace gl
return dst_id;
}
void apply_component_mapping_flags(const GLenum target, const u32 gcm_format, const rsx::texture_create_flags flags)
{
switch (flags)
{
case rsx::texture_create_flags::default_component_order:
{
auto remap = gl::get_swizzle_remap(gcm_format);
glTexParameteri(target, GL_TEXTURE_SWIZZLE_R, remap[1]);
glTexParameteri(target, GL_TEXTURE_SWIZZLE_G, remap[2]);
glTexParameteri(target, GL_TEXTURE_SWIZZLE_B, remap[3]);
glTexParameteri(target, GL_TEXTURE_SWIZZLE_A, remap[0]);
break;
}
case rsx::texture_create_flags::native_component_order:
{
glTexParameteri(target, GL_TEXTURE_SWIZZLE_R, GL_RED);
glTexParameteri(target, GL_TEXTURE_SWIZZLE_G, GL_GREEN);
glTexParameteri(target, GL_TEXTURE_SWIZZLE_B, GL_BLUE);
glTexParameteri(target, GL_TEXTURE_SWIZZLE_A, GL_ALPHA);
break;
}
case rsx::texture_create_flags::swapped_native_component_order:
{
glTexParameteri(target, GL_TEXTURE_SWIZZLE_R, GL_ALPHA);
glTexParameteri(target, GL_TEXTURE_SWIZZLE_G, GL_RED);
glTexParameteri(target, GL_TEXTURE_SWIZZLE_B, GL_GREEN);
glTexParameteri(target, GL_TEXTURE_SWIZZLE_A, GL_BLUE);
break;
}
}
}
protected:
void free_texture_section(cached_texture_section& tex) override
@ -744,14 +776,8 @@ namespace gl
break;
}
if (flags == rsx::texture_create_flags::swapped_native_component_order)
{
glBindTexture(GL_TEXTURE_2D, vram_texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_ALPHA);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_RED);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_GREEN);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_BLUE);
}
apply_component_mapping_flags(GL_TEXTURE_2D, gcm_format, flags);
auto& cached = create_texture(vram_texture, rsx_address, rsx_size, width, height, depth, mipmaps);
cached.set_dirty(false);
@ -796,21 +822,16 @@ namespace gl
return section;
}
void enforce_surface_creation_type(cached_texture_section& section, const rsx::texture_create_flags flags) override
void enforce_surface_creation_type(cached_texture_section& section, const u32 gcm_format, const rsx::texture_create_flags flags) override
{
if (flags == section.get_view_flags())
return;
if (flags == rsx::texture_create_flags::swapped_native_component_order)
{
glBindTexture(GL_TEXTURE_2D, section.get_raw_texture());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_ALPHA);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_RED);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_GREEN);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_BLUE);
}
apply_component_mapping_flags(GL_TEXTURE_2D, gcm_format, flags);
section.set_view_flags(flags);
section.set_sampler_status(rsx::texture_sampler_status::status_uninitialized);
}
void set_up_remap_vector(cached_texture_section& section, std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap_vector) override

View File

@ -483,6 +483,33 @@ namespace vk
return { final_mapping[1], final_mapping[2], final_mapping[3], final_mapping[0] };
}
VkComponentMapping apply_component_mapping_flags(const u32 gcm_format, const rsx::texture_create_flags flags, const std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap_vector)
{
VkComponentMapping mapping = {};
switch (flags)
{
case rsx::texture_create_flags::default_component_order:
{
mapping = apply_swizzle_remap(vk::get_component_mapping(gcm_format), remap_vector);
break;
}
case rsx::texture_create_flags::native_component_order:
{
mapping = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
break;
}
case rsx::texture_create_flags::swapped_native_component_order:
{
mapping = { VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_A };
break;
}
default:
break;
}
return mapping;
}
protected:
void free_texture_section(cached_texture_section& tex) override
@ -698,22 +725,7 @@ namespace vk
VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
is_cubemap ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : 0);
switch (flags)
{
case rsx::texture_create_flags::default_component_order:
{
mapping = apply_swizzle_remap(vk::get_component_mapping(gcm_format), remap_vector);
break;
}
case rsx::texture_create_flags::native_component_order:
mapping = image->native_component_map;
break;
case rsx::texture_create_flags::swapped_native_component_order:
mapping = {VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_A};
break;
default:
fmt::throw_exception("Unknown create flags 0x%X", (u32)flags);
}
mapping = apply_component_mapping_flags(gcm_format, flags, remap_vector);
vk::image_view *view = new vk::image_view(*m_device, image->value, image_view_type, vk_format,
mapping, { (aspect_flags & ~VK_IMAGE_ASPECT_STENCIL_BIT), 0, mipmaps, 0, layer});
@ -784,23 +796,15 @@ namespace vk
return section;
}
void enforce_surface_creation_type(cached_texture_section& section, const rsx::texture_create_flags expected_flags) override
void enforce_surface_creation_type(cached_texture_section& section, const u32 gcm_format, const rsx::texture_create_flags expected_flags) override
{
VkComponentMapping mapping;
if (expected_flags == section.get_view_flags())
return;
vk::image* image = section.get_raw_texture();
auto& view = section.get_view();
switch (expected_flags)
{
case rsx::texture_create_flags::native_component_order:
mapping = image->native_component_map;
break;
case rsx::texture_create_flags::swapped_native_component_order:
mapping = { VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_A };
break;
default:
return;
}
VkComponentMapping mapping = apply_component_mapping_flags(gcm_format, expected_flags, default_remap_vector);
if (mapping.a != view->info.components.a ||
mapping.b != view->info.components.b ||
@ -815,19 +819,26 @@ namespace vk
}
section.set_view_flags(expected_flags);
section.set_sampler_status(rsx::texture_sampler_status::status_uninitialized);
}
void set_up_remap_vector(cached_texture_section& section, std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap_vector) override
{
auto& view = section.get_view();
auto& original_remap = section.get_view()->info.components;
auto& original_remap = view->info.components;
std::array<VkComponentSwizzle, 4> base_remap = {original_remap.a, original_remap.r, original_remap.g, original_remap.b};
auto final_remap = apply_swizzle_remap(base_remap, remap_vector);
if (final_remap.a != original_remap.a ||
final_remap.r != original_remap.r ||
final_remap.g != original_remap.g ||
final_remap.b != original_remap.b)
{
vk::image_view *new_view = new vk::image_view(*m_device, view->info.image, view->info.viewType, view->info.format,
final_remap, view->info.subresourceRange);
view.reset(new_view);
}
section.set_sampler_status(rsx::texture_sampler_status::status_ready);
}