rsx: Implement 1D<->2D image type casts

This commit is contained in:
kd-11 2017-11-02 18:54:57 +03:00
parent 7037504dcf
commit 0961a43997
6 changed files with 242 additions and 217 deletions

View File

@ -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 <typename commandbuffer_type, typename section_storage_type, typename image_resource_type, typename image_view_type, typename image_storage_type, typename texture_format>
@ -192,6 +204,7 @@ namespace rsx
std::vector<rsx_subresource_layout>& subresource_layout, const rsx::texture_dimension_extended type, const bool swizzled, std::pair<std::array<u8, 4>, std::array<u8, 4>>& 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<image_resource_type, 6>& 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 <typename T, typename U>
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 <typename T, typename U>
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<Args>(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 <typename render_target_type, typename surface_store_type>
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 <typename RsxTextureType, typename surface_store_type, typename ...Args>
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<Args>(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<Args>(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<Args>(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<Args>(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<Args>(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 <typename surface_store_type, typename blitter_type, typename ...Args>

View File

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

View File

@ -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<gl::render_target*>(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<u32, 6>& 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<u8, 4>, std::array<u8, 4>>& /*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)

View File

@ -243,13 +243,10 @@ struct RSXFragmentProgram
void set_texture_dimension(const std::array<rsx::texture_dimension_extended, 16> &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;
}
}

View File

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

View File

@ -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<vk::image_view> 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<vk::image*, 6>& 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<u8, 4>, std::array<u8, 4>>& 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)