rsx: Reimplement cached textures and their views

This commit is contained in:
kd-11 2018-07-17 19:42:51 +03:00 committed by kd-11
parent 8b693ed7bb
commit 8695f95267
10 changed files with 146 additions and 265 deletions

View file

@ -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;

View file

@ -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;

View file

@ -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();

View file

@ -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);
}

View file

@ -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);

View file

@ -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

View file

@ -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;

View file

@ -561,7 +561,7 @@ namespace vk
vkCmdCopyBufferToImage(cmd, upload_heap.heap->value, tex->value, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
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();

View file

@ -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;

View file

@ -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