mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-25 17:35:08 +02:00
Merge pull request #8893 from jherico/texture_force_sparse
Changes to texture loading rules
This commit is contained in:
commit
863bf067b7
6 changed files with 134 additions and 13 deletions
|
@ -205,6 +205,12 @@ Item {
|
|||
StatText {
|
||||
text: " Count: " + root.gpuTextures;
|
||||
}
|
||||
StatText {
|
||||
text: " Rectified: " + root.rectifiedTextureCount;
|
||||
}
|
||||
StatText {
|
||||
text: " Decimated: " + root.decimatedTextureCount;
|
||||
}
|
||||
StatText {
|
||||
text: " Sparse Count: " + root.gpuTexturesSparse;
|
||||
visible: 0 != root.gpuSparseTextureEnabled;
|
||||
|
@ -228,6 +234,9 @@ Item {
|
|||
StatText {
|
||||
text: " Count: " + root.gpuTextures;
|
||||
}
|
||||
StatText {
|
||||
text: " Memory: " + root.gpuBufferMemory;
|
||||
}
|
||||
StatText {
|
||||
text: "GL Swapchain Memory: " + root.glContextSwapchainMemory + " MB";
|
||||
}
|
||||
|
|
|
@ -96,6 +96,8 @@ bool Stats::includeTimingRecord(const QString& name) {
|
|||
} \
|
||||
}
|
||||
|
||||
extern std::atomic<size_t> DECIMATED_TEXTURE_COUNT;
|
||||
extern std::atomic<size_t> RECTIFIED_TEXTURE_COUNT;
|
||||
|
||||
void Stats::updateStats(bool force) {
|
||||
if (!force) {
|
||||
|
@ -289,6 +291,7 @@ void Stats::updateStats(bool force) {
|
|||
}
|
||||
|
||||
STAT_UPDATE(gpuBuffers, (int)gpu::Context::getBufferGPUCount());
|
||||
STAT_UPDATE(gpuBufferMemory, (int)BYTES_TO_MB(gpu::Context::getBufferGPUMemoryUsage()));
|
||||
STAT_UPDATE(gpuTextures, (int)gpu::Context::getTextureGPUCount());
|
||||
STAT_UPDATE(gpuTexturesSparse, (int)gpu::Context::getTextureGPUSparseCount());
|
||||
|
||||
|
@ -301,6 +304,8 @@ void Stats::updateStats(bool force) {
|
|||
STAT_UPDATE(gpuTextureSparseMemory, (int)BYTES_TO_MB(gpu::Texture::getTextureGPUSparseMemoryUsage()));
|
||||
STAT_UPDATE(gpuSparseTextureEnabled, gpu::Texture::getEnableSparseTextures() ? 1 : 0);
|
||||
STAT_UPDATE(gpuFreeMemory, (int)BYTES_TO_MB(gpu::Context::getFreeGPUMemory()));
|
||||
STAT_UPDATE(rectifiedTextureCount, (int)RECTIFIED_TEXTURE_COUNT.load());
|
||||
STAT_UPDATE(decimatedTextureCount, (int)DECIMATED_TEXTURE_COUNT.load());
|
||||
|
||||
// Incoming packets
|
||||
QLocale locale(QLocale::English);
|
||||
|
|
|
@ -87,7 +87,10 @@ class Stats : public QQuickItem {
|
|||
STATS_PROPERTY(int, localElements, 0)
|
||||
STATS_PROPERTY(int, localInternal, 0)
|
||||
STATS_PROPERTY(int, localLeaves, 0)
|
||||
STATS_PROPERTY(int, rectifiedTextureCount, 0)
|
||||
STATS_PROPERTY(int, decimatedTextureCount, 0)
|
||||
STATS_PROPERTY(int, gpuBuffers, 0)
|
||||
STATS_PROPERTY(int, gpuBufferMemory, 0)
|
||||
STATS_PROPERTY(int, gpuTextures, 0)
|
||||
STATS_PROPERTY(int, gpuTexturesSparse, 0)
|
||||
STATS_PROPERTY(int, glContextSwapchainMemory, 0)
|
||||
|
@ -186,6 +189,7 @@ signals:
|
|||
void glContextSwapchainMemoryChanged();
|
||||
void qmlTextureMemoryChanged();
|
||||
void gpuBuffersChanged();
|
||||
void gpuBufferMemoryChanged();
|
||||
void gpuTexturesChanged();
|
||||
void gpuTexturesSparseChanged();
|
||||
void gpuTextureMemoryChanged();
|
||||
|
@ -194,6 +198,8 @@ signals:
|
|||
void gpuTextureSparseMemoryChanged();
|
||||
void gpuSparseTextureEnabledChanged();
|
||||
void gpuFreeMemoryChanged();
|
||||
void rectifiedTextureCountChanged();
|
||||
void decimatedTextureCountChanged();
|
||||
|
||||
private:
|
||||
int _recentMaxPackets{ 0 } ; // recent max incoming voxel packets to process
|
||||
|
|
|
@ -102,12 +102,17 @@ float GLTexture::getMemoryPressure() {
|
|||
|
||||
// If no memory limit has been set, use a percentage of the total dedicated memory
|
||||
if (!availableTextureMemory) {
|
||||
#if 0
|
||||
auto totalMemory = getDedicatedMemory();
|
||||
if ((GPU_MEMORY_RESERVE_BYTES + TEXTURE_MEMORY_MIN_BYTES) > totalMemory) {
|
||||
availableTextureMemory = TEXTURE_MEMORY_MIN_BYTES;
|
||||
} else {
|
||||
availableTextureMemory = totalMemory - GPU_MEMORY_RESERVE_BYTES;
|
||||
}
|
||||
#else
|
||||
// Hardcode texture limit for sparse textures at 1 GB for now
|
||||
availableTextureMemory = GPU_MEMORY_RESERVE_BYTES;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Return the consumed texture memory divided by the available texture memory.
|
||||
|
|
|
@ -21,12 +21,59 @@ using namespace gpu;
|
|||
|
||||
// FIXME: Declare this to enable compression
|
||||
//#define COMPRESS_TEXTURES
|
||||
|
||||
static const uvec2 SPARSE_PAGE_SIZE(128);
|
||||
static const uvec2 MAX_TEXTURE_SIZE(4096);
|
||||
bool DEV_DECIMATE_TEXTURES = false;
|
||||
QImage processSourceImage(const QImage& srcImage) {
|
||||
if (DEV_DECIMATE_TEXTURES) {
|
||||
return srcImage.scaled(srcImage.size() * 0.5f);
|
||||
|
||||
bool needsSparseRectification(const uvec2& size) {
|
||||
// Don't attempt to rectify small textures (textures less than the sparse page size in any dimension)
|
||||
if (glm::any(glm::lessThan(size, SPARSE_PAGE_SIZE))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Don't rectify textures that are already an exact multiple of sparse page size
|
||||
if (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;
|
||||
}
|
||||
|
||||
uvec2 rectifyToSparseSize(const uvec2& size) {
|
||||
uvec2 pages = ((size / SPARSE_PAGE_SIZE) + glm::clamp(size % SPARSE_PAGE_SIZE, uvec2(0), uvec2(1)));
|
||||
uvec2 result = pages * SPARSE_PAGE_SIZE;
|
||||
return result;
|
||||
}
|
||||
|
||||
std::atomic<size_t> DECIMATED_TEXTURE_COUNT { 0 };
|
||||
std::atomic<size_t> RECTIFIED_TEXTURE_COUNT { 0 };
|
||||
|
||||
QImage processSourceImage(const QImage& srcImage, bool cubemap) {
|
||||
const uvec2 srcImageSize = toGlm(srcImage.size());
|
||||
uvec2 targetSize = srcImageSize;
|
||||
|
||||
while (glm::any(glm::greaterThan(targetSize, MAX_TEXTURE_SIZE))) {
|
||||
targetSize /= 2;
|
||||
}
|
||||
if (targetSize != srcImageSize) {
|
||||
++DECIMATED_TEXTURE_COUNT;
|
||||
}
|
||||
|
||||
if (!cubemap && needsSparseRectification(targetSize)) {
|
||||
++RECTIFIED_TEXTURE_COUNT;
|
||||
targetSize = rectifyToSparseSize(targetSize);
|
||||
}
|
||||
|
||||
if (DEV_DECIMATE_TEXTURES && glm::all(glm::greaterThanEqual(targetSize / SPARSE_PAGE_SIZE, uvec2(2)))) {
|
||||
targetSize /= 2;
|
||||
}
|
||||
|
||||
if (targetSize != srcImageSize) {
|
||||
qDebug() << "Resizing texture from " << srcImageSize.x << "x" << srcImageSize.y << " to " << targetSize.x << "x" << targetSize.y;
|
||||
return srcImage.scaled(fromGlm(targetSize));
|
||||
}
|
||||
|
||||
return srcImage;
|
||||
}
|
||||
|
||||
|
@ -60,7 +107,7 @@ void TextureMap::setLightmapOffsetScale(float offset, float scale) {
|
|||
}
|
||||
|
||||
const QImage TextureUsage::process2DImageColor(const QImage& srcImage, bool& validAlpha, bool& alphaAsMask) {
|
||||
QImage image = processSourceImage(srcImage);
|
||||
QImage image = processSourceImage(srcImage, false);
|
||||
validAlpha = false;
|
||||
alphaAsMask = true;
|
||||
const uint8 OPAQUE_ALPHA = 255;
|
||||
|
@ -228,7 +275,7 @@ gpu::Texture* TextureUsage::createLightmapTextureFromImage(const QImage& srcImag
|
|||
|
||||
|
||||
gpu::Texture* TextureUsage::createNormalTextureFromNormalImage(const QImage& srcImage, const std::string& srcImageName) {
|
||||
QImage image = processSourceImage(srcImage);
|
||||
QImage image = processSourceImage(srcImage, false);
|
||||
|
||||
if (image.format() != QImage::Format_RGB888) {
|
||||
image = image.convertToFormat(QImage::Format_RGB888);
|
||||
|
@ -262,7 +309,7 @@ double mapComponent(double sobelValue) {
|
|||
}
|
||||
|
||||
gpu::Texture* TextureUsage::createNormalTextureFromBumpImage(const QImage& srcImage, const std::string& srcImageName) {
|
||||
QImage image = processSourceImage(srcImage);
|
||||
QImage image = processSourceImage(srcImage, false);
|
||||
|
||||
if (image.format() != QImage::Format_RGB888) {
|
||||
image = image.convertToFormat(QImage::Format_RGB888);
|
||||
|
@ -334,7 +381,7 @@ gpu::Texture* TextureUsage::createNormalTextureFromBumpImage(const QImage& srcIm
|
|||
}
|
||||
|
||||
gpu::Texture* TextureUsage::createRoughnessTextureFromImage(const QImage& srcImage, const std::string& srcImageName) {
|
||||
QImage image = processSourceImage(srcImage);
|
||||
QImage image = processSourceImage(srcImage, false);
|
||||
if (!image.hasAlphaChannel()) {
|
||||
if (image.format() != QImage::Format_RGB888) {
|
||||
image = image.convertToFormat(QImage::Format_RGB888);
|
||||
|
@ -368,7 +415,7 @@ gpu::Texture* TextureUsage::createRoughnessTextureFromImage(const QImage& srcIma
|
|||
}
|
||||
|
||||
gpu::Texture* TextureUsage::createRoughnessTextureFromGlossImage(const QImage& srcImage, const std::string& srcImageName) {
|
||||
QImage image = processSourceImage(srcImage);
|
||||
QImage image = processSourceImage(srcImage, false);
|
||||
if (!image.hasAlphaChannel()) {
|
||||
if (image.format() != QImage::Format_RGB888) {
|
||||
image = image.convertToFormat(QImage::Format_RGB888);
|
||||
|
@ -406,7 +453,7 @@ gpu::Texture* TextureUsage::createRoughnessTextureFromGlossImage(const QImage& s
|
|||
}
|
||||
|
||||
gpu::Texture* TextureUsage::createMetallicTextureFromImage(const QImage& srcImage, const std::string& srcImageName) {
|
||||
QImage image = processSourceImage(srcImage);
|
||||
QImage image = processSourceImage(srcImage, false);
|
||||
if (!image.hasAlphaChannel()) {
|
||||
if (image.format() != QImage::Format_RGB888) {
|
||||
image = image.convertToFormat(QImage::Format_RGB888);
|
||||
|
@ -699,7 +746,7 @@ const int CubeLayout::NUM_CUBEMAP_LAYOUTS = sizeof(CubeLayout::CUBEMAP_LAYOUTS)
|
|||
gpu::Texture* TextureUsage::processCubeTextureColorFromImage(const QImage& srcImage, const std::string& srcImageName, bool isLinear, bool doCompress, bool generateMips, bool generateIrradiance) {
|
||||
gpu::Texture* theTexture = nullptr;
|
||||
if ((srcImage.width() > 0) && (srcImage.height() > 0)) {
|
||||
QImage image = processSourceImage(srcImage);
|
||||
QImage image = processSourceImage(srcImage, true);
|
||||
if (image.format() != QImage::Format_RGB888) {
|
||||
image = image.convertToFormat(QImage::Format_RGB888);
|
||||
}
|
||||
|
@ -709,7 +756,8 @@ gpu::Texture* TextureUsage::processCubeTextureColorFromImage(const QImage& srcIm
|
|||
defineColorTexelFormats(formatGPU, formatMip, image, isLinear, doCompress);
|
||||
|
||||
// Find the layout of the cubemap in the 2D image
|
||||
int foundLayout = CubeLayout::findLayout(image.width(), image.height());
|
||||
// Use the original image size since processSourceImage may have altered the size / aspect ratio
|
||||
int foundLayout = CubeLayout::findLayout(srcImage.width(), srcImage.height());
|
||||
|
||||
std::vector<QImage> faces;
|
||||
// If found, go extract the faces as separate images
|
||||
|
|
|
@ -164,11 +164,59 @@ class MyTestWindow : public TestWindow {
|
|||
}
|
||||
};
|
||||
|
||||
extern bool needsSparseRectification(const uvec2& size);
|
||||
extern uvec2 rectifyToSparseSize(const uvec2& size);
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
void testSparseRectify() {
|
||||
std::vector<std::pair<uvec2, bool>> NEEDS_SPARSE_TESTS {{
|
||||
// Already sparse
|
||||
{ {1024, 1024 }, false },
|
||||
{ { 128, 128 }, false },
|
||||
// Too small in one dimension
|
||||
{ { 127, 127 }, false },
|
||||
{ { 1, 1 }, false },
|
||||
{ { 1000, 1 }, false },
|
||||
{ { 1024, 1 }, false },
|
||||
{ { 100, 100 }, false },
|
||||
// needs rectification
|
||||
{ { 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
|
||||
{ { 1000, 1000 }, { 1024, 1024 } },
|
||||
{ { 1024, 1000 }, { 1024, 1024 } },
|
||||
} };
|
||||
|
||||
for (const auto& test : SPARSE_SIZE_TESTS) {
|
||||
const auto& size = test.first;
|
||||
const auto& expected = test.second;
|
||||
auto result = rectifyToSparseSize(size);
|
||||
Q_ASSERT(expected == result);
|
||||
result = rectifyToSparseSize(uvec2(size.y, size.x));
|
||||
Q_ASSERT(expected == uvec2(result.y, result.x));
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
testSparseRectify();
|
||||
|
||||
// FIXME this test appears to be broken
|
||||
#if 0
|
||||
QGuiApplication app(argc, argv);
|
||||
MyTestWindow window;
|
||||
app.exec();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue