mirror of
https://github.com/lubosz/overte.git
synced 2025-04-16 09:46:29 +02:00
Bindless texture work cleanup
This commit is contained in:
parent
d858d34523
commit
09996e0b65
19 changed files with 152 additions and 239 deletions
|
@ -36,7 +36,6 @@
|
|||
//#define GPU_STEREO_TECHNIQUE_DOUBLED_SMARTER
|
||||
#define GPU_STEREO_TECHNIQUE_INSTANCED
|
||||
|
||||
|
||||
// Let these be configured by the one define picked above
|
||||
#ifdef GPU_STEREO_TECHNIQUE_DOUBLED_SIMPLE
|
||||
#define GPU_STEREO_DRAWCALL_DOUBLED
|
||||
|
@ -52,6 +51,8 @@
|
|||
#define GPU_STEREO_CAMERA_BUFFER
|
||||
#endif
|
||||
|
||||
#define GPU_BINDLESS_TEXTURES 0
|
||||
|
||||
namespace gpu { namespace gl {
|
||||
|
||||
class GLBackend : public Backend, public std::enable_shared_from_this<GLBackend> {
|
||||
|
@ -132,7 +133,7 @@ public:
|
|||
// Resource Stage
|
||||
virtual void do_setResourceBuffer(const Batch& batch, size_t paramOffset) final;
|
||||
virtual void do_setResourceTexture(const Batch& batch, size_t paramOffset) final;
|
||||
virtual void do_setResourceTextureTable(const Batch& batch, size_t paramOffset) = 0;
|
||||
virtual void do_setResourceTextureTable(const Batch& batch, size_t paramOffset);
|
||||
|
||||
// Pipeline Stage
|
||||
virtual void do_setPipeline(const Batch& batch, size_t paramOffset) final;
|
||||
|
@ -229,6 +230,10 @@ protected:
|
|||
|
||||
void recycle() const override;
|
||||
|
||||
// FIXME instead of a single flag, create a features struct similar to
|
||||
// https://www.khronos.org/registry/vulkan/specs/1.0/man/html/VkPhysicalDeviceFeatures.html
|
||||
virtual bool supportsBindless() const { return false; }
|
||||
|
||||
static const size_t INVALID_OFFSET = (size_t)-1;
|
||||
bool _inRenderTransferPass { false };
|
||||
int32_t _uboAlignment { 0 };
|
||||
|
@ -383,6 +388,10 @@ protected:
|
|||
virtual bool bindResourceBuffer(uint32_t slot, BufferPointer& buffer) = 0;
|
||||
virtual void releaseResourceBuffer(uint32_t slot) = 0;
|
||||
|
||||
// Helper function that provides common code used by do_setResourceTexture and
|
||||
// do_setResourceTextureTable (in non-bindless mode)
|
||||
void bindResourceTexture(uint32_t slot, const TexturePointer& texture);
|
||||
|
||||
// update resource cache and do the gl unbind call with the current gpu::Texture cached at slot s
|
||||
void releaseResourceTexture(uint32_t slot);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//
|
||||
//
|
||||
// GLBackendPipeline.cpp
|
||||
// libraries/gpu/src/gpu
|
||||
//
|
||||
|
@ -9,6 +9,8 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
#include "GLBackend.h"
|
||||
#include <gpu/TextureTable.h>
|
||||
|
||||
#include "GLShared.h"
|
||||
#include "GLPipeline.h"
|
||||
#include "GLShader.h"
|
||||
|
@ -247,8 +249,11 @@ void GLBackend::do_setResourceTexture(const Batch& batch, size_t paramOffset) {
|
|||
return;
|
||||
}
|
||||
|
||||
TexturePointer resourceTexture = batch._textures.get(batch._params[paramOffset + 0]._uint);
|
||||
const auto& resourceTexture = batch._textures.get(batch._params[paramOffset + 0]._uint);
|
||||
bindResourceTexture(slot, resourceTexture);
|
||||
}
|
||||
|
||||
void GLBackend::bindResourceTexture(uint32_t slot, const TexturePointer& resourceTexture) {
|
||||
if (!resourceTexture) {
|
||||
releaseResourceTexture(slot);
|
||||
return;
|
||||
|
@ -269,11 +274,11 @@ void GLBackend::do_setResourceTexture(const Batch& batch, size_t paramOffset) {
|
|||
glActiveTexture(GL_TEXTURE0 + slot);
|
||||
glBindTexture(target, to);
|
||||
|
||||
(void) CHECK_GL_ERROR();
|
||||
(void)CHECK_GL_ERROR();
|
||||
|
||||
_resource._textures[slot] = resourceTexture;
|
||||
|
||||
_stats._RSAmountTextureMemoryBounded += (int) object->size();
|
||||
_stats._RSAmountTextureMemoryBounded += (int)object->size();
|
||||
|
||||
} else {
|
||||
releaseResourceTexture(slot);
|
||||
|
@ -281,6 +286,19 @@ void GLBackend::do_setResourceTexture(const Batch& batch, size_t paramOffset) {
|
|||
}
|
||||
}
|
||||
|
||||
void GLBackend::do_setResourceTextureTable(const Batch& batch, size_t paramOffset) {
|
||||
const auto& textureTablePointer = batch._textureTables.get(batch._params[paramOffset]._uint);
|
||||
if (!textureTablePointer) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& textureTable = *textureTablePointer;
|
||||
const auto& textures = textureTable.getTextures();
|
||||
for (GLuint slot = 0; slot < textures.size(); ++slot) {
|
||||
bindResourceTexture(slot, textures[slot]);
|
||||
}
|
||||
}
|
||||
|
||||
int GLBackend::ResourceStageState::findEmptyTextureSlot() const {
|
||||
// start from the end of the slots, try to find an empty one that can be used
|
||||
for (auto i = MAX_NUM_RESOURCE_TEXTURES - 1; i > 0; i--) {
|
||||
|
@ -290,4 +308,3 @@ int GLBackend::ResourceStageState::findEmptyTextureSlot() const {
|
|||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -55,7 +55,6 @@ static const std::string textureTableVersion {
|
|||
"#extension GL_ARB_bindless_texture : require\n#define GPU_TEXTURE_TABLE_BINDLESS\n"
|
||||
};
|
||||
|
||||
|
||||
// Versions specific of the shader
|
||||
static const std::array<std::string, GLShader::NumVersions> VERSION_DEFINES { {
|
||||
"",
|
||||
|
@ -70,15 +69,13 @@ GLShader* GLBackend::compileBackendShader(const Shader& shader, const Shader::Co
|
|||
Shader::CompilationLogs compilationLogs(GLShader::NumVersions);
|
||||
shader.incrementCompilationAttempt();
|
||||
|
||||
bool supportTextureTableBindless = true;
|
||||
|
||||
for (int version = 0; version < GLShader::NumVersions; version++) {
|
||||
auto& shaderObject = shaderObjects[version];
|
||||
|
||||
std::string shaderDefines = getBackendShaderHeader() + "\n"
|
||||
+ (supportTextureTableBindless ? textureTableVersion : "\n")
|
||||
+ DOMAIN_DEFINES[shader.getType()] + "\n"
|
||||
+ VERSION_DEFINES[version];
|
||||
+ (supportsBindless() ? textureTableVersion : "\n")
|
||||
+ DOMAIN_DEFINES[shader.getType()] + "\n"
|
||||
+ VERSION_DEFINES[version];
|
||||
if (handler) {
|
||||
bool retest = true;
|
||||
std::string currentSrc = shaderSource;
|
||||
|
|
|
@ -73,9 +73,7 @@ bool GLShader::makeProgram(GLBackend& backend, Shader& shader, const Shader::Bin
|
|||
|
||||
Shader::SlotSet uniforms;
|
||||
Shader::SlotSet textures;
|
||||
Shader::SlotSet textureTables;
|
||||
Shader::SlotSet samplers;
|
||||
//backend.makeUniformSlots(shaderObject.glprogram, slotBindings, uniforms, textures, textureTables, samplers);
|
||||
backend.makeUniformSlots(shaderObject.glprogram, slotBindings, uniforms, textures, samplers);
|
||||
|
||||
Shader::SlotSet resourceBuffers;
|
||||
|
|
|
@ -17,8 +17,6 @@ struct ShaderObject {
|
|||
GLuint glprogram { 0 };
|
||||
GLint transformCameraSlot { -1 };
|
||||
GLint transformObjectSlot { -1 };
|
||||
GLint resourceTextureTableSlot0 { -1 };
|
||||
GLint resourceTextureTableSlot1 { -1 };
|
||||
};
|
||||
|
||||
class GLShader : public GPUObject {
|
||||
|
|
|
@ -157,9 +157,6 @@ protected:
|
|||
void resetInputStage() override;
|
||||
void updateInput() override;
|
||||
|
||||
// Resource stage
|
||||
void do_setResourceTextureTable(const Batch& batch, size_t paramOffset) override;
|
||||
|
||||
// Synchronize the state cache of this Backend with the actual real state of the GL Context
|
||||
void transferTransformState(const Batch& batch) const override;
|
||||
void initTransform() override;
|
||||
|
|
|
@ -606,7 +606,3 @@ GL41ResourceTexture::GL41ResourceTexture(const std::weak_ptr<GLBackend>& backend
|
|||
|
||||
GL41ResourceTexture::~GL41ResourceTexture() {
|
||||
}
|
||||
|
||||
void GL41Backend::do_setResourceTextureTable(const Batch& batch, size_t paramOffset) {
|
||||
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
#define INCREMENTAL_TRANSFER 0
|
||||
#define GPU_SSBO_TRANSFORM_OBJECT 1
|
||||
#define GPU_BINDLESS_TEXTURES 1
|
||||
|
||||
namespace gpu { namespace gl45 {
|
||||
|
||||
|
@ -32,6 +31,9 @@ class GL45Backend : public GLBackend {
|
|||
friend class Context;
|
||||
|
||||
public:
|
||||
#if GPU_BINDLESS_TEXTURES
|
||||
virtual bool supportsBindless() const override { return true; }
|
||||
#endif
|
||||
|
||||
#ifdef GPU_SSBO_TRANSFORM_OBJECT
|
||||
static const GLint TRANSFORM_OBJECT_SLOT { 14 }; // SSBO binding slot
|
||||
|
@ -60,15 +62,11 @@ public:
|
|||
Size copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const uvec3& size, uint32_t yOffset, GLenum internalFormat, GLenum format, GLenum type, Size sourceSize, const void* sourcePointer) const override;
|
||||
void syncSampler() const override;
|
||||
|
||||
bool isBindless() const {
|
||||
#if GPU_BINDLESS_TEXTURES
|
||||
bool isBindless() const {
|
||||
return _bindless.operator bool();
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if GPU_BINDLESS_TEXTURES
|
||||
struct Bindless {
|
||||
uint64_t handle{ 0 };
|
||||
uint32_t minMip{ 0 };
|
||||
|
@ -90,10 +88,9 @@ public:
|
|||
virtual const Bindless& getBindless() const;
|
||||
void releaseBindless() const;
|
||||
void recreateBindless() const;
|
||||
virtual uint16 getMinMip() const = 0;
|
||||
|
||||
|
||||
private:
|
||||
mutable Bindless _bindless;
|
||||
#endif
|
||||
class InvalidSampler : public Sampler {
|
||||
public:
|
||||
InvalidSampler() {
|
||||
|
@ -108,10 +105,6 @@ public:
|
|||
static const Sampler INVALID_SAMPLER;
|
||||
// This stores the texture handle (64 bits) in xy, the min mip available in z, and the sampler ID in w
|
||||
mutable Sampler _cachedSampler{ INVALID_SAMPLER };
|
||||
|
||||
mutable Bindless _bindless;
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
#if GPU_BINDLESS_TEXTURES
|
||||
|
@ -147,7 +140,6 @@ public:
|
|||
|
||||
protected:
|
||||
Size size() const override { return _size; }
|
||||
uint16 getMinMip() const override { return 0; }
|
||||
|
||||
void allocateStorage() const;
|
||||
void syncSampler() const override;
|
||||
|
@ -179,18 +171,18 @@ public:
|
|||
friend class GL45Backend;
|
||||
using PromoteLambda = std::function<void()>;
|
||||
|
||||
const uvec4& getHandle();
|
||||
protected:
|
||||
GL45VariableAllocationTexture(const std::weak_ptr<GLBackend>& backend, const Texture& texture);
|
||||
~GL45VariableAllocationTexture();
|
||||
|
||||
Size size() const override { return _size; }
|
||||
uint16 getMinMip() const override { return _populatedMip - _allocatedMip; }
|
||||
virtual const Bindless& getBindless() const override;
|
||||
|
||||
Size copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const uvec3& size, uint32_t yOffset, GLenum internalFormat, GLenum format, GLenum type, Size sourceSize, const void* sourcePointer) const override;
|
||||
void copyTextureMipsInGPUMem(GLuint srcId, GLuint destId, uint16_t srcMipOffset, uint16_t destMipOffset, uint16_t populatedMips) override;
|
||||
|
||||
#if GPU_BINDLESS_TEXTURES
|
||||
virtual const Bindless& getBindless() const override;
|
||||
#endif
|
||||
};
|
||||
|
||||
class GL45ResourceTexture : public GL45VariableAllocationTexture {
|
||||
|
@ -259,7 +251,6 @@ protected:
|
|||
GLuint getQueryID(const QueryPointer& query) override;
|
||||
GLQuery* syncGPUObject(const Query& query) override;
|
||||
|
||||
GL45TextureTable* syncGPUObject(const TextureTablePointer& textureTable);
|
||||
|
||||
// Draw Stage
|
||||
void do_draw(const Batch& batch, size_t paramOffset) override;
|
||||
|
@ -273,9 +264,6 @@ protected:
|
|||
void resetInputStage() override;
|
||||
void updateInput() override;
|
||||
|
||||
// Resource stage
|
||||
void do_setResourceTextureTable(const Batch& batch, size_t paramOffset) override;
|
||||
|
||||
// Synchronize the state cache of this Backend with the actual real state of the GL Context
|
||||
void transferTransformState(const Batch& batch) const override;
|
||||
void initTransform() override;
|
||||
|
@ -295,6 +283,12 @@ protected:
|
|||
|
||||
// Texture Management Stage
|
||||
void initTextureManagementStage() override;
|
||||
|
||||
#if GPU_BINDLESS_TEXTURES
|
||||
GL45TextureTable* syncGPUObject(const TextureTablePointer& textureTable);
|
||||
// Resource stage
|
||||
void do_setResourceTextureTable(const Batch& batch, size_t paramOffset) override;
|
||||
#endif
|
||||
};
|
||||
|
||||
} }
|
||||
|
|
|
@ -29,9 +29,6 @@ using namespace gpu::gl;
|
|||
using namespace gpu::gl45;
|
||||
|
||||
#define MAX_RESOURCE_TEXTURES_PER_FRAME 2
|
||||
|
||||
#pragma optimize("", off)
|
||||
|
||||
#define FORCE_STRICT_TEXTURE 0
|
||||
#define ENABLE_SPARSE_TEXTURE 0
|
||||
|
||||
|
@ -243,6 +240,7 @@ Size GL45Texture::copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const
|
|||
return amountCopied;
|
||||
}
|
||||
|
||||
#if GPU_BINDLESS_TEXTURES
|
||||
void GL45Texture::releaseBindless() const {
|
||||
// Release the old handler
|
||||
SAMPLER_CACHE.releaseGLSampler(_bindless.sampler);
|
||||
|
@ -267,9 +265,10 @@ const GL45Texture::Bindless& GL45Texture::getBindless() const {
|
|||
if (!_bindless) {
|
||||
recreateBindless();
|
||||
}
|
||||
_bindless.minMip = getMinMip();
|
||||
return _bindless;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void GL45Texture::syncSampler() const {
|
||||
const Sampler& sampler = _gpuObject.getSampler();
|
||||
|
@ -279,31 +278,33 @@ void GL45Texture::syncSampler() const {
|
|||
|
||||
_cachedSampler = sampler;
|
||||
|
||||
#if GPU_BINDLESS_TEXTURES
|
||||
if (isBindless()) {
|
||||
recreateBindless();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
const auto& fm = FILTER_MODES[sampler.getFilter()];
|
||||
glTextureParameteri(_id, GL_TEXTURE_MIN_FILTER, fm.minFilter);
|
||||
glTextureParameteri(_id, GL_TEXTURE_MAG_FILTER, fm.magFilter);
|
||||
|
||||
if (sampler.doComparison()) {
|
||||
glTextureParameteri(_id, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE_ARB);
|
||||
glTextureParameteri(_id, GL_TEXTURE_COMPARE_FUNC, COMPARISON_TO_GL[sampler.getComparisonFunction()]);
|
||||
} else {
|
||||
const auto& fm = FILTER_MODES[sampler.getFilter()];
|
||||
glTextureParameteri(_id, GL_TEXTURE_MIN_FILTER, fm.minFilter);
|
||||
glTextureParameteri(_id, GL_TEXTURE_MAG_FILTER, fm.magFilter);
|
||||
|
||||
if (sampler.doComparison()) {
|
||||
glTextureParameteri(_id, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE_ARB);
|
||||
glTextureParameteri(_id, GL_TEXTURE_COMPARE_FUNC, COMPARISON_TO_GL[sampler.getComparisonFunction()]);
|
||||
} else {
|
||||
glTextureParameteri(_id, GL_TEXTURE_COMPARE_MODE, GL_NONE);
|
||||
}
|
||||
|
||||
glTextureParameteri(_id, GL_TEXTURE_WRAP_S, WRAP_MODES[sampler.getWrapModeU()]);
|
||||
glTextureParameteri(_id, GL_TEXTURE_WRAP_T, WRAP_MODES[sampler.getWrapModeV()]);
|
||||
glTextureParameteri(_id, GL_TEXTURE_WRAP_R, WRAP_MODES[sampler.getWrapModeW()]);
|
||||
|
||||
glTextureParameterf(_id, GL_TEXTURE_MAX_ANISOTROPY_EXT, sampler.getMaxAnisotropy());
|
||||
glTextureParameterfv(_id, GL_TEXTURE_BORDER_COLOR, (const float*)&sampler.getBorderColor());
|
||||
|
||||
glTextureParameterf(_id, GL_TEXTURE_MIN_LOD, sampler.getMinMip());
|
||||
glTextureParameterf(_id, GL_TEXTURE_MAX_LOD, (sampler.getMaxMip() == Sampler::MAX_MIP_LEVEL ? 1000.f : sampler.getMaxMip()));
|
||||
glTextureParameteri(_id, GL_TEXTURE_COMPARE_MODE, GL_NONE);
|
||||
}
|
||||
(void)CHECK_GL_ERROR();
|
||||
|
||||
glTextureParameteri(_id, GL_TEXTURE_WRAP_S, WRAP_MODES[sampler.getWrapModeU()]);
|
||||
glTextureParameteri(_id, GL_TEXTURE_WRAP_T, WRAP_MODES[sampler.getWrapModeV()]);
|
||||
glTextureParameteri(_id, GL_TEXTURE_WRAP_R, WRAP_MODES[sampler.getWrapModeW()]);
|
||||
|
||||
glTextureParameterf(_id, GL_TEXTURE_MAX_ANISOTROPY_EXT, sampler.getMaxAnisotropy());
|
||||
glTextureParameterfv(_id, GL_TEXTURE_BORDER_COLOR, (const float*)&sampler.getBorderColor());
|
||||
|
||||
glTextureParameterf(_id, GL_TEXTURE_MIN_LOD, sampler.getMinMip());
|
||||
glTextureParameterf(_id, GL_TEXTURE_MAX_LOD, (sampler.getMaxMip() == Sampler::MAX_MIP_LEVEL ? 1000.f : sampler.getMaxMip()));
|
||||
}
|
||||
|
||||
// Fixed allocation textures, used for strict resources & framebuffer attachments
|
||||
|
@ -378,6 +379,7 @@ GL45StrictResourceTexture::~GL45StrictResourceTexture() {
|
|||
}
|
||||
|
||||
// Encapsulate bindless textures
|
||||
#if GPU_BINDLESS_TEXTURES
|
||||
using GL45TextureTable = GL45Backend::GL45TextureTable;
|
||||
|
||||
GLuint GL45TextureTable::allocate() {
|
||||
|
@ -416,10 +418,14 @@ GL45TextureTable* GL45Backend::syncGPUObject(const TextureTablePointer& textureT
|
|||
const auto& textureTable = *textureTablePointer;
|
||||
|
||||
// Find the target handles
|
||||
auto defaultTextures = gpu::TextureTable::getDefault()->getTextures();
|
||||
auto textures = textureTable.getTextures();
|
||||
GL45TextureTable::BindlessArray handles{};
|
||||
for (size_t i = 0; i < textures.size(); ++i) {
|
||||
auto texture = textures[i];
|
||||
if (!texture) {
|
||||
texture = defaultTextures[i];
|
||||
}
|
||||
if (!texture) {
|
||||
continue;
|
||||
}
|
||||
|
@ -444,10 +450,15 @@ GL45TextureTable* GL45Backend::syncGPUObject(const TextureTablePointer& textureT
|
|||
}
|
||||
|
||||
void GL45Backend::do_setResourceTextureTable(const Batch& batch, size_t paramOffset) {
|
||||
auto textureTable = batch._textureTables.get(batch._params[paramOffset]._uint);
|
||||
auto textureTablePointer = batch._textureTables.get(batch._params[paramOffset]._uint);
|
||||
if (!textureTablePointer) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto slot = batch._params[paramOffset + 1]._uint;
|
||||
GL45TextureTable* glTextureTable = syncGPUObject(textureTable);
|
||||
GL45TextureTable* glTextureTable = syncGPUObject(textureTablePointer);
|
||||
if (glTextureTable) {
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, slot + GLBackend::RESOURCE_TABLE_TEXTURE_SLOT_OFFSET, glTextureTable->_id);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -41,11 +41,16 @@ GL45VariableAllocationTexture::~GL45VariableAllocationTexture() {
|
|||
Backend::textureResourcePopulatedGPUMemSize.update(_populatedSize, 0);
|
||||
}
|
||||
|
||||
#if GPU_BINDLESS_TEXTURES
|
||||
const GL45Texture::Bindless& GL45VariableAllocationTexture::getBindless() const {
|
||||
auto& result = Parent::getBindless();
|
||||
// The parent call may re-initialize the _bindless member, so we need to call it first
|
||||
const auto& result = Parent::getBindless();
|
||||
// Make sure the referenced structure has the correct minimum available mip value
|
||||
_bindless.minMip = _populatedMip - _allocatedMip;
|
||||
// Now return the result
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
Size GL45VariableAllocationTexture::copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const uvec3& size, uint32_t yOffset, GLenum internalFormat, GLenum format, GLenum type, Size sourceSize, const void* sourcePointer) const {
|
||||
Size amountCopied = 0;
|
||||
|
@ -134,9 +139,13 @@ Size GL45ResourceTexture::copyMipsFromTexture() {
|
|||
|
||||
void GL45ResourceTexture::syncSampler() const {
|
||||
Parent::syncSampler();
|
||||
#if GPU_BINDLESS_TEXTURES
|
||||
if (!isBindless()) {
|
||||
glTextureParameteri(_id, GL_TEXTURE_BASE_LEVEL, _populatedMip - _allocatedMip);
|
||||
}
|
||||
#else
|
||||
glTextureParameteri(_id, GL_TEXTURE_BASE_LEVEL, _populatedMip - _allocatedMip);
|
||||
#endif
|
||||
}
|
||||
|
||||
void GL45ResourceTexture::promote() {
|
||||
|
@ -146,10 +155,12 @@ void GL45ResourceTexture::promote() {
|
|||
uint16_t targetAllocatedMip = _allocatedMip - std::min<uint16_t>(_allocatedMip, 2);
|
||||
targetAllocatedMip = std::max<uint16_t>(_minAllocatedMip, targetAllocatedMip);
|
||||
|
||||
#if GPU_BINDLESS_TEXTURES
|
||||
bool bindless = isBindless();
|
||||
if (bindless) {
|
||||
releaseBindless();
|
||||
}
|
||||
#endif
|
||||
|
||||
GLuint oldId = _id;
|
||||
auto oldSize = _size;
|
||||
|
@ -164,14 +175,17 @@ void GL45ResourceTexture::promote() {
|
|||
// copy pre-existing mips
|
||||
copyTextureMipsInGPUMem(oldId, _id, oldAllocatedMip, _allocatedMip, _populatedMip);
|
||||
|
||||
#if GPU_BINDLESS_TEXTURES
|
||||
if (bindless) {
|
||||
getBindless();
|
||||
}
|
||||
#endif
|
||||
|
||||
// destroy the old texture
|
||||
glDeleteTextures(1, &oldId);
|
||||
|
||||
// Update sampler
|
||||
_cachedSampler = InvalidSampler();
|
||||
syncSampler();
|
||||
|
||||
// update the memory usage
|
||||
|
@ -188,10 +202,12 @@ void GL45ResourceTexture::demote() {
|
|||
auto oldSize = _size;
|
||||
auto oldPopulatedMip = _populatedMip;
|
||||
|
||||
#if GPU_BINDLESS_TEXTURES
|
||||
bool bindless = isBindless();
|
||||
if (bindless) {
|
||||
releaseBindless();
|
||||
}
|
||||
#endif
|
||||
|
||||
// allocate new texture
|
||||
const_cast<GLuint&>(_id) = allocate(_gpuObject);
|
||||
|
@ -202,14 +218,17 @@ void GL45ResourceTexture::demote() {
|
|||
// copy pre-existing mips
|
||||
copyTextureMipsInGPUMem(oldId, _id, oldAllocatedMip, _allocatedMip, _populatedMip);
|
||||
|
||||
#if GPU_BINDLESS_TEXTURES
|
||||
if (bindless) {
|
||||
getBindless();
|
||||
}
|
||||
#endif
|
||||
|
||||
// destroy the old texture
|
||||
glDeleteTextures(1, &oldId);
|
||||
|
||||
// Update sampler
|
||||
_cachedSampler = InvalidSampler();
|
||||
syncSampler();
|
||||
|
||||
// update the memory usage
|
||||
|
|
|
@ -325,16 +325,16 @@ void Batch::setResourceTexture(uint32 slot, const TexturePointer& texture) {
|
|||
_params.emplace_back(slot);
|
||||
}
|
||||
|
||||
void Batch::setResourceTexture(uint32 slot, const TextureView& view) {
|
||||
setResourceTexture(slot, view._texture);
|
||||
}
|
||||
|
||||
void Batch::setResourceTextureTable(const TextureTablePointer& textureTable, uint32 slot) {
|
||||
ADD_COMMAND(setResourceTextureTable);
|
||||
_params.emplace_back(_textureTables.cache(textureTable));
|
||||
_params.emplace_back(slot);
|
||||
}
|
||||
|
||||
void Batch::setResourceTexture(uint32 slot, const TextureView& view) {
|
||||
setResourceTexture(slot, view._texture);
|
||||
}
|
||||
|
||||
void Batch::setFramebuffer(const FramebufferPointer& framebuffer) {
|
||||
ADD_COMMAND(setFramebuffer);
|
||||
|
||||
|
|
|
@ -30,11 +30,6 @@ class QDebug;
|
|||
namespace gpu {
|
||||
|
||||
enum ReservedSlot {
|
||||
#ifdef GPU_SSBO_DRAW_CALL_INFO
|
||||
TRANSFORM_OBJECT_SLOT = 14,
|
||||
#else
|
||||
TRANSFORM_OBJECT_SLOT = 31,
|
||||
#endif
|
||||
TRANSFORM_CAMERA_SLOT = 15,
|
||||
};
|
||||
|
||||
|
@ -409,9 +404,10 @@ public:
|
|||
return offset;
|
||||
}
|
||||
|
||||
Data get(uint32 offset) const {
|
||||
const Data& get(uint32 offset) const {
|
||||
if (offset >= _items.size()) {
|
||||
return Data();
|
||||
static const Data EMPTY;
|
||||
return EMPTY;
|
||||
}
|
||||
return (_items.data() + offset)->_data;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "TextureTable.h"
|
||||
#include "Texture.h"
|
||||
|
||||
#include <shared/GlobalAppProperties.h>
|
||||
using namespace gpu;
|
||||
|
||||
TextureTable::TextureTable() { }
|
||||
|
@ -42,7 +43,9 @@ void TextureTable::setTexture(size_t index, const TextureView& textureView) {
|
|||
|
||||
TextureTable::Array TextureTable::getTextures() const {
|
||||
Array result;
|
||||
Lock lock(_mutex);
|
||||
result = _textures;
|
||||
{
|
||||
Lock lock(_mutex);
|
||||
result = _textures;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ public:
|
|||
|
||||
Array getTextures() const;
|
||||
Stamp getStamp() const { return _stamp; }
|
||||
|
||||
private:
|
||||
mutable Mutex _mutex;
|
||||
Array _textures;
|
||||
|
|
|
@ -24,8 +24,6 @@
|
|||
|
||||
class Transform;
|
||||
|
||||
#define USE_BINDLESS_TEXTURES 1
|
||||
|
||||
namespace graphics {
|
||||
|
||||
class TextureMap;
|
||||
|
@ -363,10 +361,7 @@ public:
|
|||
|
||||
void setModel(const std::string& model) { _model = model; }
|
||||
|
||||
#if USE_BINDLESS_TEXTURES
|
||||
const gpu::TextureTablePointer& getTextureTable() const { return _textureTable; }
|
||||
void setTextureTable(const gpu::TextureTablePointer& textureTable) { _textureTable = textureTable; }
|
||||
#endif
|
||||
|
||||
protected:
|
||||
std::string _name { "" };
|
||||
|
@ -375,9 +370,7 @@ private:
|
|||
mutable MaterialKey _key;
|
||||
mutable UniformBufferView _schemaBuffer;
|
||||
mutable UniformBufferView _texMapArrayBuffer;
|
||||
#if USE_BINDLESS_TEXTURES
|
||||
mutable gpu::TextureTablePointer _textureTable;
|
||||
#endif
|
||||
mutable gpu::TextureTablePointer _textureTable{ std::make_shared<gpu::TextureTable>() };
|
||||
|
||||
TextureMaps _textureMaps;
|
||||
|
||||
|
|
|
@ -48,10 +48,10 @@ TexMapArray getTexMapArray() {
|
|||
|
||||
<@func declareMaterialTextures(withAlbedo, withRoughness, withNormal, withMetallic, withEmissive, withOcclusion, withScattering)@>
|
||||
|
||||
|
||||
|
||||
<@include gpu/TextureTable.slh@>
|
||||
|
||||
#ifdef GPU_TEXTURE_TABLE_BINDLESS
|
||||
|
||||
TextureTable(0, matTex);
|
||||
<!
|
||||
ALBEDO = 0,
|
||||
|
@ -114,8 +114,7 @@ float fetchScatteringMap(vec2 uv) {
|
|||
}
|
||||
<@endif@>
|
||||
|
||||
<!
|
||||
<@else@>
|
||||
#else
|
||||
|
||||
<@if withAlbedo@>
|
||||
uniform sampler2D albedoMap;
|
||||
|
@ -170,8 +169,8 @@ float fetchScatteringMap(vec2 uv) {
|
|||
return texture(scatteringMap, uv).r; // boolean scattering for now
|
||||
}
|
||||
<@endif@>
|
||||
<@endif@>
|
||||
!>
|
||||
|
||||
#endif
|
||||
|
||||
<@endfunc@>
|
||||
|
||||
|
|
|
@ -14,8 +14,6 @@
|
|||
#include <PerfStat.h>
|
||||
#include <DualQuaternion.h>
|
||||
|
||||
#include <gpu/TextureTable.h>
|
||||
|
||||
#include "DeferredLightingEffect.h"
|
||||
|
||||
#include "RenderPipelines.h"
|
||||
|
|
|
@ -612,22 +612,8 @@ void initZPassPipelines(ShapePlumber& shapePlumber, gpu::StatePointer state) {
|
|||
#include "RenderPipelines.h"
|
||||
#include <model-networking/TextureCache.h>
|
||||
|
||||
#if USE_BINDLESS_TEXTURES
|
||||
gpu::TextureTablePointer makeTextureTable() {
|
||||
auto textureCache = DependencyManager::get<TextureCache>();
|
||||
auto textureTable = std::make_shared<gpu::TextureTable>();
|
||||
textureTable->setTexture(ShapePipeline::Slot::ALBEDO, textureCache->getWhiteTexture());
|
||||
textureTable->setTexture(ShapePipeline::Slot::ROUGHNESS, textureCache->getWhiteTexture());
|
||||
textureTable->setTexture(ShapePipeline::Slot::NORMAL, textureCache->getBlueTexture());
|
||||
textureTable->setTexture(ShapePipeline::Slot::METALLIC, textureCache->getBlackTexture());
|
||||
textureTable->setTexture(ShapePipeline::Slot::OCCLUSION, textureCache->getWhiteTexture());
|
||||
textureTable->setTexture(ShapePipeline::Slot::SCATTERING, textureCache->getWhiteTexture());
|
||||
textureTable->setTexture(ShapePipeline::Slot::EMISSIVE_LIGHTMAP, textureCache->getBlackTexture());
|
||||
return textureTable;
|
||||
}
|
||||
#endif
|
||||
|
||||
void RenderPipelines::bindMaterial(graphics::MaterialPointer material, gpu::Batch& batch, bool enableTextures) {
|
||||
// FIXME find a better way to setup the default textures
|
||||
void RenderPipelines::bindMaterial(const graphics::MaterialPointer& material, gpu::Batch& batch, bool enableTextures) {
|
||||
if (!material) {
|
||||
return;
|
||||
}
|
||||
|
@ -645,63 +631,65 @@ void RenderPipelines::bindMaterial(graphics::MaterialPointer material, gpu::Batc
|
|||
numUnlit++;
|
||||
}
|
||||
|
||||
#if USE_BINDLESS_TEXTURES
|
||||
if (!material->getTextureTable()) {
|
||||
material->setTextureTable(makeTextureTable());
|
||||
}
|
||||
|
||||
batch.setResourceTextureTable(material->getTextureTable());
|
||||
if (!enableTextures) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& drawMaterialTextures = material->getTextureTable();
|
||||
|
||||
// Albedo
|
||||
if (materialKey.isAlbedoMap()) {
|
||||
auto itr = textureMaps.find(graphics::MaterialKey::ALBEDO_MAP);
|
||||
if (itr != textureMaps.end() && itr->second->isDefined()) {
|
||||
if (enableTextures && itr != textureMaps.end() && itr->second->isDefined()) {
|
||||
drawMaterialTextures->setTexture(ShapePipeline::Slot::ALBEDO, itr->second->getTextureView());
|
||||
} else {
|
||||
drawMaterialTextures->setTexture(ShapePipeline::Slot::ALBEDO, textureCache->getWhiteTexture());
|
||||
}
|
||||
}
|
||||
|
||||
// Roughness map
|
||||
if (materialKey.isRoughnessMap()) {
|
||||
auto itr = textureMaps.find(graphics::MaterialKey::ROUGHNESS_MAP);
|
||||
if (itr != textureMaps.end() && itr->second->isDefined()) {
|
||||
if (enableTextures && itr != textureMaps.end() && itr->second->isDefined()) {
|
||||
drawMaterialTextures->setTexture(ShapePipeline::Slot::ROUGHNESS, itr->second->getTextureView());
|
||||
} else {
|
||||
drawMaterialTextures->setTexture(ShapePipeline::Slot::ROUGHNESS, textureCache->getWhiteTexture());
|
||||
}
|
||||
}
|
||||
|
||||
// Normal map
|
||||
if (materialKey.isNormalMap()) {
|
||||
auto itr = textureMaps.find(graphics::MaterialKey::NORMAL_MAP);
|
||||
if (itr != textureMaps.end() && itr->second->isDefined()) {
|
||||
if (enableTextures && itr != textureMaps.end() && itr->second->isDefined()) {
|
||||
drawMaterialTextures->setTexture(ShapePipeline::Slot::NORMAL, itr->second->getTextureView());
|
||||
} else {
|
||||
drawMaterialTextures->setTexture(ShapePipeline::Slot::NORMAL, textureCache->getBlueTexture());
|
||||
}
|
||||
}
|
||||
|
||||
// Metallic map
|
||||
if (materialKey.isMetallicMap()) {
|
||||
auto itr = textureMaps.find(graphics::MaterialKey::METALLIC_MAP);
|
||||
if (itr != textureMaps.end() && itr->second->isDefined()) {
|
||||
if (enableTextures && itr != textureMaps.end() && itr->second->isDefined()) {
|
||||
drawMaterialTextures->setTexture(ShapePipeline::Slot::METALLIC, itr->second->getTextureView());
|
||||
} else {
|
||||
drawMaterialTextures->setTexture(ShapePipeline::Slot::METALLIC, textureCache->getBlackTexture());
|
||||
}
|
||||
}
|
||||
|
||||
// Occlusion map
|
||||
if (materialKey.isOcclusionMap()) {
|
||||
auto itr = textureMaps.find(graphics::MaterialKey::OCCLUSION_MAP);
|
||||
if (itr != textureMaps.end() && itr->second->isDefined()) {
|
||||
if (enableTextures && itr != textureMaps.end() && itr->second->isDefined()) {
|
||||
drawMaterialTextures->setTexture(ShapePipeline::Slot::OCCLUSION, itr->second->getTextureView());
|
||||
} else {
|
||||
drawMaterialTextures->setTexture(ShapePipeline::Slot::OCCLUSION, textureCache->getWhiteTexture());
|
||||
}
|
||||
}
|
||||
|
||||
// Scattering map
|
||||
if (materialKey.isScatteringMap()) {
|
||||
auto itr = textureMaps.find(graphics::MaterialKey::SCATTERING_MAP);
|
||||
if (itr != textureMaps.end() && itr->second->isDefined()) {
|
||||
if (enableTextures && itr != textureMaps.end() && itr->second->isDefined()) {
|
||||
drawMaterialTextures->setTexture(ShapePipeline::Slot::SCATTERING, itr->second->getTextureView());
|
||||
} else {
|
||||
drawMaterialTextures->setTexture(ShapePipeline::Slot::SCATTERING, textureCache->getWhiteTexture());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -709,120 +697,19 @@ void RenderPipelines::bindMaterial(graphics::MaterialPointer material, gpu::Batc
|
|||
if (materialKey.isLightmapMap()) {
|
||||
auto itr = textureMaps.find(graphics::MaterialKey::LIGHTMAP_MAP);
|
||||
|
||||
if (itr != textureMaps.end() && itr->second->isDefined()) {
|
||||
if (enableTextures && itr != textureMaps.end() && itr->second->isDefined()) {
|
||||
drawMaterialTextures->setTexture(ShapePipeline::Slot::EMISSIVE_LIGHTMAP, itr->second->getTextureView());
|
||||
} else {
|
||||
drawMaterialTextures->setTexture(ShapePipeline::Slot::EMISSIVE_LIGHTMAP, textureCache->getGrayTexture());
|
||||
}
|
||||
} else if (materialKey.isEmissiveMap()) {
|
||||
auto itr = textureMaps.find(graphics::MaterialKey::EMISSIVE_MAP);
|
||||
if (itr != textureMaps.end() && itr->second->isDefined()) {
|
||||
if (enableTextures && itr != textureMaps.end() && itr->second->isDefined()) {
|
||||
drawMaterialTextures->setTexture(ShapePipeline::Slot::EMISSIVE_LIGHTMAP, itr->second->getTextureView());
|
||||
} else {
|
||||
drawMaterialTextures->setTexture(ShapePipeline::Slot::EMISSIVE_LIGHTMAP, textureCache->getBlackTexture());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
if (!enableTextures) {
|
||||
batch.setResourceTexture(ShapePipeline::Slot::ALBEDO, textureCache->getWhiteTexture());
|
||||
batch.setResourceTexture(ShapePipeline::Slot::MAP::ROUGHNESS, textureCache->getWhiteTexture());
|
||||
batch.setResourceTexture(ShapePipeline::Slot::MAP::NORMAL, textureCache->getBlueTexture());
|
||||
batch.setResourceTexture(ShapePipeline::Slot::MAP::METALLIC, textureCache->getBlackTexture());
|
||||
batch.setResourceTexture(ShapePipeline::Slot::MAP::OCCLUSION, textureCache->getWhiteTexture());
|
||||
batch.setResourceTexture(ShapePipeline::Slot::MAP::SCATTERING, textureCache->getWhiteTexture());
|
||||
batch.setResourceTexture(ShapePipeline::Slot::MAP::EMISSIVE_LIGHTMAP, textureCache->getBlackTexture());
|
||||
return;
|
||||
}
|
||||
|
||||
// Albedo
|
||||
if (materialKey.isAlbedoMap()) {
|
||||
auto itr = textureMaps.find(graphics::MaterialKey::ALBEDO_MAP);
|
||||
if (itr != textureMaps.end() && itr->second->isDefined()) {
|
||||
batch.setResourceTexture(ShapePipeline::Slot::ALBEDO, itr->second->getTextureView());
|
||||
} else {
|
||||
batch.setResourceTexture(ShapePipeline::Slot::ALBEDO, textureCache->getGrayTexture());
|
||||
}
|
||||
}
|
||||
|
||||
// Roughness map
|
||||
if (materialKey.isRoughnessMap()) {
|
||||
auto itr = textureMaps.find(graphics::MaterialKey::ROUGHNESS_MAP);
|
||||
if (itr != textureMaps.end() && itr->second->isDefined()) {
|
||||
batch.setResourceTexture(ShapePipeline::Slot::MAP::ROUGHNESS, itr->second->getTextureView());
|
||||
|
||||
// texcoord are assumed to be the same has albedo
|
||||
} else {
|
||||
batch.setResourceTexture(ShapePipeline::Slot::MAP::ROUGHNESS, textureCache->getWhiteTexture());
|
||||
}
|
||||
}
|
||||
|
||||
// Normal map
|
||||
if (materialKey.isNormalMap()) {
|
||||
auto itr = textureMaps.find(graphics::MaterialKey::NORMAL_MAP);
|
||||
if (itr != textureMaps.end() && itr->second->isDefined()) {
|
||||
batch.setResourceTexture(ShapePipeline::Slot::MAP::NORMAL, itr->second->getTextureView());
|
||||
|
||||
// texcoord are assumed to be the same has albedo
|
||||
} else {
|
||||
batch.setResourceTexture(ShapePipeline::Slot::MAP::NORMAL, textureCache->getBlueTexture());
|
||||
}
|
||||
}
|
||||
|
||||
// Metallic map
|
||||
if (materialKey.isMetallicMap()) {
|
||||
auto itr = textureMaps.find(graphics::MaterialKey::METALLIC_MAP);
|
||||
if (itr != textureMaps.end() && itr->second->isDefined()) {
|
||||
batch.setResourceTexture(ShapePipeline::Slot::MAP::METALLIC, itr->second->getTextureView());
|
||||
|
||||
// texcoord are assumed to be the same has albedo
|
||||
} else {
|
||||
batch.setResourceTexture(ShapePipeline::Slot::MAP::METALLIC, textureCache->getBlackTexture());
|
||||
}
|
||||
}
|
||||
|
||||
// Occlusion map
|
||||
if (materialKey.isOcclusionMap()) {
|
||||
auto itr = textureMaps.find(graphics::MaterialKey::OCCLUSION_MAP);
|
||||
if (itr != textureMaps.end() && itr->second->isDefined()) {
|
||||
batch.setResourceTexture(ShapePipeline::Slot::MAP::OCCLUSION, itr->second->getTextureView());
|
||||
|
||||
// texcoord are assumed to be the same has albedo
|
||||
} else {
|
||||
batch.setResourceTexture(ShapePipeline::Slot::MAP::OCCLUSION, textureCache->getWhiteTexture());
|
||||
}
|
||||
}
|
||||
|
||||
// Scattering map
|
||||
if (materialKey.isScatteringMap()) {
|
||||
auto itr = textureMaps.find(graphics::MaterialKey::SCATTERING_MAP);
|
||||
if (itr != textureMaps.end() && itr->second->isDefined()) {
|
||||
batch.setResourceTexture(ShapePipeline::Slot::MAP::SCATTERING, itr->second->getTextureView());
|
||||
|
||||
// texcoord are assumed to be the same has albedo
|
||||
} else {
|
||||
batch.setResourceTexture(ShapePipeline::Slot::MAP::SCATTERING, textureCache->getWhiteTexture());
|
||||
}
|
||||
}
|
||||
|
||||
// Emissive / Lightmap
|
||||
if (materialKey.isLightmapMap()) {
|
||||
auto itr = textureMaps.find(graphics::MaterialKey::LIGHTMAP_MAP);
|
||||
|
||||
if (itr != textureMaps.end() && itr->second->isDefined()) {
|
||||
batch.setResourceTexture(ShapePipeline::Slot::MAP::EMISSIVE_LIGHTMAP, itr->second->getTextureView());
|
||||
} else {
|
||||
batch.setResourceTexture(ShapePipeline::Slot::MAP::EMISSIVE_LIGHTMAP, textureCache->getGrayTexture());
|
||||
}
|
||||
} else if (materialKey.isEmissiveMap()) {
|
||||
auto itr = textureMaps.find(graphics::MaterialKey::EMISSIVE_MAP);
|
||||
|
||||
if (itr != textureMaps.end() && itr->second->isDefined()) {
|
||||
batch.setResourceTexture(ShapePipeline::Slot::MAP::EMISSIVE_LIGHTMAP, itr->second->getTextureView());
|
||||
} else {
|
||||
batch.setResourceTexture(ShapePipeline::Slot::MAP::EMISSIVE_LIGHTMAP, textureCache->getBlackTexture());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
batch.setResourceTextureTable(material->getTextureTable());
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
class RenderPipelines {
|
||||
public:
|
||||
static void bindMaterial(graphics::MaterialPointer material, gpu::Batch& batch, bool enableTextures);
|
||||
static void bindMaterial(const graphics::MaterialPointer& material, gpu::Batch& batch, bool enableTextures);
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue