../dali-adaptor/dali-test-suite-utils/test-graphics-controller.cpp
../dali-adaptor/dali-test-suite-utils/test-graphics-texture.cpp
../dali-adaptor/dali-test-suite-utils/test-graphics-pipeline.cpp
+ ../dali-adaptor/dali-test-suite-utils/test-graphics-reflection.cpp
../dali-adaptor/dali-test-suite-utils/test-graphics-sampler.cpp
../dali-adaptor/dali-test-suite-utils/test-native-image.cpp
../dali-adaptor/dali-test-suite-utils/test-platform-abstraction.cpp
dali-test-suite-utils/test-graphics-command-buffer.cpp
dali-test-suite-utils/test-graphics-controller.cpp
dali-test-suite-utils/test-graphics-pipeline.cpp
+ dali-test-suite-utils/test-graphics-reflection.cpp
dali-test-suite-utils/test-graphics-texture.cpp
dali-test-suite-utils/test-graphics-sampler.cpp
dali-test-suite-utils/test-native-image.cpp
#include "test-graphics-buffer.h"
#include "test-graphics-command-buffer.h"
+#include "test-graphics-reflection.h"
#include "test-graphics-sampler.h"
#include "test-graphics-texture.h"
return textureProperties;
}
+const Graphics::Reflection& TestGraphicsController::GetPipelineReflection(const Graphics::Pipeline& pipeline)
+{
+ static TestGraphicsReflection reflection(mGl);
+ mCallStack.PushCall("Controller::GetPipelineReflection", "");
+
+ return reflection;
+}
+
bool TestGraphicsController::PipelineEquals(const Graphics::Pipeline& pipeline0, const Graphics::Pipeline& pipeline1) const
{
mCallStack.PushCall("Controller::PipelineEquals", "");
#include "test-gl-abstraction.h"
#include "test-gl-context-helper-abstraction.h"
#include "test-gl-sync-abstraction.h"
+#include "test-graphics-reflection.h"
namespace Dali
{
const Graphics::TextureProperties& GetTextureProperties(const Graphics::Texture& texture) override;
/**
+ * @brief Returns the reflection of the given pipeline
+ *
+ * @param[in] pipeline The pipeline
+ * @return The reflection of the pipeline
+ */
+ const Graphics::Reflection& GetPipelineReflection(const Graphics::Pipeline& pipeline) override;
+
+ /**
* @brief Tests whether two Pipelines are the same.
*
* On the higher level, this function may help wit creating pipeline cache.
--- /dev/null
+/*
+ * Copyright (c) 2021 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "test-graphics-reflection.h"
+
+namespace Dali
+{
+TestGraphicsReflection::TestGraphicsReflection(TestGlAbstraction& gl)
+: mGl(gl)
+{
+}
+
+uint32_t TestGraphicsReflection::GetVertexAttributeLocation(const std::string& name) const
+{
+ return 0u;
+}
+
+Dali::Graphics::VertexInputAttributeFormat TestGraphicsReflection::GetVertexAttributeFormat(uint32_t location) const
+{
+ return Dali::Graphics::VertexInputAttributeFormat{};
+}
+
+std::string TestGraphicsReflection::GetVertexAttributeName(uint32_t location) const
+{
+ return 0u;
+}
+
+std::vector<uint32_t> TestGraphicsReflection::GetVertexAttributeLocations() const
+{
+ return std::vector<uint32_t>{};
+}
+
+uint32_t TestGraphicsReflection::GetUniformBlockCount() const
+{
+ return 0u;
+}
+
+uint32_t TestGraphicsReflection::GetUniformBlockBinding(uint32_t index) const
+{
+ return 0u;
+}
+
+uint32_t TestGraphicsReflection::GetUniformBlockSize(uint32_t index) const
+{
+ return 0u;
+}
+
+bool TestGraphicsReflection::GetUniformBlock(uint32_t index, Dali::Graphics::UniformBlockInfo& out) const
+{
+ return true;
+}
+
+std::vector<uint32_t> TestGraphicsReflection::GetUniformBlockLocations() const
+{
+ return std::vector<uint32_t>{};
+}
+
+std::string TestGraphicsReflection::GetUniformBlockName(uint32_t blockIndex) const
+{
+ return std::string{};
+}
+
+uint32_t TestGraphicsReflection::GetUniformBlockMemberCount(uint32_t blockIndex) const
+{
+ return 0u;
+}
+
+std::string TestGraphicsReflection::GetUniformBlockMemberName(uint32_t blockIndex, uint32_t memberLocation) const
+{
+ return std::string{};
+}
+
+uint32_t TestGraphicsReflection::GetUniformBlockMemberOffset(uint32_t blockIndex, uint32_t memberLocation) const
+{
+ return 0u;
+}
+
+bool TestGraphicsReflection::GetNamedUniform(const std::string& name, Dali::Graphics::UniformInfo& out) const
+{
+ return true;
+}
+
+std::vector<Dali::Graphics::UniformInfo> TestGraphicsReflection::GetSamplers() const
+{
+ return std::vector<Dali::Graphics::UniformInfo>{};
+}
+
+Graphics::ShaderLanguage TestGraphicsReflection::GetLanguage() const
+{
+ return Graphics::ShaderLanguage::GLSL_3_1;
+}
+
+} // namespace Dali
--- /dev/null
+#ifndef DALI_TEST_GRAPHICS_REFLECTION_H
+#define DALI_TEST_GRAPHICS_REFLECTION_H
+
+/*
+ * Copyright (c) 2021 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <dali/graphics-api/graphics-reflection.h>
+#include "test-gl-abstraction.h"
+
+namespace Dali
+{
+class TestGraphicsReflection : public Graphics::Reflection
+{
+public:
+ TestGraphicsReflection(TestGlAbstraction& gl);
+
+ uint32_t GetVertexAttributeLocation(const std::string& name) const override;
+ Dali::Graphics::VertexInputAttributeFormat GetVertexAttributeFormat(uint32_t location) const override;
+ std::string GetVertexAttributeName(uint32_t location) const override;
+ std::vector<uint32_t> GetVertexAttributeLocations() const override;
+ uint32_t GetUniformBlockCount() const override;
+ uint32_t GetUniformBlockBinding(uint32_t index) const override;
+ uint32_t GetUniformBlockSize(uint32_t index) const override;
+ bool GetUniformBlock(uint32_t index, Dali::Graphics::UniformBlockInfo& out) const override;
+ std::vector<uint32_t> GetUniformBlockLocations() const override;
+ std::string GetUniformBlockName(uint32_t blockIndex) const override;
+ uint32_t GetUniformBlockMemberCount(uint32_t blockIndex) const override;
+ std::string GetUniformBlockMemberName(uint32_t blockIndex, uint32_t memberLocation) const override;
+ uint32_t GetUniformBlockMemberOffset(uint32_t blockIndex, uint32_t memberLocation) const override;
+ bool GetNamedUniform(const std::string& name, Dali::Graphics::UniformInfo& out) const override;
+ std::vector<Dali::Graphics::UniformInfo> GetSamplers() const override;
+ Graphics::ShaderLanguage GetLanguage() const override;
+
+ TestGlAbstraction& mGl;
+};
+
+} // namespace Dali
+
+#endif //DALI_TEST_GRAPHICS_REFLECTION_H
../dali-adaptor/dali-test-suite-utils/test-graphics-texture.cpp
../dali-adaptor/dali-test-suite-utils/test-graphics-sampler.cpp
../dali-adaptor/dali-test-suite-utils/test-graphics-pipeline.cpp
+ ../dali-adaptor/dali-test-suite-utils/test-graphics-reflection.cpp
../dali-adaptor/dali-test-suite-utils/test-native-image.cpp
../dali-adaptor/dali-test-suite-utils/test-platform-abstraction.cpp
../dali-adaptor/dali-test-suite-utils/test-render-controller.cpp
../dali-adaptor/dali-test-suite-utils/test-graphics-texture.cpp
../dali-adaptor/dali-test-suite-utils/test-graphics-sampler.cpp
../dali-adaptor/dali-test-suite-utils/test-graphics-pipeline.cpp
+ ../dali-adaptor/dali-test-suite-utils/test-graphics-reflection.cpp
../dali-adaptor/dali-test-suite-utils/test-native-image.cpp
../dali-adaptor/dali-test-suite-utils/test-platform-abstraction.cpp
../dali-adaptor/dali-test-suite-utils/test-render-controller.cpp
#include <dali/integration-api/gl-defines.h>
#include <dali/internal/graphics/gles-impl/gles-graphics-command-buffer.h>
#include <dali/internal/graphics/gles-impl/gles-graphics-pipeline.h>
+#include <dali/internal/graphics/gles-impl/gles-graphics-shader.h>
#include <dali/internal/graphics/gles-impl/gles-graphics-texture.h>
#include <dali/internal/graphics/gles-impl/gles-graphics-types.h>
#include <dali/public-api/common/dali-common.h>
return NewObject<GLES::Buffer>(bufferCreateInfo, *this, std::move(oldBuffer));
}
+Graphics::UniquePtr<Shader> EglGraphicsController::CreateShader(const ShaderCreateInfo& shaderCreateInfo, Graphics::UniquePtr<Shader>&& oldShader)
+{
+ return NewObject<GLES::Shader>(shaderCreateInfo, *this, std::move(oldShader));
+}
+
Graphics::UniquePtr<Pipeline> EglGraphicsController::CreatePipeline(const PipelineCreateInfo& pipelineCreateInfo, Graphics::UniquePtr<Graphics::Pipeline>&& oldPipeline)
{
// Create pipeline cache if needed
#include "gles-context.h"
#include "gles-graphics-buffer.h"
#include "gles-graphics-memory.h"
+#include "gles-graphics-pipeline.h"
#include "gles-graphics-pipeline-cache.h"
+#include "gles-graphics-reflection.h"
#include "gles-graphics-texture.h"
namespace Dali
/**
* @copydoc Dali::Graphics::CreateShader()
*/
- Graphics::UniquePtr<Shader> CreateShader(const ShaderCreateInfo& shaderCreateInfo, Graphics::UniquePtr<Shader>&& oldShader) override
- {
- return nullptr;
- }
+ Graphics::UniquePtr<Shader> CreateShader(const ShaderCreateInfo& shaderCreateInfo, Graphics::UniquePtr<Shader>&& oldShader) override;
/**
* @copydoc Dali::Graphics::CreateSampler()
}
/**
+ * @copydoc Dali::Graphics::Controller::GetPipelineReflection()
+ */
+ const Reflection& GetPipelineReflection(const Pipeline& pipeline) override
+ {
+ static GLES::Reflection dummy(*this);
+ return dummy;
+ }
+
+ /**
* @copydoc Dali::Graphics::PipelineEquals()
*/
[[nodiscard]] bool PipelineEquals(const Pipeline& pipeline0, const Pipeline& pipeline1) const override
${adaptor_graphics_dir}/gles-impl/gles-graphics-framebuffer.cpp
${adaptor_graphics_dir}/gles-impl/gles-graphics-memory.cpp
${adaptor_graphics_dir}/gles-impl/gles-graphics-pipeline.cpp
+ ${adaptor_graphics_dir}/gles-impl/gles-graphics-reflection.cpp
${adaptor_graphics_dir}/gles-impl/gles-graphics-render-pass.cpp
${adaptor_graphics_dir}/gles-impl/gles-graphics-render-target.cpp
${adaptor_graphics_dir}/gles-impl/gles-graphics-sampler.cpp
#include "egl-graphics-controller.h"
#include "gles-graphics-shader.h"
+namespace
+{
+struct LegacyProgram : Dali::Graphics::ExtensionCreateInfo
+{
+ uint32_t programId;
+};
+} // namespace
+
namespace Dali::Graphics::GLES
{
/**
};
PipelineImpl::PipelineImpl(const Graphics::PipelineCreateInfo& createInfo, Graphics::EglGraphicsController& controller)
-: mController(controller)
+: mController(controller),
+ mReflection(controller)
{
// the creation is deferred so it's needed to copy certain parts of the CreateInfo structure
mPipelineState = std::make_unique<PipelineImpl::PipelineState>();
CopyStateIfSet(createInfo.depthStencilState, mPipelineState->depthStencilState, &mCreateInfo.depthStencilState);
CopyStateIfSet(createInfo.shaderState, mPipelineState->shaderState, &mCreateInfo.shaderState);
CopyStateIfSet(createInfo.viewportState, mPipelineState->viewportState, &mCreateInfo.viewportState);
+
+ if(createInfo.nextExtension)
+ {
+ LegacyProgram* legacyProgram = static_cast<LegacyProgram*>(createInfo.nextExtension);
+ mGlProgram = legacyProgram->programId;
+ mReflection.SetGlProgram(mGlProgram);
+ printf("GLES::Pipeline: mProgramId: %u\n", mGlProgram);
+ }
+
+ const std::vector<Graphics::ShaderState>* shaderStates = mCreateInfo.shaderState;
+ if(shaderStates)
+ {
+ printf("GLES::Pipeline: shaderStates %p, shaderStates size: %lu\n", shaderStates, shaderStates->size());
+
+ std::for_each(shaderStates->begin(), shaderStates->end(), [](Graphics::ShaderState shaderState) {
+ const Graphics::Shader* shader = shaderState.shader;
+ Graphics::PipelineStage pipelineStage = shaderState.pipelineStage;
+ printf("GLES::Pipeline: shader: %p, pipelineStage: %d\n", shader, static_cast<int>(pipelineStage));
+ });
+ }
}
const PipelineCreateInfo& PipelineImpl::GetCreateInfo() const
bool PipelineImpl::InitializeResource()
{
- auto& gl = *GetController().GetGL();
- mGlProgram = gl.CreateProgram();
+ auto& gl = *GetController().GetGL();
+ // mGlProgram = gl.CreateProgram();
for(auto& shader : mPipelineState->shaderState)
{
return mPipeline.GetController();
}
-} // namespace Dali::Graphics::GLES
\ No newline at end of file
+} // namespace Dali::Graphics::GLES
#include <string.h>
// INTERNAL INCLUDES
+#include "gles-graphics-reflection.h"
#include "gles-graphics-resource.h"
namespace Dali::Graphics::GLES
[[nodiscard]] auto& GetController() const;
+ Graphics::GLES::Reflection& GetReflection();
+
private:
/**
* @brief Helper function. Copies state if pointer is set
EglGraphicsController& mController;
PipelineCreateInfo mCreateInfo;
+ Graphics::GLES::Reflection mReflection;
+
uint32_t mGlProgram{0u};
uint32_t mRefCount{0u};
--- /dev/null
+/*
+ * Copyright (c) 2021 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "gles-graphics-reflection.h"
+#include <dali/integration-api/gl-abstraction.h>
+#include <dali/integration-api/gl-defines.h>
+
+#include <vector>
+#include "egl-graphics-controller.h"
+
+#include <GLES3/gl3.h>
+#include <GLES3/gl31.h>
+
+#include <iostream>
+
+namespace
+{
+Dali::Graphics::VertexInputAttributeFormat GetVertexAttributeTypeFormat(GLenum type)
+{
+ switch(type)
+ {
+ case GL_FLOAT:
+ return Dali::Graphics::VertexInputAttributeFormat::FLOAT;
+ case GL_FLOAT_VEC2:
+ return Dali::Graphics::VertexInputAttributeFormat::VEC2;
+ case GL_FLOAT_VEC3:
+ return Dali::Graphics::VertexInputAttributeFormat::VEC3;
+ case GL_FLOAT_VEC4:
+ return Dali::Graphics::VertexInputAttributeFormat::VEC4;
+ case GL_INT:
+ return Dali::Graphics::VertexInputAttributeFormat::INTEGER;
+ default:
+ return Dali::Graphics::VertexInputAttributeFormat::UNDEFINED;
+ }
+}
+
+int 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;
+ }
+}
+
+bool IsSampler(GLenum type)
+{
+ return type == GL_SAMPLER_2D || type == GL_SAMPLER_3D;
+}
+
+bool SortByLocation(Dali::Graphics::UniformInfo a, Dali::Graphics::UniformInfo b)
+{
+ return a.location < b.location;
+}
+
+} // namespace
+
+namespace Dali
+{
+namespace Graphics
+{
+namespace GLES
+{
+Reflection::Reflection(Graphics::EglGraphicsController& controller)
+: Graphics::Reflection(),
+ mController(controller),
+ mGlProgram(0u)
+{
+}
+
+Reflection::~Reflection()
+{
+}
+
+void Reflection::BuildVertexAttributeReflection()
+{
+ int written, size, location, maxLength, nAttribs;
+ GLenum type;
+ char* name;
+
+ auto gl = mController.GetGL();
+
+ gl->GetProgramiv(mGlProgram, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxLength);
+ gl->GetProgramiv(mGlProgram, GL_ACTIVE_ATTRIBUTES, &nAttribs);
+
+ mVertexInputAttributes.clear();
+ mVertexInputAttributes.resize(nAttribs);
+
+ name = new GLchar[maxLength];
+ for(int i = 0; i < nAttribs; i++)
+ {
+ gl->GetActiveAttrib(mGlProgram, i, maxLength, &written, &size, &type, name);
+ location = gl->GetAttribLocation(mGlProgram, name);
+
+ AttributeInfo attributeInfo;
+ attributeInfo.location = location;
+ attributeInfo.name = name;
+ attributeInfo.format = GetVertexAttributeTypeFormat(type);
+
+ mVertexInputAttributes.insert(mVertexInputAttributes.begin() + location, attributeInfo);
+ }
+ delete[] name;
+}
+
+void Reflection::BuildUniformReflection()
+{
+ int maxLen;
+ char* name;
+
+ int numUniforms = 0;
+
+ auto gl = mController.GetGL();
+
+ gl->GetProgramiv(mGlProgram, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLen);
+ gl->GetProgramiv(mGlProgram, GL_ACTIVE_UNIFORMS, &numUniforms);
+
+ mUniformBlocks.clear();
+ mDefaultUniformBlock.members.clear();
+ mUniformOpaques.clear();
+
+ name = new char[maxLen];
+
+ int maxUniformLocations;
+ gl->GetProgramiv(mGlProgram, GL_MAX_UNIFORM_LOCATIONS, &maxUniformLocations);
+
+ std::vector<int> uniformSize;
+ uniformSize.reserve(maxUniformLocations);
+
+ for(int i = 0; i < numUniforms; ++i)
+ {
+ int size;
+ GLenum type;
+ int written;
+ gl->GetActiveUniform(mGlProgram, i, maxLen, &written, &size, &type, name);
+ int location = gl->GetUniformLocation(mGlProgram, name);
+ uniformSize[location] = GetGLDataTypeSize(type);
+
+ Dali::Graphics::UniformInfo uniformInfo;
+ uniformInfo.name = name;
+ uniformInfo.uniformClass = IsSampler(type) ? Dali::Graphics::UniformClass::COMBINED_IMAGE_SAMPLER : Dali::Graphics::UniformClass::UNIFORM;
+ uniformInfo.location = IsSampler(type) ? 0 : location;
+ uniformInfo.binding = IsSampler(type) ? location : 0;
+ uniformInfo.bufferIndex = 0;
+
+ if(IsSampler(type))
+ {
+ mUniformOpaques.push_back(uniformInfo);
+ }
+ else
+ {
+ mDefaultUniformBlock.members.push_back(uniformInfo);
+ }
+ }
+
+ // Re-order according to uniform locations.
+ if(mDefaultUniformBlock.members.size() > 1)
+ {
+ std::sort(mDefaultUniformBlock.members.begin(), mDefaultUniformBlock.members.end(), SortByLocation);
+ }
+
+ if(mUniformOpaques.size() > 1)
+ {
+ std::sort(mUniformOpaques.begin(), mUniformOpaques.end(), SortByLocation);
+ }
+
+ // Calculate the uniform offset
+ for(unsigned int i = 0; i < mDefaultUniformBlock.members.size(); ++i)
+ {
+ mDefaultUniformBlock.members[i].offset = i == 0 ? 0 : mDefaultUniformBlock.members[i - 1].offset + uniformSize[mDefaultUniformBlock.members[i - 1].location];
+ }
+
+ mDefaultUniformBlock.size = mDefaultUniformBlock.members.back().offset + uniformSize[mDefaultUniformBlock.members.back().location];
+
+ mUniformBlocks.push_back(mDefaultUniformBlock);
+
+ delete[] name;
+}
+
+// TODO: Maybe this is not needed if uniform block is not support by dali shaders?
+void Reflection::BuildUniformBlockReflection()
+{
+ auto gl = mController.GetGL();
+
+ int numUniformBlocks = 0;
+ gl->GetProgramiv(mGlProgram, GL_ACTIVE_UNIFORM_BLOCKS, &numUniformBlocks);
+
+ mUniformBlocks.clear();
+ mUniformBlocks.resize(numUniformBlocks);
+
+ int uniformBlockMaxLength = 0;
+ gl->GetProgramiv(mGlProgram, 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(mGlProgram, i, uniformBlockMaxLength, &length, uniformBlockName);
+ gl->GetActiveUniformBlockiv(mGlProgram, i, GL_UNIFORM_BLOCK_BINDING, &blockBinding);
+ gl->GetActiveUniformBlockiv(mGlProgram, i, GL_UNIFORM_BLOCK_DATA_SIZE, &blockDataSize);
+
+ Dali::Graphics::UniformBlockInfo uniformBlockInfo;
+ uniformBlockInfo.name = uniformBlockName;
+ uniformBlockInfo.size = blockDataSize;
+ uniformBlockInfo.binding = blockBinding;
+
+ int nUnis;
+ gl->GetActiveUniformBlockiv(mGlProgram, i, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &nUnis);
+ int* unifIndexes = new GLint[nUnis];
+ gl->GetActiveUniformBlockiv(mGlProgram, i, GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, unifIndexes);
+ char* uniformName{};
+ int maxUniLen;
+ gl->GetProgramiv(mGlProgram, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxUniLen);
+
+ for(int unif = 0; unif < nUnis; ++unif)
+ {
+ int uniIndex = unifIndexes[unif];
+ int size;
+ GLenum type;
+
+ gl->GetActiveUniform(mGlProgram, uniIndex, maxUniLen, &length, &size, &type, uniformName);
+ int location = gl->GetUniformLocation(mGlProgram, uniformName);
+
+ Dali::Graphics::UniformInfo uniform;
+ uniform.name = uniformName;
+ uniform.location = location;
+ uniformBlockInfo.members.push_back(uniform);
+ }
+
+ delete[] unifIndexes;
+
+ mUniformBlocks.push_back(uniformBlockInfo);
+ }
+ delete[] uniformBlockName;
+}
+
+uint32_t Reflection::GetVertexAttributeLocation(const std::string& name) const
+{
+ for(auto&& attr : mVertexInputAttributes)
+ {
+ if(attr.name == name)
+ {
+ return attr.location;
+ }
+ }
+ return ERROR_ATTRIBUTE_NOT_FOUND;
+}
+
+Dali::Graphics::VertexInputAttributeFormat Reflection::GetVertexAttributeFormat(uint32_t location) const
+{
+ if(location >= mVertexInputAttributes.size())
+ {
+ return Dali::Graphics::VertexInputAttributeFormat::UNDEFINED;
+ }
+
+ return mVertexInputAttributes[location].format;
+}
+
+std::string Reflection::GetVertexAttributeName(uint32_t location) const
+{
+ if(location >= mVertexInputAttributes.size())
+ {
+ return std::string();
+ }
+
+ return mVertexInputAttributes[location].name;
+}
+
+std::vector<uint32_t> Reflection::GetVertexAttributeLocations() const
+{
+ std::vector<uint32_t> locations;
+ for(auto&& attr : mVertexInputAttributes)
+ {
+ if(attr.format != Dali::Graphics::VertexInputAttributeFormat::UNDEFINED)
+ {
+ locations.push_back(attr.location);
+ }
+ }
+
+ return locations;
+}
+
+uint32_t Reflection::GetUniformBlockCount() const
+{
+ return mUniformBlocks.size();
+}
+
+uint32_t Reflection::GetUniformBlockBinding(uint32_t index) const
+{
+ return index < mUniformBlocks.size() ? mUniformBlocks[index].binding : 0u;
+}
+
+uint32_t Reflection::GetUniformBlockSize(uint32_t index) const
+{
+ return index < mUniformBlocks.size() ? mUniformBlocks[index].size : 0u;
+}
+
+bool Reflection::GetUniformBlock(uint32_t index, Dali::Graphics::UniformBlockInfo& out) const
+{
+ if(index >= mUniformBlocks.size())
+ {
+ return false;
+ }
+
+ const auto& block = mUniformBlocks[index];
+
+ out.name = block.name;
+ out.binding = block.binding;
+ out.descriptorSet = block.descriptorSet;
+ auto membersSize = block.members.size();
+ out.members.resize(membersSize);
+ out.size = block.size;
+ for(auto i = 0u; i < out.members.size(); ++i)
+ {
+ const auto& memberUniform = block.members[i];
+ out.members[i].name = memberUniform.name;
+ out.members[i].binding = block.binding;
+ out.members[i].uniformClass = Graphics::UniformClass::UNIFORM;
+ out.members[i].offset = memberUniform.offset;
+ out.members[i].location = memberUniform.location;
+ }
+
+ return true;
+}
+
+std::vector<uint32_t> Reflection::GetUniformBlockLocations() const
+{
+ std::vector<uint32_t> retval{};
+ for(auto&& ubo : mUniformBlocks)
+ {
+ retval.emplace_back(ubo.binding);
+ }
+ return retval;
+}
+
+std::string Reflection::GetUniformBlockName(uint32_t blockIndex) const
+{
+ if(blockIndex < mUniformBlocks.size())
+ {
+ return mUniformBlocks[blockIndex].name;
+ }
+ else
+ {
+ return std::string();
+ }
+}
+
+uint32_t Reflection::GetUniformBlockMemberCount(uint32_t blockIndex) const
+{
+ if(blockIndex < mUniformBlocks.size())
+ {
+ return static_cast<uint32_t>(mUniformBlocks[blockIndex].members.size());
+ }
+ else
+ {
+ return 0u;
+ }
+}
+
+std::string Reflection::GetUniformBlockMemberName(uint32_t blockIndex, uint32_t memberLocation) const
+{
+ if(blockIndex < mUniformBlocks.size() && memberLocation < mUniformBlocks[blockIndex].members.size())
+ {
+ return mUniformBlocks[blockIndex].members[memberLocation].name;
+ }
+ else
+ {
+ return std::string();
+ }
+}
+
+uint32_t Reflection::GetUniformBlockMemberOffset(uint32_t blockIndex, uint32_t memberLocation) const
+{
+ if(blockIndex < mUniformBlocks.size() && memberLocation < mUniformBlocks[blockIndex].members.size())
+ {
+ return mUniformBlocks[blockIndex].members[memberLocation].offset;
+ }
+ else
+ {
+ return 0u;
+ }
+}
+
+bool Reflection::GetNamedUniform(const std::string& name, Dali::Graphics::UniformInfo& out) const
+{
+ auto index = 0u;
+ for(auto&& ubo : mUniformBlocks)
+ {
+ for(auto&& member : ubo.members)
+ {
+ if(name == member.name || name == (ubo.name + "." + member.name))
+ {
+ out.name = name;
+ out.location = member.location;
+ out.binding = ubo.binding;
+ out.bufferIndex = index;
+ out.offset = member.offset;
+ out.uniformClass = Graphics::UniformClass::UNIFORM;
+ return true;
+ }
+ }
+ index++;
+ }
+
+ // check samplers
+ for(auto&& uniform : mUniformOpaques)
+ {
+ if(uniform.name == name)
+ {
+ out.uniformClass = Graphics::UniformClass::COMBINED_IMAGE_SAMPLER;
+ out.binding = uniform.binding;
+ out.name = name;
+ out.offset = 0;
+ out.location = uniform.location;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+std::vector<Dali::Graphics::UniformInfo> Reflection::GetSamplers() const
+{
+ return mUniformOpaques;
+}
+
+Graphics::ShaderLanguage Reflection::GetLanguage() const
+{
+ auto gl = mController.GetGL();
+
+ int majorVersion, minorVersion;
+ gl->GetIntegerv(GL_MAJOR_VERSION, &majorVersion);
+ gl->GetIntegerv(GL_MINOR_VERSION, &minorVersion);
+ printf("GL Version (integer) : %d.%d\n", majorVersion, minorVersion);
+ printf("GLSL Version : %s\n", gl->GetString(GL_SHADING_LANGUAGE_VERSION));
+
+ // TODO: the language version is hardcoded for now, but we may use what we get
+ // from GL_SHADING_LANGUAGE_VERSION?
+ return Graphics::ShaderLanguage::GLSL_3_2;
+}
+
+void Reflection::SetGlProgram(uint32_t glProgram)
+{
+ mGlProgram = glProgram;
+
+ BuildVertexAttributeReflection();
+ BuildUniformReflection();
+}
+
+} // namespace GLES
+} // namespace Graphics
+} // namespace Dali
--- /dev/null
+#ifndef DALI_GRAPHICS_GLES_REFLECTION_H
+#define DALI_GRAPHICS_GLES_REFLECTION_H
+
+/*
+ * Copyright (c) 2021 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <dali/graphics-api/graphics-reflection.h>
+#include <dali/graphics-api/graphics-types.h>
+#include <dali/integration-api/gl-abstraction.h>
+
+namespace Dali
+{
+namespace Graphics
+{
+class EglGraphicsController;
+
+namespace GLES
+{
+constexpr uint32_t ERROR_ATTRIBUTE_NOT_FOUND(-1u);
+
+/**
+ * Reflection object represents a single full graphics reflection state.
+ *
+ * The state involves compiled and linked shaders as well as state parameters
+ * like blending, stencil, scissors, viewport etc.
+ *
+ * Some of the parameters can be modified by issuing commands but
+ * the Reflection must mark those states
+ * as dynamic.
+ *
+ */
+class Reflection : public Dali::Graphics::Reflection
+{
+public:
+ Reflection(Graphics::EglGraphicsController& controller);
+ virtual ~Reflection();
+
+ // not copyable
+ Reflection(const Reflection&) = delete;
+ Reflection& operator=(const Reflection&) = delete;
+
+ /**
+ * @brief Gets the location of a vertex attribute.
+ *
+ * @param [in] name The name of vertex attribute
+ * @return The index of the vertex attribute in the shader
+ */
+ uint32_t GetVertexAttributeLocation(const std::string& name) const;
+
+ /**
+ * @brief Gets the format of a vertex attribute.
+ *
+ * @param [in] location The location of vertex attribute
+ * @return The format of a vertex attribute
+ */
+ Dali::Graphics::VertexInputAttributeFormat GetVertexAttributeFormat(uint32_t location) const;
+
+ /**
+ * @brief Gets the name of a vertex attribute.
+ *
+ * @param [in] location The location of vertex attribute
+ * @return The name of the vertex attribute
+ */
+ std::string GetVertexAttributeName(uint32_t location) const;
+
+ /**
+ * @brief Gets the locations of all the vertex attribute in the shader.
+ *
+ * @return A vector of the locations of all the vertex attributes in the shader
+ */
+ std::vector<uint32_t> GetVertexAttributeLocations() const;
+
+ // Uniform blocks
+
+ /**
+ * @brief Gets the number of uniform blocks in the shader
+ *
+ * @return The number of uniform blocks
+ */
+ uint32_t GetUniformBlockCount() const;
+
+ /**
+ * @brief Gets the binding point to which the uniform block with the given index is binded.
+ *
+ * @param [in] index The index of the uniform block
+ * @return The binding point
+ */
+ uint32_t GetUniformBlockBinding(uint32_t index) const;
+
+ /**
+ * @brief Gets the size of the uniform block with the given index.
+ *
+ * @param [in] index The index of the uniform block
+ * @return The size of the uniform block
+ */
+ uint32_t GetUniformBlockSize(uint32_t index) const;
+
+ /**
+ * @brief Retrieves the information of the uniform block with the given index.
+ *
+ * The information includes the name, binding point, size, uniforms inside the uniform block, etc.
+ *
+ * @param [in] index The index of the uniform block
+ * @param [out] out A structure that contains the information of the uniform block
+ * @return Whether the uniform block exists or not
+ */
+ bool GetUniformBlock(uint32_t index, Dali::Graphics::UniformBlockInfo& out) const;
+
+ /**
+ * @brief Gets the binding points of all the uniform blocks in the shader.
+ *
+ * @return A vector of binding points
+ */
+ std::vector<uint32_t> GetUniformBlockLocations() const;
+
+ /**
+ * @brief Gets the name of uniform block with the given index.
+ *
+ * @param [in] blockIndex The index of the uniform block
+ * @return The name of the uniform block
+ */
+ std::string GetUniformBlockName(uint32_t blockIndex) const;
+
+ /**
+ * @brief Gets the number of uniforms in the uniform block with the given index.
+ *
+ * @param [in] blockIndex The index of the uniform block
+ * @return The number of uniforms in the uniform block
+ */
+ uint32_t GetUniformBlockMemberCount(uint32_t blockIndex) const;
+
+ /**
+ * @brief Gets the name of the uniform in the given location within the uniform block.
+ *
+ * @param [in] blockIndex The index of the uniform block
+ * @param [in] memberLocation The location of the uniform within the uniform block
+ * @return The name of the uniform
+ */
+ std::string GetUniformBlockMemberName(uint32_t blockIndex, uint32_t memberLocation) const;
+
+ /**
+ * @brief Gets the byte offset of the uniform in the given location within the uniform block.
+ *
+ * @param [in] blockIndex The index of the uniform block
+ * @param [in] memberLocation The location of the uniform within the uniform block
+ * @return The byte offset of the uniform
+ */
+ uint32_t GetUniformBlockMemberOffset(uint32_t blockIndex, uint32_t memberLocation) const;
+
+ // Named uniforms
+
+ /**
+ * @brief Gets the information of the uniform by its name.
+ *
+ * @param [in] name The name of the uniform
+ * @param [out] out The information of the uniform
+ * @return Whether the uniform exists or not
+ */
+ bool GetNamedUniform(const std::string& name, Dali::Graphics::UniformInfo& out) const;
+
+ // Sampler
+
+ /**
+ * @brief Gets all the sampler uniforms
+ *
+ * @return A vector of the sampler uniforms
+ */
+ std::vector<Dali::Graphics::UniformInfo> GetSamplers() const;
+
+ // Language
+
+ /**
+ * @brief Retrieves the language of the shader
+ *
+ * @return The language of the shader
+ */
+ Graphics::ShaderLanguage GetLanguage() const;
+
+ // Other
+
+ /**
+ * @brief Set the program object whose reflection to be built
+ *
+ * @param [in] glProgram The program object
+ */
+ void SetGlProgram(uint32_t glProgram);
+
+private:
+ /**
+ * @brief Build the reflection of vertex attributes
+ */
+ void BuildVertexAttributeReflection();
+
+ /**
+ * @brief Build the reflection of uniforms
+ */
+ void BuildUniformReflection();
+
+ /**
+ * @brief Build the reflection of uniform blocks
+ */
+ void BuildUniformBlockReflection();
+
+protected:
+ Reflection(Reflection&&) = default;
+ Reflection& operator=(Reflection&&) = default;
+
+private:
+ Graphics::EglGraphicsController& mController; ///< The Graphics controller
+ uint32_t mGlProgram; ///< The GL program object
+
+ struct AttributeInfo
+ {
+ uint32_t location{};
+ std::string name{};
+ Dali::Graphics::VertexInputAttributeFormat format{};
+ };
+
+ 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
+};
+
+} // namespace GLES
+} // namespace Graphics
+} // namespace Dali
+
+#endif // DALI_GRAPHICS_GLES_REFLECTION_H
*
*/
-// CLASS HEADER
#include "gles-graphics-shader.h"
+#include <dali/integration-api/gl-abstraction.h>
+#include <vector>
+#include "egl-graphics-controller.h"
+
+#include <GLES3/gl3.h>
+
+namespace Dali
+{
+namespace Graphics
+{
+namespace GLES
+{
+Shader::Shader(const Graphics::ShaderCreateInfo& createInfo, Graphics::EglGraphicsController& controller)
+: ShaderResource(createInfo, controller)
+{
+ if(mCreateInfo.sourceData && mCreateInfo.sourceSize)
+ {
+ printf("GLES::Shader: stage: %d, sourceMode: %d, size: %u, source:\n\n%s\n", (int)mCreateInfo.pipelineStage, (int)mCreateInfo.sourceMode, mCreateInfo.sourceSize, static_cast<const char*>(mCreateInfo.sourceData));
+ }
+}
+
+} // namespace GLES
+} // namespace Graphics
+} // namespace Dali
* @param[in] createInfo Valid createInfo structure
* @param[in] controller Reference to the controller
*/
- Shader(const Graphics::ShaderCreateInfo& createInfo, Graphics::EglGraphicsController& controller)
- : ShaderResource(createInfo, controller)
- {
- }
+ Shader(const Graphics::ShaderCreateInfo& createInfo, Graphics::EglGraphicsController& controller);
/**
* @brief Destructor