Extract uniform blocks and their uniforms via the reflection interface.
Ensure sampler order is still lexical.
Added buffer offset alignment handling - memory for uniform blocks
within a buffer must be aligned according to the current graphics
context.
Change-Id: I2b06d23057904a2e2ecbb67aff42c229ab89162d
#include "test-gl-abstraction.h"
#include "test-trace-call-stack.h"
-static const bool TRACE{
- false};
+static const bool TRACE{false};
+
+uint32_t GetGLDataTypeSize(GLenum type)
+{
+ // There are many more types than what are covered here, but
+ // they are not supported in dali.
+ switch(type)
+ {
+ case GL_FLOAT: // "float", 1 float, 4 bytes
+ return 4;
+ case GL_FLOAT_VEC2: // "vec2", 2 floats, 8 bytes
+ return 8;
+ case GL_FLOAT_VEC3: // "vec3", 3 floats, 12 bytes
+ return 12;
+ case GL_FLOAT_VEC4: // "vec4", 4 floats, 16 bytes
+ return 16;
+ case GL_INT: // "int", 1 integer, 4 bytes
+ return 4;
+ case GL_FLOAT_MAT2: // "mat2", 4 floats, 16 bytes
+ return 16;
+ case GL_FLOAT_MAT3: // "mat3", 3 vec3, 36 bytes
+ return 36;
+ case GL_FLOAT_MAT4: // "mat4", 4 vec4, 64 bytes
+ return 64;
+ default:
+ return 0;
+ }
+}
namespace Dali
{
{"uLightCameraProjectionMatrix", GL_FLOAT_MAT4, 1},
{"uLightCameraViewMatrix", GL_FLOAT_MAT4, 1}};
+ int offset = 0;
+ for(uint32_t i = 0; i < mActiveUniforms.size(); ++i)
+ {
+ mActiveUniforms[i].offset = offset;
+ offset += mActiveUniforms[i].size * GetGLDataTypeSize(mActiveUniforms[i].type);
+ }
// WARNING: IF YOU CHANGE THIS LIST, ALSO CHANGE UNIFORMS IN test-graphics-reflection.cpp
}
return ((imageGlFormat == GL_RGB) && (textureGlFormat == GL_RGBA));
}
+void TestGlAbstraction::SetActiveUniforms(const std::vector<ActiveUniform>& uniforms)
+{
+ mActiveUniforms = uniforms;
+ int offset = 0;
+ for(uint32_t i = 0; i < uniforms.size(); ++i)
+ {
+ mActiveUniforms[i].offset = offset;
+ offset += mActiveUniforms[i].size * GetGLDataTypeSize(mActiveUniforms[i].type);
+ }
+}
+
} // namespace Dali
bool BlendEnabled(const Dali::TraceCallStack& callStack)
struct ActiveUniform
{
- std::string name;
- GLenum type;
- GLint size;
+ std::string name{};
+ GLenum type{GL_FLOAT};
+ GLint size{0};
+ GLint offset{0};
};
class DALI_CORE_API TestGlAbstraction : public Dali::Integration::GlAbstraction
inline void DeleteBuffers(GLsizei n, const GLuint* buffers) override
{
+ TraceCallStack::NamedParams namedParams;
+ namedParams["n"] << n;
+ namedParams["id"] << buffers[0];
+ mBufferTrace.PushCall("DeleteBuffers", namedParams.str(), namedParams);
}
inline void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers) override
inline void GenBuffers(GLsizei n, GLuint* buffers) override
{
// avoids an assert in GpuBuffers
- *buffers = 1u;
+ static GLuint id = 1;
- std::ostringstream o;
- o << n;
TraceCallStack::NamedParams namedParams;
- namedParams["n"] << o.str();
- mBufferTrace.PushCall("GenBuffers", o.str(), namedParams);
+ namedParams["n"] << n;
+
+ // Allocate some buffer names
+ bool first = true;
+ while(n)
+ {
+ namedParams["buffers"] << (first ? "" : ", ") << id;
+ first = false;
+ *buffers++ = id++;
+ --n;
+ }
+ mBufferTrace.PushCall("GenBuffers", namedParams.str(), namedParams);
}
inline void GenerateMipmap(GLenum target) override
*type = mAttribTypes[index];
}
- inline void SetActiveUniforms(const std::vector<ActiveUniform>& uniforms)
- {
- mActiveUniforms = uniforms;
- }
+ void SetActiveUniforms(const std::vector<ActiveUniform>& uniforms);
inline void GetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) override
{
case GL_PROGRAM_BINARY_FORMATS_OES:
*params = mBinaryFormats;
break;
+ case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
+ *params = mUniformBufferOffsetAlignment;
+ break;
}
}
inline void GetActiveUniformsiv(GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params) override
{
+ for(int i = 0; i < uniformCount; ++i)
+ {
+ if(i < int(mActiveUniforms.size()))
+ {
+ switch(pname)
+ {
+ case GL_UNIFORM_TYPE:
+ {
+ params[i] = mActiveUniforms[i].type;
+ break;
+ }
+ case GL_UNIFORM_SIZE:
+ {
+ params[i] = mActiveUniforms[i].size;
+ break;
+ }
+ case GL_UNIFORM_NAME_LENGTH:
+ {
+ params[i] = mActiveUniforms[i].name.length();
+ break;
+ }
+ case GL_UNIFORM_BLOCK_INDEX:
+ {
+ params[i] = -1;
+ break;
+ }
+ case GL_UNIFORM_OFFSET:
+ {
+ params[i] = mActiveUniforms[i].offset;
+ break;
+ }
+ case GL_UNIFORM_MATRIX_STRIDE:
+ {
+ break;
+ }
+ }
+ }
+ }
}
inline GLuint GetUniformBlockIndex(GLuint program, const GLchar* uniformBlockName) override
{
mProgramBinaryLength = length;
}
-
+ inline void SetUniformBufferOffsetAlignment(GLint align)
+ {
+ mUniformBufferOffsetAlignment = align;
+ }
inline bool GetVertexAttribArrayState(GLuint index)
{
if(index >= MAX_ATTRIBUTE_CACHE_SIZE)
GLint mNumBinaryFormats;
GLint mBinaryFormats;
GLint mProgramBinaryLength;
+ GLint mUniformBufferOffsetAlignment{1};
bool mVertexAttribArrayState[MAX_ATTRIBUTE_CACHE_SIZE];
bool mVertexAttribArrayChanged; // whether the vertex attrib array has been changed
bool mGetProgramBinaryCalled;
namespace Dali
{
-TestGraphicsBuffer::TestGraphicsBuffer(TraceCallStack& callStack, TestGlAbstraction& glAbstraction, uint32_t size, Graphics::BufferUsageFlags usage)
+TestGraphicsBuffer::TestGraphicsBuffer(const Graphics::BufferCreateInfo& createInfo, TestGraphicsController& controller, TestGlAbstraction& glAbstraction, TraceCallStack& callStack)
: mCallStack(callStack),
+ mController(controller),
mGl(glAbstraction),
- mUsage(usage)
+ mCreateInfo(createInfo),
+ mUsage(createInfo.usage)
{
- memory.resize(size);
- mGl.GetBufferTrace().EnableLogging(false);
+ if(createInfo.propertiesFlags & int(Graphics::BufferPropertiesFlagBit::CPU_ALLOCATED))
+ {
+ mCpuOnly = true;
+ }
+ else
+ {
+ mGl.GenBuffers(1, &mId);
+ }
+ memory.resize(createInfo.size);
+}
+
+TestGraphicsBuffer::~TestGraphicsBuffer()
+{
+ // Not strictly parameters, but useful for testing
+ TraceCallStack::NamedParams namedParams;
+ namedParams["usage"] << "0x" << std::hex << mCreateInfo.usage;
+ namedParams["propertiesFlags"] << mCreateInfo.propertiesFlags;
+
+ mCallStack.PushCall("Buffer::~Buffer", namedParams.str(), namedParams);
+ if(!mCpuOnly && mId)
+ {
+ mGl.DeleteBuffers(1, &mId);
+ }
+}
+
+void TestGraphicsBuffer::DiscardResource()
+{
+ mController.DiscardBuffer(this);
}
void TestGraphicsBuffer::Bind()
{
mCallStack.PushCall("Buffer::Bind", "");
- if(!mId)
+ if(!mCpuOnly && mId > 0)
{
- mGl.GenBuffers(1, &mId);
+ mGl.BindBuffer(GetTarget(), mId);
}
- mGl.BindBuffer(GetTarget(), mId);
}
void TestGraphicsBuffer::Unbind()
{
mCallStack.PushCall("Buffer::Unbind", "");
- if(mId)
+ if(!mCpuOnly)
{
- mGl.BindBuffer(GetTarget(), 0);
+ if(mId)
+ {
+ mGl.BindBuffer(GetTarget(), 0);
+ }
}
}
namedParams["offset"] << offset;
namedParams["size"] << size;
mCallStack.PushCall("Buffer::Upload", o.str(), namedParams);
- if(size <= memory.size() && mCreated)
- {
- // Use subData to avoid re-allocation
- mGl.BufferSubData(GetTarget(), static_cast<GLintptr>(static_cast<unsigned long>(offset)), static_cast<GLsizeiptr>(static_cast<unsigned long>(size)), &memory[offset]);
- }
- else
+
+ if(!mCpuOnly)
{
- mGl.BufferData(GetTarget(), static_cast<GLsizeiptr>(static_cast<unsigned long>(size)), &memory[0], GL_STATIC_DRAW); //@todo Query - do we need other usages?
- mCreated = true;
+ if(size <= memory.size() && mCreated)
+ {
+ // Use subData to avoid re-allocation
+ mGl.BufferSubData(GetTarget(), static_cast<GLintptr>(static_cast<unsigned long>(offset)), static_cast<GLsizeiptr>(static_cast<unsigned long>(size)), &memory[offset]);
+ }
+ else
+ {
+ mGl.BufferData(GetTarget(), static_cast<GLsizeiptr>(static_cast<unsigned long>(size)), &memory[0], GL_STATIC_DRAW); //@todo Query - do we need other usages?
+ mCreated = true;
+ }
}
}
#define DALI_TEST_GRAPHICS_BUFFER_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* limitations under the License.
*/
+#include <dali/graphics-api/graphics-buffer-create-info.h>
#include <dali/graphics-api/graphics-buffer.h>
#include <dali/graphics-api/graphics-types.h>
namespace Dali
{
class TestGraphicsProgram;
+class TestGraphicsController;
class UniformBufferBindingDescriptor;
+
class TestGraphicsBuffer : public Graphics::Buffer
{
public:
- TestGraphicsBuffer(TraceCallStack& callStack, TestGlAbstraction& glAbstraction, uint32_t size, Graphics::BufferUsageFlags usage);
+ TestGraphicsBuffer(const Graphics::BufferCreateInfo& createInfo, TestGraphicsController& controller, TestGlAbstraction& glAbstraction, TraceCallStack& callStack);
+ ~TestGraphicsBuffer();
+ void DiscardResource();
+
void Bind();
void Unbind();
void Upload(uint32_t offset, uint32_t size);
bool IsCPUAllocated() const
{
- return true;
+ return mCpuOnly;
}
void BindAsUniformBuffer(const TestGraphicsProgram* program, const Dali::UniformBufferBindingDescriptor& uboBinding) const;
- TraceCallStack& mCallStack;
- TestGlAbstraction& mGl;
- std::vector<uint8_t> memory;
+ TraceCallStack& mCallStack;
+ TestGraphicsController& mController;
+ TestGlAbstraction& mGl;
+ std::vector<uint8_t> memory;
+
+ Graphics::BufferCreateInfo mCreateInfo;
Graphics::BufferUsageFlags mUsage;
GLuint mId{0};
bool mCreated{false};
+ bool mCpuOnly{false};
};
} // namespace Dali
#include "test-graphics-controller.h"
+#include <dali/graphics-api/graphics-types.h>
#include "test-graphics-buffer.h"
#include "test-graphics-command-buffer.h"
#include "test-graphics-framebuffer.h"
#include "test-graphics-texture.h"
#include <dali/integration-api/gl-defines.h>
+#include <any>
#include <cstdio>
#include <iostream>
+#include <memory>
#include <sstream>
-#include <any>
-
namespace Dali
{
+namespace
+{
+template<class T>
+struct TestGraphicsDeleter
+{
+ TestGraphicsDeleter() = default;
+ void operator()(T* object)
+ {
+ // Discard resource
+ object->DiscardResource();
+ }
+};
+
+} //namespace
+
std::ostream& operator<<(std::ostream& o, const Graphics::BufferCreateInfo& bufferCreateInfo)
{
return o << "usage:" << std::hex << bufferCreateInfo.usage << ", size:" << std::dec << bufferCreateInfo.size;
Graphics::UniquePtr<Graphics::Buffer> TestGraphicsController::CreateBuffer(const Graphics::BufferCreateInfo& createInfo, Graphics::UniquePtr<Graphics::Buffer>&& oldBuffer)
{
- std::ostringstream oss;
- oss << "bufferCreateInfo:" << createInfo;
- mCallStack.PushCall("CreateBuffer", oss.str());
- return Graphics::MakeUnique<TestGraphicsBuffer>(mCallStack, mGl, createInfo.size, createInfo.usage);
+ TraceCallStack::NamedParams namedParams;
+ namedParams["usage"] << "0x" << std::hex << createInfo.usage;
+ namedParams["propertiesFlags"] << createInfo.propertiesFlags;
+ namedParams["size"] << createInfo.size;
+ mCallStack.PushCall("CreateBuffer", namedParams.str(), namedParams);
+
+ auto ptr = Graphics::MakeUnique<TestGraphicsBuffer, TestGraphicsDeleter<TestGraphicsBuffer>>(createInfo, *this, mGl, mCallStack);
+ mAllocatedBuffers.push_back(ptr.get());
+ return ptr;
+}
+
+void TestGraphicsController::DiscardBuffer(TestGraphicsBuffer* buffer)
+{
+ auto iter = std::find(mAllocatedBuffers.begin(), mAllocatedBuffers.end(), buffer);
+ if(iter != mAllocatedBuffers.end())
+ {
+ mAllocatedBuffers.erase(iter);
+ }
+ delete buffer;
}
Graphics::UniquePtr<Graphics::CommandBuffer> TestGraphicsController::CreateCommandBuffer(const Graphics::CommandBufferCreateInfo& commandBufferCreateInfo, Graphics::UniquePtr<Graphics::CommandBuffer>&& oldCommandBuffer)
}
mProgramCache.emplace_back();
- mProgramCache.back().programImpl = new TestGraphicsProgramImpl(mGl, programCreateInfo, mVertexFormats, mCustomUniforms);
+ mProgramCache.back().programImpl = new TestGraphicsProgramImpl(mGl, programCreateInfo, mVertexFormats, mCustomUniforms, mCustomUniformBlocks);
+
for(auto& shader : *(programCreateInfo.shaderState))
{
auto graphicsShader = Uncast<TestGraphicsShader>(shader.shader);
Graphics::MemoryRequirements TestGraphicsController::GetBufferMemoryRequirements(Graphics::Buffer& buffer) const
{
+ static GLint uniformAlign{0};
+
+ Graphics::MemoryRequirements reqs{};
mCallStack.PushCall("GetBufferMemoryRequirements", "");
- return Graphics::MemoryRequirements{};
+
+ auto gfxBuffer = Uncast<TestGraphicsBuffer>(&buffer);
+ if(gfxBuffer->mCreateInfo.usage & (0 | Graphics::BufferUsage::UNIFORM_BUFFER))
+ {
+ if(!uniformAlign)
+ {
+ // Throw off the shackles of constness
+ auto& gl = *const_cast<TestGlAbstraction*>(&mGl);
+ gl.GetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &uniformAlign);
+ }
+ reqs.size = gfxBuffer->mCreateInfo.size;
+ reqs.alignment = uint32_t(uniformAlign);
+ }
+ return reqs;
}
Graphics::TextureProperties TestGraphicsController::GetTextureProperties(const Graphics::Texture& texture)
#define TEST_GRAPHICS_CONTROLLER_H
/*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
Graphics::UniquePtr<Graphics::Buffer> CreateBuffer(const Graphics::BufferCreateInfo& bufferCreateInfo, Graphics::UniquePtr<Graphics::Buffer>&& oldBuffer) override;
+ void DiscardBuffer(TestGraphicsBuffer* buffer);
+
/**
* @brief Creates new CommandBuffer object
*
mCustomUniforms = customUniforms;
}
+ void AddCustomUniformBlock(const TestGraphicsReflection::TestUniformBlockInfo& blockInfo)
+ {
+ mCustomUniformBlocks.push_back(blockInfo);
+ }
+
void ClearSubmitStack()
{
mSubmitStack.clear();
};
std::vector<ProgramCache> mProgramCache;
+ std::vector<TestGraphicsBuffer*> mAllocatedBuffers;
+
struct PipelineCache
{
};
- std::vector<UniformData> mCustomUniforms;
+ std::vector<UniformData> mCustomUniforms;
+ std::vector<TestGraphicsReflection::TestUniformBlockInfo> mCustomUniformBlocks;
};
} // namespace Dali
/*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
namespace Dali
{
-TestGraphicsProgramImpl::TestGraphicsProgramImpl(TestGlAbstraction& gl, const Graphics::ProgramCreateInfo& createInfo, Property::Array& vertexFormats, std::vector<UniformData>& customUniforms)
+TestGraphicsProgramImpl::TestGraphicsProgramImpl(TestGlAbstraction& gl, const Graphics::ProgramCreateInfo& createInfo, Property::Array& vertexFormats, std::vector<UniformData>& customUniforms, std::vector<TestGraphicsReflection::TestUniformBlockInfo>& customUniformBlocks)
: mGl(gl),
mId(gl.CreateProgram()),
mCreateInfo(createInfo),
- mReflection(gl, mId, vertexFormats, createInfo, customUniforms)
+ mReflection(gl, mId, vertexFormats, createInfo, customUniforms, customUniformBlocks)
{
// Ensure active sampler uniforms are set
mGl.SetCustomUniforms(customUniforms);
#define DALI_TEST_GRAPHICS_PROGRAM_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
class TestGraphicsProgramImpl
{
public:
- TestGraphicsProgramImpl(TestGlAbstraction& gl, const Graphics::ProgramCreateInfo& createInfo, Property::Array& vertexFormats, std::vector<UniformData>& customUniforms);
+ TestGraphicsProgramImpl(TestGlAbstraction& gl, const Graphics::ProgramCreateInfo& createInfo, Property::Array& vertexFormats, std::vector<UniformData>& customUniforms, std::vector<TestGraphicsReflection::TestUniformBlockInfo>& customUniformBlocks);
// For API
const TestGraphicsReflection& GetReflection() const
/*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <dali/public-api/object/property-map.h>
#include <string>
#include <vector>
+
+extern "C"
+{
+ void tet_infoline(const char* str);
+ void tet_printf(const char* format, ...);
+}
+
namespace Dali
{
namespace
} // namespace
-TestGraphicsReflection::TestGraphicsReflection(TestGlAbstraction& gl, uint32_t programId, Property::Array& vfs, const Graphics::ProgramCreateInfo& createInfo, std::vector<UniformData>& customUniforms)
+TestGraphicsReflection::TestGraphicsReflection(TestGlAbstraction& gl, uint32_t programId, Property::Array& vfs, const Graphics::ProgramCreateInfo& createInfo, std::vector<UniformData>& customUniforms, std::vector<TestGraphicsReflection::TestUniformBlockInfo>& customUniformBlocks)
: mGl(gl),
mCustomUniforms(customUniforms)
{
mDefaultUniformBlock.size = offset;
mUniformBlocks.push_back(mDefaultUniformBlock);
+ for(auto& element : customUniformBlocks)
+ {
+ mUniformBlocks.push_back(element);
+ }
}
uint32_t TestGraphicsReflection::GetVertexAttributeLocation(const std::string& name) const
Dali::Graphics::VertexInputAttributeFormat TestGraphicsReflection::GetVertexAttributeFormat(uint32_t location) const
{
+ tet_infoline("Warning, TestGraphicsReflection::GetVertexAttributeFormat is unimplemented\n");
return Dali::Graphics::VertexInputAttributeFormat{};
}
std::string TestGraphicsReflection::GetVertexAttributeName(uint32_t location) const
{
+ tet_infoline("Warning, TestGraphicsReflection::GetVertexAttributeName is unimplemented\n");
return 0u;
}
uint32_t TestGraphicsReflection::GetUniformBlockBinding(uint32_t index) const
{
- return 0u;
+ if(index >= mUniformBlocks.size())
+ {
+ return 0;
+ }
+ return mUniformBlocks[index].binding;
}
uint32_t TestGraphicsReflection::GetUniformBlockSize(uint32_t index) const
std::vector<uint32_t> TestGraphicsReflection::GetUniformBlockLocations() const
{
+ tet_infoline("Warning, TestGraphicsReflection::GetUniformBlockLocations is unimplemented\n");
return std::vector<uint32_t>{};
}
std::string TestGraphicsReflection::GetUniformBlockName(uint32_t blockIndex) const
{
+ tet_infoline("Warning, TestGraphicsReflection::GetUniformBlockName is unimplemented\n");
return std::string{};
}
bool TestGraphicsReflection::GetNamedUniform(const std::string& name, Dali::Graphics::UniformInfo& out) const
{
+ tet_infoline("Warning, TestGraphicsReflection::GetNamedUniform is unimplemented\n");
return true;
}
const std::vector<Dali::Graphics::UniformInfo>& TestGraphicsReflection::GetSamplers() const
{
+ tet_infoline("Warning, TestGraphicsReflection::GetSamplers is unimplemented\n");
static std::vector<Dali::Graphics::UniformInfo> samplers{};
return samplers;
}
#define DALI_TEST_GRAPHICS_REFLECTION_H
/*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
class TestGraphicsReflection : public Graphics::Reflection
{
public:
- TestGraphicsReflection(TestGlAbstraction& gl, uint32_t program_id, Property::Array& vertexFormats, const Graphics::ProgramCreateInfo& createInfo, std::vector<UniformData>& customUniforms);
+ class TestUniformBlockInfo;
+
+ TestGraphicsReflection(TestGlAbstraction& gl, uint32_t program_id, Property::Array& vertexFormats, const Graphics::ProgramCreateInfo& createInfo, std::vector<UniformData>& customUniforms, std::vector<TestUniformBlockInfo>& customUniformBlocks);
uint32_t GetVertexAttributeLocation(const std::string& name) const override;
Dali::Graphics::VertexInputAttributeFormat GetVertexAttributeFormat(uint32_t location) const override;
public:
TestGraphicsTexture(TestGlAbstraction& glAbstraction, const Graphics::TextureCreateInfo& createInfo);
- ~TestGraphicsTexture();
+ ~TestGraphicsTexture() override;
/**
* Initialize the texture: allocate gl mem, apply default samplers
/*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
for(auto iter = params.mParams.begin(); iter != params.mParams.end(); ++iter)
{
- auto paramIter = mCallStack[i].namedParams.find(iter->parameterName);
- std::string value = paramIter->value.str();
- std::string iValue = iter->value.str();
-
- if(paramIter == mCallStack[i].namedParams.end() || value.compare(iValue))
+ auto paramIter = mCallStack[i].namedParams.find(iter->parameterName);
+ if(paramIter == mCallStack[i].namedParams.end())
+ {
+ match = false;
+ break;
+ }
+ std::string value = paramIter->value.str();
+ std::string iValue = iter->value.str();
+ if(value.compare(iValue))
{
match = false;
break;
}
}
+MemoryRequirements EglGraphicsController::GetBufferMemoryRequirements(Buffer& buffer) const
+{
+ MemoryRequirements requirements{};
+
+ auto gl = GetGL();
+ if(gl)
+ {
+ GLint align;
+ gl->GetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &align);
+ requirements.alignment = align;
+ }
+ return requirements;
+}
+
TextureProperties EglGraphicsController::GetTextureProperties(const Texture& texture)
{
const GLES::Texture* glesTexture = static_cast<const GLES::Texture*>(&texture);
Graphics::UniquePtr<Memory> EglGraphicsController::MapBufferRange(const MapBufferInfo& mapInfo)
{
- mGraphics->ActivateResourceContext();
-
// Mapping buffer requires the object to be created NOW
// Workaround - flush now, otherwise there will be given a staging buffer
// in case when the buffer is not there yet
- ProcessCreateQueues();
+ if(!mCreateBufferQueue.empty())
+ {
+ mGraphics->ActivateResourceContext();
+ ProcessCreateQueues();
+ }
if(GetGLESVersion() < GLES::GLESVersion::GLES_30)
{
/**
* @copydoc Dali::Graphics::GetBufferMemoryRequirements()
*/
- MemoryRequirements GetBufferMemoryRequirements(Buffer& buffer) const override
- {
- return {};
- }
+ MemoryRequirements GetBufferMemoryRequirements(Buffer& buffer) const override;
/**
* @copydoc Dali::Graphics::GetTextureProperties()
mImpl->mCurrentStandaloneUBOBinding = standaloneBindings;
}
- if(uboCount >= mImpl->mCurrentUBOBindings.size())
+ if(uboCount && uboCount > mImpl->mCurrentUBOBindings.size())
{
- mImpl->mCurrentUBOBindings.resize(uboCount + 1);
+ mImpl->mCurrentUBOBindings.resize(uboCount);
}
auto it = uboBindings;
{
mImpl->mCurrentUBOBindings[i] = *it;
}
+ ++it;
}
}
{
ResolveStandaloneUniforms();
}
+ if(!mImpl->mCurrentUBOBindings.empty())
+ {
+ ResolveGpuUniformBuffers();
+ }
+}
+
+void Context::ResolveGpuUniformBuffers()
+{
+ auto& gl = *mImpl->mController.GetGL();
+ auto i = 0u;
+ for(auto& binding : mImpl->mCurrentUBOBindings)
+ {
+ gl.BindBufferRange(GL_UNIFORM_BUFFER, i++, binding.buffer->GetGLBuffer(), binding.offset, binding.dataSize);
+ }
}
void Context::ResolveStandaloneUniforms()
void Context::ClearState()
{
mImpl->mCurrentTextureBindings.clear();
+ mImpl->mCurrentUBOBindings.clear();
}
void Context::ColorMask(bool enabled)
void ResolveStandaloneUniforms();
/**
+ * @brief Resolves GPU-based uniform buffers
+ */
+ void ResolveGpuUniformBuffers();
+
+ /**
* @brief Begins render pass for specified render target
*
* @param[in] renderPass render pass object to begin
}
private:
-
void InitializeCPUBuffer();
void InitializeGPUBuffer();
bool mCpuAllocated{false};
bool mTransient{false};
- bool mSetForGLRecycling{false}; ///< If flag set true the buffer will recycle
+ bool mSetForGLRecycling{false}; ///< If flag set true the buffer will recycle
};
} // namespace GLES
} // namespace Dali::Graphics
-template<>
-struct std::default_delete<Dali::Graphics::Buffer>
-{
- void operator()(Dali::Graphics::Buffer* object)
- {
- // Add to the queue
- auto resource = static_cast<Dali::Graphics::GLES::Buffer*>(object);
- resource->DiscardResource();
- }
-};
-
-#endif
\ No newline at end of file
+#endif
// TODO: could use vector?
static thread_local UniformBufferBindingDescriptor sTempBindings[MAX_UNIFORM_BUFFER_BINDINGS];
- auto maxBindingCount = 0u;
+ // reset temp bindings
+ memset(sTempBindings, 0, sizeof(UniformBufferBindingDescriptor) * MAX_UNIFORM_BUFFER_BINDINGS);
+
+ auto maxBinding = 0u;
+ bool hasBindings = false;
// find max binding and standalone UBO
+ memset(&bindCmd.standaloneUniformsBufferBinding, 0, sizeof(UniformBufferBindingDescriptor));
for(const auto& binding : bindings)
{
if(binding.buffer)
}
else // Bind regular UBO
{
- if(DALI_UNLIKELY(maxBindingCount == 0u))
- {
- // We can assume here comes first time. Reset temp bindings
- std::fill_n(sTempBindings, MAX_UNIFORM_BUFFER_BINDINGS, UniformBufferBindingDescriptor());
- }
- auto& slot = sTempBindings[binding.binding];
- slot.buffer = glesBuffer;
- slot.offset = binding.offset;
- slot.binding = binding.binding;
- slot.emulated = false;
-
- maxBindingCount = std::max(maxBindingCount, binding.binding + 1u);
+ auto& slot = sTempBindings[binding.binding];
+ slot.buffer = glesBuffer;
+ slot.offset = binding.offset;
+ slot.binding = binding.binding;
+ slot.blockIndex = 0;
+ slot.binding = binding.binding; // implicitly
+ slot.dataSize = binding.dataSize;
+ slot.emulated = false;
+ maxBinding = std::max(maxBinding, binding.binding);
+ hasBindings = true;
}
}
}
bindCmd.uniformBufferBindingsCount = 0u;
// copy data
- if(maxBindingCount)
+ if(hasBindings)
{
- auto destBindings = mCommandPool->Allocate<UniformBufferBindingDescriptor>(maxBindingCount);
+ auto destBindings = mCommandPool->Allocate<UniformBufferBindingDescriptor>(maxBinding + 1);
// copy
- memcpy(destBindings.Ptr(), sTempBindings, sizeof(UniformBufferBindingDescriptor) * (maxBindingCount));
+ auto size = sizeof(UniformBufferBindingDescriptor) * (maxBinding + 1);
+ if(!(size % sizeof(intptr_t)))
+ {
+ auto* srcPtr = reinterpret_cast<intptr_t*>(sTempBindings);
+ auto* dstPtr = reinterpret_cast<intptr_t*>(destBindings.Ptr());
+ for(auto i = 0u; i < size / sizeof(intptr_t); ++i)
+ {
+ *dstPtr++ = *srcPtr++;
+ }
+ }
+ else
+ {
+ memcpy(destBindings.Ptr(), sTempBindings, size);
+ }
bindCmd.uniformBufferBindings = destBindings;
- bindCmd.uniformBufferBindingsCount = maxBindingCount;
+ bindCmd.uniformBufferBindingsCount = maxBinding + 1;
}
}
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <dali/integration-api/gl-abstraction.h>
#include <dali/integration-api/gl-defines.h>
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gGraphicsProgramLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_GRAPHICS_PROGRAM");
+#endif
+
namespace Dali::Graphics::GLES
{
using Integration::GlAbstraction;
gl->GetProgramInfoLog(program, 4096, &size, output);
// log on error
- // TODO: un-printf-it
- printf("Log: %s\n", output);
+ DALI_LOG_INFO(gGraphicsProgramLogFilter, Debug::Verbose, "Log: %s\n", output);
gl->DeleteProgram(program);
return false;
}
mImpl->glProgram = program;
// Initialize reflection
- mImpl->reflection->BuildUniformReflection();
+ mImpl->reflection->BuildUniformBlockReflection();
mImpl->reflection->BuildVertexAttributeReflection();
// populate uniform cache memory for standalone uniforms (it's not needed
if(!reflection->GetStandaloneUniformExtraInfo().empty())
{
UniformBlockInfo blockInfo;
- mImpl->reflection->GetUniformBlock(0, blockInfo);
+ reflection->GetUniformBlock(0, blockInfo);
auto uniformCacheSize = blockInfo.size;
mImpl->uniformData.resize(uniformCacheSize);
BuildStandaloneUniformCache();
}
+
+ // Set up uniform block bindings
+ auto binding = 0u;
+ auto blockCount = reflection->GetUniformBlockCount();
+ for(uint32_t i = 1; i < blockCount; ++i) // Ignore emulated block at #0
+ {
+ UniformBlockInfo uboInfo{};
+ reflection->GetUniformBlock(i, uboInfo);
+
+ // make binding point
+ auto blockIndex = gl->GetUniformBlockIndex(program, uboInfo.name.c_str());
+ gl->UniformBlockBinding(program, blockIndex, binding++);
+ }
+
return true;
}
return type == GL_SAMPLER_2D || type == GL_SAMPLER_3D || type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES;
}
-bool SortUniformInfoByLocation(Dali::Graphics::UniformInfo a, Dali::Graphics::UniformInfo b)
-{
- return a.location < b.location;
-}
-
-bool SortUniformExtraInfoByLocation(Dali::Graphics::GLES::Reflection::UniformExtraInfo a, Dali::Graphics::GLES::Reflection::UniformExtraInfo b)
-{
- return a.location < b.location;
-}
-
std::string GetShaderSource(Dali::Graphics::ShaderState shaderState)
{
std::vector<uint8_t> data;
delete[] name;
}
-void Reflection::BuildUniformReflection()
+void Reflection::BuildUniformBlockReflection()
{
- auto glProgram = mProgram.GetGlProgram();
-
- int maxLen;
+ auto gl = mController.GetGL();
+ auto glProgram = mProgram.GetGlProgram();
char* name;
+ int numUniformBlocks = 0;
- int numUniforms = 0;
-
- auto gl = mController.GetGL();
if(!gl)
{
// Do nothing during shutdown
return;
}
- DALI_LOG_INFO(gGraphicsReflectionLogFilter, Debug::General, "Build uniform reflection for glProgram : %u\n", glProgram);
+ DALI_LOG_INFO(gGraphicsReflectionLogFilter, Debug::General, "Build uniform block reflection for glProgram : %u\n", glProgram);
- gl->GetProgramiv(glProgram, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLen);
- gl->GetProgramiv(glProgram, GL_ACTIVE_UNIFORMS, &numUniforms);
+ int maxUniformNameLength;
+ GLint activeUniformCount = 0;
+ gl->GetProgramiv(glProgram, GL_ACTIVE_UNIFORM_BLOCKS, &numUniformBlocks);
+ gl->GetProgramiv(glProgram, GL_ACTIVE_UNIFORMS, &activeUniformCount);
+ gl->GetProgramiv(glProgram, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxUniformNameLength);
- mUniformBlocks.clear();
- mDefaultUniformBlock.members.clear();
- mUniformOpaques.clear();
+ numUniformBlocks++; // add block 0 for standalone UBO block
- name = new char[maxLen];
+ mUniformBlocks.resize(numUniformBlocks);
+ mUniformOpaques.clear();
mStandaloneUniformExtraInfos.clear();
- for(int i = 0; i < numUniforms; ++i)
+ std::vector<GLuint> uniformIndices;
+ uniformIndices.reserve(activeUniformCount);
+ for(auto i = 0; i < activeUniformCount; ++i)
{
- int elementCount;
- GLenum type;
- int written;
- gl->GetActiveUniform(glProgram, i, maxLen, &written, &elementCount, &type, name);
-
- int location = gl->GetUniformLocation(glProgram, name);
+ uniformIndices.emplace_back(i);
+ }
- Dali::Graphics::UniformInfo uniformInfo;
+ // Obtain all parameters for active uniforms
+ auto getActiveUniformParams = [gl, glProgram, uniformIndices](GLenum param) {
+ std::vector<GLint> params;
+ params.resize(uniformIndices.size());
+ gl->GetActiveUniformsiv(glProgram, uniformIndices.size(), uniformIndices.data(), param, params.data());
+ return params;
+ };
- uniformInfo.name = name;
- if(elementCount > 1)
- {
- // If we have an active uniform that refers to an array, only the first element
- // is present in this list, and is referenced as "uniform[0]", but the element
- // count is non-zero to indicate how many uniforms there are in the array.
+ auto activeUniformType = getActiveUniformParams(GL_UNIFORM_TYPE);
+ auto activeUniformSize = getActiveUniformParams(GL_UNIFORM_SIZE);
+ auto activeUniformNameLength = getActiveUniformParams(GL_UNIFORM_NAME_LENGTH);
+ auto activeUniformBlockIndex = getActiveUniformParams(GL_UNIFORM_BLOCK_INDEX);
+ auto activeUniformOffset = getActiveUniformParams(GL_UNIFORM_OFFSET);
- // Strip off the array, but store the element count
- auto iter = std::string(uniformInfo.name).find("[", 0);
- if(iter != std::string::npos)
- {
- uniformInfo.name = std::string(name).substr(0, iter);
- uniformInfo.elementCount = elementCount;
- }
- }
- uniformInfo.uniformClass = IsSampler(type) ? Dali::Graphics::UniformClass::COMBINED_IMAGE_SAMPLER : Dali::Graphics::UniformClass::UNIFORM;
- uniformInfo.location = location; // GL doesn't guarantee that consecutive array elements have sequential locations. But, we only store location of first element.
- uniformInfo.binding = 0;
- uniformInfo.bufferIndex = 0;
- uniformInfo.offset = 0;
+ // Extract only uniform blocks and collect data
+ std::string uniformName;
- if(IsSampler(type))
- {
- mUniformOpaques.push_back(uniformInfo);
- }
- else
- {
- mDefaultUniformBlock.members.push_back(uniformInfo);
- mStandaloneUniformExtraInfos.emplace_back(location, GetGLDataTypeSize(type), uniformInfo.offset, elementCount, type);
- }
- }
+ // collect samplers into separate array
+ std::vector<UniformInfo> samplers;
- // Re-order according to uniform locations.
+ name = new char[maxUniformNameLength + 1];
- if(mDefaultUniformBlock.members.size() > 1)
+ for(auto i = 0u; i < activeUniformBlockIndex.size(); ++i)
{
- std::sort(mDefaultUniformBlock.members.begin(), mDefaultUniformBlock.members.end(), SortUniformInfoByLocation);
- std::sort(mStandaloneUniformExtraInfos.begin(), mStandaloneUniformExtraInfos.end(), SortUniformExtraInfoByLocation);
- }
+ GLenum type;
+ GLint elementCount;
+ GLint written;
+ gl->GetActiveUniform(glProgram, i, maxUniformNameLength, &written, &elementCount, &type, name);
- if(mUniformOpaques.size() > 1)
- {
- SortOpaques();
- }
+ auto location = gl->GetUniformLocation(glProgram, name);
+ uniformName = name;
- // Calculate the uniform offset
- for(unsigned int i = 0; i < mDefaultUniformBlock.members.size(); ++i)
- {
- if(i == 0)
+ UniformInfo* uniformInfo{nullptr};
+ if(IsSampler(activeUniformType[i]))
{
- mDefaultUniformBlock.members[i].offset = 0;
+ samplers.emplace_back();
+ uniformInfo = &samplers.back();
+ uniformInfo->uniformClass = UniformClass::COMBINED_IMAGE_SAMPLER;
}
else
{
- uint32_t previousUniformLocation = mDefaultUniformBlock.members[i - 1].location;
- auto previousUniform = std::find_if(mStandaloneUniformExtraInfos.begin(), mStandaloneUniformExtraInfos.end(), [&previousUniformLocation](const UniformExtraInfo& iter) { return iter.location == previousUniformLocation; });
- if(previousUniform != mStandaloneUniformExtraInfos.end())
+ auto blockIndex = activeUniformBlockIndex[i] + 1;
+ auto& members = mUniformBlocks[blockIndex].members;
+ members.emplace_back();
+ uniformInfo = &members.back();
+ uniformInfo->uniformClass = UniformClass::UNIFORM;
+ uniformInfo->binding = 0;
+ uniformInfo->bufferIndex = blockIndex;
+ uniformInfo->binding = blockIndex == 0 ? i : 0; // this will be reset later
+ uniformInfo->offset = activeUniformOffset[i];
+ }
+
+ uniformInfo->location = location; // location must be set later and sorted by offset
+ uniformInfo->name = name;
+ // Strip off array index from name, use element count instead
+ if(elementCount > 1)
+ {
+ auto iter = std::string(uniformName).find('[', 0);
+ if(iter != std::string::npos)
{
- mDefaultUniformBlock.members[i].offset = mDefaultUniformBlock.members[i - 1].offset + (previousUniform->size * previousUniform->arraySize);
- mStandaloneUniformExtraInfos[i].offset = mDefaultUniformBlock.members[i].offset;
+ uniformInfo->name = std::string(name).substr(0, iter);
+ uniformInfo->elementCount = elementCount;
}
}
}
- if(mDefaultUniformBlock.members.size() > 0)
+ // Sort by offset
+ uint32_t blockIndex = 0;
+ for(auto& ubo : mUniformBlocks)
{
- uint32_t lastUniformLocation = mDefaultUniformBlock.members.back().location;
- auto lastUniform = std::find_if(mStandaloneUniformExtraInfos.begin(), mStandaloneUniformExtraInfos.end(), [&lastUniformLocation](const UniformExtraInfo& iter) { return iter.location == lastUniformLocation; });
- if(lastUniform != mStandaloneUniformExtraInfos.end())
+ std::sort(ubo.members.begin(), ubo.members.end(), [](auto& lhs, auto& rhs) {
+ return lhs.offset < rhs.offset;
+ });
+
+ if(blockIndex > 0)
{
- mDefaultUniformBlock.size = mDefaultUniformBlock.members.back().offset + (lastUniform->size * lastUniform->arraySize);
- mUniformBlocks.push_back(mDefaultUniformBlock);
+ GLint uboSize;
+ GLint blockNameLength;
+ gl->GetActiveUniformBlockiv(glProgram, blockIndex - 1, GL_UNIFORM_BLOCK_DATA_SIZE, &uboSize);
+ gl->GetActiveUniformBlockiv(glProgram, blockIndex - 1, GL_UNIFORM_BLOCK_NAME_LENGTH, &blockNameLength);
+ char* blockName = new char[blockNameLength];
+ gl->GetActiveUniformBlockName(glProgram, blockIndex - 1, blockNameLength, nullptr, blockName);
+ ubo.name = blockName;
+ ubo.size = uboSize;
+ delete[] blockName;
}
- }
- else
- {
- mDefaultUniformBlock.size = 0;
+ else
+ {
+ ubo.name = "";
+ ubo.size = 0; // to compute later
+ }
+ ubo.binding = 0;
+ ubo.descriptorSet = 0;
+ blockIndex++;
}
- delete[] name;
-}
-
-// TODO: Maybe this is not needed if uniform block is not support by dali shaders?
-void Reflection::BuildUniformBlockReflection()
-{
- auto gl = mController.GetGL();
- auto glProgram = mProgram.GetGlProgram();
- int numUniformBlocks = 0;
+ // count uniform size
+ auto& defaultUniformBlock = mUniformBlocks[0]; // Standalone block
+ defaultUniformBlock.size = 0;
- if(!gl)
+ mStandaloneUniformExtraInfos.reserve(defaultUniformBlock.members.size());
+ for(auto& member : defaultUniformBlock.members)
{
- // Do nothing during shutdown
- return;
- }
+ auto& type = activeUniformType[member.binding];
+ auto dataTypeSize = GetGLDataTypeSize(type);
+ member.offset = defaultUniformBlock.size;
+ defaultUniformBlock.size += (dataTypeSize * activeUniformSize[member.binding]);
- DALI_LOG_INFO(gGraphicsReflectionLogFilter, Debug::General, "Build uniform block reflection for glProgram : %u\n", glProgram);
-
- gl->GetProgramiv(glProgram, GL_ACTIVE_UNIFORM_BLOCKS, &numUniformBlocks);
-
- mUniformBlocks.clear();
- mUniformBlocks.resize(numUniformBlocks);
-
- int uniformBlockMaxLength = 0;
- gl->GetProgramiv(glProgram, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &uniformBlockMaxLength);
-
- char* uniformBlockName = new char[uniformBlockMaxLength];
- for(int i = 0; i < numUniformBlocks; i++)
- {
- int length;
- int blockBinding;
- int blockDataSize;
- gl->GetActiveUniformBlockName(glProgram, i, uniformBlockMaxLength, &length, uniformBlockName);
- gl->GetActiveUniformBlockiv(glProgram, i, GL_UNIFORM_BLOCK_BINDING, &blockBinding);
- gl->GetActiveUniformBlockiv(glProgram, i, GL_UNIFORM_BLOCK_DATA_SIZE, &blockDataSize);
-
- Dali::Graphics::UniformBlockInfo uniformBlockInfo;
- uniformBlockInfo.name = uniformBlockName;
- uniformBlockInfo.size = blockDataSize;
- uniformBlockInfo.binding = blockBinding;
-
- int nUnis;
- gl->GetActiveUniformBlockiv(glProgram, i, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &nUnis);
- int* unifIndexes = new GLint[nUnis];
- gl->GetActiveUniformBlockiv(glProgram, i, GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, unifIndexes);
- char* uniformName{};
- int maxUniLen;
- gl->GetProgramiv(glProgram, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxUniLen);
-
- for(int unif = 0; unif < nUnis; ++unif)
- {
- int uniIndex = unifIndexes[unif];
- int size;
- GLenum type;
-
- gl->GetActiveUniform(glProgram, uniIndex, maxUniLen, &length, &size, &type, uniformName);
- int location = gl->GetUniformLocation(glProgram, uniformName);
-
- Dali::Graphics::UniformInfo uniform;
- uniform.name = uniformName;
- uniform.location = location;
- uniformBlockInfo.members.push_back(uniform);
- }
-
- delete[] unifIndexes;
-
- mUniformBlocks.push_back(uniformBlockInfo);
+ UniformExtraInfo extraInfo{};
+ extraInfo.location = member.location;
+ extraInfo.size = (dataTypeSize);
+ extraInfo.offset = member.offset;
+ extraInfo.arraySize = activeUniformSize[member.binding];
+ extraInfo.type = activeUniformType[member.binding];
+ member.binding = 0;
+ mStandaloneUniformExtraInfos.emplace_back(extraInfo);
}
- delete[] uniformBlockName;
+
+ mUniformOpaques = samplers;
+ SortOpaques();
}
uint32_t Reflection::GetVertexAttributeLocation(const std::string& name) const
#define DALI_GRAPHICS_GLES_REFLECTION_H
/*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
struct UniformExtraInfo
{
+ UniformExtraInfo() = default;
UniformExtraInfo(uint32_t location, uint32_t size, uint32_t offset, uint32_t arraySize, GLenum type)
: location(location),
size(size),
};
std::vector<AttributeInfo> mVertexInputAttributes; ///< List of vertex attributes
- Graphics::UniformBlockInfo mDefaultUniformBlock{}; ///< The emulated UBO containing all the standalone uniforms
std::vector<Graphics::UniformInfo> mUniformOpaques{}; ///< List of opaque uniforms (i.e. samplers)
- std::vector<Graphics::UniformBlockInfo> mUniformBlocks{}; ///< List of uniform blocks
+ std::vector<Graphics::UniformBlockInfo> mUniformBlocks{}; ///< List of uniform blocks (First is for standalone uniforms)
std::vector<UniformExtraInfo> mStandaloneUniformExtraInfos; ///< List of extra information for standalone uniforms
};
*/
struct UniformBufferBindingDescriptor
{
- const GLES::Buffer* buffer{nullptr};
- uint32_t binding{0u};
- uint32_t offset{0u};
- bool emulated{false}; ///<true if UBO is emulated for old gfx API
+ const GLES::Buffer* buffer;
+ uint32_t binding;
+ uint32_t offset;
+ uint32_t dataSize;
+ uint32_t blockIndex;
+ bool emulated; ///<true if UBO is emulated for old gfx API
};
/**
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
}
else
{
- // @TODO: trashing vertex binding, better find target that is rarely used
- buffer->Bind(Graphics::BufferUsage::VERTEX_BUFFER);
+ gl->BindBuffer(GL_COPY_WRITE_BUFFER, buffer->GetGLBuffer());
void* ptr = nullptr;
- ptr = gl->MapBufferRange(GL_ARRAY_BUFFER, GLintptr(mMapBufferInfo.offset), GLsizeiptr(mMapBufferInfo.size), GL_MAP_WRITE_BIT);
+ ptr = gl->MapBufferRange(GL_COPY_WRITE_BUFFER, GLintptr(mMapBufferInfo.offset), GLsizeiptr(mMapBufferInfo.size), GL_MAP_WRITE_BIT);
mMappedPointer = ptr;
}
return mMappedPointer;
auto buffer = static_cast<GLES::Buffer*>(mMapBufferInfo.buffer);
if(!buffer->IsCPUAllocated())
{
- buffer->Bind(Graphics::BufferUsage::VERTEX_BUFFER);
- gl->UnmapBuffer(GL_ARRAY_BUFFER);
+ gl->BindBuffer(GL_COPY_WRITE_BUFFER, buffer->GetGLBuffer());
+ gl->UnmapBuffer(GL_COPY_WRITE_BUFFER);
}
}