From b1eb0b0a46fabdea7ca3122a64253c7265b95095 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Wed, 30 Jan 2019 13:10:52 -0800 Subject: [PATCH] GPU tweaks --- .../gpu-gl-common/src/gpu/gl/GLBackend.cpp | 3 + .../gpu-gl-common/src/gpu/gl/GLBackend.h | 2 +- libraries/gpu-gles/src/gpu/gles/GLESBackend.h | 1 + .../src/gpu/gles/GLESBackendOutput.cpp | 66 ++++++++++++++++++- libraries/gpu/src/gpu/Context.h | 3 +- 5 files changed, 72 insertions(+), 3 deletions(-) diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp index 82f4f97e3b..1cf331cd1a 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp @@ -426,6 +426,9 @@ void GLBackend::render(const Batch& batch) { GL_PROFILE_RANGE(render_gpu_gl, batch.getName().c_str()); _transform._skybox = _stereo._skybox = batch.isSkyboxEnabled(); + // FIXME move this to between the transfer and draw passes, so that + // framebuffer setup can see the proper stereo state and enable things + // like foveation // Allow the batch to override the rendering stereo settings // for things like full framebuffer copy operations (deferred lighting passes) bool savedStereo = _stereo._enable; diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h index b5a279a54c..671d4e11d7 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h @@ -95,7 +95,7 @@ public: // Shutdown rendering and persist any required resources void shutdown() override; - void setCameraCorrection(const Mat4& correction, const Mat4& prevRenderView, bool reset = false); + void setCameraCorrection(const Mat4& correction, const Mat4& prevRenderView, bool reset = false) override; void render(const Batch& batch) final override; // This call synchronize the Full Backend cache with the current GLState diff --git a/libraries/gpu-gles/src/gpu/gles/GLESBackend.h b/libraries/gpu-gles/src/gpu/gles/GLESBackend.h index aaa1be5892..636518c85a 100644 --- a/libraries/gpu-gles/src/gpu/gles/GLESBackend.h +++ b/libraries/gpu-gles/src/gpu/gles/GLESBackend.h @@ -48,6 +48,7 @@ public: class GLESTexture : public GLTexture { using Parent = GLTexture; friend class GLESBackend; + friend class GLESFramebuffer; GLuint allocate(const Texture& texture); protected: GLESTexture(const std::weak_ptr& backend, const Texture& buffer); diff --git a/libraries/gpu-gles/src/gpu/gles/GLESBackendOutput.cpp b/libraries/gpu-gles/src/gpu/gles/GLESBackendOutput.cpp index 9c3a83ce13..90ce8c853a 100644 --- a/libraries/gpu-gles/src/gpu/gles/GLESBackendOutput.cpp +++ b/libraries/gpu-gles/src/gpu/gles/GLESBackendOutput.cpp @@ -17,6 +17,34 @@ namespace gpu { namespace gles { + +// returns the FOV from the projection matrix +static inline vec4 extractFov( const glm::mat4& m) { + static const std::array CLIPS{ { + { 1, 0, 0, 1 }, + { -1, 0, 0, 1 }, + { 0, 1, 0, 1 }, + { 0, -1, 0, 1 } + } }; + + glm::mat4 mt = glm::transpose(m); + vec4 v, result; + // Left + v = mt * CLIPS[0]; + result.x = -atanf(v.z / v.x); + // Right + v = mt * CLIPS[1]; + result.y = atanf(v.z / v.x); + // Down + v = mt * CLIPS[2]; + result.z = -atanf(v.z / v.y); + // Up + v = mt * CLIPS[3]; + result.w = atanf(v.z / v.y); + return result; +} + + class GLESFramebuffer : public gl::GLFramebuffer { using Parent = gl::GLFramebuffer; static GLuint allocate() { @@ -29,6 +57,24 @@ public: GLint currentFBO = -1; glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, ¤tFBO); glBindFramebuffer(GL_FRAMEBUFFER, _fbo); + + vec2 focalPoint{ -1.0f }; + +#if 0 + { + auto backend = _backend.lock(); + if (backend && backend->isStereo()) { + glm::mat4 projections[2]; + backend->getStereoProjections(projections); + vec4 fov = extractFov(projections[0]); + float fovwidth = fov.x + fov.y; + float fovheight = fov.z + fov.w; + focalPoint.x = fov.y / fovwidth; + focalPoint.y = (fov.z / fovheight) - 0.5f; + } + } +#endif + gl::GLTexture* gltexture = nullptr; TexturePointer surface; if (_gpuObject.getColorStamps() != _colorStamps) { @@ -58,7 +104,7 @@ public: surface = b._texture; if (surface) { Q_ASSERT(TextureUsageType::RENDERBUFFER == surface->getUsageType()); - gltexture = backend->syncGPUObject(surface); + gltexture = backend->syncGPUObject(surface); } else { gltexture = nullptr; } @@ -66,6 +112,24 @@ public: if (gltexture) { if (gltexture->_target == GL_TEXTURE_2D) { glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[unit], GL_TEXTURE_2D, gltexture->_texture, 0); +#if 0 + if (glTextureFoveationParametersQCOM && focalPoint.x != -1.0f) { + static GLint FOVEATION_QUERY = 0; + static std::once_flag once; + std::call_once(once, [&]{ + glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_FOVEATED_FEATURE_QUERY_QCOM, &FOVEATION_QUERY); + }); + static const float foveaArea = 4.0f; + static const float gain = 16.0f; + GLESBackend::GLESTexture* glestexture = static_cast(gltexture); + glestexture->withPreservedTexture([=]{ + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_FOVEATED_FEATURE_BITS_QCOM, GL_FOVEATION_ENABLE_BIT_QCOM | GL_FOVEATION_SCALED_BIN_METHOD_BIT_QCOM); + glTextureFoveationParametersQCOM(_id, 0, 0, -focalPoint.x, focalPoint.y, gain * 2.0f, gain, foveaArea); + glTextureFoveationParametersQCOM(_id, 0, 1, focalPoint.x, focalPoint.y, gain * 2.0f, gain, foveaArea); + }); + + } +#endif } else { glFramebufferTextureLayer(GL_FRAMEBUFFER, colorAttachments[unit], gltexture->_texture, 0, b._subresource); diff --git a/libraries/gpu/src/gpu/Context.h b/libraries/gpu/src/gpu/Context.h index b080b0ceac..7109b3dfeb 100644 --- a/libraries/gpu/src/gpu/Context.h +++ b/libraries/gpu/src/gpu/Context.h @@ -66,6 +66,7 @@ public: virtual void syncProgram(const gpu::ShaderPointer& program) = 0; virtual void recycle() const = 0; virtual void downloadFramebuffer(const FramebufferPointer& srcFramebuffer, const Vec4i& region, QImage& destImage) = 0; + virtual void setCameraCorrection(const Mat4& correction, const Mat4& prevRenderView, bool reset = false) {} virtual bool supportedTextureFormat(const gpu::Element& format) = 0; @@ -117,7 +118,6 @@ public: static ContextMetricSize textureResourcePopulatedGPUMemSize; static ContextMetricSize textureResourceIdealGPUMemSize; -protected: virtual bool isStereo() const { return _stereo.isStereo(); } @@ -127,6 +127,7 @@ protected: eyeProjections[i] = _stereo._eyeProjections[i]; } } +protected: void getStereoViews(mat4* eyeViews) const { for (int i = 0; i < 2; ++i) {