mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-30 12:32:43 +00:00
rsx: Texture cache fixes
- Handle blit resources in a more consistent way - TODO: Handle some corner cases (piyotama)
This commit is contained in:
parent
ac0022483a
commit
95966a467e
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user