|
|
|
|
@ -33,61 +33,69 @@ const std::tuple<GLenum, GLenum, GLenum>& OpenGLTexture::GetPixelFormatMapping(G
|
|
|
|
|
{
|
|
|
|
|
static constexpr std::array<std::tuple<GLenum, GLenum, GLenum>, static_cast<u32>(GPUTexture::Format::MaxCount)>
|
|
|
|
|
mapping = {{
|
|
|
|
|
{}, // Unknown
|
|
|
|
|
{GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE}, // RGBA8
|
|
|
|
|
{GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE}, // BGRA8
|
|
|
|
|
{GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5}, // RGB565
|
|
|
|
|
{GL_RGB5_A1, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV}, // RGBA5551
|
|
|
|
|
{GL_R8, GL_RED, GL_UNSIGNED_BYTE}, // R8
|
|
|
|
|
{GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_SHORT}, // D16
|
|
|
|
|
{GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT}, // D24S8
|
|
|
|
|
{GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT}, // D32F
|
|
|
|
|
{GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT}, // D32FS8
|
|
|
|
|
{GL_R16, GL_RED, GL_UNSIGNED_SHORT}, // R16
|
|
|
|
|
{GL_R16I, GL_RED_INTEGER, GL_SHORT}, // R16I
|
|
|
|
|
{GL_R16UI, GL_RED_INTEGER, GL_UNSIGNED_SHORT}, // R16U
|
|
|
|
|
{GL_R16F, GL_RED, GL_HALF_FLOAT}, // R16F
|
|
|
|
|
{GL_R32I, GL_RED_INTEGER, GL_INT}, // R32I
|
|
|
|
|
{GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT}, // R32U
|
|
|
|
|
{GL_R32F, GL_RED, GL_FLOAT}, // R32F
|
|
|
|
|
{GL_RG8, GL_RG_INTEGER, GL_UNSIGNED_BYTE}, // RG8
|
|
|
|
|
{GL_RG16F, GL_RG, GL_UNSIGNED_SHORT}, // RG16
|
|
|
|
|
{GL_RG16F, GL_RG, GL_HALF_FLOAT}, // RG16F
|
|
|
|
|
{GL_RG32F, GL_RG, GL_FLOAT}, // RG32F
|
|
|
|
|
{GL_RGBA16, GL_RGBA, GL_UNSIGNED_BYTE}, // RGBA16
|
|
|
|
|
{GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT}, // RGBA16F
|
|
|
|
|
{GL_RGBA32F, GL_RGBA, GL_FLOAT}, // RGBA32F
|
|
|
|
|
{GL_RGB10_A2, GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV}, // RGB10A2
|
|
|
|
|
{}, // Unknown
|
|
|
|
|
{GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE}, // RGBA8
|
|
|
|
|
{GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE}, // BGRA8
|
|
|
|
|
{GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5}, // RGB565
|
|
|
|
|
{GL_RGB5_A1, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV}, // RGBA5551
|
|
|
|
|
{GL_R8, GL_RED, GL_UNSIGNED_BYTE}, // R8
|
|
|
|
|
{GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_SHORT}, // D16
|
|
|
|
|
{GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT}, // D24S8
|
|
|
|
|
{GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT}, // D32F
|
|
|
|
|
{GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT}, // D32FS8
|
|
|
|
|
{GL_R16, GL_RED, GL_UNSIGNED_SHORT}, // R16
|
|
|
|
|
{GL_R16I, GL_RED_INTEGER, GL_SHORT}, // R16I
|
|
|
|
|
{GL_R16UI, GL_RED_INTEGER, GL_UNSIGNED_SHORT}, // R16U
|
|
|
|
|
{GL_R16F, GL_RED, GL_HALF_FLOAT}, // R16F
|
|
|
|
|
{GL_R32I, GL_RED_INTEGER, GL_INT}, // R32I
|
|
|
|
|
{GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT}, // R32U
|
|
|
|
|
{GL_R32F, GL_RED, GL_FLOAT}, // R32F
|
|
|
|
|
{GL_RG8, GL_RG_INTEGER, GL_UNSIGNED_BYTE}, // RG8
|
|
|
|
|
{GL_RG16F, GL_RG, GL_UNSIGNED_SHORT}, // RG16
|
|
|
|
|
{GL_RG16F, GL_RG, GL_HALF_FLOAT}, // RG16F
|
|
|
|
|
{GL_RG32F, GL_RG, GL_FLOAT}, // RG32F
|
|
|
|
|
{GL_RGBA16, GL_RGBA, GL_UNSIGNED_BYTE}, // RGBA16
|
|
|
|
|
{GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT}, // RGBA16F
|
|
|
|
|
{GL_RGBA32F, GL_RGBA, GL_FLOAT}, // RGBA32F
|
|
|
|
|
{GL_RGB10_A2, GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV}, // RGB10A2
|
|
|
|
|
{GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE}, // BC1
|
|
|
|
|
{GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_UNSIGNED_BYTE}, // BC2
|
|
|
|
|
{GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_UNSIGNED_BYTE}, // BC3
|
|
|
|
|
{GL_COMPRESSED_RGBA_BPTC_UNORM_ARB, GL_COMPRESSED_RGBA_BPTC_UNORM_ARB, GL_UNSIGNED_BYTE}, // BC7
|
|
|
|
|
}};
|
|
|
|
|
|
|
|
|
|
// GLES doesn't have the non-normalized 16-bit formats.. use float and hope for the best, lol.
|
|
|
|
|
static constexpr std::array<std::tuple<GLenum, GLenum, GLenum>, static_cast<u32>(GPUTexture::Format::MaxCount)>
|
|
|
|
|
mapping_gles = {{
|
|
|
|
|
{}, // Unknown
|
|
|
|
|
{GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE}, // RGBA8
|
|
|
|
|
{GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE}, // BGRA8
|
|
|
|
|
{GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5}, // RGB565
|
|
|
|
|
{GL_RGB5_A1, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV}, // RGBA5551
|
|
|
|
|
{GL_R8, GL_RED, GL_UNSIGNED_BYTE}, // R8
|
|
|
|
|
{GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_SHORT}, // D16
|
|
|
|
|
{GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT}, // D24S8
|
|
|
|
|
{GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT}, // D32F
|
|
|
|
|
{GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT}, // D32FS8
|
|
|
|
|
{GL_R16F, GL_RED, GL_HALF_FLOAT}, // R16
|
|
|
|
|
{GL_R16I, GL_RED_INTEGER, GL_SHORT}, // R16I
|
|
|
|
|
{GL_R16UI, GL_RED_INTEGER, GL_UNSIGNED_SHORT}, // R16U
|
|
|
|
|
{GL_R16F, GL_RED, GL_HALF_FLOAT}, // R16F
|
|
|
|
|
{GL_R32I, GL_RED_INTEGER, GL_INT}, // R32I
|
|
|
|
|
{GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT}, // R32U
|
|
|
|
|
{GL_R32F, GL_RED, GL_FLOAT}, // R32F
|
|
|
|
|
{GL_RG8, GL_RG, GL_UNSIGNED_BYTE}, // RG8
|
|
|
|
|
{GL_RG16F, GL_RG, GL_HALF_FLOAT}, // RG16
|
|
|
|
|
{GL_RG16F, GL_RG, GL_HALF_FLOAT}, // RG16F
|
|
|
|
|
{GL_RG32F, GL_RG, GL_FLOAT}, // RG32F
|
|
|
|
|
{GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT}, // RGBA16
|
|
|
|
|
{GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT}, // RGBA16F
|
|
|
|
|
{GL_RGBA32F, GL_RGBA, GL_FLOAT}, // RGBA32F
|
|
|
|
|
{GL_RGB10_A2, GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV}, // RGB10A2
|
|
|
|
|
{}, // Unknown
|
|
|
|
|
{GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE}, // RGBA8
|
|
|
|
|
{GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE}, // BGRA8
|
|
|
|
|
{GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5}, // RGB565
|
|
|
|
|
{GL_RGB5_A1, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV}, // RGBA5551
|
|
|
|
|
{GL_R8, GL_RED, GL_UNSIGNED_BYTE}, // R8
|
|
|
|
|
{GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_SHORT}, // D16
|
|
|
|
|
{GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT}, // D24S8
|
|
|
|
|
{GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT}, // D32F
|
|
|
|
|
{GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT}, // D32FS8
|
|
|
|
|
{GL_R16F, GL_RED, GL_HALF_FLOAT}, // R16
|
|
|
|
|
{GL_R16I, GL_RED_INTEGER, GL_SHORT}, // R16I
|
|
|
|
|
{GL_R16UI, GL_RED_INTEGER, GL_UNSIGNED_SHORT}, // R16U
|
|
|
|
|
{GL_R16F, GL_RED, GL_HALF_FLOAT}, // R16F
|
|
|
|
|
{GL_R32I, GL_RED_INTEGER, GL_INT}, // R32I
|
|
|
|
|
{GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT}, // R32U
|
|
|
|
|
{GL_R32F, GL_RED, GL_FLOAT}, // R32F
|
|
|
|
|
{GL_RG8, GL_RG, GL_UNSIGNED_BYTE}, // RG8
|
|
|
|
|
{GL_RG16F, GL_RG, GL_HALF_FLOAT}, // RG16
|
|
|
|
|
{GL_RG16F, GL_RG, GL_HALF_FLOAT}, // RG16F
|
|
|
|
|
{GL_RG32F, GL_RG, GL_FLOAT}, // RG32F
|
|
|
|
|
{GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT}, // RGBA16
|
|
|
|
|
{GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT}, // RGBA16F
|
|
|
|
|
{GL_RGBA32F, GL_RGBA, GL_FLOAT}, // RGBA32F
|
|
|
|
|
{GL_RGB10_A2, GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV}, // RGB10A2
|
|
|
|
|
{GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE}, // BC1
|
|
|
|
|
{GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_UNSIGNED_BYTE}, // BC2
|
|
|
|
|
{GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_UNSIGNED_BYTE}, // BC3
|
|
|
|
|
{GL_COMPRESSED_RGBA_BPTC_UNORM_ARB, GL_COMPRESSED_RGBA_BPTC_UNORM_ARB, GL_UNSIGNED_BYTE}, // BC7
|
|
|
|
|
}};
|
|
|
|
|
|
|
|
|
|
return gles ? mapping_gles[static_cast<u32>(format)] : mapping[static_cast<u32>(format)];
|
|
|
|
|
@ -169,6 +177,7 @@ std::unique_ptr<OpenGLTexture> OpenGLTexture::Create(u32 width, u32 height, u32
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
const bool use_texture_storage = UseTextureStorage(false);
|
|
|
|
|
const bool is_compressed = IsCompressedFormat(format);
|
|
|
|
|
if (use_texture_storage)
|
|
|
|
|
{
|
|
|
|
|
if (layers > 1)
|
|
|
|
|
@ -183,10 +192,10 @@ std::unique_ptr<OpenGLTexture> OpenGLTexture::Create(u32 width, u32 height, u32
|
|
|
|
|
const u32 alignment = GetUploadAlignment(data_pitch);
|
|
|
|
|
if (data)
|
|
|
|
|
{
|
|
|
|
|
GPUDevice::GetStatistics().buffer_streamed += data_pitch * height;
|
|
|
|
|
GPUDevice::GetStatistics().buffer_streamed += CalcUploadSize(format, height, data_pitch);
|
|
|
|
|
GPUDevice::GetStatistics().num_uploads++;
|
|
|
|
|
|
|
|
|
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, data_pitch / pixel_size);
|
|
|
|
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, CalcUploadRowLengthFromPitch(format, data_pitch));
|
|
|
|
|
if (alignment != DEFAULT_UPLOAD_ALIGNMENT)
|
|
|
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
|
|
|
|
|
}
|
|
|
|
|
@ -198,18 +207,55 @@ std::unique_ptr<OpenGLTexture> OpenGLTexture::Create(u32 width, u32 height, u32
|
|
|
|
|
{
|
|
|
|
|
if (use_texture_storage)
|
|
|
|
|
{
|
|
|
|
|
if (layers > 1)
|
|
|
|
|
glTexSubImage3D(target, i, 0, 0, 0, current_width, current_height, layers, gl_format, gl_type, data_ptr);
|
|
|
|
|
if (is_compressed)
|
|
|
|
|
{
|
|
|
|
|
const u32 size = CalcUploadSize(format, current_height, data_pitch);
|
|
|
|
|
if (layers > 1)
|
|
|
|
|
{
|
|
|
|
|
glCompressedTexSubImage3D(target, i, 0, 0, 0, current_width, current_height, layers, gl_format, size,
|
|
|
|
|
data_ptr);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
glCompressedTexSubImage2D(target, i, 0, 0, current_width, current_height, gl_format, size, data_ptr);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
glTexSubImage2D(target, i, 0, 0, current_width, current_height, gl_format, gl_type, data_ptr);
|
|
|
|
|
{
|
|
|
|
|
if (layers > 1)
|
|
|
|
|
glTexSubImage3D(target, i, 0, 0, 0, current_width, current_height, layers, gl_format, gl_type, data_ptr);
|
|
|
|
|
else
|
|
|
|
|
glTexSubImage2D(target, i, 0, 0, current_width, current_height, gl_format, gl_type, data_ptr);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (layers > 1)
|
|
|
|
|
glTexImage3D(target, i, gl_internal_format, current_width, current_height, layers, 0, gl_format, gl_type,
|
|
|
|
|
data_ptr);
|
|
|
|
|
if (is_compressed)
|
|
|
|
|
{
|
|
|
|
|
const u32 size = CalcUploadSize(format, current_height, data_pitch);
|
|
|
|
|
if (layers > 1)
|
|
|
|
|
{
|
|
|
|
|
glCompressedTexImage3D(target, i, gl_internal_format, current_width, current_height, layers, 0, size,
|
|
|
|
|
data_ptr);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
glCompressedTexImage2D(target, i, gl_internal_format, current_width, current_height, 0, size, data_ptr);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
glTexImage2D(target, i, gl_internal_format, current_width, current_height, 0, gl_format, gl_type, data_ptr);
|
|
|
|
|
{
|
|
|
|
|
if (layers > 1)
|
|
|
|
|
{
|
|
|
|
|
glTexImage3D(target, i, gl_internal_format, current_width, current_height, layers, 0, gl_format, gl_type,
|
|
|
|
|
data_ptr);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
glTexImage2D(target, i, gl_internal_format, current_width, current_height, 0, gl_format, gl_type,
|
|
|
|
|
data_ptr);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (data_ptr)
|
|
|
|
|
@ -257,14 +303,11 @@ void OpenGLTexture::CommitClear()
|
|
|
|
|
bool OpenGLTexture::Update(u32 x, u32 y, u32 width, u32 height, const void* data, u32 pitch, u32 layer /*= 0*/,
|
|
|
|
|
u32 level /*= 0*/)
|
|
|
|
|
{
|
|
|
|
|
// TODO: perf counters
|
|
|
|
|
|
|
|
|
|
// Worth using the PBO? Driver probably knows better...
|
|
|
|
|
const GLenum target = GetGLTarget();
|
|
|
|
|
const auto [gl_internal_format, gl_format, gl_type] = GetPixelFormatMapping(m_format, OpenGLDevice::IsGLES());
|
|
|
|
|
const u32 pixel_size = GetPixelSize();
|
|
|
|
|
const u32 preferred_pitch = Common::AlignUpPow2(static_cast<u32>(width) * pixel_size, TEXTURE_UPLOAD_PITCH_ALIGNMENT);
|
|
|
|
|
const u32 map_size = preferred_pitch * static_cast<u32>(height);
|
|
|
|
|
const u32 preferred_pitch = Common::AlignUpPow2(CalcUploadPitch(width), TEXTURE_UPLOAD_PITCH_ALIGNMENT);
|
|
|
|
|
const u32 map_size = CalcUploadSize(height, pitch);
|
|
|
|
|
OpenGLStreamBuffer* sb = OpenGLDevice::GetTextureStreamBuffer();
|
|
|
|
|
|
|
|
|
|
CommitClear();
|
|
|
|
|
@ -283,8 +326,22 @@ bool OpenGLTexture::Update(u32 x, u32 y, u32 width, u32 height, const void* data
|
|
|
|
|
if (alignment != DEFAULT_UPLOAD_ALIGNMENT)
|
|
|
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
|
|
|
|
|
|
|
|
|
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch / pixel_size);
|
|
|
|
|
glTexSubImage2D(target, layer, x, y, width, height, gl_format, gl_type, data);
|
|
|
|
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, CalcUploadRowLengthFromPitch(pitch));
|
|
|
|
|
if (IsCompressedFormat())
|
|
|
|
|
{
|
|
|
|
|
const u32 size = CalcUploadSize(height, pitch);
|
|
|
|
|
if (IsTextureArray())
|
|
|
|
|
glCompressedTexSubImage3D(target, level, x, y, layer, width, height, 1, gl_format, size, data);
|
|
|
|
|
else
|
|
|
|
|
glCompressedTexSubImage2D(target, level, x, y, width, height, gl_format, size, data);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (IsTextureArray())
|
|
|
|
|
glTexSubImage3D(target, level, x, y, layer, width, height, 1, gl_format, gl_type, data);
|
|
|
|
|
else
|
|
|
|
|
glTexSubImage2D(target, level, x, y, width, height, gl_format, gl_type, data);
|
|
|
|
|
}
|
|
|
|
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
|
|
|
|
|
|
|
|
|
if (alignment != DEFAULT_UPLOAD_ALIGNMENT)
|
|
|
|
|
@ -293,13 +350,39 @@ bool OpenGLTexture::Update(u32 x, u32 y, u32 width, u32 height, const void* data
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
const auto map = sb->Map(TEXTURE_UPLOAD_ALIGNMENT, map_size);
|
|
|
|
|
StringUtil::StrideMemCpy(map.pointer, preferred_pitch, data, pitch, width * pixel_size, height);
|
|
|
|
|
CopyTextureDataForUpload(width, height, m_format, map.pointer, preferred_pitch, data, pitch);
|
|
|
|
|
sb->Unmap(map_size);
|
|
|
|
|
sb->Bind();
|
|
|
|
|
|
|
|
|
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, preferred_pitch / pixel_size);
|
|
|
|
|
glTexSubImage2D(GL_TEXTURE_2D, layer, x, y, width, height, gl_format, gl_type,
|
|
|
|
|
reinterpret_cast<void*>(static_cast<uintptr_t>(map.buffer_offset)));
|
|
|
|
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, CalcUploadRowLengthFromPitch(preferred_pitch));
|
|
|
|
|
if (IsCompressedFormat())
|
|
|
|
|
{
|
|
|
|
|
const u32 size = CalcUploadSize(height, pitch);
|
|
|
|
|
if (IsTextureArray())
|
|
|
|
|
{
|
|
|
|
|
glCompressedTexSubImage3D(target, level, x, y, layer, width, height, 1, gl_format, size,
|
|
|
|
|
reinterpret_cast<void*>(static_cast<uintptr_t>(map.buffer_offset)));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
glCompressedTexSubImage2D(target, level, x, y, width, height, gl_format, size,
|
|
|
|
|
reinterpret_cast<void*>(static_cast<uintptr_t>(map.buffer_offset)));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (IsTextureArray())
|
|
|
|
|
{
|
|
|
|
|
glTexSubImage3D(target, level, x, y, layer, width, height, 1, gl_format, gl_type,
|
|
|
|
|
reinterpret_cast<void*>(static_cast<uintptr_t>(map.buffer_offset)));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
glTexSubImage2D(target, level, x, y, width, height, gl_format, gl_type,
|
|
|
|
|
reinterpret_cast<void*>(static_cast<uintptr_t>(map.buffer_offset)));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
|
|
|
|
|
|
|
|
|
sb->Unbind();
|
|
|
|
|
@ -315,8 +398,8 @@ bool OpenGLTexture::Map(void** map, u32* map_stride, u32 x, u32 y, u32 width, u3
|
|
|
|
|
if ((x + width) > GetMipWidth(level) || (y + height) > GetMipHeight(level) || layer > m_layers || level > m_levels)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
const u32 pitch = Common::AlignUpPow2(static_cast<u32>(width) * GetPixelSize(), TEXTURE_UPLOAD_PITCH_ALIGNMENT);
|
|
|
|
|
const u32 upload_size = pitch * static_cast<u32>(height);
|
|
|
|
|
const u32 pitch = Common::AlignUpPow2(CalcUploadPitch(width), TEXTURE_UPLOAD_PITCH_ALIGNMENT);
|
|
|
|
|
const u32 upload_size = CalcUploadSize(height, pitch);
|
|
|
|
|
OpenGLStreamBuffer* sb = OpenGLDevice::GetTextureStreamBuffer();
|
|
|
|
|
if (!sb || upload_size > sb->GetSize())
|
|
|
|
|
return false;
|
|
|
|
|
@ -339,8 +422,8 @@ void OpenGLTexture::Unmap()
|
|
|
|
|
{
|
|
|
|
|
CommitClear();
|
|
|
|
|
|
|
|
|
|
const u32 pitch = Common::AlignUpPow2(static_cast<u32>(m_map_width) * GetPixelSize(), TEXTURE_UPLOAD_PITCH_ALIGNMENT);
|
|
|
|
|
const u32 upload_size = pitch * static_cast<u32>(m_map_height);
|
|
|
|
|
const u32 pitch = Common::AlignUpPow2(CalcUploadPitch(m_map_width), TEXTURE_UPLOAD_PITCH_ALIGNMENT);
|
|
|
|
|
const u32 upload_size = CalcUploadSize(m_map_height, pitch);
|
|
|
|
|
|
|
|
|
|
GPUDevice::GetStatistics().buffer_streamed += upload_size;
|
|
|
|
|
GPUDevice::GetStatistics().num_uploads++;
|
|
|
|
|
@ -354,18 +437,35 @@ void OpenGLTexture::Unmap()
|
|
|
|
|
const GLenum target = GetGLTarget();
|
|
|
|
|
glBindTexture(target, m_id);
|
|
|
|
|
|
|
|
|
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch / GetPixelSize());
|
|
|
|
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, CalcUploadRowLengthFromPitch(pitch));
|
|
|
|
|
|
|
|
|
|
const auto [gl_internal_format, gl_format, gl_type] = GetPixelFormatMapping(m_format, OpenGLDevice::IsGLES());
|
|
|
|
|
if (IsTextureArray())
|
|
|
|
|
if (IsCompressedFormat())
|
|
|
|
|
{
|
|
|
|
|
glTexSubImage3D(target, m_map_level, m_map_x, m_map_y, m_map_layer, m_map_width, m_map_height, 1, gl_format,
|
|
|
|
|
gl_type, reinterpret_cast<void*>(static_cast<uintptr_t>(m_map_offset)));
|
|
|
|
|
const u32 size = CalcUploadSize(m_map_height, pitch);
|
|
|
|
|
if (IsTextureArray())
|
|
|
|
|
{
|
|
|
|
|
glCompressedTexSubImage3D(target, m_map_level, m_map_x, m_map_y, m_map_layer, m_map_width, m_map_height, 1,
|
|
|
|
|
gl_format, size, reinterpret_cast<void*>(static_cast<uintptr_t>(m_map_offset)));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
glCompressedTexSubImage2D(target, m_map_level, m_map_x, m_map_y, m_map_width, m_map_height, gl_format, size,
|
|
|
|
|
reinterpret_cast<void*>(static_cast<uintptr_t>(m_map_offset)));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
glTexSubImage2D(target, m_map_level, m_map_x, m_map_y, m_map_width, m_map_height, gl_format, gl_type,
|
|
|
|
|
reinterpret_cast<void*>(static_cast<uintptr_t>(m_map_offset)));
|
|
|
|
|
if (IsTextureArray())
|
|
|
|
|
{
|
|
|
|
|
glTexSubImage3D(target, m_map_level, m_map_x, m_map_y, m_map_layer, m_map_width, m_map_height, 1, gl_format,
|
|
|
|
|
gl_type, reinterpret_cast<void*>(static_cast<uintptr_t>(m_map_offset)));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
glTexSubImage2D(target, m_map_level, m_map_x, m_map_y, m_map_width, m_map_height, gl_format, gl_type,
|
|
|
|
|
reinterpret_cast<void*>(static_cast<uintptr_t>(m_map_offset)));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
|
|
|
|
|