mirror of
https://github.com/lubosz/overte.git
synced 2025-04-17 17:26:11 +02:00
First draft at batch generateTextureMipsWithPipeline
This commit is contained in:
parent
5978158358
commit
644ef33730
12 changed files with 124 additions and 44 deletions
|
@ -62,7 +62,8 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] =
|
|||
(&::gpu::gl::GLBackend::do_setFramebufferSwapChain),
|
||||
(&::gpu::gl::GLBackend::do_clearFramebuffer),
|
||||
(&::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),
|
||||
|
||||
|
@ -133,10 +134,23 @@ GLBackend::GLBackend() {
|
|||
|
||||
|
||||
GLBackend::~GLBackend() {
|
||||
if (_mipGenerationFramebufferId) {
|
||||
glDeleteFramebuffers(1, &_mipGenerationFramebufferId);
|
||||
_mipGenerationFramebufferId = 0;
|
||||
}
|
||||
killInput();
|
||||
killTransform();
|
||||
}
|
||||
|
||||
void GLBackend::do_draw(const Batch& batch, size_t paramOffset) {
|
||||
Primitive primitiveType = (Primitive)batch._params[paramOffset + 2]._uint;
|
||||
GLenum mode = gl::PRIMITIVE_TO_GL[primitiveType];
|
||||
uint32 numVertices = batch._params[paramOffset + 1]._uint;
|
||||
uint32 startVertex = batch._params[paramOffset + 0]._uint;
|
||||
|
||||
draw(mode, numVertices, startVertex);
|
||||
}
|
||||
|
||||
void GLBackend::renderPassTransfer(const Batch& batch) {
|
||||
const size_t numCommands = batch.getCommands().size();
|
||||
const Batch::Commands::value_type* command = batch.getCommands().data();
|
||||
|
|
|
@ -108,7 +108,7 @@ public:
|
|||
|
||||
|
||||
// Draw Stage
|
||||
virtual void do_draw(const Batch& batch, size_t paramOffset) = 0;
|
||||
virtual void do_draw(const Batch& batch, size_t paramOffset);
|
||||
virtual void do_drawIndexed(const Batch& batch, size_t paramOffset) = 0;
|
||||
virtual void do_drawInstanced(const Batch& batch, size_t paramOffset) = 0;
|
||||
virtual void do_drawIndexedInstanced(const Batch& batch, size_t paramOffset) = 0;
|
||||
|
@ -120,7 +120,8 @@ public:
|
|||
virtual void do_setInputBuffer(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_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
|
||||
virtual void do_setModelTransform(const Batch& batch, size_t paramOffset) final;
|
||||
|
@ -234,6 +235,8 @@ public:
|
|||
|
||||
protected:
|
||||
|
||||
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
|
||||
|
@ -492,6 +495,8 @@ protected:
|
|||
} _textureManagement;
|
||||
virtual void initTextureManagementStage() {}
|
||||
|
||||
GLuint _mipGenerationFramebufferId{ 0 };
|
||||
|
||||
typedef void (GLBackend::*CommandCall)(const Batch&, size_t);
|
||||
static CommandCall _commandCalls[Batch::NUM_COMMANDS];
|
||||
friend class GLState;
|
||||
|
|
|
@ -66,16 +66,58 @@ GLTexture* GLBackend::syncGPUObject(const TexturePointer& texturePointer) {
|
|||
}
|
||||
|
||||
void GLBackend::do_generateTextureMips(const Batch& batch, size_t paramOffset) {
|
||||
TexturePointer resourceTexture = batch._textures.get(batch._params[paramOffset + 0]._uint);
|
||||
if (!resourceTexture) {
|
||||
return;
|
||||
}
|
||||
TexturePointer resourceTexture = batch._textures.get(batch._params[paramOffset + 0]._uint);
|
||||
if (!resourceTexture) {
|
||||
return;
|
||||
}
|
||||
|
||||
// DO not transfer the texture, this call is expected for rendering texture
|
||||
GLTexture* object = syncGPUObject(resourceTexture);
|
||||
if (!object) {
|
||||
return;
|
||||
}
|
||||
// DO not transfer the texture, this call is expected for rendering texture
|
||||
GLTexture* object = syncGPUObject(resourceTexture);
|
||||
if (!object) {
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// Do not transfer the texture, this call is expected for rendering texture
|
||||
GLTexture* object = syncGPUObject(resourceTexture);
|
||||
if (!object) {
|
||||
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_EXT, 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);
|
||||
|
||||
resetOutputStage();
|
||||
}
|
||||
|
|
|
@ -20,12 +20,7 @@ using namespace gpu::gl41;
|
|||
|
||||
const std::string GL41Backend::GL41_VERSION { "GL41" };
|
||||
|
||||
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];
|
||||
uint32 numVertices = batch._params[paramOffset + 1]._uint;
|
||||
uint32 startVertex = batch._params[paramOffset + 0]._uint;
|
||||
|
||||
void GL41Backend::draw(GLenum mode, uint32 numVertices, uint32 startVertex) {
|
||||
if (isStereo()) {
|
||||
#ifdef GPU_STEREO_DRAWCALL_INSTANCED
|
||||
glDrawArraysInstanced(mode, startVertex, numVertices, 2);
|
||||
|
|
|
@ -133,6 +133,9 @@ public:
|
|||
};
|
||||
|
||||
protected:
|
||||
|
||||
void draw(GLenum mode, uint32 numVertices, uint32 startVertex) override;
|
||||
|
||||
GLuint getFramebufferID(const FramebufferPointer& framebuffer) override;
|
||||
GLFramebuffer* syncGPUObject(const Framebuffer& framebuffer) override;
|
||||
|
||||
|
@ -146,7 +149,6 @@ protected:
|
|||
GLQuery* syncGPUObject(const Query& query) override;
|
||||
|
||||
// Draw Stage
|
||||
void do_draw(const Batch& batch, size_t paramOffset) override;
|
||||
void do_drawIndexed(const Batch& batch, size_t paramOffset) override;
|
||||
void do_drawInstanced(const Batch& batch, size_t paramOffset) override;
|
||||
void do_drawIndexedInstanced(const Batch& batch, size_t paramOffset) override;
|
||||
|
|
|
@ -24,33 +24,28 @@ void GL45Backend::recycle() const {
|
|||
Parent::recycle();
|
||||
}
|
||||
|
||||
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];
|
||||
uint32 numVertices = batch._params[paramOffset + 1]._uint;
|
||||
uint32 startVertex = batch._params[paramOffset + 0]._uint;
|
||||
|
||||
if (isStereo()) {
|
||||
void GL45Backend::draw(GLenum mode, uint32 numVertices, uint32 startVertex) {
|
||||
if (isStereo()) {
|
||||
#ifdef GPU_STEREO_DRAWCALL_INSTANCED
|
||||
glDrawArraysInstanced(mode, startVertex, numVertices, 2);
|
||||
glDrawArraysInstanced(mode, startVertex, numVertices, 2);
|
||||
#else
|
||||
setupStereoSide(0);
|
||||
glDrawArrays(mode, startVertex, numVertices);
|
||||
setupStereoSide(1);
|
||||
glDrawArrays(mode, startVertex, numVertices);
|
||||
setupStereoSide(0);
|
||||
glDrawArrays(mode, startVertex, numVertices);
|
||||
setupStereoSide(1);
|
||||
glDrawArrays(mode, startVertex, numVertices);
|
||||
#endif
|
||||
|
||||
_stats._DSNumTriangles += 2 * numVertices / 3;
|
||||
_stats._DSNumDrawcalls += 2;
|
||||
_stats._DSNumTriangles += 2 * numVertices / 3;
|
||||
_stats._DSNumDrawcalls += 2;
|
||||
|
||||
} else {
|
||||
glDrawArrays(mode, startVertex, numVertices);
|
||||
_stats._DSNumTriangles += numVertices / 3;
|
||||
_stats._DSNumDrawcalls++;
|
||||
}
|
||||
_stats._DSNumAPIDrawcalls++;
|
||||
} else {
|
||||
glDrawArrays(mode, startVertex, numVertices);
|
||||
_stats._DSNumTriangles += numVertices / 3;
|
||||
_stats._DSNumDrawcalls++;
|
||||
}
|
||||
_stats._DSNumAPIDrawcalls++;
|
||||
|
||||
(void) CHECK_GL_ERROR();
|
||||
(void)CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
void GL45Backend::do_drawIndexed(const Batch& batch, size_t paramOffset) {
|
||||
|
|
|
@ -231,6 +231,7 @@ public:
|
|||
|
||||
protected:
|
||||
|
||||
void draw(GLenum mode, uint32 numVertices, uint32 startVertex) override;
|
||||
void recycle() const override;
|
||||
|
||||
GLuint getFramebufferID(const FramebufferPointer& framebuffer) override;
|
||||
|
@ -246,7 +247,6 @@ protected:
|
|||
|
||||
|
||||
// Draw Stage
|
||||
void do_draw(const Batch& batch, size_t paramOffset) override;
|
||||
void do_drawIndexed(const Batch& batch, size_t paramOffset) override;
|
||||
void do_drawInstanced(const Batch& batch, size_t paramOffset) override;
|
||||
void do_drawIndexedInstanced(const Batch& batch, size_t paramOffset) override;
|
||||
|
|
|
@ -425,6 +425,15 @@ void Batch::generateTextureMips(const TexturePointer& texture) {
|
|||
_params.emplace_back(_textures.cache(texture));
|
||||
}
|
||||
|
||||
void Batch::generateTextureMipsWithPipeline(const TexturePointer& texture, int numMips) {
|
||||
setResourceTexture(0, texture);
|
||||
|
||||
ADD_COMMAND(generateTextureMipsWithPipeline);
|
||||
|
||||
_params.emplace_back(_textures.cache(texture));
|
||||
_params.emplace_back(numMips);
|
||||
}
|
||||
|
||||
void Batch::beginQuery(const QueryPointer& query) {
|
||||
ADD_COMMAND(beginQuery);
|
||||
|
||||
|
|
|
@ -211,7 +211,9 @@ public:
|
|||
void blit(const FramebufferPointer& src, const Vec4i& srcRect, const FramebufferPointer& dst, const Vec4i& dstRect);
|
||||
|
||||
// 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& texture, int numMips = -1);
|
||||
|
||||
// Query Section
|
||||
void beginQuery(const QueryPointer& query);
|
||||
|
@ -310,7 +312,8 @@ public:
|
|||
COMMAND_setFramebufferSwapChain,
|
||||
COMMAND_clearFramebuffer,
|
||||
COMMAND_blit,
|
||||
COMMAND_generateTextureMips,
|
||||
COMMAND_generateTextureMips,
|
||||
COMMAND_generateTextureMipsWithPipeline,
|
||||
|
||||
COMMAND_advance,
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include "Frame.h"
|
||||
#include "GPULogging.h"
|
||||
#include "StandardShaderLib.h"
|
||||
|
||||
using namespace gpu;
|
||||
|
||||
|
@ -317,3 +318,14 @@ Size Context::getTexturePendingGPUTransferMemSize() {
|
|||
Size Context::getTextureResourcePopulatedGPUMemSize() {
|
||||
return Backend::textureResourcePopulatedGPUMemSize.getValue();
|
||||
}
|
||||
|
||||
PipelinePointer Context::createMipGenerationPipeline(const ShaderPointer& ps, const gpu::Shader::BindingSet& slotBindings) {
|
||||
auto vs = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS();
|
||||
static gpu::StatePointer state(new gpu::State());
|
||||
|
||||
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
|
||||
// Good to go add the brand new pipeline
|
||||
return gpu::Pipeline::create(program, state);
|
||||
}
|
||||
|
|
|
@ -220,6 +220,8 @@ public:
|
|||
// Same as above but grabbed at every end of a frame
|
||||
void getFrameStats(ContextStats& stats) const;
|
||||
|
||||
static PipelinePointer createMipGenerationPipeline(const ShaderPointer& pixelShader, const gpu::Shader::BindingSet& slotBindings = gpu::Shader::BindingSet());
|
||||
|
||||
double getFrameTimerGPUAverage() const;
|
||||
double getFrameTimerBatchAverage() const;
|
||||
|
||||
|
|
|
@ -313,6 +313,7 @@ float evalAO(in vec3 C, in vec3 n_C, in vec3 Q) {
|
|||
// the source occlusion texture
|
||||
uniform sampler2D occlusionMap;
|
||||
|
||||
|
||||
vec2 fetchOcclusionDepthRaw(ivec2 coords, out vec3 raw) {
|
||||
raw = texelFetch(occlusionMap, coords, 0).xyz;
|
||||
return unpackOcclusionDepth(raw);
|
||||
|
|
Loading…
Reference in a new issue