From 19e4fb2355f6948ddadf4ee19a09652c3a3e842d Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Wed, 7 Mar 2018 12:22:17 -0800 Subject: [PATCH 01/19] materials on primitives --- .../src/RenderableMaterialEntityItem.cpp | 144 +----------- .../src/RenderableMaterialEntityItem.h | 14 -- .../src/RenderableShapeEntityItem.cpp | 95 +++++++- .../src/RenderableShapeEntityItem.h | 6 + libraries/render-utils/src/GeometryCache.cpp | 216 +++++++++++++++--- libraries/render-utils/src/GeometryCache.h | 4 +- .../render-utils/src/MaterialTextures.slh | 14 +- .../src/forward_model_normal_map.slf | 2 +- .../src/model_lightmap_normal_map.slf | 6 +- .../src/model_lightmap_normal_map_fade.slf | 6 +- .../render-utils/src/model_normal_map.slf | 6 +- .../src/model_normal_map_fade.slf | 6 +- .../src/model_translucent_normal_map.slf | 2 +- .../src/model_translucent_normal_map_fade.slf | 2 +- libraries/shared/src/shared/Shapes.cpp | 111 ++++++++- libraries/shared/src/shared/Shapes.h | 2 + 16 files changed, 418 insertions(+), 218 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp index 119a46b68f..8566b9bae8 100644 --- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp @@ -9,6 +9,7 @@ #include "RenderableMaterialEntityItem.h" #include "RenderPipelines.h" +#include "GeometryCache.h" using namespace render; using namespace render::entities; @@ -90,138 +91,6 @@ ShapeKey MaterialEntityRenderer::getShapeKey() { return builder.build(); } -glm::vec3 MaterialEntityRenderer::getVertexPos(float phi, float theta) { - return glm::vec3(glm::sin(theta) * glm::cos(phi), glm::cos(theta), glm::sin(theta) * glm::sin(phi)); -} - -glm::vec3 MaterialEntityRenderer::getTangent(float phi, float theta) { - return glm::vec3(-glm::cos(theta) * glm::cos(phi), glm::sin(theta), -glm::cos(theta) * glm::sin(phi)); -} - -void MaterialEntityRenderer::addVertex(std::vector& buffer, const glm::vec3& pos, const glm::vec3& tan, const glm::vec2 uv) { - buffer.push_back(pos.x); buffer.push_back(pos.y); buffer.push_back(pos.z); - buffer.push_back(tan.x); buffer.push_back(tan.y); buffer.push_back(tan.z); - buffer.push_back(uv.x); buffer.push_back(uv.y); -} - -void MaterialEntityRenderer::addTriangleFan(std::vector& buffer, int stack, int step) { - float v1 = ((float)stack) / STACKS; - float theta1 = v1 * (float)M_PI; - glm::vec3 tip = getVertexPos(0, theta1); - float v2 = ((float)(stack + step)) / STACKS; - float theta2 = v2 * (float)M_PI; - for (int i = 0; i < SLICES; i++) { - float u1 = ((float)i) / SLICES; - float u2 = ((float)(i + step)) / SLICES; - float phi1 = u1 * M_PI_TIMES_2; - float phi2 = u2 * M_PI_TIMES_2; - /* (flipped for negative step) - p1 - / \ - / \ - / \ - p3 ------ p2 - */ - - glm::vec3 pos2 = getVertexPos(phi2, theta2); - glm::vec3 pos3 = getVertexPos(phi1, theta2); - - glm::vec3 tan1 = getTangent(0, theta1); - glm::vec3 tan2 = getTangent(phi2, theta2); - glm::vec3 tan3 = getTangent(phi1, theta2); - - glm::vec2 uv1 = glm::vec2((u1 + u2) / 2.0f, v1); - glm::vec2 uv2 = glm::vec2(u2, v2); - glm::vec2 uv3 = glm::vec2(u1, v2); - - addVertex(buffer, tip, tan1, uv1); - addVertex(buffer, pos2, tan2, uv2); - addVertex(buffer, pos3, tan3, uv3); - - _numVertices += 3; - } -} - -int MaterialEntityRenderer::_numVertices = 0; -std::shared_ptr MaterialEntityRenderer::_streamFormat = nullptr; -std::shared_ptr MaterialEntityRenderer::_stream = nullptr; -std::shared_ptr MaterialEntityRenderer::_verticesBuffer = nullptr; - -void MaterialEntityRenderer::generateMesh() { - _streamFormat = std::make_shared(); - _stream = std::make_shared(); - _verticesBuffer = std::make_shared(); - - const int NUM_POS_COORDS = 3; - const int NUM_TANGENT_COORDS = 3; - const int VERTEX_TANGENT_OFFSET = NUM_POS_COORDS * sizeof(float); - const int VERTEX_TEXCOORD_OFFSET = VERTEX_TANGENT_OFFSET + NUM_TANGENT_COORDS * sizeof(float); - - _streamFormat->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0); - _streamFormat->setAttribute(gpu::Stream::NORMAL, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0); - _streamFormat->setAttribute(gpu::Stream::TANGENT, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), VERTEX_TANGENT_OFFSET); - _streamFormat->setAttribute(gpu::Stream::TEXCOORD, 0, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV), VERTEX_TEXCOORD_OFFSET); - - _stream->addBuffer(_verticesBuffer, 0, _streamFormat->getChannels().at(0)._stride); - - std::vector vertexBuffer; - - // Top - addTriangleFan(vertexBuffer, 0, 1); - - // Middle section - for (int j = 1; j < STACKS - 1; j++) { - float v1 = ((float)j) / STACKS; - float v2 = ((float)(j + 1)) / STACKS; - float theta1 = v1 * (float)M_PI; - float theta2 = v2 * (float)M_PI; - for (int i = 0; i < SLICES; i++) { - float u1 = ((float)i) / SLICES; - float u2 = ((float)(i + 1)) / SLICES; - float phi1 = u1 * M_PI_TIMES_2; - float phi2 = u2 * M_PI_TIMES_2; - - /* - p2 ---- p3 - | / | - | / | - | / | - p1 ---- p4 - */ - - glm::vec3 pos1 = getVertexPos(phi1, theta2); - glm::vec3 pos2 = getVertexPos(phi1, theta1); - glm::vec3 pos3 = getVertexPos(phi2, theta1); - glm::vec3 pos4 = getVertexPos(phi2, theta2); - - glm::vec3 tan1 = getTangent(phi1, theta2); - glm::vec3 tan2 = getTangent(phi1, theta1); - glm::vec3 tan3 = getTangent(phi2, theta1); - glm::vec3 tan4 = getTangent(phi2, theta2); - - glm::vec2 uv1 = glm::vec2(u1, v2); - glm::vec2 uv2 = glm::vec2(u1, v1); - glm::vec2 uv3 = glm::vec2(u2, v1); - glm::vec2 uv4 = glm::vec2(u2, v2); - - addVertex(vertexBuffer, pos1, tan1, uv1); - addVertex(vertexBuffer, pos2, tan2, uv2); - addVertex(vertexBuffer, pos3, tan3, uv3); - - addVertex(vertexBuffer, pos3, tan3, uv3); - addVertex(vertexBuffer, pos4, tan4, uv4); - addVertex(vertexBuffer, pos1, tan1, uv1); - - _numVertices += 6; - } - } - - // Bottom - addTriangleFan(vertexBuffer, STACKS, -1); - - _verticesBuffer->append(vertexBuffer.size() * sizeof(float), (gpu::Byte*) vertexBuffer.data()); -} - void MaterialEntityRenderer::doRender(RenderArgs* args) { PerformanceTimer perfTimer("RenderableMaterialEntityItem::render"); Q_ASSERT(args->_batch); @@ -252,14 +121,7 @@ void MaterialEntityRenderer::doRender(RenderArgs* args) { args->_details._materialSwitches++; // Draw! - if (_numVertices == 0) { - generateMesh(); - } + DependencyManager::get()->renderSphere(batch); - batch.setInputFormat(_streamFormat); - batch.setInputStream(0, *_stream); - batch.draw(gpu::TRIANGLES, _numVertices, 0); - - const int NUM_VERTICES_PER_TRIANGLE = 3; - args->_details._trianglesRendered += _numVertices / NUM_VERTICES_PER_TRIANGLE; + args->_details._trianglesRendered += DependencyManager::get()->getSphereTriangleCount(); } diff --git a/libraries/entities-renderer/src/RenderableMaterialEntityItem.h b/libraries/entities-renderer/src/RenderableMaterialEntityItem.h index fef1a41138..8de2190a0c 100644 --- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.h +++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.h @@ -40,20 +40,6 @@ private: Transform _renderTransform; std::shared_ptr _drawMaterial; - - static int _numVertices; - static std::shared_ptr _streamFormat; - static std::shared_ptr _stream; - static std::shared_ptr _verticesBuffer; - - void generateMesh(); - void addTriangleFan(std::vector& buffer, int stack, int step); - static glm::vec3 getVertexPos(float phi, float theta); - static glm::vec3 getTangent(float phi, float theta); - static void addVertex(std::vector& buffer, const glm::vec3& pos, const glm::vec3& tan, const glm::vec2 uv); - const int SLICES = 15; - const int STACKS = 9; - const float M_PI_TIMES_2 = 2.0f * (float)M_PI; }; } } diff --git a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp index 22cd98b08a..b14e201366 100644 --- a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp @@ -19,6 +19,8 @@ #include "render-utils/simple_vert.h" #include "render-utils/simple_frag.h" +#include "RenderPipelines.h" + //#define SHAPE_ENTITY_USE_FADE_EFFECT #ifdef SHAPE_ENTITY_USE_FADE_EFFECT #include @@ -108,11 +110,93 @@ bool ShapeEntityRenderer::isTransparent() const { if (_procedural.isEnabled() && _procedural.isFading()) { return Interpolate::calculateFadeRatio(_procedural.getFadeStartTime()) < 1.0f; } - - // return _entity->getLocalRenderAlpha() < 1.0f || Parent::isTransparent(); + + auto mat = _materials.find("0"); + if (mat != _materials.end()) { + if (mat->second.top().material) { + auto matKey = mat->second.top().material->getKey(); + if (matKey.isTranslucent()) { + return true; + } + } + } + return Parent::isTransparent(); } +ItemKey ShapeEntityRenderer::getKey() { + ItemKey::Builder builder; + builder.withTypeShape().withTypeMeta().withTagBits(render::ItemKey::TAG_BITS_0 | render::ItemKey::TAG_BITS_1); + + withReadLock([&] { + if (isTransparent()) { + builder.withTransparent(); + } + }); + + return builder.build(); +} + +bool ShapeEntityRenderer::useMaterialPipeline() const { + withReadLock([&] { + if (_procedural.isReady()) { + return false; + } + }); + + graphics::MaterialKey drawMaterialKey; + auto mat = _materials.find("0"); + if (mat != _materials.end() && mat->second.top().material) { + drawMaterialKey = mat->second.top().material->getKey(); + } + + if (drawMaterialKey.isEmissive() || drawMaterialKey.isUnlit() || drawMaterialKey.isMetallic() || drawMaterialKey.isScattering()) { + return true; + } + + // If the material is using any map, we need to use a material ShapeKey + for (int i = 0; i < graphics::Material::MapChannel::NUM_MAP_CHANNELS; i++) { + if (drawMaterialKey.isMapChannel(graphics::Material::MapChannel(i))) { + return true; + } + } + return false; +} + +ShapeKey ShapeEntityRenderer::getShapeKey() { + if (useMaterialPipeline()) { + graphics::MaterialKey drawMaterialKey; + if (_materials["0"].top().material) { + drawMaterialKey = _materials["0"].top().material->getKey(); + } + + bool isTranslucent = drawMaterialKey.isTranslucent(); + bool hasTangents = drawMaterialKey.isNormalMap(); + bool hasLightmap = drawMaterialKey.isLightmapMap(); + bool isUnlit = drawMaterialKey.isUnlit(); + + ShapeKey::Builder builder; + builder.withMaterial(); + + if (isTranslucent) { + builder.withTranslucent(); + } + if (hasTangents) { + builder.withTangents(); + } + if (hasLightmap) { + builder.withLightmap(); + } + if (isUnlit) { + builder.withUnlit(); + } + + return builder.build(); + } else { + return Parent::getShapeKey(); + } +} + void ShapeEntityRenderer::doRender(RenderArgs* args) { PerformanceTimer perfTimer("RenderableShapeEntityItem::render"); Q_ASSERT(args->_batch); @@ -149,7 +233,7 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) { } else { geometryCache->renderShape(batch, geometryShape, outColor); } - } else { + } else if (!useMaterialPipeline()) { // FIXME, support instanced multi-shape rendering using multidraw indirect outColor.a *= _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f; auto pipeline = outColor.a < 1.0f ? geometryCache->getTransparentShapePipeline() : geometryCache->getOpaqueShapePipeline(); @@ -158,6 +242,11 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) { } else { geometryCache->renderSolidShapeInstance(args, batch, geometryShape, outColor, pipeline); } + } else { + RenderPipelines::bindMaterial(mat, batch, args->_enableTexturing); + args->_details._materialSwitches++; + + geometryCache->renderShape(batch, geometryShape); } const auto triCount = geometryCache->getShapeTriangleCount(geometryShape); diff --git a/libraries/entities-renderer/src/RenderableShapeEntityItem.h b/libraries/entities-renderer/src/RenderableShapeEntityItem.h index de855ce0c6..463ef187fc 100644 --- a/libraries/entities-renderer/src/RenderableShapeEntityItem.h +++ b/libraries/entities-renderer/src/RenderableShapeEntityItem.h @@ -24,6 +24,10 @@ public: virtual scriptable::ScriptableModelBase getScriptableModel() override; +protected: + ItemKey getKey() override; + ShapeKey getShapeKey() override; + private: virtual bool needsRenderUpdate() const override; virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override; @@ -32,6 +36,8 @@ private: virtual void doRender(RenderArgs* args) override; virtual bool isTransparent() const override; + bool useMaterialPipeline() const; + Procedural _procedural; QString _lastUserData; Transform _renderTransform; diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 7455da13b6..61fcdafd39 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -126,6 +126,8 @@ static const int VERTICES_PER_TRIANGLE = 3; static const gpu::Element POSITION_ELEMENT { gpu::VEC3, gpu::FLOAT, gpu::XYZ }; static const gpu::Element NORMAL_ELEMENT { gpu::VEC3, gpu::FLOAT, gpu::XYZ }; +static const gpu::Element TEXCOORD0_ELEMENT { gpu::VEC2, gpu::FLOAT, gpu::UV }; +static const gpu::Element TANGENT_ELEMENT { gpu::VEC3, gpu::FLOAT, gpu::XYZ }; static const gpu::Element COLOR_ELEMENT { gpu::VEC4, gpu::NUINT8, gpu::RGBA }; static const gpu::Element TEXCOORD4_ELEMENT { gpu::VEC4, gpu::FLOAT, gpu::XYZW }; @@ -133,8 +135,10 @@ static gpu::Stream::FormatPointer SOLID_STREAM_FORMAT; static gpu::Stream::FormatPointer INSTANCED_SOLID_STREAM_FORMAT; static gpu::Stream::FormatPointer INSTANCED_SOLID_FADE_STREAM_FORMAT; -static const uint SHAPE_VERTEX_STRIDE = sizeof(glm::vec3) * 2; // vertices and normals +static const uint SHAPE_VERTEX_STRIDE = sizeof(glm::vec3) * 3 + sizeof(glm::vec2); // position, normal, texcoords, tangent static const uint SHAPE_NORMALS_OFFSET = sizeof(glm::vec3); +static const uint SHAPE_TEXCOORD0_OFFSET = sizeof(glm::vec3) * 2; +static const uint SHAPE_TANGENT_OFFSET = sizeof(glm::vec3) * 2 + sizeof(glm::vec2); void GeometryCache::computeSimpleHullPointListForShape(const int entityShape, const glm::vec3 &entityExtents, QVector &outPointList) { @@ -193,7 +197,18 @@ std::vector polygon() { return result; } -void GeometryCache::ShapeData::setupVertices(gpu::BufferPointer& vertexBuffer, const geometry::VertexVector& vertices) { +void addVec3ToVector(std::vector& vertices, glm::vec3 vec) { + vertices.push_back(vec.x); + vertices.push_back(vec.y); + vertices.push_back(vec.z); +} + +void addVec2ToVector(std::vector& vertices, glm::vec2 vec) { + vertices.push_back(vec.x); + vertices.push_back(vec.y); +} + +void GeometryCache::ShapeData::setupVertices(gpu::BufferPointer& vertexBuffer, const std::vector& vertices) { gpu::Buffer::Size offset = vertexBuffer->getSize(); vertexBuffer->append(vertices); @@ -203,6 +218,10 @@ void GeometryCache::ShapeData::setupVertices(gpu::BufferPointer& vertexBuffer, c viewSize, SHAPE_VERTEX_STRIDE, POSITION_ELEMENT); _normalView = gpu::BufferView(vertexBuffer, offset + SHAPE_NORMALS_OFFSET, viewSize, SHAPE_VERTEX_STRIDE, NORMAL_ELEMENT); + _texCoordView = gpu::BufferView(vertexBuffer, offset + SHAPE_TEXCOORD0_OFFSET, + viewSize, SHAPE_VERTEX_STRIDE, TEXCOORD0_ELEMENT); + _tangentView = gpu::BufferView(vertexBuffer, offset + SHAPE_TANGENT_OFFSET, + viewSize, SHAPE_VERTEX_STRIDE, TANGENT_ELEMENT); } void GeometryCache::ShapeData::setupIndices(gpu::BufferPointer& indexBuffer, const geometry::IndexVector& indices, const geometry::IndexVector& wireIndices) { @@ -228,6 +247,8 @@ void GeometryCache::ShapeData::setupIndices(gpu::BufferPointer& indexBuffer, con void GeometryCache::ShapeData::setupBatch(gpu::Batch& batch) const { batch.setInputBuffer(gpu::Stream::POSITION, _positionView); batch.setInputBuffer(gpu::Stream::NORMAL, _normalView); + batch.setInputBuffer(gpu::Stream::TEXCOORD, _texCoordView); + batch.setInputBuffer(gpu::Stream::TANGENT, _tangentView); batch.setIndexBuffer(_indicesView); } @@ -294,7 +315,7 @@ static IndexPair indexToken(geometry::Index a, geometry::Index b) { template void setupFlatShape(GeometryCache::ShapeData& shapeData, const geometry::Solid& shape, gpu::BufferPointer& vertexBuffer, gpu::BufferPointer& indexBuffer) { using namespace geometry; - VertexVector vertices; + std::vector vertices; IndexVector solidIndices, wireIndices; IndexPairs wireSeenIndices; @@ -310,11 +331,38 @@ void setupFlatShape(GeometryCache::ShapeData& shapeData, const geometry::Solid void setupSmoothShape(GeometryCache::ShapeData& shapeData, const geometry::Solid& shape, gpu::BufferPointer& vertexBuffer, gpu::BufferPointer& indexBuffer) { using namespace geometry; - VertexVector vertices; - vertices.reserve(shape.vertices.size() * 2); + std::vector vertices; + vertices.reserve(shape.vertices.size() * SHAPE_VERTEX_STRIDE / sizeof(float)); for (const auto& vertex : shape.vertices) { - vertices.push_back(vertex); - vertices.push_back(vertex); + addVec3ToVector(vertices, vertex); + addVec3ToVector(vertices, vertex); + vec2 uv = calculateSphereTexCoord(vertex); + addVec2ToVector(vertices, calculateSphereTexCoord(vertex)); + // We'll fill in the correct tangents later, once we correct the UVs + addVec3ToVector(vertices, vec3(0.0f)); + } + + // We need to fix up the sphere's UVs because it's actually a tesselated icosahedron. See http://mft-dev.dk/uv-mapping-sphere/ + size_t faceCount = shape.faces.size(); + for (size_t f = 0; f < faceCount; f++) { + // Fix zipper + { + float& u1 = vertices[shape.faces[f][0] * SHAPE_VERTEX_STRIDE / sizeof(float) + SHAPE_TEXCOORD0_OFFSET / sizeof(float)]; + float& u2 = vertices[shape.faces[f][1] * SHAPE_VERTEX_STRIDE / sizeof(float) + SHAPE_TEXCOORD0_OFFSET / sizeof(float)]; + float& u3 = vertices[shape.faces[f][2] * SHAPE_VERTEX_STRIDE / sizeof(float) + SHAPE_TEXCOORD0_OFFSET / sizeof(float)]; + + if (glm::isnan(u1)) { + u1 = (u2 + u3) / 2.0f; + } + if (glm::isnan(u2)) { + u2 = (u1 + u3) / 2.0f; + } + if (glm::isnan(u3)) { + u3 = (u1 + u2) / 2.0f; + } + + const float U_THRESHOLD = 0.25f; + float max = glm::max(u1, glm::max(u2, u3)); + float min = glm::min(u1, glm::min(u2, u3)); + + if (max - min > U_THRESHOLD) { + if (u1 < U_THRESHOLD) { + u1 += 1.0f; + } + if (u2 < U_THRESHOLD) { + u2 += 1.0f; + } + if (u3 < U_THRESHOLD) { + u3 += 1.0f; + } + } + } + + // Fix swirling at poles + for (Index i = 0; i < N; i++) { + Index originalIndex = shape.faces[f][i]; + if (shape.vertices[originalIndex].y == 1.0f || shape.vertices[originalIndex].y == -1.0f) { + float uSum = 0.0f; + for (Index i2 = 1; i2 <= N - 1; i2++) { + float u = vertices[shape.faces[f][(i + i2) % N] * SHAPE_VERTEX_STRIDE / sizeof(float) + SHAPE_TEXCOORD0_OFFSET / sizeof(float)]; + uSum += u; + } + uSum /= (float)(N - 1); + vertices[originalIndex * SHAPE_VERTEX_STRIDE / sizeof(float) + SHAPE_TEXCOORD0_OFFSET / sizeof(float)] = uSum; + break; + } + } + + // Fill in tangents + for (Index i = 0; i < N; i++) { + vec3 tangent = calculateSphereTangent(vertices[shape.faces[f][i] * SHAPE_VERTEX_STRIDE / sizeof(float) + SHAPE_TEXCOORD0_OFFSET / sizeof(float)]); + vertices[shape.faces[f][i] * SHAPE_VERTEX_STRIDE / sizeof(float) + SHAPE_TANGENT_OFFSET / sizeof(float)] = tangent.x; + vertices[shape.faces[f][i] * SHAPE_VERTEX_STRIDE / sizeof(float) + SHAPE_TANGENT_OFFSET / sizeof(float) + 1] = tangent.y; + vertices[shape.faces[f][i] * SHAPE_VERTEX_STRIDE / sizeof(float) + SHAPE_TANGENT_OFFSET / sizeof(float) + 2] = tangent.z; + } } IndexVector solidIndices, wireIndices; IndexPairs wireSeenIndices; - size_t faceCount = shape.faces.size(); size_t faceIndexCount = triangulatedFaceIndexCount(); solidIndices.reserve(faceIndexCount * faceCount); @@ -391,25 +517,31 @@ void setupSmoothShape(GeometryCache::ShapeData& shapeData, const geometry::Solid template void extrudePolygon(GeometryCache::ShapeData& shapeData, gpu::BufferPointer& vertexBuffer, gpu::BufferPointer& indexBuffer, bool isConical = false) { using namespace geometry; - VertexVector vertices; + std::vector vertices; IndexVector solidIndices, wireIndices; // Top (if not conical) and bottom faces std::vector shape = polygon(); if (isConical) { for (uint32_t i = 0; i < N; i++) { - vertices.push_back(vec3(0.0f, 0.5f, 0.0f)); - vertices.push_back(vec3(0.0f, 1.0f, 0.0f)); + addVec3ToVector(vertices, vec3(0.0f, 0.5f, 0.0f)); + addVec3ToVector(vertices, vec3(0.0f, 1.0f, 0.0f)); + addVec2ToVector(vertices, vec2(i / (float)N, 1.0f)); + addVec3ToVector(vertices, vec3(0.0f)); } } else { for (const vec3& v : shape) { - vertices.push_back(vec3(v.x, 0.5f, v.z)); - vertices.push_back(vec3(0.0f, 1.0f, 0.0f)); + addVec3ToVector(vertices, vec3(v.x, 0.5f, v.z)); + addVec3ToVector(vertices, vec3(0.0f, 1.0f, 0.0f)); + addVec2ToVector(vertices, vec2(v.x, v.z) + vec2(0.5f)); + addVec3ToVector(vertices, vec3(1.0f, 0.0f, 0.0f)); } } for (const vec3& v : shape) { - vertices.push_back(vec3(v.x, -0.5f, v.z)); - vertices.push_back(vec3(0.0f, -1.0f, 0.0f)); + addVec3ToVector(vertices, vec3(v.x, -0.5f, v.z)); + addVec3ToVector(vertices, vec3(0.0f, -1.0f, 0.0f)); + addVec2ToVector(vertices, vec2(-v.x, v.z) + vec2(0.5f)); + addVec3ToVector(vertices, vec3(-1.0f, 0.0f, 0.0f)); } Index baseVertex = 0; for (uint32_t i = 2; i < N; i++) { @@ -438,15 +570,28 @@ void extrudePolygon(GeometryCache::ShapeData& shapeData, gpu::BufferPointer& ver vec3 topRight = (isConical ? vec3(0.0f, 0.5f, 0.0f) : vec3(right.x, 0.5f, right.z)); vec3 bottomLeft = vec3(left.x, -0.5f, left.z); vec3 bottomRight = vec3(right.x, -0.5f, right.z); + vec3 tangent = glm::normalize(bottomLeft - bottomRight); - vertices.push_back(topLeft); - vertices.push_back(normal); - vertices.push_back(bottomLeft); - vertices.push_back(normal); - vertices.push_back(topRight); - vertices.push_back(normal); - vertices.push_back(bottomRight); - vertices.push_back(normal); + // Our tex coords go in the opposite direction as our vertices + float u = 1.0f - i / (float)N; + float u2 = 1.0f - (i + 1) / (float)N; + + addVec3ToVector(vertices, topLeft); + addVec3ToVector(vertices, normal); + addVec2ToVector(vertices, vec2(u, 0.0f)); + addVec3ToVector(vertices, tangent); + addVec3ToVector(vertices, bottomLeft); + addVec3ToVector(vertices, normal); + addVec2ToVector(vertices, vec2(u, 1.0f)); + addVec3ToVector(vertices, tangent); + addVec3ToVector(vertices, topRight); + addVec3ToVector(vertices, normal); + addVec2ToVector(vertices, vec2(u2, 0.0f)); + addVec3ToVector(vertices, tangent); + addVec3ToVector(vertices, bottomRight); + addVec3ToVector(vertices, normal); + addVec2ToVector(vertices, vec2(u2, 1.0f)); + addVec3ToVector(vertices, tangent); solidIndices.push_back(baseVertex + 0); solidIndices.push_back(baseVertex + 2); @@ -469,14 +614,16 @@ void drawCircle(GeometryCache::ShapeData& shapeData, gpu::BufferPointer& vertexB // Draw a circle with radius 1/4th the size of the bounding box using namespace geometry; - VertexVector vertices; + std::vector vertices; IndexVector solidIndices, wireIndices; const int NUM_CIRCLE_VERTICES = 64; std::vector shape = polygon(); for (const vec3& v : shape) { - vertices.push_back(vec3(v.x, 0.0f, v.z)); - vertices.push_back(vec3(0.0f, 0.0f, 0.0f)); + addVec3ToVector(vertices, vec3(v.x, 0.0f, v.z)); + addVec3ToVector(vertices, vec3(0.0f, 0.0f, 0.0f)); + addVec2ToVector(vertices, vec2(v.x, v.z) + vec2(0.5f)); + addVec3ToVector(vertices, vec3(1.0f, 0.0f, 0.0f)); } Index baseVertex = 0; @@ -532,9 +679,9 @@ void GeometryCache::buildShapes() { // Line { ShapeData& shapeData = _shapes[Line]; - shapeData.setupVertices(_shapeVertices, VertexVector { - vec3(-0.5f, 0.0f, 0.0f), vec3(-0.5f, 0.0f, 0.0f), - vec3(0.5f, 0.0f, 0.0f), vec3(0.5f, 0.0f, 0.0f) + shapeData.setupVertices(_shapeVertices, std::vector { + -0.5f, 0.0f, 0.0f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.5f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }); IndexVector wireIndices; // Only two indices @@ -598,6 +745,8 @@ gpu::Stream::FormatPointer& getSolidStreamFormat() { SOLID_STREAM_FORMAT = std::make_shared(); // 1 for everyone SOLID_STREAM_FORMAT->setAttribute(gpu::Stream::POSITION, gpu::Stream::POSITION, POSITION_ELEMENT); SOLID_STREAM_FORMAT->setAttribute(gpu::Stream::NORMAL, gpu::Stream::NORMAL, NORMAL_ELEMENT); + SOLID_STREAM_FORMAT->setAttribute(gpu::Stream::TEXCOORD0, gpu::Stream::TEXCOORD0, TEXCOORD0_ELEMENT); + SOLID_STREAM_FORMAT->setAttribute(gpu::Stream::TANGENT, gpu::Stream::TANGENT, TANGENT_ELEMENT); } return SOLID_STREAM_FORMAT; } @@ -607,6 +756,8 @@ gpu::Stream::FormatPointer& getInstancedSolidStreamFormat() { INSTANCED_SOLID_STREAM_FORMAT = std::make_shared(); // 1 for everyone INSTANCED_SOLID_STREAM_FORMAT->setAttribute(gpu::Stream::POSITION, gpu::Stream::POSITION, POSITION_ELEMENT); INSTANCED_SOLID_STREAM_FORMAT->setAttribute(gpu::Stream::NORMAL, gpu::Stream::NORMAL, NORMAL_ELEMENT); + INSTANCED_SOLID_STREAM_FORMAT->setAttribute(gpu::Stream::TEXCOORD0, gpu::Stream::TEXCOORD0, TEXCOORD0_ELEMENT); + INSTANCED_SOLID_STREAM_FORMAT->setAttribute(gpu::Stream::TANGENT, gpu::Stream::TANGENT, TANGENT_ELEMENT); INSTANCED_SOLID_STREAM_FORMAT->setAttribute(gpu::Stream::COLOR, gpu::Stream::COLOR, COLOR_ELEMENT, 0, gpu::Stream::PER_INSTANCE); } return INSTANCED_SOLID_STREAM_FORMAT; @@ -617,6 +768,8 @@ gpu::Stream::FormatPointer& getInstancedSolidFadeStreamFormat() { INSTANCED_SOLID_FADE_STREAM_FORMAT = std::make_shared(); // 1 for everyone INSTANCED_SOLID_FADE_STREAM_FORMAT->setAttribute(gpu::Stream::POSITION, gpu::Stream::POSITION, POSITION_ELEMENT); INSTANCED_SOLID_FADE_STREAM_FORMAT->setAttribute(gpu::Stream::NORMAL, gpu::Stream::NORMAL, NORMAL_ELEMENT); + INSTANCED_SOLID_FADE_STREAM_FORMAT->setAttribute(gpu::Stream::TEXCOORD0, gpu::Stream::TEXCOORD0, TEXCOORD0_ELEMENT); + INSTANCED_SOLID_FADE_STREAM_FORMAT->setAttribute(gpu::Stream::TANGENT, gpu::Stream::TANGENT, TANGENT_ELEMENT); INSTANCED_SOLID_FADE_STREAM_FORMAT->setAttribute(gpu::Stream::COLOR, gpu::Stream::COLOR, COLOR_ELEMENT, 0, gpu::Stream::PER_INSTANCE); INSTANCED_SOLID_FADE_STREAM_FORMAT->setAttribute(gpu::Stream::TEXCOORD2, gpu::Stream::TEXCOORD2, TEXCOORD4_ELEMENT, 0, gpu::Stream::PER_INSTANCE); INSTANCED_SOLID_FADE_STREAM_FORMAT->setAttribute(gpu::Stream::TEXCOORD3, gpu::Stream::TEXCOORD3, TEXCOORD4_ELEMENT, 0, gpu::Stream::PER_INSTANCE); @@ -919,6 +1072,7 @@ void GeometryCache::updateVertices(int id, const QVector& points, con details.streamFormat->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::XYZ), 0); details.streamFormat->setAttribute(gpu::Stream::NORMAL, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), VERTEX_NORMAL_OFFSET); + // TODO: circle3D overlays use this to define their vertices, so they need tex coords details.streamFormat->setAttribute(gpu::Stream::COLOR, 1, gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA)); details.stream->addBuffer(details.verticesBuffer, 0, details.streamFormat->getChannels().at(0)._stride); diff --git a/libraries/render-utils/src/GeometryCache.h b/libraries/render-utils/src/GeometryCache.h index 998043b80e..b0caaf113c 100644 --- a/libraries/render-utils/src/GeometryCache.h +++ b/libraries/render-utils/src/GeometryCache.h @@ -357,10 +357,12 @@ public: struct ShapeData { gpu::BufferView _positionView; gpu::BufferView _normalView; + gpu::BufferView _texCoordView; + gpu::BufferView _tangentView; gpu::BufferView _indicesView; gpu::BufferView _wireIndicesView; - void setupVertices(gpu::BufferPointer& vertexBuffer, const geometry::VertexVector& vertices); + void setupVertices(gpu::BufferPointer& vertexBuffer, const std::vector& vertices); void setupIndices(gpu::BufferPointer& indexBuffer, const geometry::IndexVector& indices, const geometry::IndexVector& wireIndices); void setupBatch(gpu::Batch& batch) const; void draw(gpu::Batch& batch) const; diff --git a/libraries/render-utils/src/MaterialTextures.slh b/libraries/render-utils/src/MaterialTextures.slh index b3662385b0..26bb85a853 100644 --- a/libraries/render-utils/src/MaterialTextures.slh +++ b/libraries/render-utils/src/MaterialTextures.slh @@ -148,25 +148,25 @@ vec3 fetchLightmapMap(vec2 uv) { } <@endfunc@> -<@func tangentToViewSpace(fetchedNormal, interpolatedNormal, interpolatedTangent, normal)@> +<@func evalMaterialNormal(fetchedNormal, interpolatedNormal, interpolatedTangent, normal)@> { vec3 normalizedNormal = normalize(<$interpolatedNormal$>.xyz); vec3 normalizedTangent = normalize(<$interpolatedTangent$>.xyz); - vec3 normalizedBitangent = normalize(cross(normalizedNormal, normalizedTangent)); + vec3 normalizedBitangent = cross(normalizedNormal, normalizedTangent); vec3 localNormal = <$fetchedNormal$>; - <$normal$> = vec3(normalizedTangent * localNormal.x + normalizedNormal * localNormal.y + normalizedBitangent * localNormal.z); + <$normal$> = vec3(normalizedBitangent * localNormal.x + normalizedNormal * localNormal.y + normalizedTangent * localNormal.z); } <@endfunc@> -<@func tangentToViewSpaceLOD(fragPos, fetchedNormal, interpolatedNormal, interpolatedTangent, normal)@> +<@func evalMaterialNormalLOD(fragPos, fetchedNormal, interpolatedNormal, interpolatedTangent, normal)@> { vec3 normalizedNormal = normalize(<$interpolatedNormal$>.xyz); vec3 normalizedTangent = normalize(<$interpolatedTangent$>.xyz); - vec3 normalizedBitangent = normalize(cross(normalizedNormal, normalizedTangent)); + vec3 normalizedBitangent = cross(normalizedNormal, normalizedTangent); // attenuate the normal map divergence from the mesh normal based on distance - // THe attenuation range [20,100] meters from the eye is arbitrary for now + // The attenuation range [20,100] meters from the eye is arbitrary for now vec3 localNormal = mix(<$fetchedNormal$>, vec3(0.0, 1.0, 0.0), smoothstep(20.0, 100.0, (-<$fragPos$>).z)); - <$normal$> = vec3(normalizedTangent * localNormal.x + normalizedNormal * localNormal.y + normalizedBitangent * localNormal.z); + <$normal$> = vec3(normalizedBitangent * localNormal.x + normalizedNormal * localNormal.y + normalizedTangent * localNormal.z); } <@endfunc@> diff --git a/libraries/render-utils/src/forward_model_normal_map.slf b/libraries/render-utils/src/forward_model_normal_map.slf index b32ed862d6..0ba464d3f0 100644 --- a/libraries/render-utils/src/forward_model_normal_map.slf +++ b/libraries/render-utils/src/forward_model_normal_map.slf @@ -58,7 +58,7 @@ void main(void) { vec3 fragPosition = _position.xyz; vec3 fragNormal; - <$tangentToViewSpace(normalTex, _normal, _tangent, fragNormal)$> + <$evalMaterialNormal(normalTex, _normal, _tangent, fragNormal)$> TransformCamera cam = getTransformCamera(); diff --git a/libraries/render-utils/src/model_lightmap_normal_map.slf b/libraries/render-utils/src/model_lightmap_normal_map.slf index 8734ea74b8..eecde59e54 100644 --- a/libraries/render-utils/src/model_lightmap_normal_map.slf +++ b/libraries/render-utils/src/model_lightmap_normal_map.slf @@ -33,11 +33,11 @@ void main(void) { <$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedo, roughness, normalTexel, metallicTex)$> <$fetchMaterialTexturesCoord1(matKey, _texCoord1, _SCRIBE_NULL, lightmapVal)$> - vec3 viewNormal; - <$tangentToViewSpaceLOD(_position, normalTexel, _normal, _tangent, viewNormal)$> + vec3 fragNormal; + <$evalMaterialNormalLOD(_position, normalTexel, _normal, _tangent, fragNormal)$> packDeferredFragmentLightmap( - normalize(viewNormal.xyz), + normalize(fragNormal.xyz), evalOpaqueFinalAlpha(getMaterialOpacity(mat), albedo.a), getMaterialAlbedo(mat) * albedo.rgb * _color, getMaterialRoughness(mat) * roughness, diff --git a/libraries/render-utils/src/model_lightmap_normal_map_fade.slf b/libraries/render-utils/src/model_lightmap_normal_map_fade.slf index e6cb35ec4f..af497f90c6 100644 --- a/libraries/render-utils/src/model_lightmap_normal_map_fade.slf +++ b/libraries/render-utils/src/model_lightmap_normal_map_fade.slf @@ -43,11 +43,11 @@ void main(void) { <$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedo, roughness, normalTexel, metallicTex)$> <$fetchMaterialTexturesCoord1(matKey, _texCoord1, _SCRIBE_NULL, lightmapVal)$> - vec3 viewNormal; - <$tangentToViewSpaceLOD(_position, normalTexel, _normal, _tangent, viewNormal)$> + vec3 fragNormal; + <$evalMaterialNormalLOD(_position, normalTexel, _normal, _tangent, fragNormal)$> packDeferredFragmentLightmap( - normalize(viewNormal.xyz), + normalize(fragNormal.xyz), evalOpaqueFinalAlpha(getMaterialOpacity(mat), albedo.a), getMaterialAlbedo(mat) * albedo.rgb * _color, getMaterialRoughness(mat) * roughness, diff --git a/libraries/render-utils/src/model_normal_map.slf b/libraries/render-utils/src/model_normal_map.slf index 82f667bf73..49613eca6a 100644 --- a/libraries/render-utils/src/model_normal_map.slf +++ b/libraries/render-utils/src/model_normal_map.slf @@ -46,8 +46,8 @@ void main(void) { vec3 emissive = getMaterialEmissive(mat); <$evalMaterialEmissive(emissiveTex, emissive, matKey, emissive)$>; - vec3 viewNormal; - <$tangentToViewSpaceLOD(_position, normalTex, _normal, _tangent, viewNormal)$> + vec3 fragNormal; + <$evalMaterialNormalLOD(_position, normalTex, _normal, _tangent, fragNormal)$> float metallic = getMaterialMetallic(mat); <$evalMaterialMetallic(metallicTex, metallic, matKey, metallic)$>; @@ -56,7 +56,7 @@ void main(void) { <$evalMaterialScattering(scatteringTex, scattering, matKey, scattering)$>; packDeferredFragment( - normalize(viewNormal.xyz), + normalize(fragNormal.xyz), opacity, albedo, roughness, diff --git a/libraries/render-utils/src/model_normal_map_fade.slf b/libraries/render-utils/src/model_normal_map_fade.slf index 67bea98cf0..bf6222652c 100644 --- a/libraries/render-utils/src/model_normal_map_fade.slf +++ b/libraries/render-utils/src/model_normal_map_fade.slf @@ -56,8 +56,8 @@ void main(void) { vec3 emissive = getMaterialEmissive(mat); <$evalMaterialEmissive(emissiveTex, emissive, matKey, emissive)$>; - vec3 viewNormal; - <$tangentToViewSpaceLOD(_position, normalTex, _normal, _tangent, viewNormal)$> + vec3 fragNormal; + <$evalMaterialNormalLOD(_position, normalTex, _normal, _tangent, fragNormal)$> float metallic = getMaterialMetallic(mat); <$evalMaterialMetallic(metallicTex, metallic, matKey, metallic)$>; @@ -65,7 +65,7 @@ void main(void) { float scattering = getMaterialScattering(mat); packDeferredFragment( - normalize(viewNormal.xyz), + normalize(fragNormal.xyz), opacity, albedo, roughness, diff --git a/libraries/render-utils/src/model_translucent_normal_map.slf b/libraries/render-utils/src/model_translucent_normal_map.slf index 759007d93e..52015660c6 100644 --- a/libraries/render-utils/src/model_translucent_normal_map.slf +++ b/libraries/render-utils/src/model_translucent_normal_map.slf @@ -61,7 +61,7 @@ void main(void) { vec3 fragPosition = _position.xyz; vec3 fragNormal; - <$tangentToViewSpaceLOD(_position, normalTex, _normal, _tangent, fragNormal)$> + <$evalMaterialNormalLOD(_position, normalTex, _normal, _tangent, fragNormal)$> TransformCamera cam = getTransformCamera(); vec3 fragEyeVector = vec3(cam._viewInverse * vec4(-fragPosition, 0.0)); diff --git a/libraries/render-utils/src/model_translucent_normal_map_fade.slf b/libraries/render-utils/src/model_translucent_normal_map_fade.slf index 204b5ac56b..c6c0e16812 100644 --- a/libraries/render-utils/src/model_translucent_normal_map_fade.slf +++ b/libraries/render-utils/src/model_translucent_normal_map_fade.slf @@ -71,7 +71,7 @@ void main(void) { vec3 fragPosition = _position.xyz; // Lighting is done in world space vec3 fragNormal; - <$tangentToViewSpaceLOD(_position, normalTex, _normal, _tangent, fragNormal)$> + <$evalMaterialNormalLOD(_position, normalTex, _normal, _tangent, fragNormal)$> TransformCamera cam = getTransformCamera(); vec3 fragEyeVector = vec3(cam._viewInverse * vec4(-fragPosition, 0.0)); diff --git a/libraries/shared/src/shared/Shapes.cpp b/libraries/shared/src/shared/Shapes.cpp index dabdf21202..277154d6b6 100644 --- a/libraries/shared/src/shared/Shapes.cpp +++ b/libraries/shared/src/shared/Shapes.cpp @@ -8,8 +8,11 @@ #include "Shapes.h" +#include "qmath.h" + namespace geometry { +using glm::vec2; using glm::vec3; // The golden ratio @@ -20,7 +23,7 @@ Solid<3> tesselate(const Solid<3>& solid_, int count) { float length = glm::length(solid.vertices[0]); for (int i = 0; i < count; ++i) { Solid<3> result { solid.vertices, {} }; - result.vertices.reserve(solid.vertices.size() + solid.faces.size() * 3); + result.vertices.reserve(solid.vertices.size() + solid.faces.size() * 6); for (size_t f = 0; f < solid.faces.size(); ++f) { Index baseVertex = (Index)result.vertices.size(); const Face<3>& oldFace = solid.faces[f]; @@ -30,13 +33,26 @@ Solid<3> tesselate(const Solid<3>& solid_, int count) { vec3 ab = glm::normalize(a + b) * length; vec3 bc = glm::normalize(b + c) * length; vec3 ca = glm::normalize(c + a) * length; + + result.vertices.push_back(a); + result.vertices.push_back(ab); + result.vertices.push_back(ca); + result.faces.push_back(Face<3>{ { baseVertex, baseVertex + 1, baseVertex + 2 } }); + + result.vertices.push_back(ab); + result.vertices.push_back(b); + result.vertices.push_back(bc); + result.faces.push_back(Face<3>{ { baseVertex + 3, baseVertex + 4, baseVertex + 5 } }); + + result.vertices.push_back(bc); + result.vertices.push_back(c); + result.vertices.push_back(ca); + result.faces.push_back(Face<3>{ { baseVertex + 6, baseVertex + 7, baseVertex + 8 } }); + result.vertices.push_back(ab); result.vertices.push_back(bc); result.vertices.push_back(ca); - result.faces.push_back(Face<3>{ { oldFace[0], baseVertex, baseVertex + 2 } }); - result.faces.push_back(Face<3>{ { baseVertex, oldFace[1], baseVertex + 1 } }); - result.faces.push_back(Face<3>{ { baseVertex + 1, oldFace[2], baseVertex + 2 } }); - result.faces.push_back(Face<3>{ { baseVertex, baseVertex + 1, baseVertex + 2 } }); + result.faces.push_back(Face<3>{ { baseVertex + 9, baseVertex + 10, baseVertex + 11 } }); } solid = result; } @@ -50,6 +66,10 @@ const Solid<3>& tetrahedron() { static const auto D = vec3(-1, -1, 1); static const Solid<3> TETRAHEDRON = Solid<3>{ { A, B, C, D }, + { vec2(0.75f, 0.5f), vec2(0.5f, 0.0f), vec2(0.25f, 0.5f), + vec2(0.5f, 1.0f), vec2(1.0f, 1.0f), vec2(0.75f, 0.5f), + vec2(0.25f, 0.5f), vec2(0.5f, 1.0f), vec2(0.75f, 0.5f), + vec2(0.25f, 0.5f), vec2(0.0f, 1.0f), vec2(0.5f, 1.0f) }, FaceVector<3>{ Face<3> { { 0, 1, 2 } }, Face<3> { { 3, 1, 0 } }, @@ -65,8 +85,15 @@ const Solid<4>& cube() { static const auto B = vec3(-1, 1, 1); static const auto C = vec3(-1, 1, -1); static const auto D = vec3(1, 1, -1); + static const float THIRD = 1.0f / 3.0f; static const Solid<4> CUBE = Solid<4>{ { A, B, C, D, -A, -B, -C, -D }, + { vec2(0.5f, 0.0f), vec2(0.25f, 0.0f), vec2(0.25f, THIRD), vec2(0.5f, THIRD), + vec2(0.5f, THIRD), vec2(0.25f, THIRD), vec2(0.25f, 2.0f * THIRD), vec2(0.5f, 2.0f * THIRD), + vec2(0.25f, THIRD), vec2(0.0f, THIRD), vec2(0.0f, 2.0f * THIRD), vec2(0.25f, 2.0f * THIRD), + vec2(1.0f, THIRD), vec2(0.75f, THIRD), vec2(0.75f, 2.0f * THIRD), vec2(1.0f, 2.0f * THIRD), + vec2(0.75f, THIRD), vec2(0.5f, THIRD), vec2(0.5f, 2.0f * THIRD), vec2(0.75f, 2.0f * THIRD), + vec2(0.25f, 1.0f), vec2(0.5f, 1.0f), vec2(0.5f, 2.0f * THIRD), vec2(0.25f, 2.0f * THIRD) }, FaceVector<4>{ Face<4> { { 3, 2, 1, 0 } }, Face<4> { { 0, 1, 7, 6 } }, @@ -86,8 +113,18 @@ const Solid<3>& octahedron() { static const auto D = vec3(0, 0, -1); static const auto E = vec3(1, 0, 0); static const auto F = vec3(-1, 0, 0); + static const float THIRD = 1.0f / 3.0f; + static const float SEVENTH = 1.0f / 7.0f; static const Solid<3> OCTAHEDRON = Solid<3>{ { A, B, C, D, E, F}, + { vec2(2.0f * SEVENTH, THIRD), vec2(SEVENTH, 2.0f * THIRD), vec2(3.0f * SEVENTH, 2.0f * THIRD), + vec2(2.0f * SEVENTH, THIRD), vec2(3.0f * SEVENTH, 2.0f * THIRD), vec2(4.0f * SEVENTH, THIRD), + vec2(5.0f * SEVENTH, 0.0f), vec2(4.0f * SEVENTH, THIRD), vec2(6.0f * SEVENTH, THIRD), + vec2(2.0f * SEVENTH, THIRD), vec2(0.0f, THIRD), vec2(1.0f * SEVENTH, 2.0f * THIRD), + vec2(2.0f * SEVENTH, 1.0f), vec2(3.0f * SEVENTH, 2.0f * THIRD), vec2(1.0f * SEVENTH, 2.0f * THIRD), + vec2(5.0f * SEVENTH, 2.0f * THIRD), vec2(4.0f * SEVENTH, THIRD), vec2(3.0f * SEVENTH, 2.0f * THIRD), + vec2(5.0f * SEVENTH, 2.0f * THIRD), vec2(6.0f * SEVENTH, THIRD), vec2(4.0f * SEVENTH, THIRD), + vec2(5.0f * SEVENTH, 2.0f * THIRD), vec2(1.0f, 2.0f * THIRD), vec2(6.0f * SEVENTH, THIRD) }, FaceVector<3> { Face<3> { { 0, 2, 4, } }, Face<3> { { 0, 4, 3, } }, @@ -116,11 +153,52 @@ const Solid<5>& dodecahedron() { static const vec3 I = vec3(0, -IP, P); static const vec3 J = vec3(P, 0, IP); + + /* _ + / \ | + / \ y2 + / \ | + / \ _ + \ / | + \ / y1 + \ / | + ___________ _ + |x3|- - x1 - -||x3| + |- - - - x2- - - -| + */ + + // x1, x2, and x3 are the solutions to the following system of equations: + // 1 = 3 * x1 + 3 * x2 + x3 + // x1 + 2 * x3 = (golden ratio) * x1 + // x2 = x1 + 2 * x3 + static const float x1 = 4.0f / (17.0f + 7.0f * sqrt(5.0f)); + static const float x2 = (1.0f / 11.0f) * (5.0f * sqrt(5.0f) - 9.0f); + static const float x2_2 = x2 / 2.0f; + static const float x3 = (1.0f / 11.0f) * (6.0f * sqrt(5.0f) - 13.0f); + // y1 and y2 are the solutions to the following system of equations (x is the sidelength, but is different than x1 because the scale in the y direction is different): + // 1 = 3 * y1 + 2 * y2 + // y1 = sin(108 deg) * x + // y1 + y2 = x * sqrt(5 + 2 * sqrt(5)) / 2 + static const float y1 = sqrt(2.0f * (5.0f + sqrt(5.0f))) / (sqrt(2.0f * (5.0f + sqrt(5.0f))) + 4.0f * sqrt(5.0f + 2.0f * sqrt(5.0f))); + static const float y2 = -(sqrt(2.0f * (5.0f + sqrt(5.0f))) - 2.0f * sqrt(5.0f + 2.0f * sqrt(5.0f))) / (sqrt(2.0f * (5.0f + sqrt(5.0f))) + 4.0f * sqrt(5.0f + 2.0f * sqrt(5.0f))); + static const Solid<5> DODECAHEDRON = Solid<5>{ { A, B, C, D, E, F, G, H, I, J, -A, -B, -C, -D, -E, -F, -G, -H, -I, -J, }, + { vec2(x1 + x2_2, 0.0f), vec2(x2_2, 0.0f), vec2(x2_2 - x3, y1), vec2(x3 + x1, y1 + y2), vec2(x3 + x1 + x2_2, y1), + vec2(1.0f - (x2 - x3 + x2_2), 0.0f), vec2(1.0f - (x2 + x1 + x3), y2), vec2(1.0f - (x2 + x1), y1 + y2), vec2(1.0f - x2, y1 + y2), vec2(1.0f - (x2 - x3), y2), + vec2(1.0f - x2_2, y1), vec2(1.0f - x2, y1 + y2), vec2(1.0f - (x3 + x1), y1 + y2 + y1), vec2(1.0f - x3, y1 + y2 + y1), vec2(1.0f, y1 + y2), + vec2(x3, y1 + y2), vec2(0.0f, y1 + y2 + y1), vec2(x2_2, y1 + y2 + y1 + y2), vec2(x2, y1 + y2 + y1), vec2(x1 + x3, y1 + y2), + vec2(x3 + x1, y1 + y2), vec2(x2, y1 + y2 + y1), vec2(x2 + x1, y1 + y2 + y1), vec2(x3 + x1 + x2, y1 + y2), vec2(x3 + x1 + x2_2, y1), + vec2(x3 + x1 + x2_2, y1), vec2(x3 + x1 + x2, y1 + y2), vec2(x3 + x1 + x2 + x2_2, y1), vec2(x1 + x2 + x2_2, 0.0f), vec2(x3 + x1 + x2_2 + x3, 0.0f), + vec2(1.0f - (x3 + x1 + x2_2), 1.0f - y1), vec2(1.0f - (x3 + x1 + x2), 1.0f - (y1 + y2)), vec2(1.0f - (x3 + x1 + x2 + x2_2), 1.0f - y1), vec2(1.0f - (x1 + x2 + x2_2), 1.0f), vec2(1.0f - (x3 + x1 + x2_2 + x3), 1.0f), + vec2(x2 + x1 + x3, 1.0f - y2), vec2(x2 + x1, 1.0f - (y1 + y2)), vec2(x2, 1.0f - (y1 + y2)), vec2(x2 - x3, 1.0f - y2), vec2(x2 - x3 + x2_2, 1.0f), + vec2(x2 + x1 + x2, y1 + y2 + y1), vec2(x3 + x1 + x2 + x1, y1 + y2), vec2(x3 + x1 + x2, y1 + y2), vec2(x2 + x1, y1 + y2 + y1), vec2(x2 + x1 + x2_2, y1 + y2 + y1 + y2), + vec2(1.0f - (x3 + x1 + x2), y1 + y2 + y1), vec2(1.0f - (x2 + x1), y1 + y2), vec2(1.0f - (x2 + x1 + x2_2), y1), vec2(1.0f - (x2 + x1 + x2), y1 + y2), vec2(1.0f - (x3 + x1 + x2 + x1), y1 + y2 + y1), + vec2(1.0f - (x3 + x1 + x2_2), y1 + y2 + y1 + y2), vec2(1.0f - (x3 + x1), y1 + y2 + y1), vec2(1.0f - x2, y1 + y2), vec2(1.0f - (x2 + x1), y2 + y1), vec2(1.0f - (x3 + x1 + x2), y1 + y2 + y1), + vec2(1.0f - (x1 + x2_2), 1.0f), vec2(1.0f - x2_2, 1.0f), vec2(1.0f - (x2_2 - x3), 1.0f - y1), vec2(1.0f - (x1 + x3), 1.0f - (y1 + y2)), vec2(1.0f - (x3 + x1 + x2_2), 1.0f - y1) }, FaceVector<5> { Face<5> { { 0, 1, 2, 3, 4 } }, Face<5> { { 0, 5, 18, 6, 1 } }, @@ -148,12 +226,33 @@ const Solid<3>& icosahedron() { static const auto D = vec3(P, 0, N); static const auto E = vec3(P, 0, -N); static const auto F = vec3(0, N, -P); - + static const float THIRD = 1.0f / 3.0f; + static const float ELEVENTH = 1.0f / 11.0f; static const Solid<3> ICOSAHEDRON = Solid<3> { { A, B, C, D, E, F, -A, -B, -C, -D, -E, -F, }, + { vec2(3.0f * ELEVENTH, 0.0f), vec2(2.0f * ELEVENTH, THIRD), vec2(4.0f * ELEVENTH, THIRD), + vec2(2.0f * ELEVENTH, THIRD), vec2(3.0f * ELEVENTH, 2.0f * THIRD), vec2(4.0f * ELEVENTH, THIRD), + vec2(3.0f * ELEVENTH, 2.0f * THIRD), vec2(5.0f * ELEVENTH, 2.0f * THIRD), vec2(4.0f * ELEVENTH, THIRD), + vec2(5.0f * ELEVENTH, 2.0f * THIRD), vec2(6.0f * ELEVENTH, THIRD), vec2(4.0f * ELEVENTH, THIRD), + vec2(6.0f * ELEVENTH, THIRD), vec2(5.0f * ELEVENTH, 0.0f), vec2(4.0f * ELEVENTH, THIRD), + vec2(1.0f * ELEVENTH, 0.0f), vec2(0.0f, THIRD), vec2(2.0f * ELEVENTH, THIRD), + vec2(1.0f * ELEVENTH, 2.0f * THIRD), vec2(2.0f * ELEVENTH, THIRD), vec2(0.0f, THIRD), + vec2(2.0f * ELEVENTH, THIRD), vec2(1.0f * ELEVENTH, 2.0f * THIRD), vec2(3.0f * ELEVENTH, 2.0f * THIRD), + vec2(2.0f * ELEVENTH, 1.0f), vec2(3.0f * ELEVENTH, 2.0f * THIRD), vec2(1.0f * ELEVENTH, 2.0f * THIRD), + vec2(3.0f * ELEVENTH, 2.0f * THIRD), vec2(4.0f * ELEVENTH, 1.0f), vec2(5.0f * ELEVENTH, 2.0f * THIRD), + vec2(7.0f * ELEVENTH, 2.0f * THIRD), vec2(5.0f * ELEVENTH, 2.0f * THIRD), vec2(6.0f * ELEVENTH, 1.0f), + vec2(5.0f * ELEVENTH, 2.0f * THIRD), vec2(7.0f * ELEVENTH, 2.0f * THIRD), vec2(6.0f * ELEVENTH, THIRD), + vec2(8.0f * ELEVENTH, THIRD), vec2(6.0f * ELEVENTH, THIRD), vec2(7.0f * ELEVENTH, 2.0f * THIRD), + vec2(6.0f * ELEVENTH, THIRD), vec2(8.0f * ELEVENTH, THIRD), vec2(7.0f * ELEVENTH, 0.0f), + vec2(10.0f * ELEVENTH, THIRD), vec2(9.0f * ELEVENTH, 0.0f), vec2(8.0f * ELEVENTH, THIRD), + vec2(7.0f * ELEVENTH, 2.0f * THIRD), vec2(8.0f * ELEVENTH, 1.0f), vec2(9.0f * ELEVENTH, 2.0f * THIRD), + vec2(8.0f * ELEVENTH, THIRD), vec2(7.0f * ELEVENTH, 2.0f * THIRD), vec2(9.0f * ELEVENTH, 2.0f * THIRD), + vec2(10.0f * ELEVENTH, THIRD), vec2(8.0f * ELEVENTH, THIRD), vec2(9.0f * ELEVENTH, 2.0f * THIRD), + vec2(1.0f, 2.0f * THIRD), vec2(10.0f * ELEVENTH, THIRD), vec2(9.0f * ELEVENTH, 2.0f * THIRD), + vec2(10.0f * ELEVENTH, 1.0f), vec2(1.0f, 2.0f * THIRD), vec2(9.0f * ELEVENTH, 2.0f * THIRD) }, FaceVector<3> { Face<3> { { 1, 2, 0 } }, Face<3> { { 2, 3, 0 } }, diff --git a/libraries/shared/src/shared/Shapes.h b/libraries/shared/src/shared/Shapes.h index 3486a0a663..6bd2eab199 100644 --- a/libraries/shared/src/shared/Shapes.h +++ b/libraries/shared/src/shared/Shapes.h @@ -22,6 +22,7 @@ namespace geometry { using Index = uint32_t; using Vec = glm::vec3; using VertexVector = std::vector; + using TexCoordVector = std::vector; using IndexVector = std::vector; template @@ -33,6 +34,7 @@ namespace geometry { template struct Solid { VertexVector vertices; + TexCoordVector texCoords; FaceVector faces; Solid& fitDimension(float newMaxDimension) { From 96e48a01621d45093b05da7aa597429878e2d928 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Wed, 7 Mar 2018 13:16:13 -0800 Subject: [PATCH 02/19] warnings --- .../src/RenderableMaterialEntityItem.cpp | 2 +- .../src/RenderableShapeEntityItem.cpp | 9 +++++---- libraries/render-utils/src/GeometryCache.cpp | 3 +-- libraries/shared/src/shared/Shapes.cpp | 14 +++++++------- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp index 8566b9bae8..ea8edb8a08 100644 --- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp @@ -123,5 +123,5 @@ void MaterialEntityRenderer::doRender(RenderArgs* args) { // Draw! DependencyManager::get()->renderSphere(batch); - args->_details._trianglesRendered += DependencyManager::get()->getSphereTriangleCount(); + args->_details._trianglesRendered += (int)DependencyManager::get()->getSphereTriangleCount(); } diff --git a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp index b14e201366..0e04ae3418 100644 --- a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp @@ -138,11 +138,12 @@ ItemKey ShapeEntityRenderer::getKey() { } bool ShapeEntityRenderer::useMaterialPipeline() const { - withReadLock([&] { - if (_procedural.isReady()) { - return false; - } + bool proceduralReady = resultWithReadLock([&] { + return _procedural.isReady(); }); + if (proceduralReady) { + return false; + } graphics::MaterialKey drawMaterialKey; auto mat = _materials.find("0"); diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 61fcdafd39..edd68603cb 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -401,7 +401,7 @@ vec2 calculateSphereTexCoord(const vec3& vertex) { } vec3 calculateSphereTangent(float u) { - float phi = u * M_PI * 2.0f; + float phi = u * (float)M_PI * 2.0f; return -glm::normalize(glm::vec3(glm::sin(phi), 0.0f, glm::cos(phi))); } @@ -414,7 +414,6 @@ void setupSmoothShape(GeometryCache::ShapeData& shapeData, const geometry::Solid for (const auto& vertex : shape.vertices) { addVec3ToVector(vertices, vertex); addVec3ToVector(vertices, vertex); - vec2 uv = calculateSphereTexCoord(vertex); addVec2ToVector(vertices, calculateSphereTexCoord(vertex)); // We'll fill in the correct tangents later, once we correct the UVs addVec3ToVector(vertices, vec3(0.0f)); diff --git a/libraries/shared/src/shared/Shapes.cpp b/libraries/shared/src/shared/Shapes.cpp index 277154d6b6..afcf956165 100644 --- a/libraries/shared/src/shared/Shapes.cpp +++ b/libraries/shared/src/shared/Shapes.cpp @@ -22,7 +22,7 @@ Solid<3> tesselate(const Solid<3>& solid_, int count) { Solid<3> solid = solid_; float length = glm::length(solid.vertices[0]); for (int i = 0; i < count; ++i) { - Solid<3> result { solid.vertices, {} }; + Solid<3> result { solid.vertices, {}, {} }; result.vertices.reserve(solid.vertices.size() + solid.faces.size() * 6); for (size_t f = 0; f < solid.faces.size(); ++f) { Index baseVertex = (Index)result.vertices.size(); @@ -171,16 +171,16 @@ const Solid<5>& dodecahedron() { // 1 = 3 * x1 + 3 * x2 + x3 // x1 + 2 * x3 = (golden ratio) * x1 // x2 = x1 + 2 * x3 - static const float x1 = 4.0f / (17.0f + 7.0f * sqrt(5.0f)); - static const float x2 = (1.0f / 11.0f) * (5.0f * sqrt(5.0f) - 9.0f); + static const float x1 = 4.0f / (17.0f + 7.0f * sqrtf(5.0f)); + static const float x2 = (1.0f / 11.0f) * (5.0f * sqrtf(5.0f) - 9.0f); static const float x2_2 = x2 / 2.0f; - static const float x3 = (1.0f / 11.0f) * (6.0f * sqrt(5.0f) - 13.0f); + static const float x3 = (1.0f / 11.0f) * (6.0f * sqrtf(5.0f) - 13.0f); // y1 and y2 are the solutions to the following system of equations (x is the sidelength, but is different than x1 because the scale in the y direction is different): // 1 = 3 * y1 + 2 * y2 // y1 = sin(108 deg) * x - // y1 + y2 = x * sqrt(5 + 2 * sqrt(5)) / 2 - static const float y1 = sqrt(2.0f * (5.0f + sqrt(5.0f))) / (sqrt(2.0f * (5.0f + sqrt(5.0f))) + 4.0f * sqrt(5.0f + 2.0f * sqrt(5.0f))); - static const float y2 = -(sqrt(2.0f * (5.0f + sqrt(5.0f))) - 2.0f * sqrt(5.0f + 2.0f * sqrt(5.0f))) / (sqrt(2.0f * (5.0f + sqrt(5.0f))) + 4.0f * sqrt(5.0f + 2.0f * sqrt(5.0f))); + // y1 + y2 = x * sqrtf(5 + 2 * sqrtf(5)) / 2 + static const float y1 = sqrtf(2.0f * (5.0f + sqrtf(5.0f))) / (sqrtf(2.0f * (5.0f + sqrtf(5.0f))) + 4.0f * sqrtf(5.0f + 2.0f * sqrtf(5.0f))); + static const float y2 = -(sqrtf(2.0f * (5.0f + sqrtf(5.0f))) - 2.0f * sqrtf(5.0f + 2.0f * sqrtf(5.0f))) / (sqrtf(2.0f * (5.0f + sqrtf(5.0f))) + 4.0f * sqrtf(5.0f + 2.0f * sqrtf(5.0f))); static const Solid<5> DODECAHEDRON = Solid<5>{ { From 6fe75a3ca407573d852c6d991d9745389820b63b Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Fri, 9 Mar 2018 08:40:31 -0800 Subject: [PATCH 03/19] Breaking out common gpu-gl code --- CMakeLists.txt | 4 +- libraries/gl/src/gl/OffscreenGLCanvas.cpp | 2 + libraries/gpu-gl-common/CMakeLists.txt | 6 + .../src/gpu/gl/GLBackend.cpp | 53 +- .../src/gpu/gl/GLBackend.h | 6 +- .../src/gpu/gl/GLBackendInput.cpp | 0 .../src/gpu/gl/GLBackendOutput.cpp | 11 +- .../src/gpu/gl/GLBackendPipeline.cpp | 0 .../src/gpu/gl/GLBackendQuery.cpp | 6 + .../src/gpu/gl/GLBackendShader.cpp | 345 ++++---- .../src/gpu/gl/GLBackendState.cpp | 36 +- .../src/gpu/gl/GLBackendTexture.cpp | 0 .../src/gpu/gl/GLBackendTransform.cpp | 0 .../src/gpu/gl/GLBuffer.cpp | 0 .../src/gpu/gl/GLBuffer.h | 0 .../src/gpu/gl/GLFramebuffer.cpp | 8 +- .../src/gpu/gl/GLFramebuffer.h | 0 .../src/gpu/gl/GLInputFormat.cpp | 0 .../src/gpu/gl/GLInputFormat.h | 0 .../src/gpu/gl/GLPipeline.cpp | 0 .../src/gpu/gl/GLPipeline.h | 0 .../src/gpu/gl/GLQuery.h | 0 .../src/gpu/gl/GLShader.cpp | 0 .../src/gpu/gl/GLShader.h | 0 .../src/gpu/gl/GLShared.cpp | 17 +- .../src/gpu/gl/GLShared.h | 0 .../src/gpu/gl/GLState.cpp | 0 .../src/gpu/gl/GLState.h | 0 .../src/gpu/gl/GLTexelFormat.cpp | 83 ++ .../src/gpu/gl/GLTexelFormat.h | 0 .../src/gpu/gl/GLTexture.cpp | 0 .../src/gpu/gl/GLTexture.h | 0 libraries/gpu-gl/CMakeLists.txt | 2 +- libraries/gpu-gl/src/gpu/gl/GLBackend.cpp | 764 ------------------ .../gpu-gl/src/gpu/gl/GLBackendInput.cpp | 157 ---- .../gpu-gl/src/gpu/gl/GLDesktopBackend.cpp | 63 ++ libraries/gpu-gl/src/gpu/gl41/GL41Backend.h | 4 +- .../gpu-gl/src/gpu/gl41/GL41BackendBuffer.cpp | 2 +- .../gpu-gl/src/gpu/gl41/GL41BackendOutput.cpp | 4 +- .../gpu-gl/src/gpu/gl41/GL41BackendQuery.cpp | 2 +- .../gpu-gl/src/gpu/gl41/GL41BackendShader.cpp | 2 +- .../src/gpu/gl41/GL41BackendTexture.cpp | 2 +- libraries/gpu-gl/src/gpu/gl45/GL45Backend.h | 5 +- .../gpu-gl/src/gpu/gl45/GL45BackendBuffer.cpp | 2 +- .../gpu-gl/src/gpu/gl45/GL45BackendInput.cpp | 2 +- .../gpu-gl/src/gpu/gl45/GL45BackendOutput.cpp | 4 +- .../gpu-gl/src/gpu/gl45/GL45BackendQuery.cpp | 2 +- .../gpu-gl/src/gpu/gl45/GL45BackendShader.cpp | 2 +- .../src/gpu/gl45/GL45BackendTexture.cpp | 2 +- .../gpu/gl45/GL45BackendVariableTexture.cpp | 2 +- libraries/gpu-gles/CMakeLists.txt | 2 +- libraries/gpu-gles/src/gpu/gl/GLBackend.h | 474 ----------- .../gpu-gles/src/gpu/gl/GLBackendOutput.cpp | 175 ---- .../gpu-gles/src/gpu/gl/GLBackendPipeline.cpp | 291 ------- .../gpu-gles/src/gpu/gl/GLBackendQuery.cpp | 99 --- .../gpu-gles/src/gpu/gl/GLBackendShader.cpp | 583 ------------- .../gpu-gles/src/gpu/gl/GLBackendState.cpp | 334 -------- .../gpu-gles/src/gpu/gl/GLBackendTexture.cpp | 82 -- .../src/gpu/gl/GLBackendTransform.cpp | 171 ---- libraries/gpu-gles/src/gpu/gl/GLBuffer.cpp | 35 - libraries/gpu-gles/src/gpu/gl/GLBuffer.h | 66 -- libraries/gpu-gles/src/gpu/gl/GLESBackend.cpp | 56 ++ .../gpu-gles/src/gpu/gl/GLFramebuffer.cpp | 47 -- libraries/gpu-gles/src/gpu/gl/GLFramebuffer.h | 77 -- .../gpu-gles/src/gpu/gl/GLInputFormat.cpp | 33 - libraries/gpu-gles/src/gpu/gl/GLInputFormat.h | 29 - libraries/gpu-gles/src/gpu/gl/GLPipeline.cpp | 59 -- libraries/gpu-gles/src/gpu/gl/GLPipeline.h | 29 - libraries/gpu-gles/src/gpu/gl/GLQuery.h | 67 -- libraries/gpu-gles/src/gpu/gl/GLShader.cpp | 106 --- libraries/gpu-gles/src/gpu/gl/GLShader.h | 66 -- libraries/gpu-gles/src/gpu/gl/GLShared.cpp | 335 -------- libraries/gpu-gles/src/gpu/gl/GLShared.h | 152 ---- libraries/gpu-gles/src/gpu/gl/GLState.cpp | 248 ------ libraries/gpu-gles/src/gpu/gl/GLState.h | 73 -- .../gpu-gles/src/gpu/gl/GLTexelFormat.cpp | 652 --------------- libraries/gpu-gles/src/gpu/gl/GLTexelFormat.h | 37 - libraries/gpu-gles/src/gpu/gl/GLTexture.cpp | 701 ---------------- libraries/gpu-gles/src/gpu/gl/GLTexture.h | 211 ----- libraries/gpu-gles/src/gpu/gles/GLESBackend.h | 4 +- .../src/gpu/gles/GLESBackendBuffer.cpp | 2 +- .../src/gpu/gles/GLESBackendOutput.cpp | 4 +- .../src/gpu/gles/GLESBackendQuery.cpp | 2 +- .../src/gpu/gles/GLESBackendShader.cpp | 2 +- .../src/gpu/gles/GLESBackendTexture.cpp | 7 +- 85 files changed, 516 insertions(+), 6395 deletions(-) create mode 100644 libraries/gpu-gl-common/CMakeLists.txt rename libraries/{gpu-gles => gpu-gl-common}/src/gpu/gl/GLBackend.cpp (93%) rename libraries/{gpu-gl => gpu-gl-common}/src/gpu/gl/GLBackend.h (99%) rename libraries/{gpu-gles => gpu-gl-common}/src/gpu/gl/GLBackendInput.cpp (100%) rename libraries/{gpu-gl => gpu-gl-common}/src/gpu/gl/GLBackendOutput.cpp (96%) rename libraries/{gpu-gl => gpu-gl-common}/src/gpu/gl/GLBackendPipeline.cpp (100%) rename libraries/{gpu-gl => gpu-gl-common}/src/gpu/gl/GLBackendQuery.cpp (97%) rename libraries/{gpu-gl => gpu-gl-common}/src/gpu/gl/GLBackendShader.cpp (62%) rename libraries/{gpu-gl => gpu-gl-common}/src/gpu/gl/GLBackendState.cpp (97%) rename libraries/{gpu-gl => gpu-gl-common}/src/gpu/gl/GLBackendTexture.cpp (100%) rename libraries/{gpu-gl => gpu-gl-common}/src/gpu/gl/GLBackendTransform.cpp (100%) rename libraries/{gpu-gl => gpu-gl-common}/src/gpu/gl/GLBuffer.cpp (100%) rename libraries/{gpu-gl => gpu-gl-common}/src/gpu/gl/GLBuffer.h (100%) rename libraries/{gpu-gl => gpu-gl-common}/src/gpu/gl/GLFramebuffer.cpp (96%) rename libraries/{gpu-gl => gpu-gl-common}/src/gpu/gl/GLFramebuffer.h (100%) rename libraries/{gpu-gl => gpu-gl-common}/src/gpu/gl/GLInputFormat.cpp (100%) rename libraries/{gpu-gl => gpu-gl-common}/src/gpu/gl/GLInputFormat.h (100%) rename libraries/{gpu-gl => gpu-gl-common}/src/gpu/gl/GLPipeline.cpp (100%) rename libraries/{gpu-gl => gpu-gl-common}/src/gpu/gl/GLPipeline.h (100%) rename libraries/{gpu-gl => gpu-gl-common}/src/gpu/gl/GLQuery.h (100%) rename libraries/{gpu-gl => gpu-gl-common}/src/gpu/gl/GLShader.cpp (100%) rename libraries/{gpu-gl => gpu-gl-common}/src/gpu/gl/GLShader.h (100%) rename libraries/{gpu-gl => gpu-gl-common}/src/gpu/gl/GLShared.cpp (97%) rename libraries/{gpu-gl => gpu-gl-common}/src/gpu/gl/GLShared.h (100%) rename libraries/{gpu-gl => gpu-gl-common}/src/gpu/gl/GLState.cpp (100%) rename libraries/{gpu-gl => gpu-gl-common}/src/gpu/gl/GLState.h (100%) rename libraries/{gpu-gl => gpu-gl-common}/src/gpu/gl/GLTexelFormat.cpp (90%) rename libraries/{gpu-gl => gpu-gl-common}/src/gpu/gl/GLTexelFormat.h (100%) rename libraries/{gpu-gl => gpu-gl-common}/src/gpu/gl/GLTexture.cpp (100%) rename libraries/{gpu-gl => gpu-gl-common}/src/gpu/gl/GLTexture.h (100%) delete mode 100644 libraries/gpu-gl/src/gpu/gl/GLBackend.cpp delete mode 100644 libraries/gpu-gl/src/gpu/gl/GLBackendInput.cpp create mode 100644 libraries/gpu-gl/src/gpu/gl/GLDesktopBackend.cpp delete mode 100644 libraries/gpu-gles/src/gpu/gl/GLBackend.h delete mode 100644 libraries/gpu-gles/src/gpu/gl/GLBackendOutput.cpp delete mode 100644 libraries/gpu-gles/src/gpu/gl/GLBackendPipeline.cpp delete mode 100644 libraries/gpu-gles/src/gpu/gl/GLBackendQuery.cpp delete mode 100644 libraries/gpu-gles/src/gpu/gl/GLBackendShader.cpp delete mode 100644 libraries/gpu-gles/src/gpu/gl/GLBackendState.cpp delete mode 100644 libraries/gpu-gles/src/gpu/gl/GLBackendTexture.cpp delete mode 100644 libraries/gpu-gles/src/gpu/gl/GLBackendTransform.cpp delete mode 100644 libraries/gpu-gles/src/gpu/gl/GLBuffer.cpp delete mode 100644 libraries/gpu-gles/src/gpu/gl/GLBuffer.h create mode 100644 libraries/gpu-gles/src/gpu/gl/GLESBackend.cpp delete mode 100644 libraries/gpu-gles/src/gpu/gl/GLFramebuffer.cpp delete mode 100644 libraries/gpu-gles/src/gpu/gl/GLFramebuffer.h delete mode 100644 libraries/gpu-gles/src/gpu/gl/GLInputFormat.cpp delete mode 100644 libraries/gpu-gles/src/gpu/gl/GLInputFormat.h delete mode 100644 libraries/gpu-gles/src/gpu/gl/GLPipeline.cpp delete mode 100644 libraries/gpu-gles/src/gpu/gl/GLPipeline.h delete mode 100644 libraries/gpu-gles/src/gpu/gl/GLQuery.h delete mode 100644 libraries/gpu-gles/src/gpu/gl/GLShader.cpp delete mode 100644 libraries/gpu-gles/src/gpu/gl/GLShader.h delete mode 100644 libraries/gpu-gles/src/gpu/gl/GLShared.cpp delete mode 100644 libraries/gpu-gles/src/gpu/gl/GLShared.h delete mode 100644 libraries/gpu-gles/src/gpu/gl/GLState.cpp delete mode 100644 libraries/gpu-gles/src/gpu/gl/GLState.h delete mode 100644 libraries/gpu-gles/src/gpu/gl/GLTexelFormat.cpp delete mode 100644 libraries/gpu-gles/src/gpu/gl/GLTexelFormat.h delete mode 100644 libraries/gpu-gles/src/gpu/gl/GLTexture.cpp delete mode 100644 libraries/gpu-gles/src/gpu/gl/GLTexture.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 25fd4731e6..758d08afc9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,9 +67,9 @@ set(PLATFORM_QT_GL OpenGL) if (USE_GLES) add_definitions(-DUSE_GLES) - set(PLATFORM_GL_BACKEND gpu-gles) + set(PLATFORM_GL_BACKEND gpu-gl-common gpu-gles) else() - set(PLATFORM_GL_BACKEND gpu-gl) + set(PLATFORM_GL_BACKEND gpu-gl-common gpu-gl) endif() diff --git a/libraries/gl/src/gl/OffscreenGLCanvas.cpp b/libraries/gl/src/gl/OffscreenGLCanvas.cpp index 1bde9e289e..4d92ee8c17 100644 --- a/libraries/gl/src/gl/OffscreenGLCanvas.cpp +++ b/libraries/gl/src/gl/OffscreenGLCanvas.cpp @@ -70,6 +70,7 @@ bool OffscreenGLCanvas::create(QOpenGLContext* sharedContext) { } #endif +#if !defined(USE_GLES) if (gl::Context::enableDebugLogger()) { _context->makeCurrent(_offscreenSurface); QOpenGLDebugLogger *logger = new QOpenGLDebugLogger(this); @@ -79,6 +80,7 @@ bool OffscreenGLCanvas::create(QOpenGLContext* sharedContext) { logger->startLogging(QOpenGLDebugLogger::SynchronousLogging); _context->doneCurrent(); } +#endif return true; } diff --git a/libraries/gpu-gl-common/CMakeLists.txt b/libraries/gpu-gl-common/CMakeLists.txt new file mode 100644 index 0000000000..2b6f8d4d40 --- /dev/null +++ b/libraries/gpu-gl-common/CMakeLists.txt @@ -0,0 +1,6 @@ +set(TARGET_NAME gpu-gl-common) +setup_hifi_library(Concurrent) +link_hifi_libraries(shared gl gpu) +GroupSources("src") +target_opengl() + diff --git a/libraries/gpu-gles/src/gpu/gl/GLBackend.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp similarity index 93% rename from libraries/gpu-gles/src/gpu/gl/GLBackend.cpp rename to libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp index fc1bc39929..9e248c3947 100644 --- a/libraries/gpu-gles/src/gpu/gl/GLBackend.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp @@ -1,9 +1,9 @@ // // GLBackend.cpp -// libraries/gpu-gl-android/src/gpu/gl +// libraries/gpu/src/gpu // -// Created by Cristian Duarte & Gabriel Calero on 9/21/2016. -// Copyright 2016 High Fidelity, Inc. +// Created by Sam Gateau on 10/27/2014. +// Copyright 2014 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 @@ -16,16 +16,11 @@ #include #include -#include "../gles/GLESBackend.h" - #if defined(NSIGHT_FOUND) #include "nvToolsExt.h" #endif -#include #include -#include -#include #include "GLTexture.h" #include "GLShader.h" @@ -33,39 +28,6 @@ using namespace gpu; using namespace gpu::gl; -static GLBackend* INSTANCE{ nullptr }; - -BackendPointer GLBackend::createBackend() { - // FIXME provide a mechanism to override the backend for testing - // Where the gpuContext is initialized and where the TRUE Backend is created and assigned - //auto version = QOpenGLContextWrapper::currentContextVersion(); - std::shared_ptr result; - - qDebug() << "Using OpenGL ES backend"; - result = std::make_shared(); - - result->initInput(); - result->initTransform(); - result->initTextureManagementStage(); - - INSTANCE = result.get(); - void* voidInstance = &(*result); - qApp->setProperty(hifi::properties::gl::BACKEND, QVariant::fromValue(voidInstance)); - return result; -} - -GLBackend& getBackend() { - if (!INSTANCE) { - INSTANCE = static_cast(qApp->property(hifi::properties::gl::BACKEND).value()); - } - return *INSTANCE; -} - -bool GLBackend::makeProgram(Shader& shader, const Shader::BindingSet& slotBindings, const Shader::CompilationHandler& handler) { - return GLShader::makeProgram(getBackend(), shader, slotBindings, handler); -} - - GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] = { (&::gpu::gl::GLBackend::do_draw), @@ -147,6 +109,9 @@ void GLBackend::init() { qCDebug(gpugllogging) << "\tcard:" << gpu->getName(); qCDebug(gpugllogging) << "\tdriver:" << gpu->getDriver(); qCDebug(gpugllogging) << "\tdedicated memory:" << gpu->getMemory() << "MB"; +#if !defined(USE_GLES) + qCDebug(gpugllogging, "V-Sync is %s\n", (::gl::getSwapInterval() > 0 ? "ON" : "OFF")); +#endif #if THREADED_TEXTURE_BUFFERING // This has to happen on the main thread in order to give the thread // pool a reasonable parent object @@ -224,7 +189,7 @@ void GLBackend::renderPassTransfer(const Batch& batch) { } { // Sync the transform buffers - PROFILE_RANGE(render_gpu_gl_detail, "transferGPUTransform"); + PROFILE_RANGE(render_gpu_gl_detail, "syncGPUTransform"); transferTransformState(batch); } @@ -292,7 +257,7 @@ void GLBackend::render(const Batch& batch) { #ifdef GPU_STEREO_DRAWCALL_INSTANCED if (_stereo.isStereo()) { - glEnable(GL_CLIP_DISTANCE0_EXT); + glEnable(GL_CLIP_DISTANCE0); } #endif { @@ -301,7 +266,7 @@ void GLBackend::render(const Batch& batch) { } #ifdef GPU_STEREO_DRAWCALL_INSTANCED if (_stereo.isStereo()) { - glDisable(GL_CLIP_DISTANCE0_EXT); + glDisable(GL_CLIP_DISTANCE0); } #endif diff --git a/libraries/gpu-gl/src/gpu/gl/GLBackend.h b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h similarity index 99% rename from libraries/gpu-gl/src/gpu/gl/GLBackend.h rename to libraries/gpu-gl-common/src/gpu/gl/GLBackend.h index 18916ac18c..9d462840f5 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLBackend.h +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h @@ -32,9 +32,13 @@ // Different versions for the stereo drawcall // Current preferred is "instanced" which draw the shape twice but instanced and rely on clipping plane to draw left/right side only -//#define GPU_STEREO_TECHNIQUE_DOUBLED_SIMPLE +#if defined(USE_GLES) +#define GPU_STEREO_TECHNIQUE_DOUBLED_SIMPLE +#else //#define GPU_STEREO_TECHNIQUE_DOUBLED_SMARTER #define GPU_STEREO_TECHNIQUE_INSTANCED +#endif + // Let these be configured by the one define picked above diff --git a/libraries/gpu-gles/src/gpu/gl/GLBackendInput.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp similarity index 100% rename from libraries/gpu-gles/src/gpu/gl/GLBackendInput.cpp rename to libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp diff --git a/libraries/gpu-gl/src/gpu/gl/GLBackendOutput.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackendOutput.cpp similarity index 96% rename from libraries/gpu-gl/src/gpu/gl/GLBackendOutput.cpp rename to libraries/gpu-gl-common/src/gpu/gl/GLBackendOutput.cpp index 358b90ed8b..ab17a6295d 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLBackendOutput.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackendOutput.cpp @@ -17,6 +17,11 @@ using namespace gpu; using namespace gpu::gl; +#if defined(USE_GLES) +#define GL_FRAMEBUFFER_SRGB GL_FRAMEBUFFER_SRGB_EXT +#define glClearDepth glClearDepthf +#endif + void GLBackend::syncOutputStateCache() { GLint currentFBO; glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, ¤tFBO); @@ -68,7 +73,7 @@ void GLBackend::do_clearFramebuffer(const Batch& batch, size_t paramOffset) { if (masks & Framebuffer::BUFFER_STENCIL) { glClearStencil(stencil); glmask |= GL_STENCIL_BUFFER_BIT; - + cacheStencilMask = _pipeline._stateCache.stencilActivation.getWriteMaskFront(); if (cacheStencilMask != 0xFF) { restoreStencilMask = true; @@ -162,7 +167,11 @@ void GLBackend::downloadFramebuffer(const FramebufferPointer& srcFramebuffer, co return; } +#if defined(USE_GLES) + GLenum format = GL_RGBA; +#else GLenum format = GL_BGRA; +#endif if (destImage.format() != QImage::Format_ARGB32) { qCWarning(gpugllogging) << "GLBackend::downloadFramebuffer : destImage format must be FORMAT_ARGB32 to receive the region of the framebuffer"; return; diff --git a/libraries/gpu-gl/src/gpu/gl/GLBackendPipeline.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackendPipeline.cpp similarity index 100% rename from libraries/gpu-gl/src/gpu/gl/GLBackendPipeline.cpp rename to libraries/gpu-gl-common/src/gpu/gl/GLBackendPipeline.cpp diff --git a/libraries/gpu-gl/src/gpu/gl/GLBackendQuery.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackendQuery.cpp similarity index 97% rename from libraries/gpu-gl/src/gpu/gl/GLBackendQuery.cpp rename to libraries/gpu-gl-common/src/gpu/gl/GLBackendQuery.cpp index bdea67a99a..b64804fe7c 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLBackendQuery.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackendQuery.cpp @@ -25,6 +25,7 @@ static bool timeElapsed = false; #endif void GLBackend::do_beginQuery(const Batch& batch, size_t paramOffset) { +#if !defined(USE_GLES) auto query = batch._queries.get(batch._params[paramOffset]._uint); GLQuery* glquery = syncGPUObject(*query); if (glquery) { @@ -43,9 +44,11 @@ void GLBackend::do_beginQuery(const Batch& batch, size_t paramOffset) { glquery->_rangeQueryDepth = _queryStage._rangeQueryDepth; (void)CHECK_GL_ERROR(); } +#endif } void GLBackend::do_endQuery(const Batch& batch, size_t paramOffset) { +#if !defined(USE_GLES) auto query = batch._queries.get(batch._params[paramOffset]._uint); GLQuery* glquery = syncGPUObject(*query); if (glquery) { @@ -66,9 +69,11 @@ void GLBackend::do_endQuery(const Batch& batch, size_t paramOffset) { (void)CHECK_GL_ERROR(); } +#endif } void GLBackend::do_getQuery(const Batch& batch, size_t paramOffset) { +#if !defined(USE_GLES) auto query = batch._queries.get(batch._params[paramOffset]._uint); GLQuery* glquery = syncGPUObject(*query); if (glquery) { @@ -90,6 +95,7 @@ void GLBackend::do_getQuery(const Batch& batch, size_t paramOffset) { (void)CHECK_GL_ERROR(); } } +#endif } void GLBackend::resetQueryStage() { diff --git a/libraries/gpu-gl/src/gpu/gl/GLBackendShader.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackendShader.cpp similarity index 62% rename from libraries/gpu-gl/src/gpu/gl/GLBackendShader.cpp rename to libraries/gpu-gl-common/src/gpu/gl/GLBackendShader.cpp index 93c9b0d2ff..8fab860c8a 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLBackendShader.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackendShader.cpp @@ -14,38 +14,65 @@ using namespace gpu::gl; // GLSL version std::string GLBackend::getBackendShaderHeader() const { - return std::string("#version 410 core"); + +#if defined(USE_GLES) + static const std::string header( +R"SHADER( +#version 310 es +#extension GL_EXT_texture_buffer : enable +precision lowp float; // check precision 2 +precision lowp samplerBuffer; +precision lowp sampler2DShadow; +)SHADER"); +#else + static const std::string header( +R"SHADER( +#version 410 core +)SHADER"); +#endif + + return header; } + // Shader domain -static const size_t NUM_SHADER_DOMAINS = 3; +static const size_t NUM_SHADER_DOMAINS = 2; // GL Shader type enums // Must match the order of type specified in gpu::Shader::Type -static const std::array SHADER_DOMAINS { { +static const std::array SHADER_DOMAINS{ { GL_VERTEX_SHADER, GL_FRAGMENT_SHADER, - GL_GEOMETRY_SHADER, } }; // Domain specific defines // Must match the order of type specified in gpu::Shader::Type -static const std::array DOMAIN_DEFINES { { +static const std::array DOMAIN_DEFINES{ { "#define GPU_VERTEX_SHADER", "#define GPU_PIXEL_SHADER", - "#define GPU_GEOMETRY_SHADER", } }; // Stereo specific defines -static const std::string stereoVersion { +static const std::string stereoVersion{ #ifdef GPU_STEREO_DRAWCALL_INSTANCED - "#define GPU_TRANSFORM_IS_STEREO\n#define GPU_TRANSFORM_STEREO_CAMERA\n#define GPU_TRANSFORM_STEREO_CAMERA_INSTANCED\n#define GPU_TRANSFORM_STEREO_SPLIT_SCREEN" +R"SHADER( +#define GPU_TRANSFORM_IS_STEREO +#define GPU_TRANSFORM_STEREO_CAMERA +#define GPU_TRANSFORM_STEREO_CAMERA_INSTANCED +#define GPU_TRANSFORM_STEREO_SPLIT_SCREEN +)SHADER" #endif #ifdef GPU_STEREO_DRAWCALL_DOUBLED #ifdef GPU_STEREO_CAMERA_BUFFER - "#define GPU_TRANSFORM_IS_STEREO\n#define GPU_TRANSFORM_STEREO_CAMERA\n#define GPU_TRANSFORM_STEREO_CAMERA_ATTRIBUTED" +R"SHADER( +#define GPU_TRANSFORM_IS_STEREO +#define GPU_TRANSFORM_STEREO_CAMERA +#define GPU_TRANSFORM_STEREO_CAMERA_ATTRIBUTED +)SHADER" #else - "#define GPU_TRANSFORM_IS_STEREO" +R"SHADER( +#define GPU_TRANSFORM_IS_STEREO +)SHADER" #endif #endif }; @@ -67,7 +94,10 @@ GLShader* GLBackend::compileBackendShader(const Shader& shader, const Shader::Co for (int version = 0; version < GLShader::NumVersions; version++) { auto& shaderObject = shaderObjects[version]; - std::string shaderDefines = getBackendShaderHeader() + "\n" + DOMAIN_DEFINES[shader.getType()] + "\n" + VERSION_DEFINES[version]; + std::string shaderDefines = getBackendShaderHeader() + "\n" + + DOMAIN_DEFINES[shader.getType()] + "\n" + + VERSION_DEFINES[version]; + if (handler) { bool retest = true; std::string currentSrc = shaderSource; @@ -154,149 +184,173 @@ GLShader* GLBackend::compileBackendProgram(const Shader& program, const Shader:: return object; } + GLBackend::ElementResource GLBackend::getFormatFromGLUniform(GLenum gltype) { switch (gltype) { - case GL_FLOAT: return ElementResource(Element(SCALAR, gpu::FLOAT, UNIFORM), Resource::BUFFER); - case GL_FLOAT_VEC2: return ElementResource(Element(VEC2, gpu::FLOAT, UNIFORM), Resource::BUFFER); - case GL_FLOAT_VEC3: return ElementResource(Element(VEC3, gpu::FLOAT, UNIFORM), Resource::BUFFER); - case GL_FLOAT_VEC4: return ElementResource(Element(VEC4, gpu::FLOAT, UNIFORM), Resource::BUFFER); - /* - case GL_DOUBLE: return ElementResource(Element(SCALAR, gpu::FLOAT, UNIFORM), Resource::BUFFER); - case GL_DOUBLE_VEC2: return ElementResource(Element(VEC2, gpu::FLOAT, UNIFORM), Resource::BUFFER); - case GL_DOUBLE_VEC3: return ElementResource(Element(VEC3, gpu::FLOAT, UNIFORM), Resource::BUFFER); - case GL_DOUBLE_VEC4: return ElementResource(Element(VEC4, gpu::FLOAT, UNIFORM), Resource::BUFFER); - */ - case GL_INT: return ElementResource(Element(SCALAR, gpu::INT32, UNIFORM), Resource::BUFFER); - case GL_INT_VEC2: return ElementResource(Element(VEC2, gpu::INT32, UNIFORM), Resource::BUFFER); - case GL_INT_VEC3: return ElementResource(Element(VEC3, gpu::INT32, UNIFORM), Resource::BUFFER); - case GL_INT_VEC4: return ElementResource(Element(VEC4, gpu::INT32, UNIFORM), Resource::BUFFER); + case GL_FLOAT: + return ElementResource(Element(SCALAR, gpu::FLOAT, UNIFORM), Resource::BUFFER); + case GL_FLOAT_VEC2: + return ElementResource(Element(VEC2, gpu::FLOAT, UNIFORM), Resource::BUFFER); + case GL_FLOAT_VEC3: + return ElementResource(Element(VEC3, gpu::FLOAT, UNIFORM), Resource::BUFFER); + case GL_FLOAT_VEC4: + return ElementResource(Element(VEC4, gpu::FLOAT, UNIFORM), Resource::BUFFER); - case GL_UNSIGNED_INT: return ElementResource(Element(SCALAR, gpu::UINT32, UNIFORM), Resource::BUFFER); -#if defined(Q_OS_WIN) - case GL_UNSIGNED_INT_VEC2: return ElementResource(Element(VEC2, gpu::UINT32, UNIFORM), Resource::BUFFER); - case GL_UNSIGNED_INT_VEC3: return ElementResource(Element(VEC3, gpu::UINT32, UNIFORM), Resource::BUFFER); - case GL_UNSIGNED_INT_VEC4: return ElementResource(Element(VEC4, gpu::UINT32, UNIFORM), Resource::BUFFER); + case GL_INT: + return ElementResource(Element(SCALAR, gpu::INT32, UNIFORM), Resource::BUFFER); + case GL_INT_VEC2: + return ElementResource(Element(VEC2, gpu::INT32, UNIFORM), Resource::BUFFER); + case GL_INT_VEC3: + return ElementResource(Element(VEC3, gpu::INT32, UNIFORM), Resource::BUFFER); + case GL_INT_VEC4: + return ElementResource(Element(VEC4, gpu::INT32, UNIFORM), Resource::BUFFER); + + case GL_UNSIGNED_INT: + return ElementResource(Element(SCALAR, gpu::UINT32, UNIFORM), Resource::BUFFER); + case GL_UNSIGNED_INT_VEC2: + return ElementResource(Element(VEC2, gpu::UINT32, UNIFORM), Resource::BUFFER); + case GL_UNSIGNED_INT_VEC3: + return ElementResource(Element(VEC3, gpu::UINT32, UNIFORM), Resource::BUFFER); + case GL_UNSIGNED_INT_VEC4: + return ElementResource(Element(VEC4, gpu::UINT32, UNIFORM), Resource::BUFFER); + + case GL_BOOL: + return ElementResource(Element(SCALAR, gpu::BOOL, UNIFORM), Resource::BUFFER); + case GL_BOOL_VEC2: + return ElementResource(Element(VEC2, gpu::BOOL, UNIFORM), Resource::BUFFER); + case GL_BOOL_VEC3: + return ElementResource(Element(VEC3, gpu::BOOL, UNIFORM), Resource::BUFFER); + case GL_BOOL_VEC4: + return ElementResource(Element(VEC4, gpu::BOOL, UNIFORM), Resource::BUFFER); + + case GL_FLOAT_MAT2: + return ElementResource(Element(gpu::MAT2, gpu::FLOAT, UNIFORM), Resource::BUFFER); + case GL_FLOAT_MAT3: + return ElementResource(Element(MAT3, gpu::FLOAT, UNIFORM), Resource::BUFFER); + case GL_FLOAT_MAT4: + return ElementResource(Element(MAT4, gpu::FLOAT, UNIFORM), Resource::BUFFER); + + case GL_SAMPLER_2D: + return ElementResource(Element(SCALAR, gpu::FLOAT, SAMPLER), Resource::TEXTURE_2D); + case GL_SAMPLER_3D: + return ElementResource(Element(SCALAR, gpu::FLOAT, SAMPLER), Resource::TEXTURE_3D); + case GL_SAMPLER_CUBE: + return ElementResource(Element(SCALAR, gpu::FLOAT, SAMPLER), Resource::TEXTURE_CUBE); + case GL_SAMPLER_2D_MULTISAMPLE: + return ElementResource(Element(SCALAR, gpu::FLOAT, SAMPLER_MULTISAMPLE), Resource::TEXTURE_2D); + case GL_SAMPLER_2D_ARRAY: + return ElementResource(Element(SCALAR, gpu::FLOAT, SAMPLER), Resource::TEXTURE_2D_ARRAY); + case GL_SAMPLER_2D_MULTISAMPLE_ARRAY: + return ElementResource(Element(SCALAR, gpu::FLOAT, SAMPLER_MULTISAMPLE), Resource::TEXTURE_2D_ARRAY); + case GL_SAMPLER_2D_SHADOW: + return ElementResource(Element(SCALAR, gpu::FLOAT, SAMPLER_SHADOW), Resource::TEXTURE_2D); + case GL_SAMPLER_CUBE_SHADOW: + return ElementResource(Element(SCALAR, gpu::FLOAT, SAMPLER_SHADOW), Resource::TEXTURE_CUBE); + case GL_SAMPLER_2D_ARRAY_SHADOW: + return ElementResource(Element(SCALAR, gpu::FLOAT, SAMPLER_SHADOW), Resource::TEXTURE_2D_ARRAY); + case GL_SAMPLER_BUFFER: + return ElementResource(Element(SCALAR, gpu::FLOAT, RESOURCE_BUFFER), Resource::BUFFER); + case GL_INT_SAMPLER_2D: + return ElementResource(Element(SCALAR, gpu::INT32, SAMPLER), Resource::TEXTURE_2D); + case GL_INT_SAMPLER_2D_MULTISAMPLE: + return ElementResource(Element(SCALAR, gpu::INT32, SAMPLER_MULTISAMPLE), Resource::TEXTURE_2D); + case GL_INT_SAMPLER_3D: + return ElementResource(Element(SCALAR, gpu::INT32, SAMPLER), Resource::TEXTURE_3D); + case GL_INT_SAMPLER_CUBE: + return ElementResource(Element(SCALAR, gpu::INT32, SAMPLER), Resource::TEXTURE_CUBE); + case GL_INT_SAMPLER_2D_ARRAY: + return ElementResource(Element(SCALAR, gpu::INT32, SAMPLER), Resource::TEXTURE_2D_ARRAY); + case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: + return ElementResource(Element(SCALAR, gpu::INT32, SAMPLER_MULTISAMPLE), Resource::TEXTURE_2D_ARRAY); + case GL_UNSIGNED_INT_SAMPLER_2D: + return ElementResource(Element(SCALAR, gpu::UINT32, SAMPLER), Resource::TEXTURE_2D); + case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: + return ElementResource(Element(SCALAR, gpu::UINT32, SAMPLER_MULTISAMPLE), Resource::TEXTURE_2D); + case GL_UNSIGNED_INT_SAMPLER_3D: + return ElementResource(Element(SCALAR, gpu::UINT32, SAMPLER), Resource::TEXTURE_3D); + case GL_UNSIGNED_INT_SAMPLER_CUBE: + return ElementResource(Element(SCALAR, gpu::UINT32, SAMPLER), Resource::TEXTURE_CUBE); + case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: + return ElementResource(Element(SCALAR, gpu::UINT32, SAMPLER), Resource::TEXTURE_2D_ARRAY); + case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: + return ElementResource(Element(SCALAR, gpu::UINT32, SAMPLER_MULTISAMPLE), Resource::TEXTURE_2D_ARRAY); + +#if !defined(USE_GLES) + case GL_SAMPLER_1D: + return ElementResource(Element(SCALAR, gpu::FLOAT, SAMPLER), Resource::TEXTURE_1D); + case GL_SAMPLER_1D_ARRAY: + return ElementResource(Element(SCALAR, gpu::FLOAT, SAMPLER), Resource::TEXTURE_1D_ARRAY); + case GL_INT_SAMPLER_1D: + return ElementResource(Element(SCALAR, gpu::INT32, SAMPLER), Resource::TEXTURE_1D); + case GL_INT_SAMPLER_1D_ARRAY: + return ElementResource(Element(SCALAR, gpu::INT32, SAMPLER), Resource::TEXTURE_1D_ARRAY); + case GL_UNSIGNED_INT_SAMPLER_1D: + return ElementResource(Element(SCALAR, gpu::UINT32, SAMPLER), Resource::TEXTURE_1D); + case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY: + return ElementResource(Element(SCALAR, gpu::UINT32, SAMPLER), Resource::TEXTURE_1D_ARRAY); #endif - case GL_BOOL: return ElementResource(Element(SCALAR, gpu::BOOL, UNIFORM), Resource::BUFFER); - case GL_BOOL_VEC2: return ElementResource(Element(VEC2, gpu::BOOL, UNIFORM), Resource::BUFFER); - case GL_BOOL_VEC3: return ElementResource(Element(VEC3, gpu::BOOL, UNIFORM), Resource::BUFFER); - case GL_BOOL_VEC4: return ElementResource(Element(VEC4, gpu::BOOL, UNIFORM), Resource::BUFFER); - - - case GL_FLOAT_MAT2: return ElementResource(Element(gpu::MAT2, gpu::FLOAT, UNIFORM), Resource::BUFFER); - case GL_FLOAT_MAT3: return ElementResource(Element(MAT3, gpu::FLOAT, UNIFORM), Resource::BUFFER); - case GL_FLOAT_MAT4: return ElementResource(Element(MAT4, gpu::FLOAT, UNIFORM), Resource::BUFFER); - - /* {GL_FLOAT_MAT2x3 mat2x3}, - {GL_FLOAT_MAT2x4 mat2x4}, - {GL_FLOAT_MAT3x2 mat3x2}, - {GL_FLOAT_MAT3x4 mat3x4}, - {GL_FLOAT_MAT4x2 mat4x2}, - {GL_FLOAT_MAT4x3 mat4x3}, - {GL_DOUBLE_MAT2 dmat2}, - {GL_DOUBLE_MAT3 dmat3}, - {GL_DOUBLE_MAT4 dmat4}, - {GL_DOUBLE_MAT2x3 dmat2x3}, - {GL_DOUBLE_MAT2x4 dmat2x4}, - {GL_DOUBLE_MAT3x2 dmat3x2}, - {GL_DOUBLE_MAT3x4 dmat3x4}, - {GL_DOUBLE_MAT4x2 dmat4x2}, - {GL_DOUBLE_MAT4x3 dmat4x3}, - */ - - case GL_SAMPLER_1D: return ElementResource(Element(SCALAR, gpu::FLOAT, SAMPLER), Resource::TEXTURE_1D); - case GL_SAMPLER_2D: return ElementResource(Element(SCALAR, gpu::FLOAT, SAMPLER), Resource::TEXTURE_2D); - - case GL_SAMPLER_3D: return ElementResource(Element(SCALAR, gpu::FLOAT, SAMPLER), Resource::TEXTURE_3D); - case GL_SAMPLER_CUBE: return ElementResource(Element(SCALAR, gpu::FLOAT, SAMPLER), Resource::TEXTURE_CUBE); - -#if defined(Q_OS_WIN) - case GL_SAMPLER_2D_MULTISAMPLE: return ElementResource(Element(SCALAR, gpu::FLOAT, SAMPLER_MULTISAMPLE), Resource::TEXTURE_2D); - case GL_SAMPLER_1D_ARRAY: return ElementResource(Element(SCALAR, gpu::FLOAT, SAMPLER), Resource::TEXTURE_1D_ARRAY); - case GL_SAMPLER_2D_ARRAY: return ElementResource(Element(SCALAR, gpu::FLOAT, SAMPLER), Resource::TEXTURE_2D_ARRAY); - case GL_SAMPLER_2D_MULTISAMPLE_ARRAY: return ElementResource(Element(SCALAR, gpu::FLOAT, SAMPLER_MULTISAMPLE), Resource::TEXTURE_2D_ARRAY); -#endif - - case GL_SAMPLER_2D_SHADOW: return ElementResource(Element(SCALAR, gpu::FLOAT, SAMPLER_SHADOW), Resource::TEXTURE_2D); -#if defined(Q_OS_WIN) - case GL_SAMPLER_CUBE_SHADOW: return ElementResource(Element(SCALAR, gpu::FLOAT, SAMPLER_SHADOW), Resource::TEXTURE_CUBE); - - case GL_SAMPLER_2D_ARRAY_SHADOW: return ElementResource(Element(SCALAR, gpu::FLOAT, SAMPLER_SHADOW), Resource::TEXTURE_2D_ARRAY); -#endif - - // {GL_SAMPLER_1D_SHADOW sampler1DShadow}, - // {GL_SAMPLER_1D_ARRAY_SHADOW sampler1DArrayShadow}, - - case GL_SAMPLER_BUFFER: return ElementResource(Element(SCALAR, gpu::FLOAT, RESOURCE_BUFFER), Resource::BUFFER); - - // {GL_SAMPLER_2D_RECT sampler2DRect}, - // {GL_SAMPLER_2D_RECT_SHADOW sampler2DRectShadow}, - -#if defined(Q_OS_WIN) - case GL_INT_SAMPLER_1D: return ElementResource(Element(SCALAR, gpu::INT32, SAMPLER), Resource::TEXTURE_1D); - case GL_INT_SAMPLER_2D: return ElementResource(Element(SCALAR, gpu::INT32, SAMPLER), Resource::TEXTURE_2D); - case GL_INT_SAMPLER_2D_MULTISAMPLE: return ElementResource(Element(SCALAR, gpu::INT32, SAMPLER_MULTISAMPLE), Resource::TEXTURE_2D); - case GL_INT_SAMPLER_3D: return ElementResource(Element(SCALAR, gpu::INT32, SAMPLER), Resource::TEXTURE_3D); - case GL_INT_SAMPLER_CUBE: return ElementResource(Element(SCALAR, gpu::INT32, SAMPLER), Resource::TEXTURE_CUBE); - - case GL_INT_SAMPLER_1D_ARRAY: return ElementResource(Element(SCALAR, gpu::INT32, SAMPLER), Resource::TEXTURE_1D_ARRAY); - case GL_INT_SAMPLER_2D_ARRAY: return ElementResource(Element(SCALAR, gpu::INT32, SAMPLER), Resource::TEXTURE_2D_ARRAY); - case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: return ElementResource(Element(SCALAR, gpu::INT32, SAMPLER_MULTISAMPLE), Resource::TEXTURE_2D_ARRAY); - - // {GL_INT_SAMPLER_BUFFER isamplerBuffer}, - // {GL_INT_SAMPLER_2D_RECT isampler2DRect}, - - case GL_UNSIGNED_INT_SAMPLER_1D: return ElementResource(Element(SCALAR, gpu::UINT32, SAMPLER), Resource::TEXTURE_1D); - case GL_UNSIGNED_INT_SAMPLER_2D: return ElementResource(Element(SCALAR, gpu::UINT32, SAMPLER), Resource::TEXTURE_2D); - case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: return ElementResource(Element(SCALAR, gpu::UINT32, SAMPLER_MULTISAMPLE), Resource::TEXTURE_2D); - case GL_UNSIGNED_INT_SAMPLER_3D: return ElementResource(Element(SCALAR, gpu::UINT32, SAMPLER), Resource::TEXTURE_3D); - case GL_UNSIGNED_INT_SAMPLER_CUBE: return ElementResource(Element(SCALAR, gpu::UINT32, SAMPLER), Resource::TEXTURE_CUBE); - - case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY: return ElementResource(Element(SCALAR, gpu::UINT32, SAMPLER), Resource::TEXTURE_1D_ARRAY); - case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: return ElementResource(Element(SCALAR, gpu::UINT32, SAMPLER), Resource::TEXTURE_2D_ARRAY); - case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: return ElementResource(Element(SCALAR, gpu::UINT32, SAMPLER_MULTISAMPLE), Resource::TEXTURE_2D_ARRAY); -#endif - // {GL_UNSIGNED_INT_SAMPLER_BUFFER usamplerBuffer}, - // {GL_UNSIGNED_INT_SAMPLER_2D_RECT usampler2DRect}, - /* - {GL_IMAGE_1D image1D}, - {GL_IMAGE_2D image2D}, - {GL_IMAGE_3D image3D}, - {GL_IMAGE_2D_RECT image2DRect}, - {GL_IMAGE_CUBE imageCube}, - {GL_IMAGE_BUFFER imageBuffer}, - {GL_IMAGE_1D_ARRAY image1DArray}, - {GL_IMAGE_2D_ARRAY image2DArray}, - {GL_IMAGE_2D_MULTISAMPLE image2DMS}, - {GL_IMAGE_2D_MULTISAMPLE_ARRAY image2DMSArray}, - {GL_INT_IMAGE_1D iimage1D}, - {GL_INT_IMAGE_2D iimage2D}, - {GL_INT_IMAGE_3D iimage3D}, - {GL_INT_IMAGE_2D_RECT iimage2DRect}, - {GL_INT_IMAGE_CUBE iimageCube}, - {GL_INT_IMAGE_BUFFER iimageBuffer}, - {GL_INT_IMAGE_1D_ARRAY iimage1DArray}, - {GL_INT_IMAGE_2D_ARRAY iimage2DArray}, - {GL_INT_IMAGE_2D_MULTISAMPLE iimage2DMS}, - {GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY iimage2DMSArray}, - {GL_UNSIGNED_INT_IMAGE_1D uimage1D}, - {GL_UNSIGNED_INT_IMAGE_2D uimage2D}, - {GL_UNSIGNED_INT_IMAGE_3D uimage3D}, - {GL_UNSIGNED_INT_IMAGE_2D_RECT uimage2DRect}, - {GL_UNSIGNED_INT_IMAGE_CUBE uimageCube},+ [0] {_name="fInnerRadius" _location=0 _element={_semantic=15 '\xf' _dimension=0 '\0' _type=0 '\0' } } gpu::Shader::Slot - - {GL_UNSIGNED_INT_IMAGE_BUFFER uimageBuffer}, - {GL_UNSIGNED_INT_IMAGE_1D_ARRAY uimage1DArray}, - {GL_UNSIGNED_INT_IMAGE_2D_ARRAY uimage2DArray}, - {GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE uimage2DMS}, - {GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY uimage2DMSArray}, - {GL_UNSIGNED_INT_ATOMIC_COUNTER atomic_uint} - */ default: return ElementResource(Element(), Resource::BUFFER); } + // Non-covered types + //{GL_FLOAT_MAT2x3 mat2x3}, + //{GL_FLOAT_MAT2x4 mat2x4}, + //{GL_FLOAT_MAT3x2 mat3x2}, + //{GL_FLOAT_MAT3x4 mat3x4}, + //{GL_FLOAT_MAT4x2 mat4x2}, + //{GL_FLOAT_MAT4x3 mat4x3}, + //{GL_DOUBLE_MAT2 dmat2}, + //{GL_DOUBLE_MAT3 dmat3}, + //{GL_DOUBLE_MAT4 dmat4}, + //{GL_DOUBLE_MAT2x3 dmat2x3}, + //{GL_DOUBLE_MAT2x4 dmat2x4}, + //{GL_DOUBLE_MAT3x2 dmat3x2}, + //{GL_DOUBLE_MAT3x4 dmat3x4}, + //{GL_DOUBLE_MAT4x2 dmat4x2}, + //{GL_DOUBLE_MAT4x3 dmat4x3}, + //{GL_SAMPLER_1D_SHADOW sampler1DShadow}, + //{GL_SAMPLER_1D_ARRAY_SHADOW sampler1DArrayShadow}, + //{GL_SAMPLER_2D_RECT sampler2DRect}, + //{GL_SAMPLER_2D_RECT_SHADOW sampler2DRectShadow}, + //{GL_INT_SAMPLER_BUFFER isamplerBuffer}, + //{GL_INT_SAMPLER_2D_RECT isampler2DRect}, + //{GL_UNSIGNED_INT_SAMPLER_BUFFER usamplerBuffer}, + //{GL_UNSIGNED_INT_SAMPLER_2D_RECT usampler2DRect}, + //{GL_IMAGE_1D image1D}, + //{GL_IMAGE_2D image2D}, + //{GL_IMAGE_3D image3D}, + //{GL_IMAGE_2D_RECT image2DRect}, + //{GL_IMAGE_CUBE imageCube}, + //{GL_IMAGE_BUFFER imageBuffer}, + //{GL_IMAGE_1D_ARRAY image1DArray}, + //{GL_IMAGE_2D_ARRAY image2DArray}, + //{GL_IMAGE_2D_MULTISAMPLE image2DMS}, + //{GL_IMAGE_2D_MULTISAMPLE_ARRAY image2DMSArray}, + //{GL_INT_IMAGE_1D iimage1D}, + //{GL_INT_IMAGE_2D iimage2D}, + //{GL_INT_IMAGE_3D iimage3D}, + //{GL_INT_IMAGE_2D_RECT iimage2DRect}, + //{GL_INT_IMAGE_CUBE iimageCube}, + //{GL_INT_IMAGE_BUFFER iimageBuffer}, + //{GL_INT_IMAGE_1D_ARRAY iimage1DArray}, + //{GL_INT_IMAGE_2D_ARRAY iimage2DArray}, + //{GL_INT_IMAGE_2D_MULTISAMPLE iimage2DMS}, + //{GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY iimage2DMSArray}, + //{GL_UNSIGNED_INT_IMAGE_1D uimage1D}, + //{GL_UNSIGNED_INT_IMAGE_2D uimage2D}, + //{GL_UNSIGNED_INT_IMAGE_3D uimage3D}, + //{GL_UNSIGNED_INT_IMAGE_2D_RECT uimage2DRect}, + //{GL_UNSIGNED_INT_IMAGE_CUBE uimageCube}, + //{GL_UNSIGNED_INT_IMAGE_BUFFER uimageBuffer}, + //{GL_UNSIGNED_INT_IMAGE_1D_ARRAY uimage1DArray}, + //{GL_UNSIGNED_INT_IMAGE_2D_ARRAY uimage2DArray}, + //{GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE uimage2DMS}, + //{GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY uimage2DMSArray}, + //{GL_UNSIGNED_INT_ATOMIC_COUNTER atomic_uint} + + }; int GLBackend::makeUniformSlots(GLuint glprogram, const Shader::BindingSet& slotBindings, @@ -550,4 +604,3 @@ void GLBackend::makeProgramBindings(ShaderObject& shaderObject) { qCWarning(gpugllogging) << "GLShader::makeBindings - failed to link after assigning slotBindings?"; } } - diff --git a/libraries/gpu-gl/src/gpu/gl/GLBackendState.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackendState.cpp similarity index 97% rename from libraries/gpu-gl/src/gpu/gl/GLBackendState.cpp rename to libraries/gpu-gl-common/src/gpu/gl/GLBackendState.cpp index 24f90395d7..8363af9b00 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLBackendState.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackendState.cpp @@ -29,18 +29,19 @@ void GLBackend::resetPipelineState(State::Signature nextSignature) { } } + // Default line width accross the board + glLineWidth(1.0f); +#if !defined(USE_GLES) // force a few states regardless glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); // Point size is always on - // FIXME CORE //glHint(GL_POINT_SMOOTH_HINT, GL_NICEST); glEnable(GL_PROGRAM_POINT_SIZE_EXT); glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); - // Default line width accross the board - glLineWidth(1.0f); glEnable(GL_LINE_SMOOTH); +#endif } @@ -48,17 +49,19 @@ void GLBackend::syncPipelineStateCache() { State::Data state; // force a few states regardless - glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); - - // Point size is always on - // FIXME CORE - //glHint(GL_POINT_SMOOTH_HINT, GL_NICEST); - glEnable(GL_PROGRAM_POINT_SIZE_EXT); - glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); // Default line width accross the board glLineWidth(1.0f); + +#if !defined(USE_GLES) + glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); + + // Point size is always on + //glHint(GL_POINT_SMOOTH_HINT, GL_NICEST); + glEnable(GL_PROGRAM_POINT_SIZE_EXT); + glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); glEnable(GL_LINE_SMOOTH); +#endif getCurrentGLState(state); State::Signature signature = State::evalSignature(state); @@ -70,11 +73,13 @@ void GLBackend::syncPipelineStateCache() { void GLBackend::do_setStateFillMode(int32 mode) { if (_pipeline._stateCache.fillMode != mode) { +#if !defined(USE_GLES) static GLenum GL_FILL_MODES[] = { GL_POINT, GL_LINE, GL_FILL }; glPolygonMode(GL_FRONT_AND_BACK, GL_FILL_MODES[mode]); (void)CHECK_GL_ERROR(); _pipeline._stateCache.fillMode = State::FillMode(mode); +#endif } } @@ -106,14 +111,15 @@ void GLBackend::do_setStateFrontFaceClockwise(bool isClockwise) { void GLBackend::do_setStateDepthClampEnable(bool enable) { if (_pipeline._stateCache.depthClampEnable != enable) { +#if !defined(USE_GLES) if (enable) { glEnable(GL_DEPTH_CLAMP); } else { glDisable(GL_DEPTH_CLAMP); } (void)CHECK_GL_ERROR(); - _pipeline._stateCache.depthClampEnable = enable; +#endif } } @@ -132,6 +138,7 @@ void GLBackend::do_setStateScissorEnable(bool enable) { void GLBackend::do_setStateMultisampleEnable(bool enable) { if (_pipeline._stateCache.multisampleEnable != enable) { +#if !defined(USE_GLES) if (enable) { glEnable(GL_MULTISAMPLE); } else { @@ -140,11 +147,13 @@ void GLBackend::do_setStateMultisampleEnable(bool enable) { (void)CHECK_GL_ERROR(); _pipeline._stateCache.multisampleEnable = enable; +#endif } } void GLBackend::do_setStateAntialiasedLineEnable(bool enable) { if (_pipeline._stateCache.antialisedLineEnable != enable) { +#if !defined(USE_GLES) if (enable) { glEnable(GL_LINE_SMOOTH); } else { @@ -153,6 +162,7 @@ void GLBackend::do_setStateAntialiasedLineEnable(bool enable) { (void)CHECK_GL_ERROR(); _pipeline._stateCache.antialisedLineEnable = enable; +#endif } } @@ -160,13 +170,17 @@ void GLBackend::do_setStateDepthBias(Vec2 bias) { if ((bias.x != _pipeline._stateCache.depthBias) || (bias.y != _pipeline._stateCache.depthBiasSlopeScale)) { if ((bias.x != 0.0f) || (bias.y != 0.0f)) { glEnable(GL_POLYGON_OFFSET_FILL); +#if !defined(USE_GLES) glEnable(GL_POLYGON_OFFSET_LINE); glEnable(GL_POLYGON_OFFSET_POINT); +#endif glPolygonOffset(bias.x, bias.y); } else { glDisable(GL_POLYGON_OFFSET_FILL); +#if !defined(USE_GLES) glDisable(GL_POLYGON_OFFSET_LINE); glDisable(GL_POLYGON_OFFSET_POINT); +#endif } (void)CHECK_GL_ERROR(); diff --git a/libraries/gpu-gl/src/gpu/gl/GLBackendTexture.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackendTexture.cpp similarity index 100% rename from libraries/gpu-gl/src/gpu/gl/GLBackendTexture.cpp rename to libraries/gpu-gl-common/src/gpu/gl/GLBackendTexture.cpp diff --git a/libraries/gpu-gl/src/gpu/gl/GLBackendTransform.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackendTransform.cpp similarity index 100% rename from libraries/gpu-gl/src/gpu/gl/GLBackendTransform.cpp rename to libraries/gpu-gl-common/src/gpu/gl/GLBackendTransform.cpp diff --git a/libraries/gpu-gl/src/gpu/gl/GLBuffer.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBuffer.cpp similarity index 100% rename from libraries/gpu-gl/src/gpu/gl/GLBuffer.cpp rename to libraries/gpu-gl-common/src/gpu/gl/GLBuffer.cpp diff --git a/libraries/gpu-gl/src/gpu/gl/GLBuffer.h b/libraries/gpu-gl-common/src/gpu/gl/GLBuffer.h similarity index 100% rename from libraries/gpu-gl/src/gpu/gl/GLBuffer.h rename to libraries/gpu-gl-common/src/gpu/gl/GLBuffer.h diff --git a/libraries/gpu-gl/src/gpu/gl/GLFramebuffer.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLFramebuffer.cpp similarity index 96% rename from libraries/gpu-gl/src/gpu/gl/GLFramebuffer.cpp rename to libraries/gpu-gl-common/src/gpu/gl/GLFramebuffer.cpp index 2ac7e9d060..8d5fb6b2ef 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLFramebuffer.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLFramebuffer.cpp @@ -33,14 +33,18 @@ bool GLFramebuffer::checkStatus() const { case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: qCWarning(gpugllogging) << "GLFramebuffer::syncGPUObject : Framebuffer not valid, GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT."; break; + case GL_FRAMEBUFFER_UNSUPPORTED: + qCWarning(gpugllogging) << "GLFramebuffer::syncGPUObject : Framebuffer not valid, GL_FRAMEBUFFER_UNSUPPORTED."; + break; +#if !defined(USE_GLES) case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: qCWarning(gpugllogging) << "GLFramebuffer::syncGPUObject : Framebuffer not valid, GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER."; break; case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: qCWarning(gpugllogging) << "GLFramebuffer::syncGPUObject : Framebuffer not valid, GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER."; break; - case GL_FRAMEBUFFER_UNSUPPORTED: - qCWarning(gpugllogging) << "GLFramebuffer::syncGPUObject : Framebuffer not valid, GL_FRAMEBUFFER_UNSUPPORTED."; +#endif + default: break; } return false; diff --git a/libraries/gpu-gl/src/gpu/gl/GLFramebuffer.h b/libraries/gpu-gl-common/src/gpu/gl/GLFramebuffer.h similarity index 100% rename from libraries/gpu-gl/src/gpu/gl/GLFramebuffer.h rename to libraries/gpu-gl-common/src/gpu/gl/GLFramebuffer.h diff --git a/libraries/gpu-gl/src/gpu/gl/GLInputFormat.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLInputFormat.cpp similarity index 100% rename from libraries/gpu-gl/src/gpu/gl/GLInputFormat.cpp rename to libraries/gpu-gl-common/src/gpu/gl/GLInputFormat.cpp diff --git a/libraries/gpu-gl/src/gpu/gl/GLInputFormat.h b/libraries/gpu-gl-common/src/gpu/gl/GLInputFormat.h similarity index 100% rename from libraries/gpu-gl/src/gpu/gl/GLInputFormat.h rename to libraries/gpu-gl-common/src/gpu/gl/GLInputFormat.h diff --git a/libraries/gpu-gl/src/gpu/gl/GLPipeline.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLPipeline.cpp similarity index 100% rename from libraries/gpu-gl/src/gpu/gl/GLPipeline.cpp rename to libraries/gpu-gl-common/src/gpu/gl/GLPipeline.cpp diff --git a/libraries/gpu-gl/src/gpu/gl/GLPipeline.h b/libraries/gpu-gl-common/src/gpu/gl/GLPipeline.h similarity index 100% rename from libraries/gpu-gl/src/gpu/gl/GLPipeline.h rename to libraries/gpu-gl-common/src/gpu/gl/GLPipeline.h diff --git a/libraries/gpu-gl/src/gpu/gl/GLQuery.h b/libraries/gpu-gl-common/src/gpu/gl/GLQuery.h similarity index 100% rename from libraries/gpu-gl/src/gpu/gl/GLQuery.h rename to libraries/gpu-gl-common/src/gpu/gl/GLQuery.h diff --git a/libraries/gpu-gl/src/gpu/gl/GLShader.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLShader.cpp similarity index 100% rename from libraries/gpu-gl/src/gpu/gl/GLShader.cpp rename to libraries/gpu-gl-common/src/gpu/gl/GLShader.cpp diff --git a/libraries/gpu-gl/src/gpu/gl/GLShader.h b/libraries/gpu-gl-common/src/gpu/gl/GLShader.h similarity index 100% rename from libraries/gpu-gl/src/gpu/gl/GLShader.h rename to libraries/gpu-gl-common/src/gpu/gl/GLShader.h diff --git a/libraries/gpu-gl/src/gpu/gl/GLShared.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLShared.cpp similarity index 97% rename from libraries/gpu-gl/src/gpu/gl/GLShared.cpp rename to libraries/gpu-gl-common/src/gpu/gl/GLShared.cpp index dc1c8036b0..9ba85b8418 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLShared.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLShared.cpp @@ -24,6 +24,7 @@ namespace gpu { namespace gl { gpu::Size getFreeDedicatedMemory() { Size result { 0 }; +#if !defined(USE_GLES) static bool nvidiaMemorySupported { true }; static bool atiMemorySupported { true }; if (nvidiaMemorySupported) { @@ -45,6 +46,7 @@ gpu::Size getFreeDedicatedMemory() { atiMemorySupported = false; } } +#endif return result; } @@ -144,6 +146,9 @@ State::BlendArg blendArgFromGL(GLenum blendArg) { void getCurrentGLState(State::Data& state) { { +#if defined(USE_GLES) + state.fillMode = State::FILL_FACE; +#else GLint modes[2]; glGetIntegerv(GL_POLYGON_MODE, modes); if (modes[0] == GL_FILL) { @@ -155,6 +160,7 @@ void getCurrentGLState(State::Data& state) { state.fillMode = State::FILL_POINT; } } +#endif } { if (glIsEnabled(GL_CULL_FACE)) { @@ -169,10 +175,16 @@ void getCurrentGLState(State::Data& state) { GLint winding; glGetIntegerv(GL_FRONT_FACE, &winding); state.frontFaceClockwise = (winding == GL_CW); - state.depthClampEnable = glIsEnabled(GL_DEPTH_CLAMP); - state.scissorEnable = glIsEnabled(GL_SCISSOR_TEST); +#if defined(USE_GLES) + state.multisampleEnable = glIsEnabled(GL_MULTISAMPLE_EXT); + state.antialisedLineEnable = false; + state.depthClampEnable = false; +#else state.multisampleEnable = glIsEnabled(GL_MULTISAMPLE); state.antialisedLineEnable = glIsEnabled(GL_LINE_SMOOTH); + state.depthClampEnable = glIsEnabled(GL_DEPTH_CLAMP); +#endif + state.scissorEnable = glIsEnabled(GL_SCISSOR_TEST); } { if (glIsEnabled(GL_POLYGON_OFFSET_FILL)) { @@ -269,6 +281,7 @@ void getCurrentGLState(State::Data& state) { (void)CHECK_GL_ERROR(); } + void serverWait() { auto fence = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); assert(fence); diff --git a/libraries/gpu-gl/src/gpu/gl/GLShared.h b/libraries/gpu-gl-common/src/gpu/gl/GLShared.h similarity index 100% rename from libraries/gpu-gl/src/gpu/gl/GLShared.h rename to libraries/gpu-gl-common/src/gpu/gl/GLShared.h diff --git a/libraries/gpu-gl/src/gpu/gl/GLState.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLState.cpp similarity index 100% rename from libraries/gpu-gl/src/gpu/gl/GLState.cpp rename to libraries/gpu-gl-common/src/gpu/gl/GLState.cpp diff --git a/libraries/gpu-gl/src/gpu/gl/GLState.h b/libraries/gpu-gl-common/src/gpu/gl/GLState.h similarity index 100% rename from libraries/gpu-gl/src/gpu/gl/GLState.h rename to libraries/gpu-gl-common/src/gpu/gl/GLState.h diff --git a/libraries/gpu-gl/src/gpu/gl/GLTexelFormat.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLTexelFormat.cpp similarity index 90% rename from libraries/gpu-gl/src/gpu/gl/GLTexelFormat.cpp rename to libraries/gpu-gl-common/src/gpu/gl/GLTexelFormat.cpp index 1873034ac5..96f170ec1f 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLTexelFormat.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLTexelFormat.cpp @@ -11,15 +11,77 @@ using namespace gpu; using namespace gpu::gl; +#if defined(USE_GLES) +#define GL_R16 GL_R16_EXT +#define GL_R16_SNORM GL_R16_SNORM_EXT +#define GL_RGBA16 GL_RGBA16_EXT +#define GL_RGBA16_SNORM GL_RGBA16_SNORM_EXT +#define GL_DEPTH_COMPONENT32 GL_DEPTH_COMPONENT32_OES +#define GL_RGBA2 GL_RGBA8 +#define GL_COMPRESSED_RED_RGTC1 0x8DBB +#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC +#define GL_COMPRESSED_RG_RGTC2 0x8DBD +#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE +#define GL_COMPRESSED_RGBA_BPTC_UNORM 0x8E8C +#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM 0x8E8D +#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E +#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F +#define GL_SLUMINANCE8_EXT GL_SLUMINANCE8_NV +#endif + bool GLTexelFormat::isCompressed() const { switch (internalFormat) { case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: + + case GL_COMPRESSED_R11_EAC: + case GL_COMPRESSED_SIGNED_R11_EAC: + case GL_COMPRESSED_RG11_EAC: + case GL_COMPRESSED_SIGNED_RG11_EAC: + case GL_COMPRESSED_RGB8_ETC2: + case GL_COMPRESSED_SRGB8_ETC2: + case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: + case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: + case GL_COMPRESSED_RGBA8_ETC2_EAC: + case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: case GL_COMPRESSED_RED_RGTC1: case GL_COMPRESSED_RG_RGTC2: case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM: case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT: + +#if defined(USE_GLES) + case GL_COMPRESSED_RGBA_ASTC_4x4: + case GL_COMPRESSED_RGBA_ASTC_5x4: + case GL_COMPRESSED_RGBA_ASTC_5x5: + case GL_COMPRESSED_RGBA_ASTC_6x5: + case GL_COMPRESSED_RGBA_ASTC_6x6: + case GL_COMPRESSED_RGBA_ASTC_8x5: + case GL_COMPRESSED_RGBA_ASTC_8x6: + case GL_COMPRESSED_RGBA_ASTC_8x8: + case GL_COMPRESSED_RGBA_ASTC_10x5: + case GL_COMPRESSED_RGBA_ASTC_10x6: + case GL_COMPRESSED_RGBA_ASTC_10x8: + case GL_COMPRESSED_RGBA_ASTC_10x10: + case GL_COMPRESSED_RGBA_ASTC_12x10: + case GL_COMPRESSED_RGBA_ASTC_12x12: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12: +#endif + + return true; default: return false; @@ -346,7 +408,11 @@ GLTexelFormat GLTexelFormat::evalGLTexelFormat(const Element& dstFormat, const E switch (srcFormat.getSemantic()) { case gpu::BGRA: case gpu::SBGRA: +#if defined(USE_GLES) + texel.format = GL_RGBA; +#else texel.format = GL_BGRA; +#endif break; case gpu::RGB: case gpu::RGBA: @@ -383,8 +449,10 @@ GLTexelFormat GLTexelFormat::evalGLTexelFormat(const Element& dstFormat, const E switch (srcFormat.getSemantic()) { case gpu::BGRA: case gpu::SBGRA: +#if !defined(USE_GLES) texel.format = GL_BGRA; break; +#endif case gpu::RGB: case gpu::RGBA: case gpu::SRGB: @@ -434,6 +502,7 @@ GLTexelFormat GLTexelFormat::evalGLTexelFormat(const Element& dstFormat, const E texel.type = ELEMENT_TYPE_TO_GL[dstFormat.getType()]; switch (dstFormat.getSemantic()) { + case gpu::RED: case gpu::RGB: case gpu::RGBA: @@ -491,7 +560,11 @@ GLTexelFormat GLTexelFormat::evalGLTexelFormat(const Element& dstFormat, const E } case gpu::NUINT8: { if ((dstFormat.getSemantic() == gpu::SRGB || dstFormat.getSemantic() == gpu::SRGBA)) { +#if defined(USE_GLES) + texel.internalFormat = GL_SLUMINANCE8_NV; +#else texel.internalFormat = GL_SLUMINANCE8_EXT; +#endif } else { texel.internalFormat = GL_R8; } @@ -525,13 +598,21 @@ GLTexelFormat GLTexelFormat::evalGLTexelFormat(const Element& dstFormat, const E case gpu::DEPTH: texel.format = GL_DEPTH_COMPONENT; // It's depth component to load it +#if defined(USE_GLES) + texel.internalFormat = GL_DEPTH_COMPONENT32_OES; +#else texel.internalFormat = GL_DEPTH_COMPONENT32; +#endif switch (dstFormat.getType()) { case gpu::UINT32: case gpu::INT32: case gpu::NUINT32: case gpu::NINT32: { +#if defined(USE_GLES) + texel.internalFormat = GL_DEPTH_COMPONENT32_OES; +#else texel.internalFormat = GL_DEPTH_COMPONENT32; +#endif break; } case gpu::FLOAT: { @@ -699,8 +780,10 @@ GLTexelFormat GLTexelFormat::evalGLTexelFormat(const Element& dstFormat, const E switch (srcFormat.getSemantic()) { case gpu::BGRA: case gpu::SBGRA: +#if !defined(USE_GLES) texel.format = GL_BGRA; break; +#endif case gpu::RGB: case gpu::RGBA: case gpu::SRGB: diff --git a/libraries/gpu-gl/src/gpu/gl/GLTexelFormat.h b/libraries/gpu-gl-common/src/gpu/gl/GLTexelFormat.h similarity index 100% rename from libraries/gpu-gl/src/gpu/gl/GLTexelFormat.h rename to libraries/gpu-gl-common/src/gpu/gl/GLTexelFormat.h diff --git a/libraries/gpu-gl/src/gpu/gl/GLTexture.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLTexture.cpp similarity index 100% rename from libraries/gpu-gl/src/gpu/gl/GLTexture.cpp rename to libraries/gpu-gl-common/src/gpu/gl/GLTexture.cpp diff --git a/libraries/gpu-gl/src/gpu/gl/GLTexture.h b/libraries/gpu-gl-common/src/gpu/gl/GLTexture.h similarity index 100% rename from libraries/gpu-gl/src/gpu/gl/GLTexture.h rename to libraries/gpu-gl-common/src/gpu/gl/GLTexture.h diff --git a/libraries/gpu-gl/CMakeLists.txt b/libraries/gpu-gl/CMakeLists.txt index dc744e73f2..faddab8531 100644 --- a/libraries/gpu-gl/CMakeLists.txt +++ b/libraries/gpu-gl/CMakeLists.txt @@ -1,6 +1,6 @@ set(TARGET_NAME gpu-gl) setup_hifi_library(Concurrent) -link_hifi_libraries(shared gl gpu) +link_hifi_libraries(shared gl gpu gpu-gl-common) if (UNIX) target_link_libraries(${TARGET_NAME} pthread) endif(UNIX) diff --git a/libraries/gpu-gl/src/gpu/gl/GLBackend.cpp b/libraries/gpu-gl/src/gpu/gl/GLBackend.cpp deleted file mode 100644 index 08bd20be66..0000000000 --- a/libraries/gpu-gl/src/gpu/gl/GLBackend.cpp +++ /dev/null @@ -1,764 +0,0 @@ -// -// GLBackend.cpp -// libraries/gpu/src/gpu -// -// Created by Sam Gateau on 10/27/2014. -// Copyright 2014 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 "GLBackend.h" - -#include -#include -#include -#include -#include - -#include "../gl41/GL41Backend.h" -#include "../gl45/GL45Backend.h" - -#if defined(NSIGHT_FOUND) -#include "nvToolsExt.h" -#endif - -#include -#include -#include -#include - -#include "GLTexture.h" -#include "GLShader.h" - -using namespace gpu; -using namespace gpu::gl; - -static const QString DEBUG_FLAG("HIFI_DISABLE_OPENGL_45"); -static bool disableOpenGL45 = QProcessEnvironment::systemEnvironment().contains(DEBUG_FLAG); - -static GLBackend* INSTANCE{ nullptr }; - -BackendPointer GLBackend::createBackend() { - // FIXME provide a mechanism to override the backend for testing - // Where the gpuContext is initialized and where the TRUE Backend is created and assigned - auto version = QOpenGLContextWrapper::currentContextVersion(); - std::shared_ptr result; - if (!disableOpenGL45 && version >= 0x0405) { - qCDebug(gpugllogging) << "Using OpenGL 4.5 backend"; - result = std::make_shared(); - } else { - qCDebug(gpugllogging) << "Using OpenGL 4.1 backend"; - result = std::make_shared(); - } - result->initInput(); - result->initTransform(); - result->initTextureManagementStage(); - - INSTANCE = result.get(); - void* voidInstance = &(*result); - qApp->setProperty(hifi::properties::gl::BACKEND, QVariant::fromValue(voidInstance)); - return result; -} - -GLBackend& getBackend() { - if (!INSTANCE) { - INSTANCE = static_cast(qApp->property(hifi::properties::gl::BACKEND).value()); - } - return *INSTANCE; -} - -bool GLBackend::makeProgram(Shader& shader, const Shader::BindingSet& slotBindings, const Shader::CompilationHandler& handler) { - return GLShader::makeProgram(getBackend(), shader, slotBindings, handler); -} - -GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] = -{ - (&::gpu::gl::GLBackend::do_draw), - (&::gpu::gl::GLBackend::do_drawIndexed), - (&::gpu::gl::GLBackend::do_drawInstanced), - (&::gpu::gl::GLBackend::do_drawIndexedInstanced), - (&::gpu::gl::GLBackend::do_multiDrawIndirect), - (&::gpu::gl::GLBackend::do_multiDrawIndexedIndirect), - - (&::gpu::gl::GLBackend::do_setInputFormat), - (&::gpu::gl::GLBackend::do_setInputBuffer), - (&::gpu::gl::GLBackend::do_setIndexBuffer), - (&::gpu::gl::GLBackend::do_setIndirectBuffer), - - (&::gpu::gl::GLBackend::do_setModelTransform), - (&::gpu::gl::GLBackend::do_setViewTransform), - (&::gpu::gl::GLBackend::do_setProjectionTransform), - (&::gpu::gl::GLBackend::do_setViewportTransform), - (&::gpu::gl::GLBackend::do_setDepthRangeTransform), - - (&::gpu::gl::GLBackend::do_setPipeline), - (&::gpu::gl::GLBackend::do_setStateBlendFactor), - (&::gpu::gl::GLBackend::do_setStateScissorRect), - - (&::gpu::gl::GLBackend::do_setUniformBuffer), - (&::gpu::gl::GLBackend::do_setResourceBuffer), - (&::gpu::gl::GLBackend::do_setResourceTexture), - - (&::gpu::gl::GLBackend::do_setFramebuffer), - (&::gpu::gl::GLBackend::do_clearFramebuffer), - (&::gpu::gl::GLBackend::do_blit), - (&::gpu::gl::GLBackend::do_generateTextureMips), - - (&::gpu::gl::GLBackend::do_beginQuery), - (&::gpu::gl::GLBackend::do_endQuery), - (&::gpu::gl::GLBackend::do_getQuery), - - (&::gpu::gl::GLBackend::do_resetStages), - - (&::gpu::gl::GLBackend::do_disableContextViewCorrection), - (&::gpu::gl::GLBackend::do_restoreContextViewCorrection), - (&::gpu::gl::GLBackend::do_disableContextStereo), - (&::gpu::gl::GLBackend::do_restoreContextStereo), - - (&::gpu::gl::GLBackend::do_runLambda), - - (&::gpu::gl::GLBackend::do_startNamedCall), - (&::gpu::gl::GLBackend::do_stopNamedCall), - - (&::gpu::gl::GLBackend::do_glUniform1i), - (&::gpu::gl::GLBackend::do_glUniform1f), - (&::gpu::gl::GLBackend::do_glUniform2f), - (&::gpu::gl::GLBackend::do_glUniform3f), - (&::gpu::gl::GLBackend::do_glUniform4f), - (&::gpu::gl::GLBackend::do_glUniform3fv), - (&::gpu::gl::GLBackend::do_glUniform4fv), - (&::gpu::gl::GLBackend::do_glUniform4iv), - (&::gpu::gl::GLBackend::do_glUniformMatrix3fv), - (&::gpu::gl::GLBackend::do_glUniformMatrix4fv), - - (&::gpu::gl::GLBackend::do_glColor4f), - - (&::gpu::gl::GLBackend::do_pushProfileRange), - (&::gpu::gl::GLBackend::do_popProfileRange), -}; - -void GLBackend::init() { - static std::once_flag once; - std::call_once(once, [] { - QString vendor{ (const char*)glGetString(GL_VENDOR) }; - QString renderer{ (const char*)glGetString(GL_RENDERER) }; - qCDebug(gpugllogging) << "GL Version: " << QString((const char*) glGetString(GL_VERSION)); - qCDebug(gpugllogging) << "GL Shader Language Version: " << QString((const char*) glGetString(GL_SHADING_LANGUAGE_VERSION)); - qCDebug(gpugllogging) << "GL Vendor: " << vendor; - qCDebug(gpugllogging) << "GL Renderer: " << renderer; - GPUIdent* gpu = GPUIdent::getInstance(vendor, renderer); - // From here on, GPUIdent::getInstance()->getMumble() should efficiently give the same answers. - qCDebug(gpugllogging) << "GPU:"; - qCDebug(gpugllogging) << "\tcard:" << gpu->getName(); - qCDebug(gpugllogging) << "\tdriver:" << gpu->getDriver(); - qCDebug(gpugllogging) << "\tdedicated memory:" << gpu->getMemory() << "MB"; - qCDebug(gpugllogging, "V-Sync is %s\n", (::gl::getSwapInterval() > 0 ? "ON" : "OFF")); -#if THREADED_TEXTURE_BUFFERING - // This has to happen on the main thread in order to give the thread - // pool a reasonable parent object - GLVariableAllocationSupport::TransferJob::startBufferingThread(); -#endif - }); -} - -GLBackend::GLBackend() { - _pipeline._cameraCorrectionBuffer._buffer->flush(); - glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &_uboAlignment); -} - - -GLBackend::~GLBackend() { - killInput(); - killTransform(); -} - -void GLBackend::renderPassTransfer(const Batch& batch) { - const size_t numCommands = batch.getCommands().size(); - const Batch::Commands::value_type* command = batch.getCommands().data(); - const Batch::CommandOffsets::value_type* offset = batch.getCommandOffsets().data(); - - _inRenderTransferPass = true; - { // Sync all the buffers - PROFILE_RANGE(render_gpu_gl_detail, "syncGPUBuffer"); - - for (auto& cached : batch._buffers._items) { - if (cached._data) { - syncGPUObject(*cached._data); - } - } - } - - { // Sync all the transform states - PROFILE_RANGE(render_gpu_gl_detail, "syncCPUTransform"); - _transform._cameras.clear(); - _transform._cameraOffsets.clear(); - - for (_commandIndex = 0; _commandIndex < numCommands; ++_commandIndex) { - switch (*command) { - case Batch::COMMAND_draw: - case Batch::COMMAND_drawIndexed: - case Batch::COMMAND_drawInstanced: - case Batch::COMMAND_drawIndexedInstanced: - case Batch::COMMAND_multiDrawIndirect: - case Batch::COMMAND_multiDrawIndexedIndirect: - _transform.preUpdate(_commandIndex, _stereo); - break; - - case Batch::COMMAND_disableContextStereo: - _stereo._contextDisable = true; - break; - - case Batch::COMMAND_restoreContextStereo: - _stereo._contextDisable = false; - break; - - case Batch::COMMAND_setViewportTransform: - case Batch::COMMAND_setViewTransform: - case Batch::COMMAND_setProjectionTransform: { - CommandCall call = _commandCalls[(*command)]; - (this->*(call))(batch, *offset); - break; - } - - default: - break; - } - command++; - offset++; - } - } - - { // Sync the transform buffers - PROFILE_RANGE(render_gpu_gl_detail, "syncGPUTransform"); - transferTransformState(batch); - } - - _inRenderTransferPass = false; -} - -void GLBackend::renderPassDraw(const Batch& batch) { - _currentDraw = -1; - _transform._camerasItr = _transform._cameraOffsets.begin(); - const size_t numCommands = batch.getCommands().size(); - const Batch::Commands::value_type* command = batch.getCommands().data(); - const Batch::CommandOffsets::value_type* offset = batch.getCommandOffsets().data(); - for (_commandIndex = 0; _commandIndex < numCommands; ++_commandIndex) { - switch (*command) { - // Ignore these commands on this pass, taken care of in the transfer pass - // Note we allow COMMAND_setViewportTransform to occur in both passes - // as it both updates the transform object (and thus the uniforms in the - // UBO) as well as executes the actual viewport call - case Batch::COMMAND_setModelTransform: - case Batch::COMMAND_setViewTransform: - case Batch::COMMAND_setProjectionTransform: - break; - - case Batch::COMMAND_draw: - case Batch::COMMAND_drawIndexed: - case Batch::COMMAND_drawInstanced: - case Batch::COMMAND_drawIndexedInstanced: - case Batch::COMMAND_multiDrawIndirect: - case Batch::COMMAND_multiDrawIndexedIndirect: { - // updates for draw calls - ++_currentDraw; - updateInput(); - updateTransform(batch); - updatePipeline(); - - CommandCall call = _commandCalls[(*command)]; - (this->*(call))(batch, *offset); - break; - } - default: { - CommandCall call = _commandCalls[(*command)]; - (this->*(call))(batch, *offset); - break; - } - } - - command++; - offset++; - } -} - -void GLBackend::render(const Batch& batch) { - _transform._skybox = _stereo._skybox = batch.isSkyboxEnabled(); - // Allow the batch to override the rendering stereo settings - // for things like full framebuffer copy operations (deferred lighting passes) - bool savedStereo = _stereo._enable; - if (!batch.isStereoEnabled()) { - _stereo._enable = false; - } - - { - PROFILE_RANGE(render_gpu_gl_detail, "Transfer"); - renderPassTransfer(batch); - } - -#ifdef GPU_STEREO_DRAWCALL_INSTANCED - if (_stereo.isStereo()) { - glEnable(GL_CLIP_DISTANCE0); - } -#endif - { - PROFILE_RANGE(render_gpu_gl_detail, _stereo.isStereo() ? "Render Stereo" : "Render"); - renderPassDraw(batch); - } -#ifdef GPU_STEREO_DRAWCALL_INSTANCED - if (_stereo.isStereo()) { - glDisable(GL_CLIP_DISTANCE0); - } -#endif - // Restore the saved stereo state for the next batch - _stereo._enable = savedStereo; -} - - -void GLBackend::syncCache() { - PROFILE_RANGE(render_gpu_gl_detail, __FUNCTION__); - - syncTransformStateCache(); - syncPipelineStateCache(); - syncInputStateCache(); - syncOutputStateCache(); -} - -#ifdef GPU_STEREO_DRAWCALL_DOUBLED -void GLBackend::setupStereoSide(int side) { - ivec4 vp = _transform._viewport; - vp.z /= 2; - glViewport(vp.x + side * vp.z, vp.y, vp.z, vp.w); - - -#ifdef GPU_STEREO_CAMERA_BUFFER -#ifdef GPU_STEREO_DRAWCALL_DOUBLED - glVertexAttribI1i(14, side); -#endif -#else - _transform.bindCurrentCamera(side); -#endif - -} -#else -#endif - -void GLBackend::do_resetStages(const Batch& batch, size_t paramOffset) { - resetStages(); -} - -void GLBackend::do_disableContextViewCorrection(const Batch& batch, size_t paramOffset) { - _transform._viewCorrectionEnabled = false; -} - -void GLBackend::do_restoreContextViewCorrection(const Batch& batch, size_t paramOffset) { - _transform._viewCorrectionEnabled = true; -} - -void GLBackend::do_disableContextStereo(const Batch& batch, size_t paramOffset) { - -} - -void GLBackend::do_restoreContextStereo(const Batch& batch, size_t paramOffset) { - -} - -void GLBackend::do_runLambda(const Batch& batch, size_t paramOffset) { - std::function f = batch._lambdas.get(batch._params[paramOffset]._uint); - f(); -} - -void GLBackend::do_startNamedCall(const Batch& batch, size_t paramOffset) { - batch._currentNamedCall = batch._names.get(batch._params[paramOffset]._uint); - _currentDraw = -1; -} - -void GLBackend::do_stopNamedCall(const Batch& batch, size_t paramOffset) { - batch._currentNamedCall.clear(); -} - -void GLBackend::resetStages() { - resetInputStage(); - resetPipelineStage(); - resetTransformStage(); - resetUniformStage(); - resetResourceStage(); - resetOutputStage(); - resetQueryStage(); - - (void) CHECK_GL_ERROR(); -} - - -void GLBackend::do_pushProfileRange(const Batch& batch, size_t paramOffset) { - if (trace_render_gpu_gl_detail().isDebugEnabled()) { - auto name = batch._profileRanges.get(batch._params[paramOffset]._uint); - profileRanges.push_back(name); -#if defined(NSIGHT_FOUND) - nvtxRangePush(name.c_str()); -#endif - } -} - -void GLBackend::do_popProfileRange(const Batch& batch, size_t paramOffset) { - if (trace_render_gpu_gl_detail().isDebugEnabled()) { - profileRanges.pop_back(); -#if defined(NSIGHT_FOUND) - nvtxRangePop(); -#endif - } -} - -// TODO: As long as we have gl calls explicitely issued from interface -// code, we need to be able to record and batch these calls. THe long -// term strategy is to get rid of any GL calls in favor of the HIFI GPU API - -// As long as we don;t use several versions of shaders we can avoid this more complex code path -#ifdef GPU_STEREO_CAMERA_BUFFER -#define GET_UNIFORM_LOCATION(shaderUniformLoc) ((_pipeline._programShader) ? _pipeline._programShader->getUniformLocation(shaderUniformLoc, (GLShader::Version) isStereo()) : -1) -#else -#define GET_UNIFORM_LOCATION(shaderUniformLoc) shaderUniformLoc -#endif - -void GLBackend::do_glUniform1i(const Batch& batch, size_t paramOffset) { - if (_pipeline._program == 0) { - // We should call updatePipeline() to bind the program but we are not doing that - // because these uniform setters are deprecated and we don;t want to create side effect - return; - } - updatePipeline(); - - glUniform1i( - GET_UNIFORM_LOCATION(batch._params[paramOffset + 1]._int), - batch._params[paramOffset + 0]._int); - (void)CHECK_GL_ERROR(); -} - -void GLBackend::do_glUniform1f(const Batch& batch, size_t paramOffset) { - if (_pipeline._program == 0) { - // We should call updatePipeline() to bind the program but we are not doing that - // because these uniform setters are deprecated and we don;t want to create side effect - return; - } - updatePipeline(); - - glUniform1f( - GET_UNIFORM_LOCATION(batch._params[paramOffset + 1]._int), - batch._params[paramOffset + 0]._float); - (void)CHECK_GL_ERROR(); -} - -void GLBackend::do_glUniform2f(const Batch& batch, size_t paramOffset) { - if (_pipeline._program == 0) { - // We should call updatePipeline() to bind the program but we are not doing that - // because these uniform setters are deprecated and we don;t want to create side effect - return; - } - updatePipeline(); - glUniform2f( - GET_UNIFORM_LOCATION(batch._params[paramOffset + 2]._int), - batch._params[paramOffset + 1]._float, - batch._params[paramOffset + 0]._float); - (void)CHECK_GL_ERROR(); -} - -void GLBackend::do_glUniform3f(const Batch& batch, size_t paramOffset) { - if (_pipeline._program == 0) { - // We should call updatePipeline() to bind the program but we are not doing that - // because these uniform setters are deprecated and we don;t want to create side effect - return; - } - updatePipeline(); - glUniform3f( - GET_UNIFORM_LOCATION(batch._params[paramOffset + 3]._int), - batch._params[paramOffset + 2]._float, - batch._params[paramOffset + 1]._float, - batch._params[paramOffset + 0]._float); - (void)CHECK_GL_ERROR(); -} - -void GLBackend::do_glUniform4f(const Batch& batch, size_t paramOffset) { - if (_pipeline._program == 0) { - // We should call updatePipeline() to bind the program but we are not doing that - // because these uniform setters are deprecated and we don;t want to create side effect - return; - } - updatePipeline(); - glUniform4f( - GET_UNIFORM_LOCATION(batch._params[paramOffset + 4]._int), - batch._params[paramOffset + 3]._float, - batch._params[paramOffset + 2]._float, - batch._params[paramOffset + 1]._float, - batch._params[paramOffset + 0]._float); - (void)CHECK_GL_ERROR(); -} - -void GLBackend::do_glUniform3fv(const Batch& batch, size_t paramOffset) { - if (_pipeline._program == 0) { - // We should call updatePipeline() to bind the program but we are not doing that - // because these uniform setters are deprecated and we don;t want to create side effect - return; - } - updatePipeline(); - glUniform3fv( - GET_UNIFORM_LOCATION(batch._params[paramOffset + 2]._int), - batch._params[paramOffset + 1]._uint, - (const GLfloat*)batch.readData(batch._params[paramOffset + 0]._uint)); - - (void)CHECK_GL_ERROR(); -} - -void GLBackend::do_glUniform4fv(const Batch& batch, size_t paramOffset) { - if (_pipeline._program == 0) { - // We should call updatePipeline() to bind the program but we are not doing that - // because these uniform setters are deprecated and we don;t want to create side effect - return; - } - updatePipeline(); - - GLint location = GET_UNIFORM_LOCATION(batch._params[paramOffset + 2]._int); - GLsizei count = batch._params[paramOffset + 1]._uint; - const GLfloat* value = (const GLfloat*)batch.readData(batch._params[paramOffset + 0]._uint); - glUniform4fv(location, count, value); - - (void)CHECK_GL_ERROR(); -} - -void GLBackend::do_glUniform4iv(const Batch& batch, size_t paramOffset) { - if (_pipeline._program == 0) { - // We should call updatePipeline() to bind the program but we are not doing that - // because these uniform setters are deprecated and we don;t want to create side effect - return; - } - updatePipeline(); - glUniform4iv( - GET_UNIFORM_LOCATION(batch._params[paramOffset + 2]._int), - batch._params[paramOffset + 1]._uint, - (const GLint*)batch.readData(batch._params[paramOffset + 0]._uint)); - - (void)CHECK_GL_ERROR(); -} - -void GLBackend::do_glUniformMatrix3fv(const Batch& batch, size_t paramOffset) { - if (_pipeline._program == 0) { - // We should call updatePipeline() to bind the program but we are not doing that - // because these uniform setters are deprecated and we don;t want to create side effect - return; - } - updatePipeline(); - - glUniformMatrix3fv( - GET_UNIFORM_LOCATION(batch._params[paramOffset + 3]._int), - batch._params[paramOffset + 2]._uint, - batch._params[paramOffset + 1]._uint, - (const GLfloat*)batch.readData(batch._params[paramOffset + 0]._uint)); - (void)CHECK_GL_ERROR(); -} - -void GLBackend::do_glUniformMatrix4fv(const Batch& batch, size_t paramOffset) { - if (_pipeline._program == 0) { - // We should call updatePipeline() to bind the program but we are not doing that - // because these uniform setters are deprecated and we don;t want to create side effect - return; - } - updatePipeline(); - - glUniformMatrix4fv( - GET_UNIFORM_LOCATION(batch._params[paramOffset + 3]._int), - batch._params[paramOffset + 2]._uint, - batch._params[paramOffset + 1]._uint, - (const GLfloat*)batch.readData(batch._params[paramOffset + 0]._uint)); - (void)CHECK_GL_ERROR(); -} - -void GLBackend::do_glColor4f(const Batch& batch, size_t paramOffset) { - - glm::vec4 newColor( - batch._params[paramOffset + 3]._float, - batch._params[paramOffset + 2]._float, - batch._params[paramOffset + 1]._float, - batch._params[paramOffset + 0]._float); - - if (_input._colorAttribute != newColor) { - _input._colorAttribute = newColor; - glVertexAttrib4fv(gpu::Stream::COLOR, &_input._colorAttribute.r); - // Color has been changed and is not white. To prevent colors from bleeding - // between different objects, we need to set the _hadColorAttribute flag - // as if a previous render call had potential colors - _input._hadColorAttribute = (newColor != glm::vec4(1.0f, 1.0f, 1.0f, 1.0f)); - } - (void)CHECK_GL_ERROR(); -} - -void GLBackend::releaseBuffer(GLuint id, Size size) const { - Lock lock(_trashMutex); - _buffersTrash.push_back({ id, size }); -} - -void GLBackend::releaseExternalTexture(GLuint id, const Texture::ExternalRecycler& recycler) const { - Lock lock(_trashMutex); - _externalTexturesTrash.push_back({ id, recycler }); -} - -void GLBackend::releaseTexture(GLuint id, Size size) const { - Lock lock(_trashMutex); - _texturesTrash.push_back({ id, size }); -} - -void GLBackend::releaseFramebuffer(GLuint id) const { - Lock lock(_trashMutex); - _framebuffersTrash.push_back(id); -} - -void GLBackend::releaseShader(GLuint id) const { - Lock lock(_trashMutex); - _shadersTrash.push_back(id); -} - -void GLBackend::releaseProgram(GLuint id) const { - Lock lock(_trashMutex); - _programsTrash.push_back(id); -} - -void GLBackend::releaseQuery(GLuint id) const { - Lock lock(_trashMutex); - _queriesTrash.push_back(id); -} - -void GLBackend::queueLambda(const std::function lambda) const { - Lock lock(_trashMutex); - _lambdaQueue.push_back(lambda); -} - -void GLBackend::recycle() const { - PROFILE_RANGE(render_gpu_gl, __FUNCTION__) - { - std::list> lamdbasTrash; - { - Lock lock(_trashMutex); - std::swap(_lambdaQueue, lamdbasTrash); - } - for (auto lambda : lamdbasTrash) { - lambda(); - } - } - - { - std::vector ids; - std::list> buffersTrash; - { - Lock lock(_trashMutex); - std::swap(_buffersTrash, buffersTrash); - } - ids.reserve(buffersTrash.size()); - for (auto pair : buffersTrash) { - ids.push_back(pair.first); - } - if (!ids.empty()) { - glDeleteBuffers((GLsizei)ids.size(), ids.data()); - } - } - - { - std::vector ids; - std::list framebuffersTrash; - { - Lock lock(_trashMutex); - std::swap(_framebuffersTrash, framebuffersTrash); - } - ids.reserve(framebuffersTrash.size()); - for (auto id : framebuffersTrash) { - ids.push_back(id); - } - if (!ids.empty()) { - glDeleteFramebuffers((GLsizei)ids.size(), ids.data()); - } - } - - { - std::vector ids; - std::list> texturesTrash; - { - Lock lock(_trashMutex); - std::swap(_texturesTrash, texturesTrash); - } - ids.reserve(texturesTrash.size()); - for (auto pair : texturesTrash) { - ids.push_back(pair.first); - } - if (!ids.empty()) { - glDeleteTextures((GLsizei)ids.size(), ids.data()); - } - } - - { - std::list> externalTexturesTrash; - { - Lock lock(_trashMutex); - std::swap(_externalTexturesTrash, externalTexturesTrash); - } - if (!externalTexturesTrash.empty()) { - std::vector fences; - fences.resize(externalTexturesTrash.size()); - for (size_t i = 0; i < externalTexturesTrash.size(); ++i) { - fences[i] = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); - } - // External texture fences will be read in another thread/context, so we need a flush - glFlush(); - size_t index = 0; - for (auto pair : externalTexturesTrash) { - auto fence = fences[index++]; - pair.second(pair.first, fence); - } - } - } - - { - std::list programsTrash; - { - Lock lock(_trashMutex); - std::swap(_programsTrash, programsTrash); - } - for (auto id : programsTrash) { - glDeleteProgram(id); - } - } - - { - std::list shadersTrash; - { - Lock lock(_trashMutex); - std::swap(_shadersTrash, shadersTrash); - } - for (auto id : shadersTrash) { - glDeleteShader(id); - } - } - - { - std::vector ids; - std::list queriesTrash; - { - Lock lock(_trashMutex); - std::swap(_queriesTrash, queriesTrash); - } - ids.reserve(queriesTrash.size()); - for (auto id : queriesTrash) { - ids.push_back(id); - } - if (!ids.empty()) { - glDeleteQueries((GLsizei)ids.size(), ids.data()); - } - } - - GLVariableAllocationSupport::manageMemory(); - GLVariableAllocationSupport::_frameTexturesCreated = 0; - Texture::KtxStorage::releaseOpenKtxFiles(); -} - -void GLBackend::setCameraCorrection(const Mat4& correction) { - _transform._correction.correction = correction; - _transform._correction.correctionInverse = glm::inverse(correction); - _pipeline._cameraCorrectionBuffer._buffer->setSubData(0, _transform._correction); - _pipeline._cameraCorrectionBuffer._buffer->flush(); -} diff --git a/libraries/gpu-gl/src/gpu/gl/GLBackendInput.cpp b/libraries/gpu-gl/src/gpu/gl/GLBackendInput.cpp deleted file mode 100644 index cac214b01e..0000000000 --- a/libraries/gpu-gl/src/gpu/gl/GLBackendInput.cpp +++ /dev/null @@ -1,157 +0,0 @@ -// -// GLBackendInput.cpp -// libraries/gpu/src/gpu -// -// Created by Sam Gateau on 3/8/2015. -// Copyright 2014 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 "GLBackend.h" -#include "GLShared.h" -#include "GLInputFormat.h" - -using namespace gpu; -using namespace gpu::gl; - -void GLBackend::do_setInputFormat(const Batch& batch, size_t paramOffset) { - Stream::FormatPointer format = batch._streamFormats.get(batch._params[paramOffset]._uint); - if (format != _input._format) { - _input._format = format; - if (format) { - auto inputFormat = GLInputFormat::sync((*format)); - assert(inputFormat); - if (_input._formatKey != inputFormat->key) { - _input._formatKey = inputFormat->key; - _input._invalidFormat = true; - } - } else { - _input._formatKey.clear(); - _input._invalidFormat = true; - } - } -} - -void GLBackend::do_setInputBuffer(const Batch& batch, size_t paramOffset) { - Offset stride = batch._params[paramOffset + 0]._uint; - Offset offset = batch._params[paramOffset + 1]._uint; - BufferPointer buffer = batch._buffers.get(batch._params[paramOffset + 2]._uint); - uint32 channel = batch._params[paramOffset + 3]._uint; - - if (channel < getNumInputBuffers()) { - bool isModified = false; - if (_input._buffers[channel] != buffer) { - _input._buffers[channel] = buffer; - - GLuint vbo = 0; - if (buffer) { - vbo = getBufferID((*buffer)); - } - _input._bufferVBOs[channel] = vbo; - - isModified = true; - } - - if (_input._bufferOffsets[channel] != offset) { - _input._bufferOffsets[channel] = offset; - isModified = true; - } - - if (_input._bufferStrides[channel] != stride) { - _input._bufferStrides[channel] = stride; - isModified = true; - } - - if (isModified) { - _input._invalidBuffers.set(channel); - } - } -} - -void GLBackend::initInput() { - if(!_input._defaultVAO) { - glGenVertexArrays(1, &_input._defaultVAO); - } - glBindVertexArray(_input._defaultVAO); - (void) CHECK_GL_ERROR(); -} - -void GLBackend::killInput() { - glBindVertexArray(0); - if(_input._defaultVAO) { - glDeleteVertexArrays(1, &_input._defaultVAO); - } - (void) CHECK_GL_ERROR(); -} - -void GLBackend::syncInputStateCache() { - for (uint32_t i = 0; i < _input._attributeActivation.size(); i++) { - GLint active = 0; - glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &active); - _input._attributeActivation[i] = active; - } - //_input._defaultVAO - glBindVertexArray(_input._defaultVAO); -} - -void GLBackend::resetInputStage() { - // Reset index buffer - _input._indexBufferType = UINT32; - _input._indexBufferOffset = 0; - _input._indexBuffer.reset(); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - (void) CHECK_GL_ERROR(); - - // Reset vertex buffer and format - _input._format.reset(); - _input._formatKey.clear(); - _input._invalidFormat = false; - _input._attributeActivation.reset(); - - for (uint32_t i = 0; i < _input._buffers.size(); i++) { - _input._buffers[i].reset(); - _input._bufferOffsets[i] = 0; - _input._bufferStrides[i] = 0; - _input._bufferVBOs[i] = 0; - } - _input._invalidBuffers.reset(); - - // THe vertex array binding MUST be reset in the specific Backend versions as they use different techniques -} - -void GLBackend::do_setIndexBuffer(const Batch& batch, size_t paramOffset) { - _input._indexBufferType = (Type)batch._params[paramOffset + 2]._uint; - _input._indexBufferOffset = batch._params[paramOffset + 0]._uint; - - BufferPointer indexBuffer = batch._buffers.get(batch._params[paramOffset + 1]._uint); - if (indexBuffer != _input._indexBuffer) { - _input._indexBuffer = indexBuffer; - if (indexBuffer) { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, getBufferID(*indexBuffer)); - } else { - // FIXME do we really need this? Is there ever a draw call where we care that the element buffer is null? - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - } - } - (void) CHECK_GL_ERROR(); -} - -void GLBackend::do_setIndirectBuffer(const Batch& batch, size_t paramOffset) { - _input._indirectBufferOffset = batch._params[paramOffset + 1]._uint; - _input._indirectBufferStride = batch._params[paramOffset + 2]._uint; - - BufferPointer buffer = batch._buffers.get(batch._params[paramOffset]._uint); - if (buffer != _input._indirectBuffer) { - _input._indirectBuffer = buffer; - if (buffer) { - glBindBuffer(GL_DRAW_INDIRECT_BUFFER, getBufferID(*buffer)); - } else { - // FIXME do we really need this? Is there ever a draw call where we care that the element buffer is null? - glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0); - } - } - - (void)CHECK_GL_ERROR(); -} - diff --git a/libraries/gpu-gl/src/gpu/gl/GLDesktopBackend.cpp b/libraries/gpu-gl/src/gpu/gl/GLDesktopBackend.cpp new file mode 100644 index 0000000000..72a76f8f90 --- /dev/null +++ b/libraries/gpu-gl/src/gpu/gl/GLDesktopBackend.cpp @@ -0,0 +1,63 @@ +// +// GLBackend.cpp +// libraries/gpu/src/gpu +// +// Created by Sam Gateau on 10/27/2014. +// Copyright 2014 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 + +#include + +#include + +#include +#include +#include + +#include "../gl41/GL41Backend.h" +#include "../gl45/GL45Backend.h" + +using namespace gpu; +using namespace gpu::gl; + +static const QString DEBUG_FLAG("HIFI_DISABLE_OPENGL_45"); +static bool disableOpenGL45 = QProcessEnvironment::systemEnvironment().contains(DEBUG_FLAG); + +static GLBackend* INSTANCE{ nullptr }; + +BackendPointer GLBackend::createBackend() { + // FIXME provide a mechanism to override the backend for testing + // Where the gpuContext is initialized and where the TRUE Backend is created and assigned + auto version = QOpenGLContextWrapper::currentContextVersion(); + std::shared_ptr result; + if (!disableOpenGL45 && version >= 0x0405) { + qCDebug(gpugllogging) << "Using OpenGL 4.5 backend"; + result = std::make_shared(); + } else { + qCDebug(gpugllogging) << "Using OpenGL 4.1 backend"; + result = std::make_shared(); + } + result->initInput(); + result->initTransform(); + result->initTextureManagementStage(); + + INSTANCE = result.get(); + void* voidInstance = &(*result); + qApp->setProperty(hifi::properties::gl::BACKEND, QVariant::fromValue(voidInstance)); + return result; +} + +GLBackend& getBackend() { + if (!INSTANCE) { + INSTANCE = static_cast(qApp->property(hifi::properties::gl::BACKEND).value()); + } + return *INSTANCE; +} + +bool GLBackend::makeProgram(Shader& shader, const Shader::BindingSet& slotBindings, const Shader::CompilationHandler& handler) { + return GLShader::makeProgram(getBackend(), shader, slotBindings, handler); +} diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h b/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h index 42926fdb1c..3c59781f78 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h +++ b/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h @@ -13,8 +13,8 @@ #include -#include "../gl/GLBackend.h" -#include "../gl/GLTexture.h" +#include +#include #define GPU_CORE_41 410 #define GPU_CORE_43 430 diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendBuffer.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendBuffer.cpp index eb66cc4544..62ade673b4 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendBuffer.cpp +++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendBuffer.cpp @@ -6,7 +6,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #include "GL41Backend.h" -#include "../gl/GLBuffer.h" +#include namespace gpu { namespace gl41 { diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendOutput.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendOutput.cpp index 195b155bf3..a5ef2d92e1 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendOutput.cpp +++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendOutput.cpp @@ -12,8 +12,8 @@ #include -#include "../gl/GLFramebuffer.h" -#include "../gl/GLTexture.h" +#include +#include namespace gpu { namespace gl41 { diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendQuery.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendQuery.cpp index f712550973..0f75c29f38 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendQuery.cpp +++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendQuery.cpp @@ -10,7 +10,7 @@ // #include "GL41Backend.h" -#include "../gl/GLQuery.h" +#include using namespace gpu; using namespace gpu::gl; diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendShader.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendShader.cpp index ff9ddaae63..35bfafdc50 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendShader.cpp +++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendShader.cpp @@ -6,7 +6,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #include "GL41Backend.h" -#include "../gl/GLShader.h" +#include using namespace gpu; using namespace gpu::gl; diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp index 2834a8463c..61c3da391b 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp @@ -13,7 +13,7 @@ #include #include -#include "../gl/GLTexelFormat.h" +#include using namespace gpu; using namespace gpu::gl; diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h b/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h index 1a4b63d35f..b90c0b1857 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h +++ b/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h @@ -12,8 +12,9 @@ #ifndef hifi_gpu_45_GL45Backend_h #define hifi_gpu_45_GL45Backend_h -#include "../gl/GLBackend.h" -#include "../gl/GLTexture.h" +#include +#include + #include #define INCREMENTAL_TRANSFER 0 diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendBuffer.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendBuffer.cpp index b4a6410612..2afbea3876 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendBuffer.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendBuffer.cpp @@ -6,7 +6,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #include "GL45Backend.h" -#include "../gl/GLBuffer.h" +#include namespace gpu { namespace gl45 { using namespace gpu::gl; diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp index 4a43fc988c..34bf6774f7 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp @@ -9,7 +9,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #include "GL45Backend.h" -#include "../gl/GLShared.h" +#include using namespace gpu; using namespace gpu::gl45; diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendOutput.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendOutput.cpp index 9648af9b21..ca53d6c624 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendOutput.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendOutput.cpp @@ -9,8 +9,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #include "GL45Backend.h" -#include "../gl/GLFramebuffer.h" -#include "../gl/GLTexture.h" +#include +#include #include diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendQuery.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendQuery.cpp index df81d7914e..62f87ed913 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendQuery.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendQuery.cpp @@ -10,7 +10,7 @@ // #include "GL45Backend.h" -#include "../gl/GLQuery.h" +#include namespace gpu { namespace gl45 { diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendShader.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendShader.cpp index c2490524ae..c17a4a1524 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendShader.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendShader.cpp @@ -6,7 +6,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #include "GL45Backend.h" -#include "../gl/GLShader.h" +#include //#include using namespace gpu; diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp index 1d415c7ca3..5e64e1845e 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp @@ -20,7 +20,7 @@ #include #include -#include "../gl/GLTexelFormat.h" +#include using namespace gpu; using namespace gpu::gl; diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendVariableTexture.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendVariableTexture.cpp index 0f1de0f868..d2d7b2bf55 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendVariableTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendVariableTexture.cpp @@ -21,7 +21,7 @@ #include #include -#include "../gl/GLTexelFormat.h" +#include using namespace gpu; using namespace gpu::gl; diff --git a/libraries/gpu-gles/CMakeLists.txt b/libraries/gpu-gles/CMakeLists.txt index ea69919f6d..82bf670781 100644 --- a/libraries/gpu-gles/CMakeLists.txt +++ b/libraries/gpu-gles/CMakeLists.txt @@ -1,5 +1,5 @@ set(TARGET_NAME gpu-gles) setup_hifi_library(Gui Concurrent) -link_hifi_libraries(shared gl gpu) +link_hifi_libraries(shared gl gpu gpu-gl-common) GroupSources("src") target_opengl() diff --git a/libraries/gpu-gles/src/gpu/gl/GLBackend.h b/libraries/gpu-gles/src/gpu/gl/GLBackend.h deleted file mode 100644 index 3681fc0492..0000000000 --- a/libraries/gpu-gles/src/gpu/gl/GLBackend.h +++ /dev/null @@ -1,474 +0,0 @@ -// -// Created by Cristian Duarte & Gabriel Calero on 09/21/2016 -// Copyright 2016 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_gles_Backend_h -#define hifi_gpu_gles_Backend_h - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include -#include - -#include "GLShared.h" - - -// Different versions for the stereo drawcall -// Current preferred is "instanced" which draw the shape twice but instanced and rely on clipping plane to draw left/right side only -#define GPU_STEREO_TECHNIQUE_DOUBLED_SIMPLE -//#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 -#endif - -#ifdef GPU_STEREO_TECHNIQUE_DOUBLED_SMARTER -#define GPU_STEREO_DRAWCALL_DOUBLED -#define GPU_STEREO_CAMERA_BUFFER -#endif - -#ifdef GPU_STEREO_TECHNIQUE_INSTANCED -#define GPU_STEREO_DRAWCALL_INSTANCED -#define GPU_STEREO_CAMERA_BUFFER -#endif - -namespace gpu { namespace gl { - -class GLBackend : public Backend, public std::enable_shared_from_this { - // Context Backend static interface required - friend class gpu::Context; - static void init(); - static BackendPointer createBackend(); - -protected: - explicit GLBackend(bool syncCache); - GLBackend(); -public: - static bool makeProgram(Shader& shader, const Shader::BindingSet& slotBindings = Shader::BindingSet(), const Shader::CompilationHandler& handler = nullptr); - - virtual ~GLBackend(); - - void setCameraCorrection(const Mat4& correction); - void render(const Batch& batch) final override; - - // This call synchronize the Full Backend cache with the current GLState - // THis is only intended to be used when mixing raw gl calls with the gpu api usage in order to sync - // the gpu::Backend state with the true gl state which has probably been messed up by these ugly naked gl calls - // Let's try to avoid to do that as much as possible! - void syncCache() final override; - - // This is the ugly "download the pixels to sysmem for taking a snapshot" - // Just avoid using it, it's ugly and will break performances - virtual void downloadFramebuffer(const FramebufferPointer& srcFramebuffer, - const Vec4i& region, QImage& destImage) final override; - - - // this is the maximum numeber of available input buffers - size_t getNumInputBuffers() const { return _input._invalidBuffers.size(); } - - // this is the maximum per shader stage on the low end apple - // TODO make it platform dependant at init time - static const int MAX_NUM_UNIFORM_BUFFERS = 12; - size_t getMaxNumUniformBuffers() const { return MAX_NUM_UNIFORM_BUFFERS; } - - // this is the maximum per shader stage on the low end apple - // TODO make it platform dependant at init time - static const int MAX_NUM_RESOURCE_BUFFERS = 16; - size_t getMaxNumResourceBuffers() const { return MAX_NUM_RESOURCE_BUFFERS; } - static const int MAX_NUM_RESOURCE_TEXTURES = 16; - size_t getMaxNumResourceTextures() const { return MAX_NUM_RESOURCE_TEXTURES; } - - // Draw Stage - virtual void do_draw(const Batch& batch, size_t paramOffset) = 0; - 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; - virtual void do_multiDrawIndirect(const Batch& batch, size_t paramOffset) = 0; - virtual void do_multiDrawIndexedIndirect(const Batch& batch, size_t paramOffset) = 0; - - // Input Stage - virtual void do_setInputFormat(const Batch& batch, size_t paramOffset) final; - 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; - - // Transform Stage - virtual void do_setModelTransform(const Batch& batch, size_t paramOffset) final; - virtual void do_setViewTransform(const Batch& batch, size_t paramOffset) final; - virtual void do_setProjectionTransform(const Batch& batch, size_t paramOffset) final; - virtual void do_setViewportTransform(const Batch& batch, size_t paramOffset) final; - virtual void do_setDepthRangeTransform(const Batch& batch, size_t paramOffset) final; - - // Uniform Stage - virtual void do_setUniformBuffer(const Batch& batch, size_t paramOffset) final; - - // Resource Stage - virtual void do_setResourceBuffer(const Batch& batch, size_t paramOffset) final; - virtual void do_setResourceTexture(const Batch& batch, size_t paramOffset) final; - - // Pipeline Stage - virtual void do_setPipeline(const Batch& batch, size_t paramOffset) final; - - // Output stage - virtual void do_setFramebuffer(const Batch& batch, size_t paramOffset) final; - virtual void do_clearFramebuffer(const Batch& batch, size_t paramOffset) final; - virtual void do_blit(const Batch& batch, size_t paramOffset) = 0; - - // Query section - virtual void do_beginQuery(const Batch& batch, size_t paramOffset) final; - virtual void do_endQuery(const Batch& batch, size_t paramOffset) final; - virtual void do_getQuery(const Batch& batch, size_t paramOffset) final; - - // Reset stages - virtual void do_resetStages(const Batch& batch, size_t paramOffset) final; - - - virtual void do_disableContextViewCorrection(const Batch& batch, size_t paramOffset) final; - virtual void do_restoreContextViewCorrection(const Batch& batch, size_t paramOffset) final; - - virtual void do_disableContextStereo(const Batch& batch, size_t paramOffset) final; - virtual void do_restoreContextStereo(const Batch& batch, size_t paramOffset) final; - - virtual void do_runLambda(const Batch& batch, size_t paramOffset) final; - - virtual void do_startNamedCall(const Batch& batch, size_t paramOffset) final; - virtual void do_stopNamedCall(const Batch& batch, size_t paramOffset) final; - - static const int MAX_NUM_ATTRIBUTES = Stream::NUM_INPUT_SLOTS; - // The drawcall Info attribute channel is reserved and is the upper bound for the number of availables Input buffers - static const int MAX_NUM_INPUT_BUFFERS = Stream::DRAW_CALL_INFO; - - virtual void do_pushProfileRange(const Batch& batch, size_t paramOffset) final; - virtual void do_popProfileRange(const Batch& batch, size_t paramOffset) final; - - // TODO: As long as we have gl calls explicitely issued from interface - // code, we need to be able to record and batch these calls. THe long - // term strategy is to get rid of any GL calls in favor of the HIFI GPU API - virtual void do_glUniform1i(const Batch& batch, size_t paramOffset) final; - virtual void do_glUniform1f(const Batch& batch, size_t paramOffset) final; - virtual void do_glUniform2f(const Batch& batch, size_t paramOffset) final; - virtual void do_glUniform3f(const Batch& batch, size_t paramOffset) final; - virtual void do_glUniform4f(const Batch& batch, size_t paramOffset) final; - virtual void do_glUniform3fv(const Batch& batch, size_t paramOffset) final; - virtual void do_glUniform4fv(const Batch& batch, size_t paramOffset) final; - virtual void do_glUniform4iv(const Batch& batch, size_t paramOffset) final; - virtual void do_glUniformMatrix3fv(const Batch& batch, size_t paramOffset) final; - virtual void do_glUniformMatrix4fv(const Batch& batch, size_t paramOffset) final; - - virtual void do_glColor4f(const Batch& batch, size_t paramOffset) final; - - // The State setters called by the GLState::Commands when a new state is assigned - virtual void do_setStateFillMode(int32 mode) final; - virtual void do_setStateCullMode(int32 mode) final; - virtual void do_setStateFrontFaceClockwise(bool isClockwise) final; - virtual void do_setStateDepthClampEnable(bool enable) final; - virtual void do_setStateScissorEnable(bool enable) final; - virtual void do_setStateMultisampleEnable(bool enable) final; - virtual void do_setStateAntialiasedLineEnable(bool enable) final; - virtual void do_setStateDepthBias(Vec2 bias) final; - virtual void do_setStateDepthTest(State::DepthTest test) final; - virtual void do_setStateStencil(State::StencilActivation activation, State::StencilTest frontTest, State::StencilTest backTest) final; - virtual void do_setStateAlphaToCoverageEnable(bool enable) final; - virtual void do_setStateSampleMask(uint32 mask) final; - virtual void do_setStateBlend(State::BlendFunction blendFunction) final; - virtual void do_setStateColorWriteMask(uint32 mask) final; - virtual void do_setStateBlendFactor(const Batch& batch, size_t paramOffset) final; - virtual void do_setStateScissorRect(const Batch& batch, size_t paramOffset) final; - - virtual GLuint getFramebufferID(const FramebufferPointer& framebuffer) = 0; - virtual GLuint getTextureID(const TexturePointer& texture) final; - virtual GLuint getBufferID(const Buffer& buffer) = 0; - virtual GLuint getQueryID(const QueryPointer& query) = 0; - - virtual GLFramebuffer* syncGPUObject(const Framebuffer& framebuffer) = 0; - virtual GLBuffer* syncGPUObject(const Buffer& buffer) = 0; - virtual GLTexture* syncGPUObject(const TexturePointer& texture); - virtual GLQuery* syncGPUObject(const Query& query) = 0; - //virtual bool isTextureReady(const TexturePointer& texture); - - virtual void releaseBuffer(GLuint id, Size size) const; - virtual void releaseExternalTexture(GLuint id, const Texture::ExternalRecycler& recycler) const; - virtual void releaseTexture(GLuint id, Size size) const; - virtual void releaseFramebuffer(GLuint id) const; - virtual void releaseShader(GLuint id) const; - virtual void releaseProgram(GLuint id) const; - virtual void releaseQuery(GLuint id) const; - virtual void queueLambda(const std::function lambda) const; - - bool isTextureManagementSparseEnabled() const override { return (_textureManagement._sparseCapable && Texture::getEnableSparseTextures()); } - -protected: - - void recycle() const override; - - static const size_t INVALID_OFFSET = (size_t)-1; - bool _inRenderTransferPass { false }; - int32_t _uboAlignment { 0 }; - int _currentDraw { -1 }; - - std::list profileRanges; - mutable Mutex _trashMutex; - mutable std::list> _buffersTrash; - mutable std::list> _texturesTrash; - mutable std::list> _externalTexturesTrash; - mutable std::list _framebuffersTrash; - mutable std::list _shadersTrash; - mutable std::list _programsTrash; - mutable std::list _queriesTrash; - mutable std::list> _lambdaQueue; - - void renderPassTransfer(const Batch& batch); - void renderPassDraw(const Batch& batch); - -#ifdef GPU_STEREO_DRAWCALL_DOUBLED - void setupStereoSide(int side); -#endif - - virtual void initInput() final; - virtual void killInput() final; - virtual void syncInputStateCache() final; - virtual void resetInputStage(); - virtual void updateInput() = 0; - - struct InputStageState { - bool _invalidFormat { true }; - bool _hadColorAttribute{ true }; - Stream::FormatPointer _format; - std::string _formatKey; - - typedef std::bitset ActivationCache; - ActivationCache _attributeActivation { 0 }; - - typedef std::bitset BuffersState; - - BuffersState _invalidBuffers{ 0 }; - BuffersState _attribBindingBuffers{ 0 }; - - Buffers _buffers; - Offsets _bufferOffsets; - Offsets _bufferStrides; - std::vector _bufferVBOs; - - glm::vec4 _colorAttribute{ 0.0f }; - - BufferPointer _indexBuffer; - Offset _indexBufferOffset { 0 }; - Type _indexBufferType { UINT32 }; - - BufferPointer _indirectBuffer; - Offset _indirectBufferOffset{ 0 }; - Offset _indirectBufferStride{ 0 }; - - GLuint _defaultVAO { 0 }; - - InputStageState() : - _invalidFormat(true), - _format(0), - _formatKey(), - _attributeActivation(0), - _buffers(_invalidBuffers.size(), BufferPointer(0)), - _bufferOffsets(_invalidBuffers.size(), 0), - _bufferStrides(_invalidBuffers.size(), 0), - _bufferVBOs(_invalidBuffers.size(), 0) {} - } _input; - - virtual void initTransform() = 0; - void killTransform(); - // Synchronize the state cache of this Backend with the actual real state of the GL Context - void syncTransformStateCache(); - virtual void updateTransform(const Batch& batch) = 0; - virtual void resetTransformStage(); - - // Allows for correction of the camera pose to account for changes - // between the time when a was recorded and the time(s) when it is - // executed - struct CameraCorrection { - Mat4 correction; - Mat4 correctionInverse; - }; - - struct TransformStageState { -#ifdef GPU_STEREO_CAMERA_BUFFER - struct Cameras { - TransformCamera _cams[2]; - - Cameras() {}; - Cameras(const TransformCamera& cam) { memcpy(_cams, &cam, sizeof(TransformCamera)); }; - Cameras(const TransformCamera& camL, const TransformCamera& camR) { memcpy(_cams, &camL, sizeof(TransformCamera)); memcpy(_cams + 1, &camR, sizeof(TransformCamera)); }; - }; - - using CameraBufferElement = Cameras; -#else - using CameraBufferElement = TransformCamera; -#endif - using TransformCameras = std::vector; - - TransformCamera _camera; - TransformCameras _cameras; - - mutable std::map _drawCallInfoOffsets; - - GLuint _objectBuffer { 0 }; - GLuint _cameraBuffer { 0 }; - GLuint _drawCallInfoBuffer { 0 }; - GLuint _objectBufferTexture { 0 }; - size_t _cameraUboSize { 0 }; - bool _viewIsCamera{ false }; - bool _skybox { false }; - Transform _view; - CameraCorrection _correction; - bool _viewCorrectionEnabled{ true }; - - - Mat4 _projection; - Vec4i _viewport { 0, 0, 1, 1 }; - Vec2 _depthRange { 0.0f, 1.0f }; - bool _invalidView { false }; - bool _invalidProj { false }; - bool _invalidViewport { false }; - - bool _enabledDrawcallInfoBuffer{ false }; - - using Pair = std::pair; - using List = std::list; - List _cameraOffsets; - mutable List::const_iterator _camerasItr; - mutable size_t _currentCameraOffset{ INVALID_OFFSET }; - - void preUpdate(size_t commandIndex, const StereoState& stereo); - void update(size_t commandIndex, const StereoState& stereo) const; - void bindCurrentCamera(int stereoSide) const; - } _transform; - - virtual void transferTransformState(const Batch& batch) const = 0; - - struct UniformStageState { - std::array _buffers; - //Buffers _buffers { }; - } _uniform; - - void releaseUniformBuffer(uint32_t slot); - void resetUniformStage(); - - // update resource cache and do the gl bind/unbind call with the current gpu::Buffer cached at slot s - // This is using different gl object depending on the gl version - virtual bool bindResourceBuffer(uint32_t slot, BufferPointer& buffer) = 0; - virtual void releaseResourceBuffer(uint32_t slot) = 0; - - // update resource cache and do the gl unbind call with the current gpu::Texture cached at slot s - void releaseResourceTexture(uint32_t slot); - - void resetResourceStage(); - - struct ResourceStageState { - std::array _buffers; - std::array _textures; - //Textures _textures { { MAX_NUM_RESOURCE_TEXTURES } }; - int findEmptyTextureSlot() const; - } _resource; - - size_t _commandIndex{ 0 }; - - // Standard update pipeline check that the current Program and current State or good to go for a - void updatePipeline(); - // Force to reset all the state fields indicated by the 'toBeReset" signature - void resetPipelineState(State::Signature toBeReset); - // Synchronize the state cache of this Backend with the actual real state of the GL Context - void syncPipelineStateCache(); - void resetPipelineStage(); - - struct PipelineStageState { - PipelinePointer _pipeline; - - GLuint _program { 0 }; - GLint _cameraCorrectionLocation { -1 }; - GLShader* _programShader { nullptr }; - bool _invalidProgram { false }; - - BufferView _cameraCorrectionBuffer { gpu::BufferView(std::make_shared(sizeof(CameraCorrection), nullptr )) }; - BufferView _cameraCorrectionBufferIdentity { gpu::BufferView(std::make_shared(sizeof(CameraCorrection), nullptr )) }; - - State::Data _stateCache{ State::DEFAULT }; - State::Signature _stateSignatureCache { 0 }; - - GLState* _state { nullptr }; - bool _invalidState { false }; - - PipelineStageState() { - _cameraCorrectionBuffer.edit() = CameraCorrection(); - _cameraCorrectionBufferIdentity.edit() = CameraCorrection(); - _cameraCorrectionBufferIdentity._buffer->flush(); - } - } _pipeline; - - // Backend dependant compilation of the shader - virtual GLShader* compileBackendProgram(const Shader& program, const Shader::CompilationHandler& handler); - virtual GLShader* compileBackendShader(const Shader& shader, const Shader::CompilationHandler& handler); - virtual std::string getBackendShaderHeader() const; - virtual void makeProgramBindings(ShaderObject& shaderObject); - class ElementResource { - public: - gpu::Element _element; - uint16 _resource; - ElementResource(Element&& elem, uint16 resource) : _element(elem), _resource(resource) {} - }; - ElementResource getFormatFromGLUniform(GLenum gltype); - static const GLint UNUSED_SLOT {-1}; - static bool isUnusedSlot(GLint binding) { return (binding == UNUSED_SLOT); } - virtual int makeUniformSlots(GLuint glprogram, const Shader::BindingSet& slotBindings, - Shader::SlotSet& uniforms, Shader::SlotSet& textures, Shader::SlotSet& samplers); - virtual int makeUniformBlockSlots(GLuint glprogram, const Shader::BindingSet& slotBindings, Shader::SlotSet& buffers); - virtual int makeResourceBufferSlots(GLuint glprogram, const Shader::BindingSet& slotBindings, Shader::SlotSet& resourceBuffers) = 0; - virtual int makeInputSlots(GLuint glprogram, const Shader::BindingSet& slotBindings, Shader::SlotSet& inputs); - virtual int makeOutputSlots(GLuint glprogram, const Shader::BindingSet& slotBindings, Shader::SlotSet& outputs); - - - // Synchronize the state cache of this Backend with the actual real state of the GL Context - void syncOutputStateCache(); - void resetOutputStage(); - - struct OutputStageState { - FramebufferPointer _framebuffer { nullptr }; - GLuint _drawFBO { 0 }; - } _output; - - void resetQueryStage(); - struct QueryStageState { - uint32_t _rangeQueryDepth { 0 }; - } _queryStage; - - void resetStages(); - - struct TextureManagementStageState { - bool _sparseCapable { false }; - } _textureManagement; - virtual void initTextureManagementStage() {} - - typedef void (GLBackend::*CommandCall)(const Batch&, size_t); - static CommandCall _commandCalls[Batch::NUM_COMMANDS]; - friend class GLState; - friend class GLTexture; - friend class GLShader; -}; - -} } - -#endif diff --git a/libraries/gpu-gles/src/gpu/gl/GLBackendOutput.cpp b/libraries/gpu-gles/src/gpu/gl/GLBackendOutput.cpp deleted file mode 100644 index 45c0de8ed7..0000000000 --- a/libraries/gpu-gles/src/gpu/gl/GLBackendOutput.cpp +++ /dev/null @@ -1,175 +0,0 @@ -// -// GLBackendTexture.cpp -// libraries/gpu/src/gpu -// -// Created by Sam Gateau on 1/19/2015. -// Copyright 2014 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 "GLBackend.h" -#include "GLShared.h" -#include "GLFramebuffer.h" - -#include - -using namespace gpu; -using namespace gpu::gl; - -void GLBackend::syncOutputStateCache() { - GLint currentFBO; - glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, ¤tFBO); - - _output._drawFBO = currentFBO; - _output._framebuffer.reset(); -} - -void GLBackend::resetOutputStage() { - if (_output._framebuffer) { - _output._framebuffer.reset(); - _output._drawFBO = 0; - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); - } - - glEnable(GL_FRAMEBUFFER_SRGB_EXT); -} - -void GLBackend::do_setFramebuffer(const Batch& batch, size_t paramOffset) { - auto framebuffer = batch._framebuffers.get(batch._params[paramOffset]._uint); - if (_output._framebuffer != framebuffer) { - auto newFBO = getFramebufferID(framebuffer); - if (_output._drawFBO != newFBO) { - _output._drawFBO = newFBO; - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, newFBO); - } - _output._framebuffer = framebuffer; - } -} - -void GLBackend::do_clearFramebuffer(const Batch& batch, size_t paramOffset) { - if (_stereo.isStereo() && !_pipeline._stateCache.scissorEnable) { - qWarning("Clear without scissor in stereo mode"); - } - - uint32 masks = batch._params[paramOffset + 7]._uint; - Vec4 color; - color.x = batch._params[paramOffset + 6]._float; - color.y = batch._params[paramOffset + 5]._float; - color.z = batch._params[paramOffset + 4]._float; - color.w = batch._params[paramOffset + 3]._float; - float depth = batch._params[paramOffset + 2]._float; - int stencil = batch._params[paramOffset + 1]._int; - int useScissor = batch._params[paramOffset + 0]._int; - - GLuint glmask = 0; - bool restoreStencilMask = false; - uint8_t cacheStencilMask = 0xFF; - if (masks & Framebuffer::BUFFER_STENCIL) { - glClearStencil(stencil); - glmask |= GL_STENCIL_BUFFER_BIT; - cacheStencilMask = _pipeline._stateCache.stencilActivation.getWriteMaskFront(); - if (cacheStencilMask != 0xFF) { - restoreStencilMask = true; - glStencilMask(0xFF); - } - } - - bool restoreDepthMask = false; - if (masks & Framebuffer::BUFFER_DEPTH) { - glClearDepthf(depth); - glmask |= GL_DEPTH_BUFFER_BIT; - - bool cacheDepthMask = _pipeline._stateCache.depthTest.getWriteMask(); - if (!cacheDepthMask) { - restoreDepthMask = true; - glDepthMask(GL_TRUE); - } - } - - std::vector drawBuffers; - if (masks & Framebuffer::BUFFER_COLORS) { - if (_output._framebuffer) { - for (unsigned int i = 0; i < Framebuffer::MAX_NUM_RENDER_BUFFERS; i++) { - if (masks & (1 << i)) { - drawBuffers.push_back(GL_COLOR_ATTACHMENT0 + i); - } - } - - if (!drawBuffers.empty()) { - glDrawBuffers((GLsizei)drawBuffers.size(), drawBuffers.data()); - glClearColor(color.x, color.y, color.z, color.w); - glmask |= GL_COLOR_BUFFER_BIT; - - (void) CHECK_GL_ERROR(); - } - } else { - glClearColor(color.x, color.y, color.z, color.w); - glmask |= GL_COLOR_BUFFER_BIT; - } - - // Force the color mask cache to WRITE_ALL if not the case - do_setStateColorWriteMask(State::ColorMask::WRITE_ALL); - } - - // Apply scissor if needed and if not already on - bool doEnableScissor = (useScissor && (!_pipeline._stateCache.scissorEnable)); - if (doEnableScissor) { - glEnable(GL_SCISSOR_TEST); - } - - // Clear! - glClear(glmask); - - // Restore scissor if needed - if (doEnableScissor) { - glDisable(GL_SCISSOR_TEST); - } - - // Restore Stencil write mask - if (restoreStencilMask) { - glStencilMask(cacheStencilMask); - } - - // Restore write mask meaning turn back off - if (restoreDepthMask) { - glDepthMask(GL_FALSE); - } - - // Restore the color draw buffers only if a frmaebuffer is bound - if (_output._framebuffer && !drawBuffers.empty()) { - auto glFramebuffer = syncGPUObject(*_output._framebuffer); - if (glFramebuffer) { - glDrawBuffers((GLsizei)glFramebuffer->_colorBuffers.size(), glFramebuffer->_colorBuffers.data()); - } - } - - (void) CHECK_GL_ERROR(); -} - -void GLBackend::downloadFramebuffer(const FramebufferPointer& srcFramebuffer, const Vec4i& region, QImage& destImage) { - auto readFBO = getFramebufferID(srcFramebuffer); - if (srcFramebuffer && readFBO) { - if ((srcFramebuffer->getWidth() < (region.x + region.z)) || (srcFramebuffer->getHeight() < (region.y + region.w))) { - qCWarning(gpugllogging) << "GLBackend::downloadFramebuffer : srcFramebuffer is too small to provide the region queried"; - return; - } - } - - if ((destImage.width() < region.z) || (destImage.height() < region.w)) { - qCWarning(gpugllogging) << "GLBackend::downloadFramebuffer : destImage is too small to receive the region of the framebuffer"; - return; - } - - GLenum format = GL_RGBA; - if (destImage.format() != QImage::Format_ARGB32) { - qCWarning(gpugllogging) << "GLBackend::downloadFramebuffer : destImage format must be FORMAT_ARGB32 to receive the region of the framebuffer"; - return; - } - - glBindFramebuffer(GL_READ_FRAMEBUFFER, getFramebufferID(srcFramebuffer)); - glReadPixels(region.x, region.y, region.z, region.w, format, GL_UNSIGNED_BYTE, destImage.bits()); - glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); - - (void) CHECK_GL_ERROR(); -} diff --git a/libraries/gpu-gles/src/gpu/gl/GLBackendPipeline.cpp b/libraries/gpu-gles/src/gpu/gl/GLBackendPipeline.cpp deleted file mode 100644 index b80be8492f..0000000000 --- a/libraries/gpu-gles/src/gpu/gl/GLBackendPipeline.cpp +++ /dev/null @@ -1,291 +0,0 @@ -// -// GLBackendPipeline.cpp -// libraries/gpu/src/gpu -// -// Created by Sam Gateau on 3/8/2015. -// Copyright 2014 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 "GLBackend.h" -#include "GLShared.h" -#include "GLPipeline.h" -#include "GLShader.h" -#include "GLState.h" -#include "GLBuffer.h" -#include "GLTexture.h" - -using namespace gpu; -using namespace gpu::gl; - -void GLBackend::do_setPipeline(const Batch& batch, size_t paramOffset) { - PipelinePointer pipeline = batch._pipelines.get(batch._params[paramOffset + 0]._uint); - - if (_pipeline._pipeline == pipeline) { - return; - } - - // A true new Pipeline - _stats._PSNumSetPipelines++; - - // null pipeline == reset - if (!pipeline) { - _pipeline._pipeline.reset(); - - _pipeline._program = 0; - _pipeline._cameraCorrectionLocation = -1; - _pipeline._programShader = nullptr; - _pipeline._invalidProgram = true; - - _pipeline._state = nullptr; - _pipeline._invalidState = true; - } else { - auto pipelineObject = GLPipeline::sync(*this, *pipeline); - if (!pipelineObject) { - return; - } - - // check the program cache - // pick the program version - // check the program cache - // pick the program version -#ifdef GPU_STEREO_CAMERA_BUFFER - GLuint glprogram = pipelineObject->_program->getProgram((GLShader::Version) isStereo()); -#else - GLuint glprogram = pipelineObject->_program->getProgram(); -#endif - - if (_pipeline._program != glprogram) { - _pipeline._program = glprogram; - _pipeline._programShader = pipelineObject->_program; - _pipeline._invalidProgram = true; - _pipeline._cameraCorrectionLocation = pipelineObject->_cameraCorrection; - } - - // Now for the state - if (_pipeline._state != pipelineObject->_state) { - _pipeline._state = pipelineObject->_state; - _pipeline._invalidState = true; - } - - // Remember the new pipeline - _pipeline._pipeline = pipeline; - } - - // THis should be done on Pipeline::update... - if (_pipeline._invalidProgram) { - glUseProgram(_pipeline._program); - if (_pipeline._cameraCorrectionLocation != -1) { - gl::GLBuffer* cameraCorrectionBuffer = nullptr; - if (_transform._viewCorrectionEnabled) { - cameraCorrectionBuffer = syncGPUObject(*_pipeline._cameraCorrectionBuffer._buffer); - } else { - cameraCorrectionBuffer = syncGPUObject(*_pipeline._cameraCorrectionBufferIdentity._buffer); - } - glBindBufferRange(GL_UNIFORM_BUFFER, _pipeline._cameraCorrectionLocation, cameraCorrectionBuffer->_id, 0, sizeof(CameraCorrection)); - } - (void) CHECK_GL_ERROR(); - _pipeline._invalidProgram = false; - } -} - -void GLBackend::updatePipeline() { - if (_pipeline._invalidProgram) { - // doing it here is aproblem for calls to glUniform.... so will do it on assing... - glUseProgram(_pipeline._program); - (void) CHECK_GL_ERROR(); - _pipeline._invalidProgram = false; - } - - if (_pipeline._invalidState) { - if (_pipeline._state) { - // first reset to default what should be - // the fields which were not to default and are default now - resetPipelineState(_pipeline._state->_signature); - - // Update the signature cache with what's going to be touched - _pipeline._stateSignatureCache |= _pipeline._state->_signature; - - // And perform - for (auto command: _pipeline._state->_commands) { - command->run(this); - } - } else { - // No state ? anyway just reset everything - resetPipelineState(0); - } - _pipeline._invalidState = false; - } -} - -void GLBackend::resetPipelineStage() { - // First reset State to default - State::Signature resetSignature(0); - resetPipelineState(resetSignature); - _pipeline._state = nullptr; - _pipeline._invalidState = false; - - // Second the shader side - _pipeline._invalidProgram = false; - _pipeline._program = 0; - _pipeline._programShader = nullptr; - _pipeline._pipeline.reset(); - glUseProgram(0); -} - -void GLBackend::releaseUniformBuffer(uint32_t slot) { - auto& buf = _uniform._buffers[slot]; - if (buf) { - auto* object = Backend::getGPUObject(*buf); - if (object) { - glBindBufferBase(GL_UNIFORM_BUFFER, slot, 0); // RELEASE - (void) CHECK_GL_ERROR(); - } - buf.reset(); - } -} - -void GLBackend::resetUniformStage() { - for (uint32_t i = 0; i < _uniform._buffers.size(); i++) { - releaseUniformBuffer(i); - } -} - -void GLBackend::do_setUniformBuffer(const Batch& batch, size_t paramOffset) { - GLuint slot = batch._params[paramOffset + 3]._uint; - if (slot >(GLuint)MAX_NUM_UNIFORM_BUFFERS) { - qCDebug(gpugllogging) << "GLBackend::do_setUniformBuffer: Trying to set a uniform Buffer at slot #" << slot << " which doesn't exist. MaxNumUniformBuffers = " << getMaxNumUniformBuffers(); - return; - } - BufferPointer uniformBuffer = batch._buffers.get(batch._params[paramOffset + 2]._uint); - GLintptr rangeStart = batch._params[paramOffset + 1]._uint; - GLsizeiptr rangeSize = batch._params[paramOffset + 0]._uint; - - if (!uniformBuffer) { - releaseUniformBuffer(slot); - return; - } - - // check cache before thinking - if (_uniform._buffers[slot] == uniformBuffer) { - return; - } - - // Sync BufferObject - auto* object = syncGPUObject(*uniformBuffer); - if (object) { - glBindBufferRange(GL_UNIFORM_BUFFER, slot, object->_buffer, rangeStart, rangeSize); - - _uniform._buffers[slot] = uniformBuffer; - (void) CHECK_GL_ERROR(); - } else { - releaseUniformBuffer(slot); - return; - } -} - -void GLBackend::releaseResourceTexture(uint32_t slot) { - auto& tex = _resource._textures[slot]; - if (tex) { - auto* object = Backend::getGPUObject(*tex); - if (object) { - GLuint target = object->_target; - glActiveTexture(GL_TEXTURE0 + slot); - glBindTexture(target, 0); // RELEASE - (void) CHECK_GL_ERROR(); - } - tex.reset(); - } -} - -void GLBackend::resetResourceStage() { - for (uint32_t i = 0; i < _resource._buffers.size(); i++) { - releaseResourceBuffer(i); - } - for (uint32_t i = 0; i < _resource._textures.size(); i++) { - releaseResourceTexture(i); - } -} - -void GLBackend::do_setResourceBuffer(const Batch& batch, size_t paramOffset) { - GLuint slot = batch._params[paramOffset + 1]._uint; - if (slot >= (GLuint)MAX_NUM_RESOURCE_BUFFERS) { - qCDebug(gpugllogging) << "GLBackend::do_setResourceBuffer: Trying to set a resource Buffer at slot #" << slot << " which doesn't exist. MaxNumResourceBuffers = " << getMaxNumResourceBuffers(); - return; - } - - auto resourceBuffer = batch._buffers.get(batch._params[paramOffset + 0]._uint); - - if (!resourceBuffer) { - releaseResourceBuffer(slot); - return; - } - // check cache before thinking - if (_resource._buffers[slot] == resourceBuffer) { - return; - } - - // One more True Buffer bound - _stats._RSNumResourceBufferBounded++; - - // If successful bind then cache it - if (bindResourceBuffer(slot, resourceBuffer)) { - _resource._buffers[slot] = resourceBuffer; - } else { // else clear slot and cache - releaseResourceBuffer(slot); - return; - } -} - -void GLBackend::do_setResourceTexture(const Batch& batch, size_t paramOffset) { - GLuint slot = batch._params[paramOffset + 1]._uint; - if (slot >= (GLuint) MAX_NUM_RESOURCE_TEXTURES) { - qCDebug(gpugllogging) << "GLBackend::do_setResourceTexture: Trying to set a resource Texture at slot #" << slot << " which doesn't exist. MaxNumResourceTextures = " << getMaxNumResourceTextures(); - return; - } - - TexturePointer resourceTexture = batch._textures.get(batch._params[paramOffset + 0]._uint); - - if (!resourceTexture) { - releaseResourceTexture(slot); - return; - } - // check cache before thinking - if (_resource._textures[slot] == resourceTexture) { - return; - } - - // One more True texture bound - _stats._RSNumTextureBounded++; - - // Always make sure the GLObject is in sync - GLTexture* object = syncGPUObject(resourceTexture); - if (object) { - GLuint to = object->_texture; - GLuint target = object->_target; - glActiveTexture(GL_TEXTURE0 + slot); - glBindTexture(target, to); - - (void) CHECK_GL_ERROR(); - - _resource._textures[slot] = resourceTexture; - - _stats._RSAmountTextureMemoryBounded += (int) object->size(); - - } else { - releaseResourceTexture(slot); - return; - } -} - -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--) { - if (!_textures[i]) { - return i; - } - } - return -1; -} - diff --git a/libraries/gpu-gles/src/gpu/gl/GLBackendQuery.cpp b/libraries/gpu-gles/src/gpu/gl/GLBackendQuery.cpp deleted file mode 100644 index 43c8f8f465..0000000000 --- a/libraries/gpu-gles/src/gpu/gl/GLBackendQuery.cpp +++ /dev/null @@ -1,99 +0,0 @@ -// -// GLBackendQuery.cpp -// libraries/gpu/src/gpu -// -// Created by Sam Gateau on 7/7/2015. -// Copyright 2015 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 "GLBackend.h" -#include "GLQuery.h" -#include "GLShared.h" - -using namespace gpu; -using namespace gpu::gl; - -// Eventually, we want to test with TIME_ELAPSED instead of TIMESTAMP -#ifdef Q_OS_MAC -//const uint32_t MAX_RANGE_QUERY_DEPTH = 1; -static bool timeElapsed = true; -#else -//const uint32_t MAX_RANGE_QUERY_DEPTH = 10000; -static bool timeElapsed = false; -#endif - -void GLBackend::do_beginQuery(const Batch& batch, size_t paramOffset) { -#if !defined(USE_GLES) - auto query = batch._queries.get(batch._params[paramOffset]._uint); - GLQuery* glquery = syncGPUObject(*query); - if (glquery) { - //glGetInteger64v(GL_TIMESTAMP_EXT, (GLint64*)&glquery->_batchElapsedTime); - glquery->_batchElapsedTime = 1; - if (timeElapsed) { - glBeginQuery(GL_TIME_ELAPSED_EXT, glquery->_endqo); - } else { - if (glQueryCounterEXT != NULL) { - glQueryCounterEXT(glquery->_beginqo, GL_TIMESTAMP_EXT); - } - } - glquery->_rangeQueryDepth = _queryStage._rangeQueryDepth; - (void)CHECK_GL_ERROR(); - } -#endif -} - -void GLBackend::do_endQuery(const Batch& batch, size_t paramOffset) { -#if !defined(USE_GLES) - auto query = batch._queries.get(batch._params[paramOffset]._uint); - GLQuery* glquery = syncGPUObject(*query); - if (glquery) { - if (timeElapsed) { - glEndQuery(GL_TIME_ELAPSED_EXT); - } else { - if (glQueryCounterEXT != NULL) { - glQueryCounterEXT(glquery->_endqo, GL_TIMESTAMP_EXT); - } - } - - --_queryStage._rangeQueryDepth; - GLint64 now; - //glGetInteger64v(GL_TIMESTAMP_EXT, &now); - //glquery->_batchElapsedTime = now - glquery->_batchElapsedTime; - now = 1; - glquery->_batchElapsedTime = 1; - - PROFILE_RANGE_END(render_gpu_gl, glquery->_profileRangeId); - - (void)CHECK_GL_ERROR(); - } -#endif -} - -void GLBackend::do_getQuery(const Batch& batch, size_t paramOffset) { -#if !defined(USE_GLES) - auto query = batch._queries.get(batch._params[paramOffset]._uint); - if (glGetQueryObjectui64vEXT == NULL) - return; - GLQuery* glquery = syncGPUObject(*query); - if (glquery) { - glGetQueryObjectui64vEXT(glquery->_endqo, GL_QUERY_RESULT_AVAILABLE, &glquery->_result); - if (glquery->_result == GL_TRUE) { - if (timeElapsed) { - glGetQueryObjectui64vEXT(glquery->_endqo, GL_QUERY_RESULT, &glquery->_result); - } else { - GLuint64 start, end; - glGetQueryObjectui64vEXT(glquery->_beginqo, GL_QUERY_RESULT, &start); - glGetQueryObjectui64vEXT(glquery->_endqo, GL_QUERY_RESULT, &end); - glquery->_result = end - start; - } - query->triggerReturnHandler(glquery->_result, glquery->_batchElapsedTime); - } - (void)CHECK_GL_ERROR(); - } -#endif -} - -void GLBackend::resetQueryStage() { -} diff --git a/libraries/gpu-gles/src/gpu/gl/GLBackendShader.cpp b/libraries/gpu-gles/src/gpu/gl/GLBackendShader.cpp deleted file mode 100644 index 677bba97ca..0000000000 --- a/libraries/gpu-gles/src/gpu/gl/GLBackendShader.cpp +++ /dev/null @@ -1,583 +0,0 @@ -// -// Created by Gabriel Calero & Cristian Duarte on 2017/12/28 -// 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 "GLBackend.h" -#include "GLShader.h" -#include - -using namespace gpu; -using namespace gpu::gl; - -// GLSL version -std::string GLBackend::getBackendShaderHeader() const { - return std::string("#version 310 es"); -} - -// Shader domain -static const size_t NUM_SHADER_DOMAINS = 2; - -// GL Shader type enums -// Must match the order of type specified in gpu::Shader::Type -static const std::array SHADER_DOMAINS{ { - GL_VERTEX_SHADER, - GL_FRAGMENT_SHADER, - // GL_GEOMETRY_SHADER, -} }; - -// Domain specific defines -// Must match the order of type specified in gpu::Shader::Type -static const std::array DOMAIN_DEFINES{ { - "#define GPU_VERTEX_SHADER", - "#define GPU_PIXEL_SHADER", - // "#define GPU_GEOMETRY_SHADER", -} }; - -// Stereo specific defines -static const std::string stereoVersion{ -#ifdef GPU_STEREO_DRAWCALL_INSTANCED - "#define GPU_TRANSFORM_IS_STEREO\n#define GPU_TRANSFORM_STEREO_CAMERA\n#define GPU_TRANSFORM_STEREO_CAMERA_INSTANCED\n#define GPU_TRANSFORM_STEREO_SPLIT_SCREEN" -#endif -#ifdef GPU_STEREO_DRAWCALL_DOUBLED -#ifdef GPU_STEREO_CAMERA_BUFFER - "#define GPU_TRANSFORM_IS_STEREO\n#define GPU_TRANSFORM_STEREO_CAMERA\n#define GPU_TRANSFORM_STEREO_CAMERA_ATTRIBUTED" -#else - "#define GPU_TRANSFORM_IS_STEREO" -#endif -#endif -}; - -// Versions specific of the shader -static const std::array VERSION_DEFINES { { - "", - stereoVersion -} }; - -GLShader* GLBackend::compileBackendShader(const Shader& shader, const Shader::CompilationHandler& handler) { - // Any GLSLprogram ? normally yes... - const std::string& shaderSource = shader.getSource().getCode(); - GLenum shaderDomain = SHADER_DOMAINS[shader.getType()]; - GLShader::ShaderObjects shaderObjects; - Shader::CompilationLogs compilationLogs(GLShader::NumVersions); - - for (int version = 0; version < GLShader::NumVersions; version++) { - auto& shaderObject = shaderObjects[version]; - - std::string shaderDefines = getBackendShaderHeader() + "\n" + DOMAIN_DEFINES[shader.getType()] + "\n" + VERSION_DEFINES[version] - + "\n#extension GL_EXT_texture_buffer : enable" - + "\nprecision lowp float; // check precision 2" - + "\nprecision lowp samplerBuffer;" - + "\nprecision lowp sampler2DShadow;"; - if (handler) { - bool retest = true; - std::string currentSrc = shaderSource; - // When a Handler is specified, we can try multiple times to build the shader and let the handler change the source if the compilation fails. - // The retest bool is set to false as soon as the compilation succeed to wexit the while loop. - // The handler tells us if we should retry or not while returning a modified version of the source. - while (retest) { - bool result = ::gl::compileShader(shaderDomain, currentSrc, shaderDefines, shaderObject.glshader, compilationLogs[version].message); - compilationLogs[version].compiled = result; - if (!result) { - std::string newSrc; - retest = handler(shader, currentSrc, compilationLogs[version], newSrc); - currentSrc = newSrc; - } else { - retest = false; - } - } - } else { - compilationLogs[version].compiled = ::gl::compileShader(shaderDomain, shaderSource, shaderDefines, shaderObject.glshader, compilationLogs[version].message); - } - - if (!compilationLogs[version].compiled) { - qCWarning(gpugllogging) << "GLBackend::compileBackendProgram - Shader didn't compile:\n" << compilationLogs[version].message.c_str(); - shader.setCompilationLogs(compilationLogs); - return nullptr; - } - } - // Compilation feedback - shader.setCompilationLogs(compilationLogs); - - // So far so good, the shader is created successfully - GLShader* object = new GLShader(this->shared_from_this()); - object->_shaderObjects = shaderObjects; - - return object; -} - -GLShader* GLBackend::compileBackendProgram(const Shader& program, const Shader::CompilationHandler& handler) { - if (!program.isProgram()) { - return nullptr; - } - - GLShader::ShaderObjects programObjects; - - Shader::CompilationLogs compilationLogs(GLShader::NumVersions); - - for (int version = 0; version < GLShader::NumVersions; version++) { - auto& programObject = programObjects[version]; - - // Let's go through every shaders and make sure they are ready to go - std::vector< GLuint > shaderGLObjects; - for (auto subShader : program.getShaders()) { - auto object = GLShader::sync((*this), *subShader, handler); - if (object) { - shaderGLObjects.push_back(object->_shaderObjects[version].glshader); - } else { - qCWarning(gpugllogging) << "GLBackend::compileBackendProgram - One of the shaders of the program is not compiled?"; - program.setCompilationLogs(compilationLogs); - return nullptr; - } - } - - GLuint glprogram = ::gl::compileProgram(shaderGLObjects, compilationLogs[version].message, compilationLogs[version].binary); - if (glprogram == 0) { - qCWarning(gpugllogging) << "GLBackend::compileBackendProgram - Program didn't link:\n" << compilationLogs[version].message.c_str(); - program.setCompilationLogs(compilationLogs); - return nullptr; - } - - programObject.glprogram = glprogram; - - makeProgramBindings(programObject); - } - // Compilation feedback - program.setCompilationLogs(compilationLogs); - - // So far so good, the program versions have all been created successfully - GLShader* object = new GLShader(this->shared_from_this()); - object->_shaderObjects = programObjects; - - return object; -} - -GLBackend::ElementResource GLBackend::getFormatFromGLUniform(GLenum gltype) { - switch (gltype) { - case GL_FLOAT: - return ElementResource(Element(SCALAR, gpu::FLOAT, UNIFORM), Resource::BUFFER); - case GL_FLOAT_VEC2: - return ElementResource(Element(VEC2, gpu::FLOAT, UNIFORM), Resource::BUFFER); - case GL_FLOAT_VEC3: - return ElementResource(Element(VEC3, gpu::FLOAT, UNIFORM), Resource::BUFFER); - case GL_FLOAT_VEC4: - return ElementResource(Element(VEC4, gpu::FLOAT, UNIFORM), Resource::BUFFER); - - case GL_INT: - return ElementResource(Element(SCALAR, gpu::INT32, UNIFORM), Resource::BUFFER); - case GL_INT_VEC2: - return ElementResource(Element(VEC2, gpu::INT32, UNIFORM), Resource::BUFFER); - case GL_INT_VEC3: - return ElementResource(Element(VEC3, gpu::INT32, UNIFORM), Resource::BUFFER); - case GL_INT_VEC4: - return ElementResource(Element(VEC4, gpu::INT32, UNIFORM), Resource::BUFFER); - - case GL_UNSIGNED_INT: - return ElementResource(Element(SCALAR, gpu::UINT32, UNIFORM), Resource::BUFFER); - case GL_UNSIGNED_INT_VEC2: - return ElementResource(Element(VEC2, gpu::UINT32, UNIFORM), Resource::BUFFER); - case GL_UNSIGNED_INT_VEC3: - return ElementResource(Element(VEC3, gpu::UINT32, UNIFORM), Resource::BUFFER); - case GL_UNSIGNED_INT_VEC4: - return ElementResource(Element(VEC4, gpu::UINT32, UNIFORM), Resource::BUFFER); - - case GL_BOOL: - return ElementResource(Element(SCALAR, gpu::BOOL, UNIFORM), Resource::BUFFER); - case GL_BOOL_VEC2: - return ElementResource(Element(VEC2, gpu::BOOL, UNIFORM), Resource::BUFFER); - case GL_BOOL_VEC3: - return ElementResource(Element(VEC3, gpu::BOOL, UNIFORM), Resource::BUFFER); - case GL_BOOL_VEC4: - return ElementResource(Element(VEC4, gpu::BOOL, UNIFORM), Resource::BUFFER); - - case GL_FLOAT_MAT2: - return ElementResource(Element(gpu::MAT2, gpu::FLOAT, UNIFORM), Resource::BUFFER); - case GL_FLOAT_MAT3: - return ElementResource(Element(MAT3, gpu::FLOAT, UNIFORM), Resource::BUFFER); - case GL_FLOAT_MAT4: - return ElementResource(Element(MAT4, gpu::FLOAT, UNIFORM), Resource::BUFFER); - - //{GL_FLOAT_MAT2x3 mat2x3}, - //{GL_FLOAT_MAT2x4 mat2x4}, - //{GL_FLOAT_MAT3x2 mat3x2}, - //{GL_FLOAT_MAT3x4 mat3x4}, - //{GL_FLOAT_MAT4x2 mat4x2}, - //{GL_FLOAT_MAT4x3 mat4x3}, - //{GL_DOUBLE_MAT2 dmat2}, - //{GL_DOUBLE_MAT3 dmat3}, - //{GL_DOUBLE_MAT4 dmat4}, - //{GL_DOUBLE_MAT2x3 dmat2x3}, - //{GL_DOUBLE_MAT2x4 dmat2x4}, - //{GL_DOUBLE_MAT3x2 dmat3x2}, - //{GL_DOUBLE_MAT3x4 dmat3x4}, - //{GL_DOUBLE_MAT4x2 dmat4x2}, - //{GL_DOUBLE_MAT4x3 dmat4x3}, - - case GL_SAMPLER_2D: - return ElementResource(Element(SCALAR, gpu::FLOAT, SAMPLER), Resource::TEXTURE_2D); - - case GL_SAMPLER_3D: - return ElementResource(Element(SCALAR, gpu::FLOAT, SAMPLER), Resource::TEXTURE_3D); - case GL_SAMPLER_CUBE: - return ElementResource(Element(SCALAR, gpu::FLOAT, SAMPLER), Resource::TEXTURE_CUBE); - - case GL_SAMPLER_2D_MULTISAMPLE: - return ElementResource(Element(SCALAR, gpu::FLOAT, SAMPLER_MULTISAMPLE), Resource::TEXTURE_2D); - case GL_SAMPLER_2D_ARRAY: - return ElementResource(Element(SCALAR, gpu::FLOAT, SAMPLER), Resource::TEXTURE_2D_ARRAY); - case GL_SAMPLER_2D_MULTISAMPLE_ARRAY: - return ElementResource(Element(SCALAR, gpu::FLOAT, SAMPLER_MULTISAMPLE), Resource::TEXTURE_2D_ARRAY); - - case GL_SAMPLER_2D_SHADOW: - return ElementResource(Element(SCALAR, gpu::FLOAT, SAMPLER_SHADOW), Resource::TEXTURE_2D); - case GL_SAMPLER_CUBE_SHADOW: - return ElementResource(Element(SCALAR, gpu::FLOAT, SAMPLER_SHADOW), Resource::TEXTURE_CUBE); - - case GL_SAMPLER_2D_ARRAY_SHADOW: - return ElementResource(Element(SCALAR, gpu::FLOAT, SAMPLER_SHADOW), Resource::TEXTURE_2D_ARRAY); - - // {GL_SAMPLER_1D_SHADOW sampler1DShadow}, - // {GL_SAMPLER_1D_ARRAY_SHADOW sampler1DArrayShadow}, - - case GL_SAMPLER_BUFFER: - return ElementResource(Element(SCALAR, gpu::FLOAT, RESOURCE_BUFFER), Resource::BUFFER); - - // {GL_SAMPLER_2D_RECT sampler2DRect}, - // {GL_SAMPLER_2D_RECT_SHADOW sampler2DRectShadow}, - - case GL_INT_SAMPLER_2D: - return ElementResource(Element(SCALAR, gpu::INT32, SAMPLER), Resource::TEXTURE_2D); - case GL_INT_SAMPLER_2D_MULTISAMPLE: - return ElementResource(Element(SCALAR, gpu::INT32, SAMPLER_MULTISAMPLE), Resource::TEXTURE_2D); - case GL_INT_SAMPLER_3D: - return ElementResource(Element(SCALAR, gpu::INT32, SAMPLER), Resource::TEXTURE_3D); - case GL_INT_SAMPLER_CUBE: - return ElementResource(Element(SCALAR, gpu::INT32, SAMPLER), Resource::TEXTURE_CUBE); - - case GL_INT_SAMPLER_2D_ARRAY: - return ElementResource(Element(SCALAR, gpu::INT32, SAMPLER), Resource::TEXTURE_2D_ARRAY); - case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: - return ElementResource(Element(SCALAR, gpu::INT32, SAMPLER_MULTISAMPLE), Resource::TEXTURE_2D_ARRAY); - - // {GL_INT_SAMPLER_BUFFER isamplerBuffer}, - // {GL_INT_SAMPLER_2D_RECT isampler2DRect}, - - case GL_UNSIGNED_INT_SAMPLER_2D: - return ElementResource(Element(SCALAR, gpu::UINT32, SAMPLER), Resource::TEXTURE_2D); - case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: - return ElementResource(Element(SCALAR, gpu::UINT32, SAMPLER_MULTISAMPLE), Resource::TEXTURE_2D); - case GL_UNSIGNED_INT_SAMPLER_3D: - return ElementResource(Element(SCALAR, gpu::UINT32, SAMPLER), Resource::TEXTURE_3D); - case GL_UNSIGNED_INT_SAMPLER_CUBE: - return ElementResource(Element(SCALAR, gpu::UINT32, SAMPLER), Resource::TEXTURE_CUBE); - - case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: - return ElementResource(Element(SCALAR, gpu::UINT32, SAMPLER), Resource::TEXTURE_2D_ARRAY); - case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: - return ElementResource(Element(SCALAR, gpu::UINT32, SAMPLER_MULTISAMPLE), Resource::TEXTURE_2D_ARRAY); - //{GL_UNSIGNED_INT_SAMPLER_BUFFER usamplerBuffer}, - //{GL_UNSIGNED_INT_SAMPLER_2D_RECT usampler2DRect}, - - //{GL_IMAGE_1D image1D}, - //{GL_IMAGE_2D image2D}, - //{GL_IMAGE_3D image3D}, - //{GL_IMAGE_2D_RECT image2DRect}, - //{GL_IMAGE_CUBE imageCube}, - //{GL_IMAGE_BUFFER imageBuffer}, - //{GL_IMAGE_1D_ARRAY image1DArray}, - //{GL_IMAGE_2D_ARRAY image2DArray}, - //{GL_IMAGE_2D_MULTISAMPLE image2DMS}, - //{GL_IMAGE_2D_MULTISAMPLE_ARRAY image2DMSArray}, - //{GL_INT_IMAGE_1D iimage1D}, - //{GL_INT_IMAGE_2D iimage2D}, - //{GL_INT_IMAGE_3D iimage3D}, - //{GL_INT_IMAGE_2D_RECT iimage2DRect}, - //{GL_INT_IMAGE_CUBE iimageCube}, - //{GL_INT_IMAGE_BUFFER iimageBuffer}, - //{GL_INT_IMAGE_1D_ARRAY iimage1DArray}, - //{GL_INT_IMAGE_2D_ARRAY iimage2DArray}, - //{GL_INT_IMAGE_2D_MULTISAMPLE iimage2DMS}, - //{GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY iimage2DMSArray}, - //{GL_UNSIGNED_INT_IMAGE_1D uimage1D}, - //{GL_UNSIGNED_INT_IMAGE_2D uimage2D}, - //{GL_UNSIGNED_INT_IMAGE_3D uimage3D}, - //{GL_UNSIGNED_INT_IMAGE_2D_RECT uimage2DRect}, - //{GL_UNSIGNED_INT_IMAGE_CUBE uimageCube},+ [0] {_name="fInnerRadius" _location=0 _element={_semantic=15 '\xf' _dimension=0 '\0' _type=0 '\0' } } gpu::Shader::Slot - - //{GL_UNSIGNED_INT_IMAGE_BUFFER uimageBuffer}, - //{GL_UNSIGNED_INT_IMAGE_1D_ARRAY uimage1DArray}, - //{GL_UNSIGNED_INT_IMAGE_2D_ARRAY uimage2DArray}, - //{GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE uimage2DMS}, - //{GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY uimage2DMSArray}, - //{GL_UNSIGNED_INT_ATOMIC_COUNTER atomic_uint} -#if 0 - case GL_SAMPLER_1D: return ElementResource(Element(SCALAR, gpu::FLOAT, SAMPLER), Resource::TEXTURE_1D); - case GL_INT_SAMPLER_1D: return ElementResource(Element(SCALAR, gpu::INT32, SAMPLER), Resource::TEXTURE_1D); - case GL_INT_SAMPLER_1D_ARRAY: return ElementResource(Element(SCALAR, gpu::INT32, SAMPLER), Resource::TEXTURE_1D_ARRAY); - case GL_UNSIGNED_INT_SAMPLER_1D: return ElementResource(Element(SCALAR, gpu::UINT32, SAMPLER), Resource::TEXTURE_1D); - case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY: return ElementResource(Element(SCALAR, gpu::UINT32, SAMPLER), Resource::TEXTURE_1D_ARRAY); - case GL_SAMPLER_1D_ARRAY: return ElementResource(Element(SCALAR, gpu::FLOAT, SAMPLER), Resource::TEXTURE_1D_ARRAY); - case GL_DOUBLE: return ElementResource(Element(SCALAR, gpu::FLOAT, UNIFORM), Resource::BUFFER); - case GL_DOUBLE_VEC2: return ElementResource(Element(VEC2, gpu::FLOAT, UNIFORM), Resource::BUFFER); - case GL_DOUBLE_VEC3: return ElementResource(Element(VEC3, gpu::FLOAT, UNIFORM), Resource::BUFFER); - case GL_DOUBLE_VEC4: return ElementResource(Element(VEC4, gpu::FLOAT, UNIFORM), Resource::BUFFER); -#endif - - default: - return ElementResource(Element(), Resource::BUFFER); - } -}; - -int GLBackend::makeUniformSlots(GLuint glprogram, const Shader::BindingSet& slotBindings, - Shader::SlotSet& uniforms, Shader::SlotSet& textures, Shader::SlotSet& samplers) { - GLint uniformsCount = 0; - - glGetProgramiv(glprogram, GL_ACTIVE_UNIFORMS, &uniformsCount); - - for (int i = 0; i < uniformsCount; i++) { - const GLint NAME_LENGTH = 256; - GLchar name[NAME_LENGTH]; - GLint length = 0; - GLint size = 0; - GLenum type = 0; - glGetActiveUniform(glprogram, i, NAME_LENGTH, &length, &size, &type, name); - GLint location = glGetUniformLocation(glprogram, name); - const GLint INVALID_UNIFORM_LOCATION = -1; - - // Try to make sense of the gltype - auto elementResource = getFormatFromGLUniform(type); - - // The uniform as a standard var type - if (location != INVALID_UNIFORM_LOCATION) { - // Let's make sure the name doesn't contains an array element - std::string sname(name); - auto foundBracket = sname.find_first_of('['); - if (foundBracket != std::string::npos) { - // std::string arrayname = sname.substr(0, foundBracket); - - if (sname[foundBracket + 1] == '0') { - sname = sname.substr(0, foundBracket); - } else { - // skip this uniform since it's not the first element of an array - continue; - } - } - - if (elementResource._resource == Resource::BUFFER) { - uniforms.insert(Shader::Slot(sname, location, elementResource._element, elementResource._resource)); - } else { - // For texture/Sampler, the location is the actual binding value - GLint binding = -1; - glGetUniformiv(glprogram, location, &binding); - - auto requestedBinding = slotBindings.find(std::string(sname)); - if (requestedBinding != slotBindings.end()) { - if (binding != (*requestedBinding)._location) { - binding = (*requestedBinding)._location; - for (auto i = 0; i < size; i++) { - // If we are working with an array of textures, reserve for each elemet - glProgramUniform1i(glprogram, location + i, binding + i); - } - } - } - - textures.insert(Shader::Slot(name, binding, elementResource._element, elementResource._resource)); - samplers.insert(Shader::Slot(name, binding, elementResource._element, elementResource._resource)); - } - } - } - - return uniformsCount; -} - -int GLBackend::makeUniformBlockSlots(GLuint glprogram, const Shader::BindingSet& slotBindings, Shader::SlotSet& buffers) { - GLint buffersCount = 0; - - glGetProgramiv(glprogram, GL_ACTIVE_UNIFORM_BLOCKS, &buffersCount); - - // fast exit - if (buffersCount == 0) { - return 0; - } - - GLint maxNumUniformBufferSlots = 0; - glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &maxNumUniformBufferSlots); - std::vector uniformBufferSlotMap(maxNumUniformBufferSlots, -1); - - struct UniformBlockInfo { - using Vector = std::vector; - const GLuint index{ 0 }; - const std::string name; - GLint binding{ -1 }; - GLint size{ 0 }; - - static std::string getName(GLuint glprogram, GLuint i) { - static const GLint NAME_LENGTH = 256; - GLint length = 0; - GLchar nameBuffer[NAME_LENGTH]; - glGetActiveUniformBlockiv(glprogram, i, GL_UNIFORM_BLOCK_NAME_LENGTH, &length); - glGetActiveUniformBlockName(glprogram, i, NAME_LENGTH, &length, nameBuffer); - return std::string(nameBuffer); - } - - UniformBlockInfo(GLuint glprogram, GLuint i) : index(i), name(getName(glprogram, i)) { - glGetActiveUniformBlockiv(glprogram, index, GL_UNIFORM_BLOCK_BINDING, &binding); - glGetActiveUniformBlockiv(glprogram, index, GL_UNIFORM_BLOCK_DATA_SIZE, &size); - } - }; - - UniformBlockInfo::Vector uniformBlocks; - uniformBlocks.reserve(buffersCount); - for (int i = 0; i < buffersCount; i++) { - uniformBlocks.push_back(UniformBlockInfo(glprogram, i)); - } - - for (auto& info : uniformBlocks) { - auto requestedBinding = slotBindings.find(info.name); - if (requestedBinding != slotBindings.end()) { - info.binding = (*requestedBinding)._location; - glUniformBlockBinding(glprogram, info.index, info.binding); - uniformBufferSlotMap[info.binding] = info.index; - } - } - - for (auto& info : uniformBlocks) { - if (slotBindings.count(info.name)) { - continue; - } - - // If the binding is 0, or the binding maps to an already used binding - if (info.binding == 0 || !isUnusedSlot(uniformBufferSlotMap[info.binding])) { - // If no binding was assigned then just do it finding a free slot - auto slotIt = std::find_if(uniformBufferSlotMap.begin(), uniformBufferSlotMap.end(), GLBackend::isUnusedSlot); - if (slotIt != uniformBufferSlotMap.end()) { - info.binding = slotIt - uniformBufferSlotMap.begin(); - glUniformBlockBinding(glprogram, info.index, info.binding); - } else { - // This should neve happen, an active ubo cannot find an available slot among the max available?! - info.binding = -1; - } - } - - uniformBufferSlotMap[info.binding] = info.index; - } - - for (auto& info : uniformBlocks) { - static const Element element(SCALAR, gpu::UINT32, gpu::UNIFORM_BUFFER); - buffers.insert(Shader::Slot(info.name, info.binding, element, Resource::BUFFER, info.size)); - } - return buffersCount; -} - -int GLBackend::makeInputSlots(GLuint glprogram, const Shader::BindingSet& slotBindings, Shader::SlotSet& inputs) { - GLint inputsCount = 0; - - glGetProgramiv(glprogram, GL_ACTIVE_ATTRIBUTES, &inputsCount); - - for (int i = 0; i < inputsCount; i++) { - const GLint NAME_LENGTH = 256; - GLchar name[NAME_LENGTH]; - GLint length = 0; - GLint size = 0; - GLenum type = 0; - glGetActiveAttrib(glprogram, i, NAME_LENGTH, &length, &size, &type, name); - - GLint binding = glGetAttribLocation(glprogram, name); - - auto elementResource = getFormatFromGLUniform(type); - inputs.insert(Shader::Slot(name, binding, elementResource._element, -1)); - } - - return inputsCount; -} - -int GLBackend::makeOutputSlots(GLuint glprogram, const Shader::BindingSet& slotBindings, Shader::SlotSet& outputs) { - /* GLint outputsCount = 0; - - glGetProgramiv(glprogram, GL_ACTIVE_, &outputsCount); - - for (int i = 0; i < inputsCount; i++) { - const GLint NAME_LENGTH = 256; - GLchar name[NAME_LENGTH]; - GLint length = 0; - GLint size = 0; - GLenum type = 0; - glGetActiveAttrib(glprogram, i, NAME_LENGTH, &length, &size, &type, name); - - auto element = getFormatFromGLUniform(type); - outputs.insert(Shader::Slot(name, i, element)); - } - */ - return 0; //inputsCount; -} - -void GLBackend::makeProgramBindings(ShaderObject& shaderObject) { - if (!shaderObject.glprogram) { - return; - } - GLuint glprogram = shaderObject.glprogram; - GLint loc = -1; - - //Check for gpu specific attribute slotBindings - loc = glGetAttribLocation(glprogram, "inPosition"); - if (loc >= 0 && loc != gpu::Stream::POSITION) { - glBindAttribLocation(glprogram, gpu::Stream::POSITION, "inPosition"); - } - - loc = glGetAttribLocation(glprogram, "inNormal"); - if (loc >= 0 && loc != gpu::Stream::NORMAL) { - glBindAttribLocation(glprogram, gpu::Stream::NORMAL, "inNormal"); - } - - loc = glGetAttribLocation(glprogram, "inColor"); - if (loc >= 0 && loc != gpu::Stream::COLOR) { - glBindAttribLocation(glprogram, gpu::Stream::COLOR, "inColor"); - } - - loc = glGetAttribLocation(glprogram, "inTexCoord0"); - if (loc >= 0 && loc != gpu::Stream::TEXCOORD) { - glBindAttribLocation(glprogram, gpu::Stream::TEXCOORD, "inTexCoord0"); - } - - loc = glGetAttribLocation(glprogram, "inTangent"); - if (loc >= 0 && loc != gpu::Stream::TANGENT) { - glBindAttribLocation(glprogram, gpu::Stream::TANGENT, "inTangent"); - } - - char attribName[] = "inTexCoordn"; - for (auto i = 0; i < 4; i++) { - auto streamId = gpu::Stream::TEXCOORD1 + i; - - attribName[strlen(attribName) - 1] = '1' + i; - loc = glGetAttribLocation(glprogram, attribName); - if (loc >= 0 && loc != streamId) { - glBindAttribLocation(glprogram, streamId, attribName); - } - } - - loc = glGetAttribLocation(glprogram, "inSkinClusterIndex"); - if (loc >= 0 && loc != gpu::Stream::SKIN_CLUSTER_INDEX) { - glBindAttribLocation(glprogram, gpu::Stream::SKIN_CLUSTER_INDEX, "inSkinClusterIndex"); - } - - loc = glGetAttribLocation(glprogram, "inSkinClusterWeight"); - if (loc >= 0 && loc != gpu::Stream::SKIN_CLUSTER_WEIGHT) { - glBindAttribLocation(glprogram, gpu::Stream::SKIN_CLUSTER_WEIGHT, "inSkinClusterWeight"); - } - - loc = glGetAttribLocation(glprogram, "_drawCallInfo"); - if (loc >= 0 && loc != gpu::Stream::DRAW_CALL_INFO) { - glBindAttribLocation(glprogram, gpu::Stream::DRAW_CALL_INFO, "_drawCallInfo"); - } - - // Link again to take into account the assigned attrib location - glLinkProgram(glprogram); - - GLint linked = 0; - glGetProgramiv(glprogram, GL_LINK_STATUS, &linked); - if (!linked) { - qCWarning(gpugllogging) << "GLShader::makeBindings - failed to link after assigning slotBindings?"; - } -} diff --git a/libraries/gpu-gles/src/gpu/gl/GLBackendState.cpp b/libraries/gpu-gles/src/gpu/gl/GLBackendState.cpp deleted file mode 100644 index 4a5c772b8b..0000000000 --- a/libraries/gpu-gles/src/gpu/gl/GLBackendState.cpp +++ /dev/null @@ -1,334 +0,0 @@ -// -// GLBackendState.cpp -// libraries/gpu/src/gpu -// -// Created by Sam Gateau on 3/22/2015. -// Copyright 2014 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 "GLBackend.h" -#include "GLState.h" - -#include - -using namespace gpu; -using namespace gpu::gl; - -void GLBackend::resetPipelineState(State::Signature nextSignature) { - auto currentNotSignature = ~_pipeline._stateSignatureCache; - auto nextNotSignature = ~nextSignature; - auto fieldsToBeReset = currentNotSignature ^ (currentNotSignature | nextNotSignature); - if (fieldsToBeReset.any()) { - for (auto i = 0; i < State::NUM_FIELDS; i++) { - if (fieldsToBeReset[i]) { - GLState::_resetStateCommands[i]->run(this); - _pipeline._stateSignatureCache.reset(i); - } - } - } -} - -void GLBackend::syncPipelineStateCache() { - State::Data state; - - //glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); - qDebug() << "TODO: GLBackendState.cpp:syncPipelineStateCache GL_TEXTURE_CUBE_MAP_SEAMLESS"; - - // Point size is always on - // FIXME CORE - //glHint(GL_POINT_SMOOTH_HINT, GL_NICEST); - //glEnable(GL_PROGRAM_POINT_SIZE_EXT); - qDebug() << "TODO: GLBackendState.cpp:syncPipelineStateCache GL_PROGRAM_POINT_SIZE_EXT"; - - //glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); - qDebug() << "TODO: GLBackendState.cpp:syncPipelineStateCache GL_VERTEX_PROGRAM_POINT_SIZE"; - - // Default line width accross the board - glLineWidth(1.0f); - - getCurrentGLState(state); - State::Signature signature = State::evalSignature(state); - - _pipeline._stateCache = state; - _pipeline._stateSignatureCache = signature; -} - - -void GLBackend::do_setStateFillMode(int32 mode) { - if (_pipeline._stateCache.fillMode != mode) { - //static GLenum GL_FILL_MODES[] = { /*GL_POINT, GL_LINE, GL_FILL*/ }; - //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL_MODES[mode]); - qDebug() << "TODO: GLBackendState.cpp:do_setStateFillMode GL_POINT"; - qDebug() << "TODO: GLBackendState.cpp:do_setStateFillMode GL_LINE"; - qDebug() << "TODO: GLBackendState.cpp:do_setStateFillMode GL_FILL"; - qDebug() << "TODO: GLBackendState.cpp:do_setStateFillMode glPolygonMode"; - (void)CHECK_GL_ERROR(); - - _pipeline._stateCache.fillMode = State::FillMode(mode); - } -} - -void GLBackend::do_setStateCullMode(int32 mode) { - if (_pipeline._stateCache.cullMode != mode) { - static GLenum GL_CULL_MODES[] = { GL_FRONT_AND_BACK, GL_FRONT, GL_BACK }; - if (mode == State::CULL_NONE) { - glDisable(GL_CULL_FACE); - glCullFace(GL_FRONT_AND_BACK); - } else { - glEnable(GL_CULL_FACE); - glCullFace(GL_CULL_MODES[mode]); - } - (void)CHECK_GL_ERROR(); - - _pipeline._stateCache.cullMode = State::CullMode(mode); - } -} - -void GLBackend::do_setStateFrontFaceClockwise(bool isClockwise) { - if (_pipeline._stateCache.frontFaceClockwise != isClockwise) { - static GLenum GL_FRONT_FACES[] = { GL_CCW, GL_CW }; - glFrontFace(GL_FRONT_FACES[isClockwise]); - (void)CHECK_GL_ERROR(); - - _pipeline._stateCache.frontFaceClockwise = isClockwise; - } -} - -void GLBackend::do_setStateDepthClampEnable(bool enable) { - if (_pipeline._stateCache.depthClampEnable != enable) { - //if (enable) { - // glEnable(GL_DEPTH_CLAMP); - //} else { - // glDisable(GL_DEPTH_CLAMP); - //} - (void)CHECK_GL_ERROR(); - - _pipeline._stateCache.depthClampEnable = enable; - } -} - -void GLBackend::do_setStateScissorEnable(bool enable) { - if (_pipeline._stateCache.scissorEnable != enable) { - if (enable) { - glEnable(GL_SCISSOR_TEST); - } else { - glDisable(GL_SCISSOR_TEST); - } - (void)CHECK_GL_ERROR(); - - _pipeline._stateCache.scissorEnable = enable; - } -} - -void GLBackend::do_setStateMultisampleEnable(bool enable) { - if (_pipeline._stateCache.multisampleEnable != enable) { -#if !defined(USE_GLES) - if (enable) { - glEnable(GL_MULTISAMPLE); - } else { - glDisable(GL_MULTISAMPLE); - } - (void)CHECK_GL_ERROR(); -#endif - - _pipeline._stateCache.multisampleEnable = enable; - } -} - -void GLBackend::do_setStateAntialiasedLineEnable(bool enable) { - if (_pipeline._stateCache.antialisedLineEnable != enable) { -#if !defined(USE_GLES) - if (enable) { - glEnable(GL_LINE_SMOOTH); - } else { - glDisable(GL_LINE_SMOOTH); - } - (void)CHECK_GL_ERROR(); -#endif - - _pipeline._stateCache.antialisedLineEnable = enable; - } -} - -void GLBackend::do_setStateDepthBias(Vec2 bias) { - if ((bias.x != _pipeline._stateCache.depthBias) || (bias.y != _pipeline._stateCache.depthBiasSlopeScale)) { - if ((bias.x != 0.0f) || (bias.y != 0.0f)) { - glEnable(GL_POLYGON_OFFSET_FILL); -#if !defined(USE_GLES) - glEnable(GL_POLYGON_OFFSET_LINE); - glEnable(GL_POLYGON_OFFSET_POINT); -#endif - glPolygonOffset(bias.x, bias.y); - } else { - glDisable(GL_POLYGON_OFFSET_FILL); -#if !defined(USE_GLES) - glDisable(GL_POLYGON_OFFSET_LINE); - glDisable(GL_POLYGON_OFFSET_POINT); -#endif - } - (void)CHECK_GL_ERROR(); - - _pipeline._stateCache.depthBias = bias.x; - _pipeline._stateCache.depthBiasSlopeScale = bias.y; - } -} - -void GLBackend::do_setStateDepthTest(State::DepthTest test) { - const auto& current = _pipeline._stateCache.depthTest; - if (current != test) { - if (test.isEnabled()) { - glEnable(GL_DEPTH_TEST); - } else { - glDisable(GL_DEPTH_TEST); - } - if (test.getWriteMask() != current.getWriteMask()) { - glDepthMask(test.getWriteMask()); - } - if (test.getFunction() != current.getFunction()) { - glDepthFunc(COMPARISON_TO_GL[test.getFunction()]); - } - if (CHECK_GL_ERROR()) { - qCDebug(gpulogging) << "DepthTest" << (test.isEnabled() ? "Enabled" : "Disabled") - << "Mask=" << (test.getWriteMask() ? "Write" : "no Write") - << "Func=" << test.getFunction() - << "Raw=" << test.getRaw(); - } - _pipeline._stateCache.depthTest = test; - } -} - -void GLBackend::do_setStateStencil(State::StencilActivation activation, State::StencilTest testFront, State::StencilTest testBack) { - const auto& currentActivation = _pipeline._stateCache.stencilActivation; - const auto& currentTestFront = _pipeline._stateCache.stencilTestFront; - const auto& currentTestBack = _pipeline._stateCache.stencilTestBack; - if ((currentActivation != activation) - || (currentTestFront != testFront) - || (currentTestBack != testBack)) { - - if (activation.isEnabled()) { - glEnable(GL_STENCIL_TEST); - } else { - glDisable(GL_STENCIL_TEST); - } - - if (activation.getWriteMaskFront() != activation.getWriteMaskBack()) { - glStencilMaskSeparate(GL_FRONT, activation.getWriteMaskFront()); - glStencilMaskSeparate(GL_BACK, activation.getWriteMaskBack()); - } else { - glStencilMask(activation.getWriteMaskFront()); - } - - static GLenum STENCIL_OPS[State::NUM_STENCIL_OPS] = { - GL_KEEP, - GL_ZERO, - GL_REPLACE, - GL_INCR_WRAP, - GL_DECR_WRAP, - GL_INVERT, - GL_INCR, - GL_DECR }; - - if (testFront != testBack) { - glStencilOpSeparate(GL_FRONT, STENCIL_OPS[testFront.getFailOp()], STENCIL_OPS[testFront.getDepthFailOp()], STENCIL_OPS[testFront.getPassOp()]); - glStencilFuncSeparate(GL_FRONT, COMPARISON_TO_GL[testFront.getFunction()], testFront.getReference(), testFront.getReadMask()); - - glStencilOpSeparate(GL_BACK, STENCIL_OPS[testBack.getFailOp()], STENCIL_OPS[testBack.getDepthFailOp()], STENCIL_OPS[testBack.getPassOp()]); - glStencilFuncSeparate(GL_BACK, COMPARISON_TO_GL[testBack.getFunction()], testBack.getReference(), testBack.getReadMask()); - } else { - glStencilOp(STENCIL_OPS[testFront.getFailOp()], STENCIL_OPS[testFront.getDepthFailOp()], STENCIL_OPS[testFront.getPassOp()]); - glStencilFunc(COMPARISON_TO_GL[testFront.getFunction()], testFront.getReference(), testFront.getReadMask()); - } - - (void)CHECK_GL_ERROR(); - - _pipeline._stateCache.stencilActivation = activation; - _pipeline._stateCache.stencilTestFront = testFront; - _pipeline._stateCache.stencilTestBack = testBack; - } -} - -void GLBackend::do_setStateAlphaToCoverageEnable(bool enable) { - if (_pipeline._stateCache.alphaToCoverageEnable != enable) { - if (enable) { - glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE); - } else { - glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE); - } - (void)CHECK_GL_ERROR(); - - _pipeline._stateCache.alphaToCoverageEnable = enable; - } -} - -void GLBackend::do_setStateSampleMask(uint32 mask) { - if (_pipeline._stateCache.sampleMask != mask) { - if (mask == 0xFFFFFFFF) { - glDisable(GL_SAMPLE_MASK); - } else { - glEnable(GL_SAMPLE_MASK); - glSampleMaski(0, mask); - } - (void)CHECK_GL_ERROR(); - _pipeline._stateCache.sampleMask = mask; - } -} - -void GLBackend::do_setStateBlend(State::BlendFunction function) { - if (_pipeline._stateCache.blendFunction != function) { - if (function.isEnabled()) { - glEnable(GL_BLEND); - - glBlendEquationSeparate(BLEND_OPS_TO_GL[function.getOperationColor()], BLEND_OPS_TO_GL[function.getOperationAlpha()]); - (void)CHECK_GL_ERROR(); - - - glBlendFuncSeparate(BLEND_ARGS_TO_GL[function.getSourceColor()], BLEND_ARGS_TO_GL[function.getDestinationColor()], - BLEND_ARGS_TO_GL[function.getSourceAlpha()], BLEND_ARGS_TO_GL[function.getDestinationAlpha()]); - } else { - glDisable(GL_BLEND); - } - (void)CHECK_GL_ERROR(); - - _pipeline._stateCache.blendFunction = function; - } -} - -void GLBackend::do_setStateColorWriteMask(uint32 mask) { - if (_pipeline._stateCache.colorWriteMask != mask) { - glColorMask(mask & State::ColorMask::WRITE_RED, - mask & State::ColorMask::WRITE_GREEN, - mask & State::ColorMask::WRITE_BLUE, - mask & State::ColorMask::WRITE_ALPHA); - (void)CHECK_GL_ERROR(); - - _pipeline._stateCache.colorWriteMask = mask; - } -} - - -void GLBackend::do_setStateBlendFactor(const Batch& batch, size_t paramOffset) { - Vec4 factor(batch._params[paramOffset + 0]._float, - batch._params[paramOffset + 1]._float, - batch._params[paramOffset + 2]._float, - batch._params[paramOffset + 3]._float); - - glBlendColor(factor.x, factor.y, factor.z, factor.w); - (void)CHECK_GL_ERROR(); -} - -void GLBackend::do_setStateScissorRect(const Batch& batch, size_t paramOffset) { - Vec4i rect; - memcpy(&rect, batch.readData(batch._params[paramOffset]._uint), sizeof(Vec4i)); - - if (_stereo._enable) { - rect.z /= 2; - if (_stereo._pass) { - rect.x += rect.z; - } - } - glScissor(rect.x, rect.y, rect.z, rect.w); - (void)CHECK_GL_ERROR(); -} - diff --git a/libraries/gpu-gles/src/gpu/gl/GLBackendTexture.cpp b/libraries/gpu-gles/src/gpu/gl/GLBackendTexture.cpp deleted file mode 100644 index ace33766ce..0000000000 --- a/libraries/gpu-gles/src/gpu/gl/GLBackendTexture.cpp +++ /dev/null @@ -1,82 +0,0 @@ -// -// -// GLBackendTexture.cpp -// libraries/gpu/src/gpu -// -// Created by Sam Gateau on 1/19/2015. -// Copyright 2014 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 "GLBackend.h" -#include "GLTexture.h" - -using namespace gpu; -using namespace gpu::gl; - - -GLuint GLBackend::getTextureID(const TexturePointer& texture) { - GLTexture* object = syncGPUObject(texture); - - if (!object) { - return 0; - } - - return object->_id; -} - -GLTexture* GLBackend::syncGPUObject(const TexturePointer& texturePointer) { - const Texture& texture = *texturePointer; - // Special case external textures - if (TextureUsageType::EXTERNAL == texture.getUsageType()) { - Texture::ExternalUpdates updates = texture.getUpdates(); - if (!updates.empty()) { - Texture::ExternalRecycler recycler = texture.getExternalRecycler(); - Q_ASSERT(recycler); - // Discard any superfluous updates - while (updates.size() > 1) { - const auto& update = updates.front(); - // Superfluous updates will never have been read, but we want to ensure the previous - // writes to them are complete before they're written again, so return them with the - // same fences they arrived with. This can happen on any thread because no GL context - // work is involved - recycler(update.first, update.second); - updates.pop_front(); - } - - // The last texture remaining is the one we'll use to create the GLTexture - const auto& update = updates.front(); - // Check for a fence, and if it exists, inject a wait into the command stream, then destroy the fence - if (update.second) { - GLsync fence = static_cast(update.second); - glWaitSync(fence, 0, GL_TIMEOUT_IGNORED); - glDeleteSync(fence); - } - - // Create the new texture object (replaces any previous texture object) - new GLExternalTexture(shared_from_this(), texture, update.first); - } - - // Return the texture object (if any) associated with the texture, without extensive logic - // (external textures are - return Backend::getGPUObject(texture); - } - - return nullptr; -} - -void GLBackend::do_generateTextureMips(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; - } - - object->generateMips(); -} diff --git a/libraries/gpu-gles/src/gpu/gl/GLBackendTransform.cpp b/libraries/gpu-gles/src/gpu/gl/GLBackendTransform.cpp deleted file mode 100644 index f286a5cca9..0000000000 --- a/libraries/gpu-gles/src/gpu/gl/GLBackendTransform.cpp +++ /dev/null @@ -1,171 +0,0 @@ -// -// GLBackendTransform.cpp -// libraries/gpu/src/gpu -// -// Created by Sam Gateau on 3/8/2015. -// Copyright 2014 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 "GLBackend.h" - -using namespace gpu; -using namespace gpu::gl; - -// Transform Stage -void GLBackend::do_setModelTransform(const Batch& batch, size_t paramOffset) { -} - -void GLBackend::do_setViewTransform(const Batch& batch, size_t paramOffset) { - _transform._view = batch._transforms.get(batch._params[paramOffset]._uint); - _transform._viewIsCamera = batch._params[paramOffset + 1]._uint != 0; - _transform._invalidView = true; -} - -void GLBackend::do_setProjectionTransform(const Batch& batch, size_t paramOffset) { - memcpy(&_transform._projection, batch.readData(batch._params[paramOffset]._uint), sizeof(Mat4)); - _transform._invalidProj = true; -} - -void GLBackend::do_setViewportTransform(const Batch& batch, size_t paramOffset) { - memcpy(&_transform._viewport, batch.readData(batch._params[paramOffset]._uint), sizeof(Vec4i)); - -#ifdef GPU_STEREO_DRAWCALL_INSTANCED - { - ivec4& vp = _transform._viewport; - glViewport(vp.x, vp.y, vp.z, vp.w); - - // Where we assign the GL viewport - if (_stereo.isStereo()) { - vp.z /= 2; - if (_stereo._pass) { - vp.x += vp.z; - } - } - } -#else - if (!_inRenderTransferPass && !isStereo()) { - ivec4& vp = _transform._viewport; - glViewport(vp.x, vp.y, vp.z, vp.w); - } -#endif - - // The Viewport is tagged invalid because the CameraTransformUBO is not up to date and will need update on next drawcall - _transform._invalidViewport = true; -} - -void GLBackend::do_setDepthRangeTransform(const Batch& batch, size_t paramOffset) { - - Vec2 depthRange(batch._params[paramOffset + 1]._float, batch._params[paramOffset + 0]._float); - - if ((depthRange.x != _transform._depthRange.x) || (depthRange.y != _transform._depthRange.y)) { - _transform._depthRange = depthRange; - - glDepthRangef(depthRange.x, depthRange.y); - } -} - -void GLBackend::killTransform() { - glDeleteBuffers(1, &_transform._objectBuffer); - glDeleteBuffers(1, &_transform._cameraBuffer); - glDeleteBuffers(1, &_transform._drawCallInfoBuffer); - glDeleteTextures(1, &_transform._objectBufferTexture); -} - -void GLBackend::syncTransformStateCache() { - _transform._invalidViewport = true; - _transform._invalidProj = true; - _transform._invalidView = true; - - glGetIntegerv(GL_VIEWPORT, (GLint*) &_transform._viewport); - - glGetFloatv(GL_DEPTH_RANGE, (GLfloat*)&_transform._depthRange); - - Mat4 modelView; - auto modelViewInv = glm::inverse(modelView); - _transform._view.evalFromRawMatrix(modelViewInv); - - glDisableVertexAttribArray(gpu::Stream::DRAW_CALL_INFO); - _transform._enabledDrawcallInfoBuffer = false; -} - -void GLBackend::TransformStageState::preUpdate(size_t commandIndex, const StereoState& stereo) { - // Check all the dirty flags and update the state accordingly - if (_invalidViewport) { - _camera._viewport = glm::vec4(_viewport); - } - - if (_invalidProj) { - _camera._projection = _projection; - } - - if (_invalidView) { - // Apply the correction - if (_viewIsCamera && (_viewCorrectionEnabled && _correction.correction != glm::mat4())) { - // FIXME should I switch to using the camera correction buffer in Transform.slf and leave this out? - Transform result; - _view.mult(result, _view, _correction.correction); - if (_skybox) { - result.setTranslation(vec3()); - } - _view = result; - } - // This is when the _view matrix gets assigned - _view.getInverseMatrix(_camera._view); - } - - if (_invalidView || _invalidProj || _invalidViewport) { - size_t offset = _cameraUboSize * _cameras.size(); - _cameraOffsets.push_back(TransformStageState::Pair(commandIndex, offset)); - - if (stereo.isStereo()) { -#ifdef GPU_STEREO_CAMERA_BUFFER - _cameras.push_back(CameraBufferElement(_camera.getEyeCamera(0, stereo, _view), _camera.getEyeCamera(1, stereo, _view))); -#else - _cameras.push_back((_camera.getEyeCamera(0, stereo, _view))); - _cameras.push_back((_camera.getEyeCamera(1, stereo, _view))); -#endif - } else { -#ifdef GPU_STEREO_CAMERA_BUFFER - _cameras.push_back(CameraBufferElement(_camera.recomputeDerived(_view))); -#else - _cameras.push_back((_camera.recomputeDerived(_view))); -#endif - } - } - - // Flags are clean - _invalidView = _invalidProj = _invalidViewport = false; -} - -void GLBackend::TransformStageState::update(size_t commandIndex, const StereoState& stereo) const { - size_t offset = INVALID_OFFSET; - while ((_camerasItr != _cameraOffsets.end()) && (commandIndex >= (*_camerasItr).first)) { - offset = (*_camerasItr).second; - _currentCameraOffset = offset; - ++_camerasItr; - } - - if (offset != INVALID_OFFSET) { -#ifdef GPU_STEREO_CAMERA_BUFFER - bindCurrentCamera(0); -#else - if (!stereo.isStereo()) { - bindCurrentCamera(0); - } -#endif - } - (void)CHECK_GL_ERROR(); -} - -void GLBackend::TransformStageState::bindCurrentCamera(int eye) const { - if (_currentCameraOffset != INVALID_OFFSET) { - glBindBufferRange(GL_UNIFORM_BUFFER, TRANSFORM_CAMERA_SLOT, _cameraBuffer, _currentCameraOffset + eye * _cameraUboSize, sizeof(CameraBufferElement)); - } -} - -void GLBackend::resetTransformStage() { - glDisableVertexAttribArray(gpu::Stream::DRAW_CALL_INFO); - _transform._enabledDrawcallInfoBuffer = false; -} diff --git a/libraries/gpu-gles/src/gpu/gl/GLBuffer.cpp b/libraries/gpu-gles/src/gpu/gl/GLBuffer.cpp deleted file mode 100644 index 4f7d0a8632..0000000000 --- a/libraries/gpu-gles/src/gpu/gl/GLBuffer.cpp +++ /dev/null @@ -1,35 +0,0 @@ -// -// Created by Gabriel Calero & Cristian Duarte on 09/27/2016 -// Copyright 2013-2016 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 "GLBuffer.h" -#include "GLBackend.h" - -using namespace gpu; -using namespace gpu::gl; - -GLBuffer::~GLBuffer() { - Backend::bufferCount.decrement(); - Backend::bufferGPUMemSize.update(_size, 0); - - if (_id) { - auto backend = _backend.lock(); - if (backend) { - backend->releaseBuffer(_id, _size); - } - } -} - -GLBuffer::GLBuffer(const std::weak_ptr& backend, const Buffer& buffer, GLuint id) : - GLObject(backend, buffer, id), - _size((GLuint)buffer._renderSysmem.getSize()), - _stamp(buffer._renderSysmem.getStamp()) -{ - Backend::bufferCount.increment(); - Backend::bufferGPUMemSize.update(0, _size); -} - diff --git a/libraries/gpu-gles/src/gpu/gl/GLBuffer.h b/libraries/gpu-gles/src/gpu/gl/GLBuffer.h deleted file mode 100644 index 182014e764..0000000000 --- a/libraries/gpu-gles/src/gpu/gl/GLBuffer.h +++ /dev/null @@ -1,66 +0,0 @@ -// -// Created by Bradley Austin Davis on 2016/05/15 -// Copyright 2013-2016 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_gl_GLBuffer_h -#define hifi_gpu_gl_GLBuffer_h - -#include "GLShared.h" -#include "GLBackend.h" - -namespace gpu { namespace gl { - -class GLBuffer : public GLObject { -public: - template - static GLBufferType* sync(GLBackend& backend, const Buffer& buffer) { - if (buffer.getSysmem().getSize() != 0) { - if (buffer._getUpdateCount == 0) { - qWarning() << "Unsynced buffer"; - } - if (buffer._getUpdateCount < buffer._applyUpdateCount) { - qWarning() << "Unsynced buffer " << buffer._getUpdateCount << " " << buffer._applyUpdateCount; - } - } - GLBufferType* object = Backend::getGPUObject(buffer); - - // Has the storage size changed? - if (!object || object->_stamp != buffer._renderSysmem.getStamp()) { - object = new GLBufferType(backend.shared_from_this(), buffer, object); - } - - if (0 != (buffer._renderPages._flags & PageManager::DIRTY)) { - object->transfer(); - } - - return object; - } - - template - static GLuint getId(GLBackend& backend, const Buffer& buffer) { - GLBuffer* bo = sync(backend, buffer); - if (bo) { - return bo->_buffer; - } else { - return 0; - } - } - - const GLuint& _buffer { _id }; - const GLuint _size; - const Stamp _stamp; - - ~GLBuffer(); - - virtual void transfer() = 0; - -protected: - GLBuffer(const std::weak_ptr& backend, const Buffer& buffer, GLuint id); -}; - -} } - -#endif diff --git a/libraries/gpu-gles/src/gpu/gl/GLESBackend.cpp b/libraries/gpu-gles/src/gpu/gl/GLESBackend.cpp new file mode 100644 index 0000000000..2e2c988e77 --- /dev/null +++ b/libraries/gpu-gles/src/gpu/gl/GLESBackend.cpp @@ -0,0 +1,56 @@ +// +// GLBackend.cpp +// libraries/gpu-gl-android/src/gpu/gl +// +// Created by Cristian Duarte & Gabriel Calero on 9/21/2016. +// Copyright 2016 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 + +#include + + +#include +#include +#include +#include + +#include "../gles/GLESBackend.h" + +using namespace gpu; +using namespace gpu::gl; + +static GLBackend* INSTANCE{ nullptr }; + +BackendPointer GLBackend::createBackend() { + // FIXME provide a mechanism to override the backend for testing + // Where the gpuContext is initialized and where the TRUE Backend is created and assigned + //auto version = QOpenGLContextWrapper::currentContextVersion(); + std::shared_ptr result; + + qDebug() << "Using OpenGL ES backend"; + result = std::make_shared(); + + result->initInput(); + result->initTransform(); + result->initTextureManagementStage(); + + INSTANCE = result.get(); + void* voidInstance = &(*result); + qApp->setProperty(hifi::properties::gl::BACKEND, QVariant::fromValue(voidInstance)); + return result; +} + +GLBackend& getBackend() { + if (!INSTANCE) { + INSTANCE = static_cast(qApp->property(hifi::properties::gl::BACKEND).value()); + } + return *INSTANCE; +} + +bool GLBackend::makeProgram(Shader& shader, const Shader::BindingSet& slotBindings, const Shader::CompilationHandler& handler) { + return GLShader::makeProgram(getBackend(), shader, slotBindings, handler); +} diff --git a/libraries/gpu-gles/src/gpu/gl/GLFramebuffer.cpp b/libraries/gpu-gles/src/gpu/gl/GLFramebuffer.cpp deleted file mode 100644 index 0bca9e86d9..0000000000 --- a/libraries/gpu-gles/src/gpu/gl/GLFramebuffer.cpp +++ /dev/null @@ -1,47 +0,0 @@ -// -// Created by Gabriel Calero & Cristian Duarte on 09/27/2016 -// Copyright 2016 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 "GLFramebuffer.h" -#include "GLBackend.h" - -using namespace gpu; -using namespace gpu::gl; - -GLFramebuffer::~GLFramebuffer() { - if (_id) { - auto backend = _backend.lock(); - if (backend) { - backend->releaseFramebuffer(_id); - } - } -} - -bool GLFramebuffer::checkStatus() const { - switch (_status) { - case GL_FRAMEBUFFER_COMPLETE: - // Success ! - return true; - - case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: - qCWarning(gpugllogging) << "GLFramebuffer::syncGPUObject : Framebuffer not valid, GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT."; - break; - case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: - qCWarning(gpugllogging) << "GLFramebuffer::syncGPUObject : Framebuffer not valid, GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT."; - break; - //case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: - // qCWarning(gpugllogging) << "GLFramebuffer::syncGPUObject : Framebuffer not valid, GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER."; - // break; - //case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: - // qCWarning(gpugllogging) << "GLFramebuffer::syncGPUObject : Framebuffer not valid, GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER."; - // break; - case GL_FRAMEBUFFER_UNSUPPORTED: - qCWarning(gpugllogging) << "GLFramebuffer::syncGPUObject : Framebuffer not valid, GL_FRAMEBUFFER_UNSUPPORTED."; - break; - } - return false; -} diff --git a/libraries/gpu-gles/src/gpu/gl/GLFramebuffer.h b/libraries/gpu-gles/src/gpu/gl/GLFramebuffer.h deleted file mode 100644 index 5a388e1965..0000000000 --- a/libraries/gpu-gles/src/gpu/gl/GLFramebuffer.h +++ /dev/null @@ -1,77 +0,0 @@ -// -// Created by Gabriel Calero & Cristian Duarte on 09/27/2016 -// Copyright 2016 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_gl_GLFramebuffer_h -#define hifi_gpu_gl_GLFramebuffer_h - -#include "GLShared.h" -#include "GLBackend.h" - -namespace gpu { namespace gl { - -class GLFramebuffer : public GLObject { -public: - template - static GLFramebufferType* sync(GLBackend& backend, const Framebuffer& framebuffer) { - GLFramebufferType* object = Backend::getGPUObject(framebuffer); - - bool needsUpate { false }; - if (!object || - framebuffer.getDepthStamp() != object->_depthStamp || - framebuffer.getColorStamps() != object->_colorStamps) { - needsUpate = true; - } - - // If GPU object already created and in sync - if (!needsUpate) { - return object; - } else if (framebuffer.isEmpty()) { - // NO framebuffer definition yet so let's avoid thinking - return nullptr; - } - - // need to have a gpu object? - if (!object) { - // All is green, assign the gpuobject to the Framebuffer - object = new GLFramebufferType(backend.shared_from_this(), framebuffer); - Backend::setGPUObject(framebuffer, object); - (void)CHECK_GL_ERROR(); - } - - object->update(); - return object; - } - - template - static GLuint getId(GLBackend& backend, const Framebuffer& framebuffer) { - GLFramebufferType* fbo = sync(backend, framebuffer); - if (fbo) { - return fbo->_id; - } else { - return 0; - } - } - - const GLuint& _fbo { _id }; - std::vector _colorBuffers; - Stamp _depthStamp { 0 }; - std::vector _colorStamps; - -protected: - GLenum _status { GL_FRAMEBUFFER_COMPLETE }; - virtual void update() = 0; - bool checkStatus() const; - - GLFramebuffer(const std::weak_ptr& backend, const Framebuffer& framebuffer, GLuint id) : GLObject(backend, framebuffer, id) {} - ~GLFramebuffer(); - -}; - -} } - - -#endif diff --git a/libraries/gpu-gles/src/gpu/gl/GLInputFormat.cpp b/libraries/gpu-gles/src/gpu/gl/GLInputFormat.cpp deleted file mode 100644 index 7f42350c3b..0000000000 --- a/libraries/gpu-gles/src/gpu/gl/GLInputFormat.cpp +++ /dev/null @@ -1,33 +0,0 @@ -// -// Created by Sam Gateau on 2016/07/21 -// Copyright 2013-2016 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 "GLInputFormat.h" -#include "GLBackend.h" - -using namespace gpu; -using namespace gpu::gl; - - -GLInputFormat::GLInputFormat() { -} - -GLInputFormat:: ~GLInputFormat() { - -} - -GLInputFormat* GLInputFormat::sync(const Stream::Format& inputFormat) { - GLInputFormat* object = Backend::getGPUObject(inputFormat); - - if (!object) { - object = new GLInputFormat(); - object->key = inputFormat.getKey(); - Backend::setGPUObject(inputFormat, object); - } - - return object; -} diff --git a/libraries/gpu-gles/src/gpu/gl/GLInputFormat.h b/libraries/gpu-gles/src/gpu/gl/GLInputFormat.h deleted file mode 100644 index a14e3d4d91..0000000000 --- a/libraries/gpu-gles/src/gpu/gl/GLInputFormat.h +++ /dev/null @@ -1,29 +0,0 @@ -// -// Created by Sam Gateau on 2016/07/21 -// Copyright 2013-2016 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_gl_GLInputFormat_h -#define hifi_gpu_gl_GLInputFormat_h - -#include "GLShared.h" - -namespace gpu { -namespace gl { - -class GLInputFormat : public GPUObject { - public: - static GLInputFormat* sync(const Stream::Format& inputFormat); - - GLInputFormat(); - ~GLInputFormat(); - - std::string key; -}; - -} -} - -#endif diff --git a/libraries/gpu-gles/src/gpu/gl/GLPipeline.cpp b/libraries/gpu-gles/src/gpu/gl/GLPipeline.cpp deleted file mode 100644 index ebf1a55232..0000000000 --- a/libraries/gpu-gles/src/gpu/gl/GLPipeline.cpp +++ /dev/null @@ -1,59 +0,0 @@ -// -// Created by Bradley Austin Davis on 2016/05/15 -// Copyright 2013-2016 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 "GLPipeline.h" - -#include "GLShader.h" -#include "GLState.h" - -using namespace gpu; -using namespace gpu::gl; - -GLPipeline* GLPipeline::sync(GLBackend& backend, const Pipeline& pipeline) { - GLPipeline* object = Backend::getGPUObject(pipeline); - - // If GPU object already created then good - if (object) { - return object; - } - - // No object allocated yet, let's see if it's worth it... - ShaderPointer shader = pipeline.getProgram(); - - // If this pipeline's shader has already failed to compile, don't try again - if (shader->compilationHasFailed()) { - return nullptr; - } - - GLShader* programObject = GLShader::sync(backend, *shader); - if (programObject == nullptr) { - shader->setCompilationHasFailed(true); - return nullptr; - } - - StatePointer state = pipeline.getState(); - GLState* stateObject = GLState::sync(*state); - if (stateObject == nullptr) { - return nullptr; - } - - // Program and state are valid, we can create the pipeline object - if (!object) { - object = new GLPipeline(); - Backend::setGPUObject(pipeline, object); - } - - // Special case for view correction matrices, any pipeline that declares the correction buffer - // uniform will automatically have it provided without any client code necessary. - // Required for stable lighting in the HMD. - object->_cameraCorrection = shader->getUniformBuffers().findLocation("cameraCorrectionBuffer"); - object->_program = programObject; - object->_state = stateObject; - - return object; -} diff --git a/libraries/gpu-gles/src/gpu/gl/GLPipeline.h b/libraries/gpu-gles/src/gpu/gl/GLPipeline.h deleted file mode 100644 index a298f149d9..0000000000 --- a/libraries/gpu-gles/src/gpu/gl/GLPipeline.h +++ /dev/null @@ -1,29 +0,0 @@ -// -// Created by Bradley Austin Davis on 2016/05/15 -// Copyright 2013-2016 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_gl_GLPipeline_h -#define hifi_gpu_gl_GLPipeline_h - -#include "GLShared.h" - -namespace gpu { namespace gl { - -class GLPipeline : public GPUObject { -public: - static GLPipeline* sync(GLBackend& backend, const Pipeline& pipeline); - - GLShader* _program { nullptr }; - GLState* _state { nullptr }; - // Bit of a hack, any pipeline can need the camera correction buffer at execution time, so - // we store whether a given pipeline has declared the uniform buffer for it. - int32 _cameraCorrection { -1 }; -}; - -} } - - -#endif diff --git a/libraries/gpu-gles/src/gpu/gl/GLQuery.h b/libraries/gpu-gles/src/gpu/gl/GLQuery.h deleted file mode 100644 index 23b1f38621..0000000000 --- a/libraries/gpu-gles/src/gpu/gl/GLQuery.h +++ /dev/null @@ -1,67 +0,0 @@ -// -// Created by Bradley Austin Davis on 2016/05/15 -// Copyright 2013-2016 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_gl_GLQuery_h -#define hifi_gpu_gl_GLQuery_h - -#include "GLShared.h" -#include "GLBackend.h" - -namespace gpu { namespace gl { - -class GLQuery : public GLObject { - using Parent = gpu::gl::GLObject; -public: - template - static GLQueryType* sync(GLBackend& backend, const Query& query) { - GLQueryType* object = Backend::getGPUObject(query); - - // need to have a gpu object? - if (!object) { - // All is green, assign the gpuobject to the Query - object = new GLQueryType(backend.shared_from_this(), query); - (void)CHECK_GL_ERROR(); - Backend::setGPUObject(query, object); - } - - return object; - } - - template - static GLuint getId(GLBackend& backend, const QueryPointer& query) { - if (!query) { - return 0; - } - - GLQuery* object = sync(backend, *query); - if (!object) { - return 0; - } - - return object->_endqo; - } - - const GLuint& _endqo = { _id }; - const GLuint _beginqo = { 0 }; - GLuint64 _result { (GLuint64)-1 }; - GLuint64 _batchElapsedTime { (GLuint64) 0 }; - uint64_t _profileRangeId { 0 }; - uint32_t _rangeQueryDepth { 0 }; - -protected: - GLQuery(const std::weak_ptr& backend, const Query& query, GLuint endId, GLuint beginId) : Parent(backend, query, endId), _beginqo(beginId) {} - ~GLQuery() { - if (_id) { - GLuint ids[2] = { _endqo, _beginqo }; - glDeleteQueries(2, ids); - } - } -}; - -} } - -#endif diff --git a/libraries/gpu-gles/src/gpu/gl/GLShader.cpp b/libraries/gpu-gles/src/gpu/gl/GLShader.cpp deleted file mode 100644 index 010a7c479c..0000000000 --- a/libraries/gpu-gles/src/gpu/gl/GLShader.cpp +++ /dev/null @@ -1,106 +0,0 @@ -// -// Created by Bradley Austin Davis on 2016/05/15 -// Copyright 2013-2016 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 "GLShader.h" -#include - -#include "GLBackend.h" - -using namespace gpu; -using namespace gpu::gl; - -GLShader::GLShader(const std::weak_ptr& backend) : _backend(backend) { -} - -GLShader::~GLShader() { - for (auto& so : _shaderObjects) { - auto backend = _backend.lock(); - if (backend) { - if (so.glshader != 0) { - backend->releaseShader(so.glshader); - } - if (so.glprogram != 0) { - backend->releaseProgram(so.glprogram); - } - } - } -} - -GLShader* GLShader::sync(GLBackend& backend, const Shader& shader, const Shader::CompilationHandler& handler) { - GLShader* object = Backend::getGPUObject(shader); - - // If GPU object already created then good - if (object) { - return object; - } - // need to have a gpu object? - if (shader.isProgram()) { - GLShader* tempObject = backend.compileBackendProgram(shader, handler); - if (tempObject) { - object = tempObject; - Backend::setGPUObject(shader, object); - } - } else if (shader.isDomain()) { - GLShader* tempObject = backend.compileBackendShader(shader, handler); - if (tempObject) { - object = tempObject; - Backend::setGPUObject(shader, object); - } - } - - glFinish(); - return object; -} - -bool GLShader::makeProgram(GLBackend& backend, Shader& shader, const Shader::BindingSet& slotBindings, const Shader::CompilationHandler& handler) { - - // First make sure the Shader has been compiled - GLShader* object = sync(backend, shader, handler); - if (!object) { - return false; - } - - // Apply bindings to all program versions and generate list of slots from default version - for (int version = 0; version < GLShader::NumVersions; version++) { - auto& shaderObject = object->_shaderObjects[version]; - if (shaderObject.glprogram) { - Shader::SlotSet buffers; - backend.makeUniformBlockSlots(shaderObject.glprogram, slotBindings, buffers); - - Shader::SlotSet uniforms; - Shader::SlotSet textures; - Shader::SlotSet samplers; - backend.makeUniformSlots(shaderObject.glprogram, slotBindings, uniforms, textures, samplers); - - Shader::SlotSet resourceBuffers; - backend.makeResourceBufferSlots(shaderObject.glprogram, slotBindings, resourceBuffers); - - Shader::SlotSet inputs; - backend.makeInputSlots(shaderObject.glprogram, slotBindings, inputs); - - Shader::SlotSet outputs; - backend.makeOutputSlots(shaderObject.glprogram, slotBindings, outputs); - - // Define the public slots only from the default version - if (version == 0) { - shader.defineSlots(uniforms, buffers, resourceBuffers, textures, samplers, inputs, outputs); - } // else - { - GLShader::UniformMapping mapping; - for (auto srcUniform : shader.getUniforms()) { - mapping[srcUniform._location] = uniforms.findLocation(srcUniform._name); - } - object->_uniformMappings.push_back(mapping); - } - } - } - - return true; -} - - - diff --git a/libraries/gpu-gles/src/gpu/gl/GLShader.h b/libraries/gpu-gles/src/gpu/gl/GLShader.h deleted file mode 100644 index f2a144a81c..0000000000 --- a/libraries/gpu-gles/src/gpu/gl/GLShader.h +++ /dev/null @@ -1,66 +0,0 @@ -// -// Created by Bradley Austin Davis on 2016/05/15 -// Copyright 2013-2016 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_gl_GLShader_h -#define hifi_gpu_gl_GLShader_h - -#include "GLShared.h" - -namespace gpu { namespace gl { - -struct ShaderObject { - GLuint glshader { 0 }; - GLuint glprogram { 0 }; - GLint transformCameraSlot { -1 }; - GLint transformObjectSlot { -1 }; -}; - -class GLShader : public GPUObject { -public: - static GLShader* sync(GLBackend& backend, const Shader& shader, const Shader::CompilationHandler& handler = nullptr); - static bool makeProgram(GLBackend& backend, Shader& shader, const Shader::BindingSet& slotBindings, const Shader::CompilationHandler& handler = nullptr); - - enum Version { - Mono = 0, - Stereo, - - NumVersions - }; - - using ShaderObject = gpu::gl::ShaderObject; - using ShaderObjects = std::array< ShaderObject, NumVersions >; - - using UniformMapping = std::map; - using UniformMappingVersions = std::vector; - - GLShader(const std::weak_ptr& backend); - ~GLShader(); - - ShaderObjects _shaderObjects; - UniformMappingVersions _uniformMappings; - - GLuint getProgram(Version version = Mono) const { - return _shaderObjects[version].glprogram; - } - - GLint getUniformLocation(GLint srcLoc, Version version = Mono) const { - // This check protect against potential invalid src location for this shader, if unknown then return -1. - const auto& mapping = _uniformMappings[version]; - auto found = mapping.find(srcLoc); - if (found == mapping.end()) { - return -1; - } - return found->second; - } - - const std::weak_ptr _backend; -}; - -} } - - -#endif diff --git a/libraries/gpu-gles/src/gpu/gl/GLShared.cpp b/libraries/gpu-gles/src/gpu/gl/GLShared.cpp deleted file mode 100644 index f818a221b2..0000000000 --- a/libraries/gpu-gles/src/gpu/gl/GLShared.cpp +++ /dev/null @@ -1,335 +0,0 @@ -// -// Created by Bradley Austin Davis on 2016/05/14 -// Copyright 2013-2016 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 "GLShared.h" - -#include - -#include - -#include -#include -#include - -Q_LOGGING_CATEGORY(gpugllogging, "hifi.gpu.gl") -Q_LOGGING_CATEGORY(trace_render_gpu_gl, "trace.render.gpu.gl") -Q_LOGGING_CATEGORY(trace_render_gpu_gl_detail, "trace.render.gpu.gl.detail") - -namespace gpu { namespace gl { - -bool checkGLError(const char* name) { - GLenum error = glGetError(); - if (!error) { - return false; - } else { - switch (error) { - case GL_INVALID_ENUM: - qCWarning(gpugllogging) << "GLBackend::" << name << ": An unacceptable value is specified for an enumerated argument.The offending command is ignored and has no other side effect than to set the error flag."; - break; - case GL_INVALID_VALUE: - qCWarning(gpugllogging) << "GLBackend" << name << ": A numeric argument is out of range.The offending command is ignored and has no other side effect than to set the error flag"; - break; - case GL_INVALID_OPERATION: - qCWarning(gpugllogging) << "GLBackend" << name << ": The specified operation is not allowed in the current state.The offending command is ignored and has no other side effect than to set the error flag.."; - break; - case GL_INVALID_FRAMEBUFFER_OPERATION: - qCWarning(gpugllogging) << "GLBackend" << name << ": The framebuffer object is not complete.The offending command is ignored and has no other side effect than to set the error flag."; - break; - case GL_OUT_OF_MEMORY: - qCWarning(gpugllogging) << "GLBackend" << name << ": There is not enough memory left to execute the command.The state of the GL is undefined, except for the state of the error flags, after this error is recorded."; - break; - case GL_STACK_UNDERFLOW: - qCWarning(gpugllogging) << "GLBackend" << name << ": An attempt has been made to perform an operation that would cause an internal stack to underflow."; - break; - case GL_STACK_OVERFLOW: - qCWarning(gpugllogging) << "GLBackend" << name << ": An attempt has been made to perform an operation that would cause an internal stack to overflow."; - break; - } - return true; - } -} - -bool checkGLErrorDebug(const char* name) { - // FIXME, disable in debug mode when near release - return checkGLError(name); -} - -gpu::Size getFreeDedicatedMemory() { - Size result { 0 }; - static bool nvidiaMemorySupported { false }; - static bool atiMemorySupported { false }; - if (nvidiaMemorySupported) { - - GLint nvGpuMemory { 0 }; - qDebug() << "TODO: GLShared.cpp getFreeDedicatedMemory GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX"; - //glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &nvGpuMemory); - if (GL_NO_ERROR == glGetError()) { - result = KB_TO_BYTES(nvGpuMemory); - } else { - nvidiaMemorySupported = false; - } - } else if (atiMemorySupported) { - GLint atiGpuMemory[4]; - qDebug() << "TODO: GLShared.cpp getFreeDedicatedMemory GL_TEXTURE_FREE_MEMORY_ATI"; - // not really total memory, but close enough if called early enough in the application lifecycle - //glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, atiGpuMemory); - if (GL_NO_ERROR == glGetError()) { - result = KB_TO_BYTES(atiGpuMemory[0]); - } else { - atiMemorySupported = false; - } - } - return result; -} - -ComparisonFunction comparisonFuncFromGL(GLenum func) { - if (func == GL_NEVER) { - return NEVER; - } else if (func == GL_LESS) { - return LESS; - } else if (func == GL_EQUAL) { - return EQUAL; - } else if (func == GL_LEQUAL) { - return LESS_EQUAL; - } else if (func == GL_GREATER) { - return GREATER; - } else if (func == GL_NOTEQUAL) { - return NOT_EQUAL; - } else if (func == GL_GEQUAL) { - return GREATER_EQUAL; - } else if (func == GL_ALWAYS) { - return ALWAYS; - } - - return ALWAYS; -} - -State::StencilOp stencilOpFromGL(GLenum stencilOp) { - if (stencilOp == GL_KEEP) { - return State::STENCIL_OP_KEEP; - } else if (stencilOp == GL_ZERO) { - return State::STENCIL_OP_ZERO; - } else if (stencilOp == GL_REPLACE) { - return State::STENCIL_OP_REPLACE; - } else if (stencilOp == GL_INCR_WRAP) { - return State::STENCIL_OP_INCR_SAT; - } else if (stencilOp == GL_DECR_WRAP) { - return State::STENCIL_OP_DECR_SAT; - } else if (stencilOp == GL_INVERT) { - return State::STENCIL_OP_INVERT; - } else if (stencilOp == GL_INCR) { - return State::STENCIL_OP_INCR; - } else if (stencilOp == GL_DECR) { - return State::STENCIL_OP_DECR; - } - - return State::STENCIL_OP_KEEP; -} - -State::BlendOp blendOpFromGL(GLenum blendOp) { - if (blendOp == GL_FUNC_ADD) { - return State::BLEND_OP_ADD; - } else if (blendOp == GL_FUNC_SUBTRACT) { - return State::BLEND_OP_SUBTRACT; - } else if (blendOp == GL_FUNC_REVERSE_SUBTRACT) { - return State::BLEND_OP_REV_SUBTRACT; - } else if (blendOp == GL_MIN) { - return State::BLEND_OP_MIN; - } else if (blendOp == GL_MAX) { - return State::BLEND_OP_MAX; - } - - return State::BLEND_OP_ADD; -} - -State::BlendArg blendArgFromGL(GLenum blendArg) { - if (blendArg == GL_ZERO) { - return State::ZERO; - } else if (blendArg == GL_ONE) { - return State::ONE; - } else if (blendArg == GL_SRC_COLOR) { - return State::SRC_COLOR; - } else if (blendArg == GL_ONE_MINUS_SRC_COLOR) { - return State::INV_SRC_COLOR; - } else if (blendArg == GL_DST_COLOR) { - return State::DEST_COLOR; - } else if (blendArg == GL_ONE_MINUS_DST_COLOR) { - return State::INV_DEST_COLOR; - } else if (blendArg == GL_SRC_ALPHA) { - return State::SRC_ALPHA; - } else if (blendArg == GL_ONE_MINUS_SRC_ALPHA) { - return State::INV_SRC_ALPHA; - } else if (blendArg == GL_DST_ALPHA) { - return State::DEST_ALPHA; - } else if (blendArg == GL_ONE_MINUS_DST_ALPHA) { - return State::INV_DEST_ALPHA; - } else if (blendArg == GL_CONSTANT_COLOR) { - return State::FACTOR_COLOR; - } else if (blendArg == GL_ONE_MINUS_CONSTANT_COLOR) { - return State::INV_FACTOR_COLOR; - } else if (blendArg == GL_CONSTANT_ALPHA) { - return State::FACTOR_ALPHA; - } else if (blendArg == GL_ONE_MINUS_CONSTANT_ALPHA) { - return State::INV_FACTOR_ALPHA; - } - - return State::ONE; -} - -void getCurrentGLState(State::Data& state) { - { - //GLint modes[2]; - //glGetIntegerv(GL_POLYGON_MODE, modes); - //if (modes[0] == GL_FILL) { - // state.fillMode = State::FILL_FACE; - //} else { - // if (modes[0] == GL_LINE) { - // state.fillMode = State::FILL_LINE; - // } else { - // state.fillMode = State::FILL_POINT; - // } - //} - } - { - if (glIsEnabled(GL_CULL_FACE)) { - GLint mode; - glGetIntegerv(GL_CULL_FACE_MODE, &mode); - state.cullMode = (mode == GL_FRONT ? State::CULL_FRONT : State::CULL_BACK); - } else { - state.cullMode = State::CULL_NONE; - } - } - { - GLint winding; - glGetIntegerv(GL_FRONT_FACE, &winding); - state.frontFaceClockwise = (winding == GL_CW); - state.depthClampEnable = false; //glIsEnabled(GL_DEPTH_CLAMP_EXT); - state.scissorEnable = glIsEnabled(GL_SCISSOR_TEST); - state.multisampleEnable = false; //glIsEnabled(GL_MULTISAMPLE_EXT); - state.antialisedLineEnable = false; //glIsEnabled(GL_LINE_SMOOTH); - } - { - if (glIsEnabled(GL_POLYGON_OFFSET_FILL)) { - glGetFloatv(GL_POLYGON_OFFSET_FACTOR, &state.depthBiasSlopeScale); - glGetFloatv(GL_POLYGON_OFFSET_UNITS, &state.depthBias); - } - } - { - GLboolean isEnabled = glIsEnabled(GL_DEPTH_TEST); - GLboolean writeMask; - glGetBooleanv(GL_DEPTH_WRITEMASK, &writeMask); - GLint func; - glGetIntegerv(GL_DEPTH_FUNC, &func); - - state.depthTest = State::DepthTest(isEnabled, writeMask, comparisonFuncFromGL(func)); - } - { - GLboolean isEnabled = glIsEnabled(GL_STENCIL_TEST); - - GLint frontWriteMask; - GLint frontReadMask; - GLint frontRef; - GLint frontFail; - GLint frontDepthFail; - GLint frontPass; - GLint frontFunc; - glGetIntegerv(GL_STENCIL_WRITEMASK, &frontWriteMask); - glGetIntegerv(GL_STENCIL_VALUE_MASK, &frontReadMask); - glGetIntegerv(GL_STENCIL_REF, &frontRef); - glGetIntegerv(GL_STENCIL_FAIL, &frontFail); - glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &frontDepthFail); - glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &frontPass); - glGetIntegerv(GL_STENCIL_FUNC, &frontFunc); - - GLint backWriteMask; - GLint backReadMask; - GLint backRef; - GLint backFail; - GLint backDepthFail; - GLint backPass; - GLint backFunc; - glGetIntegerv(GL_STENCIL_BACK_WRITEMASK, &backWriteMask); - glGetIntegerv(GL_STENCIL_BACK_VALUE_MASK, &backReadMask); - glGetIntegerv(GL_STENCIL_BACK_REF, &backRef); - glGetIntegerv(GL_STENCIL_BACK_FAIL, &backFail); - glGetIntegerv(GL_STENCIL_BACK_PASS_DEPTH_FAIL, &backDepthFail); - glGetIntegerv(GL_STENCIL_BACK_PASS_DEPTH_PASS, &backPass); - glGetIntegerv(GL_STENCIL_BACK_FUNC, &backFunc); - - state.stencilActivation = State::StencilActivation(isEnabled, frontWriteMask, backWriteMask); - state.stencilTestFront = State::StencilTest(frontRef, frontReadMask, comparisonFuncFromGL(frontFunc), stencilOpFromGL(frontFail), stencilOpFromGL(frontDepthFail), stencilOpFromGL(frontPass)); - state.stencilTestBack = State::StencilTest(backRef, backReadMask, comparisonFuncFromGL(backFunc), stencilOpFromGL(backFail), stencilOpFromGL(backDepthFail), stencilOpFromGL(backPass)); - } - { - GLint mask = 0xFFFFFFFF; - if (glIsEnabled(GL_SAMPLE_MASK)) { - glGetIntegerv(GL_SAMPLE_MASK, &mask); - state.sampleMask = mask; - } - state.sampleMask = mask; - } - { - state.alphaToCoverageEnable = glIsEnabled(GL_SAMPLE_ALPHA_TO_COVERAGE); - } - { - GLboolean isEnabled = glIsEnabled(GL_BLEND); - GLint srcRGB; - GLint srcA; - GLint dstRGB; - GLint dstA; - glGetIntegerv(GL_BLEND_SRC_RGB, &srcRGB); - glGetIntegerv(GL_BLEND_SRC_ALPHA, &srcA); - glGetIntegerv(GL_BLEND_DST_RGB, &dstRGB); - glGetIntegerv(GL_BLEND_DST_ALPHA, &dstA); - - GLint opRGB; - GLint opA; - glGetIntegerv(GL_BLEND_EQUATION_RGB, &opRGB); - glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &opA); - - state.blendFunction = State::BlendFunction(isEnabled, - blendArgFromGL(srcRGB), blendOpFromGL(opRGB), blendArgFromGL(dstRGB), - blendArgFromGL(srcA), blendOpFromGL(opA), blendArgFromGL(dstA)); - } - { - GLboolean mask[4]; - glGetBooleanv(GL_COLOR_WRITEMASK, mask); - state.colorWriteMask = (mask[0] ? State::WRITE_RED : 0) - | (mask[1] ? State::WRITE_GREEN : 0) - | (mask[2] ? State::WRITE_BLUE : 0) - | (mask[3] ? State::WRITE_ALPHA : 0); - } - - (void)CHECK_GL_ERROR(); -} - - -void serverWait() { - auto fence = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); - assert(fence); - glWaitSync(fence, 0, GL_TIMEOUT_IGNORED); - glDeleteSync(fence); -} - -void clientWait() { - auto fence = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); - assert(fence); - auto result = glClientWaitSync(fence, GL_SYNC_FLUSH_COMMANDS_BIT, 0); - while (GL_TIMEOUT_EXPIRED == result || GL_WAIT_FAILED == result) { - // Minimum sleep - QThread::usleep(1); - result = glClientWaitSync(fence, 0, 0); - } - glDeleteSync(fence); -} - -} } - - -using namespace gpu; - - diff --git a/libraries/gpu-gles/src/gpu/gl/GLShared.h b/libraries/gpu-gles/src/gpu/gl/GLShared.h deleted file mode 100644 index 1341dd16fa..0000000000 --- a/libraries/gpu-gles/src/gpu/gl/GLShared.h +++ /dev/null @@ -1,152 +0,0 @@ -// -// Created by Bradley Austin Davis on 2016/05/15 -// Copyright 2013-2016 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_GLShared_h -#define hifi_gpu_GLShared_h - -#include -#include - -#include -#include -#include -#include - - -Q_DECLARE_LOGGING_CATEGORY(gpugllogging) -Q_DECLARE_LOGGING_CATEGORY(trace_render_gpu_gl) -Q_DECLARE_LOGGING_CATEGORY(trace_render_gpu_gl_detail) - -#define BUFFER_OFFSET(bytes) ((GLubyte*) nullptr + (bytes)) - -namespace gpu { namespace gl { - -// Create a fence and inject a GPU wait on the fence -void serverWait(); - -// Create a fence and synchronously wait on the fence -void clientWait(); - -gpu::Size getFreeDedicatedMemory(); -ComparisonFunction comparisonFuncFromGL(GLenum func); -State::StencilOp stencilOpFromGL(GLenum stencilOp); -State::BlendOp blendOpFromGL(GLenum blendOp); -State::BlendArg blendArgFromGL(GLenum blendArg); -void getCurrentGLState(State::Data& state); - -enum GLSyncState { - // The object is currently undergoing no processing, although it's content - // may be out of date, or it's storage may be invalid relative to the - // owning GPU object - Idle, - // The object has been queued for transfer to the GPU - Pending, - // The object has been transferred to the GPU, but is awaiting - // any post transfer operations that may need to occur on the - // primary rendering thread - Transferred, -}; - -static const GLenum BLEND_OPS_TO_GL[State::NUM_BLEND_OPS] = { - GL_FUNC_ADD, - GL_FUNC_SUBTRACT, - GL_FUNC_REVERSE_SUBTRACT, - GL_MIN, - GL_MAX -}; - -static const GLenum BLEND_ARGS_TO_GL[State::NUM_BLEND_ARGS] = { - GL_ZERO, - GL_ONE, - GL_SRC_COLOR, - GL_ONE_MINUS_SRC_COLOR, - GL_SRC_ALPHA, - GL_ONE_MINUS_SRC_ALPHA, - GL_DST_ALPHA, - GL_ONE_MINUS_DST_ALPHA, - GL_DST_COLOR, - GL_ONE_MINUS_DST_COLOR, - GL_SRC_ALPHA_SATURATE, - GL_CONSTANT_COLOR, - GL_ONE_MINUS_CONSTANT_COLOR, - GL_CONSTANT_ALPHA, - GL_ONE_MINUS_CONSTANT_ALPHA, -}; - -static const GLenum COMPARISON_TO_GL[gpu::NUM_COMPARISON_FUNCS] = { - GL_NEVER, - GL_LESS, - GL_EQUAL, - GL_LEQUAL, - GL_GREATER, - GL_NOTEQUAL, - GL_GEQUAL, - GL_ALWAYS -}; - -static const GLenum PRIMITIVE_TO_GL[gpu::NUM_PRIMITIVES] = { - GL_POINTS, - GL_LINES, - GL_LINE_STRIP, - GL_TRIANGLES, - GL_TRIANGLE_STRIP, - GL_TRIANGLE_FAN, -}; - -static const GLenum ELEMENT_TYPE_TO_GL[gpu::NUM_TYPES] = { - GL_FLOAT, - GL_INT, - GL_UNSIGNED_INT, - GL_HALF_FLOAT, - GL_SHORT, - GL_UNSIGNED_SHORT, - GL_BYTE, - GL_UNSIGNED_BYTE, - // Normalized values - GL_INT, - GL_UNSIGNED_INT, - GL_SHORT, - GL_UNSIGNED_SHORT, - GL_BYTE, - GL_UNSIGNED_BYTE, - GL_UNSIGNED_BYTE, - GL_INT_2_10_10_10_REV, -}; - -bool checkGLError(const char* name = nullptr); -bool checkGLErrorDebug(const char* name = nullptr); - -class GLBackend; - -template -struct GLObject : public GPUObject { -public: - GLObject(const std::weak_ptr& backend, const GPUType& gpuObject, GLuint id) : _gpuObject(gpuObject), _id(id), _backend(backend) {} - - virtual ~GLObject() { } - - const GPUType& _gpuObject; - const GLuint _id; -protected: - const std::weak_ptr _backend; -}; - -class GlBuffer; -class GLFramebuffer; -class GLPipeline; -class GLQuery; -class GLState; -class GLShader; -class GLTexture; -struct ShaderObject; - -} } // namespace gpu::gl - -#endif - - - diff --git a/libraries/gpu-gles/src/gpu/gl/GLState.cpp b/libraries/gpu-gles/src/gpu/gl/GLState.cpp deleted file mode 100644 index b6d917b928..0000000000 --- a/libraries/gpu-gles/src/gpu/gl/GLState.cpp +++ /dev/null @@ -1,248 +0,0 @@ -// -// Created by Bradley Austin Davis on 2016/05/15 -// Copyright 2013-2016 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 defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic push -#if __GNUC__ >= 5 && __GNUC_MINOR__ >= 1 -#pragma GCC diagnostic ignored "-Wsuggest-override" -#endif -#endif - - -#include "GLState.h" - -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic pop -#endif - - -#include "GLBackend.h" - -using namespace gpu; -using namespace gpu::gl; - -typedef GLState::Command Command; -typedef GLState::CommandPointer CommandPointer; -typedef GLState::Command1 Command1U; -typedef GLState::Command1 Command1I; -typedef GLState::Command1 Command1B; -typedef GLState::Command1 CommandDepthBias; -typedef GLState::Command1 CommandDepthTest; -typedef GLState::Command3 CommandStencil; -typedef GLState::Command1 CommandBlend; - -const GLState::Commands makeResetStateCommands(); - -// NOTE: This must stay in sync with the ordering of the State::Field enum -const GLState::Commands makeResetStateCommands() { - // Since State::DEFAULT is a static defined in another .cpp the initialisation order is random - // and we have a 50/50 chance that State::DEFAULT is not yet initialized. - // Since State::DEFAULT = State::Data() it is much easier to not use the actual State::DEFAULT - // but another State::Data object with a default initialization. - const State::Data DEFAULT = State::Data(); - - auto depthBiasCommand = std::make_shared(&GLBackend::do_setStateDepthBias, - Vec2(DEFAULT.depthBias, DEFAULT.depthBiasSlopeScale)); - auto stencilCommand = std::make_shared(&GLBackend::do_setStateStencil, DEFAULT.stencilActivation, - DEFAULT.stencilTestFront, DEFAULT.stencilTestBack); - - // The state commands to reset to default, - // WARNING depending on the order of the State::Field enum - return { - std::make_shared(&GLBackend::do_setStateFillMode, DEFAULT.fillMode), - std::make_shared(&GLBackend::do_setStateCullMode, DEFAULT.cullMode), - std::make_shared(&GLBackend::do_setStateFrontFaceClockwise, DEFAULT.frontFaceClockwise), - std::make_shared(&GLBackend::do_setStateDepthClampEnable, DEFAULT.depthClampEnable), - std::make_shared(&GLBackend::do_setStateScissorEnable, DEFAULT.scissorEnable), - std::make_shared(&GLBackend::do_setStateMultisampleEnable, DEFAULT.multisampleEnable), - std::make_shared(&GLBackend::do_setStateAntialiasedLineEnable, DEFAULT.antialisedLineEnable), - - // Depth bias has 2 fields in State but really one call in GLBackend - CommandPointer(depthBiasCommand), - CommandPointer(depthBiasCommand), - - std::make_shared(&GLBackend::do_setStateDepthTest, DEFAULT.depthTest), - - // Depth bias has 3 fields in State but really one call in GLBackend - CommandPointer(stencilCommand), - CommandPointer(stencilCommand), - CommandPointer(stencilCommand), - - std::make_shared(&GLBackend::do_setStateSampleMask, DEFAULT.sampleMask), - - std::make_shared(&GLBackend::do_setStateAlphaToCoverageEnable, DEFAULT.alphaToCoverageEnable), - - std::make_shared(&GLBackend::do_setStateBlend, DEFAULT.blendFunction), - - std::make_shared(&GLBackend::do_setStateColorWriteMask, DEFAULT.colorWriteMask) - }; -} - -const GLState::Commands GLState::_resetStateCommands = makeResetStateCommands(); - - -void generateFillMode(GLState::Commands& commands, State::FillMode fillMode) { - commands.push_back(std::make_shared(&GLBackend::do_setStateFillMode, int32(fillMode))); -} - -void generateCullMode(GLState::Commands& commands, State::CullMode cullMode) { - commands.push_back(std::make_shared(&GLBackend::do_setStateCullMode, int32(cullMode))); -} - -void generateFrontFaceClockwise(GLState::Commands& commands, bool isClockwise) { - commands.push_back(std::make_shared(&GLBackend::do_setStateFrontFaceClockwise, isClockwise)); -} - -void generateDepthClampEnable(GLState::Commands& commands, bool enable) { - commands.push_back(std::make_shared(&GLBackend::do_setStateDepthClampEnable, enable)); -} - -void generateScissorEnable(GLState::Commands& commands, bool enable) { - commands.push_back(std::make_shared(&GLBackend::do_setStateScissorEnable, enable)); -} - -void generateMultisampleEnable(GLState::Commands& commands, bool enable) { - commands.push_back(std::make_shared(&GLBackend::do_setStateMultisampleEnable, enable)); -} - -void generateAntialiasedLineEnable(GLState::Commands& commands, bool enable) { - commands.push_back(std::make_shared(&GLBackend::do_setStateAntialiasedLineEnable, enable)); -} - -void generateDepthBias(GLState::Commands& commands, const State& state) { - commands.push_back(std::make_shared(&GLBackend::do_setStateDepthBias, Vec2(state.getDepthBias(), state.getDepthBiasSlopeScale()))); -} - -void generateDepthTest(GLState::Commands& commands, const State::DepthTest& test) { - commands.push_back(std::make_shared(&GLBackend::do_setStateDepthTest, int32(test.getRaw()))); -} - -void generateStencil(GLState::Commands& commands, const State& state) { - commands.push_back(std::make_shared(&GLBackend::do_setStateStencil, state.getStencilActivation(), state.getStencilTestFront(), state.getStencilTestBack())); -} - -void generateAlphaToCoverageEnable(GLState::Commands& commands, bool enable) { - commands.push_back(std::make_shared(&GLBackend::do_setStateAlphaToCoverageEnable, enable)); -} - -void generateSampleMask(GLState::Commands& commands, uint32 mask) { - commands.push_back(std::make_shared(&GLBackend::do_setStateSampleMask, mask)); -} - -void generateBlend(GLState::Commands& commands, const State& state) { - commands.push_back(std::make_shared(&GLBackend::do_setStateBlend, state.getBlendFunction())); -} - -void generateColorWriteMask(GLState::Commands& commands, uint32 mask) { - commands.push_back(std::make_shared(&GLBackend::do_setStateColorWriteMask, mask)); -} - -GLState* GLState::sync(const State& state) { - GLState* object = Backend::getGPUObject(state); - - // If GPU object already created then good - if (object) { - return object; - } - - // Else allocate and create the GLState - if (!object) { - object = new GLState(); - Backend::setGPUObject(state, object); - } - - // here, we need to regenerate something so let's do it all - object->_commands.clear(); - object->_stamp = state.getStamp(); - object->_signature = state.getSignature(); - - bool depthBias = false; - bool stencilState = false; - - // go thorugh the list of state fields in the State and record the corresponding gl command - for (int i = 0; i < State::NUM_FIELDS; i++) { - if (state.getSignature()[i]) { - switch (i) { - case State::FILL_MODE: { - generateFillMode(object->_commands, state.getFillMode()); - break; - } - case State::CULL_MODE: { - generateCullMode(object->_commands, state.getCullMode()); - break; - } - case State::DEPTH_BIAS: - case State::DEPTH_BIAS_SLOPE_SCALE: { - depthBias = true; - break; - } - case State::FRONT_FACE_CLOCKWISE: { - generateFrontFaceClockwise(object->_commands, state.isFrontFaceClockwise()); - break; - } - case State::DEPTH_CLAMP_ENABLE: { - generateDepthClampEnable(object->_commands, state.isDepthClampEnable()); - break; - } - case State::SCISSOR_ENABLE: { - generateScissorEnable(object->_commands, state.isScissorEnable()); - break; - } - case State::MULTISAMPLE_ENABLE: { - generateMultisampleEnable(object->_commands, state.isMultisampleEnable()); - break; - } - case State::ANTIALISED_LINE_ENABLE: { - generateAntialiasedLineEnable(object->_commands, state.isAntialiasedLineEnable()); - break; - } - case State::DEPTH_TEST: { - generateDepthTest(object->_commands, state.getDepthTest()); - break; - } - - case State::STENCIL_ACTIVATION: - case State::STENCIL_TEST_FRONT: - case State::STENCIL_TEST_BACK: { - stencilState = true; - break; - } - - case State::SAMPLE_MASK: { - generateSampleMask(object->_commands, state.getSampleMask()); - break; - } - case State::ALPHA_TO_COVERAGE_ENABLE: { - generateAlphaToCoverageEnable(object->_commands, state.isAlphaToCoverageEnabled()); - break; - } - - case State::BLEND_FUNCTION: { - generateBlend(object->_commands, state); - break; - } - - case State::COLOR_WRITE_MASK: { - generateColorWriteMask(object->_commands, state.getColorWriteMask()); - break; - } - } - } - } - - if (depthBias) { - generateDepthBias(object->_commands, state); - } - - if (stencilState) { - generateStencil(object->_commands, state); - } - - return object; -} - diff --git a/libraries/gpu-gles/src/gpu/gl/GLState.h b/libraries/gpu-gles/src/gpu/gl/GLState.h deleted file mode 100644 index 82635db893..0000000000 --- a/libraries/gpu-gles/src/gpu/gl/GLState.h +++ /dev/null @@ -1,73 +0,0 @@ -// -// Created by Bradley Austin Davis on 2016/05/15 -// Copyright 2013-2016 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_gl_GLState_h -#define hifi_gpu_gl_GLState_h - -#include "GLShared.h" - -#include - -namespace gpu { namespace gl { - -class GLBackend; -class GLState : public GPUObject { -public: - static GLState* sync(const State& state); - - class Command { - public: - virtual void run(GLBackend* backend) = 0; - Command() {} - virtual ~Command() {}; - }; - - template class Command1 : public Command { - public: - typedef void (GLBackend::*GLFunction)(T); - void run(GLBackend* backend) { (backend->*(_func))(_param); } - Command1(GLFunction func, T param) : _func(func), _param(param) {}; - GLFunction _func; - T _param; - }; - template class Command2 : public Command { - public: - typedef void (GLBackend::*GLFunction)(T, U); - void run(GLBackend* backend) { (backend->*(_func))(_param0, _param1); } - Command2(GLFunction func, T param0, U param1) : _func(func), _param0(param0), _param1(param1) {}; - GLFunction _func; - T _param0; - U _param1; - }; - - template class Command3 : public Command { - public: - typedef void (GLBackend::*GLFunction)(T, U, V); - void run(GLBackend* backend) { (backend->*(_func))(_param0, _param1, _param2); } - Command3(GLFunction func, T param0, U param1, V param2) : _func(func), _param0(param0), _param1(param1), _param2(param2) {}; - GLFunction _func; - T _param0; - U _param1; - V _param2; - }; - - typedef std::shared_ptr< Command > CommandPointer; - typedef std::vector< CommandPointer > Commands; - - Commands _commands; - Stamp _stamp; - State::Signature _signature; - - // The state commands to reset to default, - static const Commands _resetStateCommands; - - friend class GLBackend; -}; - -} } - -#endif diff --git a/libraries/gpu-gles/src/gpu/gl/GLTexelFormat.cpp b/libraries/gpu-gles/src/gpu/gl/GLTexelFormat.cpp deleted file mode 100644 index 2a39901ee7..0000000000 --- a/libraries/gpu-gles/src/gpu/gl/GLTexelFormat.cpp +++ /dev/null @@ -1,652 +0,0 @@ -// -// Created by Bradley Austin Davis on 2016/05/15 -// Copyright 2013-2016 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 "GLTexelFormat.h" - -using namespace gpu; -using namespace gpu::gl; - -bool GLTexelFormat::isCompressed() const { - switch (internalFormat) { - case GL_COMPRESSED_R11_EAC: - case GL_COMPRESSED_SIGNED_R11_EAC: - case GL_COMPRESSED_RG11_EAC: - case GL_COMPRESSED_SIGNED_RG11_EAC: - case GL_COMPRESSED_RGB8_ETC2: - case GL_COMPRESSED_SRGB8_ETC2: - case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: - case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: - case GL_COMPRESSED_RGBA8_ETC2_EAC: - case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: - case GL_COMPRESSED_RGBA_ASTC_4x4: - case GL_COMPRESSED_RGBA_ASTC_5x4: - case GL_COMPRESSED_RGBA_ASTC_5x5: - case GL_COMPRESSED_RGBA_ASTC_6x5: - case GL_COMPRESSED_RGBA_ASTC_6x6: - case GL_COMPRESSED_RGBA_ASTC_8x5: - case GL_COMPRESSED_RGBA_ASTC_8x6: - case GL_COMPRESSED_RGBA_ASTC_8x8: - case GL_COMPRESSED_RGBA_ASTC_10x5: - case GL_COMPRESSED_RGBA_ASTC_10x6: - case GL_COMPRESSED_RGBA_ASTC_10x8: - case GL_COMPRESSED_RGBA_ASTC_10x10: - case GL_COMPRESSED_RGBA_ASTC_12x10: - case GL_COMPRESSED_RGBA_ASTC_12x12: - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4: - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4: - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5: - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5: - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6: - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5: - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6: - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8: - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5: - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6: - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8: - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10: - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10: - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12: - return true; - default: - return false; - } -} - -GLenum GLTexelFormat::evalGLTexelFormatInternal(const gpu::Element& dstFormat) { - GLenum result = GL_RGBA8; - switch (dstFormat.getDimension()) { - case gpu::SCALAR: { - switch (dstFormat.getSemantic()) { - case gpu::RED: - case gpu::RGB: - case gpu::RGBA: - case gpu::SRGB: - case gpu::SRGBA: - switch (dstFormat.getType()) { - case gpu::UINT32: - result = GL_R32UI; - break; - case gpu::INT32: - result = GL_R32I; - break; - case gpu::NUINT32: - result = GL_R8; - break; - case gpu::NINT32: - result = GL_R8_SNORM; - break; - case gpu::FLOAT: - result = GL_R32F; - break; - case gpu::UINT16: - result = GL_R16UI; - break; - case gpu::INT16: - result = GL_R16I; - break; - case gpu::NUINT16: - //result = GL_R16_EXT; - break; - case gpu::NINT16: - //result = GL_R16_SNORM_EXT; - break; - case gpu::HALF: - result = GL_R16F; - break; - case gpu::UINT8: - result = GL_R8UI; - break; - case gpu::INT8: - result = GL_R8I; - break; - case gpu::NUINT8: - if ((dstFormat.getSemantic() == gpu::SRGB || dstFormat.getSemantic() == gpu::SRGBA)) { - result = GL_SLUMINANCE8_NV; - } else { - result = GL_R8; - } - break; - case gpu::NINT8: - result = GL_R8_SNORM; - break; - default: - Q_UNREACHABLE(); - break; - } - break; - case gpu::R11G11B10: - // the type should be float - result = GL_R11F_G11F_B10F; - break; - case gpu::RGB9E5: - // the type should be float - result = GL_RGB9_E5; - break; - case gpu::DEPTH: - result = GL_DEPTH_COMPONENT16; - switch (dstFormat.getType()) { - case gpu::UINT32: - case gpu::INT32: - case gpu::NUINT32: - case gpu::NINT32: - result = GL_DEPTH_COMPONENT32_OES; - break; - case gpu::FLOAT: - result = GL_DEPTH_COMPONENT32F; - break; - case gpu::UINT16: - case gpu::INT16: - case gpu::NUINT16: - case gpu::NINT16: - case gpu::HALF: - result = GL_DEPTH_COMPONENT16; - break; - case gpu::UINT8: - case gpu::INT8: - case gpu::NUINT8: - case gpu::NINT8: - result = GL_DEPTH_COMPONENT24; - break; - default: - Q_UNREACHABLE(); - break; - } - break; - - case gpu::DEPTH_STENCIL: - result = GL_DEPTH24_STENCIL8; - break; - - default: - qCWarning(gpugllogging) << "Unknown combination of texel format"; - } - break; - } - - case gpu::VEC2: { - switch (dstFormat.getSemantic()) { - case gpu::RGB: - case gpu::RGBA: - case gpu::XY: - result = GL_RG8; - break; - default: - qCWarning(gpugllogging) << "Unknown combination of texel format"; - } - - break; - } - - case gpu::VEC3: { - switch (dstFormat.getSemantic()) { - case gpu::RGB: - case gpu::RGBA: - result = GL_RGB8; - break; - case gpu::SRGB: - case gpu::SRGBA: - result = GL_SRGB8; // standard 2.2 gamma correction color - break; - default: - qCWarning(gpugllogging) << "Unknown combination of texel format"; - } - - break; - } - - case gpu::VEC4: { - switch (dstFormat.getSemantic()) { - case gpu::RGB: - result = GL_RGB8; - break; - case gpu::RGBA: - switch (dstFormat.getType()) { - case gpu::UINT32: - result = GL_RGBA32UI; - break; - case gpu::INT32: - result = GL_RGBA32I; - break; - case gpu::FLOAT: - result = GL_RGBA32F; - break; - case gpu::UINT16: - result = GL_RGBA16UI; - break; - case gpu::INT16: - result = GL_RGBA16I; - break; - case gpu::NUINT16: - //result = GL_RGBA16_EXT; - break; - case gpu::NINT16: - //result = GL_RGBA16_SNORM_EXT; - break; - case gpu::HALF: - result = GL_RGBA16F; - break; - case gpu::UINT8: - result = GL_RGBA8UI; - break; - case gpu::INT8: - result = GL_RGBA8I; - break; - case gpu::NUINT8: - result = GL_RGBA8; - break; - case gpu::NUINT2: - //result = GL_RGBA2; - break; - case gpu::NINT8: - result = GL_RGBA8_SNORM; - break; - case gpu::NINT2_10_10_10: - case gpu::NUINT32: - case gpu::NINT32: - case gpu::COMPRESSED: - case gpu::NUM_TYPES: // quiet compiler - Q_UNREACHABLE(); - } - break; - case gpu::SRGB: - result = GL_SRGB8; - break; - case gpu::SRGBA: - result = GL_SRGB8_ALPHA8; // standard 2.2 gamma correction color - break; - default: - qCWarning(gpugllogging) << "Unknown combination of texel format"; - } - break; - } - default: - qCDebug(gpugllogging) << "Unknown combination of texel format"; - } - - //qDebug() << "GLTexelFormat::evalGLTexelFormatInternal result " << result; - return result; -} - -GLTexelFormat GLTexelFormat::evalGLTexelFormat(const Element& dstFormat, const Element& srcFormat) { - - if (dstFormat != srcFormat) { - GLTexelFormat texel = { GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE }; - - switch (dstFormat.getDimension()) { - case gpu::SCALAR: { - texel.format = GL_RED; - texel.type = ELEMENT_TYPE_TO_GL[dstFormat.getType()]; - - switch (dstFormat.getSemantic()) { - case gpu::RED: - case gpu::RGB: - case gpu::RGBA: - texel.internalFormat = GL_R8; - break; - - case gpu::DEPTH: - texel.format = GL_DEPTH_COMPONENT; - texel.internalFormat = GL_DEPTH_COMPONENT32F; - break; - case gpu::DEPTH_STENCIL: - texel.type = GL_UNSIGNED_INT_24_8; - texel.format = GL_DEPTH_STENCIL; - texel.internalFormat = GL_DEPTH24_STENCIL8; - break; - default: - qCWarning(gpugllogging) << "Unknown combination of texel format"; - } - break; - } - - case gpu::VEC2: { - texel.format = GL_RG; - texel.type = ELEMENT_TYPE_TO_GL[dstFormat.getType()]; - - switch (dstFormat.getSemantic()) { - case gpu::RGB: - case gpu::RGBA: - case gpu::XY: - texel.internalFormat = GL_RG8; - break; - default: - qCWarning(gpugllogging) << "Unknown combination of texel format"; - } - - break; - } - - case gpu::VEC3: { - texel.format = GL_RGB; - - texel.type = ELEMENT_TYPE_TO_GL[dstFormat.getType()]; - - switch (dstFormat.getSemantic()) { - case gpu::RGB: - case gpu::RGBA: - texel.internalFormat = GL_RGB8; - break; - default: - qCWarning(gpugllogging) << "Unknown combination of texel format"; - } - - break; - } - - case gpu::VEC4: { - texel.format = GL_RGBA; - texel.type = ELEMENT_TYPE_TO_GL[dstFormat.getType()]; - - switch (srcFormat.getSemantic()) { - case gpu::BGRA: - case gpu::SBGRA: - texel.format = GL_RGBA; // GL_BGRA_EXT; - break; - case gpu::RGB: - case gpu::RGBA: - case gpu::SRGB: - case gpu::SRGBA: - default: - break; - }; - - switch (dstFormat.getSemantic()) { - case gpu::RGB: - texel.internalFormat = GL_RGB8; - break; - case gpu::RGBA: - texel.internalFormat = GL_RGBA8; - break; - case gpu::SRGB: - texel.internalFormat = GL_SRGB8; - break; - case gpu::SRGBA: - texel.internalFormat = GL_SRGB8_ALPHA8; - break; - default: - qCWarning(gpugllogging) << "Unknown combination of texel format"; - } - break; - } - - default: - qCWarning(gpugllogging) << "Unknown combination of texel format"; - } - return texel; - } else { - GLTexelFormat texel = { GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE }; - - switch (dstFormat.getDimension()) { - case gpu::SCALAR: { - texel.format = GL_RED; - texel.type = ELEMENT_TYPE_TO_GL[dstFormat.getType()]; - - switch (dstFormat.getSemantic()) { - - case gpu::RED: - case gpu::RGB: - case gpu::RGBA: - case gpu::SRGB: - case gpu::SRGBA: - texel.internalFormat = GL_RED; - switch (dstFormat.getType()) { - case gpu::UINT32: { - texel.internalFormat = GL_R32UI; - break; - } - case gpu::INT32: { - texel.internalFormat = GL_R32I; - break; - } - case gpu::NUINT32: { - texel.internalFormat = GL_R8; - break; - } - case gpu::NINT32: { - texel.internalFormat = GL_R8_SNORM; - break; - } - case gpu::FLOAT: { - texel.internalFormat = GL_R32F; - break; - } - case gpu::UINT16: { - texel.internalFormat = GL_R16UI; - break; - } - case gpu::INT16: { - texel.internalFormat = GL_R16I; - break; - } - case gpu::NUINT16: { - texel.internalFormat = GL_R16_EXT; - break; - } - case gpu::NINT16: { - texel.internalFormat = GL_R16_SNORM_EXT; - break; - } - case gpu::HALF: { - texel.internalFormat = GL_R16F; - break; - } - case gpu::UINT8: { - texel.internalFormat = GL_R8UI; - break; - } - case gpu::INT8: { - texel.internalFormat = GL_R8I; - break; - } - case gpu::NUINT8: { - if ((dstFormat.getSemantic() == gpu::SRGB || dstFormat.getSemantic() == gpu::SRGBA)) { - texel.internalFormat = GL_SLUMINANCE8_NV; - } else { - texel.internalFormat = GL_R8; - } - break; - } - case gpu::NINT8: { - texel.internalFormat = GL_R8_SNORM; - break; - } - case gpu::COMPRESSED: - case gpu::NUINT2: - case gpu::NUM_TYPES: { // quiet compiler - Q_UNREACHABLE(); - } - - } - break; - - case gpu::R11G11B10: - texel.format = GL_RGB; - texel.type = GL_UNSIGNED_INT_10F_11F_11F_REV; - texel.internalFormat = GL_R11F_G11F_B10F; - break; - - case gpu::RGB9E5: - texel.format = GL_RGB; - texel.type = GL_UNSIGNED_INT_5_9_9_9_REV; - texel.internalFormat = GL_RGB9_E5; - break; - - case gpu::DEPTH: - texel.format = GL_DEPTH_COMPONENT; // It's depth component to load it - texel.internalFormat = GL_DEPTH_COMPONENT32_OES; - switch (dstFormat.getType()) { - case gpu::UINT32: - case gpu::INT32: - case gpu::NUINT32: - case gpu::NINT32: { - texel.internalFormat = GL_DEPTH_COMPONENT32_OES; - break; - } - case gpu::FLOAT: { - texel.internalFormat = GL_DEPTH_COMPONENT32F; - break; - } - case gpu::UINT16: - case gpu::INT16: - case gpu::NUINT16: - case gpu::NINT16: - case gpu::HALF: { - texel.internalFormat = GL_DEPTH_COMPONENT16; - break; - } - case gpu::UINT8: - case gpu::INT8: - case gpu::NUINT8: - case gpu::NINT8: { - texel.internalFormat = GL_DEPTH_COMPONENT24; - break; - } - case gpu::COMPRESSED: - case gpu::NUINT2: - case gpu::NINT2_10_10_10: - case gpu::NUM_TYPES: { // quiet compiler - Q_UNREACHABLE(); - } - } - break; - case gpu::DEPTH_STENCIL: - texel.type = GL_UNSIGNED_INT_24_8; - texel.format = GL_DEPTH_STENCIL; - texel.internalFormat = GL_DEPTH24_STENCIL8; - break; - default: - qCWarning(gpugllogging) << "Unknown combination of texel format"; - } - - break; - } - - case gpu::VEC2: { - texel.format = GL_RG; - texel.type = ELEMENT_TYPE_TO_GL[dstFormat.getType()]; - - switch (dstFormat.getSemantic()) { - case gpu::RGB: - case gpu::RGBA: - case gpu::XY: - texel.internalFormat = GL_RG8; - break; - default: - qCWarning(gpugllogging) << "Unknown combination of texel format"; - } - - break; - } - - case gpu::VEC3: { - texel.format = GL_RGB; - - texel.type = ELEMENT_TYPE_TO_GL[dstFormat.getType()]; - - switch (dstFormat.getSemantic()) { - case gpu::RGB: - case gpu::RGBA: - texel.internalFormat = GL_RGB8; - break; - case gpu::SRGB: - case gpu::SRGBA: - texel.internalFormat = GL_SRGB8; // standard 2.2 gamma correction color - break; - default: - qCWarning(gpugllogging) << "Unknown combination of texel format"; - } - break; - } - - case gpu::VEC4: { - texel.format = GL_RGBA; - texel.type = ELEMENT_TYPE_TO_GL[dstFormat.getType()]; - - switch (dstFormat.getSemantic()) { - case gpu::RGB: - texel.internalFormat = GL_RGB8; - break; - case gpu::RGBA: - texel.internalFormat = GL_RGBA8; - switch (dstFormat.getType()) { - case gpu::UINT32: - texel.format = GL_RGBA_INTEGER; - texel.internalFormat = GL_RGBA32UI; - break; - case gpu::INT32: - texel.format = GL_RGBA_INTEGER; - texel.internalFormat = GL_RGBA32I; - break; - case gpu::FLOAT: - texel.internalFormat = GL_RGBA32F; - break; - case gpu::UINT16: - texel.format = GL_RGBA_INTEGER; - texel.internalFormat = GL_RGBA16UI; - break; - case gpu::INT16: - texel.format = GL_RGBA_INTEGER; - texel.internalFormat = GL_RGBA16I; - break; - case gpu::NUINT16: - texel.format = GL_RGBA; - //texel.internalFormat = GL_RGBA16_EXT; - break; - case gpu::NINT16: - texel.format = GL_RGBA; - //texel.internalFormat = GL_RGBA16_SNORM_EXT; - break; - case gpu::HALF: - texel.format = GL_RGBA; - texel.internalFormat = GL_RGBA16F; - break; - case gpu::UINT8: - texel.format = GL_RGBA_INTEGER; - texel.internalFormat = GL_RGBA8UI; - break; - case gpu::INT8: - texel.format = GL_RGBA_INTEGER; - texel.internalFormat = GL_RGBA8I; - break; - case gpu::NUINT8: - texel.format = GL_RGBA; - texel.internalFormat = GL_RGBA8; - break; - case gpu::NINT8: - texel.format = GL_RGBA; - texel.internalFormat = GL_RGBA8_SNORM; - break; - case gpu::NUINT2: - texel.format = GL_RGBA; - texel.internalFormat = GL_RGBA8; - break; - case gpu::NUINT32: - case gpu::NINT32: - case gpu::NINT2_10_10_10: - case gpu::COMPRESSED: - case gpu::NUM_TYPES: // quiet compiler - Q_UNREACHABLE(); - } - break; - case gpu::SRGB: - texel.internalFormat = GL_SRGB8; - break; - case gpu::SRGBA: - texel.internalFormat = GL_SRGB8_ALPHA8; // standard 2.2 gamma correction color - break; - default: - qCWarning(gpugllogging) << "Unknown combination of texel format"; - } - break; - } - default: - qCDebug(gpugllogging) << "Unknown combination of texel format"; - } - return texel; - } -} diff --git a/libraries/gpu-gles/src/gpu/gl/GLTexelFormat.h b/libraries/gpu-gles/src/gpu/gl/GLTexelFormat.h deleted file mode 100644 index 8f37f6b604..0000000000 --- a/libraries/gpu-gles/src/gpu/gl/GLTexelFormat.h +++ /dev/null @@ -1,37 +0,0 @@ -// -// Created by Bradley Austin Davis on 2016/05/15 -// Copyright 2013-2016 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_gl_GLTexelFormat_h -#define hifi_gpu_gl_GLTexelFormat_h - -#include "GLShared.h" - -namespace gpu { namespace gl { - -class GLTexelFormat { -public: - GLenum internalFormat; - GLenum format; - GLenum type; - - GLTexelFormat(GLenum glinternalFormat, GLenum glformat, GLenum gltype) : internalFormat(glinternalFormat), format(glformat), type(gltype) {} - GLTexelFormat(GLenum glinternalFormat) : internalFormat(glinternalFormat) {} - - bool isCompressed() const; - - static GLTexelFormat evalGLTexelFormat(const Element& dstFormat) { - return evalGLTexelFormat(dstFormat, dstFormat); - } - static GLenum evalGLTexelFormatInternal(const Element& dstFormat); - - static GLTexelFormat evalGLTexelFormat(const Element& dstFormat, const Element& srcFormat); -}; - -} } - - -#endif diff --git a/libraries/gpu-gles/src/gpu/gl/GLTexture.cpp b/libraries/gpu-gles/src/gpu/gl/GLTexture.cpp deleted file mode 100644 index 08b3f87094..0000000000 --- a/libraries/gpu-gles/src/gpu/gl/GLTexture.cpp +++ /dev/null @@ -1,701 +0,0 @@ -// -// Created by Bradley Austin Davis on 2016/05/15 -// Copyright 2013-2016 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 "GLTexture.h" - -#include -#include - -#include "GLBackend.h" - -using namespace gpu; -using namespace gpu::gl; - - -const GLenum GLTexture::CUBE_FACE_LAYOUT[GLTexture::TEXTURE_CUBE_NUM_FACES] = { - GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, - GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, - GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z -}; - - -const GLenum GLTexture::WRAP_MODES[Sampler::NUM_WRAP_MODES] = { - GL_REPEAT, // WRAP_REPEAT, - GL_MIRRORED_REPEAT, // WRAP_MIRROR, - GL_CLAMP_TO_EDGE, // WRAP_CLAMP, - GL_CLAMP_TO_BORDER, // WRAP_BORDER, - GL_MIRRORED_REPEAT //GL_MIRROR_CLAMP_TO_EDGE_EXT // WRAP_MIRROR_ONCE, -}; - -const GLFilterMode GLTexture::FILTER_MODES[Sampler::NUM_FILTERS] = { - { GL_NEAREST, GL_NEAREST }, //FILTER_MIN_MAG_POINT, - { GL_NEAREST, GL_LINEAR }, //FILTER_MIN_POINT_MAG_LINEAR, - { GL_LINEAR, GL_NEAREST }, //FILTER_MIN_LINEAR_MAG_POINT, - { GL_LINEAR, GL_LINEAR }, //FILTER_MIN_MAG_LINEAR, - - { GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST }, //FILTER_MIN_MAG_MIP_POINT, - { GL_NEAREST_MIPMAP_LINEAR, GL_NEAREST }, //FILTER_MIN_MAG_POINT_MIP_LINEAR, - { GL_NEAREST_MIPMAP_NEAREST, GL_LINEAR }, //FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT, - { GL_NEAREST_MIPMAP_LINEAR, GL_LINEAR }, //FILTER_MIN_POINT_MAG_MIP_LINEAR, - { GL_LINEAR_MIPMAP_NEAREST, GL_NEAREST }, //FILTER_MIN_LINEAR_MAG_MIP_POINT, - { GL_LINEAR_MIPMAP_LINEAR, GL_NEAREST }, //FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR, - { GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR }, //FILTER_MIN_MAG_LINEAR_MIP_POINT, - { GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR }, //FILTER_MIN_MAG_MIP_LINEAR, - { GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR } //FILTER_ANISOTROPIC, -}; - -GLenum GLTexture::getGLTextureType(const Texture& texture) { - switch (texture.getType()) { - case Texture::TEX_2D: - return GL_TEXTURE_2D; - break; - - case Texture::TEX_CUBE: - return GL_TEXTURE_CUBE_MAP; - break; - - default: - qFatal("Unsupported texture type"); - } - Q_UNREACHABLE(); - return GL_TEXTURE_2D; -} - -uint8_t GLTexture::getFaceCount(GLenum target) { - switch (target) { - case GL_TEXTURE_2D: - return TEXTURE_2D_NUM_FACES; - case GL_TEXTURE_CUBE_MAP: - return TEXTURE_CUBE_NUM_FACES; - default: - Q_UNREACHABLE(); - break; - } -} - -const std::vector& GLTexture::getFaceTargets(GLenum target) { - static std::vector cubeFaceTargets { - GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, - GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, - GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z - }; - static std::vector faceTargets { - GL_TEXTURE_2D - }; - switch (target) { - case GL_TEXTURE_2D: - return faceTargets; - case GL_TEXTURE_CUBE_MAP: - return cubeFaceTargets; - default: - Q_UNREACHABLE(); - break; - } - Q_UNREACHABLE(); - return faceTargets; -} - -GLTexture::GLTexture(const std::weak_ptr& backend, const Texture& texture, GLuint id) : - GLObject(backend, texture, id), - _source(texture.source()), - _target(getGLTextureType(texture)), - _texelFormat(GLTexelFormat::evalGLTexelFormatInternal(texture.getTexelFormat())) -{ - Backend::setGPUObject(texture, this); -} - -GLTexture::~GLTexture() { - auto backend = _backend.lock(); - if (backend && _id) { - backend->releaseTexture(_id, 0); - } -} - -Size GLTexture::copyMipFaceFromTexture(uint16_t sourceMip, uint16_t targetMip, uint8_t face) const { - if (!_gpuObject.isStoredMipFaceAvailable(sourceMip)) { - return 0; - } - auto dim = _gpuObject.evalMipDimensions(sourceMip); - auto mipData = _gpuObject.accessStoredMipFace(sourceMip, face); - auto mipSize = _gpuObject.getStoredMipFaceSize(sourceMip, face); - if (mipData) { - GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat(), _gpuObject.getStoredMipFormat()); - return copyMipFaceLinesFromTexture(targetMip, face, dim, 0, texelFormat.internalFormat, texelFormat.format, texelFormat.type, mipSize, mipData->readData()); - } else { - qCDebug(gpugllogging) << "Missing mipData level=" << sourceMip << " face=" << (int)face << " for texture " << _gpuObject.source().c_str(); - } - return 0; -} - - -GLExternalTexture::GLExternalTexture(const std::weak_ptr& backend, const Texture& texture, GLuint id) - : Parent(backend, texture, id) { - Backend::textureExternalCount.increment(); -} - -GLExternalTexture::~GLExternalTexture() { - auto backend = _backend.lock(); - if (backend) { - auto recycler = _gpuObject.getExternalRecycler(); - if (recycler) { - backend->releaseExternalTexture(_id, recycler); - } else { - qCWarning(gpugllogging) << "No recycler available for texture " << _id << " possible leak"; - } - const_cast(_id) = 0; - } - Backend::textureExternalCount.decrement(); -} - - -// Variable sized textures -using MemoryPressureState = GLVariableAllocationSupport::MemoryPressureState; -using WorkQueue = GLVariableAllocationSupport::WorkQueue; -using TransferJobPointer = GLVariableAllocationSupport::TransferJobPointer; - -std::list GLVariableAllocationSupport::_memoryManagedTextures; -MemoryPressureState GLVariableAllocationSupport::_memoryPressureState { MemoryPressureState::Idle }; -std::atomic GLVariableAllocationSupport::_memoryPressureStateStale { false }; -const uvec3 GLVariableAllocationSupport::INITIAL_MIP_TRANSFER_DIMENSIONS { 64, 64, 1 }; -WorkQueue GLVariableAllocationSupport::_transferQueue; -WorkQueue GLVariableAllocationSupport::_promoteQueue; -WorkQueue GLVariableAllocationSupport::_demoteQueue; -size_t GLVariableAllocationSupport::_frameTexturesCreated { 0 }; - -#define OVERSUBSCRIBED_PRESSURE_VALUE 0.95f -#define UNDERSUBSCRIBED_PRESSURE_VALUE 0.85f -#define DEFAULT_ALLOWED_TEXTURE_MEMORY_MB ((size_t)1024) - -static const size_t DEFAULT_ALLOWED_TEXTURE_MEMORY = MB_TO_BYTES(DEFAULT_ALLOWED_TEXTURE_MEMORY_MB); - -using TransferJob = GLVariableAllocationSupport::TransferJob; - -const uvec3 GLVariableAllocationSupport::MAX_TRANSFER_DIMENSIONS { 1024, 1024, 1 }; -const size_t GLVariableAllocationSupport::MAX_TRANSFER_SIZE = GLVariableAllocationSupport::MAX_TRANSFER_DIMENSIONS.x * GLVariableAllocationSupport::MAX_TRANSFER_DIMENSIONS.y * 4; - -#if THREADED_TEXTURE_BUFFERING - -TexturePointer GLVariableAllocationSupport::_currentTransferTexture; -TransferJobPointer GLVariableAllocationSupport::_currentTransferJob; -QThreadPool* TransferJob::_bufferThreadPool { nullptr }; - -void TransferJob::startBufferingThread() { - static std::once_flag once; - std::call_once(once, [&] { - _bufferThreadPool = new QThreadPool(qApp); - _bufferThreadPool->setMaxThreadCount(1); - }); -} - -#endif - -TransferJob::TransferJob(const GLTexture& parent, uint16_t sourceMip, uint16_t targetMip, uint8_t face, uint32_t lines, uint32_t lineOffset) - : _parent(parent) { - - auto transferDimensions = _parent._gpuObject.evalMipDimensions(sourceMip); - GLenum format; - GLenum internalFormat; - GLenum type; - GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_parent._gpuObject.getTexelFormat(), _parent._gpuObject.getStoredMipFormat()); - format = texelFormat.format; - internalFormat = texelFormat.internalFormat; - type = texelFormat.type; - _transferSize = _parent._gpuObject.getStoredMipFaceSize(sourceMip, face); - - // If we're copying a subsection of the mip, do additional calculations to find the size and offset of the segment - if (0 != lines) { - transferDimensions.y = lines; - auto dimensions = _parent._gpuObject.evalMipDimensions(sourceMip); - auto bytesPerLine = (uint32_t)_transferSize / dimensions.y; - _transferOffset = bytesPerLine * lineOffset; - _transferSize = bytesPerLine * lines; - } - - Backend::texturePendingGPUTransferMemSize.update(0, _transferSize); - - if (_transferSize > GLVariableAllocationSupport::MAX_TRANSFER_SIZE) { - qCWarning(gpugllogging) << "Transfer size of " << _transferSize << " exceeds theoretical maximum transfer size"; - } - - // Buffering can invoke disk IO, so it should be off of the main and render threads - _bufferingLambda = [=] { - auto mipStorage = _parent._gpuObject.accessStoredMipFace(sourceMip, face); - if (mipStorage) { - _mipData = mipStorage->createView(_transferSize, _transferOffset); - } else { - qCWarning(gpugllogging) << "Buffering failed because mip could not be retrieved from texture " << _parent._source.c_str() ; - } - }; - - _transferLambda = [=] { - if (_mipData) { - _parent.copyMipFaceLinesFromTexture(targetMip, face, transferDimensions, lineOffset, internalFormat, format, type, _mipData->size(), _mipData->readData()); - _mipData.reset(); - } else { - qCWarning(gpugllogging) << "Transfer failed because mip could not be retrieved from texture " << _parent._source.c_str(); - } - }; -} - -TransferJob::TransferJob(const GLTexture& parent, std::function transferLambda) - : _parent(parent), _bufferingRequired(false), _transferLambda(transferLambda) { -} - -TransferJob::~TransferJob() { - Backend::texturePendingGPUTransferMemSize.update(_transferSize, 0); -} - -bool TransferJob::tryTransfer() { -#if THREADED_TEXTURE_BUFFERING - // Are we ready to transfer - if (!bufferingCompleted()) { - startBuffering(); - return false; - } -#else - if (_bufferingRequired) { - _bufferingLambda(); - } -#endif - _transferLambda(); - return true; -} - -#if THREADED_TEXTURE_BUFFERING -bool TransferJob::bufferingRequired() const { - if (!_bufferingRequired) { - return false; - } - - // The default state of a QFuture is with status Canceled | Started | Finished, - // so we have to check isCancelled before we check the actual state - if (_bufferingStatus.isCanceled()) { - return true; - } - - return !_bufferingStatus.isStarted(); -} - -bool TransferJob::bufferingCompleted() const { - if (!_bufferingRequired) { - return true; - } - - // The default state of a QFuture is with status Canceled | Started | Finished, - // so we have to check isCancelled before we check the actual state - if (_bufferingStatus.isCanceled()) { - return false; - } - - return _bufferingStatus.isFinished(); -} - -void TransferJob::startBuffering() { - if (bufferingRequired()) { - assert(_bufferingStatus.isCanceled()); - _bufferingStatus = QtConcurrent::run(_bufferThreadPool, [=] { - _bufferingLambda(); - }); - assert(!_bufferingStatus.isCanceled()); - assert(_bufferingStatus.isStarted()); - } -} -#endif - -GLVariableAllocationSupport::GLVariableAllocationSupport() { - _memoryPressureStateStale = true; -} - -GLVariableAllocationSupport::~GLVariableAllocationSupport() { - _memoryPressureStateStale = true; -} - -void GLVariableAllocationSupport::addMemoryManagedTexture(const TexturePointer& texturePointer) { - _memoryManagedTextures.push_back(texturePointer); - if (MemoryPressureState::Idle != _memoryPressureState) { - addToWorkQueue(texturePointer); - } -} - -void GLVariableAllocationSupport::addToWorkQueue(const TexturePointer& texturePointer) { - GLTexture* gltexture = Backend::getGPUObject(*texturePointer); - GLVariableAllocationSupport* vargltexture = dynamic_cast(gltexture); - switch (_memoryPressureState) { - case MemoryPressureState::Oversubscribed: - if (vargltexture->canDemote()) { - // Demote largest first - _demoteQueue.push({ texturePointer, (float)gltexture->size() }); - } - break; - - case MemoryPressureState::Undersubscribed: - if (vargltexture->canPromote()) { - // Promote smallest first - _promoteQueue.push({ texturePointer, 1.0f / (float)gltexture->size() }); - } - break; - - case MemoryPressureState::Transfer: - if (vargltexture->hasPendingTransfers()) { - // Transfer priority given to smaller mips first - _transferQueue.push({ texturePointer, 1.0f / (float)gltexture->_gpuObject.evalMipSize(vargltexture->_populatedMip) }); - } - break; - - case MemoryPressureState::Idle: - Q_UNREACHABLE(); - break; - } -} - -WorkQueue& GLVariableAllocationSupport::getActiveWorkQueue() { - static WorkQueue empty; - switch (_memoryPressureState) { - case MemoryPressureState::Oversubscribed: - return _demoteQueue; - - case MemoryPressureState::Undersubscribed: - return _promoteQueue; - - case MemoryPressureState::Transfer: - return _transferQueue; - - case MemoryPressureState::Idle: - Q_UNREACHABLE(); - break; - } - return empty; -} - -// FIXME hack for stats display -QString getTextureMemoryPressureModeString() { - switch (GLVariableAllocationSupport::_memoryPressureState) { - case MemoryPressureState::Oversubscribed: - return "Oversubscribed"; - - case MemoryPressureState::Undersubscribed: - return "Undersubscribed"; - - case MemoryPressureState::Transfer: - return "Transfer"; - - case MemoryPressureState::Idle: - return "Idle"; - } - Q_UNREACHABLE(); - return "Unknown"; -} - -void GLVariableAllocationSupport::updateMemoryPressure() { - static size_t lastAllowedMemoryAllocation = gpu::Texture::getAllowedGPUMemoryUsage(); - - size_t allowedMemoryAllocation = gpu::Texture::getAllowedGPUMemoryUsage(); - if (0 == allowedMemoryAllocation) { - allowedMemoryAllocation = DEFAULT_ALLOWED_TEXTURE_MEMORY; - } - - // If the user explicitly changed the allowed memory usage, we need to mark ourselves stale - // so that we react - if (allowedMemoryAllocation != lastAllowedMemoryAllocation) { - _memoryPressureStateStale = true; - lastAllowedMemoryAllocation = allowedMemoryAllocation; - } - - if (!_memoryPressureStateStale.exchange(false)) { - return; - } - - PROFILE_RANGE(render_gpu_gl, __FUNCTION__); - - // Clear any defunct textures (weak pointers that no longer have a valid texture) - _memoryManagedTextures.remove_if([&](const TextureWeakPointer& weakPointer) { - return weakPointer.expired(); - }); - - // Convert weak pointers to strong. This new list may still contain nulls if a texture was - // deleted on another thread between the previous line and this one - std::vector strongTextures; { - strongTextures.reserve(_memoryManagedTextures.size()); - std::transform( - _memoryManagedTextures.begin(), _memoryManagedTextures.end(), - std::back_inserter(strongTextures), - [](const TextureWeakPointer& p) { return p.lock(); }); - } - - size_t totalVariableMemoryAllocation = 0; - size_t idealMemoryAllocation = 0; - bool canDemote = false; - bool canPromote = false; - bool hasTransfers = false; - for (const auto& texture : strongTextures) { - // Race conditions can still leave nulls in the list, so we need to check - if (!texture) { - continue; - } - GLTexture* gltexture = Backend::getGPUObject(*texture); - GLVariableAllocationSupport* vartexture = dynamic_cast(gltexture); - // Track how much the texture thinks it should be using - idealMemoryAllocation += texture->evalTotalSize(); - // Track how much we're actually using - totalVariableMemoryAllocation += gltexture->size(); - canDemote |= vartexture->canDemote(); - canPromote |= vartexture->canPromote(); - hasTransfers |= vartexture->hasPendingTransfers(); - } - - size_t unallocated = idealMemoryAllocation - totalVariableMemoryAllocation; - float pressure = (float)totalVariableMemoryAllocation / (float)allowedMemoryAllocation; - - auto newState = MemoryPressureState::Idle; - if (pressure < UNDERSUBSCRIBED_PRESSURE_VALUE && (unallocated != 0 && canPromote)) { - newState = MemoryPressureState::Undersubscribed; - } else if (pressure > OVERSUBSCRIBED_PRESSURE_VALUE && canDemote) { - newState = MemoryPressureState::Oversubscribed; - } else if (hasTransfers) { - newState = MemoryPressureState::Transfer; - } - - if (newState != _memoryPressureState) { - _memoryPressureState = newState; - // Clear the existing queue - _transferQueue = WorkQueue(); - _promoteQueue = WorkQueue(); - _demoteQueue = WorkQueue(); - - // Populate the existing textures into the queue - if (_memoryPressureState != MemoryPressureState::Idle) { - for (const auto& texture : strongTextures) { - // Race conditions can still leave nulls in the list, so we need to check - if (!texture) { - continue; - } - addToWorkQueue(texture); - } - } - } -} - -TexturePointer GLVariableAllocationSupport::getNextWorkQueueItem(WorkQueue& workQueue) { - while (!workQueue.empty()) { - auto workTarget = workQueue.top(); - - auto texture = workTarget.first.lock(); - if (!texture) { - workQueue.pop(); - continue; - } - - // Check whether the resulting texture can actually have work performed - GLTexture* gltexture = Backend::getGPUObject(*texture); - GLVariableAllocationSupport* vartexture = dynamic_cast(gltexture); - switch (_memoryPressureState) { - case MemoryPressureState::Oversubscribed: - if (vartexture->canDemote()) { - return texture; - } - break; - - case MemoryPressureState::Undersubscribed: - if (vartexture->canPromote()) { - return texture; - } - break; - - case MemoryPressureState::Transfer: - if (vartexture->hasPendingTransfers()) { - return texture; - } - break; - - case MemoryPressureState::Idle: - Q_UNREACHABLE(); - break; - } - - // If we got here, then the texture has no work to do in the current state, - // so pop it off the queue and continue - workQueue.pop(); - } - - return TexturePointer(); -} - -void GLVariableAllocationSupport::processWorkQueue(WorkQueue& workQueue) { - if (workQueue.empty()) { - return; - } - - // Get the front of the work queue to perform work - auto texture = getNextWorkQueueItem(workQueue); - if (!texture) { - return; - } - - // Grab the first item off the demote queue - PROFILE_RANGE(render_gpu_gl, __FUNCTION__); - - GLTexture* gltexture = Backend::getGPUObject(*texture); - GLVariableAllocationSupport* vartexture = dynamic_cast(gltexture); - switch (_memoryPressureState) { - case MemoryPressureState::Oversubscribed: - vartexture->demote(); - workQueue.pop(); - addToWorkQueue(texture); - _memoryPressureStateStale = true; - break; - - case MemoryPressureState::Undersubscribed: - vartexture->promote(); - workQueue.pop(); - addToWorkQueue(texture); - _memoryPressureStateStale = true; - break; - - case MemoryPressureState::Transfer: - if (vartexture->executeNextTransfer(texture)) { - workQueue.pop(); - addToWorkQueue(texture); - -#if THREADED_TEXTURE_BUFFERING - // Eagerly start the next buffering job if possible - texture = getNextWorkQueueItem(workQueue); - if (texture) { - gltexture = Backend::getGPUObject(*texture); - vartexture = dynamic_cast(gltexture); - vartexture->executeNextBuffer(texture); - } -#endif - } - break; - - case MemoryPressureState::Idle: - Q_UNREACHABLE(); - break; - } -} - -void GLVariableAllocationSupport::processWorkQueues() { - if (MemoryPressureState::Idle == _memoryPressureState) { - return; - } - - auto& workQueue = getActiveWorkQueue(); - // Do work on the front of the queue - processWorkQueue(workQueue); - - if (workQueue.empty()) { - _memoryPressureState = MemoryPressureState::Idle; - _memoryPressureStateStale = true; - } -} - -void GLVariableAllocationSupport::manageMemory() { - PROFILE_RANGE(render_gpu_gl, __FUNCTION__); - updateMemoryPressure(); - processWorkQueues(); -} - -bool GLVariableAllocationSupport::executeNextTransfer(const TexturePointer& currentTexture) { -#if THREADED_TEXTURE_BUFFERING - // If a transfer job is active on the buffering thread, but has not completed it's buffering lambda, - // then we need to exit early, since we don't want to have the transfer job leave scope while it's - // being used in another thread -- See https://highfidelity.fogbugz.com/f/cases/4626 - if (_currentTransferJob && !_currentTransferJob->bufferingCompleted()) { - return false; - } -#endif - - if (_populatedMip <= _allocatedMip) { -#if THREADED_TEXTURE_BUFFERING - _currentTransferJob.reset(); - _currentTransferTexture.reset(); -#endif - return true; - } - - // If the transfer queue is empty, rebuild it - if (_pendingTransfers.empty()) { - populateTransferQueue(); - } - - bool result = false; - if (!_pendingTransfers.empty()) { -#if THREADED_TEXTURE_BUFFERING - // If there is a current transfer, but it's not the top of the pending transfer queue, then it's an orphan, so we want to abandon it. - if (_currentTransferJob && _currentTransferJob != _pendingTransfers.front()) { - _currentTransferJob.reset(); - } - - if (!_currentTransferJob) { - // Keeping hold of a strong pointer to the transfer job ensures that if the pending transfer queue is rebuilt, the transfer job - // doesn't leave scope, causing a crash in the buffering thread - _currentTransferJob = _pendingTransfers.front(); - - // Keeping hold of a strong pointer during the transfer ensures that the transfer thread cannot try to access a destroyed texture - _currentTransferTexture = currentTexture; - } - - // transfer jobs use asynchronous buffering of the texture data because it may involve disk IO, so we execute a try here to determine if the buffering - // is complete - if (_currentTransferJob->tryTransfer()) { - _pendingTransfers.pop(); - // Once a given job is finished, release the shared pointers keeping them alive - _currentTransferTexture.reset(); - _currentTransferJob.reset(); - result = true; - } -#else - if (_pendingTransfers.front()->tryTransfer()) { - _pendingTransfers.pop(); - result = true; - } -#endif - } - return result; -} - -#if THREADED_TEXTURE_BUFFERING -void GLVariableAllocationSupport::executeNextBuffer(const TexturePointer& currentTexture) { - if (_currentTransferJob && !_currentTransferJob->bufferingCompleted()) { - return; - } - - // If the transfer queue is empty, rebuild it - if (_pendingTransfers.empty()) { - populateTransferQueue(); - } - - if (!_pendingTransfers.empty()) { - if (!_currentTransferJob) { - _currentTransferJob = _pendingTransfers.front(); - _currentTransferTexture = currentTexture; - } - - _currentTransferJob->startBuffering(); - } -} -#endif - -void GLVariableAllocationSupport::incrementPopulatedSize(Size delta) const { - _populatedSize += delta; - // Keep the 2 code paths to be able to debug - if (_size < _populatedSize) { - Backend::textureResourcePopulatedGPUMemSize.update(0, delta); - } else { - Backend::textureResourcePopulatedGPUMemSize.update(0, delta); - } -} -void GLVariableAllocationSupport::decrementPopulatedSize(Size delta) const { - _populatedSize -= delta; - // Keep the 2 code paths to be able to debug - if (_size < _populatedSize) { - Backend::textureResourcePopulatedGPUMemSize.update(delta, 0); - } else { - Backend::textureResourcePopulatedGPUMemSize.update(delta, 0); - } -} \ No newline at end of file diff --git a/libraries/gpu-gles/src/gpu/gl/GLTexture.h b/libraries/gpu-gles/src/gpu/gl/GLTexture.h deleted file mode 100644 index ce27d02033..0000000000 --- a/libraries/gpu-gles/src/gpu/gl/GLTexture.h +++ /dev/null @@ -1,211 +0,0 @@ -// -// Created by Bradley Austin Davis on 2016/05/15 -// Copyright 2013-2016 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_gl_GLTexture_h -#define hifi_gpu_gl_GLTexture_h - -#include -#include - -#include "GLShared.h" -#include "GLBackend.h" -#include "GLTexelFormat.h" -#include - -#define THREADED_TEXTURE_BUFFERING 1 - -namespace gpu { namespace gl { - -struct GLFilterMode { - GLint minFilter; - GLint magFilter; -}; - -class GLVariableAllocationSupport { - friend class GLBackend; - -public: - GLVariableAllocationSupport(); - virtual ~GLVariableAllocationSupport(); - - enum class MemoryPressureState { - Idle, - Transfer, - Oversubscribed, - Undersubscribed, - }; - - using QueuePair = std::pair; - struct QueuePairLess { - bool operator()(const QueuePair& a, const QueuePair& b) { - return a.second < b.second; - } - }; - using WorkQueue = std::priority_queue, QueuePairLess>; - - class TransferJob { - using VoidLambda = std::function; - using VoidLambdaQueue = std::queue; - const GLTexture& _parent; - Texture::PixelsPointer _mipData; - size_t _transferOffset { 0 }; - size_t _transferSize { 0 }; - - bool _bufferingRequired { true }; - VoidLambda _transferLambda; - VoidLambda _bufferingLambda; - -#if THREADED_TEXTURE_BUFFERING - // Indicates if a transfer from backing storage to interal storage has started - QFuture _bufferingStatus; - static QThreadPool* _bufferThreadPool; -#endif - - public: - TransferJob(const TransferJob& other) = delete; - TransferJob(const GLTexture& parent, std::function transferLambda); - TransferJob(const GLTexture& parent, uint16_t sourceMip, uint16_t targetMip, uint8_t face, uint32_t lines = 0, uint32_t lineOffset = 0); - ~TransferJob(); - bool tryTransfer(); - -#if THREADED_TEXTURE_BUFFERING - void startBuffering(); - bool bufferingRequired() const; - bool bufferingCompleted() const; - static void startBufferingThread(); -#endif - - private: - void transfer(); - }; - - using TransferJobPointer = std::shared_ptr; - using TransferQueue = std::queue; - static MemoryPressureState _memoryPressureState; - -public: - static void addMemoryManagedTexture(const TexturePointer& texturePointer); - -protected: - static size_t _frameTexturesCreated; - static std::atomic _memoryPressureStateStale; - static std::list _memoryManagedTextures; - static WorkQueue _transferQueue; - static WorkQueue _promoteQueue; - static WorkQueue _demoteQueue; -#if THREADED_TEXTURE_BUFFERING - static TexturePointer _currentTransferTexture; - static TransferJobPointer _currentTransferJob; -#endif - static const uvec3 INITIAL_MIP_TRANSFER_DIMENSIONS; - static const uvec3 MAX_TRANSFER_DIMENSIONS; - static const size_t MAX_TRANSFER_SIZE; - - - static void updateMemoryPressure(); - static void processWorkQueues(); - static void processWorkQueue(WorkQueue& workQueue); - static TexturePointer getNextWorkQueueItem(WorkQueue& workQueue); - static void addToWorkQueue(const TexturePointer& texture); - static WorkQueue& getActiveWorkQueue(); - - static void manageMemory(); - - //bool canPromoteNoAllocate() const { return _allocatedMip < _populatedMip; } - bool canPromote() const { return _allocatedMip > _minAllocatedMip; } - bool canDemote() const { return _allocatedMip < _maxAllocatedMip; } - bool hasPendingTransfers() const { return _populatedMip > _allocatedMip; } -#if THREADED_TEXTURE_BUFFERING - void executeNextBuffer(const TexturePointer& currentTexture); -#endif - bool executeNextTransfer(const TexturePointer& currentTexture); - virtual void populateTransferQueue() = 0; - virtual void promote() = 0; - virtual void demote() = 0; - - // THe amount of memory currently allocated - Size _size { 0 }; - - // The amount of memory currnently populated - void incrementPopulatedSize(Size delta) const; - void decrementPopulatedSize(Size delta) const; - mutable Size _populatedSize { 0 }; - - // The allocated mip level, relative to the number of mips in the gpu::Texture object - // The relationship between a given glMip to the original gpu::Texture mip is always - // glMip + _allocatedMip - uint16 _allocatedMip { 0 }; - // The populated mip level, relative to the number of mips in the gpu::Texture object - // This must always be >= the allocated mip - uint16 _populatedMip { 0 }; - // The highest (lowest resolution) mip that we will support, relative to the number - // of mips in the gpu::Texture object - uint16 _maxAllocatedMip { 0 }; - // The lowest (highest resolution) mip that we will support, relative to the number - // of mips in the gpu::Texture object - uint16 _minAllocatedMip { 0 }; - // Contains a series of lambdas that when executed will transfer data to the GPU, modify - // the _populatedMip and update the sampler in order to fully populate the allocated texture - // until _populatedMip == _allocatedMip - TransferQueue _pendingTransfers; -}; - -class GLTexture : public GLObject { - using Parent = GLObject; - friend class GLBackend; - friend class GLVariableAllocationSupport; -public: - static const uint16_t INVALID_MIP { (uint16_t)-1 }; - static const uint8_t INVALID_FACE { (uint8_t)-1 }; - - ~GLTexture(); - - const GLuint& _texture { _id }; - const std::string _source; - const GLenum _target; - GLTexelFormat _texelFormat; - - static const std::vector& getFaceTargets(GLenum textureType); - static uint8_t getFaceCount(GLenum textureType); - static GLenum getGLTextureType(const Texture& texture); - - static const uint8_t TEXTURE_2D_NUM_FACES = 1; - static const uint8_t TEXTURE_CUBE_NUM_FACES = 6; - static const GLenum CUBE_FACE_LAYOUT[TEXTURE_CUBE_NUM_FACES]; - static const GLFilterMode FILTER_MODES[Sampler::NUM_FILTERS]; - static const GLenum WRAP_MODES[Sampler::NUM_WRAP_MODES]; - -protected: - virtual Size size() const = 0; - virtual void generateMips() const = 0; - virtual void syncSampler() const = 0; - - virtual 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 = 0; - virtual Size copyMipFaceFromTexture(uint16_t sourceMip, uint16_t targetMip, uint8_t face) const final; - virtual void copyTextureMipsInGPUMem(GLuint srcId, GLuint destId, uint16_t srcMipOffset, uint16_t destMipOffset, uint16_t populatedMips) {} // Only relevant for Variable Allocation textures - - GLTexture(const std::weak_ptr& backend, const Texture& texture, GLuint id); -}; - -class GLExternalTexture : public GLTexture { - using Parent = GLTexture; - friend class GLBackend; -public: - ~GLExternalTexture(); -protected: - GLExternalTexture(const std::weak_ptr& backend, const Texture& texture, GLuint id); - void generateMips() const override {} - void syncSampler() 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 { return 0;} - - Size size() const override { return 0; } -}; - - -} } - -#endif diff --git a/libraries/gpu-gles/src/gpu/gles/GLESBackend.h b/libraries/gpu-gles/src/gpu/gles/GLESBackend.h index aeda054e72..38e28e630a 100644 --- a/libraries/gpu-gles/src/gpu/gles/GLESBackend.h +++ b/libraries/gpu-gles/src/gpu/gles/GLESBackend.h @@ -13,8 +13,8 @@ #include -#include "../gl/GLBackend.h" -#include "../gl/GLTexture.h" +#include +#include namespace gpu { namespace gles { diff --git a/libraries/gpu-gles/src/gpu/gles/GLESBackendBuffer.cpp b/libraries/gpu-gles/src/gpu/gles/GLESBackendBuffer.cpp index 05bda34d7f..17fdad8377 100644 --- a/libraries/gpu-gles/src/gpu/gles/GLESBackendBuffer.cpp +++ b/libraries/gpu-gles/src/gpu/gles/GLESBackendBuffer.cpp @@ -6,7 +6,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #include "GLESBackend.h" -#include "../gl/GLBuffer.h" +#include namespace gpu { namespace gles { diff --git a/libraries/gpu-gles/src/gpu/gles/GLESBackendOutput.cpp b/libraries/gpu-gles/src/gpu/gles/GLESBackendOutput.cpp index dc4025247e..0bf1548a4b 100644 --- a/libraries/gpu-gles/src/gpu/gles/GLESBackendOutput.cpp +++ b/libraries/gpu-gles/src/gpu/gles/GLESBackendOutput.cpp @@ -12,8 +12,8 @@ #include -#include "../gl/GLFramebuffer.h" -#include "../gl/GLTexture.h" +#include +#include namespace gpu { namespace gles { diff --git a/libraries/gpu-gles/src/gpu/gles/GLESBackendQuery.cpp b/libraries/gpu-gles/src/gpu/gles/GLESBackendQuery.cpp index db541b07bc..434fbcb04f 100644 --- a/libraries/gpu-gles/src/gpu/gles/GLESBackendQuery.cpp +++ b/libraries/gpu-gles/src/gpu/gles/GLESBackendQuery.cpp @@ -10,7 +10,7 @@ // #include "GLESBackend.h" -#include "../gl/GLQuery.h" +#include using namespace gpu; using namespace gpu::gl; diff --git a/libraries/gpu-gles/src/gpu/gles/GLESBackendShader.cpp b/libraries/gpu-gles/src/gpu/gles/GLESBackendShader.cpp index 01a87978c2..16cf1559dd 100644 --- a/libraries/gpu-gles/src/gpu/gles/GLESBackendShader.cpp +++ b/libraries/gpu-gles/src/gpu/gles/GLESBackendShader.cpp @@ -6,7 +6,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #include "GLESBackend.h" -#include "../gl/GLShader.h" +#include using namespace gpu; using namespace gpu::gl; diff --git a/libraries/gpu-gles/src/gpu/gles/GLESBackendTexture.cpp b/libraries/gpu-gles/src/gpu/gles/GLESBackendTexture.cpp index d2fa2aabab..6bc55a23d4 100644 --- a/libraries/gpu-gles/src/gpu/gles/GLESBackendTexture.cpp +++ b/libraries/gpu-gles/src/gpu/gles/GLESBackendTexture.cpp @@ -13,7 +13,7 @@ #include #include -#include "../gl/GLTexelFormat.h" +#include using namespace gpu; using namespace gpu::gl; @@ -251,9 +251,6 @@ void GLESFixedAllocationTexture::allocateStorage() const { void GLESFixedAllocationTexture::syncSampler() const { Parent::syncSampler(); const Sampler& sampler = _gpuObject.getSampler(); - auto baseMip = std::max(sampler.getMipOffset(), sampler.getMinMip()); - - glTexParameteri(_target, GL_TEXTURE_BASE_LEVEL, baseMip); glTexParameterf(_target, GL_TEXTURE_MIN_LOD, (float)sampler.getMinMip()); glTexParameterf(_target, GL_TEXTURE_MAX_LOD, (sampler.getMaxMip() == Sampler::MAX_MIP_LEVEL ? 1000.0f : sampler.getMaxMip())); } @@ -459,7 +456,6 @@ void copyCompressedTexGPUMem(const gpu::Texture& texture, GLenum texTarget, GLui sourceMip._size = (GLint)faceTargets.size() * sourceMip._faceSize; sourceMip._offset = bufferOffset; bufferOffset += sourceMip._size; - gpu::gl::checkGLError(); } (void)CHECK_GL_ERROR(); @@ -505,7 +501,6 @@ void copyCompressedTexGPUMem(const gpu::Texture& texture, GLenum texTarget, GLui #endif glCompressedTexSubImage2D(faceTargets[f], destLevel, 0, 0, sourceMip._width, sourceMip._height, internalFormat, sourceMip._faceSize, BUFFER_OFFSET(sourceMip._offset + f * sourceMip._faceSize)); - gpu::gl::checkGLError(); } } From d67044f220d47791a5ff18d6caa04356b942ea53 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Wed, 14 Mar 2018 13:32:48 -0700 Subject: [PATCH 04/19] EntityScriptServer should wait for script engine to finish when stopping Script engine will still running and using EntityEditPacketSender, which is owned by EntityScriptServer, which was destroyed. https://highfidelity.manuscript.com/f/cases/11071/ --- assignment-client/src/scripts/EntityScriptServer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/assignment-client/src/scripts/EntityScriptServer.cpp b/assignment-client/src/scripts/EntityScriptServer.cpp index 60cb1e349b..8276807be7 100644 --- a/assignment-client/src/scripts/EntityScriptServer.cpp +++ b/assignment-client/src/scripts/EntityScriptServer.cpp @@ -476,6 +476,7 @@ void EntityScriptServer::clear() { // do this here (instead of in deleter) to avoid marshalling unload signals back to this thread _entitiesScriptEngine->unloadAllEntityScripts(); _entitiesScriptEngine->stop(); + _entitiesScriptEngine->waitTillDoneRunning(); } _entityViewer.clear(); From 4fd6eb559bda55ecc7869174fa50bf4dabc8e8ca Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Wed, 14 Mar 2018 17:06:38 -0700 Subject: [PATCH 05/19] Remove dangling packet sender pointer before it's invalid. --- assignment-client/src/scripts/EntityScriptServer.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/assignment-client/src/scripts/EntityScriptServer.cpp b/assignment-client/src/scripts/EntityScriptServer.cpp index 8276807be7..1255c18e71 100644 --- a/assignment-client/src/scripts/EntityScriptServer.cpp +++ b/assignment-client/src/scripts/EntityScriptServer.cpp @@ -566,8 +566,15 @@ void EntityScriptServer::handleOctreePacket(QSharedPointer mess void EntityScriptServer::aboutToFinish() { shutdownScriptEngine(); + auto entityScriptingInterface = DependencyManager::get(); // our entity tree is going to go away so tell that to the EntityScriptingInterface - DependencyManager::get()->setEntityTree(nullptr); + entityScriptingInterface->setEntityTree(nullptr); + + // Should always be true as they are singletons. + if (entityScriptingInterface->getPacketSender() == &_entityEditSender) { + // The packet sender is about to go away. + entityScriptingInterface->setPacketSender(nullptr); + } DependencyManager::get()->cleanup(); From 984a48316d742b8bbcfd182c69dc1f4ccdb0813b Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 16 Mar 2018 10:56:56 -0700 Subject: [PATCH 06/19] CR --- libraries/render-utils/src/GeometryCache.cpp | 145 +++++-------------- libraries/render-utils/src/GeometryCache.h | 11 +- 2 files changed, 45 insertions(+), 111 deletions(-) diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index edd68603cb..693e288d5d 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -135,10 +135,10 @@ static gpu::Stream::FormatPointer SOLID_STREAM_FORMAT; static gpu::Stream::FormatPointer INSTANCED_SOLID_STREAM_FORMAT; static gpu::Stream::FormatPointer INSTANCED_SOLID_FADE_STREAM_FORMAT; -static const uint SHAPE_VERTEX_STRIDE = sizeof(glm::vec3) * 3 + sizeof(glm::vec2); // position, normal, texcoords, tangent -static const uint SHAPE_NORMALS_OFFSET = sizeof(glm::vec3); -static const uint SHAPE_TEXCOORD0_OFFSET = sizeof(glm::vec3) * 2; -static const uint SHAPE_TANGENT_OFFSET = sizeof(glm::vec3) * 2 + sizeof(glm::vec2); +static const uint SHAPE_VERTEX_STRIDE = sizeof(GeometryCache::ShapeVertex); // position, normal, texcoords, tangent +static const uint SHAPE_NORMALS_OFFSET = offsetof(GeometryCache::ShapeVertex, normal); +static const uint SHAPE_TEXCOORD0_OFFSET = offsetof(GeometryCache::ShapeVertex, uv); +static const uint SHAPE_TANGENT_OFFSET = offsetof(GeometryCache::ShapeVertex, tangent); void GeometryCache::computeSimpleHullPointListForShape(const int entityShape, const glm::vec3 &entityExtents, QVector &outPointList) { @@ -197,22 +197,11 @@ std::vector polygon() { return result; } -void addVec3ToVector(std::vector& vertices, glm::vec3 vec) { - vertices.push_back(vec.x); - vertices.push_back(vec.y); - vertices.push_back(vec.z); -} - -void addVec2ToVector(std::vector& vertices, glm::vec2 vec) { - vertices.push_back(vec.x); - vertices.push_back(vec.y); -} - -void GeometryCache::ShapeData::setupVertices(gpu::BufferPointer& vertexBuffer, const std::vector& vertices) { +void GeometryCache::ShapeData::setupVertices(gpu::BufferPointer& vertexBuffer, const std::vector& vertices) { gpu::Buffer::Size offset = vertexBuffer->getSize(); vertexBuffer->append(vertices); - gpu::Buffer::Size viewSize = vertices.size() * sizeof(glm::vec3); + gpu::Buffer::Size viewSize = vertices.size() * sizeof(ShapeVertex); _positionView = gpu::BufferView(vertexBuffer, offset, viewSize, SHAPE_VERTEX_STRIDE, POSITION_ELEMENT); @@ -315,14 +304,14 @@ static IndexPair indexToken(geometry::Index a, geometry::Index b) { template void setupFlatShape(GeometryCache::ShapeData& shapeData, const geometry::Solid& shape, gpu::BufferPointer& vertexBuffer, gpu::BufferPointer& indexBuffer) { using namespace geometry; - std::vector vertices; + std::vector vertices; IndexVector solidIndices, wireIndices; IndexPairs wireSeenIndices; size_t faceCount = shape.faces.size(); size_t faceIndexCount = triangulatedFaceIndexCount(); - vertices.reserve(N * faceCount * 2); + vertices.reserve(N * faceCount); solidIndices.reserve(faceIndexCount * faceCount); Index baseVertex = 0; @@ -359,10 +348,7 @@ void setupFlatShape(GeometryCache::ShapeData& shapeData, const geometry::Solid void setupSmoothShape(GeometryCache::ShapeData& shapeData, const geometry::Solid& shape, gpu::BufferPointer& vertexBuffer, gpu::BufferPointer& indexBuffer) { using namespace geometry; - std::vector vertices; - vertices.reserve(shape.vertices.size() * SHAPE_VERTEX_STRIDE / sizeof(float)); + std::vector vertices; + vertices.reserve(shape.vertices.size()); for (const auto& vertex : shape.vertices) { - addVec3ToVector(vertices, vertex); - addVec3ToVector(vertices, vertex); - addVec2ToVector(vertices, calculateSphereTexCoord(vertex)); // We'll fill in the correct tangents later, once we correct the UVs - addVec3ToVector(vertices, vec3(0.0f)); + vertices.emplace_back(vertex, vertex, calculateSphereTexCoord(vertex), vec3(0.0f)); } // We need to fix up the sphere's UVs because it's actually a tesselated icosahedron. See http://mft-dev.dk/uv-mapping-sphere/ @@ -424,9 +409,9 @@ void setupSmoothShape(GeometryCache::ShapeData& shapeData, const geometry::Solid for (size_t f = 0; f < faceCount; f++) { // Fix zipper { - float& u1 = vertices[shape.faces[f][0] * SHAPE_VERTEX_STRIDE / sizeof(float) + SHAPE_TEXCOORD0_OFFSET / sizeof(float)]; - float& u2 = vertices[shape.faces[f][1] * SHAPE_VERTEX_STRIDE / sizeof(float) + SHAPE_TEXCOORD0_OFFSET / sizeof(float)]; - float& u3 = vertices[shape.faces[f][2] * SHAPE_VERTEX_STRIDE / sizeof(float) + SHAPE_TEXCOORD0_OFFSET / sizeof(float)]; + float& u1 = vertices[shape.faces[f][0]].uv.x; + float& u2 = vertices[shape.faces[f][1]].uv.x; + float& u3 = vertices[shape.faces[f][2]].uv.x; if (glm::isnan(u1)) { u1 = (u2 + u3) / 2.0f; @@ -461,21 +446,19 @@ void setupSmoothShape(GeometryCache::ShapeData& shapeData, const geometry::Solid if (shape.vertices[originalIndex].y == 1.0f || shape.vertices[originalIndex].y == -1.0f) { float uSum = 0.0f; for (Index i2 = 1; i2 <= N - 1; i2++) { - float u = vertices[shape.faces[f][(i + i2) % N] * SHAPE_VERTEX_STRIDE / sizeof(float) + SHAPE_TEXCOORD0_OFFSET / sizeof(float)]; + float u = vertices[shape.faces[f][(i + i2) % N]].uv.x; uSum += u; } uSum /= (float)(N - 1); - vertices[originalIndex * SHAPE_VERTEX_STRIDE / sizeof(float) + SHAPE_TEXCOORD0_OFFSET / sizeof(float)] = uSum; + vertices[originalIndex].uv.x = uSum; break; } } // Fill in tangents for (Index i = 0; i < N; i++) { - vec3 tangent = calculateSphereTangent(vertices[shape.faces[f][i] * SHAPE_VERTEX_STRIDE / sizeof(float) + SHAPE_TEXCOORD0_OFFSET / sizeof(float)]); - vertices[shape.faces[f][i] * SHAPE_VERTEX_STRIDE / sizeof(float) + SHAPE_TANGENT_OFFSET / sizeof(float)] = tangent.x; - vertices[shape.faces[f][i] * SHAPE_VERTEX_STRIDE / sizeof(float) + SHAPE_TANGENT_OFFSET / sizeof(float) + 1] = tangent.y; - vertices[shape.faces[f][i] * SHAPE_VERTEX_STRIDE / sizeof(float) + SHAPE_TANGENT_OFFSET / sizeof(float) + 2] = tangent.z; + vec3 tangent = calculateSphereTangent(vertices[shape.faces[f][i]].uv.x); + vertices[shape.faces[f][i]].tangent = tangent; } } @@ -516,31 +499,22 @@ void setupSmoothShape(GeometryCache::ShapeData& shapeData, const geometry::Solid template void extrudePolygon(GeometryCache::ShapeData& shapeData, gpu::BufferPointer& vertexBuffer, gpu::BufferPointer& indexBuffer, bool isConical = false) { using namespace geometry; - std::vector vertices; + std::vector vertices; IndexVector solidIndices, wireIndices; // Top (if not conical) and bottom faces std::vector shape = polygon(); if (isConical) { for (uint32_t i = 0; i < N; i++) { - addVec3ToVector(vertices, vec3(0.0f, 0.5f, 0.0f)); - addVec3ToVector(vertices, vec3(0.0f, 1.0f, 0.0f)); - addVec2ToVector(vertices, vec2(i / (float)N, 1.0f)); - addVec3ToVector(vertices, vec3(0.0f)); + vertices.emplace_back(vec3(0.0f, 0.5f, 0.0f), vec3(0.0f, 1.0f, 0.0f), vec2((float)i / (float)N, 1.0f), vec3(0.0f)); } } else { for (const vec3& v : shape) { - addVec3ToVector(vertices, vec3(v.x, 0.5f, v.z)); - addVec3ToVector(vertices, vec3(0.0f, 1.0f, 0.0f)); - addVec2ToVector(vertices, vec2(v.x, v.z) + vec2(0.5f)); - addVec3ToVector(vertices, vec3(1.0f, 0.0f, 0.0f)); + vertices.emplace_back(vec3(v.x, 0.5f, v.z), vec3(0.0f, 1.0f, 0.0f), vec2(v.x, v.z) + vec2(0.5f), vec3(1.0f, 0.0f, 0.0f)); } } for (const vec3& v : shape) { - addVec3ToVector(vertices, vec3(v.x, -0.5f, v.z)); - addVec3ToVector(vertices, vec3(0.0f, -1.0f, 0.0f)); - addVec2ToVector(vertices, vec2(-v.x, v.z) + vec2(0.5f)); - addVec3ToVector(vertices, vec3(-1.0f, 0.0f, 0.0f)); + vertices.emplace_back(vec3(v.x, -0.5f, v.z), vec3(0.0f, -1.0f, 0.0f), vec2(-v.x, v.z) + vec2(0.5f), vec3(-1.0f, 0.0f, 0.0f)); } Index baseVertex = 0; for (uint32_t i = 2; i < N; i++) { @@ -572,25 +546,13 @@ void extrudePolygon(GeometryCache::ShapeData& shapeData, gpu::BufferPointer& ver vec3 tangent = glm::normalize(bottomLeft - bottomRight); // Our tex coords go in the opposite direction as our vertices - float u = 1.0f - i / (float)N; - float u2 = 1.0f - (i + 1) / (float)N; + float u = 1.0f - (float)i / (float)N; + float u2 = 1.0f - (float)(i + 1) / (float)N; - addVec3ToVector(vertices, topLeft); - addVec3ToVector(vertices, normal); - addVec2ToVector(vertices, vec2(u, 0.0f)); - addVec3ToVector(vertices, tangent); - addVec3ToVector(vertices, bottomLeft); - addVec3ToVector(vertices, normal); - addVec2ToVector(vertices, vec2(u, 1.0f)); - addVec3ToVector(vertices, tangent); - addVec3ToVector(vertices, topRight); - addVec3ToVector(vertices, normal); - addVec2ToVector(vertices, vec2(u2, 0.0f)); - addVec3ToVector(vertices, tangent); - addVec3ToVector(vertices, bottomRight); - addVec3ToVector(vertices, normal); - addVec2ToVector(vertices, vec2(u2, 1.0f)); - addVec3ToVector(vertices, tangent); + vertices.emplace_back(topLeft, normal, vec2(u, 0.0f), tangent); + vertices.emplace_back(bottomLeft, normal, vec2(u, 1.0f), tangent); + vertices.emplace_back(topRight, normal, vec2(u2, 0.0f), tangent); + vertices.emplace_back(bottomRight, normal, vec2(u2, 1.0f), tangent); solidIndices.push_back(baseVertex + 0); solidIndices.push_back(baseVertex + 2); @@ -609,43 +571,6 @@ void extrudePolygon(GeometryCache::ShapeData& shapeData, gpu::BufferPointer& ver shapeData.setupIndices(indexBuffer, solidIndices, wireIndices); } -void drawCircle(GeometryCache::ShapeData& shapeData, gpu::BufferPointer& vertexBuffer, gpu::BufferPointer& indexBuffer) { - // Draw a circle with radius 1/4th the size of the bounding box - using namespace geometry; - - std::vector vertices; - IndexVector solidIndices, wireIndices; - const int NUM_CIRCLE_VERTICES = 64; - - std::vector shape = polygon(); - for (const vec3& v : shape) { - addVec3ToVector(vertices, vec3(v.x, 0.0f, v.z)); - addVec3ToVector(vertices, vec3(0.0f, 0.0f, 0.0f)); - addVec2ToVector(vertices, vec2(v.x, v.z) + vec2(0.5f)); - addVec3ToVector(vertices, vec3(1.0f, 0.0f, 0.0f)); - } - - Index baseVertex = 0; - for (uint32_t i = 2; i < NUM_CIRCLE_VERTICES; i++) { - solidIndices.push_back(baseVertex + 0); - solidIndices.push_back(baseVertex + i); - solidIndices.push_back(baseVertex + i - 1); - solidIndices.push_back(baseVertex + NUM_CIRCLE_VERTICES); - solidIndices.push_back(baseVertex + i + NUM_CIRCLE_VERTICES - 1); - solidIndices.push_back(baseVertex + i + NUM_CIRCLE_VERTICES); - } - - for (uint32_t i = 1; i <= NUM_CIRCLE_VERTICES; i++) { - wireIndices.push_back(baseVertex + (i % NUM_CIRCLE_VERTICES)); - wireIndices.push_back(baseVertex + i - 1); - wireIndices.push_back(baseVertex + (i % NUM_CIRCLE_VERTICES) + NUM_CIRCLE_VERTICES); - wireIndices.push_back(baseVertex + (i - 1) + NUM_CIRCLE_VERTICES); - } - - shapeData.setupVertices(vertexBuffer, vertices); - shapeData.setupIndices(indexBuffer, solidIndices, wireIndices); -} - // FIXME solids need per-face vertices, but smooth shaded // components do not. Find a way to support using draw elements // or draw arrays as appropriate @@ -678,9 +603,9 @@ void GeometryCache::buildShapes() { // Line { ShapeData& shapeData = _shapes[Line]; - shapeData.setupVertices(_shapeVertices, std::vector { - -0.5f, 0.0f, 0.0f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, - 0.5f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f + shapeData.setupVertices(_shapeVertices, std::vector { + ShapeVertex(vec3(-0.5f, 0.0f, 0.0f), vec3(-0.5f, 0.0f, 0.0f), vec2(0.0f, 0.0f), vec3(0.0f, 0.0f, 0.0f)), + ShapeVertex(vec3(0.5f, 0.0f, 0.0f), vec3(0.5f, 0.0f, 0.0f), vec2(0.0f, 0.0f), vec3(0.0f, 0.0f, 0.0f)) }); IndexVector wireIndices; // Only two indices diff --git a/libraries/render-utils/src/GeometryCache.h b/libraries/render-utils/src/GeometryCache.h index b0caaf113c..63154398a4 100644 --- a/libraries/render-utils/src/GeometryCache.h +++ b/libraries/render-utils/src/GeometryCache.h @@ -354,6 +354,15 @@ public: /// Set a batch to the simple pipeline, returning the previous pipeline void useSimpleDrawPipeline(gpu::Batch& batch, bool noBlend = false); + struct ShapeVertex { + ShapeVertex(const vec3& pos, const vec3& normal, const vec2& uv, const vec3& tangent) : pos(pos), normal(normal), uv(uv), tangent(tangent) {} + + vec3 pos; + vec3 normal; + vec2 uv; + vec3 tangent; + }; + struct ShapeData { gpu::BufferView _positionView; gpu::BufferView _normalView; @@ -362,7 +371,7 @@ public: gpu::BufferView _indicesView; gpu::BufferView _wireIndicesView; - void setupVertices(gpu::BufferPointer& vertexBuffer, const std::vector& vertices); + void setupVertices(gpu::BufferPointer& vertexBuffer, const std::vector& vertices); void setupIndices(gpu::BufferPointer& indexBuffer, const geometry::IndexVector& indices, const geometry::IndexVector& wireIndices); void setupBatch(gpu::Batch& batch) const; void draw(gpu::Batch& batch) const; From f77228bbfea8f20846d313dc558434e5af927584 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 20 Mar 2018 09:58:47 -0700 Subject: [PATCH 07/19] Fixing missing m_pi define --- libraries/render-utils/src/AnimDebugDraw.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/render-utils/src/AnimDebugDraw.cpp b/libraries/render-utils/src/AnimDebugDraw.cpp index 02ff234c01..90424b04b2 100644 --- a/libraries/render-utils/src/AnimDebugDraw.cpp +++ b/libraries/render-utils/src/AnimDebugDraw.cpp @@ -9,6 +9,7 @@ #include "AnimDebugDraw.h" +#include #include #include @@ -21,7 +22,6 @@ #include "animdebugdraw_vert.h" #include "animdebugdraw_frag.h" - class AnimDebugDrawData { public: From a861be112fa54275128fc418f08365c60e131954 Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Tue, 20 Mar 2018 14:15:38 -0700 Subject: [PATCH 08/19] Fix GLES build --- .../src/gpu/gl/GLTexelFormat.cpp | 20 ++++++------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLTexelFormat.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLTexelFormat.cpp index 2c5b22c410..99a9afb4c4 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLTexelFormat.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLTexelFormat.cpp @@ -12,12 +12,17 @@ using namespace gpu; using namespace gpu::gl; #if defined(USE_GLES) +// Missing GL formats #define GL_R16 GL_R16_EXT #define GL_R16_SNORM GL_R16_SNORM_EXT +#define GL_RG16 GL_RG16_EXT +#define GL_RG16_SNORM GL_RG16_SNORM_EXT +#define GL_RGBA2 GL_RGBA8 #define GL_RGBA16 GL_RGBA16_EXT #define GL_RGBA16_SNORM GL_RGBA16_SNORM_EXT #define GL_DEPTH_COMPONENT32 GL_DEPTH_COMPONENT32_OES -#define GL_RGBA2 GL_RGBA8 +#define GL_SLUMINANCE8_EXT GL_SLUMINANCE8_NV +// Missing GL compressed formats #define GL_COMPRESSED_RED_RGTC1 0x8DBB #define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC #define GL_COMPRESSED_RG_RGTC2 0x8DBD @@ -26,7 +31,6 @@ using namespace gpu::gl; #define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM 0x8E8D #define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E #define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F -#define GL_SLUMINANCE8_EXT GL_SLUMINANCE8_NV #endif bool GLTexelFormat::isCompressed() const { @@ -604,11 +608,7 @@ GLTexelFormat GLTexelFormat::evalGLTexelFormat(const Element& dstFormat, const E } case gpu::NUINT8: { if ((dstFormat.getSemantic() == gpu::SRGB || dstFormat.getSemantic() == gpu::SRGBA)) { -#if defined(USE_GLES) - texel.internalFormat = GL_SLUMINANCE8_NV; -#else texel.internalFormat = GL_SLUMINANCE8_EXT; -#endif } else { texel.internalFormat = GL_R8; } @@ -642,21 +642,13 @@ GLTexelFormat GLTexelFormat::evalGLTexelFormat(const Element& dstFormat, const E case gpu::DEPTH: texel.format = GL_DEPTH_COMPONENT; // It's depth component to load it -#if defined(USE_GLES) - texel.internalFormat = GL_DEPTH_COMPONENT32_OES; -#else texel.internalFormat = GL_DEPTH_COMPONENT32; -#endif switch (dstFormat.getType()) { case gpu::UINT32: case gpu::INT32: case gpu::NUINT32: case gpu::NINT32: { -#if defined(USE_GLES) - texel.internalFormat = GL_DEPTH_COMPONENT32_OES; -#else texel.internalFormat = GL_DEPTH_COMPONENT32; -#endif break; } case gpu::FLOAT: { From 1405c8fcb3d93781179ce6081a7aa139f1a5cd13 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 8 Mar 2018 15:21:55 -0800 Subject: [PATCH 09/19] add a client only option to cmake --- CMakeLists.txt | 90 +++++++++++++++------------ cmake/macros/GenerateInstallers.cmake | 9 ++- interface/CMakeLists.txt | 25 ++++---- plugins/hifiCodec/CMakeLists.txt | 4 +- plugins/pcmCodec/CMakeLists.txt | 4 +- tools/oven/CMakeLists.txt | 4 +- 6 files changed, 78 insertions(+), 58 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ff9fbe9244..7052276956 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,8 +14,12 @@ include("cmake/init.cmake") include("cmake/compiler.cmake") if (BUILD_SCRIBE_ONLY) - add_subdirectory(tools/scribe) - return() + add_subdirectory(tools/scribe) + return() +endif() + +if (NOT DEFINED CLIENT_ONLY) + set(CLIENT_ONLY 0) endif() if (NOT DEFINED SERVER_ONLY) @@ -23,42 +27,52 @@ if (NOT DEFINED SERVER_ONLY) endif() if (ANDROID OR UWP) - set(MOBILE 1) + set(MOBILE 1) else() - set(MOBILE 0) + set(MOBILE 0) endif() +set(BUILD_CLIENT_OPTION ON) +set(BUILD_SERVER_OPTION ON) +set(BUILD_TESTS_OPTION ON) +set(BUILD_TOOLS_OPTION ON) +set(BUILD_INSTALLER_OPTION ON) +set(GLES_OPTION OFF) +set(DISABLE_QML_OPTION OFF) + if (ANDROID OR UWP) - option(BUILD_SERVER "Build server components" OFF) - option(BUILD_TOOLS "Build tools" OFF) - option(BUILD_INSTALLER "Build installer" OFF) -else() - option(BUILD_SERVER "Build server components" ON) - option(BUILD_TOOLS "Build tools" ON) - option(BUILD_INSTALLER "Build installer" ON) + set(BUILD_SERVER_OPTION OFF) + set(BUILD_TOOLS_OPTION OFF) + set(BUILD_INSTALLER OFF) +endif() + +if (CLIENT_ONLY) + set(BUILD_SERVER_OPTION OFF) endif() if (SERVER_ONLY) - option(BUILD_CLIENT "Build client components" OFF) - option(BUILD_TESTS "Build tests" OFF) -else() - option(BUILD_CLIENT "Build client components" ON) - option(BUILD_TESTS "Build tests" ON) + set(BUILD_CLIENT_OPTION OFF) + set(BUILD_TESTS_OPTION OFF) endif() if (ANDROID) - option(USE_GLES "Use OpenGL ES" ON) - set(PLATFORM_QT_COMPONENTS AndroidExtras WebView) + set(GLES_OPTION ON) + set(PLATFORM_QT_COMPONENTS AndroidExtras WebView) else () - option(USE_GLES "Use OpenGL ES" OFF) - set(PLATFORM_QT_COMPONENTS WebEngine WebEngineWidgets) + set(PLATFORM_QT_COMPONENTS WebEngine WebEngineWidgets) endif () if (USE_GLES AND (NOT ANDROID)) - option(DISABLE_QML "Disable QML" ON) -else() - option(DISABLE_QML "Disable QML" OFF) + set(DISABLE_QML_OPTION ON) endif() + +option(BUILD_CLIENT "Build client components" ${BUILD_CLIENT_OPTION}) +option(BUILD_SERVER "Build server components" ${BUILD_SERVER_OPTION}) +option(BUILD_TESTS "Build tests" ${BUILD_TESTS_OPTION}) +option(BUILD_TOOLS "Build tools" ${BUILD_TOOLS_OPTION}) +option(BUILD_INSTALLER "Build installer" ${BUILD_INSTALLER_OPTION}) +option(USE_GLES "Use OpenGL ES" ${GLES_OPTION}) +option(DISABLE_QML "Disable QML" ${DISABLE_QML_OPTION}) option(DISABLE_KTX_CACHE "Disable KTX Cache" OFF) set(PLATFORM_QT_GL OpenGL) @@ -70,12 +84,10 @@ else() set(PLATFORM_GL_BACKEND gpu-gl) endif() - foreach(PLATFORM_QT_COMPONENT ${PLATFORM_QT_COMPONENTS}) list(APPEND PLATFORM_QT_LIBRARIES "Qt5::${PLATFORM_QT_COMPONENT}") endforeach() - MESSAGE(STATUS "Build server: " ${BUILD_SERVER}) MESSAGE(STATUS "Build client: " ${BUILD_CLIENT}) MESSAGE(STATUS "Build tests: " ${BUILD_TESTS}) @@ -84,17 +96,17 @@ MESSAGE(STATUS "Build installer: " ${BUILD_INSTALLER}) MESSAGE(STATUS "GL ES: " ${USE_GLES}) if (DISABLE_QML) -MESSAGE(STATUS "QML disabled!") -add_definitions(-DDISABLE_QML) + MESSAGE(STATUS "QML disabled!") + add_definitions(-DDISABLE_QML) endif() if (DISABLE_KTX_CACHE) -MESSAGE(STATUS "KTX cache disabled!") -add_definitions(-DDISABLE_KTX_CACHE) + MESSAGE(STATUS "KTX cache disabled!") + add_definitions(-DDISABLE_KTX_CACHE) endif() if (UNIX AND DEFINED ENV{HIFI_MEMORY_DEBUGGING}) - MESSAGE(STATUS "Memory debugging is enabled") + MESSAGE(STATUS "Memory debugging is enabled") endif() # @@ -160,16 +172,16 @@ endif() add_subdirectory(tools) if (BUILD_TESTS) - add_subdirectory(tests) + add_subdirectory(tests) endif() if (BUILD_INSTALLER) - if (UNIX) - install( - DIRECTORY "${CMAKE_SOURCE_DIR}/scripts" - DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/interface - COMPONENT ${CLIENT_COMPONENT} - ) - endif() - generate_installers() + if (UNIX) + install( + DIRECTORY "${CMAKE_SOURCE_DIR}/scripts" + DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/interface + COMPONENT ${CLIENT_COMPONENT} + ) + endif() + generate_installers() endif() diff --git a/cmake/macros/GenerateInstallers.cmake b/cmake/macros/GenerateInstallers.cmake index 032f83e8be..a263da677c 100644 --- a/cmake/macros/GenerateInstallers.cmake +++ b/cmake/macros/GenerateInstallers.cmake @@ -88,8 +88,13 @@ macro(GENERATE_INSTALLERS) set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE") - cpack_add_component(${CLIENT_COMPONENT} DISPLAY_NAME "High Fidelity Interface") - cpack_add_component(${SERVER_COMPONENT} DISPLAY_NAME "High Fidelity Sandbox") + if (BUILD_CLIENT) + cpack_add_component(${CLIENT_COMPONENT} DISPLAY_NAME "High Fidelity Interface") + endif () + + if (BUILD_SERVER) + cpack_add_component(${SERVER_COMPONENT} DISPLAY_NAME "High Fidelity Sandbox") + endif () include(CPack) endmacro() diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 4ce35027f2..d98ac67dfd 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -26,17 +26,17 @@ generate_qrc(OUTPUT ${RESOURCES_QRC} PATH ${CMAKE_CURRENT_SOURCE_DIR}/resources if (ANDROID) # on Android, don't compress the rcc binary add_custom_command( - OUTPUT ${RESOURCES_RCC} - DEPENDS ${RESOURCES_QRC} ${GENERATE_QRC_DEPENDS} - COMMAND "${QT_DIR}/bin/rcc" - ARGS ${RESOURCES_QRC} -no-compress -binary -o ${RESOURCES_RCC} + OUTPUT ${RESOURCES_RCC} + DEPENDS ${RESOURCES_QRC} ${GENERATE_QRC_DEPENDS} + COMMAND "${QT_DIR}/bin/rcc" + ARGS ${RESOURCES_QRC} -no-compress -binary -o ${RESOURCES_RCC} ) else () add_custom_command( - OUTPUT ${RESOURCES_RCC} - DEPENDS ${RESOURCES_QRC} ${GENERATE_QRC_DEPENDS} - COMMAND "${QT_DIR}/bin/rcc" - ARGS ${RESOURCES_QRC} -binary -o ${RESOURCES_RCC} + OUTPUT ${RESOURCES_RCC} + DEPENDS ${RESOURCES_QRC} ${GENERATE_QRC_DEPENDS} + COMMAND "${QT_DIR}/bin/rcc" + ARGS ${RESOURCES_QRC} -binary -o ${RESOURCES_RCC} ) endif() @@ -203,12 +203,6 @@ if (WIN32) add_dependency_external_projects(steamworks) endif() -# include OPENSSL -include_directories(SYSTEM "${OPENSSL_INCLUDE_DIR}") - -# append OpenSSL to our list of libraries to link -target_link_libraries(${TARGET_NAME} ${OPENSSL_LIBRARIES}) - # disable /OPT:REF and /OPT:ICF for the Debug builds # This will prevent the following linker warnings # LINK : warning LNK4075: ignoring '/INCREMENTAL' due to '/OPT:ICF' specification @@ -232,6 +226,9 @@ link_hifi_libraries( # include the binary directory of render-utils for shader includes target_include_directories(${TARGET_NAME} PRIVATE "${CMAKE_BINARY_DIR}/libraries/render-utils") +# include OpenSSL +target_openssl() + target_bullet() target_opengl() add_crashpad() diff --git a/plugins/hifiCodec/CMakeLists.txt b/plugins/hifiCodec/CMakeLists.txt index 28c1dc3807..9ecaf7b511 100644 --- a/plugins/hifiCodec/CMakeLists.txt +++ b/plugins/hifiCodec/CMakeLists.txt @@ -12,5 +12,7 @@ link_hifi_libraries(audio plugins) add_dependency_external_projects(hifiAudioCodec) target_include_directories(${TARGET_NAME} PRIVATE ${HIFIAUDIOCODEC_INCLUDE_DIRS}) target_link_libraries(${TARGET_NAME} ${HIFIAUDIOCODEC_LIBRARIES}) -install_beside_console() +if (BUILD_SERVER) + install_beside_console() +endif () diff --git a/plugins/pcmCodec/CMakeLists.txt b/plugins/pcmCodec/CMakeLists.txt index 900a642a88..cce33ecd1a 100644 --- a/plugins/pcmCodec/CMakeLists.txt +++ b/plugins/pcmCodec/CMakeLists.txt @@ -9,5 +9,7 @@ set(TARGET_NAME pcmCodec) setup_hifi_client_server_plugin() link_hifi_libraries(shared plugins) -install_beside_console() +if (BUILD_SERVER) + install_beside_console() +endif () diff --git a/tools/oven/CMakeLists.txt b/tools/oven/CMakeLists.txt index 549414cbab..71bb997303 100644 --- a/tools/oven/CMakeLists.txt +++ b/tools/oven/CMakeLists.txt @@ -18,4 +18,6 @@ elseif (APPLE) set_target_properties(${TARGET_NAME} PROPERTIES INSTALL_RPATH "@executable_path/../Frameworks") endif() -install_beside_console() +if (BUILD_SERVER) + install_beside_console() +endif () From c743bfcf278cb83733609c7059c36e5e40e2246b Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 8 Mar 2018 17:02:13 -0800 Subject: [PATCH 10/19] templatize conditional for selection of server component --- cmake/macros/SetPackagingParameters.cmake | 18 +++++++++++++----- cmake/templates/CPackProperties.cmake.in | 1 + cmake/templates/NSIS.template.in | 20 ++++++++++---------- 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/cmake/macros/SetPackagingParameters.cmake b/cmake/macros/SetPackagingParameters.cmake index a962504e72..a47452c7cf 100644 --- a/cmake/macros/SetPackagingParameters.cmake +++ b/cmake/macros/SetPackagingParameters.cmake @@ -27,6 +27,11 @@ macro(SET_PACKAGING_PARAMETERS) message(STATUS "The BRANCH environment variable is: $ENV{BRANCH}") message(STATUS "The RELEASE_TYPE variable is: ${RELEASE_TYPE}") + # setup component categories for installer + set(DDE_COMPONENT dde) + set(CLIENT_COMPONENT client) + set(SERVER_COMPONENT server) + if (RELEASE_TYPE STREQUAL "PRODUCTION") set(DEPLOY_PACKAGE TRUE) set(PRODUCTION_BUILD 1) @@ -151,12 +156,15 @@ macro(SET_PACKAGING_PARAMETERS) set(CUSTOM_INSTALL_REG_KEY "CustomInstall") set(CLIENT_ID_REG_KEY "ClientGUID") set(GA_TRACKING_ID $ENV{GA_TRACKING_ID}) - endif () - # setup component categories for installer - set(DDE_COMPONENT dde) - set(CLIENT_COMPONENT client) - set(SERVER_COMPONENT server) + # setup conditional checks for server component selection depending on + # the inclusion of the server component at all + if (CLIENT_ONLY) + set(SERVER_COMPONENT_CONDITIONAL "0 == 1") + else () + set(SERVER_COMPONENT_CONDITIONAL "\${SectionIsSelected} \${${SERVER_COMPONENT_NAME}}") + endif () + endif () # print out some results for testing this new build feature message(STATUS "The BUILD_GLOBAL_SERVICES variable is: ${BUILD_GLOBAL_SERVICES}") diff --git a/cmake/templates/CPackProperties.cmake.in b/cmake/templates/CPackProperties.cmake.in index 1a0fa2fac7..ad38e067b6 100644 --- a/cmake/templates/CPackProperties.cmake.in +++ b/cmake/templates/CPackProperties.cmake.in @@ -46,3 +46,4 @@ set(CLIENT_ID_REG_KEY "@CLIENT_ID_REG_KEY@") set(INSTALLER_HEADER_IMAGE "@INSTALLER_HEADER_IMAGE@") set(UNINSTALLER_HEADER_IMAGE "@UNINSTALLER_HEADER_IMAGE@") set(ADD_REMOVE_ICON_PATH "@ADD_REMOVE_ICON_PATH@") +set(SERVER_COMPONENT_CONDITIONAL "@SERVER_COMPONENT_CONDITIONAL@") diff --git a/cmake/templates/NSIS.template.in b/cmake/templates/NSIS.template.in index f174727f95..5f652f58b6 100644 --- a/cmake/templates/NSIS.template.in +++ b/cmake/templates/NSIS.template.in @@ -658,7 +658,7 @@ Function PostInstallOptionsPage !insertmacro SetInstallOption $DesktopClientCheckbox @CLIENT_DESKTOP_SHORTCUT_REG_KEY@ ${BST_CHECKED} ${EndIf} - ${If} ${SectionIsSelected} ${@SERVER_COMPONENT_NAME@} + ${If} @SERVER_COMPONENT_CONDITIONAL@ ${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Create a desktop shortcut for @CONSOLE_HF_SHORTCUT_NAME@" Pop $DesktopServerCheckbox IntOp $CurrentOffset $CurrentOffset + 15 @@ -667,7 +667,7 @@ Function PostInstallOptionsPage !insertmacro SetInstallOption $DesktopServerCheckbox @CONSOLE_DESKTOP_SHORTCUT_REG_KEY@ ${BST_UNCHECKED} ${EndIf} - ${If} ${SectionIsSelected} ${@SERVER_COMPONENT_NAME@} + ${If} @SERVER_COMPONENT_CONDITIONAL@ ${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Launch @CONSOLE_HF_SHORTCUT_NAME@ after install" Pop $LaunchServerNowCheckbox @@ -694,7 +694,7 @@ Function PostInstallOptionsPage ${EndIf} ${EndIf} - ${If} ${SectionIsSelected} ${@SERVER_COMPONENT_NAME@} + ${If} @SERVER_COMPONENT_CONDITIONAL@ ${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Launch @CONSOLE_HF_SHORTCUT_NAME@ on startup" Pop $ServerStartupCheckbox IntOp $CurrentOffset $CurrentOffset + 15 @@ -703,7 +703,7 @@ Function PostInstallOptionsPage !insertmacro SetInstallOption $ServerStartupCheckbox @CONSOLE_STARTUP_REG_KEY@ ${BST_CHECKED} ${EndIf} - ${If} ${SectionIsSelected} ${@CLIENT_COMPONENT_NAME@} + ${If} @SERVER_COMPONENT_CONDITIONAL@ ${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Perform a clean install (Delete older settings and content)" Pop $CleanInstallCheckbox IntOp $CurrentOffset $CurrentOffset + 15 @@ -715,7 +715,7 @@ Function PostInstallOptionsPage ${NSD_SetState} $DesktopClientCheckbox ${BST_UNCHECKED} ${EndIf} - ${If} ${SectionIsSelected} ${@SERVER_COMPONENT_NAME@} + ${If} @SERVER_COMPONENT_CONDITIONAL@ ${NSD_SetState} $DesktopServerCheckbox ${BST_UNCHECKED} ${NSD_SetState} $ServerStartupCheckbox ${BST_UNCHECKED} ${EndIf} @@ -779,7 +779,7 @@ Function ReadPostInstallOptions ${NSD_GetState} $DesktopClientCheckbox $DesktopClientState ${EndIf} - ${If} ${SectionIsSelected} ${@SERVER_COMPONENT_NAME@} + ${If} @SERVER_COMPONENT_CONDITIONAL@ ; check if the user asked for a desktop shortcut to Sandbox ${NSD_GetState} $DesktopServerCheckbox $DesktopServerState @@ -792,7 +792,7 @@ Function ReadPostInstallOptions ${NSD_GetState} $CopyFromProductionCheckbox $CopyFromProductionState ${EndIf} - ${If} ${SectionIsSelected} ${@SERVER_COMPONENT_NAME@} + ${If} @SERVER_COMPONENT_CONDITIONAL@ ; check if we need to launch the server post-install ${NSD_GetState} $LaunchServerNowCheckbox $LaunchServerNowState ${EndIf} @@ -820,7 +820,7 @@ Function HandlePostInstallOptions ${EndIf} - ${If} ${SectionIsSelected} ${@SERVER_COMPONENT_NAME@} + ${If} @SERVER_COMPONENT_CONDITIONAL@ ; check if the user asked for a desktop shortcut to Sandbox ${If} $DesktopServerState == ${BST_CHECKED} CreateShortCut "$DESKTOP\@CONSOLE_HF_SHORTCUT_NAME@.lnk" "$INSTDIR\@CONSOLE_INSTALL_SUBDIR@\@CONSOLE_WIN_EXEC_NAME@" @@ -1041,7 +1041,7 @@ Section "-Core installation" ${EndIf} ; Conditional handling for server console shortcut - ${If} ${SectionIsSelected} ${@SERVER_COMPONENT_NAME@} + ${If} @SERVER_COMPONENT_CONDITIONAL@ CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\@CONSOLE_SHORTCUT_NAME@.lnk" \ "$INSTDIR\@CONSOLE_INSTALL_SUBDIR@\@CONSOLE_WIN_EXEC_NAME@" ${EndIf} @@ -1186,7 +1186,7 @@ Function .onSelChange ; if neither component is selected, disable the install button ${IfNot} ${SectionIsSelected} ${@CLIENT_COMPONENT_NAME@} - ${AndIfNot} ${SectionIsSelected} ${@SERVER_COMPONENT_NAME@} + ${AndIfNot} @SERVER_COMPONENT_CONDITIONAL@ GetDlgItem $0 $HWNDPARENT 1 EnableWindow $0 0 ${Else} From f93935f5f6d3bb08562a989e2f9d9b5bc2081b57 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 13 Mar 2018 13:58:51 -0700 Subject: [PATCH 11/19] change PR build compression to bzip2 --- cmake/macros/GenerateInstallers.cmake | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/cmake/macros/GenerateInstallers.cmake b/cmake/macros/GenerateInstallers.cmake index a263da677c..b770bc9e7f 100644 --- a/cmake/macros/GenerateInstallers.cmake +++ b/cmake/macros/GenerateInstallers.cmake @@ -22,11 +22,12 @@ macro(GENERATE_INSTALLERS) set(CPACK_PACKAGE_FILE_NAME "HighFidelity-Beta-${BUILD_VERSION}") set(CPACK_NSIS_DISPLAY_NAME ${_DISPLAY_NAME}) set(CPACK_NSIS_PACKAGE_NAME ${_DISPLAY_NAME}) - if (PR_BUILD) - set(CPACK_NSIS_COMPRESSOR "/SOLID bzip2") - endif () - set(CPACK_PACKAGE_INSTALL_DIRECTORY ${_DISPLAY_NAME}) + if (PR_BUILD) + set(CPACK_NSIS_COMPRESSOR "bzip2") + endif () + + set(CPACK_PACKAGE_INSTALL_DIRECTORY ${_DISPLAY_NAME}) if (WIN32) set(CPACK_NSIS_MUI_ICON "${HF_CMAKE_DIR}/installer/installer.ico") From 6ee6f8808770dba48c45615073681f82365129e5 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 13 Mar 2018 15:07:52 -0700 Subject: [PATCH 12/19] only add components to cmake for multi-component installer --- cmake/macros/GenerateInstallers.cmake | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/cmake/macros/GenerateInstallers.cmake b/cmake/macros/GenerateInstallers.cmake index b770bc9e7f..215e2bf3ca 100644 --- a/cmake/macros/GenerateInstallers.cmake +++ b/cmake/macros/GenerateInstallers.cmake @@ -22,13 +22,12 @@ macro(GENERATE_INSTALLERS) set(CPACK_PACKAGE_FILE_NAME "HighFidelity-Beta-${BUILD_VERSION}") set(CPACK_NSIS_DISPLAY_NAME ${_DISPLAY_NAME}) set(CPACK_NSIS_PACKAGE_NAME ${_DISPLAY_NAME}) - if (PR_BUILD) set(CPACK_NSIS_COMPRESSOR "bzip2") endif () - set(CPACK_PACKAGE_INSTALL_DIRECTORY ${_DISPLAY_NAME}) + if (WIN32) set(CPACK_NSIS_MUI_ICON "${HF_CMAKE_DIR}/installer/installer.ico") @@ -59,6 +58,10 @@ macro(GENERATE_INSTALLERS) set(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION ${INTERFACE_INSTALL_DIR}) set(CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT ${CLIENT_COMPONENT}) include(InstallRequiredSystemLibraries) + + if (CLIENT_ONLY OR SERVER_ONLY) + set(CPACK_MONOLITHIC_INSTALL 1) + endif () elseif (APPLE) # produce a drag and drop DMG on OS X set(CPACK_GENERATOR "DragNDrop") From 932c55ca089d2f3b1c7d7d2c13c43da20d33c059 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 13 Mar 2018 15:30:10 -0700 Subject: [PATCH 13/19] handle client section in component-less install --- cmake/macros/GenerateInstallers.cmake | 10 ++++++++++ cmake/macros/SetPackagingParameters.cmake | 8 -------- cmake/templates/CPackProperties.cmake.in | 1 + cmake/templates/NSIS.template.in | 20 ++++++++++---------- 4 files changed, 21 insertions(+), 18 deletions(-) diff --git a/cmake/macros/GenerateInstallers.cmake b/cmake/macros/GenerateInstallers.cmake index 215e2bf3ca..5c68997b8e 100644 --- a/cmake/macros/GenerateInstallers.cmake +++ b/cmake/macros/GenerateInstallers.cmake @@ -62,6 +62,16 @@ macro(GENERATE_INSTALLERS) if (CLIENT_ONLY OR SERVER_ONLY) set(CPACK_MONOLITHIC_INSTALL 1) endif () + + # setup conditional checks for server component selection depending on + # the inclusion of the server component at all + if (CLIENT_ONLY) + set(SERVER_COMPONENT_CONDITIONAL "0 == 1") + set(CLIENT_COMPONENT_CONDITIONAL "1 == 1") + else () + set(SERVER_COMPONENT_CONDITIONAL "\\\${SectionIsSelected} \\\${${SERVER_COMPONENT}}") + set(CLIENT_COMPONENT_CONDITIONAL "\\\${SectionIsSelected} \\\${${CLIENT_COMPONENT}}") + endif () elseif (APPLE) # produce a drag and drop DMG on OS X set(CPACK_GENERATOR "DragNDrop") diff --git a/cmake/macros/SetPackagingParameters.cmake b/cmake/macros/SetPackagingParameters.cmake index a47452c7cf..601fbdaa20 100644 --- a/cmake/macros/SetPackagingParameters.cmake +++ b/cmake/macros/SetPackagingParameters.cmake @@ -156,14 +156,6 @@ macro(SET_PACKAGING_PARAMETERS) set(CUSTOM_INSTALL_REG_KEY "CustomInstall") set(CLIENT_ID_REG_KEY "ClientGUID") set(GA_TRACKING_ID $ENV{GA_TRACKING_ID}) - - # setup conditional checks for server component selection depending on - # the inclusion of the server component at all - if (CLIENT_ONLY) - set(SERVER_COMPONENT_CONDITIONAL "0 == 1") - else () - set(SERVER_COMPONENT_CONDITIONAL "\${SectionIsSelected} \${${SERVER_COMPONENT_NAME}}") - endif () endif () # print out some results for testing this new build feature diff --git a/cmake/templates/CPackProperties.cmake.in b/cmake/templates/CPackProperties.cmake.in index ad38e067b6..9c303f7532 100644 --- a/cmake/templates/CPackProperties.cmake.in +++ b/cmake/templates/CPackProperties.cmake.in @@ -47,3 +47,4 @@ set(INSTALLER_HEADER_IMAGE "@INSTALLER_HEADER_IMAGE@") set(UNINSTALLER_HEADER_IMAGE "@UNINSTALLER_HEADER_IMAGE@") set(ADD_REMOVE_ICON_PATH "@ADD_REMOVE_ICON_PATH@") set(SERVER_COMPONENT_CONDITIONAL "@SERVER_COMPONENT_CONDITIONAL@") +set(CLIENT_COMPONENT_CONDITIONAL "@CLIENT_COMPONENT_CONDITIONAL@") diff --git a/cmake/templates/NSIS.template.in b/cmake/templates/NSIS.template.in index 5f652f58b6..f9a70ee10e 100644 --- a/cmake/templates/NSIS.template.in +++ b/cmake/templates/NSIS.template.in @@ -649,7 +649,7 @@ Function PostInstallOptionsPage StrCpy $CurrentOffset 0 StrCpy $OffsetUnits u - ${If} ${SectionIsSelected} ${@CLIENT_COMPONENT_NAME@} + ${If} @CLIENT_COMPONENT_CONDITIONAL@ ${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Create a desktop shortcut for @INTERFACE_HF_SHORTCUT_NAME@" Pop $DesktopClientCheckbox IntOp $CurrentOffset $CurrentOffset + 15 @@ -681,7 +681,7 @@ Function PostInstallOptionsPage IntOp $CurrentOffset $CurrentOffset + 15 ${EndIf} - ${If} ${SectionIsSelected} ${@CLIENT_COMPONENT_NAME@} + ${If} @CLIENT_COMPONENT_CONDITIONAL@ ${NSD_CreateCheckbox} 0 $CurrentOffset$OffsetUnits 100% 10u "&Launch @INTERFACE_HF_SHORTCUT_NAME@ after install" Pop $LaunchClientNowCheckbox IntOp $CurrentOffset $CurrentOffset + 30 @@ -711,7 +711,7 @@ Function PostInstallOptionsPage ${If} @PR_BUILD@ == 1 ; a PR build defaults all install options expect LaunchServerNowCheckbox, LaunchClientNowCheckbox and the settings copy to unchecked - ${If} ${SectionIsSelected} ${@CLIENT_COMPONENT_NAME@} + ${If} @CLIENT_COMPONENT_CONDITIONAL@ ${NSD_SetState} $DesktopClientCheckbox ${BST_UNCHECKED} ${EndIf} @@ -774,7 +774,7 @@ Function ReadInstallTypes FunctionEnd Function ReadPostInstallOptions - ${If} ${SectionIsSelected} ${@CLIENT_COMPONENT_NAME@} + ${If} @CLIENT_COMPONENT_CONDITIONAL@ ; check if the user asked for a desktop shortcut to High Fidelity ${NSD_GetState} $DesktopClientCheckbox $DesktopClientState ${EndIf} @@ -797,19 +797,19 @@ Function ReadPostInstallOptions ${NSD_GetState} $LaunchServerNowCheckbox $LaunchServerNowState ${EndIf} - ${If} ${SectionIsSelected} ${@CLIENT_COMPONENT_NAME@} + ${If} @CLIENT_COMPONENT_CONDITIONAL@ ; check if we need to launch the client post-install ${NSD_GetState} $LaunchClientNowCheckbox $LaunchClientNowState ${EndIf} - ${If} ${SectionIsSelected} ${@CLIENT_COMPONENT_NAME@} + ${If} @CLIENT_COMPONENT_CONDITIONAL@ ; check if the user asked for a clean install ${NSD_GetState} $CleanInstallCheckbox $CleanInstallState ${EndIf} FunctionEnd Function HandlePostInstallOptions - ${If} ${SectionIsSelected} ${@CLIENT_COMPONENT_NAME@} + ${If} @CLIENT_COMPONENT_CONDITIONAL@ ; check if the user asked for a desktop shortcut to High Fidelity ${If} $DesktopClientState == ${BST_CHECKED} CreateShortCut "$DESKTOP\@INTERFACE_HF_SHORTCUT_NAME@.lnk" "$INSTDIR\@INTERFACE_WIN_EXEC_NAME@" @@ -849,7 +849,7 @@ Function HandlePostInstallOptions ${EndIf} ${EndIf} - ${If} ${SectionIsSelected} ${@CLIENT_COMPONENT_NAME@} + ${If} @CLIENT_COMPONENT_CONDITIONAL@ ; check if the user asked for a clean install ${If} $CleanInstallState == ${BST_CHECKED} SetShellVarContext current @@ -1026,7 +1026,7 @@ Section "-Core installation" @CPACK_NSIS_CREATE_ICONS_EXTRA@ ; Conditional handling for Interface specific options - ${If} ${SectionIsSelected} ${@CLIENT_COMPONENT_NAME@} + ${If} @CLIENT_COMPONENT_CONDITIONAL@ CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\@INTERFACE_SHORTCUT_NAME@.lnk" \ "$INSTDIR\@INTERFACE_WIN_EXEC_NAME@" @@ -1185,7 +1185,7 @@ Function .onSelChange !insertmacro SectionList MaybeSelectionChanged ; if neither component is selected, disable the install button - ${IfNot} ${SectionIsSelected} ${@CLIENT_COMPONENT_NAME@} + ${IfNot} @CLIENT_COMPONENT_CONDITIONAL@ ${AndIfNot} @SERVER_COMPONENT_CONDITIONAL@ GetDlgItem $0 $HWNDPARENT 1 EnableWindow $0 0 From 38606f83c8379522d08b39da402399ac52f69fd6 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 14 Mar 2018 16:29:47 -0700 Subject: [PATCH 14/19] add SERVER_ONLY handling for installer generation --- cmake/macros/GenerateInstallers.cmake | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmake/macros/GenerateInstallers.cmake b/cmake/macros/GenerateInstallers.cmake index 5c68997b8e..742c5b5b94 100644 --- a/cmake/macros/GenerateInstallers.cmake +++ b/cmake/macros/GenerateInstallers.cmake @@ -68,6 +68,9 @@ macro(GENERATE_INSTALLERS) if (CLIENT_ONLY) set(SERVER_COMPONENT_CONDITIONAL "0 == 1") set(CLIENT_COMPONENT_CONDITIONAL "1 == 1") + elseif (SERVER_ONLY) + set(SERVER_COMPONENT_CONDITIONAL "1 == 1") + set(CLIENT_COMPONENT_CONDITIONAL "0 == 1") else () set(SERVER_COMPONENT_CONDITIONAL "\\\${SectionIsSelected} \\\${${SERVER_COMPONENT}}") set(CLIENT_COMPONENT_CONDITIONAL "\\\${SectionIsSelected} \\\${${CLIENT_COMPONENT}}") From 9a664f25dcc194e810d99ebd47b2c5b1440d5fd6 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 16 Mar 2018 10:28:00 -0700 Subject: [PATCH 15/19] setup custom or express label correctly in installer --- cmake/templates/NSIS.template.in | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cmake/templates/NSIS.template.in b/cmake/templates/NSIS.template.in index f9a70ee10e..c2a223146d 100644 --- a/cmake/templates/NSIS.template.in +++ b/cmake/templates/NSIS.template.in @@ -612,10 +612,11 @@ Function InstallTypesPage ${If} $CustomInstallTemporaryState == ${BST_UNCHECKED} ${NSD_Check} $ExpressInstallRadioButton + Call ChangeExpressLabel + ${Else} + Call ChangeCustomLabel ${EndIf} - Call ChangeExpressLabel - nsDialogs::Show FunctionEnd From 45d16731c3a0a14673dea66160c7a9e6b7b42f06 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 16 Mar 2018 13:48:02 -0700 Subject: [PATCH 16/19] fix abort of setup options page for express client --- cmake/templates/NSIS.template.in | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cmake/templates/NSIS.template.in b/cmake/templates/NSIS.template.in index c2a223146d..5a7dd3ced3 100644 --- a/cmake/templates/NSIS.template.in +++ b/cmake/templates/NSIS.template.in @@ -437,6 +437,12 @@ SectionEnd !define MUI_PAGE_CUSTOMFUNCTION_PRE PageComponentsPre @CPACK_NSIS_PAGE_COMPONENTS@ + ; the MUI_PAGE_CUSTOMFUNCTION_PRE shouldn't be defined here + ; which can happen for a component-less (like client only) install + !ifdef MUI_PAGE_CUSTOMFUNCTION_PRE + !undef MUI_PAGE_CUSTOMFUNCTION_PRE + !endif + Page custom PostInstallOptionsPage ReadPostInstallOptions !define MUI_PAGE_CUSTOMFUNCTION_PRE PageInstallFilesPre From cfdf8c25882fa5b62e5a7e8bd679f3fa9ec6a361 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 19 Mar 2018 13:58:07 -0700 Subject: [PATCH 17/19] handle launch client option for client only --- cmake/templates/NSIS.template.in | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cmake/templates/NSIS.template.in b/cmake/templates/NSIS.template.in index 5a7dd3ced3..7faa67d1b0 100644 --- a/cmake/templates/NSIS.template.in +++ b/cmake/templates/NSIS.template.in @@ -893,7 +893,8 @@ Function HandlePostInstallOptions ${EndIf} ${EndIf} - ${If} $LaunchServerNowState == ${BST_CHECKED} + ${If} @SERVER_COMPONENT_CONDITIONAL@ + ${AndIf} $LaunchServerNowState == ${BST_CHECKED} !insertmacro WriteInstallOption @SERVER_LAUNCH_NOW_REG_KEY@ YES ; both launches use the explorer trick in case the user has elevated permissions for the installer @@ -907,7 +908,7 @@ Function HandlePostInstallOptions Exec '"$WINDIR\explorer.exe" "$INSTDIR\@CONSOLE_INSTALL_SUBDIR@\@CONSOLE_WIN_EXEC_NAME@"' ${EndIf} - ${Else} + ${ElseIf} @CLIENT_COMPONENT_CONDITIONAL@ !insertmacro WriteInstallOption @SERVER_LAUNCH_NOW_REG_KEY@ NO ; launch uses the explorer trick in case the user has elevated permissions for the installer From d5d8e4c0b0f23c9d375a5f8b2e9330acd360c534 Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Tue, 20 Mar 2018 18:28:53 -0700 Subject: [PATCH 18/19] Restoring geometry shader --- libraries/gpu-gl-common/src/gpu/gl/GLBackendShader.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackendShader.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackendShader.cpp index 8fab860c8a..46931ec08f 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackendShader.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackendShader.cpp @@ -36,13 +36,15 @@ R"SHADER( // Shader domain -static const size_t NUM_SHADER_DOMAINS = 2; +static const size_t NUM_SHADER_DOMAINS = 3; +static_assert(Shader::Type::NUM_DOMAINS == NUM_SHADER_DOMAINS, "GL shader domains must equal defined GPU shader domains"); // GL Shader type enums // Must match the order of type specified in gpu::Shader::Type static const std::array SHADER_DOMAINS{ { GL_VERTEX_SHADER, GL_FRAGMENT_SHADER, + GL_GEOMETRY_SHADER, } }; // Domain specific defines @@ -50,6 +52,7 @@ static const std::array SHADER_DOMAINS{ { static const std::array DOMAIN_DEFINES{ { "#define GPU_VERTEX_SHADER", "#define GPU_PIXEL_SHADER", + "#define GPU_GEOMETRY_SHADER", } }; // Stereo specific defines From 00aa564d84f57e0add0b02bfde28183af663dbf4 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 21 Mar 2018 10:19:44 -0700 Subject: [PATCH 19/19] Fix crashes on exit because of ResourceManager thread destruction --- tools/oven/src/Oven.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/oven/src/Oven.cpp b/tools/oven/src/Oven.cpp index a9aa6907f1..c3fec2d15e 100644 --- a/tools/oven/src/Oven.cpp +++ b/tools/oven/src/Oven.cpp @@ -40,6 +40,8 @@ Oven::Oven() { } Oven::~Oven() { + DependencyManager::get()->cleanup(); + // quit all worker threads and wait on them for (auto& thread : _workerThreads) { thread->quit();