diff --git a/rpcs3/Emu/RSX/Common/texture_cache.h b/rpcs3/Emu/RSX/Common/texture_cache.h index 5462856be3..8bb6f4bdf6 100644 --- a/rpcs3/Emu/RSX/Common/texture_cache.h +++ b/rpcs3/Emu/RSX/Common/texture_cache.h @@ -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& subresource_layout, rsx::texture_dimension_extended type, rsx::texture_colorspace colorspace, bool swizzled, const texture_channel_remap_t& remap_vector) = 0; + const std::vector& 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& 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& 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(extras)...); + region.create(width, height, 1, 1, image, pitch, false, std::forward(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; diff --git a/rpcs3/Emu/RSX/GL/GLHelpers.h b/rpcs3/Emu/RSX/GL/GLHelpers.h index 9d0b52aba8..81ff25f487 100644 --- a/rpcs3/Emu/RSX/GL/GLHelpers.h +++ b/rpcs3/Emu/RSX/GL/GLHelpers.h @@ -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 apply_swizzle_remap(const std::array& swizzle_remap, const std::pair, std::array>& decoded_remap); + class exception : public std::exception { protected: @@ -1889,6 +1892,28 @@ namespace gl } }; + class viewable_image : public texture + { + std::unordered_map> views; + +public: + using texture::texture; + texture_view* get_view(u32 remap_encoding, const std::pair, std::array>& 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(this, mapping.data()); + auto result = view.get(); + views[remap_encoding] = std::move(view); + return result; + } + }; + class rbo { GLuint m_id = 0; diff --git a/rpcs3/Emu/RSX/GL/GLRenderTargets.h b/rpcs3/Emu/RSX/GL/GLRenderTargets.h index d8bde35c3d..ddde8116bb 100644 --- a/rpcs3/Emu/RSX/GL/GLRenderTargets.h +++ b/rpcs3/Emu/RSX/GL/GLRenderTargets.h @@ -49,7 +49,7 @@ namespace rsx namespace gl { - class render_target : public texture, public rsx::ref_counted, public rsx::render_target_descriptor + class render_target : public viewable_image, public rsx::ref_counted, public rsx::render_target_descriptor { 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> 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>& 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(this, mapping.data()); - auto result = view.get(); - views[remap_encoding] = std::move(view); - return result; - } - u32 raw_handle() const { return id(); diff --git a/rpcs3/Emu/RSX/GL/GLTexture.cpp b/rpcs3/Emu/RSX/GL/GLTexture.cpp index d3446636fc..83ffc907aa 100644 --- a/rpcs3/Emu/RSX/GL/GLTexture.cpp +++ b/rpcs3/Emu/RSX/GL/GLTexture.cpp @@ -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& subresources_layout, const std::pair, std::array>& decoded_remap, bool static_state, - rsx::texture_colorspace colorspace) + const std::vector& 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); } diff --git a/rpcs3/Emu/RSX/GL/GLTexture.h b/rpcs3/Emu/RSX/GL/GLTexture.h index cbdb656b90..3f66bfcdfd 100644 --- a/rpcs3/Emu/RSX/GL/GLTexture.h +++ b/rpcs3/Emu/RSX/GL/GLTexture.h @@ -19,7 +19,7 @@ namespace gl float max_aniso(rsx::texture_max_anisotropy aniso); std::array 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& subresources_layout, const std::pair, std::array>& decoded_remap, bool static_state, - rsx::texture_colorspace colorspace); + const std::vector& subresources_layout); std::array apply_swizzle_remap(const std::array& swizzle_remap, const std::pair, std::array>& decoded_remap); diff --git a/rpcs3/Emu/RSX/GL/GLTextureCache.h b/rpcs3/Emu/RSX/GL/GLTextureCache.h index e734352518..4d7b032259 100644 --- a/rpcs3/Emu/RSX/GL/GLTextureCache.h +++ b/rpcs3/Emu/RSX/GL/GLTextureCache.h @@ -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 view; - std::unique_ptr managed_texture; + std::unique_ptr managed_texture; std::unique_ptr 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(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>& 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& 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 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& 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& 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 diff --git a/rpcs3/Emu/RSX/VK/VKHelpers.h b/rpcs3/Emu/RSX/VK/VKHelpers.h index ead4133d8d..166652d3d3 100644 --- a/rpcs3/Emu/RSX/VK/VKHelpers.h +++ b/rpcs3/Emu/RSX/VK/VKHelpers.h @@ -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> 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>& 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(*get_current_renderer(), this, real_mapping, range); + + auto result = view.get(); + views.emplace(remap_encoding, std::move(view)); + return result; + } + }; + struct buffer { VkBuffer value; diff --git a/rpcs3/Emu/RSX/VK/VKOverlays.h b/rpcs3/Emu/RSX/VK/VKOverlays.h index 80f5f2236a..a99dd31f30 100644 --- a/rpcs3/Emu/RSX/VK/VKOverlays.h +++ b/rpcs3/Emu/RSX/VK/VKOverlays.h @@ -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(dev, tex.get(), range, mapping); + auto view = std::make_unique(dev, tex.get(), mapping, range); auto result = view.get(); diff --git a/rpcs3/Emu/RSX/VK/VKRenderTargets.h b/rpcs3/Emu/RSX/VK/VKRenderTargets.h index 9547902903..0cd4c3eb4f 100644 --- a/rpcs3/Emu/RSX/VK/VKRenderTargets.h +++ b/rpcs3/Emu/RSX/VK/VKRenderTargets.h @@ -10,7 +10,7 @@ namespace vk { - struct render_target : public image, public rsx::ref_counted, public rsx::render_target_descriptor + struct render_target : public viewable_image, public rsx::ref_counted, public rsx::render_target_descriptor { 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>& 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::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; diff --git a/rpcs3/Emu/RSX/VK/VKTextureCache.h b/rpcs3/Emu/RSX/VK/VKTextureCache.h index ef7ec7b571..f046ff3eec 100644 --- a/rpcs3/Emu/RSX/VK/VKTextureCache.h +++ b/rpcs3/Emu/RSX/VK/VKTextureCache.h @@ -15,13 +15,12 @@ namespace vk { class cached_texture_section : public rsx::cached_texture_section { - std::unique_ptr uploaded_image_view; - std::unique_ptr managed_texture = nullptr; + std::unique_ptr 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 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(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& get_view() + vk::image_view* get_view(u32 remap_encoding, const std::pair, std::array>& remap) { - return uploaded_image_view; - } - - std::unique_ptr& 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(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& 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 combined_image; std::unique_ptr view; std::unique_ptr 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& 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& 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 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