First pass at bindless textures

This commit is contained in:
Bradley Austin Davis 2017-01-25 17:47:33 -08:00
parent 03aeb7adda
commit ab5355dbdd
13 changed files with 160 additions and 26 deletions

View file

@ -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),

View file

@ -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;

View file

@ -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;

View file

@ -611,3 +611,6 @@ GL41ResourceTexture::GL41ResourceTexture(const std::weak_ptr<GLBackend>& backend
GL41ResourceTexture::~GL41ResourceTexture() {
}
void GL41Backend::do_setResourceTextureTable(const Batch& batch, size_t paramOffset) {
}

View file

@ -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;

View file

@ -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;

View file

@ -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);
}

View file

@ -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;

View file

@ -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 {

View 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;
}

View 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

View file

@ -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());
}
}
}

View file

@ -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; }