mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-21 12:05:23 +00:00
rsx/gl/vk: Obey channel remapping on framebuffer resources if requested
This commit is contained in:
parent
27552891ad
commit
9f416e5ce1
7 changed files with 164 additions and 113 deletions
|
@ -262,11 +262,13 @@ namespace rsx
|
|||
u16 h;
|
||||
};
|
||||
|
||||
using texture_channel_remap_t = std::pair<std::array<u8, 4>, std::array<u8, 4>>;
|
||||
struct deferred_subresource
|
||||
{
|
||||
image_resource_type external_handle = 0;
|
||||
std::array<image_resource_type, 6> external_cubemap_sources;
|
||||
std::vector<copy_region_descriptor> sections_to_copy;
|
||||
texture_channel_remap_t remap;
|
||||
u32 base_address = 0;
|
||||
u32 gcm_format = 0;
|
||||
u16 x = 0;
|
||||
|
@ -280,8 +282,8 @@ namespace rsx
|
|||
deferred_subresource()
|
||||
{}
|
||||
|
||||
deferred_subresource(image_resource_type _res, u32 _addr, u32 _fmt, u16 _x, u16 _y, u16 _w, u16 _h) :
|
||||
external_handle(_res), base_address(_addr), gcm_format(_fmt), x(_x), y(_y), width(_w), height(_h)
|
||||
deferred_subresource(image_resource_type _res, u32 _addr, u32 _fmt, u16 _x, u16 _y, u16 _w, u16 _h, const texture_channel_remap_t& _remap) :
|
||||
external_handle(_res), base_address(_addr), gcm_format(_fmt), x(_x), y(_y), width(_w), height(_h), remap(_remap)
|
||||
{}
|
||||
};
|
||||
|
||||
|
@ -316,9 +318,9 @@ namespace rsx
|
|||
}
|
||||
|
||||
sampled_image_descriptor(image_resource_type external_handle, u32 base_address, u32 gcm_format, u16 x_offset, u16 y_offset, u16 width, u16 height,
|
||||
texture_upload_context ctx, bool is_depth, f32 x_scale, f32 y_scale, rsx::texture_dimension_extended type)
|
||||
texture_upload_context ctx, bool is_depth, f32 x_scale, f32 y_scale, rsx::texture_dimension_extended type, const texture_channel_remap_t& remap)
|
||||
{
|
||||
external_subresource_desc = { external_handle, base_address, gcm_format, x_offset, y_offset, width, height };
|
||||
external_subresource_desc = { external_handle, base_address, gcm_format, x_offset, y_offset, width, height, remap };
|
||||
|
||||
image_handle = 0;
|
||||
upload_context = ctx;
|
||||
|
@ -336,7 +338,7 @@ namespace rsx
|
|||
};
|
||||
|
||||
protected:
|
||||
std::pair<std::array<u8, 4>, std::array<u8, 4>> default_remap_vector =
|
||||
texture_channel_remap_t 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 }
|
||||
|
@ -375,17 +377,17 @@ namespace rsx
|
|||
|
||||
/* Helpers */
|
||||
virtual void free_texture_section(section_storage_type&) = 0;
|
||||
virtual image_view_type create_temporary_subresource_view(commandbuffer_type&, image_resource_type* src, u32 gcm_format, u16 x, u16 y, u16 w, u16 h) = 0;
|
||||
virtual image_view_type create_temporary_subresource_view(commandbuffer_type&, image_storage_type* src, u32 gcm_format, u16 x, u16 y, u16 w, u16 h) = 0;
|
||||
virtual image_view_type create_temporary_subresource_view(commandbuffer_type&, image_resource_type* src, u32 gcm_format, u16 x, u16 y, u16 w, u16 h, const texture_channel_remap_t& remap_vector) = 0;
|
||||
virtual image_view_type create_temporary_subresource_view(commandbuffer_type&, image_storage_type* src, u32 gcm_format, u16 x, u16 y, u16 w, u16 h, const texture_channel_remap_t& remap_vector) = 0;
|
||||
virtual section_storage_type* create_new_texture(commandbuffer_type&, u32 rsx_address, u32 rsx_size, u16 width, u16 height, u16 depth, u16 mipmaps, u32 gcm_format,
|
||||
rsx::texture_upload_context context, rsx::texture_dimension_extended type, texture_create_flags flags, rsx::texture_colorspace colorspace, const std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap_vector) = 0;
|
||||
rsx::texture_upload_context context, rsx::texture_dimension_extended type, texture_create_flags flags, rsx::texture_colorspace colorspace, const texture_channel_remap_t& 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, u32 gcm_format, texture_upload_context context,
|
||||
const std::vector<rsx_subresource_layout>& subresource_layout, rsx::texture_dimension_extended type, rsx::texture_colorspace colorspace, bool swizzled, const std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap_vector) = 0;
|
||||
const std::vector<rsx_subresource_layout>& subresource_layout, rsx::texture_dimension_extended type, rsx::texture_colorspace colorspace, bool swizzled, const texture_channel_remap_t& remap_vector) = 0;
|
||||
virtual void enforce_surface_creation_type(section_storage_type& section, u32 gcm_format, texture_create_flags expected) = 0;
|
||||
virtual void set_up_remap_vector(section_storage_type& section, const std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap_vector) = 0;
|
||||
virtual void set_up_remap_vector(section_storage_type& section, const texture_channel_remap_t& remap_vector) = 0;
|
||||
virtual void insert_texture_barrier(commandbuffer_type&, image_storage_type* tex) = 0;
|
||||
virtual image_view_type generate_cubemap_from_images(commandbuffer_type&, u32 gcm_format, u16 size, const std::array<image_resource_type, 6>& sources) = 0;
|
||||
virtual image_view_type generate_atlas_from_images(commandbuffer_type&, u32 gcm_format, u16 width, u16 height, const std::vector<copy_region_descriptor>& sections_to_copy) = 0;
|
||||
virtual image_view_type generate_cubemap_from_images(commandbuffer_type&, u32 gcm_format, u16 size, const std::array<image_resource_type, 6>& sources, const texture_channel_remap_t& remap_vector) = 0;
|
||||
virtual image_view_type generate_atlas_from_images(commandbuffer_type&, u32 gcm_format, u16 width, u16 height, const std::vector<copy_region_descriptor>& sections_to_copy, const texture_channel_remap_t& remap_vector) = 0;
|
||||
virtual void update_image_contents(commandbuffer_type&, image_view_type dst, image_resource_type src, u16 width, u16 height) = 0;
|
||||
virtual bool render_target_format_is_compatible(image_storage_type* tex, u32 gcm_format) = 0;
|
||||
|
||||
|
@ -1267,11 +1269,11 @@ namespace rsx
|
|||
|
||||
image_view_type result = 0;
|
||||
if (desc.is_copy_cmd)
|
||||
result = generate_atlas_from_images(cmd, desc.gcm_format, desc.width, desc.height, desc.sections_to_copy);
|
||||
result = generate_atlas_from_images(cmd, desc.gcm_format, desc.width, desc.height, desc.sections_to_copy, desc.remap);
|
||||
else if (desc.is_cubemap)
|
||||
result = generate_cubemap_from_images(cmd, desc.gcm_format, desc.width, desc.external_cubemap_sources);
|
||||
result = generate_cubemap_from_images(cmd, desc.gcm_format, desc.width, desc.external_cubemap_sources, desc.remap);
|
||||
else
|
||||
result = create_temporary_subresource_view(cmd, &desc.external_handle, desc.gcm_format, desc.x, desc.y, desc.width, desc.height);
|
||||
result = create_temporary_subresource_view(cmd, &desc.external_handle, desc.gcm_format, desc.x, desc.y, desc.width, desc.height, desc.remap);
|
||||
|
||||
if (result)
|
||||
{
|
||||
|
@ -1288,7 +1290,7 @@ namespace rsx
|
|||
|
||||
template <typename render_target_type, typename surface_store_type>
|
||||
sampled_image_descriptor process_framebuffer_resource(commandbuffer_type& cmd, render_target_type texptr, u32 texaddr, u32 gcm_format, surface_store_type& m_rtts,
|
||||
u16 tex_width, u16 tex_height, u16 tex_pitch, rsx::texture_dimension_extended extended_dimension, bool is_depth)
|
||||
u16 tex_width, u16 tex_height, u16 tex_pitch, rsx::texture_dimension_extended extended_dimension, bool is_depth, const texture_channel_remap_t& remap)
|
||||
{
|
||||
const u32 format = gcm_format & ~(CELL_GCM_TEXTURE_UN | CELL_GCM_TEXTURE_LN);
|
||||
const auto surface_width = texptr->get_surface_width();
|
||||
|
@ -1348,7 +1350,7 @@ namespace rsx
|
|||
|
||||
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 };
|
||||
rsx::texture_dimension_extended::texture_dimension_cubemap, remap };
|
||||
|
||||
desc.set_external_cubemap_resources(image_array);
|
||||
return desc;
|
||||
|
@ -1383,7 +1385,7 @@ namespace rsx
|
|||
|
||||
sampled_image_descriptor result = { texptr->get_surface(), texaddr, format, 0, 0, w, h,
|
||||
texture_upload_context::framebuffer_storage, is_depth, scale_x, scale_y,
|
||||
rsx::texture_dimension_extended::texture_dimension_2d };
|
||||
rsx::texture_dimension_extended::texture_dimension_2d, remap };
|
||||
|
||||
result.external_subresource_desc.is_copy_cmd = true;
|
||||
result.external_subresource_desc.sections_to_copy.reserve(overlapping.size());
|
||||
|
@ -1472,13 +1474,13 @@ namespace rsx
|
|||
const auto h = rsx::apply_resolution_scale(internal_height, true);
|
||||
|
||||
sampled_image_descriptor result = { texptr->get_surface(), texaddr, format, 0, 0, w, h, texture_upload_context::framebuffer_storage,
|
||||
is_depth, scale_x, scale_y, rsx::texture_dimension_extended::texture_dimension_2d };
|
||||
is_depth, scale_x, scale_y, rsx::texture_dimension_extended::texture_dimension_2d, remap };
|
||||
|
||||
result.external_subresource_desc.update_cached = update_subresource_cache;
|
||||
return result;
|
||||
}
|
||||
|
||||
return{ texptr->get_view(), texture_upload_context::framebuffer_storage, is_depth, scale_x, scale_y, rsx::texture_dimension_extended::texture_dimension_2d };
|
||||
return{ texptr->get_view(remap), texture_upload_context::framebuffer_storage, is_depth, scale_x, scale_y, rsx::texture_dimension_extended::texture_dimension_2d };
|
||||
}
|
||||
|
||||
template <typename RsxTextureType, typename surface_store_type, typename ...Args>
|
||||
|
@ -1527,7 +1529,8 @@ namespace rsx
|
|||
{
|
||||
if (test_framebuffer(texaddr))
|
||||
{
|
||||
return process_framebuffer_resource(cmd, texptr, texaddr, tex.format(), m_rtts, tex_width, tex_height, tex_pitch, extended_dimension, false);
|
||||
return process_framebuffer_resource(cmd, texptr, texaddr, tex.format(), m_rtts,
|
||||
tex_width, tex_height, tex_pitch, extended_dimension, false, tex.decoded_remap());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1540,7 +1543,8 @@ namespace rsx
|
|||
{
|
||||
if (test_framebuffer(texaddr))
|
||||
{
|
||||
return process_framebuffer_resource(cmd, texptr, texaddr, tex.format(), m_rtts, tex_width, tex_height, tex_pitch, extended_dimension, true);
|
||||
return process_framebuffer_resource(cmd, texptr, texaddr, tex.format(), m_rtts,
|
||||
tex_width, tex_height, tex_pitch, extended_dimension, true, tex.decoded_remap());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1559,17 +1563,11 @@ namespace rsx
|
|||
|
||||
if (!is_compressed_format)
|
||||
{
|
||||
/* Check if we are re-sampling a subresource of an RTV/DSV texture, bound or otherwise
|
||||
* This check is much stricter than the one above
|
||||
* (Turbo: Super Stunt Squad does this; bypassing the need for a sync object)
|
||||
* The engine does not read back the texture resource through cell, but specifies a texture location that is
|
||||
* a bound render target. We can bypass the expensive download in this case
|
||||
*/
|
||||
// Check if we are re-sampling a subresource of an RTV/DSV texture, bound or otherwise
|
||||
|
||||
const auto rsc = m_rtts.get_surface_subresource_if_applicable(texaddr, tex_width, tex_height, tex_pitch);
|
||||
if (rsc.surface)
|
||||
{
|
||||
//TODO: Check that this region is not cpu-dirty before doing a copy
|
||||
if (!test_framebuffer(rsc.base_address))
|
||||
{
|
||||
m_rtts.invalidate_surface_address(rsc.base_address, rsc.is_depth_surface);
|
||||
|
@ -1587,23 +1585,10 @@ namespace rsx
|
|||
u16 internal_height = tex_height;
|
||||
|
||||
get_native_dimensions(internal_width, internal_height, rsc.surface);
|
||||
if (!rsc.is_bound || !g_cfg.video.strict_rendering_mode)
|
||||
if (!rsc.x && !rsc.y && rsc.w == internal_width && rsc.h == internal_height)
|
||||
{
|
||||
if (!rsc.x && !rsc.y && rsc.w == internal_width && rsc.h == internal_height)
|
||||
{
|
||||
if (rsc.is_bound)
|
||||
{
|
||||
LOG_WARNING(RSX, "Sampling from a currently bound render target @ 0x%x", texaddr);
|
||||
insert_texture_barrier(cmd, rsc.surface);
|
||||
}
|
||||
|
||||
return{ rsc.surface->get_view(), texture_upload_context::framebuffer_storage, rsc.is_depth_surface,
|
||||
scale_x, scale_y, rsx::texture_dimension_extended::texture_dimension_2d };
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_WARNING(RSX, "Attempting to sample a currently bound render target @ 0x%x", texaddr);
|
||||
//Full sized hit from the surface cache. This should have been already found before getting here
|
||||
fmt::throw_exception("Unreachable" HERE);
|
||||
}
|
||||
|
||||
internal_width = rsx::apply_resolution_scale(internal_width, true);
|
||||
|
@ -1611,7 +1596,7 @@ namespace rsx
|
|||
|
||||
return{ rsc.surface->get_surface(), rsc.base_address, format, rsx::apply_resolution_scale(rsc.x, false), rsx::apply_resolution_scale(rsc.y, false),
|
||||
internal_width, internal_height, texture_upload_context::framebuffer_storage, rsc.is_depth_surface, scale_x, scale_y,
|
||||
rsx::texture_dimension_extended::texture_dimension_2d };
|
||||
rsx::texture_dimension_extended::texture_dimension_2d, tex.decoded_remap() };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1680,7 +1665,7 @@ namespace rsx
|
|||
|
||||
auto src_image = surface->get_raw_texture();
|
||||
return{ src_image, surface->get_section_base(), format, offset_x, offset_y, tex_width, tex_height, texture_upload_context::blit_engine_dst,
|
||||
surface->is_depth_texture(), scale_x, scale_y, rsx::texture_dimension_extended::texture_dimension_2d };
|
||||
surface->is_depth_texture(), scale_x, scale_y, rsx::texture_dimension_extended::texture_dimension_2d, default_remap_vector };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ namespace gl
|
|||
u16 surface_pixel_size = 0;
|
||||
|
||||
texture::internal_format compatible_internal_format = texture::internal_format::rgba8;
|
||||
|
||||
std::array<GLenum, 4> native_component_mapping;
|
||||
public:
|
||||
render_target *old_contents = nullptr;
|
||||
|
||||
|
@ -116,8 +116,10 @@ namespace gl
|
|||
return id();
|
||||
}
|
||||
|
||||
u32 get_view() const
|
||||
u32 get_view(const std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap) const
|
||||
{
|
||||
bind();
|
||||
apply_swizzle_remap(GL_TEXTURE_2D, native_component_mapping, remap);
|
||||
return id();
|
||||
}
|
||||
|
||||
|
@ -137,6 +139,12 @@ namespace gl
|
|||
internal_height = height();
|
||||
surface_width = rsx::apply_inverse_resolution_scale(internal_width, true);
|
||||
surface_height = rsx::apply_inverse_resolution_scale(internal_height, true);
|
||||
|
||||
bind();
|
||||
glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, (GLint*)&native_component_mapping[0]);
|
||||
glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, (GLint*)&native_component_mapping[1]);
|
||||
glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, (GLint*)&native_component_mapping[2]);
|
||||
glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, (GLint*)&native_component_mapping[3]);
|
||||
}
|
||||
|
||||
bool matches_dimensions(u16 _width, u16 _height) const
|
||||
|
|
|
@ -654,7 +654,8 @@ namespace gl
|
|||
m_temporary_surfaces.resize(0);
|
||||
}
|
||||
|
||||
u32 create_temporary_subresource_impl(u32 src_id, GLenum sized_internal_fmt, GLenum dst_type, u32 gcm_format, u16 x, u16 y, u16 width, u16 height, bool copy = true)
|
||||
u32 create_temporary_subresource_impl(u32 src_id, GLenum sized_internal_fmt, GLenum dst_type, u32 gcm_format,
|
||||
u16 x, u16 y, u16 width, u16 height, const texture_channel_remap_t& remap, bool copy)
|
||||
{
|
||||
u32 dst_id = 0;
|
||||
|
||||
|
@ -712,6 +713,10 @@ namespace gl
|
|||
apply_component_mapping_flags(dst_type, gcm_format, rsx::texture_create_flags::default_component_order);
|
||||
}
|
||||
|
||||
if (memcmp(remap.first.data(), default_remap_vector.first.data(), 4) ||
|
||||
memcmp(remap.second.data(), default_remap_vector.second.data(), 4))
|
||||
set_up_remap_vector(dst_id, dst_type, remap);
|
||||
|
||||
return dst_id;
|
||||
}
|
||||
|
||||
|
@ -765,6 +770,18 @@ namespace gl
|
|||
}
|
||||
}
|
||||
|
||||
void set_up_remap_vector(u32 texture_id, GLenum texture_type, const texture_channel_remap_t& remap_vector)
|
||||
{
|
||||
std::array<GLenum, 4> swizzle_remap;
|
||||
glBindTexture(texture_type, texture_id);
|
||||
glGetTexParameteriv(texture_type, GL_TEXTURE_SWIZZLE_A, (GLint*)&swizzle_remap[0]);
|
||||
glGetTexParameteriv(texture_type, GL_TEXTURE_SWIZZLE_R, (GLint*)&swizzle_remap[1]);
|
||||
glGetTexParameteriv(texture_type, GL_TEXTURE_SWIZZLE_G, (GLint*)&swizzle_remap[2]);
|
||||
glGetTexParameteriv(texture_type, GL_TEXTURE_SWIZZLE_B, (GLint*)&swizzle_remap[3]);
|
||||
|
||||
apply_swizzle_remap(texture_type, swizzle_remap, remap_vector);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
void free_texture_section(cached_texture_section& tex) override
|
||||
|
@ -772,24 +789,28 @@ namespace gl
|
|||
tex.destroy();
|
||||
}
|
||||
|
||||
u32 create_temporary_subresource_view(void*&, u32* src, u32 gcm_format, u16 x, u16 y, u16 w, u16 h) override
|
||||
u32 create_temporary_subresource_view(void*&, u32* src, u32 gcm_format, u16 x, u16 y, u16 w, u16 h,
|
||||
const texture_channel_remap_t& remap_vector) override
|
||||
{
|
||||
return create_temporary_subresource_impl(*src, GL_NONE, GL_TEXTURE_2D, gcm_format, x, y, w, h);
|
||||
return create_temporary_subresource_impl(*src, GL_NONE, GL_TEXTURE_2D, gcm_format, x, y, w, h, remap_vector, true);
|
||||
}
|
||||
|
||||
u32 create_temporary_subresource_view(void*&, gl::texture* src, u32 gcm_format, u16 x, u16 y, u16 w, u16 h) override
|
||||
u32 create_temporary_subresource_view(void*&, gl::texture* src, u32 gcm_format, u16 x, u16 y, u16 w, u16 h,
|
||||
const texture_channel_remap_t& remap_vector) override
|
||||
{
|
||||
if (auto as_rtt = dynamic_cast<gl::render_target*>(src))
|
||||
{
|
||||
return create_temporary_subresource_impl(src->id(), (GLenum)as_rtt->get_compatible_internal_format(), GL_TEXTURE_2D, gcm_format, x, y, w, h);
|
||||
return create_temporary_subresource_impl(src->id(), (GLenum)as_rtt->get_compatible_internal_format(),
|
||||
GL_TEXTURE_2D, gcm_format, x, y, w, h, remap_vector, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
return create_temporary_subresource_impl(src->id(), GL_NONE, GL_TEXTURE_2D, gcm_format, x, y, w, h);
|
||||
return create_temporary_subresource_impl(src->id(), GL_NONE, GL_TEXTURE_2D, gcm_format, x, y, w, h,
|
||||
remap_vector, true);
|
||||
}
|
||||
}
|
||||
|
||||
u32 generate_cubemap_from_images(void*&, u32 gcm_format, u16 size, const std::array<u32, 6>& sources) override
|
||||
u32 generate_cubemap_from_images(void*&, u32 gcm_format, u16 size, const std::array<u32, 6>& sources, const texture_channel_remap_t& remap_vector) override
|
||||
{
|
||||
const GLenum ifmt = gl::get_sized_internal_format(gcm_format);
|
||||
GLuint dst_id = 0;
|
||||
|
@ -826,9 +847,10 @@ namespace gl
|
|||
return dst_id;
|
||||
}
|
||||
|
||||
u32 generate_atlas_from_images(void*&, u32 gcm_format, u16 width, u16 height, const std::vector<copy_region_descriptor>& sections_to_copy) override
|
||||
u32 generate_atlas_from_images(void*&, u32 gcm_format, u16 width, u16 height, const std::vector<copy_region_descriptor>& sections_to_copy,
|
||||
const texture_channel_remap_t& remap_vector) override
|
||||
{
|
||||
auto result = create_temporary_subresource_impl(sections_to_copy.front().src, GL_NONE, GL_TEXTURE_2D, gcm_format, 0, 0, width, height, false);
|
||||
auto result = create_temporary_subresource_impl(sections_to_copy.front().src, GL_NONE, GL_TEXTURE_2D, gcm_format, 0, 0, width, height, remap_vector, false);
|
||||
|
||||
for (const auto ®ion : sections_to_copy)
|
||||
{
|
||||
|
@ -847,7 +869,7 @@ namespace gl
|
|||
|
||||
cached_texture_section* create_new_texture(void*&, u32 rsx_address, u32 rsx_size, u16 width, u16 height, u16 depth, u16 mipmaps, u32 gcm_format,
|
||||
rsx::texture_upload_context context, rsx::texture_dimension_extended type, rsx::texture_create_flags flags,
|
||||
rsx::texture_colorspace colorspace, const std::pair<std::array<u8, 4>, std::array<u8, 4>>& /*remap_vector*/) override
|
||||
rsx::texture_colorspace colorspace, const texture_channel_remap_t& /*remap_vector*/) override
|
||||
{
|
||||
u32 vram_texture = gl::create_texture(gcm_format, width, height, depth, mipmaps, type, colorspace);
|
||||
bool depth_flag = false;
|
||||
|
@ -919,7 +941,7 @@ namespace gl
|
|||
|
||||
cached_texture_section* upload_image_from_cpu(void*&, u32 rsx_address, u16 width, u16 height, u16 depth, u16 mipmaps, u16 pitch, u32 gcm_format,
|
||||
rsx::texture_upload_context context, const std::vector<rsx_subresource_layout>& subresource_layout, rsx::texture_dimension_extended type,
|
||||
rsx::texture_colorspace colorspace, bool swizzled, const std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap_vector) override
|
||||
rsx::texture_colorspace colorspace, bool swizzled, const texture_channel_remap_t& remap_vector) override
|
||||
{
|
||||
void* unused = nullptr;
|
||||
auto section = create_new_texture(unused, rsx_address, pitch * height, width, height, depth, mipmaps, gcm_format, context, type,
|
||||
|
@ -955,16 +977,9 @@ namespace gl
|
|||
section.set_sampler_status(rsx::texture_sampler_status::status_uninitialized);
|
||||
}
|
||||
|
||||
void set_up_remap_vector(cached_texture_section& section, const std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap_vector) override
|
||||
void set_up_remap_vector(cached_texture_section& section, const texture_channel_remap_t& remap_vector) override
|
||||
{
|
||||
std::array<GLenum, 4> swizzle_remap;
|
||||
glBindTexture(GL_TEXTURE_2D, section.get_raw_texture());
|
||||
glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, (GLint*)&swizzle_remap[0]);
|
||||
glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, (GLint*)&swizzle_remap[1]);
|
||||
glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, (GLint*)&swizzle_remap[2]);
|
||||
glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, (GLint*)&swizzle_remap[3]);
|
||||
|
||||
apply_swizzle_remap(GL_TEXTURE_2D, swizzle_remap, remap_vector);
|
||||
set_up_remap_vector(section.get_raw_texture(), GL_TEXTURE_2D, remap_vector);
|
||||
section.set_sampler_status(rsx::texture_sampler_status::status_ready);
|
||||
}
|
||||
|
||||
|
|
|
@ -75,6 +75,7 @@ namespace vk
|
|||
bool sanitize_fp_values();
|
||||
|
||||
VkComponentMapping default_component_map();
|
||||
VkComponentMapping apply_swizzle_remap(const std::array<VkComponentSwizzle, 4>& base_remap, const std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap_vector);
|
||||
VkImageSubresource default_image_subresource();
|
||||
VkImageSubresourceRange get_image_subresource_range(uint32_t base_layer, uint32_t base_mip, uint32_t layer_count, uint32_t level_count, VkImageAspectFlags aspect);
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace vk
|
|||
u16 surface_height = 0;
|
||||
|
||||
VkImageAspectFlags attachment_aspect_flag = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
std::unique_ptr<vk::image_view> view;
|
||||
std::vector<std::unique_ptr<vk::image_view>> views;
|
||||
|
||||
render_target *old_contents = nullptr; //Data occupying the memory location that this surface is replacing
|
||||
u64 frame_tag = 0; //frame id when invalidated, 0 if not invalid
|
||||
|
@ -42,13 +42,43 @@ namespace vk
|
|||
mipmaps, layers, samples, initial_layout, tiling, usage, image_flags)
|
||||
{}
|
||||
|
||||
vk::image_view* get_view(const std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap)
|
||||
{
|
||||
VkComponentMapping real_mapping = vk::apply_swizzle_remap
|
||||
(
|
||||
{native_component_map.a, native_component_map.r, native_component_map.g, native_component_map.b },
|
||||
remap
|
||||
);
|
||||
|
||||
for (const auto& view : views)
|
||||
{
|
||||
if (view->info.components.a == real_mapping.a &&
|
||||
view->info.components.r == real_mapping.r &&
|
||||
view->info.components.g == real_mapping.g &&
|
||||
view->info.components.b == real_mapping.b)
|
||||
{
|
||||
return view.get();
|
||||
}
|
||||
}
|
||||
|
||||
auto view = std::make_unique<vk::image_view>(*vk::get_current_renderer(), value, VK_IMAGE_VIEW_TYPE_2D, info.format,
|
||||
real_mapping, vk::get_image_subresource_range(0, 0, 1, 1, attachment_aspect_flag & ~(VK_IMAGE_ASPECT_STENCIL_BIT)));
|
||||
|
||||
views.push_back(std::move(view));
|
||||
return views.back().get();
|
||||
}
|
||||
|
||||
vk::image_view* get_view()
|
||||
{
|
||||
if (!view)
|
||||
view = std::make_unique<vk::image_view>(*vk::get_current_renderer(), value, VK_IMAGE_VIEW_TYPE_2D, info.format,
|
||||
if (views.empty())
|
||||
{
|
||||
auto view = std::make_unique<vk::image_view>(*vk::get_current_renderer(), value, VK_IMAGE_VIEW_TYPE_2D, info.format,
|
||||
native_component_map, vk::get_image_subresource_range(0, 0, 1, 1, attachment_aspect_flag & ~(VK_IMAGE_ASPECT_STENCIL_BIT)));
|
||||
|
||||
return view.get();
|
||||
views.push_back(std::move(view));
|
||||
}
|
||||
|
||||
return views.back().get();
|
||||
}
|
||||
|
||||
vk::image* get_surface() const override
|
||||
|
|
|
@ -180,4 +180,29 @@ namespace vk
|
|||
mipmap_level++;
|
||||
}
|
||||
}
|
||||
|
||||
VkComponentMapping apply_swizzle_remap(const std::array<VkComponentSwizzle, 4>& base_remap, const std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap_vector)
|
||||
{
|
||||
VkComponentSwizzle final_mapping[4] = {};
|
||||
|
||||
for (u8 channel = 0; channel < 4; ++channel)
|
||||
{
|
||||
switch (remap_vector.second[channel])
|
||||
{
|
||||
case CELL_GCM_TEXTURE_REMAP_ONE:
|
||||
final_mapping[channel] = VK_COMPONENT_SWIZZLE_ONE;
|
||||
break;
|
||||
case CELL_GCM_TEXTURE_REMAP_ZERO:
|
||||
final_mapping[channel] = VK_COMPONENT_SWIZZLE_ZERO;
|
||||
break;
|
||||
case CELL_GCM_TEXTURE_REMAP_REMAP:
|
||||
final_mapping[channel] = base_remap[remap_vector.first[channel]];
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR(RSX, "Unknown remap lookup value %d", remap_vector.second[channel]);
|
||||
}
|
||||
}
|
||||
|
||||
return{ final_mapping[1], final_mapping[2], final_mapping[3], final_mapping[0] };
|
||||
}
|
||||
}
|
||||
|
|
|
@ -489,32 +489,7 @@ namespace vk
|
|||
m_discarded_memory_size = 0;
|
||||
}
|
||||
|
||||
VkComponentMapping apply_swizzle_remap(const std::array<VkComponentSwizzle, 4>& base_remap, const std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap_vector)
|
||||
{
|
||||
VkComponentSwizzle final_mapping[4] = {};
|
||||
|
||||
for (u8 channel = 0; channel < 4; ++channel)
|
||||
{
|
||||
switch (remap_vector.second[channel])
|
||||
{
|
||||
case CELL_GCM_TEXTURE_REMAP_ONE:
|
||||
final_mapping[channel] = VK_COMPONENT_SWIZZLE_ONE;
|
||||
break;
|
||||
case CELL_GCM_TEXTURE_REMAP_ZERO:
|
||||
final_mapping[channel] = VK_COMPONENT_SWIZZLE_ZERO;
|
||||
break;
|
||||
case CELL_GCM_TEXTURE_REMAP_REMAP:
|
||||
final_mapping[channel] = base_remap[remap_vector.first[channel]];
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR(RSX, "Unknown remap lookup value %d", remap_vector.second[channel]);
|
||||
}
|
||||
}
|
||||
|
||||
return { final_mapping[1], final_mapping[2], final_mapping[3], final_mapping[0] };
|
||||
}
|
||||
|
||||
VkComponentMapping apply_component_mapping_flags(u32 gcm_format, rsx::texture_create_flags flags, const std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap_vector)
|
||||
VkComponentMapping apply_component_mapping_flags(u32 gcm_format, rsx::texture_create_flags flags, const texture_channel_remap_t& remap_vector)
|
||||
{
|
||||
//NOTE: Depth textures should always read RRRR
|
||||
switch (gcm_format)
|
||||
|
@ -535,7 +510,7 @@ namespace vk
|
|||
{
|
||||
case rsx::texture_create_flags::default_component_order:
|
||||
{
|
||||
mapping = apply_swizzle_remap(vk::get_component_mapping(gcm_format), remap_vector);
|
||||
mapping = vk::apply_swizzle_remap(vk::get_component_mapping(gcm_format), remap_vector);
|
||||
break;
|
||||
}
|
||||
case rsx::texture_create_flags::native_component_order:
|
||||
|
@ -564,7 +539,8 @@ namespace vk
|
|||
tex.destroy();
|
||||
}
|
||||
|
||||
vk::image_view* create_temporary_subresource_view_impl(vk::command_buffer& cmd, vk::image* source, VkImageType image_type, VkImageViewType view_type, u32 gcm_format, u16 x, u16 y, u16 w, u16 h, bool copy = true)
|
||||
vk::image_view* create_temporary_subresource_view_impl(vk::command_buffer& cmd, vk::image* source, VkImageType image_type, VkImageViewType view_type,
|
||||
u32 gcm_format, u16 x, u16 y, u16 w, u16 h, const texture_channel_remap_t& remap_vector, bool copy)
|
||||
{
|
||||
VkImageAspectFlags aspect = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
|
||||
|
@ -597,16 +573,22 @@ namespace vk
|
|||
w, h, 1, 1, 1, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, source->info.flags));
|
||||
|
||||
//This method is almost exclusively used to work on framebuffer resources
|
||||
//Keep the original swizzle layout unless there is data format conversion
|
||||
VkComponentMapping view_swizzle = source->native_component_map;
|
||||
if (dst_format != source->info.format)
|
||||
{
|
||||
//This is a data cast operation
|
||||
//Use native mapping for the new type
|
||||
//TODO: Also reapply the view swizzle
|
||||
//TODO: Also simlulate the readback+reupload step (very tricky)
|
||||
const auto remap = get_component_mapping(gcm_format);
|
||||
view_swizzle = { remap[1], remap[2], remap[3], remap[0] };
|
||||
}
|
||||
|
||||
if (memcmp(remap_vector.first.data(), default_remap_vector.first.data(), 4) ||
|
||||
memcmp(remap_vector.second.data(), default_remap_vector.second.data(), 4))
|
||||
view_swizzle = vk::apply_swizzle_remap({view_swizzle.a, view_swizzle.r, view_swizzle.g, view_swizzle.b}, remap_vector);
|
||||
|
||||
VkImageSubresourceRange view_range = { aspect & ~(VK_IMAGE_ASPECT_STENCIL_BIT), 0, 1, 0, 1 };
|
||||
view.reset(new vk::image_view(*vk::get_current_renderer(), image->value, view_type, dst_format, view_swizzle, view_range));
|
||||
|
||||
|
@ -637,17 +619,21 @@ namespace vk
|
|||
return m_discardable_storage.back().view.get();
|
||||
}
|
||||
|
||||
vk::image_view* create_temporary_subresource_view(vk::command_buffer& cmd, vk::image* source, u32 gcm_format, u16 x, u16 y, u16 w, u16 h) override
|
||||
vk::image_view* create_temporary_subresource_view(vk::command_buffer& cmd, vk::image* source, u32 gcm_format,
|
||||
u16 x, u16 y, u16 w, u16 h, const texture_channel_remap_t& remap_vector) override
|
||||
{
|
||||
return create_temporary_subresource_view_impl(cmd, source, source->info.imageType, VK_IMAGE_VIEW_TYPE_2D, gcm_format, x, y, w, h);
|
||||
return create_temporary_subresource_view_impl(cmd, source, source->info.imageType, VK_IMAGE_VIEW_TYPE_2D,
|
||||
gcm_format, x, y, w, h, remap_vector, true);
|
||||
}
|
||||
|
||||
vk::image_view* create_temporary_subresource_view(vk::command_buffer& cmd, vk::image** source, u32 gcm_format, u16 x, u16 y, u16 w, u16 h) override
|
||||
vk::image_view* create_temporary_subresource_view(vk::command_buffer& cmd, vk::image** source, u32 gcm_format,
|
||||
u16 x, u16 y, u16 w, u16 h, const texture_channel_remap_t& remap_vector) override
|
||||
{
|
||||
return create_temporary_subresource_view(cmd, *source, gcm_format, x, y, w, h);
|
||||
return create_temporary_subresource_view(cmd, *source, gcm_format, x, y, w, h, remap_vector);
|
||||
}
|
||||
|
||||
vk::image_view* generate_cubemap_from_images(vk::command_buffer& cmd, u32 gcm_format, u16 size, const std::array<vk::image*, 6>& sources) override
|
||||
vk::image_view* generate_cubemap_from_images(vk::command_buffer& cmd, u32 gcm_format, u16 size,
|
||||
const std::array<vk::image*, 6>& sources, const texture_channel_remap_t& remap_vector) override
|
||||
{
|
||||
std::unique_ptr<vk::image> image;
|
||||
std::unique_ptr<vk::image_view> view;
|
||||
|
@ -719,10 +705,11 @@ namespace vk
|
|||
return m_discardable_storage.back().view.get();
|
||||
}
|
||||
|
||||
vk::image_view* generate_atlas_from_images(vk::command_buffer& cmd, u32 gcm_format, u16 width, u16 height, const std::vector<copy_region_descriptor>& sections_to_copy) override
|
||||
vk::image_view* generate_atlas_from_images(vk::command_buffer& cmd, u32 gcm_format, u16 width, u16 height,
|
||||
const std::vector<copy_region_descriptor>& sections_to_copy, const texture_channel_remap_t& remap_vector) override
|
||||
{
|
||||
auto result = create_temporary_subresource_view_impl(cmd, sections_to_copy.front().src, VK_IMAGE_TYPE_2D,
|
||||
VK_IMAGE_VIEW_TYPE_2D, gcm_format, 0, 0, width, height, false);
|
||||
VK_IMAGE_VIEW_TYPE_2D, gcm_format, 0, 0, width, height, default_remap_vector, false);
|
||||
|
||||
VkImage dst = result->info.image;
|
||||
VkImageAspectFlags aspect = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
|
@ -800,7 +787,7 @@ namespace vk
|
|||
|
||||
cached_texture_section* create_new_texture(vk::command_buffer& cmd, u32 rsx_address, u32 rsx_size, u16 width, u16 height, u16 depth, u16 mipmaps, u32 gcm_format,
|
||||
rsx::texture_upload_context context, rsx::texture_dimension_extended type, rsx::texture_create_flags flags,
|
||||
rsx::texture_colorspace colorspace, const std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap_vector) override
|
||||
rsx::texture_colorspace colorspace, const texture_channel_remap_t& remap_vector) override
|
||||
{
|
||||
const u16 section_depth = depth;
|
||||
const bool is_cubemap = type == rsx::texture_dimension_extended::texture_dimension_cubemap;
|
||||
|
@ -902,7 +889,7 @@ namespace vk
|
|||
|
||||
cached_texture_section* upload_image_from_cpu(vk::command_buffer& cmd, u32 rsx_address, u16 width, u16 height, u16 depth, u16 mipmaps, u16 pitch, u32 gcm_format,
|
||||
rsx::texture_upload_context context, const std::vector<rsx_subresource_layout>& subresource_layout, rsx::texture_dimension_extended type,
|
||||
rsx::texture_colorspace colorspace, bool swizzled, const std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap_vector) override
|
||||
rsx::texture_colorspace colorspace, bool swizzled, const texture_channel_remap_t& remap_vector) override
|
||||
{
|
||||
auto section = create_new_texture(cmd, rsx_address, pitch * height, width, height, depth, mipmaps, gcm_format, context, type,
|
||||
rsx::texture_create_flags::default_component_order, colorspace, remap_vector);
|
||||
|
@ -971,13 +958,13 @@ namespace vk
|
|||
section.set_sampler_status(rsx::texture_sampler_status::status_uninitialized);
|
||||
}
|
||||
|
||||
void set_up_remap_vector(cached_texture_section& section, const std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap_vector) override
|
||||
void set_up_remap_vector(cached_texture_section& section, const texture_channel_remap_t& remap_vector) override
|
||||
{
|
||||
auto& view = section.get_view();
|
||||
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);
|
||||
auto final_remap = vk::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 ||
|
||||
|
|
Loading…
Add table
Reference in a new issue