mirror of
https://github.com/RPCSX/rpcsx.git
synced 2026-01-30 04:14:43 +01:00
rsx: Reimplement cached textures and their views
This commit is contained in:
parent
8b693ed7bb
commit
8695f95267
|
|
@ -17,12 +17,6 @@ namespace rsx
|
|||
swapped_native_component_order = 2,
|
||||
};
|
||||
|
||||
enum texture_sampler_status
|
||||
{
|
||||
status_uninitialized = 0,
|
||||
status_ready = 1
|
||||
};
|
||||
|
||||
enum memory_read_flags
|
||||
{
|
||||
flush_always = 0,
|
||||
|
|
@ -83,7 +77,6 @@ namespace rsx
|
|||
rsx::texture_create_flags view_flags = rsx::texture_create_flags::default_component_order;
|
||||
rsx::texture_upload_context context = rsx::texture_upload_context::shader_read;
|
||||
rsx::texture_dimension_extended image_type = rsx::texture_dimension_extended::texture_dimension_2d;
|
||||
rsx::texture_sampler_status sampler_status = rsx::texture_sampler_status::status_uninitialized;
|
||||
|
||||
bool matches(u32 rsx_address, u32 rsx_size)
|
||||
{
|
||||
|
|
@ -146,11 +139,6 @@ namespace rsx
|
|||
image_type = type;
|
||||
}
|
||||
|
||||
void set_sampler_status(rsx::texture_sampler_status status)
|
||||
{
|
||||
sampler_status = status;
|
||||
}
|
||||
|
||||
void set_gcm_format(u32 format)
|
||||
{
|
||||
gcm_format = format;
|
||||
|
|
@ -196,11 +184,6 @@ namespace rsx
|
|||
return readback_behaviour;
|
||||
}
|
||||
|
||||
rsx::texture_sampler_status get_sampler_status() const
|
||||
{
|
||||
return sampler_status;
|
||||
}
|
||||
|
||||
bool writes_likely_completed() const
|
||||
{
|
||||
// TODO: Move this to the miss statistics block
|
||||
|
|
@ -479,11 +462,10 @@ namespace rsx
|
|||
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 texture_channel_remap_t& remap_vector) = 0;
|
||||
rsx::texture_upload_context context, rsx::texture_dimension_extended type, texture_create_flags flags) = 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 texture_channel_remap_t& remap_vector) = 0;
|
||||
const std::vector<rsx_subresource_layout>& subresource_layout, rsx::texture_dimension_extended type, bool swizzled) = 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 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::vector<copy_region_descriptor>& sources, const texture_channel_remap_t& remap_vector) = 0;
|
||||
virtual image_view_type generate_3d_from_2d_images(commandbuffer_type&, u32 gcm_format, u16 width, u16 height, u16 depth, const std::vector<copy_region_descriptor>& sources, const texture_channel_remap_t& remap_vector) = 0;
|
||||
|
|
@ -1064,9 +1046,8 @@ namespace rsx
|
|||
no_access_range = region.get_min_max(no_access_range);
|
||||
}
|
||||
|
||||
region.create(width, height, 1, 1, nullptr, image, pitch, false, std::forward<Args>(extras)...);
|
||||
region.create(width, height, 1, 1, image, pitch, false, std::forward<Args>(extras)...);
|
||||
region.set_context(texture_upload_context::framebuffer_storage);
|
||||
region.set_sampler_status(rsx::texture_sampler_status::status_uninitialized);
|
||||
region.set_image_type(rsx::texture_dimension_extended::texture_dimension_2d);
|
||||
region.set_memory_read_flags(memory_read_flags::flush_always);
|
||||
region.touch();
|
||||
|
|
@ -1860,10 +1841,7 @@ namespace rsx
|
|||
if (cached_texture->get_image_type() == rsx::texture_dimension_extended::texture_dimension_1d)
|
||||
scale_y = 0.f;
|
||||
|
||||
if (cached_texture->get_sampler_status() != rsx::texture_sampler_status::status_ready)
|
||||
set_up_remap_vector(*cached_texture, tex.decoded_remap());
|
||||
|
||||
return{ cached_texture->get_raw_view(), cached_texture->get_context(), cached_texture->is_depth_texture(), scale_x, scale_y, cached_texture->get_image_type() };
|
||||
return{ cached_texture->get_view(tex.remap(), tex.decoded_remap()), cached_texture->get_context(), cached_texture->is_depth_texture(), scale_x, scale_y, cached_texture->get_image_type() };
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1899,9 +1877,6 @@ namespace rsx
|
|||
break;
|
||||
}
|
||||
|
||||
if (surface->get_sampler_status() != rsx::texture_sampler_status::status_ready)
|
||||
set_up_remap_vector(*surface, tex.decoded_remap());
|
||||
|
||||
auto src_image = surface->get_raw_texture();
|
||||
return{ src_image, deferred_request_command::copy_image_static, surface->get_section_base(), format, offset_x, offset_y, tex_width, tex_height, 1,
|
||||
texture_upload_context::blit_engine_dst, surface->is_depth_texture(), scale_x, scale_y, rsx::texture_dimension_extended::texture_dimension_2d,
|
||||
|
|
@ -1917,7 +1892,6 @@ namespace rsx
|
|||
writer_lock lock(m_cache_mutex);
|
||||
const bool is_swizzled = !(tex.format() & CELL_GCM_TEXTURE_LN);
|
||||
auto subresources_layout = get_subresources_layout(tex);
|
||||
auto remap_vector = tex.decoded_remap();
|
||||
|
||||
bool is_depth_format = false;
|
||||
switch (format)
|
||||
|
|
@ -1936,7 +1910,7 @@ namespace rsx
|
|||
//NOTE: SRGB correction is to be handled in the fragment shader; upload as linear RGB
|
||||
m_texture_memory_in_use += (tex_pitch * tex_height);
|
||||
return{ upload_image_from_cpu(cmd, texaddr, tex_width, tex_height, depth, tex.get_exact_mipmap_count(), tex_pitch, format,
|
||||
texture_upload_context::shader_read, subresources_layout, extended_dimension, rsx::texture_colorspace::rgb_linear, is_swizzled, remap_vector)->get_raw_view(),
|
||||
texture_upload_context::shader_read, subresources_layout, extended_dimension, is_swizzled)->get_view(tex.remap(), tex.decoded_remap()),
|
||||
texture_upload_context::shader_read, is_depth_format, scale_x, scale_y, extended_dimension };
|
||||
}
|
||||
|
||||
|
|
@ -2220,7 +2194,7 @@ namespace rsx
|
|||
|
||||
const u32 gcm_format = src_is_argb8 ? CELL_GCM_TEXTURE_A8R8G8B8 : CELL_GCM_TEXTURE_R5G6B5;
|
||||
vram_texture = upload_image_from_cpu(cmd, src_address, src.width, src.slice_h, 1, 1, src.pitch, gcm_format, texture_upload_context::blit_engine_src,
|
||||
subresource_layout, rsx::texture_dimension_extended::texture_dimension_2d, rsx::texture_colorspace::rgb_linear, dst.swizzled, rsx::default_remap_vector)->get_raw_texture();
|
||||
subresource_layout, rsx::texture_dimension_extended::texture_dimension_2d, dst.swizzled)->get_raw_texture();
|
||||
|
||||
m_texture_memory_in_use += src.pitch * src.slice_h;
|
||||
}
|
||||
|
|
@ -2356,7 +2330,7 @@ namespace rsx
|
|||
cached_dest = 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,
|
||||
channel_order, rsx::texture_colorspace::rgb_linear, rsx::default_remap_vector);
|
||||
channel_order);
|
||||
|
||||
dest_texture = cached_dest->get_raw_texture();
|
||||
m_texture_memory_in_use += dst.pitch * dst_dimensions.height;
|
||||
|
|
|
|||
|
|
@ -68,6 +68,9 @@ namespace gl
|
|||
bool is_primitive_native(rsx::primitive_type in);
|
||||
GLenum draw_mode(rsx::primitive_type in);
|
||||
|
||||
// Texture helpers
|
||||
std::array<GLenum, 4> apply_swizzle_remap(const std::array<GLenum, 4>& swizzle_remap, const std::pair<std::array<u8, 4>, std::array<u8, 4>>& decoded_remap);
|
||||
|
||||
class exception : public std::exception
|
||||
{
|
||||
protected:
|
||||
|
|
@ -1889,6 +1892,28 @@ namespace gl
|
|||
}
|
||||
};
|
||||
|
||||
class viewable_image : public texture
|
||||
{
|
||||
std::unordered_map<u32, std::unique_ptr<texture_view>> views;
|
||||
|
||||
public:
|
||||
using texture::texture;
|
||||
texture_view* get_view(u32 remap_encoding, const std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap)
|
||||
{
|
||||
auto found = views.find(remap_encoding);
|
||||
if (found != views.end())
|
||||
{
|
||||
return found->second.get();
|
||||
}
|
||||
|
||||
auto mapping = apply_swizzle_remap(get_native_component_layout(), remap);
|
||||
auto view = std::make_unique<texture_view>(this, mapping.data());
|
||||
auto result = view.get();
|
||||
views[remap_encoding] = std::move(view);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
class rbo
|
||||
{
|
||||
GLuint m_id = 0;
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ namespace rsx
|
|||
|
||||
namespace gl
|
||||
{
|
||||
class render_target : public texture, public rsx::ref_counted, public rsx::render_target_descriptor<texture*>
|
||||
class render_target : public viewable_image, public rsx::ref_counted, public rsx::render_target_descriptor<texture*>
|
||||
{
|
||||
u32 rsx_pitch = 0;
|
||||
u16 native_pitch = 0;
|
||||
|
|
@ -60,11 +60,9 @@ namespace gl
|
|||
u16 surface_width = 0;
|
||||
u16 surface_pixel_size = 0;
|
||||
|
||||
std::unordered_map<u32, std::unique_ptr<texture_view>> views;
|
||||
|
||||
public:
|
||||
render_target(GLuint width, GLuint height, GLenum sized_format)
|
||||
:texture(GL_TEXTURE_2D, width, height, 1, 1, sized_format)
|
||||
: viewable_image(GL_TEXTURE_2D, width, height, 1, 1, sized_format)
|
||||
{}
|
||||
|
||||
void set_cleared(bool clear=true)
|
||||
|
|
@ -114,21 +112,6 @@ namespace gl
|
|||
return (gl::texture*)this;
|
||||
}
|
||||
|
||||
texture_view* get_view(u32 remap_encoding, const std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap)
|
||||
{
|
||||
auto found = views.find(remap_encoding);
|
||||
if (found != views.end())
|
||||
{
|
||||
return found->second.get();
|
||||
}
|
||||
|
||||
auto mapping = gl::apply_swizzle_remap(get_native_component_layout(), remap);
|
||||
auto view = std::make_unique<texture_view>(this, mapping.data());
|
||||
auto result = view.get();
|
||||
views[remap_encoding] = std::move(view);
|
||||
return result;
|
||||
}
|
||||
|
||||
u32 raw_handle() const
|
||||
{
|
||||
return id();
|
||||
|
|
|
|||
|
|
@ -387,8 +387,8 @@ namespace gl
|
|||
fmt::throw_exception("Unknown format 0x%x" HERE, texture_format);
|
||||
}
|
||||
|
||||
gl::texture* create_texture(u32 gcm_format, u16 width, u16 height, u16 depth, u16 mipmaps,
|
||||
rsx::texture_dimension_extended type, rsx::texture_colorspace colorspace)
|
||||
gl::viewable_image* create_texture(u32 gcm_format, u16 width, u16 height, u16 depth, u16 mipmaps,
|
||||
rsx::texture_dimension_extended type)
|
||||
{
|
||||
if (is_compressed_format(gcm_format))
|
||||
{
|
||||
|
|
@ -401,9 +401,6 @@ namespace gl
|
|||
GLenum target;
|
||||
GLenum internal_format = get_sized_internal_format(gcm_format);
|
||||
|
||||
if (colorspace != rsx::texture_colorspace::rgb_linear)
|
||||
internal_format = get_srgb_format(internal_format);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case rsx::texture_dimension_extended::texture_dimension_1d:
|
||||
|
|
@ -420,7 +417,7 @@ namespace gl
|
|||
break;
|
||||
}
|
||||
|
||||
return new gl::texture(target, width, height, depth, mipmaps, internal_format);
|
||||
return new gl::viewable_image(target, width, height, depth, mipmaps, internal_format);
|
||||
}
|
||||
|
||||
void fill_texture(rsx::texture_dimension_extended dim, u16 mipmap_count, int format, u16 width, u16 height, u16 depth,
|
||||
|
|
@ -564,8 +561,7 @@ namespace gl
|
|||
}
|
||||
|
||||
void upload_texture(GLuint id, u32 texaddr, u32 gcm_format, u16 width, u16 height, u16 depth, u16 mipmaps, bool is_swizzled, rsx::texture_dimension_extended type,
|
||||
const std::vector<rsx_subresource_layout>& subresources_layout, const std::pair<std::array<u8, 4>, std::array<u8, 4>>& decoded_remap, bool static_state,
|
||||
rsx::texture_colorspace colorspace)
|
||||
const std::vector<rsx_subresource_layout>& subresources_layout)
|
||||
{
|
||||
const bool is_cubemap = type == rsx::texture_dimension_extended::texture_dimension_cubemap;
|
||||
|
||||
|
|
@ -596,21 +592,9 @@ namespace gl
|
|||
glTexParameteri(target, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, mipmaps - 1);
|
||||
|
||||
if (static_state)
|
||||
{
|
||||
//Usually for vertex textures
|
||||
glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_REPEAT);
|
||||
|
||||
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.f);
|
||||
}
|
||||
|
||||
//The rest of sampler state is now handled by sampler state objects
|
||||
const auto format_type = get_format_type(gcm_format);
|
||||
const GLenum gl_format = (colorspace == rsx::texture_colorspace::rgb_linear)? std::get<0>(format_type) : get_srgb_format(std::get<0>(format_type));
|
||||
const GLenum gl_format = std::get<0>(format_type);
|
||||
const GLenum gl_type = std::get<1>(format_type);
|
||||
fill_texture(type, mipmaps, gcm_format, width, height, depth, subresources_layout, is_swizzled, gl_format, gl_type, data_upload_buf);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ namespace gl
|
|||
float max_aniso(rsx::texture_max_anisotropy aniso);
|
||||
std::array<GLenum, 4> get_swizzle_remap(u32 texture_format);
|
||||
|
||||
texture* create_texture(u32 gcm_format, u16 width, u16 height, u16 depth, u16 mipmaps, rsx::texture_dimension_extended type, rsx::texture_colorspace colorspace);
|
||||
viewable_image* create_texture(u32 gcm_format, u16 width, u16 height, u16 depth, u16 mipmaps, rsx::texture_dimension_extended type);
|
||||
|
||||
void copy_typeless(texture* dst, const texture* src);
|
||||
/**
|
||||
|
|
@ -31,8 +31,7 @@ namespace gl
|
|||
* static_state - set up the texture without consideration for sampler state (useful for vertex textures which have no real sampler state on RSX)
|
||||
*/
|
||||
void upload_texture(GLuint id, u32 texaddr, u32 gcm_format, u16 width, u16 height, u16 depth, u16 mipmaps, bool is_swizzled, rsx::texture_dimension_extended type,
|
||||
const std::vector<rsx_subresource_layout>& subresources_layout, const std::pair<std::array<u8, 4>, std::array<u8, 4>>& decoded_remap, bool static_state,
|
||||
rsx::texture_colorspace colorspace);
|
||||
const std::vector<rsx_subresource_layout>& subresources_layout);
|
||||
|
||||
std::array<GLenum, 4> apply_swizzle_remap(const std::array<GLenum, 4>& swizzle_remap, const std::pair<std::array<u8, 4>, std::array<u8, 4>>& decoded_remap);
|
||||
|
||||
|
|
|
|||
|
|
@ -148,10 +148,9 @@ namespace gl
|
|||
u32 pbo_id = 0;
|
||||
u32 pbo_size = 0;
|
||||
|
||||
gl::texture* vram_texture = nullptr;
|
||||
gl::viewable_image* vram_texture = nullptr;
|
||||
|
||||
std::unique_ptr<gl::texture_view> view;
|
||||
std::unique_ptr<gl::texture> managed_texture;
|
||||
std::unique_ptr<gl::viewable_image> managed_texture;
|
||||
std::unique_ptr<gl::texture> scaled_texture;
|
||||
|
||||
bool is_depth = false;
|
||||
|
|
@ -265,25 +264,20 @@ namespace gl
|
|||
|
||||
vram_texture = nullptr;
|
||||
managed_texture.reset();
|
||||
view.reset();
|
||||
}
|
||||
|
||||
void create(u16 w, u16 h, u16 depth, u16 mipmaps, gl::texture_view* _view,
|
||||
gl::texture* image, u32 rsx_pitch, bool read_only,
|
||||
void create(u16 w, u16 h, u16 depth, u16 mipmaps, gl::texture* image, u32 rsx_pitch, bool read_only,
|
||||
gl::texture::format gl_format, gl::texture::type gl_type, bool swap_bytes)
|
||||
{
|
||||
vram_texture = static_cast<gl::viewable_image*>(image);
|
||||
|
||||
if (read_only)
|
||||
{
|
||||
managed_texture.reset(image);
|
||||
view.reset(_view);
|
||||
|
||||
managed_texture.reset(vram_texture);
|
||||
aa_mode = rsx::surface_antialiasing::center_1_sample;
|
||||
}
|
||||
else
|
||||
{
|
||||
view.reset();
|
||||
managed_texture.reset();
|
||||
|
||||
if (pbo_id == 0)
|
||||
init_buffer();
|
||||
|
||||
|
|
@ -302,11 +296,10 @@ namespace gl
|
|||
this->depth = depth;
|
||||
this->mipmaps = mipmaps;
|
||||
|
||||
vram_texture = image;
|
||||
set_format(gl_format, gl_type, swap_bytes);
|
||||
}
|
||||
|
||||
void create_read_only(gl::texture* image, gl::texture_view* _view, u32 width, u32 height, u32 depth, u32 mipmaps)
|
||||
void create_read_only(gl::viewable_image* image, u32 width, u32 height, u32 depth, u32 mipmaps)
|
||||
{
|
||||
//Only to be used for ro memory, we dont care about most members, just dimensions and the vram texture handle
|
||||
this->width = width;
|
||||
|
|
@ -315,7 +308,6 @@ namespace gl
|
|||
this->mipmaps = mipmaps;
|
||||
|
||||
managed_texture.reset(image);
|
||||
view.reset(_view);
|
||||
vram_texture = image;
|
||||
|
||||
rsx_pitch = 0;
|
||||
|
|
@ -360,11 +352,6 @@ namespace gl
|
|||
is_depth = is_depth_fmt;
|
||||
}
|
||||
|
||||
void set_source(gl::texture &source)
|
||||
{
|
||||
vram_texture = &source;
|
||||
}
|
||||
|
||||
void copy_texture(bool=false)
|
||||
{
|
||||
if (!pbo_id)
|
||||
|
|
@ -619,7 +606,6 @@ namespace gl
|
|||
{
|
||||
//Read-only texture, destroy texture memory
|
||||
managed_texture.reset();
|
||||
view.reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -648,7 +634,7 @@ namespace gl
|
|||
|
||||
bool is_flushable() const
|
||||
{
|
||||
return (locked && pbo_id != 0);
|
||||
return (protection == utils::protection::no);
|
||||
}
|
||||
|
||||
bool is_flushed() const
|
||||
|
|
@ -671,9 +657,9 @@ namespace gl
|
|||
return vram_texture == 0;
|
||||
}
|
||||
|
||||
gl::texture_view* get_raw_view() const
|
||||
gl::texture_view* get_view(u32 remap_encoding, const std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap)
|
||||
{
|
||||
return view.get();
|
||||
return vram_texture->get_view(remap_encoding, remap);
|
||||
}
|
||||
|
||||
gl::texture* get_raw_texture() const
|
||||
|
|
@ -681,9 +667,9 @@ namespace gl
|
|||
return managed_texture.get();
|
||||
}
|
||||
|
||||
std::unique_ptr<gl::texture_view>& get_view()
|
||||
gl::texture_view* get_raw_view()
|
||||
{
|
||||
return view;
|
||||
return vram_texture->get_view(0xAAE4, rsx::default_remap_vector);
|
||||
}
|
||||
|
||||
bool is_depth_texture() const
|
||||
|
|
@ -732,11 +718,11 @@ namespace gl
|
|||
blitter m_hw_blitter;
|
||||
std::vector<discardable_storage> m_temporary_surfaces;
|
||||
|
||||
cached_texture_section& create_texture(gl::texture* image, gl::texture_view* view, u32 texaddr, u32 texsize, u32 w, u32 h, u32 depth, u32 mipmaps)
|
||||
cached_texture_section& create_texture(gl::viewable_image* image, u32 texaddr, u32 texsize, u32 w, u32 h, u32 depth, u32 mipmaps)
|
||||
{
|
||||
cached_texture_section& tex = find_cached_texture(texaddr, texsize, true, w, h, depth);
|
||||
tex.reset(texaddr, texsize, false);
|
||||
tex.create_read_only(image, view, w, h, depth, mipmaps);
|
||||
tex.create_read_only(image, w, h, depth, mipmaps);
|
||||
read_only_range = tex.get_min_max(read_only_range);
|
||||
return tex;
|
||||
}
|
||||
|
|
@ -962,8 +948,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 texture_channel_remap_t& remap_vector) override
|
||||
rsx::texture_upload_context context, rsx::texture_dimension_extended type, rsx::texture_create_flags flags) override
|
||||
{
|
||||
bool depth_flag = false;
|
||||
switch (gcm_format)
|
||||
|
|
@ -974,18 +959,17 @@ namespace gl
|
|||
break;
|
||||
}
|
||||
|
||||
auto image = gl::create_texture(gcm_format, width, height, depth, mipmaps, type, colorspace);
|
||||
auto swizzle = get_component_mapping(gcm_format, flags);
|
||||
swizzle = gl::apply_swizzle_remap(swizzle, remap_vector);
|
||||
auto view = new gl::texture_view(image, swizzle.data());
|
||||
auto image = gl::create_texture(gcm_format, width, height, depth, mipmaps, type);
|
||||
|
||||
auto& cached = create_texture(image, view, rsx_address, rsx_size, width, height, depth, mipmaps);
|
||||
const auto swizzle = get_component_mapping(gcm_format, flags);
|
||||
image->set_native_component_layout(swizzle);
|
||||
|
||||
auto& cached = create_texture(image, rsx_address, rsx_size, width, height, depth, mipmaps);
|
||||
cached.set_dirty(false);
|
||||
cached.set_depth_flag(depth_flag);
|
||||
cached.set_view_flags(flags);
|
||||
cached.set_context(context);
|
||||
cached.set_gcm_format(gcm_format);
|
||||
cached.set_sampler_status(rsx::texture_sampler_status::status_uninitialized);
|
||||
cached.set_image_type(type);
|
||||
|
||||
if (context != rsx::texture_upload_context::blit_engine_dst)
|
||||
|
|
@ -1034,28 +1018,15 @@ 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 texture_channel_remap_t& remap_vector) override
|
||||
rsx::texture_upload_context context, const std::vector<rsx_subresource_layout>& subresource_layout, rsx::texture_dimension_extended type, bool input_swizzled) override
|
||||
{
|
||||
void* unused = nullptr;
|
||||
auto section = create_new_texture(unused, rsx_address, pitch * height, width, height, depth, mipmaps, gcm_format, context, type,
|
||||
rsx::texture_create_flags::default_component_order, colorspace, remap_vector);
|
||||
|
||||
bool input_swizzled = swizzled;
|
||||
if (context == rsx::texture_upload_context::blit_engine_src)
|
||||
{
|
||||
//Swizzling is ignored for blit engine copy and emulated using remapping
|
||||
input_swizzled = false;
|
||||
section->set_sampler_status(rsx::texture_sampler_status::status_uninitialized);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Generic upload - sampler status will be set on upload
|
||||
section->set_sampler_status(rsx::texture_sampler_status::status_ready);
|
||||
}
|
||||
rsx::texture_create_flags::default_component_order);
|
||||
|
||||
gl::upload_texture(section->get_raw_texture()->id(), rsx_address, gcm_format, width, height, depth, mipmaps,
|
||||
input_swizzled, type, subresource_layout, remap_vector, false, colorspace);
|
||||
input_swizzled, type, subresource_layout);
|
||||
|
||||
return section;
|
||||
}
|
||||
|
||||
|
|
@ -1064,30 +1035,10 @@ namespace gl
|
|||
if (flags == section.get_view_flags())
|
||||
return;
|
||||
|
||||
auto swizzle = get_component_mapping(gcm_format, flags);
|
||||
auto& view = section.get_view();
|
||||
|
||||
if (!view->compare_swizzle(swizzle.data()))
|
||||
{
|
||||
view.reset(new gl::texture_view(view->image(), swizzle.data()));
|
||||
}
|
||||
const auto swizzle = get_component_mapping(gcm_format, flags);
|
||||
section.get_raw_texture()->set_native_component_layout(swizzle);
|
||||
|
||||
section.set_view_flags(flags);
|
||||
section.set_sampler_status(rsx::texture_sampler_status::status_uninitialized);
|
||||
}
|
||||
|
||||
void set_up_remap_vector(cached_texture_section& section, const texture_channel_remap_t& remap_vector) override
|
||||
{
|
||||
auto& view = section.get_view();
|
||||
auto swizzle = view->component_mapping();
|
||||
|
||||
swizzle = apply_swizzle_remap(swizzle, remap_vector);
|
||||
if (!view->compare_swizzle(swizzle.data()))
|
||||
{
|
||||
view.reset(new gl::texture_view(view->image(), swizzle.data()));
|
||||
}
|
||||
|
||||
section.set_sampler_status(rsx::texture_sampler_status::status_ready);
|
||||
}
|
||||
|
||||
void insert_texture_barrier(void*&, gl::texture*) override
|
||||
|
|
|
|||
|
|
@ -671,7 +671,9 @@ namespace vk
|
|||
CHECK_RESULT(vkCreateImageView(m_device, &info, nullptr, &value));
|
||||
}
|
||||
|
||||
image_view(VkDevice dev, vk::image* resource, VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}, VkComponentMapping mapping = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A })
|
||||
image_view(VkDevice dev, vk::image* resource,
|
||||
const VkComponentMapping mapping = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A },
|
||||
const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1})
|
||||
: m_device(dev)
|
||||
{
|
||||
info.format = resource->info.format;
|
||||
|
|
@ -710,6 +712,54 @@ namespace vk
|
|||
VkDevice m_device;
|
||||
};
|
||||
|
||||
struct viewable_image : public image
|
||||
{
|
||||
std::unordered_multimap<u32, std::unique_ptr<vk::image_view>> views;
|
||||
|
||||
viewable_image(vk::render_device &dev,
|
||||
uint32_t memory_type_index,
|
||||
uint32_t access_flags,
|
||||
VkImageType image_type,
|
||||
VkFormat format,
|
||||
uint32_t width, uint32_t height, uint32_t depth,
|
||||
uint32_t mipmaps, uint32_t layers,
|
||||
VkSampleCountFlagBits samples,
|
||||
VkImageLayout initial_layout,
|
||||
VkImageTiling tiling,
|
||||
VkImageUsageFlags usage,
|
||||
VkImageCreateFlags image_flags)
|
||||
|
||||
:image(dev, memory_type_index, access_flags, image_type, format, width, height, depth,
|
||||
mipmaps, layers, samples, initial_layout, tiling, usage, image_flags)
|
||||
{}
|
||||
|
||||
image_view* get_view(u32 remap_encoding, const std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap,
|
||||
VkImageAspectFlags mask = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT)
|
||||
{
|
||||
auto found = views.equal_range(remap_encoding);
|
||||
for (auto It = found.first; It != found.second; ++It)
|
||||
{
|
||||
if (It->second->info.subresourceRange.aspectMask & mask)
|
||||
{
|
||||
return It->second.get();
|
||||
}
|
||||
}
|
||||
|
||||
VkComponentMapping real_mapping = vk::apply_swizzle_remap
|
||||
(
|
||||
{native_component_map.a, native_component_map.r, native_component_map.g, native_component_map.b },
|
||||
remap
|
||||
);
|
||||
|
||||
const auto range = vk::get_image_subresource_range(0, 0, 1, info.mipLevels, get_aspect_flags(info.format) & mask);
|
||||
auto view = std::make_unique<vk::image_view>(*get_current_renderer(), this, real_mapping, range);
|
||||
|
||||
auto result = view.get();
|
||||
views.emplace(remap_encoding, std::move(view));
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
struct buffer
|
||||
{
|
||||
VkBuffer value;
|
||||
|
|
|
|||
|
|
@ -561,7 +561,7 @@ namespace vk
|
|||
vkCmdCopyBufferToImage(cmd, upload_heap.heap->value, tex->value, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
||||
change_image_layout(cmd, tex.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, range);
|
||||
|
||||
auto view = std::make_unique<vk::image_view>(dev, tex.get(), range, mapping);
|
||||
auto view = std::make_unique<vk::image_view>(dev, tex.get(), mapping, range);
|
||||
|
||||
auto result = view.get();
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
namespace vk
|
||||
{
|
||||
struct render_target : public image, public rsx::ref_counted, public rsx::render_target_descriptor<vk::image*>
|
||||
struct render_target : public viewable_image, public rsx::ref_counted, public rsx::render_target_descriptor<vk::image*>
|
||||
{
|
||||
u16 native_pitch = 0;
|
||||
u16 rsx_pitch = 0;
|
||||
|
|
@ -36,36 +36,10 @@ namespace vk
|
|||
VkImageUsageFlags usage,
|
||||
VkImageCreateFlags image_flags)
|
||||
|
||||
:image(dev, memory_type_index, access_flags, image_type, format, width, height, depth,
|
||||
: viewable_image(dev, memory_type_index, access_flags, image_type, format, width, height, depth,
|
||||
mipmaps, layers, samples, initial_layout, tiling, usage, image_flags)
|
||||
{}
|
||||
|
||||
vk::image_view* get_view(u32 remap_encoding, const std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap,
|
||||
VkImageAspectFlags mask = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT)
|
||||
{
|
||||
auto found = views.equal_range(remap_encoding);
|
||||
for (auto It = found.first; It != found.second; ++It)
|
||||
{
|
||||
if (It->second->info.subresourceRange.aspectMask & mask)
|
||||
{
|
||||
return It->second.get();
|
||||
}
|
||||
}
|
||||
|
||||
VkComponentMapping real_mapping = vk::apply_swizzle_remap
|
||||
(
|
||||
{native_component_map.a, native_component_map.r, native_component_map.g, native_component_map.b },
|
||||
remap
|
||||
);
|
||||
|
||||
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 & mask));
|
||||
|
||||
auto result = view.get();
|
||||
views.emplace(remap_encoding, std::move(view));
|
||||
return result;
|
||||
}
|
||||
|
||||
vk::image* get_surface() override
|
||||
{
|
||||
return (vk::image*)this;
|
||||
|
|
|
|||
|
|
@ -15,13 +15,12 @@ namespace vk
|
|||
{
|
||||
class cached_texture_section : public rsx::cached_texture_section
|
||||
{
|
||||
std::unique_ptr<vk::image_view> uploaded_image_view;
|
||||
std::unique_ptr<vk::image> managed_texture = nullptr;
|
||||
std::unique_ptr<vk::viewable_image> managed_texture = nullptr;
|
||||
|
||||
//DMA relevant data
|
||||
VkFence dma_fence = VK_NULL_HANDLE;
|
||||
vk::render_device* m_device = nullptr;
|
||||
vk::image *vram_texture = nullptr;
|
||||
vk::viewable_image *vram_texture = nullptr;
|
||||
std::unique_ptr<vk::buffer> dma_buffer;
|
||||
|
||||
public:
|
||||
|
|
@ -37,7 +36,7 @@ namespace vk
|
|||
rsx::buffered_section::reset(base, length, policy);
|
||||
}
|
||||
|
||||
void create(u16 w, u16 h, u16 depth, u16 mipmaps, vk::image_view *view, vk::image *image, u32 rsx_pitch, bool managed, u32 gcm_format, bool pack_swap_bytes = false)
|
||||
void create(u16 w, u16 h, u16 depth, u16 mipmaps, vk::image *image, u32 rsx_pitch, bool managed, u32 gcm_format, bool pack_swap_bytes = false)
|
||||
{
|
||||
width = w;
|
||||
height = h;
|
||||
|
|
@ -47,17 +46,12 @@ namespace vk
|
|||
this->gcm_format = gcm_format;
|
||||
this->pack_unpack_swap_bytes = pack_swap_bytes;
|
||||
|
||||
vram_texture = static_cast<vk::viewable_image*>(image);
|
||||
|
||||
if (managed)
|
||||
{
|
||||
managed_texture.reset(image);
|
||||
uploaded_image_view.reset(view);
|
||||
managed_texture.reset(vram_texture);
|
||||
}
|
||||
else
|
||||
{
|
||||
verify(HERE), uploaded_image_view.get() == nullptr;
|
||||
}
|
||||
|
||||
vram_texture = image;
|
||||
|
||||
//TODO: Properly compute these values
|
||||
if (rsx_pitch > 0)
|
||||
|
|
@ -97,22 +91,14 @@ namespace vk
|
|||
return (vram_texture != nullptr);
|
||||
}
|
||||
|
||||
std::unique_ptr<vk::image_view>& get_view()
|
||||
vk::image_view* get_view(u32 remap_encoding, const std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap)
|
||||
{
|
||||
return uploaded_image_view;
|
||||
}
|
||||
|
||||
std::unique_ptr<vk::image>& get_texture()
|
||||
{
|
||||
return managed_texture;
|
||||
return vram_texture->get_view(remap_encoding, remap);
|
||||
}
|
||||
|
||||
vk::image_view* get_raw_view()
|
||||
{
|
||||
if (context != rsx::texture_upload_context::framebuffer_storage)
|
||||
return uploaded_image_view.get();
|
||||
else
|
||||
return static_cast<vk::render_target*>(vram_texture)->get_view(0xAAE4, rsx::default_remap_vector);
|
||||
return vram_texture->get_view(0xAAE4, rsx::default_remap_vector);
|
||||
}
|
||||
|
||||
vk::image* get_raw_texture()
|
||||
|
|
@ -120,6 +106,11 @@ namespace vk
|
|||
return managed_texture.get();
|
||||
}
|
||||
|
||||
std::unique_ptr<vk::viewable_image>& get_texture()
|
||||
{
|
||||
return managed_texture;
|
||||
}
|
||||
|
||||
VkFormat get_format()
|
||||
{
|
||||
return vram_texture->info.format;
|
||||
|
|
@ -134,7 +125,7 @@ namespace vk
|
|||
bool is_flushed() const
|
||||
{
|
||||
//This memory section was flushable, but a flush has already removed protection
|
||||
return (protection == utils::protection::rw && uploaded_image_view.get() == nullptr && managed_texture.get() == nullptr);
|
||||
return flushed;
|
||||
}
|
||||
|
||||
void copy_texture(bool manage_cb_lifetime, vk::command_buffer& cmd, VkQueue submit_queue)
|
||||
|
|
@ -374,6 +365,7 @@ namespace vk
|
|||
|
||||
struct discarded_storage
|
||||
{
|
||||
std::unique_ptr<vk::viewable_image> combined_image;
|
||||
std::unique_ptr<vk::image_view> view;
|
||||
std::unique_ptr<vk::image> img;
|
||||
|
||||
|
|
@ -401,8 +393,7 @@ namespace vk
|
|||
|
||||
discarded_storage(cached_texture_section& tex)
|
||||
{
|
||||
view = std::move(tex.get_view());
|
||||
img = std::move(tex.get_texture());
|
||||
combined_image = std::move(tex.get_texture());
|
||||
block_size = tex.get_section_size();
|
||||
}
|
||||
|
||||
|
|
@ -784,8 +775,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 texture_channel_remap_t& remap_vector) override
|
||||
rsx::texture_upload_context context, rsx::texture_dimension_extended type, rsx::texture_create_flags flags) override
|
||||
{
|
||||
const u16 section_depth = depth;
|
||||
const bool is_cubemap = type == rsx::texture_dimension_extended::texture_dimension_cubemap;
|
||||
|
|
@ -842,32 +832,25 @@ namespace vk
|
|||
default:
|
||||
aspect_flags = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
vk_format = get_compatible_sampler_format(m_formats_support, gcm_format);
|
||||
|
||||
if (colorspace != rsx::texture_colorspace::rgb_linear)
|
||||
vk_format = get_compatible_srgb_format(vk_format);
|
||||
break;
|
||||
}
|
||||
|
||||
vk::image *image = new vk::image(*m_device, m_memory_types.device_local, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||
auto *image = new vk::viewable_image(*m_device, m_memory_types.device_local, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||
image_type,
|
||||
vk_format,
|
||||
width, height, depth, mipmaps, layer, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
VK_IMAGE_TILING_OPTIMAL, usage_flags, is_cubemap ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : 0);
|
||||
|
||||
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});
|
||||
image->native_component_map = apply_component_mapping_flags(gcm_format, flags, rsx::default_remap_vector);
|
||||
|
||||
change_image_layout(cmd, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, { aspect_flags, 0, mipmaps, 0, layer });
|
||||
|
||||
cached_texture_section& region = find_cached_texture(rsx_address, rsx_size, true, width, height, section_depth);
|
||||
region.reset(rsx_address, rsx_size);
|
||||
region.create(width, height, section_depth, mipmaps, view, image, 0, true, gcm_format);
|
||||
region.create(width, height, section_depth, mipmaps, image, 0, true, gcm_format);
|
||||
region.set_dirty(false);
|
||||
region.set_context(context);
|
||||
region.set_gcm_format(gcm_format);
|
||||
region.set_sampler_status(rsx::texture_sampler_status::status_uninitialized);
|
||||
region.set_image_type(type);
|
||||
|
||||
//Its not necessary to lock blit dst textures as they are just reused as necessary
|
||||
|
|
@ -889,11 +872,10 @@ 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 texture_channel_remap_t& remap_vector) override
|
||||
rsx::texture_upload_context context, const std::vector<rsx_subresource_layout>& subresource_layout, rsx::texture_dimension_extended type, bool swizzled) 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);
|
||||
rsx::texture_create_flags::default_component_order);
|
||||
|
||||
auto image = section->get_raw_texture();
|
||||
auto subres_range = section->get_raw_view()->info.subresourceRange;
|
||||
|
|
@ -915,12 +897,6 @@ namespace vk
|
|||
{
|
||||
//Swizzling is ignored for blit engine copy and emulated using remapping
|
||||
input_swizzled = false;
|
||||
section->set_sampler_status(rsx::texture_sampler_status::status_uninitialized);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Generic upload - sampler status will be set on upload
|
||||
section->set_sampler_status(rsx::texture_sampler_status::status_ready);
|
||||
}
|
||||
|
||||
vk::copy_mipmaped_image_using_buffer(cmd, image, subresource_layout, gcm_format, input_swizzled, mipmaps, subres_range.aspectMask,
|
||||
|
|
@ -938,45 +914,10 @@ namespace vk
|
|||
if (expected_flags == section.get_view_flags())
|
||||
return;
|
||||
|
||||
vk::image* image = section.get_raw_texture();
|
||||
auto& view = section.get_view();
|
||||
|
||||
VkComponentMapping mapping = apply_component_mapping_flags(gcm_format, expected_flags, rsx::default_remap_vector);
|
||||
|
||||
if (mapping.a != view->info.components.a ||
|
||||
mapping.b != view->info.components.b ||
|
||||
mapping.g != view->info.components.g ||
|
||||
mapping.r != view->info.components.r)
|
||||
{
|
||||
//Replace view map
|
||||
vk::image_view *new_view = new vk::image_view(*m_device, image->value, view->info.viewType, view->info.format,
|
||||
mapping, view->info.subresourceRange);
|
||||
|
||||
view.reset(new_view);
|
||||
}
|
||||
const VkComponentMapping mapping = apply_component_mapping_flags(gcm_format, expected_flags, rsx::default_remap_vector);
|
||||
section.get_raw_texture()->native_component_map = mapping;
|
||||
|
||||
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, 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 = 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 ||
|
||||
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);
|
||||
}
|
||||
|
||||
void insert_texture_barrier(vk::command_buffer& cmd, vk::image* tex) override
|
||||
|
|
|
|||
Loading…
Reference in a new issue