From 1ff91219a8d7b726289f880af62c4212512156ed Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Fri, 16 Sep 2016 14:36:24 -0700 Subject: [PATCH] Fix strange artifacts in skybox --- .../src/gpu/gl45/GL45BackendTexture.cpp | 20 ++++++++++++++++++- libraries/gpu/src/gpu/Texture.h | 4 ++++ libraries/model/src/model/TextureMap.cpp | 18 +++++++++++------ libraries/model/src/model/TextureMap.h | 2 +- .../render-utils/src/SubsurfaceScattering.cpp | 3 +++ 5 files changed, 39 insertions(+), 8 deletions(-) diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp index b6eae6e611..d967a1a7a2 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp @@ -92,6 +92,11 @@ SparseInfo::SparseInfo(GL45Texture& texture) } void SparseInfo::maybeMakeSparse() { + // Don't enable sparse for objects with explicitly managed mip levels + if (!_texture._gpuObject.isAutogenerateMips()) { + qCDebug(gpugl45logging) << "Don't enable sparse texture for explicitly generated mipmaps on texture " << _texture._gpuObject.source().c_str(); + return; + } const uvec3 dimensions = _texture._gpuObject.getDimensions(); auto allowedPageDimensions = getPageDimensionsForFormat(_texture._target, _texture._internalFormat); // In order to enable sparse the texture size must be an integer multiple of the page size @@ -100,6 +105,7 @@ void SparseInfo::maybeMakeSparse() { _pageDimensions = allowedPageDimensions[i]; // Is this texture an integer multiple of page dimensions? if (uvec3(0) == (dimensions % _pageDimensions)) { + qCDebug(gpugl45logging) << "Enabling sparse for texture " << _texture._gpuObject.source().c_str(); _sparse = true; break; } @@ -109,12 +115,16 @@ void SparseInfo::maybeMakeSparse() { glTextureParameteri(_texture._id, GL_TEXTURE_SPARSE_ARB, GL_TRUE); glTextureParameteri(_texture._id, GL_VIRTUAL_PAGE_SIZE_INDEX_ARB, _pageDimensionsIndex); } else { - qDebug() << "Texture size " << dimensions.x << " x " << dimensions.y << " is not supported by any sparse page size"; + qCDebug(gpugl45logging) << "Size " << dimensions.x << " x " << dimensions.y << + " is not supported by any sparse page size for texture" << _texture._gpuObject.source().c_str(); } } // This can only be called after we've established our storage size void SparseInfo::update() { + if (!_sparse) { + return; + } glGetTextureParameterIuiv(_texture._id, GL_NUM_SPARSE_LEVELS_ARB, &_maxSparseLevel); _pageBytes = _texture._gpuObject.getTexelFormat().getSize(); _pageBytes *= _pageDimensions.x * _pageDimensions.y * _pageDimensions.z; @@ -282,6 +292,7 @@ void GL45Texture::withPreservedTexture(std::function f) const { } void GL45Texture::generateMips() const { + qDebug() << "Generating mipmaps for " << _gpuObject.source().c_str(); glGenerateTextureMipmap(_id); (void)CHECK_GL_ERROR(); } @@ -435,6 +446,13 @@ void GL45Texture::stripToMip(uint16_t newMinMip) { } } + // If we weren't generating mips before, we need to now that we're stripping down mip levels. + if (!_gpuObject.isAutogenerateMips()) { + qDebug() << "Force mip generation for texture"; + glGenerateTextureMipmap(_id); + } + + uint8_t maxFace = (uint8_t)((_target == GL_TEXTURE_CUBE_MAP) ? GLTexture::CUBE_NUM_FACES : 1); for (uint16_t mip = _minMip; mip < newMinMip; ++mip) { auto mipDimensions = _gpuObject.evalMipDimensions(mip); diff --git a/libraries/gpu/src/gpu/Texture.h b/libraries/gpu/src/gpu/Texture.h index a7ac472922..ae1afcafcb 100755 --- a/libraries/gpu/src/gpu/Texture.h +++ b/libraries/gpu/src/gpu/Texture.h @@ -389,6 +389,8 @@ public: uint16 usedMipLevels() const { return (_maxMip - _minMip) + 1; } + const std::string& source() const { return _source; } + void setSource(const std::string& source) { _source = source; } bool setMinMip(uint16 newMinMip); bool incremementMinMip(uint16 count = 1); @@ -450,6 +452,8 @@ public: const GPUObjectPointer gpuObject {}; protected: + // Not strictly necessary, but incredibly useful for debugging + std::string _source; std::unique_ptr< Storage > _storage; Stamp _stamp = 0; diff --git a/libraries/model/src/model/TextureMap.cpp b/libraries/model/src/model/TextureMap.cpp index 9345124d54..30f176b5a6 100755 --- a/libraries/model/src/model/TextureMap.cpp +++ b/libraries/model/src/model/TextureMap.cpp @@ -176,7 +176,7 @@ void generateFaceMips(gpu::Texture* texture, QImage& image, gpu::Element formatM #endif } -gpu::Texture* TextureUsage::process2DTextureColorFromImage(const QImage& srcImage, bool isLinear, bool doCompress, bool generateMips) { +gpu::Texture* TextureUsage::process2DTextureColorFromImage(const QImage& srcImage, const std::string& srcImageName, bool isLinear, bool doCompress, bool generateMips) { bool validAlpha = false; bool alphaAsMask = true; QImage image = process2DImageColor(srcImage, validAlpha, alphaAsMask); @@ -189,7 +189,7 @@ gpu::Texture* TextureUsage::process2DTextureColorFromImage(const QImage& srcImag defineColorTexelFormats(formatGPU, formatMip, image, isLinear, doCompress); theTexture = (gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR))); - + theTexture->setSource(srcImageName); auto usage = gpu::Texture::Usage::Builder().withColor(); if (validAlpha) { usage.withAlpha(); @@ -210,20 +210,20 @@ gpu::Texture* TextureUsage::process2DTextureColorFromImage(const QImage& srcImag } gpu::Texture* TextureUsage::create2DTextureFromImage(const QImage& srcImage, const std::string& srcImageName) { - return process2DTextureColorFromImage(srcImage, false, false, true); + return process2DTextureColorFromImage(srcImage, srcImageName, false, false, true); } gpu::Texture* TextureUsage::createAlbedoTextureFromImage(const QImage& srcImage, const std::string& srcImageName) { - return process2DTextureColorFromImage(srcImage, false, true, true); + return process2DTextureColorFromImage(srcImage, srcImageName, false, true, true); } gpu::Texture* TextureUsage::createEmissiveTextureFromImage(const QImage& srcImage, const std::string& srcImageName) { - return process2DTextureColorFromImage(srcImage, false, true, true); + return process2DTextureColorFromImage(srcImage, srcImageName, false, true, true); } gpu::Texture* TextureUsage::createLightmapTextureFromImage(const QImage& srcImage, const std::string& srcImageName) { - return process2DTextureColorFromImage(srcImage, false, true, true); + return process2DTextureColorFromImage(srcImage, srcImageName, false, true, true); } @@ -241,6 +241,7 @@ gpu::Texture* TextureUsage::createNormalTextureFromNormalImage(const QImage& src gpu::Element formatMip = gpu::Element(gpu::VEC3, gpu::NUINT8, gpu::RGB); 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); } @@ -324,6 +325,7 @@ gpu::Texture* TextureUsage::createNormalTextureFromBumpImage(const QImage& srcIm gpu::Element formatMip = gpu::Element(gpu::VEC3, gpu::NUINT8, gpu::RGB); 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); } @@ -355,6 +357,7 @@ gpu::Texture* TextureUsage::createRoughnessTextureFromImage(const QImage& srcIma gpu::Element formatMip = gpu::Element(gpu::SCALAR, gpu::NUINT8, gpu::RGB); 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); @@ -392,6 +395,7 @@ gpu::Texture* TextureUsage::createRoughnessTextureFromGlossImage(const QImage& s gpu::Element formatMip = gpu::Element(gpu::SCALAR, gpu::NUINT8, gpu::RGB); 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); @@ -426,6 +430,7 @@ gpu::Texture* TextureUsage::createMetallicTextureFromImage(const QImage& srcImag gpu::Element formatMip = gpu::Element(gpu::SCALAR, gpu::NUINT8, gpu::RGB); 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); @@ -737,6 +742,7 @@ gpu::Texture* TextureUsage::processCubeTextureColorFromImage(const QImage& srcIm // If the 6 faces have been created go on and define the true Texture 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); int f = 0; for (auto& face : faces) { theTexture->assignStoredMipFace(0, formatMip, face.byteCount(), face.constBits(), f); diff --git a/libraries/model/src/model/TextureMap.h b/libraries/model/src/model/TextureMap.h index ac35db2f03..220ee57a97 100755 --- a/libraries/model/src/model/TextureMap.h +++ b/libraries/model/src/model/TextureMap.h @@ -47,7 +47,7 @@ public: static const QImage process2DImageColor(const QImage& srcImage, bool& validAlpha, bool& alphaAsMask); static void defineColorTexelFormats(gpu::Element& formatGPU, gpu::Element& formatMip, const QImage& srcImage, bool isLinear, bool doCompress); - static gpu::Texture* process2DTextureColorFromImage(const QImage& srcImage, bool isLinear, bool doCompress, bool generateMips); + static gpu::Texture* process2DTextureColorFromImage(const QImage& srcImage, const std::string& srcImageName, bool isLinear, bool doCompress, bool generateMips); static gpu::Texture* processCubeTextureColorFromImage(const QImage& srcImage, const std::string& srcImageName, bool isLinear, bool doCompress, bool generateMips, bool generateIrradiance); }; diff --git a/libraries/render-utils/src/SubsurfaceScattering.cpp b/libraries/render-utils/src/SubsurfaceScattering.cpp index f1aec66433..3e4ec50dee 100644 --- a/libraries/render-utils/src/SubsurfaceScattering.cpp +++ b/libraries/render-utils/src/SubsurfaceScattering.cpp @@ -415,6 +415,7 @@ gpu::TexturePointer SubsurfaceScatteringResource::generateScatteringProfile(Rend // const auto pixelFormat = gpu::Element::COLOR_SRGBA_32; const auto pixelFormat = gpu::Element::COLOR_R11G11B10; auto profileMap = gpu::TexturePointer(gpu::Texture::create2D(pixelFormat, PROFILE_RESOLUTION, 1, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR, gpu::Sampler::WRAP_CLAMP))); + profileMap->setSource("Generated Scattering Profile"); diffuseProfileGPU(profileMap, args); return profileMap; } @@ -426,6 +427,7 @@ gpu::TexturePointer SubsurfaceScatteringResource::generatePreIntegratedScatterin const auto pixelFormat = gpu::Element::COLOR_R11G11B10; auto scatteringLUT = gpu::TexturePointer(gpu::Texture::create2D(pixelFormat, TABLE_RESOLUTION, TABLE_RESOLUTION, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR, gpu::Sampler::WRAP_CLAMP))); //diffuseScatter(scatteringLUT); + scatteringLUT->setSource("Generated pre-integrated scattering"); diffuseScatterGPU(profile, scatteringLUT, args); return scatteringLUT; } @@ -433,6 +435,7 @@ gpu::TexturePointer SubsurfaceScatteringResource::generatePreIntegratedScatterin gpu::TexturePointer SubsurfaceScatteringResource::generateScatteringSpecularBeckmann(RenderArgs* args) { const int SPECULAR_RESOLUTION = 256; auto beckmannMap = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_RGBA_32 /*gpu::Element(gpu::SCALAR, gpu::HALF, gpu::RGB)*/, SPECULAR_RESOLUTION, SPECULAR_RESOLUTION, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR, gpu::Sampler::WRAP_CLAMP))); + beckmannMap->setSource("Generated beckmannMap"); computeSpecularBeckmannGPU(beckmannMap, args); return beckmannMap; }