mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-16 17:46:46 +02:00
First pass at bindless textures
This commit is contained in:
parent
03aeb7adda
commit
ab5355dbdd
13 changed files with 160 additions and 26 deletions
|
@ -99,6 +99,7 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] =
|
|||
(&::gpu::gl::GLBackend::do_setUniformBuffer),
|
||||
(&::gpu::gl::GLBackend::do_setResourceBuffer),
|
||||
(&::gpu::gl::GLBackend::do_setResourceTexture),
|
||||
(&::gpu::gl::GLBackend::do_setResourceTextureTable),
|
||||
|
||||
(&::gpu::gl::GLBackend::do_setFramebuffer),
|
||||
(&::gpu::gl::GLBackend::do_clearFramebuffer),
|
||||
|
|
|
@ -132,6 +132,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;
|
||||
|
||||
// Pipeline Stage
|
||||
virtual void do_setPipeline(const Batch& batch, size_t paramOffset) final;
|
||||
|
|
|
@ -157,6 +157,9 @@ 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;
|
||||
|
|
|
@ -611,3 +611,6 @@ GL41ResourceTexture::GL41ResourceTexture(const std::weak_ptr<GLBackend>& backend
|
|||
GL41ResourceTexture::~GL41ResourceTexture() {
|
||||
}
|
||||
|
||||
void GL41Backend::do_setResourceTextureTable(const Batch& batch, size_t paramOffset) {
|
||||
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "../gl/GLBackend.h"
|
||||
#include "../gl/GLTexture.h"
|
||||
#include <thread>
|
||||
#include <gpu/TextureTable.h>
|
||||
|
||||
#define INCREMENTAL_TRANSFER 0
|
||||
#define GPU_SSBO_TRANSFORM_OBJECT 1
|
||||
|
@ -48,6 +49,21 @@ public:
|
|||
static const std::string GL45_VERSION;
|
||||
const std::string& getVersion() const override { return GL45_VERSION; }
|
||||
|
||||
class GL45TextureTable : public GLObject<TextureTable> {
|
||||
static GLuint allocate();
|
||||
using Parent = GLObject<TextureTable>;
|
||||
public:
|
||||
using HandlesArray = std::array<uvec4, TextureTable::COUNT>;
|
||||
GL45TextureTable(const std::weak_ptr<GLBackend>& backend, const TextureTable& texture, const HandlesArray& newHandles, bool complete);
|
||||
~GL45TextureTable();
|
||||
|
||||
// FIXME instead of making a buffer for each table, there should be a global buffer of all materials
|
||||
// and we should store an offset into that buffer
|
||||
const uint32_t _stamp { 0 };
|
||||
const HandlesArray _handles;
|
||||
const bool _complete { false };
|
||||
};
|
||||
|
||||
class GL45Texture : public GLTexture {
|
||||
using Parent = GLTexture;
|
||||
friend class GL45Backend;
|
||||
|
@ -181,6 +197,8 @@ 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;
|
||||
void do_drawIndexed(const Batch& batch, size_t paramOffset) override;
|
||||
|
@ -193,6 +211,9 @@ 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;
|
||||
|
|
|
@ -20,15 +20,16 @@
|
|||
#include <QtCore/QDebug>
|
||||
|
||||
#include <NumericalConstants.h>
|
||||
#include <gpu/TextureTable.h>
|
||||
#include "../gl/GLTexelFormat.h"
|
||||
|
||||
using namespace gpu;
|
||||
using namespace gpu::gl;
|
||||
using namespace gpu::gl45;
|
||||
|
||||
#define SPARSE_PAGE_SIZE_OVERHEAD_ESTIMATE 1.3f
|
||||
#define MAX_RESOURCE_TEXTURES_PER_FRAME 2
|
||||
|
||||
|
||||
GLTexture* GL45Backend::syncGPUObject(const TexturePointer& texturePointer) {
|
||||
if (!texturePointer) {
|
||||
return nullptr;
|
||||
|
|
|
@ -59,6 +59,7 @@ Batch::Batch(const Batch& batch_) {
|
|||
|
||||
_buffers._items.swap(batch._buffers._items);
|
||||
_textures._items.swap(batch._textures._items);
|
||||
_textureTables._items.swap(batch._textureTables._items);
|
||||
_streamFormats._items.swap(batch._streamFormats._items);
|
||||
_transforms._items.swap(batch._transforms._items);
|
||||
_pipelines._items.swap(batch._pipelines._items);
|
||||
|
@ -96,6 +97,7 @@ void Batch::clear() {
|
|||
_data.clear();
|
||||
_buffers.clear();
|
||||
_textures.clear();
|
||||
_textureTables.clear();
|
||||
_streamFormats.clear();
|
||||
_transforms.clear();
|
||||
_pipelines.clear();
|
||||
|
@ -306,6 +308,12 @@ void Batch::setResourceTexture(uint32 slot, const TexturePointer& texture) {
|
|||
_params.emplace_back(slot);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -193,6 +193,7 @@ public:
|
|||
void setResourceTexture(uint32 slot, const TexturePointer& texture);
|
||||
void setResourceTexture(uint32 slot, const TextureView& view); // not a command, just a shortcut from a TextureView
|
||||
|
||||
void setResourceTextureTable(const TextureTablePointer& table, uint32 slot = 0);
|
||||
|
||||
// Ouput Stage
|
||||
void setFramebuffer(const FramebufferPointer& framebuffer);
|
||||
|
@ -304,6 +305,7 @@ public:
|
|||
COMMAND_setUniformBuffer,
|
||||
COMMAND_setResourceBuffer,
|
||||
COMMAND_setResourceTexture,
|
||||
COMMAND_setResourceTextureTable,
|
||||
|
||||
COMMAND_setFramebuffer,
|
||||
COMMAND_clearFramebuffer,
|
||||
|
@ -422,6 +424,7 @@ public:
|
|||
|
||||
typedef Cache<BufferPointer>::Vector BufferCaches;
|
||||
typedef Cache<TexturePointer>::Vector TextureCaches;
|
||||
typedef Cache<TextureTablePointer>::Vector TextureTableCaches;
|
||||
typedef Cache<Stream::FormatPointer>::Vector StreamFormatCaches;
|
||||
typedef Cache<Transform>::Vector TransformCaches;
|
||||
typedef Cache<PipelinePointer>::Vector PipelineCaches;
|
||||
|
@ -476,6 +479,7 @@ public:
|
|||
|
||||
BufferCaches _buffers;
|
||||
TextureCaches _textures;
|
||||
TextureTableCaches _textureTables;
|
||||
StreamFormatCaches _streamFormats;
|
||||
TransformCaches _transforms;
|
||||
PipelineCaches _pipelines;
|
||||
|
|
|
@ -91,6 +91,8 @@ namespace gpu {
|
|||
using Textures = std::vector<TexturePointer>;
|
||||
class TextureView;
|
||||
using TextureViews = std::vector<TextureView>;
|
||||
class TextureTable;
|
||||
using TextureTablePointer = std::shared_ptr<TextureTable>;
|
||||
|
||||
struct StereoState {
|
||||
bool isStereo() const {
|
||||
|
|
48
libraries/gpu/src/gpu/TextureTable.cpp
Normal file
48
libraries/gpu/src/gpu/TextureTable.cpp
Normal file
|
@ -0,0 +1,48 @@
|
|||
//
|
||||
// Created by Bradley Austin Davis on 2017/01/25
|
||||
// Copyright 2013-2017 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
|
||||
//
|
||||
#include "TextureTable.h"
|
||||
#include "Texture.h"
|
||||
|
||||
using namespace gpu;
|
||||
|
||||
TextureTable::TextureTable() { }
|
||||
|
||||
TextureTable::TextureTable(const std::initializer_list<TexturePointer>& textures) {
|
||||
auto max = std::min<size_t>(COUNT, textures.size());
|
||||
auto itr = textures.begin();
|
||||
size_t index = 0;
|
||||
while (itr != textures.end() && index < max) {
|
||||
setTexture(index, *itr);
|
||||
++index;
|
||||
}
|
||||
}
|
||||
|
||||
TextureTable::TextureTable(const std::array<TexturePointer, COUNT>& textures) : _stamp(1), _textures(textures) {
|
||||
}
|
||||
|
||||
void TextureTable::setTexture(size_t index, const TexturePointer& texturePointer) {
|
||||
if (index >= COUNT || _textures[index] == texturePointer) {
|
||||
return;
|
||||
}
|
||||
{
|
||||
Lock lock(_mutex);
|
||||
++_stamp;
|
||||
_textures[index] = texturePointer;
|
||||
}
|
||||
}
|
||||
|
||||
void TextureTable::setTexture(size_t index, const TextureView& textureView) {
|
||||
setTexture(index, textureView._texture);
|
||||
}
|
||||
|
||||
TextureTable::Array TextureTable::getTextures() const {
|
||||
Array result;
|
||||
Lock lock(_mutex);
|
||||
result = _textures;
|
||||
return result;
|
||||
}
|
42
libraries/gpu/src/gpu/TextureTable.h
Normal file
42
libraries/gpu/src/gpu/TextureTable.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
//
|
||||
// Created by Bradley Austin Davis on 2017/01/25
|
||||
// Copyright 2013-2017 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
|
||||
//
|
||||
#ifndef hifi_gpu_TextureTable_h
|
||||
#define hifi_gpu_TextureTable_h
|
||||
|
||||
#include "Forward.h"
|
||||
|
||||
#include <array>
|
||||
|
||||
namespace gpu {
|
||||
|
||||
class TextureTable {
|
||||
public:
|
||||
static const size_t COUNT = 8;
|
||||
using Array = std::array<TexturePointer, COUNT>;
|
||||
using Array = std::array<TexturePointer, COUNT>;
|
||||
TextureTable();
|
||||
TextureTable(const std::initializer_list<TexturePointer>& textures);
|
||||
TextureTable(const std::array<TexturePointer, COUNT>& textures);
|
||||
|
||||
// Only for gpu::Context
|
||||
const GPUObjectPointer gpuObject{};
|
||||
|
||||
void setTexture(size_t index, const TexturePointer& texturePointer);
|
||||
void setTexture(size_t index, const TextureView& texturePointer);
|
||||
|
||||
Array getTextures() const;
|
||||
Stamp getStamp() const { return _stamp; }
|
||||
private:
|
||||
mutable Mutex _mutex;
|
||||
Array _textures;
|
||||
Stamp _stamp{ 0 };
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -14,6 +14,8 @@
|
|||
#include <PerfStat.h>
|
||||
#include <DualQuaternion.h>
|
||||
|
||||
#include <gpu/TextureTable.h>
|
||||
|
||||
#include "DeferredLightingEffect.h"
|
||||
|
||||
using namespace render;
|
||||
|
@ -144,24 +146,25 @@ void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ShapePipeline::Locat
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
const auto& textureMaps = _drawMaterial->getTextureMaps();
|
||||
const auto& materialKey = _drawMaterial->getKey();
|
||||
auto textureCache = DependencyManager::get<TextureCache>();
|
||||
if (!_drawMaterialTextures) {
|
||||
_drawMaterialTextures = std::make_shared<gpu::TextureTable>();
|
||||
_drawMaterialTextures->setTexture(model::MaterialKey::ALBEDO_MAP, textureCache->getWhiteTexture());
|
||||
_drawMaterialTextures->setTexture(model::MaterialKey::ROUGHNESS_MAP, textureCache->getWhiteTexture());
|
||||
_drawMaterialTextures->setTexture(model::MaterialKey::NORMAL_MAP, textureCache->getBlueTexture());
|
||||
_drawMaterialTextures->setTexture(model::MaterialKey::METALLIC_MAP, textureCache->getBlackTexture());
|
||||
_drawMaterialTextures->setTexture(model::MaterialKey::OCCLUSION_MAP, textureCache->getWhiteTexture());
|
||||
_drawMaterialTextures->setTexture(model::MaterialKey::SCATTERING_MAP, textureCache->getWhiteTexture());
|
||||
_drawMaterialTextures->setTexture(model::MaterialKey::EMISSIVE_MAP, textureCache->getBlackTexture());
|
||||
_drawMaterialTextures->setTexture(model::MaterialKey::LIGHTMAP_MAP, textureCache->getGrayTexture());
|
||||
_drawMaterialTextures->setTexture(graphics::MaterialKey::ALBEDO_MAP, textureCache->getWhiteTexture());
|
||||
_drawMaterialTextures->setTexture(graphics::MaterialKey::ROUGHNESS_MAP, textureCache->getWhiteTexture());
|
||||
_drawMaterialTextures->setTexture(graphics::MaterialKey::NORMAL_MAP, textureCache->getBlueTexture());
|
||||
_drawMaterialTextures->setTexture(graphics::MaterialKey::METALLIC_MAP, textureCache->getBlackTexture());
|
||||
_drawMaterialTextures->setTexture(graphics::MaterialKey::OCCLUSION_MAP, textureCache->getWhiteTexture());
|
||||
_drawMaterialTextures->setTexture(graphics::MaterialKey::SCATTERING_MAP, textureCache->getWhiteTexture());
|
||||
_drawMaterialTextures->setTexture(graphics::MaterialKey::EMISSIVE_MAP, textureCache->getBlackTexture());
|
||||
_drawMaterialTextures->setTexture(graphics::MaterialKey::LIGHTMAP_MAP, textureCache->getGrayTexture());
|
||||
}
|
||||
|
||||
batch.setUniformBuffer(ShapePipeline::Slot::BUFFER::MATERIAL, _drawMaterial->getSchemaBuffer());
|
||||
batch.setUniformBuffer(ShapePipeline::Slot::BUFFER::TEXMAPARRAY, _drawMaterial->getTexMapArrayBuffer());
|
||||
|
||||
const auto& materialKey = _drawMaterial->getKey();
|
||||
const auto& textureMaps = _drawMaterial->getTextureMaps();
|
||||
batch.setResourceTextureTable(_drawMaterialTextures);
|
||||
|
||||
int numUnlit = 0;
|
||||
if (materialKey.isUnlit()) {
|
||||
|
@ -183,7 +186,7 @@ void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ShapePipeline::Locat
|
|||
if (materialKey.isAlbedoMap()) {
|
||||
auto itr = textureMaps.find(graphics::MaterialKey::ALBEDO_MAP);
|
||||
if (itr != textureMaps.end() && itr->second->isDefined()) {
|
||||
_drawMaterialTextures->setTexture(model::MaterialKey::ALBEDO_MAP, itr->second->getTextureView());
|
||||
_drawMaterialTextures->setTexture(graphics::MaterialKey::ALBEDO_MAP, itr->second->getTextureView());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -191,7 +194,7 @@ void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ShapePipeline::Locat
|
|||
if (materialKey.isRoughnessMap()) {
|
||||
auto itr = textureMaps.find(graphics::MaterialKey::ROUGHNESS_MAP);
|
||||
if (itr != textureMaps.end() && itr->second->isDefined()) {
|
||||
_drawMaterialTextures->setTexture(model::MaterialKey::ROUGHNESS_MAP, itr->second->getTextureView());
|
||||
_drawMaterialTextures->setTexture(graphics::MaterialKey::ROUGHNESS_MAP, itr->second->getTextureView());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -199,7 +202,7 @@ void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ShapePipeline::Locat
|
|||
if (materialKey.isNormalMap()) {
|
||||
auto itr = textureMaps.find(graphics::MaterialKey::NORMAL_MAP);
|
||||
if (itr != textureMaps.end() && itr->second->isDefined()) {
|
||||
_drawMaterialTextures->setTexture(model::MaterialKey::NORMAL_MAP, itr->second->getTextureView());
|
||||
_drawMaterialTextures->setTexture(graphics::MaterialKey::NORMAL_MAP, itr->second->getTextureView());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -207,11 +210,7 @@ void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ShapePipeline::Locat
|
|||
if (materialKey.isMetallicMap()) {
|
||||
auto itr = textureMaps.find(graphics::MaterialKey::METALLIC_MAP);
|
||||
if (itr != textureMaps.end() && itr->second->isDefined()) {
|
||||
_drawMaterialTextures->setTexture(model::MaterialKey::METALLIC_MAP, itr->second->getTextureView());
|
||||
|
||||
// texcoord are assumed to be the same has albedo
|
||||
} else {
|
||||
_drawMaterialTextures->setTexture(model::MaterialKey::METALLIC_MAP, textureCache->getBlackTexture());
|
||||
_drawMaterialTextures->setTexture(graphics::MaterialKey::METALLIC_MAP, itr->second->getTextureView());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -219,7 +218,7 @@ void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ShapePipeline::Locat
|
|||
if (materialKey.isOcclusionMap()) {
|
||||
auto itr = textureMaps.find(graphics::MaterialKey::OCCLUSION_MAP);
|
||||
if (itr != textureMaps.end() && itr->second->isDefined()) {
|
||||
_drawMaterialTextures->setTexture(model::MaterialKey::OCCLUSION_MAP, itr->second->getTextureView());
|
||||
_drawMaterialTextures->setTexture(graphics::MaterialKey::OCCLUSION_MAP, itr->second->getTextureView());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -227,7 +226,7 @@ void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ShapePipeline::Locat
|
|||
if (materialKey.isScatteringMap()) {
|
||||
auto itr = textureMaps.find(graphics::MaterialKey::SCATTERING_MAP);
|
||||
if (itr != textureMaps.end() && itr->second->isDefined()) {
|
||||
_drawMaterialTextures->setTexture(model::MaterialKey::SCATTERING_MAP, itr->second->getTextureView());
|
||||
_drawMaterialTextures->setTexture(graphics::MaterialKey::SCATTERING_MAP, itr->second->getTextureView());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -236,16 +235,16 @@ void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ShapePipeline::Locat
|
|||
auto itr = textureMaps.find(graphics::MaterialKey::LIGHTMAP_MAP);
|
||||
|
||||
if (itr != textureMaps.end() && itr->second->isDefined()) {
|
||||
_drawMaterialTextures->setTexture(model::MaterialKey::LIGHTMAP_MAP, itr->second->getTextureView());
|
||||
_drawMaterialTextures->setTexture(graphics::MaterialKey::LIGHTMAP_MAP, itr->second->getTextureView());
|
||||
} else {
|
||||
_drawMaterialTextures->setTexture(model::MaterialKey::LIGHTMAP_MAP, textureCache->getGrayTexture());
|
||||
_drawMaterialTextures->setTexture(graphics::MaterialKey::LIGHTMAP_MAP, textureCache->getGrayTexture());
|
||||
}
|
||||
} else if (materialKey.isEmissiveMap()) {
|
||||
auto itr = textureMaps.find(graphics::MaterialKey::EMISSIVE_MAP);
|
||||
if (itr != textureMaps.end() && itr->second->isDefined()) {
|
||||
_drawMaterialTextures->setTexture(model::MaterialKey::EMISSIVE_MAP, itr->second->getTextureView());
|
||||
_drawMaterialTextures->setTexture(graphics::MaterialKey::EMISSIVE_MAP, itr->second->getTextureView());
|
||||
} else {
|
||||
_drawMaterialTextures->setTexture(model::MaterialKey::EMISSIVE_MAP, textureCache->getBlackTexture());
|
||||
_drawMaterialTextures->setTexture(graphics::MaterialKey::EMISSIVE_MAP, textureCache->getBlackTexture());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,6 +67,7 @@ public:
|
|||
|
||||
std::shared_ptr<const graphics::Material> _drawMaterial;
|
||||
graphics::Mesh::Part _drawPart;
|
||||
mutable gpu::TextureTablePointer _drawMaterialTextures;
|
||||
|
||||
size_t getVerticesCount() const { return _drawMesh ? _drawMesh->getNumVertices() : 0; }
|
||||
size_t getMaterialTextureSize() { return _drawMaterial ? _drawMaterial->getTextureSize() : 0; }
|
||||
|
|
Loading…
Reference in a new issue