diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLTexture.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLTexture.cpp index e9494a1271..082edd47bc 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLTexture.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLTexture.cpp @@ -60,9 +60,17 @@ GLenum GLTexture::getGLTextureType(const Texture& texture) { switch (texture.getType()) { case Texture::TEX_2D: if (!texture.isArray()) { - return GL_TEXTURE_2D; + if (!texture.isMultisample()) { + return GL_TEXTURE_2D; + } else { + return GL_TEXTURE_2D_MULTISAMPLE; + } } else { - return GL_TEXTURE_2D_ARRAY; + if (!texture.isMultisample()) { + return GL_TEXTURE_2D_ARRAY; + } else { + return GL_TEXTURE_2D_MULTISAMPLE_ARRAY; + } } break; @@ -81,7 +89,9 @@ GLenum GLTexture::getGLTextureType(const Texture& texture) { uint8_t GLTexture::getFaceCount(GLenum target) { switch (target) { case GL_TEXTURE_2D: + case GL_TEXTURE_2D_MULTISAMPLE: case GL_TEXTURE_2D_ARRAY: + case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: return TEXTURE_2D_NUM_FACES; case GL_TEXTURE_CUBE_MAP: return TEXTURE_CUBE_NUM_FACES; @@ -96,15 +106,20 @@ const std::vector& GLTexture::getFaceTargets(GLenum target) { GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z }; - static const std::vector faceTargets { + static const std::vector face2DTargets { GL_TEXTURE_2D }; - static const std::vector arrayFaceTargets{ + static const std::vector face2DMSTargets{ + GL_TEXTURE_2D_MULTISAMPLE + }; + static const std::vector arrayFaceTargets{ GL_TEXTURE_2D_ARRAY }; switch (target) { case GL_TEXTURE_2D: - return faceTargets; + return face2DTargets; + case GL_TEXTURE_2D_MULTISAMPLE: + return face2DMSTargets; case GL_TEXTURE_2D_ARRAY: return arrayFaceTargets; case GL_TEXTURE_CUBE_MAP: @@ -114,7 +129,7 @@ const std::vector& GLTexture::getFaceTargets(GLenum target) { break; } Q_UNREACHABLE(); - return faceTargets; + return face2DTargets; } GLTexture::GLTexture(const std::weak_ptr& backend, const Texture& texture, GLuint id) : diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendOutput.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendOutput.cpp index 1d512103bd..0f50b0724e 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendOutput.cpp +++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendOutput.cpp @@ -66,6 +66,8 @@ public: if (gltexture) { if (gltexture->_target == GL_TEXTURE_2D) { glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[unit], GL_TEXTURE_2D, gltexture->_texture, 0); + } else if (gltexture->_target == GL_TEXTURE_2D_MULTISAMPLE) { + glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[unit], GL_TEXTURE_2D_MULTISAMPLE, gltexture->_texture, 0); } else { glFramebufferTextureLayer(GL_FRAMEBUFFER, colorAttachments[unit], gltexture->_texture, 0, b._subresource); @@ -98,6 +100,8 @@ public: if (gltexture) { if (gltexture->_target == GL_TEXTURE_2D) { glFramebufferTexture2D(GL_FRAMEBUFFER, attachement, GL_TEXTURE_2D, gltexture->_texture, 0); + } else if (gltexture->_target == GL_TEXTURE_2D_MULTISAMPLE) { + glFramebufferTexture2D(GL_FRAMEBUFFER, attachement, GL_TEXTURE_2D_MULTISAMPLE, gltexture->_texture, 0); } else { glFramebufferTextureLayer(GL_FRAMEBUFFER, attachement, gltexture->_texture, 0, _gpuObject.getDepthStencilBufferSubresource()); diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp index 4068865274..f47211555a 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp @@ -216,19 +216,29 @@ void GL41FixedAllocationTexture::allocateStorage() const { const GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat()); const auto numMips = _gpuObject.getNumMips(); const auto numSlices = _gpuObject.getNumSlices(); + const auto numSamples = _gpuObject.getNumSamples(); // glTextureStorage2D(_id, mips, texelFormat.internalFormat, dimensions.x, dimensions.y); - for (GLint level = 0; level < numMips; level++) { - Vec3u dimensions = _gpuObject.evalMipDimensions(level); - for (GLenum target : getFaceTargets(_target)) { - if (!_gpuObject.isArray()) { - glTexImage2D(target, level, texelFormat.internalFormat, dimensions.x, dimensions.y, 0, texelFormat.format, - texelFormat.type, nullptr); - } else { - glTexImage3D(target, level, texelFormat.internalFormat, dimensions.x, dimensions.y, numSlices, 0, - texelFormat.format, texelFormat.type, nullptr); + if (!_gpuObject.isMultisample()) { + for (GLint level = 0; level < numMips; level++) { + Vec3u dimensions = _gpuObject.evalMipDimensions(level); + for (GLenum target : getFaceTargets(_target)) { + if (!_gpuObject.isArray()) { + glTexImage2D(target, level, texelFormat.internalFormat, dimensions.x, dimensions.y, 0, texelFormat.format, + texelFormat.type, nullptr); + } else { + glTexImage3D(target, level, texelFormat.internalFormat, dimensions.x, dimensions.y, numSlices, 0, + texelFormat.format, texelFormat.type, nullptr); + } } } + } else { + const auto dimensions = _gpuObject.getDimensions(); + if (!_gpuObject.isArray()) { + glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, numSamples, texelFormat.internalFormat, dimensions.x, dimensions.y, GL_FALSE); + } else { + glTexImage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, numSamples, texelFormat.internalFormat, dimensions.x, dimensions.y, dimensions.z, GL_FALSE); + } } glTexParameteri(_target, GL_TEXTURE_BASE_LEVEL, 0); diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendOutput.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendOutput.cpp index 86332558e3..7a299e792b 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendOutput.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendOutput.cpp @@ -62,6 +62,8 @@ public: if (gltexture) { if (gltexture->_target == GL_TEXTURE_2D) { glNamedFramebufferTexture(_id, colorAttachments[unit], gltexture->_texture, 0); + } else if (gltexture->_target == GL_TEXTURE_2D_MULTISAMPLE) { + glNamedFramebufferTexture(_id, colorAttachments[unit], gltexture->_texture, 0); } else { glNamedFramebufferTextureLayer(_id, colorAttachments[unit], gltexture->_texture, 0, b._subresource); } @@ -93,6 +95,9 @@ public: if (gltexture) { if (gltexture->_target == GL_TEXTURE_2D) { glNamedFramebufferTexture(_id, attachement, gltexture->_texture, 0); + } + else if (gltexture->_target == GL_TEXTURE_2D_MULTISAMPLE) { + glNamedFramebufferTexture(_id, attachement, gltexture->_texture, 0); } else { glNamedFramebufferTextureLayer(_id, attachement, gltexture->_texture, 0, _gpuObject.getDepthStencilBufferSubresource()); diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp index a8b5ec85e8..4aff76df21 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp @@ -380,11 +380,22 @@ void GL45FixedAllocationTexture::allocateStorage() const { const auto dimensions = _gpuObject.getDimensions(); const auto mips = _gpuObject.getNumMips(); const auto numSlices = _gpuObject.getNumSlices(); + const auto numSamples = _gpuObject.getNumSamples(); - if (!_gpuObject.isArray()) { - glTextureStorage2D(_id, mips, texelFormat.internalFormat, dimensions.x, dimensions.y); + + if (!_gpuObject.isMultisample()) { + if (!_gpuObject.isArray()) { + glTextureStorage2D(_id, mips, texelFormat.internalFormat, dimensions.x, dimensions.y); + } else { + glTextureStorage3D(_id, mips, texelFormat.internalFormat, dimensions.x, dimensions.y, numSlices); + } } else { - glTextureStorage3D(_id, mips, texelFormat.internalFormat, dimensions.x, dimensions.y, numSlices); + if (!_gpuObject.isArray()) { + glTextureStorage2DMultisample(_id, numSamples, texelFormat.internalFormat, dimensions.x, dimensions.y, GL_FALSE); + } + else { + glTextureStorage3DMultisample(_id, numSamples, texelFormat.internalFormat, dimensions.x, dimensions.y, numSlices, GL_FALSE); + } } glTextureParameteri(_id, GL_TEXTURE_BASE_LEVEL, 0); diff --git a/libraries/gpu-gles/src/gpu/gles/GLESBackendOutput.cpp b/libraries/gpu-gles/src/gpu/gles/GLESBackendOutput.cpp index 90ce8c853a..36b37083cb 100644 --- a/libraries/gpu-gles/src/gpu/gles/GLESBackendOutput.cpp +++ b/libraries/gpu-gles/src/gpu/gles/GLESBackendOutput.cpp @@ -130,6 +130,8 @@ public: } #endif + } else if (gltexture->_target == GL_TEXTURE_2D_MULTISAMPLE) { + glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[unit], GL_TEXTURE_2D_MULTISAMPLE, gltexture->_texture, 0); } else { glFramebufferTextureLayer(GL_FRAMEBUFFER, colorAttachments[unit], gltexture->_texture, 0, b._subresource); @@ -162,6 +164,8 @@ public: if (gltexture) { if (gltexture->_target == GL_TEXTURE_2D) { glFramebufferTexture2D(GL_FRAMEBUFFER, attachement, GL_TEXTURE_2D, gltexture->_texture, 0); + } else if (gltexture->_target == GL_TEXTURE_2D_MULTISAMPLE) { + glFramebufferTexture2D(GL_FRAMEBUFFER, attachement, GL_TEXTURE_2D_MULTISAMPLE, gltexture->_texture, 0); } else { glFramebufferTextureLayer(GL_FRAMEBUFFER, attachement, gltexture->_texture, 0, _gpuObject.getDepthStencilBufferSubresource()); diff --git a/libraries/gpu-gles/src/gpu/gles/GLESBackendTexture.cpp b/libraries/gpu-gles/src/gpu/gles/GLESBackendTexture.cpp index 23dc271af9..4b2d4d09e6 100644 --- a/libraries/gpu-gles/src/gpu/gles/GLESBackendTexture.cpp +++ b/libraries/gpu-gles/src/gpu/gles/GLESBackendTexture.cpp @@ -272,28 +272,40 @@ void GLESFixedAllocationTexture::allocateStorage() const { const GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat()); const auto numMips = _gpuObject.getNumMips(); const auto numSlices = _gpuObject.getNumSlices(); + const auto numSamples = _gpuObject.getNumSamples(); // glTextureStorage2D(_id, mips, texelFormat.internalFormat, dimensions.x, dimensions.y); - for (GLint level = 0; level < numMips; level++) { - Vec3u dimensions = _gpuObject.evalMipDimensions(level); - for (GLenum target : getFaceTargets(_target)) { - if (texelFormat.isCompressed()) { - auto size = getCompressedImageSize(dimensions.x, dimensions.y, texelFormat.internalFormat); - if (!_gpuObject.isArray()) { - glCompressedTexImage2D(target, level, texelFormat.internalFormat, dimensions.x, dimensions.y, 0, size, nullptr); + if (!_gpuObject.isMultisample()) { + for (GLint level = 0; level < numMips; level++) { + Vec3u dimensions = _gpuObject.evalMipDimensions(level); + for (GLenum target : getFaceTargets(_target)) { + if (texelFormat.isCompressed()) { + auto size = getCompressedImageSize(dimensions.x, dimensions.y, texelFormat.internalFormat); + if (!_gpuObject.isArray()) { + glCompressedTexImage2D(target, level, texelFormat.internalFormat, dimensions.x, dimensions.y, 0, size, nullptr); + } else { + glCompressedTexImage3D(target, level, texelFormat.internalFormat, dimensions.x, dimensions.y, numSlices, 0, size * numSlices, nullptr); + } } else { - glCompressedTexImage3D(target, level, texelFormat.internalFormat, dimensions.x, dimensions.y, numSlices, 0, size * numSlices, nullptr); - } - } else { - if (!_gpuObject.isArray()) { - glTexImage2D(target, level, texelFormat.internalFormat, dimensions.x, dimensions.y, 0, texelFormat.format, - texelFormat.type, nullptr); - } else { - glTexImage3D(target, level, texelFormat.internalFormat, dimensions.x, dimensions.y, numSlices, 0, - texelFormat.format, texelFormat.type, nullptr); + if (!_gpuObject.isArray()) { + glTexImage2D(target, level, texelFormat.internalFormat, dimensions.x, dimensions.y, 0, texelFormat.format, + texelFormat.type, nullptr); + } else { + glTexImage3D(target, level, texelFormat.internalFormat, dimensions.x, dimensions.y, numSlices, 0, + texelFormat.format, texelFormat.type, nullptr); + } } } } + } else { + const auto dimensions = _gpuObject.getDimensions(); + if (!_gpuObject.isArray()) { + glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, numSamples, + texelFormat.internalFormat, dimensions.x, dimensions.y, + GL_FALSE); + } else { + // NOT SUPPORTED (yet) + } } glTexParameteri(_target, GL_TEXTURE_BASE_LEVEL, 0); diff --git a/libraries/gpu/src/gpu/Texture.cpp b/libraries/gpu/src/gpu/Texture.cpp index c6f3cd9b9a..5c2e181810 100755 --- a/libraries/gpu/src/gpu/Texture.cpp +++ b/libraries/gpu/src/gpu/Texture.cpp @@ -176,10 +176,18 @@ TexturePointer Texture::createRenderBuffer(const Element& texelFormat, uint16 wi return create(TextureUsageType::RENDERBUFFER, TEX_2D, texelFormat, width, height, 1, 1, 0, numMips, sampler); } +TexturePointer Texture::createRenderBufferMultisample(const Element& texelFormat, uint16 width, uint16 height, uint16 numSamples, const Sampler& sampler) { + return create(TextureUsageType::RENDERBUFFER, TEX_2D, texelFormat, width, height, 1, numSamples, 0, gpu::Texture::SINGLE_MIP, sampler); +} + TexturePointer Texture::createRenderBufferArray(const Element& texelFormat, uint16 width, uint16 height, uint16 numSlices, uint16 numMips, const Sampler& sampler) { return create(TextureUsageType::RENDERBUFFER, TEX_2D, texelFormat, width, height, 1, 1, numSlices, numMips, sampler); } +TexturePointer Texture::createRenderBufferMultisampleArray(const Element& texelFormat, uint16 width, uint16 height, uint16 numSlices, uint16 numSamples, const Sampler& sampler) { + return create(TextureUsageType::RENDERBUFFER, TEX_2D, texelFormat, width, height, 1, numSamples, numSlices, gpu::Texture::SINGLE_MIP, sampler); +} + TexturePointer Texture::create1D(const Element& texelFormat, uint16 width, uint16 numMips, const Sampler& sampler) { return create(TextureUsageType::RESOURCE, TEX_1D, texelFormat, width, 1, 1, 1, 0, numMips, sampler); } diff --git a/libraries/gpu/src/gpu/Texture.h b/libraries/gpu/src/gpu/Texture.h index 23bfff6873..d410671481 100755 --- a/libraries/gpu/src/gpu/Texture.h +++ b/libraries/gpu/src/gpu/Texture.h @@ -387,7 +387,9 @@ public: static TexturePointer create3D(const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numMips = SINGLE_MIP, const Sampler& sampler = Sampler()); static TexturePointer createCube(const Element& texelFormat, uint16 width, uint16 numMips = 1, const Sampler& sampler = Sampler()); static TexturePointer createRenderBuffer(const Element& texelFormat, uint16 width, uint16 height, uint16 numMips = SINGLE_MIP, const Sampler& sampler = Sampler()); + static TexturePointer createRenderBufferMultisample(const Element& texelFormat, uint16 width, uint16 height, uint16 numSamples, const Sampler& sampler = Sampler()); static TexturePointer createRenderBufferArray(const Element& texelFormat, uint16 width, uint16 height, uint16 numSlices, uint16 numMips = SINGLE_MIP, const Sampler& sampler = Sampler()); + static TexturePointer createRenderBufferMultisampleArray(const Element& texelFormat, uint16 width, uint16 height, uint16 numSlices, uint16 numSamples, const Sampler& sampler = Sampler()); static TexturePointer createStrict(const Element& texelFormat, uint16 width, uint16 height, uint16 numMips = SINGLE_MIP, const Sampler& sampler = Sampler()); static TexturePointer createExternal(const ExternalRecycler& recycler, const Sampler& sampler = Sampler()); @@ -435,6 +437,7 @@ public: uint16 getNumSamples() const { return _numSamples; } // NumSamples can only have certain values based on the hw static uint16 evalNumSamplesUsed(uint16 numSamplesTried); + bool isMultisample() const { return _numSamples > 1; } // max mip is in the range [ 0 if no sub mips, log2(max(width, height, depth))] // It is defined at creation time (immutable) diff --git a/libraries/render-utils/src/ToneMappingEffect.cpp b/libraries/render-utils/src/ToneMappingEffect.cpp index d192266d7e..64a2adb5d4 100644 --- a/libraries/render-utils/src/ToneMappingEffect.cpp +++ b/libraries/render-utils/src/ToneMappingEffect.cpp @@ -79,8 +79,8 @@ void ToneMappingEffect::render(RenderArgs* args, const gpu::TexturePointer& ligh void ToneMappingDeferred::configure(const Config& config) { - _toneMappingEffect.setExposure(config.exposure); - _toneMappingEffect.setToneCurve((ToneMappingEffect::ToneCurve)config.curve); + _toneMappingEffect.setExposure(config.exposure); + _toneMappingEffect.setToneCurve((ToneMappingEffect::ToneCurve)config.curve); } void ToneMappingDeferred::run(const render::RenderContextPointer& renderContext, const Inputs& inputs) { diff --git a/libraries/render-utils/src/toneMapping.slf b/libraries/render-utils/src/toneMapping.slf index 29f618c2f0..3fe53d9be1 100644 --- a/libraries/render-utils/src/toneMapping.slf +++ b/libraries/render-utils/src/toneMapping.slf @@ -37,7 +37,7 @@ int getToneCurve() { } LAYOUT(binding=RENDER_UTILS_TEXTURE_TM_COLOR) uniform sampler2D colorMap; - + layout(location=0) in vec2 varTexCoord0; layout(location=0) out vec4 outFragColor; diff --git a/scripts/developer/utilities/render/deferredLighting.qml b/scripts/developer/utilities/render/deferredLighting.qml index aef533b7a3..6d98e96780 100644 --- a/scripts/developer/utilities/render/deferredLighting.qml +++ b/scripts/developer/utilities/render/deferredLighting.qml @@ -123,7 +123,6 @@ Rectangle { anchors.right: parent.right } } - Item { height: childrenRect.height anchors.left: parent.left @@ -134,18 +133,17 @@ Rectangle { anchors.left: parent.left } - HifiControls.ComboBox { + ComboBox { anchors.right: parent.right currentIndex: 1 - model: ListModel { - id: cbItems - ListElement { text: "RGB"; color: "Yellow" } - ListElement { text: "SRGB"; color: "Green" } - ListElement { text: "Reinhard"; color: "Yellow" } - ListElement { text: "Filmic"; color: "White" } - } + model: [ + "RGB", + "SRGB", + "Reinhard", + "Filmic", + ] width: 200 - onCurrentIndexChanged: { render.mainViewTask.getConfig("ToneMapping")["curve"] = currentIndex } + onCurrentIndexChanged: { render.mainViewTask.getConfig("ToneMapping")["curve"] = currentIndex; } } } } @@ -170,7 +168,7 @@ Rectangle { framebuffer.config.mode = mode; } - HifiControls.ComboBox { + ComboBox { anchors.right: parent.right currentIndex: 0 model: ListModel {