mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-06 06:51:26 +12:00
gl: Rewrite image transfer operations to support image subregions
- Working exclusively with full sized images is very expensive
This commit is contained in:
parent
d9a9766e41
commit
27f48fbc06
7 changed files with 103 additions and 62 deletions
|
@ -756,19 +756,19 @@ void GLGSRender::on_init_thread()
|
||||||
|
|
||||||
//1D
|
//1D
|
||||||
auto tex1D = std::make_unique<gl::texture>(GL_TEXTURE_1D, 1, 1, 1, 1, GL_RGBA8);
|
auto tex1D = std::make_unique<gl::texture>(GL_TEXTURE_1D, 1, 1, 1, 1, GL_RGBA8);
|
||||||
tex1D->copy_from(pixeldata.data(), gl::texture::format::rgba, gl::texture::type::uint_8_8_8_8);
|
tex1D->copy_from(pixeldata.data(), gl::texture::format::rgba, gl::texture::type::uint_8_8_8_8, {});
|
||||||
|
|
||||||
//2D
|
//2D
|
||||||
auto tex2D = std::make_unique<gl::texture>(GL_TEXTURE_2D, 1, 1, 1, 1, GL_RGBA8);
|
auto tex2D = std::make_unique<gl::texture>(GL_TEXTURE_2D, 1, 1, 1, 1, GL_RGBA8);
|
||||||
tex2D->copy_from(pixeldata.data(), gl::texture::format::rgba, gl::texture::type::uint_8_8_8_8);
|
tex2D->copy_from(pixeldata.data(), gl::texture::format::rgba, gl::texture::type::uint_8_8_8_8, {});
|
||||||
|
|
||||||
//3D
|
//3D
|
||||||
auto tex3D = std::make_unique<gl::texture>(GL_TEXTURE_3D, 1, 1, 1, 1, GL_RGBA8);
|
auto tex3D = std::make_unique<gl::texture>(GL_TEXTURE_3D, 1, 1, 1, 1, GL_RGBA8);
|
||||||
tex3D->copy_from(pixeldata.data(), gl::texture::format::rgba, gl::texture::type::uint_8_8_8_8);
|
tex3D->copy_from(pixeldata.data(), gl::texture::format::rgba, gl::texture::type::uint_8_8_8_8, {});
|
||||||
|
|
||||||
//CUBE
|
//CUBE
|
||||||
auto texCUBE = std::make_unique<gl::texture>(GL_TEXTURE_CUBE_MAP, 1, 1, 1, 1, GL_RGBA8);
|
auto texCUBE = std::make_unique<gl::texture>(GL_TEXTURE_CUBE_MAP, 1, 1, 1, 1, GL_RGBA8);
|
||||||
texCUBE->copy_from(pixeldata.data(), gl::texture::format::rgba, gl::texture::type::uint_8_8_8_8);
|
texCUBE->copy_from(pixeldata.data(), gl::texture::format::rgba, gl::texture::type::uint_8_8_8_8, {});
|
||||||
|
|
||||||
m_null_textures[GL_TEXTURE_1D] = std::move(tex1D);
|
m_null_textures[GL_TEXTURE_1D] = std::move(tex1D);
|
||||||
m_null_textures[GL_TEXTURE_2D] = std::move(tex2D);
|
m_null_textures[GL_TEXTURE_2D] = std::move(tex2D);
|
||||||
|
@ -966,8 +966,15 @@ void GLGSRender::on_init_thread()
|
||||||
|
|
||||||
void GLGSRender::on_exit()
|
void GLGSRender::on_exit()
|
||||||
{
|
{
|
||||||
|
// Globals
|
||||||
|
// TODO: Move these
|
||||||
gl::destroy_compute_tasks();
|
gl::destroy_compute_tasks();
|
||||||
|
|
||||||
|
if (gl::g_typeless_transfer_buffer)
|
||||||
|
{
|
||||||
|
gl::g_typeless_transfer_buffer.remove();
|
||||||
|
}
|
||||||
|
|
||||||
zcull_ctrl.release();
|
zcull_ctrl.release();
|
||||||
|
|
||||||
m_prog_buffer.clear();
|
m_prog_buffer.clear();
|
||||||
|
|
|
@ -702,7 +702,8 @@ namespace gl
|
||||||
array = GL_ARRAY_BUFFER,
|
array = GL_ARRAY_BUFFER,
|
||||||
element_array = GL_ELEMENT_ARRAY_BUFFER,
|
element_array = GL_ELEMENT_ARRAY_BUFFER,
|
||||||
uniform = GL_UNIFORM_BUFFER,
|
uniform = GL_UNIFORM_BUFFER,
|
||||||
texture = GL_TEXTURE_BUFFER
|
texture = GL_TEXTURE_BUFFER,
|
||||||
|
ssbo = GL_SHADER_STORAGE_BUFFER
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class access
|
enum class access
|
||||||
|
@ -925,6 +926,11 @@ namespace gl
|
||||||
{
|
{
|
||||||
glBindBufferRange((GLenum)current_target(), index, id(), offset, size);
|
glBindBufferRange((GLenum)current_target(), index, id(), offset, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void bind_range(target target_, u32 index, u32 offset, u32 size) const
|
||||||
|
{
|
||||||
|
glBindBufferRange((GLenum)target_, index, id(), offset, size);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class ring_buffer : public buffer
|
class ring_buffer : public buffer
|
||||||
|
@ -1764,9 +1770,15 @@ namespace gl
|
||||||
return m_aspect_flags;
|
return m_aspect_flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
sizei size2D() const
|
sizeu size2D() const
|
||||||
{
|
{
|
||||||
return{ (int)m_width, (int)m_height };
|
return{ m_width, m_height };
|
||||||
|
}
|
||||||
|
|
||||||
|
size3u size3D() const
|
||||||
|
{
|
||||||
|
const auto depth = (m_target == target::textureCUBE) ? 6 : m_depth;
|
||||||
|
return{ m_width, m_height, depth };
|
||||||
}
|
}
|
||||||
|
|
||||||
texture::internal_format get_internal_format() const
|
texture::internal_format get_internal_format() const
|
||||||
|
@ -1779,7 +1791,7 @@ namespace gl
|
||||||
return m_component_layout;
|
return m_component_layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
void copy_from(const void* src, texture::format format, texture::type type, class pixel_unpack_settings pixel_settings)
|
void copy_from(const void* src, texture::format format, texture::type type, const coord3u region, const pixel_unpack_settings& pixel_settings)
|
||||||
{
|
{
|
||||||
pixel_settings.apply();
|
pixel_settings.apply();
|
||||||
|
|
||||||
|
@ -1787,33 +1799,34 @@ namespace gl
|
||||||
{
|
{
|
||||||
case GL_TEXTURE_1D:
|
case GL_TEXTURE_1D:
|
||||||
{
|
{
|
||||||
DSA_CALL(TextureSubImage1D, m_id, GL_TEXTURE_1D, 0, 0, m_width, (GLenum)format, (GLenum)type, src);
|
DSA_CALL(TextureSubImage1D, m_id, GL_TEXTURE_1D, 0, region.x, region.width, (GLenum)format, (GLenum)type, src);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GL_TEXTURE_2D:
|
case GL_TEXTURE_2D:
|
||||||
{
|
{
|
||||||
DSA_CALL(TextureSubImage2D, m_id, GL_TEXTURE_2D, 0, 0, 0, m_width, m_height, (GLenum)format, (GLenum)type, src);
|
DSA_CALL(TextureSubImage2D, m_id, GL_TEXTURE_2D, 0, region.x, region.y, region.width, region.height, (GLenum)format, (GLenum)type, src);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GL_TEXTURE_3D:
|
case GL_TEXTURE_3D:
|
||||||
{
|
{
|
||||||
DSA_CALL(TextureSubImage3D, m_id, GL_TEXTURE_3D, 0, 0, 0, 0, m_width, m_height, m_depth, (GLenum)format, (GLenum)type, src);
|
DSA_CALL(TextureSubImage3D, m_id, GL_TEXTURE_3D, 0, region.x, region.y, region.z, region.width, region.height, region.depth, (GLenum)format, (GLenum)type, src);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GL_TEXTURE_CUBE_MAP:
|
case GL_TEXTURE_CUBE_MAP:
|
||||||
{
|
{
|
||||||
if (::gl::get_driver_caps().ARB_dsa_supported)
|
if (get_driver_caps().ARB_dsa_supported)
|
||||||
{
|
{
|
||||||
glTextureSubImage3D(m_id, 0, 0, 0, 0, m_width, m_height, 6, (GLenum)format, (GLenum)type, src);
|
glTextureSubImage3D(m_id, 0, region.x, region.y, region.z, region.width, region.height, region.depth, (GLenum)format, (GLenum)type, src);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG_WARNING(RSX, "Cubemap upload via texture::copy_from is halfplemented!");
|
LOG_WARNING(RSX, "Cubemap upload via texture::copy_from is halfplemented!");
|
||||||
u8* ptr = (u8*)src;
|
u8* ptr = (u8*)src;
|
||||||
for (int face = 0; face < 6; ++face)
|
const auto end = std::min(6u, region.z + region.depth);
|
||||||
|
for (unsigned face = region.z; face < end; ++face)
|
||||||
{
|
{
|
||||||
glTextureSubImage2DEXT(m_id, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, 0, 0, m_width, m_height, (GLenum)format, (GLenum)type, ptr);
|
glTextureSubImage2DEXT(m_id, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, region.x, region.y, region.width, region.height, (GLenum)format, (GLenum)type, ptr);
|
||||||
ptr += (m_width * m_height * 4); //TODO
|
ptr += (region.width * region.height * 4); //TODO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1821,6 +1834,12 @@ namespace gl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void copy_from(const void* src, texture::format format, texture::type type, const pixel_unpack_settings& pixel_settings)
|
||||||
|
{
|
||||||
|
const coord3u region = { {}, size3D() };
|
||||||
|
copy_from(src, format, type, region, pixel_settings);
|
||||||
|
}
|
||||||
|
|
||||||
void copy_from(buffer &buf, u32 gl_format_type, u32 offset, u32 length)
|
void copy_from(buffer &buf, u32 gl_format_type, u32 offset, u32 length)
|
||||||
{
|
{
|
||||||
if (get_target() != target::textureBuffer)
|
if (get_target() != target::textureBuffer)
|
||||||
|
@ -1834,45 +1853,41 @@ namespace gl
|
||||||
copy_from(*view.value(), view.format(), view.offset(), view.range());
|
copy_from(*view.value(), view.format(), view.offset(), view.range());
|
||||||
}
|
}
|
||||||
|
|
||||||
void copy_from(const buffer& buf, texture::format format, texture::type type, class pixel_unpack_settings pixel_settings)
|
void copy_to(void* dst, texture::format format, texture::type type, const coord3u& region, const pixel_pack_settings& pixel_settings) const
|
||||||
{
|
|
||||||
buffer::save_binding_state save_buffer(buffer::target::pixel_unpack, buf);
|
|
||||||
copy_from(nullptr, format, type, pixel_settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
void copy_from(void* src, texture::format format, texture::type type)
|
|
||||||
{
|
|
||||||
copy_from(src, format, type, pixel_unpack_settings());
|
|
||||||
}
|
|
||||||
|
|
||||||
void copy_from(const buffer& buf, texture::format format, texture::type type)
|
|
||||||
{
|
|
||||||
copy_from(buf, format, type, pixel_unpack_settings());
|
|
||||||
}
|
|
||||||
|
|
||||||
void copy_to(void* dst, texture::format format, texture::type type, class pixel_pack_settings pixel_settings) const
|
|
||||||
{
|
{
|
||||||
pixel_settings.apply();
|
pixel_settings.apply();
|
||||||
if (gl::get_driver_caps().ARB_dsa_supported)
|
const auto& caps = get_driver_caps();
|
||||||
glGetTextureImage(m_id, 0, (GLenum)format, (GLenum)type, m_width * m_height * 16, dst);
|
|
||||||
|
if (!region.x && !region.y && !region.z &&
|
||||||
|
region.width == m_width && region.height == m_height && region.depth == m_depth)
|
||||||
|
{
|
||||||
|
if (caps.ARB_dsa_supported)
|
||||||
|
glGetTextureImage(m_id, 0, (GLenum)format, (GLenum)type, INT32_MAX, dst);
|
||||||
|
else
|
||||||
|
glGetTextureImageEXT(m_id, (GLenum)m_target, 0, (GLenum)format, (GLenum)type, dst);
|
||||||
|
}
|
||||||
|
else if (caps.ARB_dsa_supported)
|
||||||
|
{
|
||||||
|
glGetTextureSubImage(m_id, 0, region.x, region.y, region.z, region.width, region.height, region.depth,
|
||||||
|
(GLenum)format, (GLenum)type, INT32_MAX, dst);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
glGetTextureImageEXT(m_id, (GLenum)m_target, 0, (GLenum)format, (GLenum)type, dst);
|
{
|
||||||
|
// Worst case scenario. For some reason, EXT_dsa does not have glGetTextureSubImage
|
||||||
|
const auto target_ = static_cast<GLenum>(m_target);
|
||||||
|
texture tmp{ target_, region.width, region.height, region.depth, 1, (GLenum)m_internal_format };
|
||||||
|
glCopyImageSubData(m_id, target_, 0, region.x, region.y, region.z, tmp.id(), target_, 0, 0, 0, 0,
|
||||||
|
region.width, region.height, region.depth);
|
||||||
|
|
||||||
|
const coord3u region2 = { {0, 0, 0}, region.size };
|
||||||
|
tmp.copy_to(dst, format, type, region2, pixel_settings);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void copy_to(const buffer& buf, texture::format format, texture::type type, class pixel_pack_settings pixel_settings) const
|
void copy_to(void* dst, texture::format format, texture::type type, const pixel_pack_settings& pixel_settings) const
|
||||||
{
|
{
|
||||||
buffer::save_binding_state save_buffer(buffer::target::pixel_pack, buf);
|
const coord3u region = { {}, size3D() };
|
||||||
copy_to(nullptr, format, type, pixel_settings);
|
copy_to(dst, format, type, region, pixel_settings);
|
||||||
}
|
|
||||||
|
|
||||||
void copy_to(void* dst, texture::format format, texture::type type) const
|
|
||||||
{
|
|
||||||
copy_to(dst, format, type, pixel_pack_settings());
|
|
||||||
}
|
|
||||||
|
|
||||||
void copy_to(const buffer& buf, texture::format format, texture::type type) const
|
|
||||||
{
|
|
||||||
copy_to(buf, format, type, pixel_pack_settings());
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -480,7 +480,7 @@ namespace gl
|
||||||
gl::texture_view* load_simple_image(rsx::overlays::image_info* desc, bool temp_resource, u32 owner_uid)
|
gl::texture_view* load_simple_image(rsx::overlays::image_info* desc, bool temp_resource, u32 owner_uid)
|
||||||
{
|
{
|
||||||
auto tex = std::make_unique<gl::texture>(GL_TEXTURE_2D, desc->w, desc->h, 1, 1, GL_RGBA8);
|
auto tex = std::make_unique<gl::texture>(GL_TEXTURE_2D, desc->w, desc->h, 1, 1, GL_RGBA8);
|
||||||
tex->copy_from(desc->data, gl::texture::format::rgba, gl::texture::type::uint_8_8_8_8);
|
tex->copy_from(desc->data, gl::texture::format::rgba, gl::texture::type::uint_8_8_8_8, {});
|
||||||
|
|
||||||
GLenum remap[] = { GL_RED, GL_ALPHA, GL_BLUE, GL_GREEN };
|
GLenum remap[] = { GL_RED, GL_ALPHA, GL_BLUE, GL_GREEN };
|
||||||
auto view = std::make_unique<gl::texture_view>(tex.get(), remap);
|
auto view = std::make_unique<gl::texture_view>(tex.get(), remap);
|
||||||
|
@ -551,7 +551,7 @@ namespace gl
|
||||||
|
|
||||||
//Create font file
|
//Create font file
|
||||||
auto tex = std::make_unique<gl::texture>(GL_TEXTURE_2D, (int)font->width, (int)font->height, 1, 1, GL_R8);
|
auto tex = std::make_unique<gl::texture>(GL_TEXTURE_2D, (int)font->width, (int)font->height, 1, 1, GL_R8);
|
||||||
tex->copy_from(font->glyph_data.data(), gl::texture::format::r, gl::texture::type::ubyte);
|
tex->copy_from(font->glyph_data.data(), gl::texture::format::r, gl::texture::type::ubyte, {});
|
||||||
|
|
||||||
GLenum remap[] = { GL_RED, GL_RED, GL_RED, GL_RED };
|
GLenum remap[] = { GL_RED, GL_RED, GL_RED, GL_RED };
|
||||||
auto view = std::make_unique<gl::texture_view>(tex.get(), remap);
|
auto view = std::make_unique<gl::texture_view>(tex.get(), remap);
|
||||||
|
|
|
@ -166,6 +166,7 @@ OPENGL_PROC(PFNGLPRIMITIVERESTARTINDEXPROC, PrimitiveRestartIndex);
|
||||||
|
|
||||||
OPENGL_PROC(PFNGLGETINTEGER64VPROC, GetInteger64v);
|
OPENGL_PROC(PFNGLGETINTEGER64VPROC, GetInteger64v);
|
||||||
OPENGL_PROC(PFNGLGETSTRINGIPROC, GetStringi);
|
OPENGL_PROC(PFNGLGETSTRINGIPROC, GetStringi);
|
||||||
|
OPENGL_PROC(PFNGLGETINTEGERI_VPROC, GetIntegeri_v);
|
||||||
|
|
||||||
OPENGL_PROC(PFNGLCHECKFRAMEBUFFERSTATUSPROC, CheckFramebufferStatus);
|
OPENGL_PROC(PFNGLCHECKFRAMEBUFFERSTATUSPROC, CheckFramebufferStatus);
|
||||||
|
|
||||||
|
@ -178,6 +179,7 @@ OPENGL_PROC(PFNGLMULTIDRAWARRAYSPROC, MultiDrawArrays);
|
||||||
|
|
||||||
OPENGL_PROC(PFNGLGETTEXTUREIMAGEEXTPROC, GetTextureImageEXT);
|
OPENGL_PROC(PFNGLGETTEXTUREIMAGEEXTPROC, GetTextureImageEXT);
|
||||||
OPENGL_PROC(PFNGLGETTEXTUREIMAGEPROC, GetTextureImage);
|
OPENGL_PROC(PFNGLGETTEXTUREIMAGEPROC, GetTextureImage);
|
||||||
|
OPENGL_PROC(PFNGLGETTEXTURESUBIMAGEPROC, GetTextureSubImage);
|
||||||
OPENGL_PROC(PFNGLTEXTURESUBIMAGE1DEXTPROC, TextureSubImage1DEXT);
|
OPENGL_PROC(PFNGLTEXTURESUBIMAGE1DEXTPROC, TextureSubImage1DEXT);
|
||||||
OPENGL_PROC(PFNGLTEXTURESUBIMAGE1DPROC, TextureSubImage1D);
|
OPENGL_PROC(PFNGLTEXTURESUBIMAGE1DPROC, TextureSubImage1D);
|
||||||
OPENGL_PROC(PFNGLTEXTURESUBIMAGE2DEXTPROC, TextureSubImage2DEXT);
|
OPENGL_PROC(PFNGLTEXTURESUBIMAGE2DEXTPROC, TextureSubImage2DEXT);
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
namespace gl
|
namespace gl
|
||||||
{
|
{
|
||||||
static buffer g_typeless_transfer_buffer;
|
buffer g_typeless_transfer_buffer;
|
||||||
|
|
||||||
GLenum get_target(rsx::texture_dimension_extended type)
|
GLenum get_target(rsx::texture_dimension_extended type)
|
||||||
{
|
{
|
||||||
|
@ -775,10 +775,10 @@ namespace gl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void copy_typeless(texture * dst, const texture * src)
|
void copy_typeless(texture * dst, const texture * src, const coord3u& dst_region, const coord3u& src_region)
|
||||||
{
|
{
|
||||||
GLsizeiptr src_mem = src->pitch() * src->height();
|
const u32 src_mem = src->pitch() * src_region.height;
|
||||||
GLsizeiptr dst_mem = dst->pitch() * dst->height();
|
const u32 dst_mem = dst->pitch() * dst_region.height;
|
||||||
|
|
||||||
auto max_mem = std::max(src_mem, dst_mem);
|
auto max_mem = std::max(src_mem, dst_mem);
|
||||||
if (!g_typeless_transfer_buffer || max_mem > g_typeless_transfer_buffer.size())
|
if (!g_typeless_transfer_buffer || max_mem > g_typeless_transfer_buffer.size())
|
||||||
|
@ -797,13 +797,13 @@ namespace gl
|
||||||
if (LIKELY(caps.ARB_compute_shader_supported))
|
if (LIKELY(caps.ARB_compute_shader_supported))
|
||||||
{
|
{
|
||||||
// Raw copy
|
// Raw copy
|
||||||
src->copy_to(nullptr, (texture::format)pack_info.format, (texture::type)pack_info.type);
|
src->copy_to(nullptr, (texture::format)pack_info.format, (texture::type)pack_info.type, src_region, {});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pixel_pack_settings pack_settings{};
|
pixel_pack_settings pack_settings{};
|
||||||
pack_settings.swap_bytes(pack_info.swap_bytes);
|
pack_settings.swap_bytes(pack_info.swap_bytes);
|
||||||
src->copy_to(nullptr, (texture::format)pack_info.format, (texture::type)pack_info.type, pack_settings);
|
src->copy_to(nullptr, (texture::format)pack_info.format, (texture::type)pack_info.type, src_region, pack_settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, GL_NONE);
|
glBindBuffer(GL_PIXEL_PACK_BUFFER, GL_NONE);
|
||||||
|
@ -850,7 +850,14 @@ namespace gl
|
||||||
}
|
}
|
||||||
|
|
||||||
g_typeless_transfer_buffer.bind(buffer::target::pixel_unpack);
|
g_typeless_transfer_buffer.bind(buffer::target::pixel_unpack);
|
||||||
dst->copy_from(nullptr, (texture::format)unpack_info.format, (texture::type)unpack_info.type, unpack_settings);
|
dst->copy_from(nullptr, (texture::format)unpack_info.format, (texture::type)unpack_info.type, dst_region, unpack_settings);
|
||||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, GL_NONE);
|
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, GL_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void copy_typeless(texture* dst, const texture* src)
|
||||||
|
{
|
||||||
|
const coord3u src_area = { {}, src->size3D() };
|
||||||
|
const coord3u dst_area = { {}, dst->size3D() };
|
||||||
|
copy_typeless(dst, src, dst_area, src_area);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,9 @@ namespace gl
|
||||||
viewable_image* create_texture(u32 gcm_format, u16 width, u16 height, u16 depth, u16 mipmaps, rsx::texture_dimension_extended type);
|
viewable_image* create_texture(u32 gcm_format, u16 width, u16 height, u16 depth, u16 mipmaps, rsx::texture_dimension_extended type);
|
||||||
|
|
||||||
bool formats_are_bitcast_compatible(GLenum format1, GLenum format2);
|
bool formats_are_bitcast_compatible(GLenum format1, GLenum format2);
|
||||||
|
void copy_typeless(texture* dst, const texture* src, const coord3u& dst_region, const coord3u& src_region);
|
||||||
void copy_typeless(texture* dst, const texture* src);
|
void copy_typeless(texture* dst, const texture* src);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* is_swizzled - determines whether input bytes are in morton order
|
* is_swizzled - determines whether input bytes are in morton order
|
||||||
* subresources_layout - descriptor of the mipmap levels in memory
|
* subresources_layout - descriptor of the mipmap levels in memory
|
||||||
|
@ -110,4 +112,6 @@ namespace gl
|
||||||
|
|
||||||
void apply_defaults(GLenum default_filter = GL_NEAREST);
|
void apply_defaults(GLenum default_filter = GL_NEAREST);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern buffer g_typeless_transfer_buffer;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ namespace gl
|
||||||
class blitter;
|
class blitter;
|
||||||
|
|
||||||
extern GLenum get_sized_internal_format(u32);
|
extern GLenum get_sized_internal_format(u32);
|
||||||
extern void copy_typeless(texture*, const texture*);
|
extern void copy_typeless(texture*, const texture*, const coord3u&, const coord3u&);
|
||||||
extern blitter *g_hw_blitter;
|
extern blitter *g_hw_blitter;
|
||||||
|
|
||||||
class cached_texture_section;
|
class cached_texture_section;
|
||||||
|
@ -632,11 +632,17 @@ namespace gl
|
||||||
tmp = std::make_unique<texture>(GL_TEXTURE_2D, convert_w, slice.src->height(), 1, 1, (GLenum)dst_image->get_internal_format());
|
tmp = std::make_unique<texture>(GL_TEXTURE_2D, convert_w, slice.src->height(), 1, 1, (GLenum)dst_image->get_internal_format());
|
||||||
|
|
||||||
src_image = tmp.get();
|
src_image = tmp.get();
|
||||||
gl::copy_typeless(src_image, slice.src);
|
|
||||||
|
|
||||||
// Compute src region in dst format layout
|
// Compute src region in dst format layout
|
||||||
src_x = u16(src_x * src_bpp) / dst_bpp;
|
const u16 src_w2 = u16(src_w * src_bpp) / dst_bpp;
|
||||||
src_w = u16(src_w * src_bpp) / dst_bpp;
|
const u16 src_x2 = u16(src_x * src_bpp) / dst_bpp;
|
||||||
|
|
||||||
|
const coord3u src_region = { { src_x, src_y, 0 }, { src_w, src_h, 1 } };
|
||||||
|
const coord3u dst_region = { { src_x2, src_y, 0 }, { src_w2, src_h, 1 } };
|
||||||
|
gl::copy_typeless(src_image, slice.src, dst_region, src_region);
|
||||||
|
|
||||||
|
src_x = src_x2;
|
||||||
|
src_w = src_w2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (src_w == slice.dst_w && src_h == slice.dst_h)
|
if (src_w == slice.dst_w && src_h == slice.dst_h)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue