mirror of
https://github.com/JulianGro/overte.git
synced 2025-08-09 21:23:03 +02: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_clearFramebuffer),
|
||||||
(&::gpu::gl::GLBackend::do_blit),
|
(&::gpu::gl::GLBackend::do_blit),
|
||||||
(&::gpu::gl::GLBackend::do_generateTextureMips),
|
(&::gpu::gl::GLBackend::do_generateTextureMips),
|
||||||
|
(&::gpu::gl::GLBackend::do_generateTextureMipsWithPipeline),
|
||||||
|
|
||||||
(&::gpu::gl::GLBackend::do_advance),
|
(&::gpu::gl::GLBackend::do_advance),
|
||||||
|
|
||||||
|
@ -166,6 +167,10 @@ GLBackend::GLBackend() {
|
||||||
GLBackend::~GLBackend() {}
|
GLBackend::~GLBackend() {}
|
||||||
|
|
||||||
void GLBackend::shutdown() {
|
void GLBackend::shutdown() {
|
||||||
|
if (_mipGenerationFramebufferId) {
|
||||||
|
glDeleteFramebuffers(1, &_mipGenerationFramebufferId);
|
||||||
|
_mipGenerationFramebufferId = 0;
|
||||||
|
}
|
||||||
killInput();
|
killInput();
|
||||||
killTransform();
|
killTransform();
|
||||||
killTextureManagementStage();
|
killTextureManagementStage();
|
||||||
|
|
|
@ -288,6 +288,7 @@ public:
|
||||||
virtual void do_setIndexBuffer(const Batch& batch, size_t paramOffset) final;
|
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_setIndirectBuffer(const Batch& batch, size_t paramOffset) final;
|
||||||
virtual void do_generateTextureMips(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
|
// Transform Stage
|
||||||
virtual void do_setModelTransform(const Batch& batch, size_t paramOffset) final;
|
virtual void do_setModelTransform(const Batch& batch, size_t paramOffset) final;
|
||||||
|
@ -407,6 +408,8 @@ public:
|
||||||
protected:
|
protected:
|
||||||
virtual GLint getRealUniformLocation(GLint location) const;
|
virtual GLint getRealUniformLocation(GLint location) const;
|
||||||
|
|
||||||
|
virtual void draw(GLenum mode, uint32 numVertices, uint32 startVertex) = 0;
|
||||||
|
|
||||||
void recycle() const override;
|
void recycle() const override;
|
||||||
|
|
||||||
// FIXME instead of a single flag, create a features struct similar to
|
// FIXME instead of a single flag, create a features struct similar to
|
||||||
|
@ -696,6 +699,8 @@ protected:
|
||||||
virtual void initTextureManagementStage();
|
virtual void initTextureManagementStage();
|
||||||
virtual void killTextureManagementStage();
|
virtual void killTextureManagementStage();
|
||||||
|
|
||||||
|
GLuint _mipGenerationFramebufferId{ 0 };
|
||||||
|
|
||||||
typedef void (GLBackend::*CommandCall)(const Batch&, size_t);
|
typedef void (GLBackend::*CommandCall)(const Batch&, size_t);
|
||||||
static CommandCall _commandCalls[Batch::NUM_COMMANDS];
|
static CommandCall _commandCalls[Batch::NUM_COMMANDS];
|
||||||
friend class GLState;
|
friend class GLState;
|
||||||
|
|
|
@ -79,3 +79,55 @@ void GLBackend::do_generateTextureMips(const Batch& batch, size_t paramOffset) {
|
||||||
|
|
||||||
object->generateMips();
|
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" };
|
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) {
|
void GL41Backend::do_draw(const Batch& batch, size_t paramOffset) {
|
||||||
Primitive primitiveType = (Primitive)batch._params[paramOffset + 2]._uint;
|
Primitive primitiveType = (Primitive)batch._params[paramOffset + 2]._uint;
|
||||||
GLenum mode = gl::PRIMITIVE_TO_GL[primitiveType];
|
GLenum mode = gl::PRIMITIVE_TO_GL[primitiveType];
|
||||||
|
|
|
@ -130,6 +130,9 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
void draw(GLenum mode, uint32 numVertices, uint32 startVertex) override;
|
||||||
|
|
||||||
GLuint getFramebufferID(const FramebufferPointer& framebuffer) override;
|
GLuint getFramebufferID(const FramebufferPointer& framebuffer) override;
|
||||||
GLFramebuffer* syncGPUObject(const Framebuffer& framebuffer) override;
|
GLFramebuffer* syncGPUObject(const Framebuffer& framebuffer) override;
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,30 @@ void GL45Backend::recycle() const {
|
||||||
Parent::recycle();
|
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) {
|
void GL45Backend::do_draw(const Batch& batch, size_t paramOffset) {
|
||||||
Primitive primitiveType = (Primitive)batch._params[paramOffset + 2]._uint;
|
Primitive primitiveType = (Primitive)batch._params[paramOffset + 2]._uint;
|
||||||
GLenum mode = gl::PRIMITIVE_TO_GL[primitiveType];
|
GLenum mode = gl::PRIMITIVE_TO_GL[primitiveType];
|
||||||
|
|
|
@ -229,6 +229,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
void draw(GLenum mode, uint32 numVertices, uint32 startVertex) override;
|
||||||
void recycle() const override;
|
void recycle() const override;
|
||||||
|
|
||||||
GLuint getFramebufferID(const FramebufferPointer& framebuffer) override;
|
GLuint getFramebufferID(const FramebufferPointer& framebuffer) override;
|
||||||
|
|
|
@ -20,6 +20,29 @@ using namespace gpu::gles;
|
||||||
|
|
||||||
const std::string GLESBackend::GLES_VERSION { "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) {
|
void GLESBackend::do_draw(const Batch& batch, size_t paramOffset) {
|
||||||
Primitive primitiveType = (Primitive)batch._params[paramOffset + 2]._uint;
|
Primitive primitiveType = (Primitive)batch._params[paramOffset + 2]._uint;
|
||||||
GLenum mode = gl::PRIMITIVE_TO_GL[primitiveType];
|
GLenum mode = gl::PRIMITIVE_TO_GL[primitiveType];
|
||||||
|
|
|
@ -126,6 +126,9 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
void draw(GLenum mode, uint32 numVertices, uint32 startVertex) override;
|
||||||
|
|
||||||
GLuint getFramebufferID(const FramebufferPointer& framebuffer) override;
|
GLuint getFramebufferID(const FramebufferPointer& framebuffer) override;
|
||||||
GLFramebuffer* syncGPUObject(const Framebuffer& framebuffer) override;
|
GLFramebuffer* syncGPUObject(const Framebuffer& framebuffer) override;
|
||||||
|
|
||||||
|
|
|
@ -426,6 +426,13 @@ void Batch::generateTextureMips(const TexturePointer& texture) {
|
||||||
_params.emplace_back(_textures.cache(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) {
|
void Batch::beginQuery(const QueryPointer& query) {
|
||||||
ADD_COMMAND(beginQuery);
|
ADD_COMMAND(beginQuery);
|
||||||
|
|
||||||
|
|
|
@ -226,6 +226,8 @@ public:
|
||||||
|
|
||||||
// Generate the mips for a texture
|
// Generate the mips for a texture
|
||||||
void generateTextureMips(const TexturePointer& 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
|
// Query Section
|
||||||
void beginQuery(const QueryPointer& query);
|
void beginQuery(const QueryPointer& query);
|
||||||
|
@ -326,6 +328,7 @@ public:
|
||||||
COMMAND_clearFramebuffer,
|
COMMAND_clearFramebuffer,
|
||||||
COMMAND_blit,
|
COMMAND_blit,
|
||||||
COMMAND_generateTextureMips,
|
COMMAND_generateTextureMips,
|
||||||
|
COMMAND_generateTextureMipsWithPipeline,
|
||||||
|
|
||||||
COMMAND_advance,
|
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
|
#define GPU_TEXTURE_TRANSFORM_OBJECT 31
|
||||||
|
|
||||||
|
// Mip creation
|
||||||
|
#define GPU_TEXTURE_MIP_CREATION_INPUT 30
|
||||||
|
|
||||||
#define GPU_STORAGE_TRANSFORM_OBJECT 7
|
#define GPU_STORAGE_TRANSFORM_OBJECT 7
|
||||||
|
|
||||||
#define GPU_ATTR_POSITION 0
|
#define GPU_ATTR_POSITION 0
|
||||||
|
@ -67,7 +70,8 @@ enum Buffer {
|
||||||
namespace texture {
|
namespace texture {
|
||||||
enum Texture {
|
enum Texture {
|
||||||
ObjectTransforms = GPU_TEXTURE_TRANSFORM_OBJECT,
|
ObjectTransforms = GPU_TEXTURE_TRANSFORM_OBJECT,
|
||||||
};
|
MipCreationInput = GPU_TEXTURE_MIP_CREATION_INPUT,
|
||||||
|
};
|
||||||
} // namespace texture
|
} // namespace texture
|
||||||
|
|
||||||
namespace storage {
|
namespace storage {
|
||||||
|
|
Loading…
Reference in a new issue