mirror of
https://github.com/JulianGro/overte.git
synced 2025-08-08 05:07:43 +02:00
Fix sparse rectification for small textures
This commit is contained in:
parent
a5e671e0fd
commit
a4b3180271
2 changed files with 37 additions and 56 deletions
|
@ -19,15 +19,6 @@
|
||||||
#include <QBuffer>
|
#include <QBuffer>
|
||||||
#include <QImageReader>
|
#include <QImageReader>
|
||||||
|
|
||||||
|
|
||||||
#if defined(Q_OS_ANDROID)
|
|
||||||
#define CPU_MIPMAPS 0
|
|
||||||
#else
|
|
||||||
#define CPU_MIPMAPS 1
|
|
||||||
#include <nvtt/nvtt.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#include <Finally.h>
|
#include <Finally.h>
|
||||||
#include <Profile.h>
|
#include <Profile.h>
|
||||||
#include <StatTracker.h>
|
#include <StatTracker.h>
|
||||||
|
@ -37,6 +28,12 @@
|
||||||
|
|
||||||
using namespace gpu;
|
using namespace gpu;
|
||||||
|
|
||||||
|
#if defined(Q_OS_ANDROID)
|
||||||
|
#define CPU_MIPMAPS 0
|
||||||
|
#else
|
||||||
|
#define CPU_MIPMAPS 1
|
||||||
|
#include <nvtt/nvtt.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
static const glm::uvec2 SPARSE_PAGE_SIZE(128);
|
static const glm::uvec2 SPARSE_PAGE_SIZE(128);
|
||||||
static const glm::uvec2 MAX_TEXTURE_SIZE(4096);
|
static const glm::uvec2 MAX_TEXTURE_SIZE(4096);
|
||||||
|
@ -51,25 +48,21 @@ static std::atomic<bool> compressNormalTextures { false };
|
||||||
static std::atomic<bool> compressGrayscaleTextures { false };
|
static std::atomic<bool> compressGrayscaleTextures { false };
|
||||||
static std::atomic<bool> compressCubeTextures { false };
|
static std::atomic<bool> compressCubeTextures { false };
|
||||||
|
|
||||||
bool needsSparseRectification(const glm::uvec2& size) {
|
uint rectifyDimension(const uint& dimension) {
|
||||||
// Don't attempt to rectify small textures (textures less than the sparse page size in any dimension)
|
if (dimension < SPARSE_PAGE_SIZE.x) {
|
||||||
if (glm::any(glm::lessThan(size, SPARSE_PAGE_SIZE))) {
|
uint newSize = SPARSE_PAGE_SIZE.x;
|
||||||
return false;
|
while (dimension <= newSize / 2) {
|
||||||
|
newSize /= 2;
|
||||||
|
}
|
||||||
|
return newSize;
|
||||||
|
} else {
|
||||||
|
uint pages = (dimension / SPARSE_PAGE_SIZE.x) + (dimension % SPARSE_PAGE_SIZE.x == 0 ? 0 : 1);
|
||||||
|
return pages * SPARSE_PAGE_SIZE.x;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't rectify textures that are already an exact multiple of sparse page size
|
|
||||||
if (glm::uvec2(0) == (size % SPARSE_PAGE_SIZE)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Texture is not sparse compatible, but is bigger than the sparse page size in both dimensions, rectify!
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::uvec2 rectifyToSparseSize(const glm::uvec2& size) {
|
glm::uvec2 rectifySize(const glm::uvec2& size) {
|
||||||
glm::uvec2 pages = ((size / SPARSE_PAGE_SIZE) + glm::clamp(size % SPARSE_PAGE_SIZE, glm::uvec2(0), glm::uvec2(1)));
|
return { rectifyDimension(size.x), rectifyDimension(size.y) };
|
||||||
glm::uvec2 result = pages * SPARSE_PAGE_SIZE;
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -307,9 +300,12 @@ QImage processSourceImage(const QImage& srcImage, bool cubemap) {
|
||||||
++DECIMATED_TEXTURE_COUNT;
|
++DECIMATED_TEXTURE_COUNT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cubemap && needsSparseRectification(targetSize)) {
|
if (!cubemap) {
|
||||||
++RECTIFIED_TEXTURE_COUNT;
|
auto rectifiedSize = rectifySize(targetSize);
|
||||||
targetSize = rectifyToSparseSize(targetSize);
|
if (rectifiedSize != targetSize) {
|
||||||
|
++RECTIFIED_TEXTURE_COUNT;
|
||||||
|
targetSize = rectifiedSize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DEV_DECIMATE_TEXTURES && glm::all(glm::greaterThanEqual(targetSize / SPARSE_PAGE_SIZE, glm::uvec2(2)))) {
|
if (DEV_DECIMATE_TEXTURES && glm::all(glm::greaterThanEqual(targetSize / SPARSE_PAGE_SIZE, glm::uvec2(2)))) {
|
||||||
|
|
|
@ -163,46 +163,31 @@ class MyTestWindow : public TestWindow {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
extern bool needsSparseRectification(const uvec2& size);
|
extern uvec2 rectifySize(const uvec2& size);
|
||||||
extern uvec2 rectifyToSparseSize(const uvec2& size);
|
|
||||||
|
|
||||||
void testSparseRectify() {
|
void testSparseRectify() {
|
||||||
std::vector<std::pair<uvec2, bool>> NEEDS_SPARSE_TESTS {{
|
std::vector<std::pair<uvec2, uvec2>> SPARSE_SIZE_TESTS {
|
||||||
// Already sparse
|
// Already sparse
|
||||||
{ {1024, 1024 }, false },
|
{ {1024, 1024 }, { 1024, 1024 } },
|
||||||
{ { 128, 128 }, false },
|
{ { 128, 128 }, { 128, 128 } },
|
||||||
// Too small in one dimension
|
// Too small in one dimension
|
||||||
{ { 127, 127 }, false },
|
{ { 127, 127 }, { 128, 128 } },
|
||||||
{ { 1, 1 }, false },
|
{ { 1, 1 }, { 1, 1 } },
|
||||||
{ { 1000, 1 }, false },
|
{ { 1000, 1 }, { 1024, 1 } },
|
||||||
{ { 1024, 1 }, false },
|
{ { 1024, 1 }, { 1024, 1 } },
|
||||||
{ { 100, 100 }, false },
|
{ { 100, 100 }, { 128, 128 } },
|
||||||
// needs rectification
|
{ { 57, 510 }, { 64, 512 } },
|
||||||
{ { 1000, 1000 }, true },
|
|
||||||
{ { 1024, 1000 }, true },
|
|
||||||
} };
|
|
||||||
|
|
||||||
for (const auto& test : NEEDS_SPARSE_TESTS) {
|
|
||||||
const auto& size = test.first;
|
|
||||||
const auto& expected = test.second;
|
|
||||||
auto result = needsSparseRectification(size);
|
|
||||||
Q_ASSERT(expected == result);
|
|
||||||
result = needsSparseRectification(uvec2(size.y, size.x));
|
|
||||||
Q_ASSERT(expected == result);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::pair<uvec2, uvec2>> SPARSE_SIZE_TESTS { {
|
|
||||||
// needs rectification
|
// needs rectification
|
||||||
{ { 1000, 1000 }, { 1024, 1024 } },
|
{ { 1000, 1000 }, { 1024, 1024 } },
|
||||||
{ { 1024, 1000 }, { 1024, 1024 } },
|
{ { 1024, 1000 }, { 1024, 1024 } },
|
||||||
} };
|
};
|
||||||
|
|
||||||
for (const auto& test : SPARSE_SIZE_TESTS) {
|
for (const auto& test : SPARSE_SIZE_TESTS) {
|
||||||
const auto& size = test.first;
|
const auto& size = test.first;
|
||||||
const auto& expected = test.second;
|
const auto& expected = test.second;
|
||||||
auto result = rectifyToSparseSize(size);
|
auto result = rectifySize(size);
|
||||||
Q_ASSERT(expected == result);
|
Q_ASSERT(expected == result);
|
||||||
result = rectifyToSparseSize(uvec2(size.y, size.x));
|
result = rectifySize(uvec2(size.y, size.x));
|
||||||
Q_ASSERT(expected == uvec2(result.y, result.x));
|
Q_ASSERT(expected == uvec2(result.y, result.x));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue