mirror of
https://github.com/Armored-Dragon/overte.git
synced 2025-03-11 16:13:16 +01:00
Merge pull request #14096 from Zvork/mipgen
Added generateTextureMipsWithPipeline function in gpu::Batch
This commit is contained in:
commit
1f06c87580
13 changed files with 174 additions and 1 deletions
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
||||
|
|
20
libraries/gpu/src/gpu/MipGeneration.slh
Normal file
20
libraries/gpu/src/gpu/MipGeneration.slh
Normal 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@>
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue