Make sure mips are copied to memory

This commit is contained in:
Atlante45 2017-04-13 14:28:16 -07:00
parent a450f52427
commit 5ceb30b69c
13 changed files with 75 additions and 31 deletions

View file

@ -645,6 +645,18 @@ GLTexelFormat GLTexelFormat::evalGLTexelFormat(const Element& dstFormat, const E
case gpu::COMPRESSED_SRGBA:
texel.internalFormat = GL_COMPRESSED_SRGB_ALPHA;
break;
case gpu::COMPRESSED_BC3_RGBA:
texel.internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
break;
case gpu::COMPRESSED_BC3_SRGBA:
texel.internalFormat = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;
break;
case gpu::COMPRESSED_BC7_RGBA:
texel.internalFormat = GL_COMPRESSED_RGBA_BPTC_UNORM_ARB;
break;
case gpu::COMPRESSED_BC7_SRGBA:
texel.internalFormat = GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM;
break;
default:
qCWarning(gpugllogging) << "Unknown combination of texel format";
}

View file

@ -120,11 +120,12 @@ void GLTexture::copyMipFaceFromTexture(uint16_t sourceMip, uint16_t targetMip, u
}
auto size = _gpuObject.evalMipDimensions(sourceMip);
auto mipData = _gpuObject.accessStoredMipFace(sourceMip, face);
auto mipSize = _gpuObject.getStoredMipFaceSize(sourceMip, face);
if (mipData) {
GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat(), _gpuObject.getStoredMipFormat());
copyMipFaceLinesFromTexture(targetMip, face, size, 0, texelFormat.format, texelFormat.type, mipData->readData());
copyMipFaceLinesFromTexture(targetMip, face, size, 0, texelFormat.format, texelFormat.internalFormat, texelFormat.type, mipSize, mipData->readData());
} else {
qCDebug(gpugllogging) << "Missing mipData level=" << sourceMip << " face=" << (int)face << " for texture " << _gpuObject.source().c_str();
qCDebug(gpugllogging) << "Missing mipData level=" << sourceMip << " face=" << (int)face << " for texture " << _gpuObject.source().c_str();
}
}
@ -203,9 +204,11 @@ TransferJob::TransferJob(const GLTexture& parent, uint16_t sourceMip, uint16_t t
auto transferDimensions = _parent._gpuObject.evalMipDimensions(sourceMip);
GLenum format;
GLenum internalFormat;
GLenum type;
GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_parent._gpuObject.getTexelFormat(), _parent._gpuObject.getStoredMipFormat());
format = texelFormat.format;
internalFormat = texelFormat.internalFormat;
type = texelFormat.type;
auto mipSize = _parent._gpuObject.getStoredMipFaceSize(sourceMip, face);
@ -236,7 +239,7 @@ TransferJob::TransferJob(const GLTexture& parent, uint16_t sourceMip, uint16_t t
Backend::updateTextureTransferPendingSize(0, _transferSize);
_transferLambda = [=] {
_parent.copyMipFaceLinesFromTexture(targetMip, face, transferDimensions, lineOffset, format, type, _buffer.data());
_parent.copyMipFaceLinesFromTexture(targetMip, face, transferDimensions, lineOffset, format, internalFormat, type, _buffer.size(), _buffer.data());
std::vector<uint8_t> emptyVector;
_buffer.swap(emptyVector);
};

View file

@ -163,7 +163,7 @@ public:
protected:
virtual Size size() const = 0;
virtual void generateMips() const = 0;
virtual void copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const uvec3& size, uint32_t yOffset, GLenum format, GLenum type, const void* sourcePointer) const = 0;
virtual void copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const uvec3& size, uint32_t yOffset, GLenum format, GLenum internalFormat, GLenum type, Size sourceSize, const void* sourcePointer) const = 0;
virtual void copyMipFaceFromTexture(uint16_t sourceMip, uint16_t targetMip, uint8_t face) const final;
GLTexture(const std::weak_ptr<gl::GLBackend>& backend, const Texture& texture, GLuint id);

View file

@ -50,7 +50,7 @@ public:
protected:
GL41Texture(const std::weak_ptr<GLBackend>& backend, const Texture& texture);
void generateMips() const override;
void copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const uvec3& size, uint32_t yOffset, GLenum format, GLenum type, const void* sourcePointer) const override;
void copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const uvec3& size, uint32_t yOffset, GLenum format, GLenum internalFormat, GLenum type, Size sourceSize, const void* sourcePointer) const override;
virtual void syncSampler() const;
void withPreservedTexture(std::function<void()> f) const;

View file

@ -92,9 +92,15 @@ void GL41Texture::generateMips() const {
(void)CHECK_GL_ERROR();
}
void GL41Texture::copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const uvec3& size, uint32_t yOffset, GLenum format, GLenum type, const void* sourcePointer) const {
void GL41Texture::copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const uvec3& size, uint32_t yOffset, GLenum format, GLenum internalFormat, GLenum type, Size sourceSize, const void* sourcePointer) const {
if (GL_TEXTURE_2D == _target) {
glTexSubImage2D(_target, mip, 0, yOffset, size.x, size.y, format, type, sourcePointer);
if (GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT == internalFormat) {
qCDebug(gpugllogging) << "Compressed mipData level=" << mip << " face=" << (int)face << " for texture " << _gpuObject.source().c_str();
qCDebug(gpugllogging) << "Compressed mipData" << internalFormat << size.x << size.y << sourceSize << sourcePointer;
glCompressedTexImage2D(_target, mip, internalFormat, size.x, size.y, 0, sourceSize, sourcePointer);
} else {
glTexSubImage2D(_target, mip, 0, yOffset, size.x, size.y, format, type, sourcePointer);
}
} else if (GL_TEXTURE_CUBE_MAP == _target) {
auto target = GLTexture::CUBE_FACE_LAYOUT[face];
glTexSubImage2D(target, mip, 0, yOffset, size.x, size.y, format, type, sourcePointer);

View file

@ -48,7 +48,7 @@ public:
protected:
GL45Texture(const std::weak_ptr<GLBackend>& backend, const Texture& texture);
void generateMips() const override;
void copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const uvec3& size, uint32_t yOffset, GLenum format, GLenum type, const void* sourcePointer) const override;
void copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const uvec3& size, uint32_t yOffset, GLenum format, GLenum internalFormat, GLenum type, Size sourceSize, const void* sourcePointer) const override;
virtual void syncSampler() const;
};

View file

@ -117,9 +117,18 @@ void GL45Texture::generateMips() const {
(void)CHECK_GL_ERROR();
}
void GL45Texture::copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const uvec3& size, uint32_t yOffset, GLenum format, GLenum type, const void* sourcePointer) const {
void GL45Texture::copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const uvec3& size, uint32_t yOffset, GLenum format, GLenum internalFormat, GLenum type, Size sourceSize, const void* sourcePointer) const {
if (GL_TEXTURE_2D == _target) {
glTextureSubImage2D(_id, mip, 0, yOffset, size.x, size.y, format, type, sourcePointer);
if (GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT == internalFormat) {
qCDebug(gpugllogging) << "Compressed mipData level=" << mip << " face=" << (int)face << " for texture " << _gpuObject.source().c_str();
qCDebug(gpugllogging) << "Compressed mipData" << internalFormat << size.x << size.y << sourceSize << sourcePointer << "4.5";
glCompressedTextureSubImage2D(_id, mip, 0, yOffset, size.x, size.y, internalFormat, sourceSize, sourcePointer);
}
else {
qCDebug(gpugllogging) << "Uncompressed mipData level=" << mip << " face=" << (int)face << " for texture " << _gpuObject.source().c_str();
qCDebug(gpugllogging) << "Uncompressed mipData" << internalFormat << size.x << size.y << sourceSize << sourcePointer << "4.5";
glTextureSubImage2D(_id, mip, 0, yOffset, size.x, size.y, format, type, sourcePointer);
}
} else if (GL_TEXTURE_CUBE_MAP == _target) {
// DSA ARB does not work on AMD, so use EXT
// unless EXT is not available on the driver

View file

@ -19,6 +19,8 @@ const Element Element::COLOR_SRGBA_32{ VEC4, NUINT8, SRGBA };
const Element Element::COLOR_BGRA_32{ VEC4, NUINT8, BGRA };
const Element Element::COLOR_SBGRA_32{ VEC4, NUINT8, SBGRA };
const Element Element::COLOR_COMPRESSED_SRGBA{ VEC4, NUINT8, COMPRESSED_BC3_SRGBA };
const Element Element::COLOR_R11G11B10{ SCALAR, FLOAT, R11G11B10 };
const Element Element::VEC4F_COLOR_RGBA{ VEC4, FLOAT, RGBA };
const Element Element::VEC2F_UV{ VEC2, FLOAT, UV };

View file

@ -236,6 +236,7 @@ public:
static const Element COLOR_BGRA_32;
static const Element COLOR_SBGRA_32;
static const Element COLOR_R11G11B10;
static const Element COLOR_COMPRESSED_SRGBA;
static const Element VEC4F_COLOR_RGBA;
static const Element VEC2F_UV;
static const Element VEC2F_XY;

View file

@ -434,7 +434,7 @@ void Texture::assignStoredMip(uint16 level, storage::StoragePointer& storage) {
// THen check that the mem texture passed make sense with its format
Size expectedSize = evalStoredMipSize(level, getStoredMipFormat());
auto size = storage->size();
if (storage->size() == expectedSize) {
if (storage->size() <= expectedSize) {
_storage->assignMipData(level, storage);
_stamp++;
} else if (size > expectedSize) {
@ -461,7 +461,7 @@ void Texture::assignStoredMipFace(uint16 level, uint8 face, storage::StoragePoin
// THen check that the mem texture passed make sense with its format
Size expectedSize = evalStoredMipFaceSize(level, getStoredMipFormat());
auto size = storage->size();
if (size == expectedSize) {
if (size <= expectedSize) {
_storage->assignMipFaceData(level, face, storage);
_stamp++;
} else if (size > expectedSize) {

View file

@ -260,6 +260,9 @@ bool Texture::evalKTXFormat(const Element& mipFormat, const Element& texelFormat
header.setUncompressed(ktx::GLType::UNSIGNED_BYTE, 1, ktx::GLFormat::RGBA, ktx::GLInternalFormat_Uncompressed::SRGB8_ALPHA8, ktx::GLBaseInternalFormat::RGBA);
} else if (texelFormat == Format::COLOR_R_8 && mipFormat == Format::COLOR_R_8) {
header.setUncompressed(ktx::GLType::UNSIGNED_BYTE, 1, ktx::GLFormat::RED, ktx::GLInternalFormat_Uncompressed::R8, ktx::GLBaseInternalFormat::RED);
} else if (texelFormat == Format::COLOR_COMPRESSED_SRGBA && mipFormat == Format::COLOR_COMPRESSED_SRGBA) {
return false;
header.setCompressed(ktx::GLInternalFormat_Compressed::COMPRESSED_SRGB_ALPHA_BPTC_UNORM, ktx::GLBaseInternalFormat::RGBA);
} else {
return false;
}
@ -295,6 +298,13 @@ bool Texture::evalTextureFormat(const ktx::Header& header, Element& mipFormat, E
} else {
return false;
}
} else if (header.getGLFormat() == ktx::GLFormat::COMPRESSED_FORMAT && header.getGLType() == ktx::GLType::COMPRESSED_TYPE) {
if (header.getGLInternaFormat_Compressed() == ktx::GLInternalFormat_Compressed::COMPRESSED_SRGB_ALPHA_BPTC_UNORM) {
mipFormat = Format::COLOR_COMPRESSED_SRGBA;
texelFormat = Format::COLOR_COMPRESSED_SRGBA;
} else {
return false;
}
} else {
return false;
}

View file

@ -27,6 +27,9 @@ using namespace gpu;
// FIXME: Declare this to enable compression
//#define COMPRESS_TEXTURES
#define CPU_MIPMAPS 1
#define DEBUG_NVTT 1
static const glm::uvec2 SPARSE_PAGE_SIZE(128);
static const glm::uvec2 MAX_TEXTURE_SIZE(4096);
bool DEV_DECIMATE_TEXTURES = false;
@ -219,6 +222,10 @@ const QImage TextureUsage::process2DImageColor(const QImage& srcImage, bool& val
void TextureUsage::defineColorTexelFormats(gpu::Element& formatGPU, gpu::Element& formatMip,
const QImage& image, bool isLinear, bool doCompress) {
#ifdef COMPRESS_TEXTURES
#else
doCompress = false;
#endif
if (image.hasAlphaChannel()) {
gpu::Semantic gpuSemantic;
@ -226,14 +233,14 @@ void TextureUsage::defineColorTexelFormats(gpu::Element& formatGPU, gpu::Element
if (isLinear) {
mipSemantic = gpu::BGRA;
if (doCompress) {
gpuSemantic = gpu::COMPRESSED_BC3_RGBA;
gpuSemantic = gpu::COMPRESSED_RGBA;
} else {
gpuSemantic = gpu::RGBA;
}
} else {
mipSemantic = gpu::SBGRA;
if (doCompress) {
gpuSemantic = gpu::COMPRESSED_BC3_SRGBA;
gpuSemantic = gpu::COMPRESSED_SRGBA;
} else {
gpuSemantic = gpu::SRGBA;
}
@ -263,9 +270,6 @@ void TextureUsage::defineColorTexelFormats(gpu::Element& formatGPU, gpu::Element
}
}
#define CPU_MIPMAPS 1
#define DEBUG_NVTT 0
void generateMips(gpu::Texture* texture, QImage& image, bool fastResize) {
#if CPU_MIPMAPS
PROFILE_RANGE(resource_parse, "generateMips");
@ -276,6 +280,8 @@ void generateMips(gpu::Texture* texture, QImage& image, bool fastResize) {
debug << (QList<int>() << image.byteCount() << image.width() << image.height() << image.depth()) << "\n";
#endif // DEBUG_NVTT
texture->assignStoredMip(0, image.byteCount(), image.constBits());
auto numMips = texture->getNumMips();
for (uint16 level = 1; level < numMips; ++level) {
QSize mipSize(texture->evalMipWidth(level), texture->evalMipHeight(level));
@ -305,6 +311,8 @@ void generateMips(gpu::Texture* texture, QImage& image, bool fastResize) {
void generateFaceMips(gpu::Texture* texture, QImage& image, uint8 face) {
#if CPU_MIPMAPS
PROFILE_RANGE(resource_parse, "generateFaceMips");
auto numMips = texture->getNumMips();
for (uint16 level = 1; level < numMips; ++level) {
QSize mipSize(texture->evalMipWidth(level), texture->evalMipHeight(level));
@ -390,6 +398,7 @@ void generateNVTTMips(gpu::Texture* texture, QImage& image) {
return;
/**/
#if DEBUG_NVTT
QDebug debug = qDebug();
QDebug* debugPtr = &debug;
@ -409,7 +418,7 @@ void generateNVTTMips(gpu::Texture* texture, QImage& image) {
nvtt::InputFormat inputFormat = nvtt::InputFormat_BGRA_8UB;
nvtt::AlphaMode alphaMode = image.hasAlphaChannel() ? nvtt::AlphaMode_Transparency : nvtt::AlphaMode_None;
nvtt::WrapMode wrapMode = nvtt::WrapMode_Repeat;
nvtt::Format compressionFormat = image.hasAlphaChannel() ? nvtt::Format_RGBA : nvtt::Format_RGB;
nvtt::Format compressionFormat = nvtt::Format_BC3;
float inputGamma = 1.0f;
float outputGamma = 2.2f;
@ -436,7 +445,7 @@ void generateNVTTMips(gpu::Texture* texture, QImage& image) {
nvtt::CompressionOptions compressionOptions;
compressionOptions.setFormat(compressionFormat);
compressionOptions.setQuality(nvtt::Quality_Production);
compressionOptions.setQuality(nvtt::Quality_Fastest);
nvtt::Compressor compressor;
compressor.process(inputOptions, compressionOptions, outputOptions);
@ -457,6 +466,8 @@ gpu::Texture* TextureUsage::process2DTextureColorFromImage(const QImage& srcImag
gpu::Element formatGPU;
gpu::Element formatMip;
defineColorTexelFormats(formatGPU, formatMip, image, isLinear, doCompress);
formatGPU = gpu::Element::COLOR_COMPRESSED_SRGBA;
formatMip = gpu::Element::COLOR_COMPRESSED_SRGBA;
if (isStrict) {
theTexture = (gpu::Texture::createStrict(formatGPU, image.width(), image.height(), gpu::Texture::MAX_NUM_MIPS, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)));
@ -484,11 +495,11 @@ gpu::Texture* TextureUsage::process2DTextureColorFromImage(const QImage& srcImag
}
gpu::Texture* TextureUsage::createStrict2DTextureFromImage(const QImage& srcImage, const std::string& srcImageName) {
return process2DTextureColorFromImage(srcImage, srcImageName, false, true, true, true);
return process2DTextureColorFromImage(srcImage, srcImageName, false, false, true, true);
}
gpu::Texture* TextureUsage::create2DTextureFromImage(const QImage& srcImage, const std::string& srcImageName) {
return process2DTextureColorFromImage(srcImage, srcImageName, false, true, true);
return process2DTextureColorFromImage(srcImage, srcImageName, false, false, true);
}
gpu::Texture* TextureUsage::createAlbedoTextureFromImage(const QImage& srcImage, const std::string& srcImageName) {

View file

@ -101,8 +101,6 @@ namespace ktx {
UNSIGNED_INT_10F_11F_11F_REV = 0x8C3B,
UNSIGNED_INT_5_9_9_9_REV = 0x8C3E,
FLOAT_32_UNSIGNED_INT_24_8_REV = 0x8DAD,
NUM_GLTYPES = 25,
};
enum class GLFormat : uint32_t {
@ -130,8 +128,6 @@ namespace ktx {
RGBA_INTEGER = 0x8D99,
BGR_INTEGER = 0x8D9A,
BGRA_INTEGER = 0x8D9B,
NUM_GLFORMATS = 20,
};
enum class GLInternalFormat_Uncompressed : uint32_t {
@ -232,8 +228,6 @@ namespace ktx {
STENCIL_INDEX4 = 0x8D47,
STENCIL_INDEX8 = 0x8D48,
STENCIL_INDEX16 = 0x8D49,
NUM_UNCOMPRESSED_GLINTERNALFORMATS = 74,
};
enum class GLInternalFormat_Compressed : uint32_t {
@ -267,8 +261,6 @@ namespace ktx {
COMPRESSED_SIGNED_R11_EAC = 0x9271,
COMPRESSED_RG11_EAC = 0x9272,
COMPRESSED_SIGNED_RG11_EAC = 0x9273,
NUM_COMPRESSED_GLINTERNALFORMATS = 24,
};
enum class GLBaseInternalFormat : uint32_t {
@ -280,8 +272,6 @@ namespace ktx {
RGB = 0x1907,
RGBA = 0x1908,
STENCIL_INDEX = 0x1901,
NUM_GLBASEINTERNALFORMATS = 7,
};
enum CubeMapFace {