diff --git a/filament/backend/include/backend/DriverEnums.h b/filament/backend/include/backend/DriverEnums.h index b998f6a96f..4c85f50e88 100644 --- a/filament/backend/include/backend/DriverEnums.h +++ b/filament/backend/include/backend/DriverEnums.h @@ -640,6 +640,10 @@ enum class TextureCubemapFace : uint8_t { NEGATIVE_Z = 5, //!< -z face }; +inline constexpr int operator +(TextureCubemapFace rhs) noexcept { + return int(rhs); +} + //! Face offsets for all faces of a cubemap struct FaceOffsets { using size_type = size_t; diff --git a/filament/backend/include/backend/TargetBufferInfo.h b/filament/backend/include/backend/TargetBufferInfo.h index c43df55160..a2f30d4539 100644 --- a/filament/backend/include/backend/TargetBufferInfo.h +++ b/filament/backend/include/backend/TargetBufferInfo.h @@ -22,38 +22,19 @@ #include -namespace filament { -namespace backend { +namespace filament::backend { //! \privatesection -class TargetBufferInfo { -public: - // ctor for 2D textures - TargetBufferInfo(Handle h, uint8_t level = 0) noexcept // NOLINT(google-explicit-constructor) - : handle(h), level(level) { } - // ctor for cubemaps - TargetBufferInfo(Handle h, uint8_t level, TextureCubemapFace face) noexcept - : handle(h), level(level), face(face) { } - // ctor for 3D textures - TargetBufferInfo(Handle h, uint8_t level, uint16_t layer) noexcept - : handle(h), level(level), layer(layer) { } - - explicit TargetBufferInfo(TextureCubemapFace face) noexcept : face(face) {} - - explicit TargetBufferInfo(uint16_t layer) noexcept : layer(layer) {} - +struct TargetBufferInfo { // texture to be used as render target Handle handle; + // level to be used uint8_t level = 0; - union { - // face if texture is a cubemap - TextureCubemapFace face; - // for 3D textures - uint16_t layer = 0; - }; - TargetBufferInfo() noexcept { } + + // for cubemaps and 3D textures. See TextureCubemapFace for the face->layer mapping + uint16_t layer = 0; }; class MRT { @@ -96,13 +77,12 @@ public: } // this is here for backward compatibility - MRT(Handle h, uint8_t level, uint16_t layer) noexcept - : mInfos{{ h, level, layer }} { + MRT(Handle handle, uint8_t level, uint16_t layer) noexcept + : mInfos{{ handle, level, layer }} { } }; -} // namespace backend -} // namespace filament +} // namespace filament::backend #if !defined(NDEBUG) utils::io::ostream& operator<<(utils::io::ostream& out, const filament::backend::TargetBufferInfo& tbi); diff --git a/filament/backend/src/opengl/GLUtils.h b/filament/backend/src/opengl/GLUtils.h index 1eacc04880..4278845a74 100644 --- a/filament/backend/src/opengl/GLUtils.h +++ b/filament/backend/src/opengl/GLUtils.h @@ -168,8 +168,9 @@ constexpr inline GLenum getComponentType(backend::ElementType type) noexcept { } } -constexpr inline GLenum getCubemapTarget(backend::TextureCubemapFace face) noexcept { - return GL_TEXTURE_CUBE_MAP_POSITIVE_X + GLenum(face); +constexpr inline GLenum getCubemapTarget(uint16_t layer) noexcept { + assert_invariant(layer <= 5); + return GL_TEXTURE_CUBE_MAP_POSITIVE_X + layer; } constexpr inline GLenum getWrapMode(backend::SamplerWrapMode mode) noexcept { diff --git a/filament/backend/src/opengl/OpenGLDriver.cpp b/filament/backend/src/opengl/OpenGLDriver.cpp index fc704c6726..7eb44d5666 100644 --- a/filament/backend/src/opengl/OpenGLDriver.cpp +++ b/filament/backend/src/opengl/OpenGLDriver.cpp @@ -785,7 +785,7 @@ void OpenGLDriver::framebufferTexture(backend::TargetBufferInfo const& binfo, // note: multi-sampled textures can't have mipmaps break; case SamplerType::SAMPLER_CUBEMAP: - target = getCubemapTarget(binfo.face); + target = getCubemapTarget(binfo.layer); // note: cubemaps can't be multi-sampled break; default: @@ -1912,9 +1912,9 @@ void OpenGLDriver::setTextureData(GLTexture* t, bindTexture(OpenGLContext::MAX_TEXTURE_UNIT_COUNT - 1, t); gl.activeTexture(OpenGLContext::MAX_TEXTURE_UNIT_COUNT - 1); FaceOffsets const& offsets = *faceOffsets; -#pragma nounroll + UTILS_NOUNROLL for (size_t face = 0; face < 6; face++) { - GLenum target = getCubemapTarget(TextureCubemapFace(face)); + GLenum target = getCubemapTarget(face); glTexSubImage2D(target, GLint(level), 0, 0, width, height, glFormat, glType, static_cast(p.buffer) + offsets[face]); @@ -1997,9 +1997,9 @@ void OpenGLDriver::setCompressedTextureData(GLTexture* t, uint32_t level, bindTexture(OpenGLContext::MAX_TEXTURE_UNIT_COUNT - 1, t); gl.activeTexture(OpenGLContext::MAX_TEXTURE_UNIT_COUNT - 1); FaceOffsets const& offsets = *faceOffsets; -#pragma nounroll + UTILS_NOUNROLL for (size_t face = 0; face < 6; face++) { - GLenum target = getCubemapTarget(TextureCubemapFace(face)); + GLenum target = getCubemapTarget(face); glCompressedTexSubImage2D(target, GLint(level), 0, 0, width, height, t->gl.internalFormat, imageSize, static_cast(p.buffer) + offsets[face]); diff --git a/filament/backend/src/opengl/OpenGLDriver.h b/filament/backend/src/opengl/OpenGLDriver.h index f6a1ce5f7e..10496942bb 100644 --- a/filament/backend/src/opengl/OpenGLDriver.h +++ b/filament/backend/src/opengl/OpenGLDriver.h @@ -44,7 +44,7 @@ namespace filament { namespace backend { class OpenGLPlatform; class PixelBufferDescriptor; -class TargetBufferInfo; +struct TargetBufferInfo; } // namespace backend class OpenGLProgram; diff --git a/filament/backend/src/ostream.cpp b/filament/backend/src/ostream.cpp index d909921dbb..adbe9f6234 100644 --- a/filament/backend/src/ostream.cpp +++ b/filament/backend/src/ostream.cpp @@ -426,9 +426,9 @@ io::ostream& operator<<(io::ostream& out, const RasterState& rs) { io::ostream& operator<<(io::ostream& out, const TargetBufferInfo& tbi) { return out << "TargetBufferInfo{" - << "h=" << tbi.handle + << "handle=" << tbi.handle << ", level=" << tbi.level - << ", face=" << tbi.face << "}"; + << ", layer=" << tbi.layer << "}"; } io::ostream& operator<<(io::ostream& out, const PolygonOffset& po) { diff --git a/filament/backend/test/test_Blit.cpp b/filament/backend/test/test_Blit.cpp index a2229caf82..ad2c01b76b 100644 --- a/filament/backend/test/test_Blit.cpp +++ b/filament/backend/test/test_Blit.cpp @@ -185,8 +185,8 @@ TEST_F(BackendTest, CubemapMinify) { const TextureCubemapFace srcFace = TextureCubemapFace::NEGATIVE_Y; const TextureCubemapFace dstFace = TextureCubemapFace::NEGATIVE_Y; - const TargetBufferInfo srcInfo = { texture, srcLevel, srcFace }; - const TargetBufferInfo dstInfo = { texture, dstLevel, dstFace }; + const TargetBufferInfo srcInfo = { texture, srcLevel, +srcFace }; + const TargetBufferInfo dstInfo = { texture, dstLevel, +dstFace }; Handle srcRenderTarget; srcRenderTarget = api.createRenderTarget( TargetBufferFlags::COLOR, @@ -425,14 +425,14 @@ TEST_F(BackendTest, DepthMinify) { Handle srcRenderTarget = api.createRenderTarget( TargetBufferFlags::COLOR | TargetBufferFlags::DEPTH, kSrcTexWidth >> level, kSrcTexHeight >> level, 1, - { srcColorTexture, level, 0 }, - { srcDepthTexture, level, 0 }, {}); + {{ srcColorTexture, level }}, + { srcDepthTexture, level }, {}); Handle dstRenderTarget = api.createRenderTarget( TargetBufferFlags::COLOR | TargetBufferFlags::DEPTH, kDstTexWidth >> level, kDstTexHeight >> level, 1, - { dstColorTexture, level, 0 }, - { dstDepthTexture, level, 0 }, {}); + {{ dstColorTexture, level }}, + { dstDepthTexture, level }, {}); // Prep for rendering. RenderPassParams params = {}; @@ -555,11 +555,11 @@ TEST_F(BackendTest, ColorResolve) { // Create a 4-sample render target with the 4-sample texture. Handle srcRenderTarget = api.createRenderTarget( - TargetBufferFlags::COLOR, kSrcTexWidth, kSrcTexHeight, kSampleCount, { srcColorTexture }, {}, {}); + TargetBufferFlags::COLOR, kSrcTexWidth, kSrcTexHeight, kSampleCount,{{ srcColorTexture }}, {}, {}); // Create a 1-sample render target with the 1-sample texture. Handle dstRenderTarget = api.createRenderTarget( - TargetBufferFlags::COLOR, kDstTexWidth, kDstTexHeight, 1, { dstColorTexture }, {}, {}); + TargetBufferFlags::COLOR, kDstTexWidth, kDstTexHeight, 1, {{ dstColorTexture }}, {}, {}); // Prep for rendering. RenderPassParams params = {}; @@ -672,12 +672,12 @@ TEST_F(BackendTest, DepthResolve) { // Create a 4-sample render target with 4-sample textures. Handle srcRenderTarget = api.createRenderTarget( TargetBufferFlags::COLOR | TargetBufferFlags::DEPTH, kSrcTexWidth, kSrcTexHeight, - kSampleCount, { srcColorTexture }, { srcDepthTexture }, {}); + kSampleCount, {{ srcColorTexture }}, { srcDepthTexture }, {}); // Create a 1-sample render target with 1-sample textures. Handle dstRenderTarget = api.createRenderTarget( TargetBufferFlags::COLOR | TargetBufferFlags::DEPTH, kDstTexWidth, kDstTexHeight, - 1, { dstColorTexture }, { dstDepthTexture }, {}); + 1, {{ dstColorTexture }}, { dstDepthTexture }, {}); // Prep for rendering. RenderPassParams params = {}; diff --git a/filament/backend/test/test_MRT.cpp b/filament/backend/test/test_MRT.cpp index 800e308438..64e65e374e 100644 --- a/filament/backend/test/test_MRT.cpp +++ b/filament/backend/test/test_MRT.cpp @@ -101,7 +101,7 @@ TEST_F(BackendTest, MRT) { 512, // width 512, // height 1, // samples - { textureA, textureB }, // color + {{textureA },{textureB }}, // color {}, // depth {}); // stencil diff --git a/filament/backend/test/test_ReadPixels.cpp b/filament/backend/test/test_ReadPixels.cpp index 72fc2a6e6e..768edfb3c8 100644 --- a/filament/backend/test/test_ReadPixels.cpp +++ b/filament/backend/test/test_ReadPixels.cpp @@ -251,7 +251,7 @@ TEST_F(ReadPixelsTest, ReadPixels) { // level (at least for OpenGL). Handle renderTarget = getDriverApi().createRenderTarget( TargetBufferFlags::COLOR, t.getRenderTargetSize(), - t.getRenderTargetSize(), t.samples, TargetBufferInfo(texture, t.mipLevel), {}, + t.getRenderTargetSize(), t.samples, {{ texture, uint8_t(t.mipLevel) }}, {}, {}); TrianglePrimitive triangle(getDriverApi()); @@ -290,7 +290,7 @@ TEST_F(ReadPixelsTest, ReadPixels) { RenderPassParams p = params; Handle mipLevelOneRT = getDriverApi().createRenderTarget( TargetBufferFlags::COLOR, renderTargetBaseSize, renderTargetBaseSize, 1, - TargetBufferInfo(texture, 0), {}, + {{ texture }}, {}, {}); p.clearColor = {1.f, 0.f, 0.f, 1.f}; getDriverApi().beginRenderPass(mipLevelOneRT, p); @@ -378,7 +378,7 @@ TEST_F(ReadPixelsTest, ReadPixelsPerformance) { renderTargetSize, // width renderTargetSize, // height 1, // samples - TargetBufferInfo(texture, 0), // color + {{ texture }}, // color {}, // depth {}); // stencil diff --git a/filament/src/PostProcessManager.cpp b/filament/src/PostProcessManager.cpp index a386c05099..f17efa2db6 100644 --- a/filament/src/PostProcessManager.cpp +++ b/filament/src/PostProcessManager.cpp @@ -686,7 +686,7 @@ FrameGraphId PostProcessManager::screenSpaceAmbientOcclusion( // create a temporary render target for source, needed for the blit. auto inTarget = driver.createRenderTarget(TargetBufferFlags::DEPTH, desc.width, desc.height, desc.samples, {}, - resources.getTexture(data.input), {}); + { resources.getTexture(data.input) }, {}); driver.blit(TargetBufferFlags::DEPTH, out.target, out.params.viewport, inTarget, out.params.viewport, @@ -2965,7 +2965,7 @@ FrameGraphId PostProcessManager::resolveBaseLevelNoCheck(Fram if (data.usage == FrameGraphTexture::Usage::COLOR_ATTACHMENT) { inRt = driver.createRenderTarget(data.inFlags, out.params.viewport.width, out.params.viewport.height, - inDesc.samples, { in }, {}, {}); + inDesc.samples, {{ in }}, {}, {}); } if (data.usage == FrameGraphTexture::Usage::DEPTH_ATTACHMENT) { inRt = driver.createRenderTarget(data.inFlags, diff --git a/filament/src/details/RenderTarget.cpp b/filament/src/details/RenderTarget.cpp index 7da7cb041f..aa2c2901b8 100644 --- a/filament/src/details/RenderTarget.cpp +++ b/filament/src/details/RenderTarget.cpp @@ -133,7 +133,7 @@ FRenderTarget::FRenderTarget(FEngine& engine, const RenderTarget::Builder& build info.handle = t->getHwHandle(); info.level = attachment.mipLevel; if (t->getTarget() == Texture::Sampler::SAMPLER_CUBEMAP) { - info.face = attachment.face; + info.layer = +attachment.face; } else { info.layer = attachment.layer; } diff --git a/filament/src/details/Texture.cpp b/filament/src/details/Texture.cpp index 9b549bcfea..dc89e3e3e5 100644 --- a/filament/src/details/Texture.cpp +++ b/filament/src/details/Texture.cpp @@ -452,16 +452,18 @@ void FTexture::generateMipmaps(FEngine& engine) const noexcept { switch (mTarget) { case SamplerType::SAMPLER_2D: - generateMipsForLayer(TargetBufferInfo{ 0 }); + generateMipsForLayer({}); break; case SamplerType::SAMPLER_2D_ARRAY: + UTILS_NOUNROLL for (uint16_t layer = 0, c = mDepth; layer < c; ++layer) { - generateMipsForLayer(TargetBufferInfo{ layer }); + generateMipsForLayer({ .layer = layer }); } break; case SamplerType::SAMPLER_CUBEMAP: + UTILS_NOUNROLL for (uint8_t face = 0; face < 6; ++face) { - generateMipsForLayer(TargetBufferInfo{ TextureCubemapFace(face) }); + generateMipsForLayer({ .layer = face }); } break; case SamplerType::SAMPLER_EXTERNAL: