diff --git a/rpcs3/Emu/RSX/Common/texture_cache.h b/rpcs3/Emu/RSX/Common/texture_cache.h index 03ae680224..5297475bdf 100644 --- a/rpcs3/Emu/RSX/Common/texture_cache.h +++ b/rpcs3/Emu/RSX/Common/texture_cache.h @@ -29,6 +29,7 @@ namespace rsx struct sampled_image_descriptor_base { texture_upload_context upload_context = texture_upload_context::shader_read; + rsx::texture_dimension_extended image_type = texture_dimension_extended::texture_dimension_2d; bool is_depth_texture = false; f32 scale_x = 1.f; f32 scale_y = 1.f; @@ -48,6 +49,7 @@ 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; bool matches(const u32 rsx_address, const u32 rsx_size) { @@ -89,6 +91,11 @@ namespace rsx context = upload_context; } + void set_image_type(const rsx::texture_dimension_extended type) + { + image_type = type; + } + u16 get_width() const { return width; @@ -108,6 +115,11 @@ namespace rsx { return context; } + + rsx::texture_dimension_extended get_image_type() const + { + return image_type; + } }; template @@ -192,6 +204,7 @@ namespace rsx std::vector& subresource_layout, const rsx::texture_dimension_extended type, const bool swizzled, std::pair, std::array>& remap_vector) = 0; virtual void enforce_surface_creation_type(section_storage_type& section, const texture_create_flags expected) = 0; virtual void insert_texture_barrier() = 0; + virtual image_view_type generate_cubemap_from_images(commandbuffer_type&, std::array& sources) = 0; constexpr u32 get_block_size() const { return 0x1000000; } inline u32 get_block_address(u32 address) const { return (address & ~0xFFFFFF); } @@ -239,17 +252,18 @@ namespace rsx sampled_image_descriptor() {} - sampled_image_descriptor(image_view_type handle, const texture_upload_context ctx, const bool is_depth, const f32 x_scale, const f32 y_scale) + sampled_image_descriptor(image_view_type handle, const texture_upload_context ctx, const bool is_depth, const f32 x_scale, const f32 y_scale, const rsx::texture_dimension_extended type) { image_handle = handle; upload_context = ctx; is_depth_texture = is_depth; scale_x = x_scale; scale_y = y_scale; + image_type = type; } sampled_image_descriptor(image_resource_type external_handle, u32 gcm_format, u16 x_offset, u16 y_offset, u16 width, u16 height, - const texture_upload_context ctx, const bool is_depth, const f32 x_scale, const f32 y_scale) + const texture_upload_context ctx, const bool is_depth, const f32 x_scale, const f32 y_scale, const rsx::texture_dimension_extended type) { external_subresource_desc = {external_handle, gcm_format, x_offset, y_offset, width, height}; @@ -258,6 +272,7 @@ namespace rsx is_depth_texture = is_depth; scale_x = x_scale; scale_y = y_scale; + image_type = type; } }; @@ -503,7 +518,7 @@ namespace rsx * when sampling with unnormalized coordinates. tcoords passed to rsx will be in rsx dimensions */ template - inline void get_native_dimensions(T &width, T &height, T rsx_pitch, U surface) + inline void get_native_dimensions(T &width, T &height, U surface) { switch (surface->aa_mode) { @@ -521,7 +536,7 @@ namespace rsx } template - inline void get_rsx_dimensions(T &width, T &height, T rsx_pitch, U surface) + inline void get_rsx_dimensions(T &width, T &height, U surface) { switch (surface->aa_mode) { @@ -711,6 +726,7 @@ namespace rsx region.protect(utils::protection::no); region.create(width, height, 1, 1, nullptr, image, pitch, false, std::forward(extras)...); region.set_context(texture_upload_context::framebuffer_storage); + region.set_image_type(rsx::texture_dimension_extended::texture_dimension_2d); update_cache_tag(); } @@ -970,6 +986,107 @@ namespace rsx m_unreleased_texture_objects = 0; } + template + sampled_image_descriptor process_framebuffer_resource(render_target_type texptr, const u32 texaddr, const u32 format, surface_store_type& m_rtts, + const u16 tex_width, const u16 tex_height, const rsx::texture_dimension_extended extended_dimension, const bool is_depth) + { + if (extended_dimension != rsx::texture_dimension_extended::texture_dimension_2d && + extended_dimension != rsx::texture_dimension_extended::texture_dimension_1d) + { + LOG_ERROR(RSX, "Texture resides in render target memory, but requested type is not 2D (%d)", (u32)extended_dimension); + } + + const auto surface_width = texptr->get_surface_width(); + const auto surface_height = texptr->get_surface_height(); + + u32 internal_width = tex_width; + u32 internal_height = tex_height; + get_native_dimensions(internal_width, internal_height, texptr); + + if (internal_width > surface_width || internal_height > surface_height) + { + //An AA flag is likely missing + //HACK + auto aa_mode = texptr->aa_mode; + if ((internal_width >> 1) == surface_width) + { + if (internal_height > surface_height) + texptr->aa_mode = rsx::surface_antialiasing::square_centered_4_samples; + else + texptr->aa_mode = rsx::surface_antialiasing::diagonal_centered_2_samples; + + internal_width = tex_width; + internal_height = tex_height; + get_native_dimensions(internal_width, internal_height, texptr); + } + + internal_width = std::min(internal_width, (u32)surface_width); + internal_height = std::min(internal_height, (u32)surface_height); + texptr->aa_mode = aa_mode; + } + + f32 scale_x = get_internal_scaling_x(texptr); + f32 scale_y = get_internal_scaling_y(texptr); + + if (extended_dimension == rsx::texture_dimension_extended::texture_dimension_1d) + { + internal_height = 1; + scale_y = 0.f; + } + + bool requires_processing = surface_width != internal_width || surface_height != internal_height; + if (!requires_processing) + { + if (!is_depth) + { + for (const auto& tex : m_rtts.m_bound_render_targets) + { + if (std::get<0>(tex) == texaddr) + { + if (g_cfg.video.strict_rendering_mode) + { + LOG_WARNING(RSX, "Attempting to sample a currently bound render target @ 0x%x", texaddr); + requires_processing = true; + break; + } + else + { + //issue a texture barrier to ensure previous writes are visible + insert_texture_barrier(); + break; + } + } + } + } + else + { + if (texaddr == std::get<0>(m_rtts.m_bound_depth_stencil)) + { + if (g_cfg.video.strict_rendering_mode) + { + LOG_WARNING(RSX, "Attempting to sample a currently bound depth surface @ 0x%x", texaddr); + requires_processing = true; + } + else + { + //issue a texture barrier to ensure previous writes are visible + insert_texture_barrier(); + } + } + } + } + + if (requires_processing) + { + const auto w = rsx::apply_resolution_scale(internal_width, true); + const auto h = rsx::apply_resolution_scale(internal_height, true); + return{ texptr->get_surface(), format, 0, 0, w, h, texture_upload_context::framebuffer_storage, + is_depth, scale_x, scale_y, rsx::texture_dimension_extended::texture_dimension_2d }; + } + + return{ texptr->get_view(), texture_upload_context::framebuffer_storage, is_depth, scale_x, scale_y, rsx::texture_dimension_extended::texture_dimension_2d }; + } + template sampled_image_descriptor upload_texture(commandbuffer_type& cmd, RsxTextureType& tex, surface_store_type& m_rtts, Args&&... extras) { @@ -990,158 +1107,6 @@ namespace rsx u16 tex_pitch = tex.pitch(); const u16 tex_width = tex.width(); - if (!is_compressed_format) - { - //Check for sampleable rtts from previous render passes - //TODO: When framebuffer Y compression is properly handled, this section can be removed. A more accurate framebuffer storage check exists below this block - if (auto texptr = m_rtts.get_texture_from_render_target_if_applicable(texaddr)) - { - if (test_framebuffer(texaddr)) - { - if (extended_dimension != rsx::texture_dimension_extended::texture_dimension_2d) - LOG_ERROR(RSX, "Texture resides in render target memory, but requested type is not 2D (%d)", (u32)extended_dimension); - - const auto surface_width = texptr->get_surface_width(); - const auto surface_height = texptr->get_surface_height(); - - u32 internal_width = tex_width; - u32 internal_height = tex_height; - get_native_dimensions(internal_width, internal_height, (u32)tex_pitch, texptr); - - if (internal_width > surface_width || internal_height > surface_height) - { - //An AA flag is likely missing - //HACK - auto aa_mode = texptr->aa_mode; - if ((internal_width >> 1) == surface_width) - { - if (internal_height > surface_height) - texptr->aa_mode = rsx::surface_antialiasing::square_centered_4_samples; - else - texptr->aa_mode = rsx::surface_antialiasing::diagonal_centered_2_samples; - - internal_width = tex_width; - internal_height = tex_height; - get_native_dimensions(internal_width, internal_height, (u32)tex_pitch, texptr); - } - - internal_width = std::min(internal_width, (u32)surface_width); - internal_height = std::min(internal_height, (u32)surface_height); - texptr->aa_mode = aa_mode; - } - - bool requires_processing = surface_width != internal_width || surface_height != internal_height; - if (!requires_processing) - { - for (const auto& tex : m_rtts.m_bound_render_targets) - { - if (std::get<0>(tex) == texaddr) - { - if (g_cfg.video.strict_rendering_mode) - { - LOG_WARNING(RSX, "Attempting to sample a currently bound render target @ 0x%x", texaddr); - requires_processing = true; - break; - } - else - { - //issue a texture barrier to ensure previous writes are visible - insert_texture_barrier(); - break; - } - } - } - } - - if (requires_processing) - { - const auto w = rsx::apply_resolution_scale(internal_width, true); - const auto h = rsx::apply_resolution_scale(internal_height, true); - return{ texptr->get_surface(), format, 0, 0, w, h, texture_upload_context::framebuffer_storage, - false, get_internal_scaling_x(texptr), get_internal_scaling_y(texptr) }; - } - - return{ texptr->get_view(), texture_upload_context::framebuffer_storage, false, get_internal_scaling_x(texptr), get_internal_scaling_y(texptr) }; - } - else - { - m_rtts.invalidate_surface_address(texaddr, false); - invalidate_address(texaddr, false, true, std::forward(extras)...); - } - } - - if (auto texptr = m_rtts.get_texture_from_depth_stencil_if_applicable(texaddr)) - { - if (test_framebuffer(texaddr)) - { - if (extended_dimension != rsx::texture_dimension_extended::texture_dimension_2d) - LOG_ERROR(RSX, "Texture resides in depth buffer memory, but requested type is not 2D (%d)", (u32)extended_dimension); - - const auto surface_width = texptr->get_surface_width(); - const auto surface_height = texptr->get_surface_height(); - - u32 internal_width = tex_width; - u32 internal_height = tex_height; - get_native_dimensions(internal_width, internal_height, (u32)tex_pitch, texptr); - - if (internal_width > surface_width || internal_height > surface_height) - { - //An AA flag is likely missing - //HACK - auto aa_mode = texptr->aa_mode; - if ((internal_width >> 1) == surface_width) - { - if (internal_height > surface_height) - texptr->aa_mode = rsx::surface_antialiasing::square_centered_4_samples; - else - texptr->aa_mode = rsx::surface_antialiasing::diagonal_centered_2_samples; - - internal_width = tex_width; - internal_height = tex_height; - get_native_dimensions(internal_width, internal_height, (u32)tex_pitch, texptr); - } - - internal_width = std::min(internal_width, (u32)surface_width); - internal_height = std::min(internal_height, (u32)surface_height); - texptr->aa_mode = aa_mode; - } - - bool requires_processing = surface_width != internal_width || surface_height != internal_height; - if (!requires_processing && texaddr == std::get<0>(m_rtts.m_bound_depth_stencil)) - { - if (g_cfg.video.strict_rendering_mode) - { - LOG_WARNING(RSX, "Attempting to sample a currently bound depth surface @ 0x%x", texaddr); - requires_processing = true; - } - else - { - //issue a texture barrier to ensure previous writes are visible - insert_texture_barrier(); - } - } - - if (requires_processing) - { - const auto w = rsx::apply_resolution_scale(internal_width, true); - const auto h = rsx::apply_resolution_scale(internal_height, true); - return{ texptr->get_surface(), format, 0, 0, w, h, texture_upload_context::framebuffer_storage, - true, get_internal_scaling_x(texptr), get_internal_scaling_y(texptr) }; - } - - return{ texptr->get_view(), texture_upload_context::framebuffer_storage, true, get_internal_scaling_x(texptr), get_internal_scaling_y(texptr) }; - } - else - { - m_rtts.invalidate_surface_address(texaddr, true); - invalidate_address(texaddr, false, true, std::forward(extras)...); - } - } - } - - tex_pitch = is_compressed_format? (tex_size / tex_height) : tex_pitch; //NOTE: Compressed textures dont have a real pitch (tex_size = (w*h)/6) - if (tex_pitch == 0) tex_pitch = tex_width * get_format_block_size_in_bytes(format); - switch (extended_dimension) { case rsx::texture_dimension_extended::texture_dimension_1d: @@ -1159,6 +1124,40 @@ namespace rsx break; } + if (!is_compressed_format) + { + //Check for sampleable rtts from previous render passes + //TODO: When framebuffer Y compression is properly handled, this section can be removed. A more accurate framebuffer storage check exists below this block + if (auto texptr = m_rtts.get_texture_from_render_target_if_applicable(texaddr)) + { + if (test_framebuffer(texaddr)) + { + return process_framebuffer_resource(texptr, texaddr, format, m_rtts, tex_width, tex_height, extended_dimension, false); + } + else + { + m_rtts.invalidate_surface_address(texaddr, false); + invalidate_address(texaddr, false, true, std::forward(extras)...); + } + } + + if (auto texptr = m_rtts.get_texture_from_depth_stencil_if_applicable(texaddr)) + { + if (test_framebuffer(texaddr)) + { + return process_framebuffer_resource(texptr, texaddr, format, m_rtts, tex_width, tex_height, extended_dimension, true); + } + else + { + m_rtts.invalidate_surface_address(texaddr, true); + invalidate_address(texaddr, false, true, std::forward(extras)...); + } + } + } + + tex_pitch = is_compressed_format? (tex_size / tex_height) : tex_pitch; //NOTE: Compressed textures dont have a real pitch (tex_size = (w*h)/6) + if (tex_pitch == 0) tex_pitch = tex_width * get_format_block_size_in_bytes(format); + if (!is_compressed_format) { /* Check if we are re-sampling a subresource of an RTV/DSV texture, bound or otherwise @@ -1178,13 +1177,24 @@ namespace rsx m_rtts.invalidate_surface_address(rsc.base_address, rsc.is_depth_surface); invalidate_address(rsc.base_address, false, true, std::forward(extras)...); } - else if (extended_dimension != rsx::texture_dimension_extended::texture_dimension_2d) + else if (extended_dimension != rsx::texture_dimension_extended::texture_dimension_2d && + extended_dimension != rsx::texture_dimension_extended::texture_dimension_1d) { LOG_ERROR(RSX, "Sampling of RTT region as non-2D texture! addr=0x%x, Type=%d, dims=%dx%d", texaddr, (u8)tex.get_extended_texture_dimension(), tex.width(), tex.height()); } else { + f32 scale_x = get_internal_scaling_x(rsc.surface); + f32 scale_y = get_internal_scaling_x(rsc.surface); + u16 internal_height = rsx::apply_resolution_scale(rsc.h, true); + + if (extended_dimension == rsx::texture_dimension_extended::texture_dimension_1d) + { + internal_height = 1; + scale_y = 0.f; + } + if (!rsc.is_bound || !g_cfg.video.strict_rendering_mode) { if (rsc.w == tex_width && rsc.h == tex_height) @@ -1195,19 +1205,18 @@ namespace rsx insert_texture_barrier(); } - return{ rsc.surface->get_view(), texture_upload_context::framebuffer_storage, rsc.is_depth_surface, get_internal_scaling_x(rsc.surface), get_internal_scaling_y(rsc.surface) }; + return{ rsc.surface->get_view(), texture_upload_context::framebuffer_storage, rsc.is_depth_surface, + scale_x, scale_y, rsx::texture_dimension_extended::texture_dimension_2d }; } - else return{ rsc.surface->get_surface(), format, rsx::apply_resolution_scale(rsc.x, false), rsx::apply_resolution_scale(rsc.y, false), - rsx::apply_resolution_scale(rsc.w, true), rsx::apply_resolution_scale(rsc.h, true), texture_upload_context::framebuffer_storage, - rsc.is_depth_surface, get_internal_scaling_x(rsc.surface), get_internal_scaling_y(rsc.surface) }; } else { LOG_WARNING(RSX, "Attempting to sample a currently bound render target @ 0x%x", texaddr); - return{ rsc.surface->get_surface(), format, rsx::apply_resolution_scale(rsc.x, false), rsx::apply_resolution_scale(rsc.y, false), - rsx::apply_resolution_scale(rsc.w, true), rsx::apply_resolution_scale(rsc.h, true), texture_upload_context::framebuffer_storage, - rsc.is_depth_surface, get_internal_scaling_x(rsc.surface), get_internal_scaling_y(rsc.surface) }; } + + return{ rsc.surface->get_surface(), format, rsx::apply_resolution_scale(rsc.x, false), rsx::apply_resolution_scale(rsc.y, false), + rsx::apply_resolution_scale(rsc.w, true), internal_height, texture_upload_context::framebuffer_storage, + rsc.is_depth_surface, scale_x, scale_y, rsx::texture_dimension_extended::texture_dimension_2d }; } } } @@ -1219,7 +1228,12 @@ namespace rsx auto cached_texture = find_texture_from_dimensions(texaddr, tex_width, tex_height, depth); if (cached_texture) { - return{ cached_texture->get_raw_view(), cached_texture->get_context(), cached_texture->is_depth_texture(), 1.f, 1.f }; + f32 scale_y = 1.f; + if (extended_dimension == rsx::texture_dimension_extended::texture_dimension_1d || + cached_texture->get_image_type() == rsx::texture_dimension_extended::texture_dimension_1d) + scale_y = 0.f; + + return{ cached_texture->get_raw_view(), cached_texture->get_context(), cached_texture->is_depth_texture(), 1.f, scale_y, cached_texture->get_image_type() }; } if ((!blit_engine_incompatibility_warning_raised && g_cfg.video.use_gpu_texture_scaling) || is_hw_blit_engine_compatible(format)) @@ -1246,7 +1260,8 @@ namespace rsx if ((offset_x + tex_width) <= surface->get_width() && (offset_y + tex_height) <= surface->get_height()) { - if (extended_dimension != rsx::texture_dimension_extended::texture_dimension_2d) + if (extended_dimension != rsx::texture_dimension_extended::texture_dimension_2d && + extended_dimension != rsx::texture_dimension_extended::texture_dimension_1d) { LOG_ERROR(RSX, "Texture resides in blit engine memory, but requested type is not 2D (%d)", (u32)extended_dimension); break; @@ -1261,7 +1276,9 @@ namespace rsx } auto src_image = surface->get_raw_texture(); - return{ src_image, format, offset_x, offset_y, tex_width, tex_height, texture_upload_context::blit_engine_dst, surface->is_depth_texture(), 1.f, 1.f }; + f32 scale_y = (extended_dimension == rsx::texture_dimension_extended::texture_dimension_1d) ? 0.f : 1.f; + return{ src_image, format, offset_x, offset_y, tex_width, tex_height, texture_upload_context::blit_engine_dst, + surface->is_depth_texture(), 1.f, scale_y, rsx::texture_dimension_extended::texture_dimension_2d }; } } } @@ -1281,7 +1298,7 @@ namespace rsx 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, is_swizzled, remap_vector)->get_raw_view(), - texture_upload_context::shader_read, false, 1.f, 1.f }; + texture_upload_context::shader_read, false, 1.f, 1.f, extended_dimension }; } template diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index 682da0ba7d..b9e5be8c99 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -179,21 +179,9 @@ void GLGSRender::begin() namespace { - GLenum get_gl_target_for_texture(const rsx::fragment_texture& tex) + GLenum get_gl_target_for_texture(const rsx::texture_dimension_extended type) { - switch (tex.get_extended_texture_dimension()) - { - case rsx::texture_dimension_extended::texture_dimension_1d: return GL_TEXTURE_1D; - case rsx::texture_dimension_extended::texture_dimension_2d: return GL_TEXTURE_2D; - case rsx::texture_dimension_extended::texture_dimension_cubemap: return GL_TEXTURE_CUBE_MAP; - case rsx::texture_dimension_extended::texture_dimension_3d: return GL_TEXTURE_3D; - } - fmt::throw_exception("Unknown texture target" HERE); - } - - GLenum get_gl_target_for_texture(const rsx::vertex_texture& tex) - { - switch (tex.get_extended_texture_dimension()) + switch (type) { case rsx::texture_dimension_extended::texture_dimension_1d: return GL_TEXTURE_1D; case rsx::texture_dimension_extended::texture_dimension_2d: return GL_TEXTURE_2D; @@ -339,7 +327,7 @@ void GLGSRender::end() if (tex.enabled()) { - GLenum target = get_gl_target_for_texture(tex); + GLenum target = get_gl_target_for_texture(sampler_state->image_type); if (sampler_state->image_handle) { glBindTexture(target, sampler_state->image_handle); @@ -959,6 +947,12 @@ void GLGSRender::load_program(u32 vertex_base, u32 vertex_count) vertex_program.skip_vertex_input_check = true; //not needed for us since decoding is done server side void* pipeline_properties = nullptr; + m_program = &m_prog_buffer.getGraphicPipelineState(vertex_program, fragment_program, pipeline_properties); + m_program->use(); + + if (m_prog_buffer.check_cache_missed()) + m_shaders_cache->store(pipeline_properties, vertex_program, fragment_program); + u8 *buf; u32 vertex_state_offset; u32 vertex_constants_offset; @@ -1017,13 +1011,6 @@ void GLGSRender::load_program(u32 vertex_base, u32 vertex_count) } m_transform_constants_dirty = false; - - //Search/compile program after transfer operations - m_program = &m_prog_buffer.getGraphicPipelineState(vertex_program, fragment_program, pipeline_properties); - m_program->use(); - - if (m_prog_buffer.check_cache_missed()) - m_shaders_cache->store(pipeline_properties, vertex_program, fragment_program); } void GLGSRender::update_draw_state() diff --git a/rpcs3/Emu/RSX/GL/GLTextureCache.h b/rpcs3/Emu/RSX/GL/GLTextureCache.h index 2cc38c58c3..93413355df 100644 --- a/rpcs3/Emu/RSX/GL/GLTextureCache.h +++ b/rpcs3/Emu/RSX/GL/GLTextureCache.h @@ -571,7 +571,7 @@ namespace gl m_temporary_surfaces.resize(0); } - u32 create_temporary_subresource(u32 src_id, GLenum sized_internal_fmt, u16 x, u16 y, u16 width, u16 height) + u32 create_temporary_subresource_impl(u32 src_id, GLenum sized_internal_fmt, const GLenum dst_type, u16 x, u16 y, u16 width, u16 height) { u32 dst_id = 0; @@ -589,19 +589,23 @@ namespace gl } glGenTextures(1, &dst_id); - glBindTexture(GL_TEXTURE_2D, dst_id); + glBindTexture(dst_type, dst_id); - glTexStorage2D(GL_TEXTURE_2D, 1, sized_internal_fmt, width, height); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); + if (dst_type == GL_TEXTURE_2D) + glTexStorage2D(GL_TEXTURE_2D, 1, sized_internal_fmt, width, height); + else if (dst_type == GL_TEXTURE_1D) + glTexStorage1D(GL_TEXTURE_1D, 1, sized_internal_fmt, width); + + glTexParameteri(dst_type, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(dst_type, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(dst_type, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(dst_type, GL_TEXTURE_MAX_LEVEL, 0); //Empty GL_ERROR glGetError(); glCopyImageSubData(src_id, GL_TEXTURE_2D, 0, x, y, 0, - dst_id, GL_TEXTURE_2D, 0, 0, 0, 0, width, height, 1); + dst_id, dst_type, 0, 0, 0, 0, width, height, 1); m_temporary_surfaces.push_back(dst_id); @@ -625,22 +629,27 @@ namespace gl u32 create_temporary_subresource_view(void*&, u32* src, u32 gcm_format, u16 x, u16 y, u16 w, u16 h) override { const GLenum ifmt = gl::get_sized_internal_format(gcm_format); - return create_temporary_subresource(*src, ifmt, x, y, w, h); + return create_temporary_subresource_impl(*src, ifmt, GL_TEXTURE_2D, x, y, w, h); } u32 create_temporary_subresource_view(void*&, gl::texture* src, u32 gcm_format, u16 x, u16 y, u16 w, u16 h) override { if (auto as_rtt = dynamic_cast(src)) { - return create_temporary_subresource(src->id(), (GLenum)as_rtt->get_compatible_internal_format(), x, y, w, h); + return create_temporary_subresource_impl(src->id(), (GLenum)as_rtt->get_compatible_internal_format(), GL_TEXTURE_2D, x, y, w, h); } else { const GLenum ifmt = gl::get_sized_internal_format(gcm_format); - return create_temporary_subresource(src->id(), ifmt, x, y, w, h); + return create_temporary_subresource_impl(src->id(), ifmt, GL_TEXTURE_2D, x, y, w, h); } } + u32 generate_cubemap_from_images(void*&, std::array& sources) override + { + return 0; + } + cached_texture_section* create_new_texture(void*&, u32 rsx_address, u32 rsx_size, u16 width, u16 height, u16 depth, u16 mipmaps, const u32 gcm_format, const rsx::texture_upload_context context, const rsx::texture_dimension_extended type, const rsx::texture_create_flags flags, std::pair, std::array>& /*remap_vector*/) override @@ -670,6 +679,7 @@ namespace gl cached.set_depth_flag(depth_flag); cached.set_view_flags(flags); cached.set_context(context); + cached.set_image_type(type); //Its not necessary to lock blit dst textures as they are just reused as necessary if (context != rsx::texture_upload_context::blit_engine_dst || g_cfg.video.strict_rendering_mode) diff --git a/rpcs3/Emu/RSX/RSXFragmentProgram.h b/rpcs3/Emu/RSX/RSXFragmentProgram.h index 645aa0446c..d6be3ece46 100644 --- a/rpcs3/Emu/RSX/RSXFragmentProgram.h +++ b/rpcs3/Emu/RSX/RSXFragmentProgram.h @@ -243,13 +243,10 @@ struct RSXFragmentProgram void set_texture_dimension(const std::array &dimensions) { - size_t id = 0; - for (const rsx::texture_dimension_extended &dim : dimensions) + texture_dimensions = 0; + for (u32 i = 0, offset = 0; i < 16; ++i, offset += 2) { - texture_dimensions &= ~(0x3 << (id * 2)); - u8 d = (u8)dim; - texture_dimensions |= ((d & 0x3) << (id * 2)); - id++; + texture_dimensions |= (u32)dimensions[i] << offset; } } diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 8d31730db4..df79b9a547 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -1364,7 +1364,7 @@ namespace rsx } else { - texture_dimensions[i] = tex.get_extended_texture_dimension(); + texture_dimensions[i] = sampler_descriptors[i]->image_type; if (tex.alpha_kill_enabled()) { @@ -1383,13 +1383,16 @@ namespace rsx if (raw_format & CELL_GCM_TEXTURE_UN) result.unnormalized_coords |= (1 << i); - if (sampler_descriptors[i]->upload_context == rsx::texture_upload_context::framebuffer_storage) + if (sampler_descriptors[i]->upload_context == rsx::texture_upload_context::framebuffer_storage && + raw_format & CELL_GCM_TEXTURE_UN) { - if (raw_format & CELL_GCM_TEXTURE_UN) - { - result.texture_scale[i][0] = (resolution_scale * sampler_descriptors[i]->scale_x); - result.texture_scale[i][1] = (resolution_scale * sampler_descriptors[i]->scale_y); - } + result.texture_scale[i][0] = (resolution_scale * sampler_descriptors[i]->scale_x); + result.texture_scale[i][1] = (resolution_scale * sampler_descriptors[i]->scale_y); + } + else + { + result.texture_scale[i][0] = sampler_descriptors[i]->scale_x; + result.texture_scale[i][1] = sampler_descriptors[i]->scale_y; } if (sampler_descriptors[i]->is_depth_texture) diff --git a/rpcs3/Emu/RSX/VK/VKTextureCache.h b/rpcs3/Emu/RSX/VK/VKTextureCache.h index 3a02280af8..079d66ac46 100644 --- a/rpcs3/Emu/RSX/VK/VKTextureCache.h +++ b/rpcs3/Emu/RSX/VK/VKTextureCache.h @@ -448,7 +448,7 @@ namespace vk tex.destroy(); } - vk::image_view* create_temporary_subresource_view(vk::command_buffer& cmd, vk::image* source, u32 /*gcm_format*/, u16 x, u16 y, u16 w, u16 h) override + vk::image_view* create_temporary_subresource_view_impl(vk::command_buffer& cmd, vk::image* source, VkImageType image_type, VkImageViewType view_type, u16 x, u16 y, u16 w, u16 h) { VkImageAspectFlags aspect = VK_IMAGE_ASPECT_COLOR_BIT; @@ -469,13 +469,13 @@ namespace vk std::unique_ptr view; image.reset(new vk::image(*vk::get_current_renderer(), m_memory_types.device_local, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, - source->info.imageType, + image_type, source->info.format, w, h, 1, 1, 1, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, source->info.flags)); VkImageSubresourceRange view_range = { aspect & ~(VK_IMAGE_ASPECT_STENCIL_BIT), 0, 1, 0, 1 }; - view.reset(new vk::image_view(*vk::get_current_renderer(), image->value, VK_IMAGE_VIEW_TYPE_2D, source->info.format, source->native_component_map, view_range)); + view.reset(new vk::image_view(*vk::get_current_renderer(), image->value, view_type, source->info.format, source->native_component_map, view_range)); VkImageLayout old_src_layout = source->current_layout; @@ -501,11 +501,21 @@ namespace vk return m_discardable_storage.back().view.get(); } + vk::image_view* create_temporary_subresource_view(vk::command_buffer& cmd, vk::image* source, u32 /*gcm_format*/, u16 x, u16 y, u16 w, u16 h) override + { + return create_temporary_subresource_view_impl(cmd, source, source->info.imageType, VK_IMAGE_VIEW_TYPE_2D, x, y, w, h); + } + vk::image_view* create_temporary_subresource_view(vk::command_buffer& cmd, vk::image** source, u32 gcm_format, u16 x, u16 y, u16 w, u16 h) override { return create_temporary_subresource_view(cmd, *source, gcm_format, x, y, w, h); } + vk::image_view* generate_cubemap_from_images(vk::command_buffer&, std::array& sources) override + { + return nullptr; + } + cached_texture_section* create_new_texture(vk::command_buffer& cmd, u32 rsx_address, u32 rsx_size, u16 width, u16 height, u16 depth, u16 mipmaps, const u32 gcm_format, const rsx::texture_upload_context context, const rsx::texture_dimension_extended type, const rsx::texture_create_flags flags, std::pair, std::array>& remap_vector) override @@ -618,6 +628,7 @@ namespace vk region.create(width, height, section_depth, mipmaps, view, image); region.set_dirty(false); region.set_context(context); + region.set_image_type(type); //Its not necessary to lock blit dst textures as they are just reused as necessary if (context != rsx::texture_upload_context::blit_engine_dst || g_cfg.video.strict_rendering_mode)