Changed mip-map handling to use mip/lod levels rather than maximum dimensions of the lod.
Some checks failed
CMake on multiple platforms / build (Release, cl, cl, windows-latest) (push) Has been cancelled
CMake on multiple platforms / build (Release, clang, clang++, macos-latest) (push) Has been cancelled
CMake on multiple platforms / build (Release, clang, clang++, ubuntu-latest) (push) Has been cancelled
CMake on multiple platforms / build (Release, gcc, g++, ubuntu-latest) (push) Has been cancelled

This commit is contained in:
2026-03-17 00:03:12 -07:00
parent d1299ccc13
commit d652d747a2
22 changed files with 150 additions and 241 deletions

View File

@@ -57,7 +57,8 @@ int KRContext::KRENGINE_MAX_PIPELINE_HANDLES = 4000;
int KRContext::KRENGINE_GPU_MEM_MAX = 256000000;
int KRContext::KRENGINE_GPU_MEM_TARGET = 192000000;
int KRContext::KRENGINE_MAX_TEXTURE_DIM = 8192;
int KRContext::KRENGINE_MIN_TEXTURE_DIM = 64;
int KRContext::KRENGINE_TEXTURE_HQ_LOD = 0;
int KRContext::KRENGINE_TEXTURE_LQ_LOD = 4;
// TODO - This should be configured per-scene? Or auto/dynamic?
int KRContext::KRENGINE_PRESTREAM_DISTANCE = 1000.0f;

View File

@@ -65,8 +65,9 @@ public:
static int KRENGINE_GPU_MEM_MAX;
static int KRENGINE_GPU_MEM_TARGET;
static int KRENGINE_MAX_TEXTURE_DIM;
static int KRENGINE_MIN_TEXTURE_DIM;
static int KRENGINE_PRESTREAM_DISTANCE;
static int KRENGINE_TEXTURE_HQ_LOD;
static int KRENGINE_TEXTURE_LQ_LOD;
KRContext(const KrInitializeInfo* initializeInfo);

View File

@@ -89,7 +89,8 @@ void kraken::set_debug_text(const std::string &print_text)
KRContext::KRENGINE_MAX_TEXTURE_DIM = 2048;
KRContext::KRENGINE_MIN_TEXTURE_DIM = 64;
KRContext::KRENGINE_TEXTURE_HQ_LOD = 0;
KRContext::KRENGINE_TEXTURE_LQ_LOD = 4;
KRContext::KRENGINE_PRESTREAM_DISTANCE = 1000.0f;
@@ -105,19 +106,22 @@ void kraken::set_debug_text(const std::string &print_text)
KRContext::KRENGINE_GPU_MEM_MAX = 64000000 * 2;
KRContext::KRENGINE_GPU_MEM_TARGET = 48000000 * 2;
KRContext::KRENGINE_MAX_TEXTURE_DIM = 2048;
KRContext::KRENGINE_MIN_TEXTURE_DIM = 64;
KRContext::KRENGINE_TEXTURE_HQ_LOD = 0;
KRContext::KRENGINE_TEXTURE_LQ_LOD = 4;
} else {
KRContext::KRENGINE_GPU_MEM_MAX = 64000000;
KRContext::KRENGINE_GPU_MEM_TARGET = 48000000;
KRContext::KRENGINE_MAX_TEXTURE_DIM = 2048;
KRContext::KRENGINE_MIN_TEXTURE_DIM = 64;
KRContext::KRENGINE_TEXTURE_HQ_LOD = 0;
KRContext::KRENGINE_TEXTURE_LQ_LOD = 4;
}
*/
#else
KRContext::KRENGINE_GPU_MEM_MAX = 256000000;
KRContext::KRENGINE_GPU_MEM_TARGET = 192000000;
KRContext::KRENGINE_MAX_TEXTURE_DIM = 8192;
KRContext::KRENGINE_MIN_TEXTURE_DIM = 64;
KRContext::KRENGINE_TEXTURE_HQ_LOD = 0;
KRContext::KRENGINE_TEXTURE_LQ_LOD = 4;
KRContext::KRENGINE_PRESTREAM_DISTANCE = 1000.0f;
#endif

View File

@@ -37,8 +37,8 @@
KRTexture::KRTexture(KRContext& context, std::string name) : KRResource(context, name)
{
m_current_lod_max_dim = 0;
m_new_lod_max_dim = 0;
m_current_lod = -1;
m_new_lod = -1;
m_textureMemUsed = 0;
m_newTextureMemUsed = 0;
m_last_frame_used = 0;
@@ -96,8 +96,8 @@ void KRTexture::releaseHandles()
destroyNewHandles();
destroyHandles();
m_current_lod_max_dim = 0;
m_new_lod_max_dim = 0;
m_current_lod = -1;
m_new_lod = -1;
m_handle_lock.clear();
@@ -115,25 +115,24 @@ long KRTexture::getReferencedMemSize()
return 0;
}
void KRTexture::resize(int max_dim)
void KRTexture::resize(int lod)
{
while (m_handle_lock.test_and_set()) {
}; // Spin lock
if (!m_haveNewHandles) {
if (max_dim > 0) {
int target_dim = max_dim;
if (target_dim < (int)m_min_lod_max_dim) target_dim = m_min_lod_max_dim;
if (lod != -1) {
int target_lod = KRMIN(lod, m_lod_count);
if (m_new_lod_max_dim != target_dim || m_handles.empty()) {
if (m_new_lod != target_lod || m_handles.empty()) {
assert(m_newTextureMemUsed == 0);
m_newTextureMemUsed = getMemRequiredForSize(target_dim);
m_newTextureMemUsed = getMemRequiredForLod(target_lod);
getContext().getTextureManager()->memoryChanged(m_newTextureMemUsed);
getContext().getTextureManager()->addMemoryTransferredThisFrame(m_newTextureMemUsed);
if (createGPUTexture(target_dim)) {
m_new_lod_max_dim = target_dim;
if (createGPUTexture(target_lod)) {
m_new_lod = target_lod;
} else {
getContext().getTextureManager()->memoryChanged(-m_newTextureMemUsed);
m_newTextureMemUsed = 0;
@@ -168,14 +167,12 @@ void KRTexture::requestResidency(float lodCoverage, KRTexture::texture_usage_t t
kraken_stream_level KRTexture::getStreamLevel()
{
if (m_current_lod_max_dim == 0) {
if (m_current_lod == -1) {
return kraken_stream_level::STREAM_LEVEL_OUT;
} else if (m_current_lod_max_dim == KRMIN(getContext().KRENGINE_MAX_TEXTURE_DIM, (int)m_max_lod_max_dim)) {
} else if (m_current_lod <= getContext().KRENGINE_TEXTURE_HQ_LOD) {
return kraken_stream_level::STREAM_LEVEL_IN_HQ;
} else if (m_current_lod_max_dim >= KRMAX(getContext().KRENGINE_MIN_TEXTURE_DIM, (int)m_min_lod_max_dim)) {
return kraken_stream_level::STREAM_LEVEL_IN_LQ;
} else {
return kraken_stream_level::STREAM_LEVEL_OUT;
return kraken_stream_level::STREAM_LEVEL_IN_LQ;
}
}
@@ -225,29 +222,34 @@ KRTexture* KRTexture::compress(bool premultiply_alpha)
return NULL;
}
int KRTexture::getCurrentLodMaxDim()
int KRTexture::getLodCount() const
{
return m_current_lod_max_dim;
return m_lod_count;
}
int KRTexture::getNewLodMaxDim()
int KRTexture::getCurrentLodMaxDim()
{
return m_new_lod_max_dim;
if (m_current_lod == -1) {
return 0;
} else {
return getMaxMipMap() >> m_current_lod;
}
}
int KRTexture::getNewLod()
{
return m_new_lod;
}
int KRTexture::getMaxMipMap()
{
return m_max_lod_max_dim;
}
int KRTexture::getMinMipMap()
{
return m_min_lod_max_dim;
hydra::Vector3i size = getDimensions();
return std::max(size.x, std::max(size.y, size.z));
}
bool KRTexture::hasMipmaps()
{
return m_max_lod_max_dim != m_min_lod_max_dim;
return m_lod_count > 0;
}
void KRTexture::_swapHandles()
@@ -259,7 +261,7 @@ void KRTexture::_swapHandles()
m_handles.swap(m_newHandles);
m_textureMemUsed = (long)m_newTextureMemUsed;
m_newTextureMemUsed = 0;
m_current_lod_max_dim = m_new_lod_max_dim;
m_current_lod = m_new_lod;
m_haveNewHandles = false;
}
m_handle_lock.clear();

View File

@@ -52,8 +52,8 @@ public:
long getMemSize();
virtual long getReferencedMemSize();
virtual long getMemRequiredForSize(int max_dim) = 0;
virtual void resize(int max_dim);
virtual long getMemRequiredForLod(int lod) = 0;
virtual void resize(int lod);
long getLastFrameUsed();
@@ -83,13 +83,13 @@ public:
virtual KRTexture* compress(bool premultiply_alpha = false);
int getCurrentLodMaxDim();
int getNewLodMaxDim(); // For use by streamer only
int getNewLod(); // For use by streamer only
int getMaxMipMap();
int getMinMipMap();
bool hasMipmaps();
virtual int getFaceCount() const = 0;
virtual VkFormat getFormat() const = 0;
virtual hydra::Vector3i getDimensions() const = 0;
int getLodCount() const;
kraken_stream_level getStreamLevel();
float getLastFrameLodCoverage() const;
@@ -100,7 +100,7 @@ public:
VkImage getImage(KrDeviceHandle device);
protected:
virtual bool createGPUTexture(int lod_max_dim) = 0;
virtual bool createGPUTexture(int lod) = 0;
void destroyHandles();
void destroyNewHandles();
@@ -120,11 +120,10 @@ protected:
std::atomic_flag m_handle_lock;
int m_current_lod_max_dim;
int m_new_lod_max_dim;
int m_current_lod;
int m_new_lod;
uint32_t m_max_lod_max_dim;
uint32_t m_min_lod_max_dim;
int m_lod_count;
long m_last_frame_used;
float m_last_frame_max_lod_coverage;

View File

@@ -46,24 +46,24 @@ KRTexture2D::~KRTexture2D()
delete m_pData;
}
bool KRTexture2D::createGPUTexture(int lod_max_dim)
bool KRTexture2D::createGPUTexture(int lod)
{
if (m_haveNewHandles) {
return true;
}
Vector3i dimensions = getDimensions();
size_t bufferSize = getMemRequiredForSize(lod_max_dim);
size_t bufferSize = getMemRequiredForLod(lod);
void* buffer = malloc(bufferSize);
if (!getLodData(buffer, lod_max_dim)) {
if (!getLodData(buffer, lod)) {
delete buffer;
return false;
}
bool success = true;
int prev_lod_max_dim = m_new_lod_max_dim;
m_new_lod_max_dim = 0;
int prev_lod = m_new_lod;
m_new_lod = -1;
KRDeviceManager* deviceManager = getContext().getDeviceManager();
@@ -107,7 +107,7 @@ bool KRTexture2D::createGPUTexture(int lod_max_dim)
delete buffer;
if (success) {
m_new_lod_max_dim = prev_lod_max_dim;
m_new_lod = prev_lod;
m_haveNewHandles = true;
} else {
destroyNewHandles();

View File

@@ -48,10 +48,10 @@ public:
virtual bool save(const std::string& path) override;
virtual bool save(mimir::Block& data) override;
virtual bool getLodData(void* buffer, int lod_max_dim) = 0;
virtual bool getLodData(void* buffer, int lod) = 0;
protected:
mimir::Block* m_pData;
bool createGPUTexture(int lod_max_dim) override;
bool createGPUTexture(int lod) override;
};

View File

@@ -51,8 +51,7 @@ KRTextureAnimated::KRTextureAnimated(KRContext& context, std::string name) : KRT
m_frame_count = atoi(name.substr(first_comma_pos + 1, second_comma_pos - first_comma_pos - 1).c_str());
m_frame_rate = (float)atof(name.substr(second_comma_pos + 1).c_str());
m_max_lod_max_dim = 2048;
m_min_lod_max_dim = 64;
m_lod_count = 0;
m_dimensions = Vector2i::Create(0, 0);
for (int i = 0; i < m_frame_count; i++) {
@@ -60,8 +59,7 @@ KRTextureAnimated::KRTextureAnimated(KRContext& context, std::string name) : KRT
if (frame_texture) {
m_dimensions.x = std::max(m_dimensions.x, frame_texture->getDimensions().x);
m_dimensions.y = std::max(m_dimensions.y, frame_texture->getDimensions().y);
if (frame_texture->getMaxMipMap() < (int)m_max_lod_max_dim) m_max_lod_max_dim = frame_texture->getMaxMipMap();
if (frame_texture->getMinMipMap() > (int)m_min_lod_max_dim) m_min_lod_max_dim = frame_texture->getMinMipMap();
m_lod_count = std::max(m_lod_count, frame_texture->getLodCount());
}
}
}
@@ -83,12 +81,12 @@ KRTextureAnimated::~KRTextureAnimated()
}
bool KRTextureAnimated::createGPUTexture(int lod_max_dim)
bool KRTextureAnimated::createGPUTexture(int lod)
{
return true;
}
long KRTextureAnimated::getMemRequiredForSize(int max_dim)
long KRTextureAnimated::getMemRequiredForLod(int lod)
{
return 0; // Memory is allocated by individual frame textures
}
@@ -151,7 +149,7 @@ bool KRTextureAnimated::save(Block& data)
return true; // Animated textures are just references; there are no files to output
}
void KRTextureAnimated::resize(int max_dim)
void KRTextureAnimated::resize(int lod)
{
// Purposely not calling the superclass method
}

View File

@@ -46,19 +46,19 @@ public:
virtual bool save(const std::string& path) override;
virtual bool save(Block& data) override;
virtual long getMemRequiredForSize(int max_dim) override;
virtual long getMemRequiredForLod(int lod) override;
virtual void requestResidency(float lodCoverage, texture_usage_t textureUsage) override;
virtual long getReferencedMemSize() override;
virtual bool isAnimated() override;
virtual void resize(int max_dim) override;
virtual void resize(int lod) override;
virtual int getFaceCount() const override;
virtual VkFormat getFormat() const override;
virtual hydra::Vector3i getDimensions() const override;
private:
bool createGPUTexture(int lod_max_dim) override;
bool createGPUTexture(int lod) override;
float m_frame_rate;
int m_frame_count;

View File

@@ -38,16 +38,14 @@ using namespace hydra;
KRTextureCube::KRTextureCube(KRContext& context, std::string name) : KRTexture(context, name)
{
m_max_lod_max_dim = 2048;
m_min_lod_max_dim = 64;
m_lod_count = 0;
for (int i = 0; i < 6; i++) {
m_textures[i] = NULL;
std::string faceName = getName() + SUFFIXES[i];
m_textures[i] = (KRTexture2D*)getContext().getTextureManager()->getTexture(faceName);
if (m_textures[i]) {
if (m_textures[i]->getMaxMipMap() < (int)m_max_lod_max_dim) m_max_lod_max_dim = m_textures[i]->getMaxMipMap();
if (m_textures[i]->getMinMipMap() > (int)m_min_lod_max_dim) m_min_lod_max_dim = m_textures[i]->getMinMipMap();
m_lod_count = std::max(m_lod_count, m_textures[i]->getLodCount());
} else {
assert(false);
}
@@ -57,14 +55,14 @@ KRTextureCube::KRTextureCube(KRContext& context, std::string name) : KRTexture(c
KRTextureCube::~KRTextureCube()
{}
bool KRTextureCube::createGPUTexture(int lod_max_dim)
bool KRTextureCube::createGPUTexture(int lod)
{
assert(!m_haveNewHandles); // Only allow one resize per frame
bool success = true;
int prev_lod_max_dim = m_new_lod_max_dim;
m_new_lod_max_dim = 0;
int prev_lod = m_new_lod;
m_new_lod = -1;
bool bMipMaps = false;
Vector2i dimensions = Vector2i::Zero();
@@ -95,9 +93,9 @@ bool KRTextureCube::createGPUTexture(int lod_max_dim)
size_t bufferSizes[6] = {};
void* buffers[6] = {};
for (int i = 0; i < 6; i++) {
bufferSizes[i] = getMemRequiredForSize(lod_max_dim);
bufferSizes[i] = getMemRequiredForLod(lod);
buffers[i] = malloc(bufferSizes[i]);
m_textures[i]->getLodData(buffers[i], lod_max_dim);
m_textures[i]->getLodData(buffers[i], lod);
}
KRDeviceManager* deviceManager = getContext().getDeviceManager();
@@ -132,7 +130,7 @@ bool KRTextureCube::createGPUTexture(int lod_max_dim)
m_haveNewHandles = true;
} else {
destroyHandles();
m_new_lod_max_dim = prev_lod_max_dim;
m_new_lod = prev_lod;
}
for (int i = 0; i < 6; i++) {
@@ -144,15 +142,12 @@ bool KRTextureCube::createGPUTexture(int lod_max_dim)
return success;
}
long KRTextureCube::getMemRequiredForSize(int max_dim)
long KRTextureCube::getMemRequiredForLod(int lod)
{
int target_dim = max_dim;
if (target_dim < (int)m_min_lod_max_dim) target_dim = m_min_lod_max_dim;
long memoryRequired = 0;
for (int i = 0; i < 6; i++) {
if (m_textures[i]) {
memoryRequired += m_textures[i]->getMemRequiredForSize(target_dim);
memoryRequired += m_textures[i]->getMemRequiredForLod(lod);
}
}
return memoryRequired;

View File

@@ -44,14 +44,14 @@ public:
virtual bool save(const std::string& path) override;
virtual bool save(mimir::Block& data) override;
virtual long getMemRequiredForSize(int max_dim) override;
virtual long getMemRequiredForLod(int lod) override;
virtual void requestResidency(float lodCoverage, texture_usage_t textureUsage) override;
virtual int getFaceCount() const override;
virtual VkFormat getFormat() const override;
virtual hydra::Vector3i getDimensions() const override;
private:
bool createGPUTexture(int lod_max_dim) override;
bool createGPUTexture(int lod) override;
const char* SUFFIXES[6] = {
"_positive_x",

View File

@@ -82,8 +82,7 @@ KRTextureKTX::KRTextureKTX(KRContext& context, Block* data, std::string name) :
}
}
m_max_lod_max_dim = KRMAX(m_header.pixelWidth, m_header.pixelHeight);
m_min_lod_max_dim = KRMAX(width, height);
m_lod_count = (int)KRMAX(m_header.numberOfMipmapLevels, 1) - 1;
}
KRTextureKTX::KRTextureKTX(KRContext& context, std::string name, unsigned int internal_format, unsigned int base_internal_format, int width, int height, const std::list<Block*>& blocks) : KRTexture2D(context, new Block(), name)
@@ -361,59 +360,43 @@ VkFormat KRTextureKTX::getFormat() const
}
}
long KRTextureKTX::getMemRequiredForSize(int max_dim)
long KRTextureKTX::getMemRequiredForLod(int lod)
{
int target_dim = max_dim;
if (target_dim < (int)m_min_lod_max_dim) target_dim = target_dim;
// Determine how much memory will be consumed
int width = m_header.pixelWidth;
int height = m_header.pixelHeight;
long memoryRequired = 0;
int level = 0;
for (std::list<Block*>::iterator itr = m_blocks.begin(); itr != m_blocks.end(); itr++) {
Block* block = *itr;
if (width <= target_dim && height <= target_dim) {
if (level >= lod) {
memoryRequired += (long)block->getSize();
}
width = width >> 1;
if (width < 1) {
width = 1;
}
height = height >> 1;
if (height < 1) {
height = 1;
}
level++;
}
return memoryRequired;
}
bool KRTextureKTX::getLodData(void* buffer, int lod_max_dim)
bool KRTextureKTX::getLodData(void* buffer, int lod)
{
unsigned char* converted_image = (unsigned char*)buffer;
int target_dim = lod_max_dim;
if (target_dim < (int)m_min_lod_max_dim) target_dim = m_min_lod_max_dim;
int target_lod = KRMIN(lod, m_lod_count);
if (m_blocks.size() == 0) {
return false;
}
// Determine how much memory will be consumed
int width = m_header.pixelWidth;
int height = m_header.pixelHeight;
long memoryRequired = 0;
long memoryTransferred = 0;
// Upload texture data
int destination_level = 0;
int source_level = 0;
int level = 0;
for (std::list<Block*>::iterator itr = m_blocks.begin(); itr != m_blocks.end(); itr++) {
Block* block = *itr;
if (width <= target_dim && height <= target_dim) {
if (level >= target_lod) {
/*
if (width > current_lod_max_dim) {
@@ -440,22 +423,9 @@ bool KRTextureKTX::getLodData(void* buffer, int lod_max_dim)
// return false;
// }
//
destination_level++;
}
if (width <= m_current_lod_max_dim && height <= m_current_lod_max_dim) {
source_level++;
}
width = width >> 1;
if (width < 1) {
width = 1;
}
height = height >> 1;
if (height < 1) {
height = 1;
}
level++;
}
return true;

View File

@@ -43,9 +43,9 @@ public:
virtual ~KRTextureKTX();
virtual std::string getExtension() override;
bool getLodData(void* buffer, int lod_max_dim) override;
bool getLodData(void* buffer, int lod) override;
virtual long getMemRequiredForSize(int max_dim) override;
virtual long getMemRequiredForLod(int lod) override;
virtual hydra::Vector3i getDimensions() const override;
virtual int getFaceCount() const override;
virtual VkFormat getFormat() const override;

View File

@@ -68,8 +68,7 @@ KRTextureKTX2::KRTextureKTX2(KRContext& context, Block* data, std::string name)
if (height < 1) {
height = 1;
}
m_max_lod_max_dim = KRMAX(m_header.pixelWidth, m_header.pixelHeight);
m_min_lod_max_dim = KRMAX(width, height);
m_lod_count = (int)KRMAX(m_header.levelCount, 1) - 1;
}
KRTextureKTX2::~KRTextureKTX2()
@@ -81,59 +80,42 @@ Vector3i KRTextureKTX2::getDimensions() const
return Vector3i::Create(Vector3i::Create(m_header.pixelWidth, m_header.pixelHeight, m_header.pixelDepth));
}
long KRTextureKTX2::getMemRequiredForSize(int max_dim)
long KRTextureKTX2::getMemRequiredForLod(int lod)
{
int target_dim = max_dim;
if (target_dim < (int)m_min_lod_max_dim) target_dim = target_dim;
int target_lod = KRMIN(lod, m_lod_count);
// Determine how much memory will be consumed
int width = m_header.pixelWidth;
int height = m_header.pixelHeight;
long memoryRequired = 0;
int level = 0;
for (__uint32_t level = 0; level < m_header.levelCount; level++) {
KTX2LevelIndex levelIndex;
m_pData->copy(&levelIndex, sizeof(m_header) + sizeof(KTX2LevelIndex) * level, sizeof(KTX2LevelIndex));
if (width <= target_dim && height <= target_dim) {
if (level >= target_lod) {
memoryRequired += (long)levelIndex.byteLength;
}
width = width >> 1;
if (width < 1) {
width = 1;
}
height = height >> 1;
if (height < 1) {
height = 1;
}
level++;
}
return memoryRequired;
}
bool KRTextureKTX2::getLodData(void* buffer, int lod_max_dim)
bool KRTextureKTX2::getLodData(void* buffer, int lod)
{
unsigned char* converted_image = (unsigned char*)buffer;
int target_dim = lod_max_dim;
if (target_dim < (int)m_min_lod_max_dim) target_dim = m_min_lod_max_dim;
int target_lod = KRMIN(lod, m_lod_count);
// Determine how much memory will be consumed
int width = m_header.pixelWidth;
int height = m_header.pixelHeight;
long memoryRequired = 0;
long memoryTransferred = 0;
// Upload texture data
int destination_level = 0;
int source_level = 0;
int level = 0;
for (__uint32_t level = 0; level < m_header.levelCount; level++) {
KTX2LevelIndex levelIndex;
m_pData->copy(&levelIndex, sizeof(m_header) + sizeof(KTX2LevelIndex) * level, sizeof(KTX2LevelIndex));
if (width <= target_dim && height <= target_dim) {
if (level >= target_lod) {
/*
* TODO - Vulkan Refactoring
@@ -150,21 +132,9 @@ bool KRTextureKTX2::getLodData(void* buffer, int lod_max_dim)
// }
//
destination_level++;
}
if (width <= m_current_lod_max_dim && height <= m_current_lod_max_dim) {
source_level++;
}
width = width >> 1;
if (width < 1) {
width = 1;
}
height = height >> 1;
if (height < 1) {
height = 1;
}
level++;
}
return true;

View File

@@ -40,9 +40,9 @@ public:
virtual ~KRTextureKTX2();
virtual std::string getExtension() override;
bool getLodData(void* buffer, int lod_max_dim) override;
bool getLodData(void* buffer, int lod) override;
virtual long getMemRequiredForSize(int max_dim) override;
virtual long getMemRequiredForLod(int lod) override;
virtual hydra::Vector3i getDimensions() const override;
virtual int getFaceCount() const override;
virtual VkFormat getFormat() const override;

View File

@@ -302,13 +302,13 @@ void KRTextureManager::balanceTextureMemory(long& memoryRemaining, long& memoryR
for (auto itr = m_activeTextures_streamer.begin(); itr != m_activeTextures_streamer.end(); itr++) {
KRTexture* texture = (*itr).second;
int min_mip_level = KRMAX(getContext().KRENGINE_MIN_TEXTURE_DIM, texture->getMinMipMap());
long minLodMem = texture->getMemRequiredForSize(min_mip_level);
int min_lod_level = KRMIN(getContext().KRENGINE_TEXTURE_LQ_LOD, texture->getLodCount());
long minLodMem = texture->getMemRequiredForLod(min_lod_level);
memoryRemaining -= minLodMem;
if (memoryRemainingThisFrame > minLodMem && texture->getNewLodMaxDim() < min_mip_level) {
if (memoryRemainingThisFrame > minLodMem && (texture->getNewLod() != -1 || texture->getNewLod() > min_lod_level)) {
memoryRemainingThisFrame -= minLodMem;
texture->resize(min_mip_level);
texture->resize(min_lod_level);
}
}
@@ -331,24 +331,29 @@ void KRTextureManager::balanceTextureMemory(long& memoryRemaining, long& memoryR
}
KRTexture* texture = (*itr).second;
int min_mip_level = KRMAX(getContext().KRENGINE_MIN_TEXTURE_DIM, texture->getMinMipMap());
int max_mip_level = KRMIN(getContext().KRENGINE_MAX_TEXTURE_DIM, texture->getMaxMipMap());
int target_mip_level = (max_mip_level >> mip_drop);
long targetMem = texture->getMemRequiredForSize(target_mip_level);
long additionalMemRequired = targetMem - texture->getMemRequiredForSize(min_mip_level);
int min_lod_level = KRMIN(getContext().KRENGINE_TEXTURE_LQ_LOD, texture->getLodCount());
int target_lod_level = KRMIN(getContext().KRENGINE_TEXTURE_HQ_LOD + mip_drop, texture->getLodCount());
long targetMem = texture->getMemRequiredForLod(target_lod_level);
long additionalMemRequired = targetMem - texture->getMemRequiredForLod(min_lod_level);
memoryRemainingThisMip -= additionalMemRequired;
memoryRemaining -= additionalMemRequired;
if (memoryRemainingThisMip > 0 && memoryRemainingThisFrame > targetMem) {
int current_mip_level = texture->getNewLodMaxDim();
if (current_mip_level == (target_mip_level >> 1) || target_mip_level < current_mip_level) {
int current_lod_level = texture->getNewLod();
if (current_lod_level == (target_lod_level + 1) || target_lod_level > current_lod_level) {
// We are are just one lod level away from the target, or we are reducing the quality.
// Advance directly to the target level.
memoryRemainingThisFrame -= targetMem;
texture->resize(target_mip_level);
} else if (current_mip_level == (target_mip_level >> 2)) {
memoryRemainingThisFrame -= texture->getMemRequiredForSize(target_mip_level >> 1);
texture->resize(target_mip_level >> 1);
} else if (current_mip_level < (target_mip_level >> 2)) {
memoryRemainingThisFrame -= texture->getMemRequiredForSize(target_mip_level >> 2);
texture->resize(target_mip_level >> 2);
texture->resize(target_lod_level);
} else if (current_lod_level == (target_lod_level + 2)) {
// We are two lod levels away from the target.
// Advance to the lod level inbetween.
memoryRemainingThisFrame -= texture->getMemRequiredForLod(target_lod_level + 1);
texture->resize(target_lod_level + 1);
} else if (current_lod_level > (target_lod_level + 2)) {
// We are more than two lod levels away from the target.
// Advance directly to the lod 2 levels away from the target.
memoryRemainingThisFrame -= texture->getMemRequiredForLod(target_lod_level + 2);
texture->resize(target_lod_level + 2);
}
}

View File

@@ -77,8 +77,7 @@ KRTexturePNG::KRTexturePNG(KRContext& context, Block* data, std::string name) :
m_dimensions.x = SWAP_4(pHeader->chunk_IHDR.width);
m_dimensions.y = SWAP_4(pHeader->chunk_IHDR.height);
m_max_lod_max_dim = m_dimensions.x > m_dimensions.y ? m_dimensions.x : m_dimensions.y;
m_min_lod_max_dim = m_max_lod_max_dim; // Mipmaps not yet supported for PNG images
m_lod_count = 0; // Mipmaps not yet supported for PNG images
switch (pHeader->chunk_IHDR.colorType) {
case 0:
// greyscale
@@ -113,9 +112,9 @@ KRTexturePNG::~KRTexturePNG()
}
bool KRTexturePNG::getLodData(void* buffer, int lod_max_dim)
bool KRTexturePNG::getLodData(void* buffer, int lod)
{
unsigned char* converted_image = (unsigned char*)buffer;
unsigned char* converted_image = (unsigned char*)buffer;
// TODO - Vulkan Refactoring - Perhaps it would be more efficient to reformat the color channels during the copy to the staging buffer.
m_pData->lock();
PNG_HEADER* pHeader = (PNG_HEADER*)m_pData->getStart();
@@ -158,7 +157,7 @@ KRTexture* KRTexturePNG::compress(bool premultiply_alpha)
}
#endif
long KRTexturePNG::getMemRequiredForSize(int max_dim)
long KRTexturePNG::getMemRequiredForLod(int lod)
{
return m_imageSize;
}

View File

@@ -42,13 +42,13 @@ public:
virtual ~KRTexturePNG();
virtual std::string getExtension() override;
bool getLodData(void* buffer, int lod_max_dim) override;
bool getLodData(void* buffer, int lod) override;
#if !TARGET_OS_IPHONE && !defined(ANDROID)
virtual KRTexture* compress(bool premultiply_alpha = false) override;
#endif
virtual long getMemRequiredForSize(int max_dim) override;
virtual long getMemRequiredForLod(int lod) override;
virtual hydra::Vector3i getDimensions() const override;
virtual VkFormat getFormat() const override;
virtual int getFaceCount() const override;

View File

@@ -172,39 +172,27 @@ VkFormat KRTexturePVR::getFormat() const
}
}
long KRTexturePVR::getMemRequiredForSize(int max_dim)
long KRTexturePVR::getMemRequiredForLod(int lod)
{
int target_dim = max_dim;
if (target_dim < (int)m_min_lod_max_dim) target_dim = target_dim;
// Determine how much memory will be consumed
int width = m_iWidth;
int height = m_iHeight;
long memoryRequired = 0;
int level = 0;
for (std::list<Block*>::iterator itr = m_blocks.begin(); itr != m_blocks.end(); itr++) {
Block* block = *itr;
if (width <= target_dim && height <= target_dim) {
if (level >= lod) {
memoryRequired += (long)block->getSize();
}
width = width >> 1;
if (width < 1) {
width = 1;
}
height = height >> 1;
if (height < 1) {
height = 1;
}
level++;
}
return memoryRequired;
}
bool KRTexturePVR::getLodData(void* buffer, int lod_max_dim)
bool KRTexturePVR::getLodData(void* buffer, int lod)
{
int target_dim = lod_max_dim;
if (target_dim < (int)m_min_lod_max_dim) target_dim = m_min_lod_max_dim;
int target_lod = KRMIN(lod, m_lod_count);
if (m_blocks.size() == 0) {
return false;
@@ -217,19 +205,10 @@ bool KRTexturePVR::getLodData(void* buffer, int lod_max_dim)
long memoryTransferred = 0;
// Upload texture data
int destination_level = 0;
int source_level = 0;
int level = 0;
for (std::list<Block*>::iterator itr = m_blocks.begin(); itr != m_blocks.end(); itr++) {
Block* block = *itr;
if (width <= target_dim && height <= target_dim) {
/*
if (width > current_lod_max_dim) {
current_lod_max_dim = width;
}
if (height > current_lod_max_dim) {
current_lod_max_dim = height;
}
*/
if (level >= target_lod) {
block->lock();
/*
@@ -246,22 +225,9 @@ bool KRTexturePVR::getLodData(void* buffer, int lod_max_dim)
// return false;
// }
//
destination_level++;
}
if (width <= m_current_lod_max_dim && height <= m_current_lod_max_dim) {
source_level++;
}
width = width >> 1;
if (width < 1) {
width = 1;
}
height = height >> 1;
if (height < 1) {
height = 1;
}
level++;
}
return true;

View File

@@ -40,9 +40,9 @@ public:
virtual ~KRTexturePVR();
virtual std::string getExtension() override;
bool getLodData(void* buffer, int lod_max_dim) override;
bool getLodData(void* buffer, int lod) override;
virtual long getMemRequiredForSize(int max_dim) override;
virtual long getMemRequiredForLod(int lod) override;
virtual hydra::Vector3i getDimensions() const override;
virtual VkFormat getFormat() const override;
virtual int getFaceCount() const override;

View File

@@ -79,8 +79,7 @@ KRTextureTGA::KRTextureTGA(KRContext& context, Block* data, std::string name) :
m_dimensions.x = pHeader->width;
m_dimensions.y = pHeader->height;
m_max_lod_max_dim = pHeader->width > pHeader->height ? pHeader->width : pHeader->height;
m_min_lod_max_dim = m_max_lod_max_dim; // Mipmaps not yet supported for TGA images
m_lod_count = 0; // Mipmaps not yet supported for TGA images
switch (pHeader->imagetype) {
case 2: // rgb
case 10: // rgb + rle
@@ -118,7 +117,7 @@ KRTextureTGA::~KRTextureTGA()
}
bool KRTextureTGA::getLodData(void* buffer, int lod_max_dim)
bool KRTextureTGA::getLodData(void* buffer, int lod)
{
unsigned char* converted_image = (unsigned char*)buffer;
@@ -338,7 +337,7 @@ KRTexture* KRTextureTGA::compress(bool premultiply_alpha)
}
#endif
long KRTextureTGA::getMemRequiredForSize(int max_dim)
long KRTextureTGA::getMemRequiredForLod(int lod)
{
return m_imageSize;
}

View File

@@ -42,13 +42,13 @@ public:
virtual ~KRTextureTGA();
virtual std::string getExtension() override;
bool getLodData(void* buffer, int lod_max_dim) override;
bool getLodData(void* buffer, int lod) override;
#if !TARGET_OS_IPHONE && !defined(ANDROID)
virtual KRTexture* compress(bool premultiply_alpha = false) override;
#endif
virtual long getMemRequiredForSize(int max_dim) override;
virtual long getMemRequiredForLod(int lod) override;
virtual hydra::Vector3i getDimensions() const override;
virtual VkFormat getFormat() const override;
virtual int getFaceCount() const override;