#define TEST_GL_ABSTRACTION_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.
}
};
+struct ActiveUniform
+{
+ std::string name{};
+ GLenum type{GL_FLOAT};
+ GLint size{0};
+ GLint offset{0};
+};
+
class DALI_CORE_API TestGlAbstraction : public Dali::Integration::GlAbstraction
{
public:
bool IsAdvancedBlendEquationSupported() override;
+ bool IsMultisampledRenderToTextureSupported() override;
+
bool IsBlendEquationSupported(DevelBlendEquation::Type blendEquation) override;
std::string GetShaderVersionPrefix();
return mFramebufferColorAttachmentCount;
}
+ inline GLuint CheckFramebufferDepthAttachmentCount()
+ {
+ return mFramebufferDepthAttachmentCount;
+ }
+
+ inline GLuint CheckFramebufferStencilAttachmentCount()
+ {
+ return mFramebufferStencilAttachmentCount;
+ }
+
+ inline GLuint CheckFramebufferDepthStencilAttachmentCount()
+ {
+ return mFramebufferDepthStencilAttachmentCount;
+ }
+
inline GLenum CheckFramebufferDepthAttachment()
{
return mFramebufferDepthAttached;
return mFramebufferStencilAttached;
}
+ inline GLenum CheckFramebufferDepthStencilAttachment()
+ {
+ return mFramebufferDepthStencilAttached;
+ }
+
inline void Clear(GLbitfield mask) override
{
mClearCount++;
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
{
mFramebufferStencilAttached = true;
}
+ else if(attachment == GL_DEPTH_STENCIL_ATTACHMENT)
+ {
+ mFramebufferStencilAttached = true;
+ mFramebufferDepthAttached = true;
+ mFramebufferDepthStencilAttached = true;
+ }
}
inline void FramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) override
++mFramebufferColorAttachmentCount;
}
}
+ else if(attachment == GL_DEPTH_ATTACHMENT)
+ {
+ ++mFramebufferDepthAttachmentCount;
+ }
+ else if(attachment == GL_STENCIL_ATTACHMENT)
+ {
+ ++mFramebufferStencilAttachmentCount;
+ }
+ else if(attachment == GL_DEPTH_STENCIL_ATTACHMENT)
+ {
+ ++mFramebufferDepthAttachmentCount;
+ ++mFramebufferStencilAttachmentCount;
+ ++mFramebufferDepthStencilAttachmentCount;
+ }
}
inline void FrontFace(GLenum mode) 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
inline void GetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) override
{
+ strncpy(name, mAttribLocs[index].c_str(), 99);
+ *type = mAttribTypes[index];
}
+ 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
{
- switch(index)
+ if(index < mActiveUniforms.size())
{
- case 0:
- *length = snprintf(name, bufsize, "sTexture");
- *type = GL_SAMPLER_2D;
- *size = 1;
- break;
- case 1:
- *length = snprintf(name, bufsize, "sEffect");
- *type = GL_SAMPLER_2D;
- *size = 1;
- break;
- case 2:
- *length = snprintf(name, bufsize, "sGloss");
- *type = GL_SAMPLER_2D;
- *size = 1;
- break;
- default:
- break;
+ *length = snprintf(name, bufsize, "%s", mActiveUniforms[index].name.c_str());
+ *type = mActiveUniforms[index].type;
+ *size = mActiveUniforms[index].size;
}
}
case GL_PROGRAM_BINARY_FORMATS_OES:
*params = mBinaryFormats;
break;
+ case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
+ *params = mUniformBufferOffsetAlignment;
+ break;
}
}
*params = mProgramBinaryLength;
break;
case GL_ACTIVE_UNIFORMS:
- *params = mNumberOfActiveUniforms;
+ *params = mActiveUniforms.size();
break;
case GL_ACTIVE_UNIFORM_MAX_LENGTH:
*params = 100;
case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
*params = 100;
break;
+ case GL_ACTIVE_ATTRIBUTES:
+ *params = static_cast<GLint>(mAttribLocs.size());
+ break;
}
}
if(it2 == uniformIDs.end())
{
// Uniform not found, so add it...
- uniformIDs[name] = mLastUniformIdUsed++;
- return mLastUniformIdUsed;
+ uniformIDs[name] = ++mLastUniformIdUsed;
+ return uniformIDs[name];
}
return it2->second;
namedParams["program"] << program;
mShaderTrace.PushCall("LinkProgram", out.str(), namedParams);
- mNumberOfActiveUniforms = 3;
-
- GetUniformLocation(program, "uRendererColor");
- GetUniformLocation(program, "uCustom");
- GetUniformLocation(program, "uCustom3");
- GetUniformLocation(program, "uFadeColor");
- GetUniformLocation(program, "uUniform1");
- GetUniformLocation(program, "uUniform2");
- GetUniformLocation(program, "uUniform3");
- GetUniformLocation(program, "uFadeProgress");
- GetUniformLocation(program, "uANormalMatrix");
- GetUniformLocation(program, "sEffect");
- GetUniformLocation(program, "sTexture");
- GetUniformLocation(program, "sTextureRect");
- GetUniformLocation(program, "sGloss");
- GetUniformLocation(program, "uColor");
- GetUniformLocation(program, "uModelMatrix");
- GetUniformLocation(program, "uModelView");
- GetUniformLocation(program, "uMvpMatrix");
- GetUniformLocation(program, "uNormalMatrix");
- GetUniformLocation(program, "uProjection");
- GetUniformLocation(program, "uSize");
- GetUniformLocation(program, "uViewMatrix");
- GetUniformLocation(program, "uLightCameraProjectionMatrix");
- GetUniformLocation(program, "uLightCameraViewMatrix");
+ for(const auto& uniform : mActiveUniforms)
+ {
+ std::string name = uniform.name;
+ if(uniform.size <= 1)
+ {
+ GetUniformLocation(program, name.c_str());
+ }
+ else
+ {
+ // Convert single active uniform from "uBlah[0]" or "uStruct[0].element" to N versions of the same
+ std::string suffix;
+ auto iter = name.find("["); // Search for index operator
+ if(iter != std::string::npos)
+ {
+ name = uniform.name.substr(0, iter); // Strip off index operator
+ iter = uniform.name.find("]");
+ if(iter != std::string::npos && iter + 1 != uniform.name.length())
+ {
+ suffix = uniform.name.substr(iter + 1);
+ }
+ }
+ for(int i = 0; i < uniform.size; ++i)
+ {
+ std::stringstream nss;
+ nss << name << "[" << i << "]" << suffix;
+ GetUniformLocation(program, nss.str().c_str()); // Generate N uniforms in the uniform map
+ }
+ }
+ }
for(const auto& uniform : mCustomUniformData)
{
- GetUniformLocation(program, uniform.name.c_str());
+ auto iter = uniform.name.find("[");
+ auto name = uniform.name;
+ if(iter != std::string::npos)
+ {
+ name = uniform.name.substr(0, iter);
+ auto arrayCount = std::stoi(uniform.name.substr(iter + 1));
+ iter = uniform.name.find("]");
+ std::string suffix;
+ if(iter != std::string::npos && iter + 1 != uniform.name.length())
+ {
+ suffix = uniform.name.substr(iter + 1); // If there is a suffix, it means its an element of an array of struct
+ }
+
+ for(int i = 0; i < arrayCount; ++i)
+ {
+ std::stringstream nss;
+ nss << name << "[" << i << "]" << suffix;
+ GetUniformLocation(program, nss.str().c_str()); // Generate a GL loc per element
+ }
+ }
+ else
+ {
+ GetUniformLocation(program, name.c_str());
+ }
}
}
mBufferTrace.PushCall("VertexAttribPointer", namedParams.str(), namedParams);
}
+ inline void VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer) override
+ {
+ TraceCallStack::NamedParams namedParams;
+ namedParams["index"] << index;
+ namedParams["size"] << size;
+ namedParams["type"] << std::hex << type;
+ namedParams["stride"] << stride;
+ namedParams["offset"] << std::to_string(reinterpret_cast<unsigned long>(pointer));
+
+ mBufferTrace.PushCall("VertexAttribIPointer", namedParams.str(), namedParams);
+ }
+
inline void Viewport(GLint x, GLint y, GLsizei width, GLsizei height) override
{
std::string commaString(", ");
{
}
+ inline void FramebufferTexture2DMultisample(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples) override
+ {
+ // TODO : Check it if need
+ FramebufferTexture2D(target, attachment, textarget, texture, level);
+ }
+
inline void FramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) override
{
}
{
}
- inline void VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer) override
- {
- }
-
inline void GetVertexAttribIiv(GLuint index, GLenum pname, GLint* params) override
{
}
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
inline void DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount) override
{
+ std::stringstream out;
+ out << mode << ", " << first << ", " << count << ", " << instanceCount;
+ TraceCallStack::NamedParams namedParams;
+ namedParams["mode"] << std::hex << mode;
+ namedParams["first"] << first;
+ namedParams["count"] << count;
+ namedParams["instanceCount"] << instanceCount;
+ mDrawTrace.PushCall("DrawArraysInstanced", out.str(), namedParams);
}
inline void DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei instanceCount) override
{
+ std::stringstream out;
+ out << mode << ", " << count << ", " << type << ", " << instanceCount;
+ TraceCallStack::NamedParams namedParams;
+ namedParams["mode"] << std::hex << mode;
+ namedParams["count"] << count;
+ namedParams["type"] << std::hex << type;
+ namedParams["indexCount"] << instanceCount;
+ mDrawTrace.PushCall("DrawElementsInstanced", out.str(), namedParams);
}
inline GLsync FenceSync(GLenum condition, GLbitfield flags) override
inline void VertexAttribDivisor(GLuint index, GLuint divisor) override
{
+ std::stringstream out;
+ out << index << ", " << divisor;
+ TraceCallStack::NamedParams namedParams;
+ namedParams["index"] << index;
+ namedParams["divisor"] << divisor;
+ mBufferTrace.PushCall("VertexAttribDivisor", out.str(), namedParams);
}
inline void BindTransformFeedback(GLenum target, GLuint id) override
{
mLinkStatus = value;
}
- inline void SetAttribLocations(std::vector<std::string> locs)
+ inline void SetAttribLocations(std::vector<std::string>& locs)
{
mAttribLocs = locs;
}
+ inline void SetAttribTypes(std::vector<GLenum>& types)
+ {
+ mAttribTypes = types;
+ }
inline void SetGetErrorResult(GLenum result)
{
mGetErrorResult = result;
{
mProgramBinaryLength = length;
}
-
+ inline void SetUniformBufferOffsetAlignment(GLint align)
+ {
+ mUniformBufferOffsetAlignment = align;
+ }
inline bool GetVertexAttribArrayState(GLuint index)
{
if(index >= MAX_ATTRIBUTE_CACHE_SIZE)
mBufferSubDataCalls.clear();
}
-private:
+public:
GLuint mCurrentProgram;
GLuint mCompileStatus;
BufferDataCalls mBufferDataCalls;
BufferSubDataCalls mBufferSubDataCalls;
GLvoid* mMappedBuffer{nullptr};
GLuint mLinkStatus;
- GLint mNumberOfActiveUniforms;
GLenum mGetErrorResult;
GLubyte* mGetStringResult;
GLboolean mIsBufferResult;
GLint mFramebufferStatus;
GLenum mFramebufferDepthAttached;
GLenum mFramebufferStencilAttached;
+ GLenum mFramebufferDepthStencilAttached;
GLuint mFramebufferColorAttachmentCount;
GLuint mFrameBufferColorStatus;
+ GLuint mFramebufferDepthAttachmentCount;
+ GLuint mFramebufferStencilAttachmentCount;
+ GLuint mFramebufferDepthStencilAttachmentCount;
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;
typedef std::map<GLuint, std::string> ShaderSourceMap;
ShaderSourceMap mShaderSources;
- std::vector<std::string> mAttribLocs; // should be bound to shader
+ std::vector<std::string> mAttribLocs; // should be bound to shader
+ std::vector<GLenum> mAttribTypes; // should be bound to shader
GLuint mLastShaderCompiled;
GLbitfield mLastClearBitMask;
Vector4 mLastClearColor;
typedef std::map<std::string, GLint> UniformIDMap;
typedef std::map<GLuint, UniformIDMap> ProgramUniformMap;
ProgramUniformMap mUniforms;
-
- std::vector<UniformData> mCustomUniformData{};
+ std::vector<ActiveUniform> mActiveUniforms;
+ std::vector<UniformData> mCustomUniformData{};
template<typename T>
struct ProgramUniformValue : public std::map<GLuint, std::map<GLint, T> >