Merge pull request #14096 from Zvork/mipgen

Added generateTextureMipsWithPipeline function in gpu::Batch
This commit is contained in:
John Conklin II 2018-10-18 16:06:28 -07:00 committed by GitHub
commit 1f06c87580
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 174 additions and 1 deletions

View file

@ -67,6 +67,7 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] =
(&::gpu::gl::GLBackend::do_clearFramebuffer),
(&::gpu::gl::GLBackend::do_blit),
(&::gpu::gl::GLBackend::do_generateTextureMips),
(&::gpu::gl::GLBackend::do_generateTextureMipsWithPipeline),
(&::gpu::gl::GLBackend::do_advance),
@ -166,6 +167,10 @@ GLBackend::GLBackend() {
GLBackend::~GLBackend() {}
void GLBackend::shutdown() {
if (_mipGenerationFramebufferId) {
glDeleteFramebuffers(1, &_mipGenerationFramebufferId);
_mipGenerationFramebufferId = 0;
}
killInput();
killTransform();
killTextureManagementStage();

View file

@ -288,6 +288,7 @@ public:
virtual void do_setIndexBuffer(const Batch& batch, size_t paramOffset) final;
virtual void do_setIndirectBuffer(const Batch& batch, size_t paramOffset) final;
virtual void do_generateTextureMips(const Batch& batch, size_t paramOffset) final;
virtual void do_generateTextureMipsWithPipeline(const Batch& batch, size_t paramOffset) final;
// Transform Stage
virtual void do_setModelTransform(const Batch& batch, size_t paramOffset) final;
@ -407,6 +408,8 @@ public:
protected:
virtual GLint getRealUniformLocation(GLint location) const;
virtual void draw(GLenum mode, uint32 numVertices, uint32 startVertex) = 0;
void recycle() const override;
// FIXME instead of a single flag, create a features struct similar to
@ -696,6 +699,8 @@ protected:
virtual void initTextureManagementStage();
virtual void killTextureManagementStage();
GLuint _mipGenerationFramebufferId{ 0 };
typedef void (GLBackend::*CommandCall)(const Batch&, size_t);
static CommandCall _commandCalls[Batch::NUM_COMMANDS];
friend class GLState;

View file

@ -79,3 +79,55 @@ void GLBackend::do_generateTextureMips(const Batch& batch, size_t paramOffset) {
object->generateMips();
}
void GLBackend::do_generateTextureMipsWithPipeline(const Batch& batch, size_t paramOffset) {
TexturePointer resourceTexture = batch._textures.get(batch._params[paramOffset + 0]._uint);
if (!resourceTexture) {
return;
}
// Always make sure the GLObject is in sync
GLTexture* object = syncGPUObject(resourceTexture);
if (object) {
GLuint to = object->_texture;
glActiveTexture(GL_TEXTURE0 + gpu::slot::texture::MipCreationInput);
glBindTexture(object->_target, to);
(void)CHECK_GL_ERROR();
} else {
return;
}
auto numMips = batch._params[paramOffset + 1]._int;
if (numMips < 0) {
numMips = resourceTexture->getNumMips();
} else {
numMips = std::min(numMips, (int)resourceTexture->getNumMips());
}
if (_mipGenerationFramebufferId == 0) {
glGenFramebuffers(1, &_mipGenerationFramebufferId);
Q_ASSERT(_mipGenerationFramebufferId > 0);
}
glBindFramebuffer(GL_FRAMEBUFFER, _mipGenerationFramebufferId);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
for (int level = 1; level < numMips; level++) {
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, object->_id, level);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, level - 1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, level - 1);
const auto mipDimensions = resourceTexture->evalMipDimensions(level);
glViewport(0, 0, mipDimensions.x, mipDimensions.y);
draw(GL_TRIANGLE_STRIP, 4, 0);
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, numMips - 1);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
resetOutputStage();
// Restore viewport
ivec4& vp = _transform._viewport;
glViewport(vp.x, vp.y, vp.z, vp.w);
}

View file

@ -20,6 +20,29 @@ using namespace gpu::gl41;
const std::string GL41Backend::GL41_VERSION { "GL41" };
void GL41Backend::draw(GLenum mode, uint32 numVertices, uint32 startVertex) {
if (isStereo()) {
#ifdef GPU_STEREO_DRAWCALL_INSTANCED
glDrawArraysInstanced(mode, startVertex, numVertices, 2);
#else
setupStereoSide(0);
glDrawArrays(mode, startVertex, numVertices);
setupStereoSide(1);
glDrawArrays(mode, startVertex, numVertices);
#endif
_stats._DSNumTriangles += 2 * numVertices / 3;
_stats._DSNumDrawcalls += 2;
} else {
glDrawArrays(mode, startVertex, numVertices);
_stats._DSNumTriangles += numVertices / 3;
_stats._DSNumDrawcalls++;
}
_stats._DSNumAPIDrawcalls++;
(void)CHECK_GL_ERROR();
}
void GL41Backend::do_draw(const Batch& batch, size_t paramOffset) {
Primitive primitiveType = (Primitive)batch._params[paramOffset + 2]._uint;
GLenum mode = gl::PRIMITIVE_TO_GL[primitiveType];

View file

@ -130,6 +130,9 @@ public:
};
protected:
void draw(GLenum mode, uint32 numVertices, uint32 startVertex) override;
GLuint getFramebufferID(const FramebufferPointer& framebuffer) override;
GLFramebuffer* syncGPUObject(const Framebuffer& framebuffer) override;

View file

@ -42,6 +42,30 @@ void GL45Backend::recycle() const {
Parent::recycle();
}
void GL45Backend::draw(GLenum mode, uint32 numVertices, uint32 startVertex) {
if (isStereo()) {
#ifdef GPU_STEREO_DRAWCALL_INSTANCED
glDrawArraysInstanced(mode, startVertex, numVertices, 2);
#else
setupStereoSide(0);
glDrawArrays(mode, startVertex, numVertices);
setupStereoSide(1);
glDrawArrays(mode, startVertex, numVertices);
#endif
_stats._DSNumTriangles += 2 * numVertices / 3;
_stats._DSNumDrawcalls += 2;
} else {
glDrawArrays(mode, startVertex, numVertices);
_stats._DSNumTriangles += numVertices / 3;
_stats._DSNumDrawcalls++;
}
_stats._DSNumAPIDrawcalls++;
(void)CHECK_GL_ERROR();
}
void GL45Backend::do_draw(const Batch& batch, size_t paramOffset) {
Primitive primitiveType = (Primitive)batch._params[paramOffset + 2]._uint;
GLenum mode = gl::PRIMITIVE_TO_GL[primitiveType];

View file

@ -229,6 +229,7 @@ public:
protected:
void draw(GLenum mode, uint32 numVertices, uint32 startVertex) override;
void recycle() const override;
GLuint getFramebufferID(const FramebufferPointer& framebuffer) override;

View file

@ -20,6 +20,29 @@ using namespace gpu::gles;
const std::string GLESBackend::GLES_VERSION { "GLES" };
void GLESBackend::draw(GLenum mode, uint32 numVertices, uint32 startVertex) {
if (isStereo()) {
#ifdef GPU_STEREO_DRAWCALL_INSTANCED
glDrawArraysInstanced(mode, startVertex, numVertices, 2);
#else
setupStereoSide(0);
glDrawArrays(mode, startVertex, numVertices);
setupStereoSide(1);
glDrawArrays(mode, startVertex, numVertices);
#endif
_stats._DSNumTriangles += 2 * numVertices / 3;
_stats._DSNumDrawcalls += 2;
} else {
glDrawArrays(mode, startVertex, numVertices);
_stats._DSNumTriangles += numVertices / 3;
_stats._DSNumDrawcalls++;
}
_stats._DSNumAPIDrawcalls++;
(void)CHECK_GL_ERROR();
}
void GLESBackend::do_draw(const Batch& batch, size_t paramOffset) {
Primitive primitiveType = (Primitive)batch._params[paramOffset + 2]._uint;
GLenum mode = gl::PRIMITIVE_TO_GL[primitiveType];

View file

@ -126,6 +126,9 @@ public:
};
protected:
void draw(GLenum mode, uint32 numVertices, uint32 startVertex) override;
GLuint getFramebufferID(const FramebufferPointer& framebuffer) override;
GLFramebuffer* syncGPUObject(const Framebuffer& framebuffer) override;

View file

@ -426,6 +426,13 @@ void Batch::generateTextureMips(const TexturePointer& texture) {
_params.emplace_back(_textures.cache(texture));
}
void Batch::generateTextureMipsWithPipeline(const TexturePointer& texture, int numMips) {
ADD_COMMAND(generateTextureMipsWithPipeline);
_params.emplace_back(_textures.cache(texture));
_params.emplace_back(numMips);
}
void Batch::beginQuery(const QueryPointer& query) {
ADD_COMMAND(beginQuery);

View file

@ -226,6 +226,8 @@ public:
// Generate the mips for a texture
void generateTextureMips(const TexturePointer& texture);
// Generate the mips for a texture using the current pipeline
void generateTextureMipsWithPipeline(const TexturePointer& destTexture, int numMips = -1);
// Query Section
void beginQuery(const QueryPointer& query);
@ -326,6 +328,7 @@ public:
COMMAND_clearFramebuffer,
COMMAND_blit,
COMMAND_generateTextureMips,
COMMAND_generateTextureMipsWithPipeline,
COMMAND_advance,

View file

@ -0,0 +1,20 @@
<!
// MipGeneration.slh
// libraries/gpu/src
//
// Created by Olivier Prat on 10/16/18.
// Copyright 2018 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
!>
<@if not MIP_GENERATION_SLH@>
<@def MIP_GENERATION_SLH@>
<@include gpu/ShaderConstants.h@>
layout(binding=GPU_TEXTURE_MIP_CREATION_INPUT) uniform sampler2D texMap;
in vec2 varTexCoord0;
<@endif@>

View file

@ -21,6 +21,9 @@
#define GPU_TEXTURE_TRANSFORM_OBJECT 31
// Mip creation
#define GPU_TEXTURE_MIP_CREATION_INPUT 30
#define GPU_STORAGE_TRANSFORM_OBJECT 7
#define GPU_ATTR_POSITION 0
@ -67,7 +70,8 @@ enum Buffer {
namespace texture {
enum Texture {
ObjectTransforms = GPU_TEXTURE_TRANSFORM_OBJECT,
};
MipCreationInput = GPU_TEXTURE_MIP_CREATION_INPUT,
};
} // namespace texture
namespace storage {