mirror of
https://github.com/lubosz/overte.git
synced 2025-04-07 09:42:06 +02:00
Adding new storage backing for gpu::Texture, moving mip format into Storage abstraction
This commit is contained in:
parent
07506b0078
commit
27e8750b9b
14 changed files with 178 additions and 154 deletions
|
@ -362,7 +362,8 @@ void OpenGLDisplayPlugin::customizeContext() {
|
|||
cursorData.texture->setSource("cursor texture");
|
||||
auto usage = gpu::Texture::Usage::Builder().withColor().withAlpha();
|
||||
cursorData.texture->setUsage(usage.build());
|
||||
cursorData.texture->assignStoredMip(0, gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA), image.byteCount(), image.constBits());
|
||||
cursorData.texture->setStoredMipFormat(gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA));
|
||||
cursorData.texture->assignStoredMip(0, image.byteCount(), image.constBits());
|
||||
cursorData.texture->autoGenerateMips(-1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -302,7 +302,8 @@ void HmdDisplayPlugin::internalPresent() {
|
|||
gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)));
|
||||
_previewTexture->setSource("HMD Preview Texture");
|
||||
_previewTexture->setUsage(gpu::Texture::Usage::Builder().withColor().build());
|
||||
_previewTexture->assignStoredMip(0, gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA), image.byteCount(), image.constBits());
|
||||
_previewTexture->setStoredMipFormat(gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA));
|
||||
_previewTexture->assignStoredMip(0, image.byteCount(), image.constBits());
|
||||
_previewTexture->autoGenerateMips(-1);
|
||||
}
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ GL41Texture::GL41Texture(const std::weak_ptr<GLBackend>& backend, const Texture&
|
|||
: GLTexture(backend, texture, allocate()), _storageStamp { texture.getStamp() }, _size(texture.evalTotalSize()) {
|
||||
incrementTextureGPUCount();
|
||||
withPreservedTexture([&] {
|
||||
GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat());
|
||||
GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat(), _gpuObject.getStoredMipFormat());
|
||||
const Sampler& sampler = _gpuObject.getSampler();
|
||||
auto numMips = _gpuObject.evalNumMips();
|
||||
for (uint16_t mipLevel = 0; mipLevel < numMips; ++mipLevel) {
|
||||
|
@ -83,7 +83,6 @@ GL41Texture::GL41Texture(const std::weak_ptr<GLBackend>& backend, const Texture&
|
|||
if (_gpuObject.isStoredMipFaceAvailable(mipLevel, face)) {
|
||||
auto mip = _gpuObject.accessStoredMipFace(mipLevel, face);
|
||||
mipData = mip->readData();
|
||||
texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat(), mip->getFormat());
|
||||
}
|
||||
glTexImage2D(target, mipLevel, texelFormat.internalFormat, dimensions.x, dimensions.y, 0, texelFormat.format, texelFormat.type, mipData);
|
||||
(void)CHECK_GL_ERROR();
|
||||
|
|
|
@ -142,7 +142,7 @@ void GL45Texture::copyMipFaceFromTexture(uint16_t sourceMip, uint16_t targetMip,
|
|||
}
|
||||
auto size = _gpuObject.evalMipDimensions(sourceMip);
|
||||
auto mipData = _gpuObject.accessStoredMipFace(sourceMip, face);
|
||||
GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat(), mipData->getFormat());
|
||||
GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat(), _gpuObject.getStoredMipFormat());
|
||||
copyMipFaceLinesFromTexture(targetMip, face, size, 0, texelFormat.format, texelFormat.type, mipData->readData());
|
||||
}
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ TransferJob::TransferJob(const GL45VariableAllocationTexture& parent, uint16_t s
|
|||
GLenum format;
|
||||
GLenum type;
|
||||
auto mipData = _parent._gpuObject.accessStoredMipFace(sourceMip, face);
|
||||
GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_parent._gpuObject.getTexelFormat(), mipData->getFormat());
|
||||
GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_parent._gpuObject.getTexelFormat(), _parent._gpuObject.getStoredMipFormat());
|
||||
format = texelFormat.format;
|
||||
type = texelFormat.type;
|
||||
|
||||
|
|
|
@ -120,18 +120,6 @@ void Texture::setAllowedGPUMemoryUsage(Size size) {
|
|||
|
||||
uint8 Texture::NUM_FACES_PER_TYPE[NUM_TYPES] = { 1, 1, 1, 6 };
|
||||
|
||||
Texture::Pixels::Pixels(const Element& format, Size size, const Byte* bytes) :
|
||||
_format(format),
|
||||
_storage(new storage::MemoryStorage(size, bytes)) {
|
||||
Texture::updateTextureCPUMemoryUsage(0, _storage->size());
|
||||
}
|
||||
|
||||
Texture::Pixels::~Pixels() {
|
||||
if (_storage) {
|
||||
Texture::updateTextureCPUMemoryUsage(_storage->size(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
void Texture::Storage::assignTexture(Texture* texture) {
|
||||
_texture = texture;
|
||||
if (_texture) {
|
||||
|
@ -139,21 +127,12 @@ void Texture::Storage::assignTexture(Texture* texture) {
|
|||
}
|
||||
}
|
||||
|
||||
void Texture::Storage::reset() {
|
||||
void Texture::MemoryStorage::reset() {
|
||||
_mips.clear();
|
||||
bumpStamp();
|
||||
}
|
||||
|
||||
Texture::PixelsPointer Texture::Storage::editMipFace(uint16 level, uint8 face) {
|
||||
if (level < _mips.size()) {
|
||||
assert(face < _mips[level].size());
|
||||
bumpStamp();
|
||||
return _mips[level][face];
|
||||
}
|
||||
return PixelsPointer();
|
||||
}
|
||||
|
||||
const Texture::PixelsPointer Texture::Storage::getMipFace(uint16 level, uint8 face) const {
|
||||
const Texture::PixelsPointer Texture::MemoryStorage::getMipFace(uint16 level, uint8 face) const {
|
||||
if (level < _mips.size()) {
|
||||
assert(face < _mips[level].size());
|
||||
return _mips[level][face];
|
||||
|
@ -161,12 +140,12 @@ const Texture::PixelsPointer Texture::Storage::getMipFace(uint16 level, uint8 fa
|
|||
return PixelsPointer();
|
||||
}
|
||||
|
||||
bool Texture::Storage::isMipAvailable(uint16 level, uint8 face) const {
|
||||
bool Texture::MemoryStorage::isMipAvailable(uint16 level, uint8 face) const {
|
||||
PixelsPointer mipFace = getMipFace(level, face);
|
||||
return (mipFace && mipFace->getSize());
|
||||
}
|
||||
|
||||
bool Texture::Storage::allocateMip(uint16 level) {
|
||||
bool Texture::MemoryStorage::allocateMip(uint16 level) {
|
||||
bool changed = false;
|
||||
if (level >= _mips.size()) {
|
||||
_mips.resize(level+1, std::vector<PixelsPointer>(Texture::NUM_FACES_PER_TYPE[getType()]));
|
||||
|
@ -176,7 +155,6 @@ bool Texture::Storage::allocateMip(uint16 level) {
|
|||
auto& mip = _mips[level];
|
||||
for (auto& face : mip) {
|
||||
if (!face) {
|
||||
face = std::make_shared<Pixels>();
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
@ -186,7 +164,7 @@ bool Texture::Storage::allocateMip(uint16 level) {
|
|||
return changed;
|
||||
}
|
||||
|
||||
bool Texture::Storage::assignMipData(uint16 level, const Element& format, Size size, const Byte* bytes) {
|
||||
void Texture::MemoryStorage::assignMipData(uint16 level, const storage::StoragePointer& storagePointer) {
|
||||
|
||||
allocateMip(level);
|
||||
auto& mip = _mips[level];
|
||||
|
@ -195,33 +173,24 @@ bool Texture::Storage::assignMipData(uint16 level, const Element& format, Size s
|
|||
// The bytes assigned here are supposed to contain all the faces bytes of the mip.
|
||||
// For tex1D, 2D, 3D there is only one face
|
||||
// For Cube, we expect the 6 faces in the order X+, X-, Y+, Y-, Z+, Z-
|
||||
auto sizePerFace = size / mip.size();
|
||||
auto faceBytes = bytes;
|
||||
Size allocated = 0;
|
||||
auto sizePerFace = storagePointer->size() / mip.size();
|
||||
size_t offset = 0;
|
||||
for (auto& face : mip) {
|
||||
face.reset(new Pixels(format, size, bytes));
|
||||
allocated += size;
|
||||
faceBytes += sizePerFace;
|
||||
face = storagePointer->createView(sizePerFace, offset);
|
||||
offset += sizePerFace;
|
||||
}
|
||||
|
||||
bumpStamp();
|
||||
|
||||
return allocated == size;
|
||||
}
|
||||
|
||||
|
||||
bool Texture::Storage::assignMipFaceData(uint16 level, const Element& format, Size size, const Byte* bytes, uint8 face) {
|
||||
|
||||
void Texture::MemoryStorage::assignMipFaceData(uint16 level, uint8 face, const storage::StoragePointer& storagePointer) {
|
||||
allocateMip(level);
|
||||
auto& mip = _mips[level];
|
||||
Size allocated = 0;
|
||||
if (face < mip.size()) {
|
||||
mip[face].reset(new Pixels(format, size, bytes));
|
||||
allocated += size;
|
||||
mip[face] = storagePointer;
|
||||
bumpStamp();
|
||||
}
|
||||
|
||||
return allocated == size;
|
||||
}
|
||||
|
||||
Texture* Texture::createExternal(const ExternalRecycler& recycler, const Sampler& sampler) {
|
||||
|
@ -260,7 +229,7 @@ Texture* Texture::createCube(const Element& texelFormat, uint16 width, const Sam
|
|||
Texture* Texture::create(TextureUsageType usageType, Type type, const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numSamples, uint16 numSlices, const Sampler& sampler)
|
||||
{
|
||||
Texture* tex = new Texture(usageType);
|
||||
tex->_storage.reset(new Storage());
|
||||
tex->_storage.reset(new MemoryStorage());
|
||||
tex->_type = type;
|
||||
tex->_storage->assignTexture(tex);
|
||||
tex->_maxMip = 0;
|
||||
|
@ -402,69 +371,83 @@ uint16 Texture::evalNumMips() const {
|
|||
return evalNumMips({ _width, _height, _depth });
|
||||
}
|
||||
|
||||
bool Texture::assignStoredMip(uint16 level, const Element& format, Size size, const Byte* bytes) {
|
||||
void Texture::setStoredMipFormat(const Element& format) {
|
||||
_storage->setFormat(format);
|
||||
}
|
||||
|
||||
const Element& Texture::getStoredMipFormat() const {
|
||||
return _storage->getFormat();
|
||||
}
|
||||
|
||||
void Texture::assignStoredMip(uint16 level, Size size, const Byte* bytes) {
|
||||
storage::StoragePointer storage { new storage::MemoryStorage(size, bytes) };
|
||||
assignStoredMip(level, storage);
|
||||
}
|
||||
|
||||
void Texture::assignStoredMipFace(uint16 level, uint8 face, Size size, const Byte* bytes) {
|
||||
storage::StoragePointer storage { new storage::MemoryStorage(size, bytes) };
|
||||
assignStoredMipFace(level, face, storage);
|
||||
}
|
||||
|
||||
void Texture::assignStoredMip(uint16 level, storage::StoragePointer& storage) {
|
||||
// Check that level accessed make sense
|
||||
if (level != 0) {
|
||||
if (_autoGenerateMips) {
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
if (level >= evalNumMips()) {
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// THen check that the mem texture passed make sense with its format
|
||||
Size expectedSize = evalStoredMipSize(level, format);
|
||||
if (size == expectedSize) {
|
||||
_storage->assignMipData(level, format, size, bytes);
|
||||
Size expectedSize = evalStoredMipSize(level, getStoredMipFormat());
|
||||
auto size = storage->size();
|
||||
auto bytes = storage->data();
|
||||
if (storage->size() == expectedSize) {
|
||||
_storage->assignMipData(level, storage);
|
||||
_maxMip = std::max(_maxMip, level);
|
||||
_stamp++;
|
||||
return true;
|
||||
} else if (size > expectedSize) {
|
||||
// NOTE: We are facing this case sometime because apparently QImage (from where we get the bits) is generating images
|
||||
// and alligning the line of pixels to 32 bits.
|
||||
// We should probably consider something a bit more smart to get the correct result but for now (UI elements)
|
||||
// it seems to work...
|
||||
_storage->assignMipData(level, format, size, bytes);
|
||||
_storage->assignMipData(level, storage);
|
||||
_maxMip = std::max(_maxMip, level);
|
||||
_stamp++;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool Texture::assignStoredMipFace(uint16 level, const Element& format, Size size, const Byte* bytes, uint8 face) {
|
||||
void Texture::assignStoredMipFace(uint16 level, uint8 face, storage::StoragePointer& storage) {
|
||||
// Check that level accessed make sense
|
||||
if (level != 0) {
|
||||
if (_autoGenerateMips) {
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
if (level >= evalNumMips()) {
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// THen check that the mem texture passed make sense with its format
|
||||
Size expectedSize = evalStoredMipFaceSize(level, format);
|
||||
Size expectedSize = evalStoredMipFaceSize(level, getStoredMipFormat());
|
||||
auto size = storage->size();
|
||||
auto bytes = storage->data();
|
||||
if (size == expectedSize) {
|
||||
_storage->assignMipFaceData(level, format, size, bytes, face);
|
||||
_storage->assignMipFaceData(level, face, storage);
|
||||
_stamp++;
|
||||
return true;
|
||||
} else if (size > expectedSize) {
|
||||
// NOTE: We are facing this case sometime because apparently QImage (from where we get the bits) is generating images
|
||||
// and alligning the line of pixels to 32 bits.
|
||||
// We should probably consider something a bit more smart to get the correct result but for now (UI elements)
|
||||
// it seems to work...
|
||||
_storage->assignMipFaceData(level, format, size, bytes, face);
|
||||
_storage->assignMipFaceData(level, face, storage);
|
||||
_stamp++;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
uint16 Texture::autoGenerateMips(uint16 maxMip) {
|
||||
bool changed = false;
|
||||
if (!_autoGenerateMips) {
|
||||
|
@ -498,7 +481,7 @@ uint16 Texture::getStoredMipHeight(uint16 level) const {
|
|||
if (mip && mip->getSize()) {
|
||||
return evalMipHeight(level);
|
||||
}
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16 Texture::getStoredMipDepth(uint16 level) const {
|
||||
|
@ -770,8 +753,8 @@ bool sphericalHarmonicsFromTexture(const gpu::Texture& cubeTexture, std::vector<
|
|||
for(int face=0; face < gpu::Texture::NUM_CUBE_FACES; face++) {
|
||||
PROFILE_RANGE(render_gpu, "ProcessFace");
|
||||
|
||||
auto numComponents = cubeTexture.accessStoredMipFace(0,face)->getFormat().getScalarCount();
|
||||
auto data = cubeTexture.accessStoredMipFace(0,face)->readData();
|
||||
auto numComponents = cubeTexture.getStoredMipFormat().getScalarCount();
|
||||
auto data = cubeTexture.accessStoredMipFace(0,face)->data();
|
||||
if (data == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -226,30 +226,7 @@ public:
|
|||
bool operator!=(const Usage& usage) { return (_flags != usage._flags); }
|
||||
};
|
||||
|
||||
|
||||
class Pixels {
|
||||
public:
|
||||
using StoragePointer = storage::StoragePointer;
|
||||
|
||||
Pixels() {}
|
||||
Pixels(const Pixels& pixels) = default;
|
||||
Pixels(const Element& format, Size size, const Byte* bytes);
|
||||
Pixels(const Element& format, StoragePointer& storage) : _format(format), _storage(storage.release()) {}
|
||||
~Pixels();
|
||||
|
||||
const Byte* readData() const { return _storage->data(); }
|
||||
Size getSize() const { return _storage->size(); }
|
||||
|
||||
const Element& getFormat() const { return _format; }
|
||||
|
||||
|
||||
protected:
|
||||
Element _format;
|
||||
StoragePointer _storage;
|
||||
|
||||
friend class Texture;
|
||||
};
|
||||
typedef std::shared_ptr< Pixels > PixelsPointer;
|
||||
using PixelsPointer = storage::StoragePointer;
|
||||
|
||||
enum Type {
|
||||
TEX_1D = 0,
|
||||
|
@ -272,35 +249,68 @@ public:
|
|||
NUM_CUBE_FACES, // Not a valid vace index
|
||||
};
|
||||
|
||||
|
||||
class Storage {
|
||||
public:
|
||||
Storage() {}
|
||||
virtual ~Storage() {}
|
||||
virtual void reset();
|
||||
virtual PixelsPointer editMipFace(uint16 level, uint8 face = 0);
|
||||
virtual const PixelsPointer getMipFace(uint16 level, uint8 face = 0) const;
|
||||
virtual bool allocateMip(uint16 level);
|
||||
virtual bool assignMipData(uint16 level, const Element& format, Size size, const Byte* bytes);
|
||||
virtual bool assignMipFaceData(uint16 level, const Element& format, Size size, const Byte* bytes, uint8 face);
|
||||
virtual bool isMipAvailable(uint16 level, uint8 face = 0) const;
|
||||
|
||||
virtual void reset() = 0;
|
||||
virtual const PixelsPointer getMipFace(uint16 level, uint8 face = 0) const = 0;
|
||||
virtual void assignMipData(uint16 level, const storage::StoragePointer& storage) = 0;
|
||||
virtual void assignMipFaceData(uint16 level, uint8 face, const storage::StoragePointer& storage) = 0;
|
||||
virtual bool isMipAvailable(uint16 level, uint8 face = 0) const = 0;
|
||||
Texture::Type getType() const { return _type; }
|
||||
|
||||
|
||||
Stamp getStamp() const { return _stamp; }
|
||||
Stamp bumpStamp() { return ++_stamp; }
|
||||
protected:
|
||||
Stamp _stamp = 0;
|
||||
Texture* _texture = nullptr; // Points to the parent texture (not owned)
|
||||
Texture::Type _type = Texture::TEX_2D; // The type of texture is needed to know the number of faces to expect
|
||||
std::vector<std::vector<PixelsPointer>> _mips; // an array of mips, each mip is an array of faces
|
||||
|
||||
void setFormat(const Element& format) { _format = format; }
|
||||
const Element& getFormat() const { return _format; }
|
||||
|
||||
private:
|
||||
Stamp _stamp { 0 };
|
||||
Element _format;
|
||||
Texture::Type _type { Texture::TEX_2D }; // The type of texture is needed to know the number of faces to expect
|
||||
Texture* _texture { nullptr }; // Points to the parent texture (not owned)
|
||||
virtual void assignTexture(Texture* tex); // Texture storage is pointing to ONE corrresponding Texture.
|
||||
const Texture* getTexture() const { return _texture; }
|
||||
|
||||
friend class Texture;
|
||||
};
|
||||
|
||||
|
||||
class MemoryStorage : public Storage {
|
||||
public:
|
||||
void reset() override;
|
||||
const PixelsPointer getMipFace(uint16 level, uint8 face = 0) const override;
|
||||
void assignMipData(uint16 level, const storage::StoragePointer& storage) override;
|
||||
void assignMipFaceData(uint16 level, uint8 face, const storage::StoragePointer& storage) override;
|
||||
bool isMipAvailable(uint16 level, uint8 face = 0) const override;
|
||||
|
||||
protected:
|
||||
bool allocateMip(uint16 level);
|
||||
std::vector<std::vector<PixelsPointer>> _mips; // an array of mips, each mip is an array of faces
|
||||
};
|
||||
|
||||
class KtxStorage : public Storage {
|
||||
public:
|
||||
KtxStorage(ktx::KTXUniquePointer& ktxData);
|
||||
const PixelsPointer getMipFace(uint16 level, uint8 face = 0) const override;
|
||||
bool isMipAvailable(uint16 level, uint8 face = 0) const override;
|
||||
|
||||
void assignMipData(uint16 level, const storage::StoragePointer& storage) override {
|
||||
throw std::runtime_error("Invalid call");
|
||||
}
|
||||
|
||||
void assignMipFaceData(uint16 level, uint8 face, const storage::StoragePointer& storage) override {
|
||||
throw std::runtime_error("Invalid call");
|
||||
}
|
||||
void reset() override { }
|
||||
|
||||
protected:
|
||||
ktx::KTXUniquePointer _ktxData;
|
||||
friend class Texture;
|
||||
};
|
||||
|
||||
static Texture* create1D(const Element& texelFormat, uint16 width, const Sampler& sampler = Sampler());
|
||||
static Texture* create2D(const Element& texelFormat, uint16 width, uint16 height, const Sampler& sampler = Sampler());
|
||||
static Texture* create3D(const Element& texelFormat, uint16 width, uint16 height, uint16 depth, const Sampler& sampler = Sampler());
|
||||
|
@ -444,13 +454,21 @@ public:
|
|||
|
||||
// Managing Storage and mips
|
||||
|
||||
// Mip storage format is constant across all mips
|
||||
void setStoredMipFormat(const Element& format);
|
||||
const Element& getStoredMipFormat() const;
|
||||
|
||||
// Manually allocate the mips down until the specified maxMip
|
||||
// this is just allocating the sysmem version of it
|
||||
// in case autoGen is on, this doesn't allocate
|
||||
// Explicitely assign mip data for a certain level
|
||||
// If Bytes is NULL then simply allocate the space so mip sysmem can be accessed
|
||||
bool assignStoredMip(uint16 level, const Element& format, Size size, const Byte* bytes);
|
||||
bool assignStoredMipFace(uint16 level, const Element& format, Size size, const Byte* bytes, uint8 face);
|
||||
|
||||
void assignStoredMip(uint16 level, Size size, const Byte* bytes);
|
||||
void assignStoredMipFace(uint16 level, uint8 face, Size size, const Byte* bytes);
|
||||
|
||||
void assignStoredMip(uint16 level, storage::StoragePointer& storage);
|
||||
void assignStoredMipFace(uint16 level, uint8 face, storage::StoragePointer& storage);
|
||||
|
||||
// Access the the sub mips
|
||||
bool isStoredMipFaceAvailable(uint16 level, uint8 face = 0) const { return _storage->isMipAvailable(level, face); }
|
||||
|
|
|
@ -116,9 +116,10 @@ Texture* Texture::unserialize(TextureUsageType usageType, const ktx::KTXUniquePo
|
|||
Sampler());
|
||||
|
||||
// Assing the mips availables
|
||||
tex->setStoredMipFormat(mipFormat);
|
||||
uint16_t level = 0;
|
||||
for (auto& image : srcData->_images) {
|
||||
tex->assignStoredMip(level, mipFormat, image._imageSize, image._bytes);
|
||||
tex->assignStoredMip(level, image._imageSize, image._bytes);
|
||||
level++;
|
||||
}
|
||||
|
||||
|
|
|
@ -108,7 +108,8 @@ const gpu::TexturePointer& TextureCache::getPermutationNormalTexture() {
|
|||
}
|
||||
|
||||
_permutationNormalTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::VEC3, gpu::NUINT8, gpu::RGB), 256, 2));
|
||||
_permutationNormalTexture->assignStoredMip(0, _blueTexture->getTexelFormat(), sizeof(data), data);
|
||||
_permutationNormalTexture->setStoredMipFormat(_permutationNormalTexture->getTexelFormat());
|
||||
_permutationNormalTexture->assignStoredMip(0, sizeof(data), data);
|
||||
}
|
||||
return _permutationNormalTexture;
|
||||
}
|
||||
|
@ -122,7 +123,8 @@ const gpu::TexturePointer& TextureCache::getWhiteTexture() {
|
|||
if (!_whiteTexture) {
|
||||
_whiteTexture = gpu::TexturePointer(gpu::Texture::createStrict(gpu::Element::COLOR_RGBA_32, 1, 1));
|
||||
_whiteTexture->setSource("TextureCache::_whiteTexture");
|
||||
_whiteTexture->assignStoredMip(0, _whiteTexture->getTexelFormat(), sizeof(OPAQUE_WHITE), OPAQUE_WHITE);
|
||||
_whiteTexture->setStoredMipFormat(_whiteTexture->getTexelFormat());
|
||||
_whiteTexture->assignStoredMip(0, sizeof(OPAQUE_WHITE), OPAQUE_WHITE);
|
||||
}
|
||||
return _whiteTexture;
|
||||
}
|
||||
|
@ -131,7 +133,8 @@ const gpu::TexturePointer& TextureCache::getGrayTexture() {
|
|||
if (!_grayTexture) {
|
||||
_grayTexture = gpu::TexturePointer(gpu::Texture::createStrict(gpu::Element::COLOR_RGBA_32, 1, 1));
|
||||
_grayTexture->setSource("TextureCache::_grayTexture");
|
||||
_grayTexture->assignStoredMip(0, _grayTexture->getTexelFormat(), sizeof(OPAQUE_GRAY), OPAQUE_GRAY);
|
||||
_grayTexture->setStoredMipFormat(_grayTexture->getTexelFormat());
|
||||
_grayTexture->assignStoredMip(0, sizeof(OPAQUE_GRAY), OPAQUE_GRAY);
|
||||
}
|
||||
return _grayTexture;
|
||||
}
|
||||
|
@ -140,7 +143,8 @@ const gpu::TexturePointer& TextureCache::getBlueTexture() {
|
|||
if (!_blueTexture) {
|
||||
_blueTexture = gpu::TexturePointer(gpu::Texture::createStrict(gpu::Element::COLOR_RGBA_32, 1, 1));
|
||||
_blueTexture->setSource("TextureCache::_blueTexture");
|
||||
_blueTexture->assignStoredMip(0, _blueTexture->getTexelFormat(), sizeof(OPAQUE_BLUE), OPAQUE_BLUE);
|
||||
_blueTexture->setStoredMipFormat(_blueTexture->getTexelFormat());
|
||||
_blueTexture->assignStoredMip(0, sizeof(OPAQUE_BLUE), OPAQUE_BLUE);
|
||||
}
|
||||
return _blueTexture;
|
||||
}
|
||||
|
@ -149,7 +153,8 @@ const gpu::TexturePointer& TextureCache::getBlackTexture() {
|
|||
if (!_blackTexture) {
|
||||
_blackTexture = gpu::TexturePointer(gpu::Texture::createStrict(gpu::Element::COLOR_RGBA_32, 1, 1));
|
||||
_blackTexture->setSource("TextureCache::_blackTexture");
|
||||
_blackTexture->assignStoredMip(0, _blackTexture->getTexelFormat(), sizeof(OPAQUE_BLACK), OPAQUE_BLACK);
|
||||
_blackTexture->setStoredMipFormat(_blackTexture->getTexelFormat());
|
||||
_blackTexture->assignStoredMip(0, sizeof(OPAQUE_BLACK), OPAQUE_BLACK);
|
||||
}
|
||||
return _blackTexture;
|
||||
}
|
||||
|
|
|
@ -96,7 +96,7 @@ gpu::Texture* cacheTexture(const std::string& name, gpu::Texture* srcTexture, bo
|
|||
// Prepare cache directory
|
||||
QString path("hifi_ktx/");
|
||||
QFileInfo originalFileInfo(path);
|
||||
QString docsLocation = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
|
||||
QString docsLocation = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
|
||||
path = docsLocation + "/" + path;
|
||||
QFileInfo info(path);
|
||||
if (!info.absoluteDir().exists()) {
|
||||
|
@ -262,7 +262,7 @@ const QImage& image, bool isLinear, bool doCompress) {
|
|||
|
||||
#define CPU_MIPMAPS 1
|
||||
|
||||
void generateMips(gpu::Texture* texture, QImage& image, gpu::Element formatMip, bool fastResize) {
|
||||
void generateMips(gpu::Texture* texture, QImage& image, bool fastResize) {
|
||||
#if CPU_MIPMAPS
|
||||
PROFILE_RANGE(resource_parse, "generateMips");
|
||||
auto numMips = texture->evalNumMips();
|
||||
|
@ -270,10 +270,10 @@ void generateMips(gpu::Texture* texture, QImage& image, gpu::Element formatMip,
|
|||
QSize mipSize(texture->evalMipWidth(level), texture->evalMipHeight(level));
|
||||
if (fastResize) {
|
||||
image = image.scaled(mipSize);
|
||||
texture->assignStoredMip(level, formatMip, image.byteCount(), image.constBits());
|
||||
texture->assignStoredMip(level, image.byteCount(), image.constBits());
|
||||
} else {
|
||||
QImage mipImage = image.scaled(mipSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||
texture->assignStoredMip(level, formatMip, mipImage.byteCount(), mipImage.constBits());
|
||||
texture->assignStoredMip(level, mipImage.byteCount(), mipImage.constBits());
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
@ -281,14 +281,14 @@ void generateMips(gpu::Texture* texture, QImage& image, gpu::Element formatMip,
|
|||
#endif
|
||||
}
|
||||
|
||||
void generateFaceMips(gpu::Texture* texture, QImage& image, gpu::Element formatMip, uint8 face) {
|
||||
void generateFaceMips(gpu::Texture* texture, QImage& image, uint8 face) {
|
||||
#if CPU_MIPMAPS
|
||||
PROFILE_RANGE(resource_parse, "generateFaceMips");
|
||||
auto numMips = texture->evalNumMips();
|
||||
for (uint16 level = 1; level < numMips; ++level) {
|
||||
QSize mipSize(texture->evalMipWidth(level), texture->evalMipHeight(level));
|
||||
QImage mipImage = image.scaled(mipSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||
texture->assignStoredMipFace(level, formatMip, mipImage.byteCount(), mipImage.constBits(), face);
|
||||
texture->assignStoredMipFace(level, face, mipImage.byteCount(), mipImage.constBits());
|
||||
}
|
||||
#else
|
||||
texture->autoGenerateMips(-1);
|
||||
|
@ -322,11 +322,11 @@ gpu::Texture* TextureUsage::process2DTextureColorFromImage(const QImage& srcImag
|
|||
}
|
||||
}
|
||||
theTexture->setUsage(usage.build());
|
||||
|
||||
theTexture->assignStoredMip(0, formatMip, image.byteCount(), image.constBits());
|
||||
theTexture->setStoredMipFormat(formatMip);
|
||||
theTexture->assignStoredMip(0, image.byteCount(), image.constBits());
|
||||
|
||||
if (generateMips) {
|
||||
::generateMips(theTexture, image, formatMip, false);
|
||||
::generateMips(theTexture, image, false);
|
||||
}
|
||||
|
||||
theTexture = cacheTexture(std::to_string((size_t) theTexture), theTexture);
|
||||
|
@ -373,8 +373,9 @@ gpu::Texture* TextureUsage::createNormalTextureFromNormalImage(const QImage& src
|
|||
|
||||
theTexture = (gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)));
|
||||
theTexture->setSource(srcImageName);
|
||||
theTexture->assignStoredMip(0, formatMip, image.byteCount(), image.constBits());
|
||||
generateMips(theTexture, image, formatMip, true);
|
||||
theTexture->setStoredMipFormat(formatMip);
|
||||
theTexture->assignStoredMip(0, image.byteCount(), image.constBits());
|
||||
generateMips(theTexture, image, true);
|
||||
|
||||
theTexture = cacheTexture(std::to_string((size_t) theTexture), theTexture);
|
||||
}
|
||||
|
@ -461,8 +462,9 @@ gpu::Texture* TextureUsage::createNormalTextureFromBumpImage(const QImage& srcIm
|
|||
|
||||
theTexture = (gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)));
|
||||
theTexture->setSource(srcImageName);
|
||||
theTexture->assignStoredMip(0, formatMip, image.byteCount(), image.constBits());
|
||||
generateMips(theTexture, image, formatMip, true);
|
||||
theTexture->setStoredMipFormat(formatMip);
|
||||
theTexture->assignStoredMip(0, image.byteCount(), image.constBits());
|
||||
generateMips(theTexture, image, true);
|
||||
|
||||
theTexture = cacheTexture(std::to_string((size_t) theTexture), theTexture);
|
||||
}
|
||||
|
@ -496,8 +498,9 @@ gpu::Texture* TextureUsage::createRoughnessTextureFromImage(const QImage& srcIma
|
|||
|
||||
theTexture = (gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)));
|
||||
theTexture->setSource(srcImageName);
|
||||
theTexture->assignStoredMip(0, formatMip, image.byteCount(), image.constBits());
|
||||
generateMips(theTexture, image, formatMip, true);
|
||||
theTexture->setStoredMipFormat(formatMip);
|
||||
theTexture->assignStoredMip(0, image.byteCount(), image.constBits());
|
||||
generateMips(theTexture, image, true);
|
||||
|
||||
theTexture = cacheTexture(std::to_string((size_t) theTexture), theTexture);
|
||||
}
|
||||
|
@ -535,8 +538,9 @@ gpu::Texture* TextureUsage::createRoughnessTextureFromGlossImage(const QImage& s
|
|||
|
||||
theTexture = (gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)));
|
||||
theTexture->setSource(srcImageName);
|
||||
theTexture->assignStoredMip(0, formatMip, image.byteCount(), image.constBits());
|
||||
generateMips(theTexture, image, formatMip, true);
|
||||
theTexture->setStoredMipFormat(formatMip);
|
||||
theTexture->assignStoredMip(0, image.byteCount(), image.constBits());
|
||||
generateMips(theTexture, image, true);
|
||||
|
||||
theTexture = cacheTexture(std::to_string((size_t) theTexture), theTexture);
|
||||
}
|
||||
|
@ -571,8 +575,9 @@ gpu::Texture* TextureUsage::createMetallicTextureFromImage(const QImage& srcImag
|
|||
|
||||
theTexture = (gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)));
|
||||
theTexture->setSource(srcImageName);
|
||||
theTexture->assignStoredMip(0, formatMip, image.byteCount(), image.constBits());
|
||||
generateMips(theTexture, image, formatMip, true);
|
||||
theTexture->setStoredMipFormat(formatMip);
|
||||
theTexture->assignStoredMip(0, image.byteCount(), image.constBits());
|
||||
generateMips(theTexture, image, true);
|
||||
|
||||
theTexture = cacheTexture(std::to_string((size_t) theTexture), theTexture);
|
||||
}
|
||||
|
@ -886,11 +891,12 @@ gpu::Texture* TextureUsage::processCubeTextureColorFromImage(const QImage& srcIm
|
|||
if (faces.size() == gpu::Texture::NUM_FACES_PER_TYPE[gpu::Texture::TEX_CUBE]) {
|
||||
theTexture = gpu::Texture::createCube(formatGPU, faces[0].width(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR, gpu::Sampler::WRAP_CLAMP));
|
||||
theTexture->setSource(srcImageName);
|
||||
theTexture->setStoredMipFormat(formatMip);
|
||||
int f = 0;
|
||||
for (auto& face : faces) {
|
||||
theTexture->assignStoredMipFace(0, formatMip, face.byteCount(), face.constBits(), f);
|
||||
theTexture->assignStoredMipFace(0, f, face.byteCount(), face.constBits());
|
||||
if (generateMips) {
|
||||
generateFaceMips(theTexture, face, formatMip, f);
|
||||
generateFaceMips(theTexture, face, f);
|
||||
}
|
||||
f++;
|
||||
}
|
||||
|
|
|
@ -209,7 +209,8 @@ void Font::read(QIODevice& in) {
|
|||
}
|
||||
_texture = gpu::TexturePointer(gpu::Texture::create2D(formatGPU, image.width(), image.height(),
|
||||
gpu::Sampler(gpu::Sampler::FILTER_MIN_POINT_MAG_LINEAR)));
|
||||
_texture->assignStoredMip(0, formatMip, image.byteCount(), image.constBits());
|
||||
_texture->setStoredMipFormat(formatMip);
|
||||
_texture->assignStoredMip(0, image.byteCount(), image.constBits());
|
||||
}
|
||||
|
||||
void Font::setupGPU() {
|
||||
|
|
|
@ -14,10 +14,13 @@ using namespace storage;
|
|||
|
||||
ViewStoragePointer Storage::createView(size_t viewSize, size_t offset) const {
|
||||
auto selfSize = size();
|
||||
if ((viewSize + offset) > selfSize) {
|
||||
throw std::runtime_error("Unable to map file");
|
||||
if (0 == viewSize) {
|
||||
viewSize = selfSize;
|
||||
}
|
||||
return ViewStoragePointer(new ViewStorage(viewSize, data() + offset));
|
||||
if ((viewSize + offset) > selfSize) {
|
||||
throw std::runtime_error("Invalid mapping range");
|
||||
}
|
||||
return ViewStoragePointer(new ViewStorage(shared_from_this(), viewSize, data() + offset));
|
||||
}
|
||||
|
||||
MemoryStoragePointer Storage::toMemoryStorage() const {
|
||||
|
|
|
@ -18,22 +18,27 @@
|
|||
|
||||
namespace storage {
|
||||
class Storage;
|
||||
using StoragePointer = std::unique_ptr<Storage>;
|
||||
using StoragePointer = std::shared_ptr<const Storage>;
|
||||
class MemoryStorage;
|
||||
using MemoryStoragePointer = std::unique_ptr<MemoryStorage>;
|
||||
using MemoryStoragePointer = std::shared_ptr<const MemoryStorage>;
|
||||
class FileStorage;
|
||||
using FileStoragePointer = std::unique_ptr<FileStorage>;
|
||||
using FileStoragePointer = std::shared_ptr<const FileStorage>;
|
||||
class ViewStorage;
|
||||
using ViewStoragePointer = std::unique_ptr<ViewStorage>;
|
||||
using ViewStoragePointer = std::shared_ptr<const ViewStorage>;
|
||||
|
||||
class Storage {
|
||||
class Storage : public std::enable_shared_from_this<Storage> {
|
||||
public:
|
||||
virtual ~Storage() {}
|
||||
virtual const uint8_t* data() const = 0;
|
||||
virtual size_t size() const = 0;
|
||||
ViewStoragePointer createView(size_t size, size_t offset = 0) const;
|
||||
|
||||
ViewStoragePointer createView(size_t size = 0, size_t offset = 0) const;
|
||||
FileStoragePointer toFileStorage(const QString& filename) const;
|
||||
MemoryStoragePointer toMemoryStorage() const;
|
||||
|
||||
// Aliases to prevent having to re-write a ton of code
|
||||
inline size_t getSize() const { return size(); }
|
||||
inline const uint8_t* readData() const { return data(); }
|
||||
};
|
||||
|
||||
class MemoryStorage : public Storage {
|
||||
|
@ -63,10 +68,11 @@ namespace storage {
|
|||
|
||||
class ViewStorage : public Storage {
|
||||
public:
|
||||
ViewStorage(size_t size, const uint8_t* data) : _size(size), _data(data) {}
|
||||
ViewStorage(const storage::StoragePointer& owner, size_t size, const uint8_t* data) : _owner(owner), _size(size), _data(data) {}
|
||||
const uint8_t* data() const override { return _data; }
|
||||
size_t size() const override { return _size; }
|
||||
private:
|
||||
const storage::StoragePointer _owner;
|
||||
const size_t _size;
|
||||
const uint8_t* _data;
|
||||
};
|
||||
|
|
|
@ -10,7 +10,7 @@ setup_hifi_project(Quick Gui OpenGL)
|
|||
set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "Tests/manual-tests/")
|
||||
|
||||
# link in the shared libraries
|
||||
link_hifi_libraries(shared octree gl gpu gpu-gl render model model-networking networking render-utils fbx entities entities-renderer animation audio avatars script-engine physics)
|
||||
link_hifi_libraries(shared octree ktx gl gpu gpu-gl render model model-networking networking render-utils fbx entities entities-renderer animation audio avatars script-engine physics)
|
||||
|
||||
package_libraries_for_deployment()
|
||||
|
||||
|
|
Loading…
Reference in a new issue