mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-08 04:08:32 +09:00
[Fix] (MG_Impl/GLImpl, MG_State, MG_Backend): validate image uniform state
This commit is contained in:
@@ -2792,9 +2792,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
MG_Util::ConvertGLEnumToString(format).c_str());
|
||||
MOBILEGL_ASSERT(type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_INT || type == GL_UNSIGNED_INT_2_10_10_10_REV ||
|
||||
type == GL_INT || type == GL_FLOAT || type == GL_UNSIGNED_INT_8_8_8_8 ||
|
||||
type == GL_UNSIGNED_INT_8_8_8_8_REV,
|
||||
type == GL_UNSIGNED_INT_8_8_8_8_REV || type == GL_HALF_FLOAT,
|
||||
"Only GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, GL_UNSIGNED_INT_2_10_10_10_REV, "
|
||||
"GL_INT, GL_FLOAT, GL_UNSIGNED_INT_8_8_8_8 and GL_UNSIGNED_INT_8_8_8_8_REV "
|
||||
"GL_INT, GL_FLOAT, GL_HALF_FLOAT, GL_UNSIGNED_INT_8_8_8_8 and GL_UNSIGNED_INT_8_8_8_8_REV "
|
||||
"are supported currently, while requested %s.",
|
||||
MG_Util::ConvertGLEnumToString(type).c_str());
|
||||
|
||||
|
||||
@@ -227,12 +227,12 @@ DECLARE_GL_FUNCTION_STUB_HEAD(void, GetQueryObjectuiv, GLuint id, GLenum pname,
|
||||
DECLARE_GL_FUNCTION_HEAD(GLboolean, UnmapBuffer, GLenum target) DECLARE_GL_FUNCTION_END(GLboolean, UnmapBuffer, target)
|
||||
DECLARE_GL_FUNCTION_HEAD(void, GetBufferPointerv, GLenum target, GLenum pname, void** params) DECLARE_GL_FUNCTION_END_NO_RETURN(void, GetBufferPointerv, target, pname, params)
|
||||
DECLARE_GL_FUNCTION_HEAD(void, DrawBuffers, GLsizei n, const GLenum* bufs) DECLARE_GL_FUNCTION_END_NO_RETURN(void, DrawBuffers, n, bufs)
|
||||
DECLARE_GL_FUNCTION_STUB_HEAD(void, UniformMatrix2x3fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, UniformMatrix2x3fv, location, count, transpose, value)
|
||||
DECLARE_GL_FUNCTION_STUB_HEAD(void, UniformMatrix3x2fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, UniformMatrix3x2fv, location, count, transpose, value)
|
||||
DECLARE_GL_FUNCTION_STUB_HEAD(void, UniformMatrix2x4fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, UniformMatrix2x4fv, location, count, transpose, value)
|
||||
DECLARE_GL_FUNCTION_STUB_HEAD(void, UniformMatrix4x2fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, UniformMatrix4x2fv, location, count, transpose, value)
|
||||
DECLARE_GL_FUNCTION_STUB_HEAD(void, UniformMatrix3x4fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, UniformMatrix3x4fv, location, count, transpose, value)
|
||||
DECLARE_GL_FUNCTION_STUB_HEAD(void, UniformMatrix4x3fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, UniformMatrix4x3fv, location, count, transpose, value)
|
||||
DECLARE_GL_FUNCTION_HEAD(void, UniformMatrix2x3fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) DECLARE_GL_FUNCTION_END_NO_RETURN(void, UniformMatrix2x3fv, location, count, transpose, value)
|
||||
DECLARE_GL_FUNCTION_HEAD(void, UniformMatrix3x2fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) DECLARE_GL_FUNCTION_END_NO_RETURN(void, UniformMatrix3x2fv, location, count, transpose, value)
|
||||
DECLARE_GL_FUNCTION_HEAD(void, UniformMatrix2x4fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) DECLARE_GL_FUNCTION_END_NO_RETURN(void, UniformMatrix2x4fv, location, count, transpose, value)
|
||||
DECLARE_GL_FUNCTION_HEAD(void, UniformMatrix4x2fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) DECLARE_GL_FUNCTION_END_NO_RETURN(void, UniformMatrix4x2fv, location, count, transpose, value)
|
||||
DECLARE_GL_FUNCTION_HEAD(void, UniformMatrix3x4fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) DECLARE_GL_FUNCTION_END_NO_RETURN(void, UniformMatrix3x4fv, location, count, transpose, value)
|
||||
DECLARE_GL_FUNCTION_HEAD(void, UniformMatrix4x3fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) DECLARE_GL_FUNCTION_END_NO_RETURN(void, UniformMatrix4x3fv, location, count, transpose, value)
|
||||
DECLARE_GL_FUNCTION_HEAD(void, BlitFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) DECLARE_GL_FUNCTION_END_NO_RETURN(void, BlitFramebuffer, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter)
|
||||
//DECLARE_GL_FUNCTION_HEAD(void, BlitFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) DECLARE_GL_FUNCTION_END_NO_RETURN(void, BlitFramebuffer, srcX0,srcY0,srcX1,srcY1,dstX0,dstY0,dstX1,dstY1,mask,filter)
|
||||
DECLARE_GL_FUNCTION_HEAD(void, RenderbufferStorageMultisample, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) DECLARE_GL_FUNCTION_END_NO_RETURN(void, RenderbufferStorageMultisample, target, samples, internalformat, width, height)
|
||||
@@ -359,12 +359,12 @@ DECLARE_GL_FUNCTION_HEAD(void, ProgramUniform4fv, GLuint program, GLint location
|
||||
DECLARE_GL_FUNCTION_HEAD(void, ProgramUniformMatrix2fv, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) DECLARE_GL_FUNCTION_END_NO_RETURN(void, ProgramUniformMatrix2fv, program, location, count, transpose, value)
|
||||
DECLARE_GL_FUNCTION_HEAD(void, ProgramUniformMatrix3fv, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) DECLARE_GL_FUNCTION_END_NO_RETURN(void, ProgramUniformMatrix3fv, program, location, count, transpose, value)
|
||||
DECLARE_GL_FUNCTION_HEAD(void, ProgramUniformMatrix4fv, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) DECLARE_GL_FUNCTION_END_NO_RETURN(void, ProgramUniformMatrix4fv, program, location, count, transpose, value)
|
||||
DECLARE_GL_FUNCTION_STUB_HEAD(void, ProgramUniformMatrix2x3fv, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, ProgramUniformMatrix2x3fv, program, location, count, transpose, value)
|
||||
DECLARE_GL_FUNCTION_STUB_HEAD(void, ProgramUniformMatrix3x2fv, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, ProgramUniformMatrix3x2fv, program, location, count, transpose, value)
|
||||
DECLARE_GL_FUNCTION_STUB_HEAD(void, ProgramUniformMatrix2x4fv, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, ProgramUniformMatrix2x4fv, program, location, count, transpose, value)
|
||||
DECLARE_GL_FUNCTION_STUB_HEAD(void, ProgramUniformMatrix4x2fv, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, ProgramUniformMatrix4x2fv, program, location, count, transpose, value)
|
||||
DECLARE_GL_FUNCTION_STUB_HEAD(void, ProgramUniformMatrix3x4fv, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, ProgramUniformMatrix3x4fv, program, location, count, transpose, value)
|
||||
DECLARE_GL_FUNCTION_STUB_HEAD(void, ProgramUniformMatrix4x3fv, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, ProgramUniformMatrix4x3fv, program, location, count, transpose, value)
|
||||
DECLARE_GL_FUNCTION_HEAD(void, ProgramUniformMatrix2x3fv, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) DECLARE_GL_FUNCTION_END_NO_RETURN(void, ProgramUniformMatrix2x3fv, program, location, count, transpose, value)
|
||||
DECLARE_GL_FUNCTION_HEAD(void, ProgramUniformMatrix3x2fv, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) DECLARE_GL_FUNCTION_END_NO_RETURN(void, ProgramUniformMatrix3x2fv, program, location, count, transpose, value)
|
||||
DECLARE_GL_FUNCTION_HEAD(void, ProgramUniformMatrix2x4fv, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) DECLARE_GL_FUNCTION_END_NO_RETURN(void, ProgramUniformMatrix2x4fv, program, location, count, transpose, value)
|
||||
DECLARE_GL_FUNCTION_HEAD(void, ProgramUniformMatrix4x2fv, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) DECLARE_GL_FUNCTION_END_NO_RETURN(void, ProgramUniformMatrix4x2fv, program, location, count, transpose, value)
|
||||
DECLARE_GL_FUNCTION_HEAD(void, ProgramUniformMatrix3x4fv, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) DECLARE_GL_FUNCTION_END_NO_RETURN(void, ProgramUniformMatrix3x4fv, program, location, count, transpose, value)
|
||||
DECLARE_GL_FUNCTION_HEAD(void, ProgramUniformMatrix4x3fv, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) DECLARE_GL_FUNCTION_END_NO_RETURN(void, ProgramUniformMatrix4x3fv, program, location, count, transpose, value)
|
||||
DECLARE_GL_FUNCTION_STUB_HEAD(void, ValidateProgramPipeline, GLuint pipeline) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, ValidateProgramPipeline, pipeline)
|
||||
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetProgramPipelineInfoLog, GLuint pipeline, GLsizei bufSize, GLsizei* length, GLchar* infoLog) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetProgramPipelineInfoLog, pipeline, bufSize, length, infoLog)
|
||||
DECLARE_GL_FUNCTION_HEAD(void, BindImageTexture, GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format) DECLARE_GL_FUNCTION_END_NO_RETURN(void, BindImageTexture, unit, texture, level, layered, layer, access, format)
|
||||
|
||||
@@ -646,6 +646,52 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
}
|
||||
}
|
||||
|
||||
switch (target) {
|
||||
case GL_IMAGE_BINDING_NAME:
|
||||
case GL_IMAGE_BINDING_LEVEL:
|
||||
case GL_IMAGE_BINDING_LAYERED:
|
||||
case GL_IMAGE_BINDING_LAYER:
|
||||
case GL_IMAGE_BINDING_ACCESS:
|
||||
case GL_IMAGE_BINDING_FORMAT: {
|
||||
const auto maxImageUnits = static_cast<GLuint>(std::min<GLint>(
|
||||
MG_Backend::pActiveBackendObject->GetDynamicParameters().MaxImageUnits,
|
||||
MG_State::GLState::TextureState::MAX_TEXTURE_IMAGE_UNITS));
|
||||
if (index >= maxImageUnits) {
|
||||
*data = 0;
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidValue,
|
||||
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "Image unit index is out of range."));
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& binding = MG_State::pGLContext->GetImageTextureBinding(static_cast<Int>(index));
|
||||
switch (target) {
|
||||
case GL_IMAGE_BINDING_NAME:
|
||||
*data = binding.Texture ? static_cast<GLint>(binding.Texture->GetExternalIndex()) : 0;
|
||||
return;
|
||||
case GL_IMAGE_BINDING_LEVEL:
|
||||
*data = binding.Level;
|
||||
return;
|
||||
case GL_IMAGE_BINDING_LAYERED:
|
||||
*data = binding.Layered;
|
||||
return;
|
||||
case GL_IMAGE_BINDING_LAYER:
|
||||
*data = binding.Layer;
|
||||
return;
|
||||
case GL_IMAGE_BINDING_ACCESS:
|
||||
*data = static_cast<GLint>(binding.Access);
|
||||
return;
|
||||
case GL_IMAGE_BINDING_FORMAT:
|
||||
*data = static_cast<GLint>(binding.Format);
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
auto getIntegeri = MG_Backend::gBackendFunctionsTable.GL.GetIntegeri_v;
|
||||
if (target == GL_MAX_COMPUTE_WORK_GROUP_COUNT || target == GL_MAX_COMPUTE_WORK_GROUP_SIZE) {
|
||||
if (index >= 3) {
|
||||
|
||||
@@ -216,6 +216,25 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
return false;
|
||||
}
|
||||
|
||||
GLint GetOpaqueUniformUnitLimit(const glslang::TType* type) {
|
||||
const auto& dynamicParameters = MG_Backend::pActiveBackendObject->GetDynamicParameters();
|
||||
if (type && type->isImage()) return dynamicParameters.MaxImageUnits;
|
||||
if (type && type->isTexture()) return dynamicParameters.MaxCombinedTextureImageUnits;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool ValidateOpaqueUniformUnit(const char* functionName, const glslang::TType* type, GLint unit) {
|
||||
const GLint limit = GetOpaqueUniformUnitLimit(type);
|
||||
if (unit < 0 || unit >= limit) {
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidValue,
|
||||
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", functionName,
|
||||
"Opaque uniform unit is out of range."));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void AttachShader_State(GLuint program, GLuint shader) {
|
||||
auto& programObject = TryToGetProgramObject(program);
|
||||
if (!programObject) return;
|
||||
@@ -776,12 +795,19 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
Memcpy((char*)programObject.MapUBO() + offset + byteOffsetInsideUniform, value, ItemCount * sizeof(T));
|
||||
} else {
|
||||
auto* ttype = programObject.GetUniformTType(location);
|
||||
if (ttype->isTexture() || ttype->isImage()) {
|
||||
MGLOG_D("%s: program = %d, opaque uniform location = %d, name = '%s', unit = %d", __func__,
|
||||
programObject.GetExternalIndex(), location, programObject.GetUniformName(location).c_str(),
|
||||
static_cast<Int>(*value));
|
||||
programObject.SetUniformSamplerOrImageUnitIndex(location, *value);
|
||||
if (!ttype->isTexture() && !ttype->isImage()) return;
|
||||
if constexpr (!std::is_same_v<std::remove_cv_t<T>, GLint> || ItemCount != 1) {
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidOperation,
|
||||
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||
"Opaque uniforms can only be set with Uniform1i/Uniform1iv."));
|
||||
return;
|
||||
}
|
||||
if (!ValidateOpaqueUniformUnit(__func__, ttype, *value)) return;
|
||||
MGLOG_D("%s: program = %d, opaque uniform location = %d, name = '%s', unit = %d", __func__,
|
||||
programObject.GetExternalIndex(), location, programObject.GetUniformName(location).c_str(),
|
||||
static_cast<Int>(*value));
|
||||
programObject.SetUniformSamplerOrImageUnitIndex(location, *value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1033,6 +1059,34 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
}
|
||||
}
|
||||
|
||||
void UniformMatrixNonSquarefv_State(const char* caller, GLint location, GLsizei count) {
|
||||
if (location == -1) return;
|
||||
|
||||
auto& programObject = MG_State::pGLContext->GetCurrentProgram();
|
||||
if (programObject == nullptr) {
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidOperation,
|
||||
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", caller, "There is no current program object."));
|
||||
return;
|
||||
}
|
||||
|
||||
for (GLint i = 0; i < count; i++) {
|
||||
if (!programObject->IsValidUniformLocation(location + i)) {
|
||||
RecordInvalidUniformLocationError(caller, location + i, "the current program object");
|
||||
return;
|
||||
}
|
||||
if (programObject->IsUniformOpaqueAtLocation(location + i)) {
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidOperation,
|
||||
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", caller,
|
||||
"Opaque uniforms cannot be set with matrix Uniform calls."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Implement non-square matrix uniform uploads for non-opaque uniforms.
|
||||
}
|
||||
|
||||
void ProgramUniformMatrix2fv_State(GLuint program, GLint location, GLsizei count, GLboolean transpose,
|
||||
const GLfloat* value) {
|
||||
if (location == -1) return;
|
||||
@@ -1127,6 +1181,37 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
}
|
||||
}
|
||||
|
||||
void ProgramUniformMatrixNonSquarefv_State(const char* caller, GLuint program, GLint location, GLsizei count) {
|
||||
if (location == -1) return;
|
||||
|
||||
auto& programObject = TryToGetProgramObject(program);
|
||||
if (!programObject) return;
|
||||
|
||||
if (!programObject->GetLinkStatus()) {
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidOperation,
|
||||
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", caller,
|
||||
"program " + std::to_string(program) + " is not linked."));
|
||||
return;
|
||||
}
|
||||
|
||||
for (GLint i = 0; i < count; i++) {
|
||||
if (!programObject->IsValidUniformLocation(location + i)) {
|
||||
RecordInvalidUniformLocationError(caller, location + i, "program " + std::to_string(program));
|
||||
return;
|
||||
}
|
||||
if (programObject->IsUniformOpaqueAtLocation(location + i)) {
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidOperation,
|
||||
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", caller,
|
||||
"Opaque uniforms cannot be set with matrix Uniform calls."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Implement non-square matrix uniform uploads for non-opaque uniforms.
|
||||
}
|
||||
|
||||
GLuint GetUniformBlockIndex_State(GLuint program, const GLchar* uniformBlockName) {
|
||||
const auto& programObject = TryToGetProgramObject(program);
|
||||
if (!programObject) return GL_INVALID_INDEX;
|
||||
@@ -1576,6 +1661,30 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
UniformMatrix4fv_State(location, count, transpose, value);
|
||||
}
|
||||
|
||||
void UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) {
|
||||
UniformMatrixNonSquarefv_State(__func__, location, count);
|
||||
}
|
||||
|
||||
void UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) {
|
||||
UniformMatrixNonSquarefv_State(__func__, location, count);
|
||||
}
|
||||
|
||||
void UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) {
|
||||
UniformMatrixNonSquarefv_State(__func__, location, count);
|
||||
}
|
||||
|
||||
void UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) {
|
||||
UniformMatrixNonSquarefv_State(__func__, location, count);
|
||||
}
|
||||
|
||||
void UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) {
|
||||
UniformMatrixNonSquarefv_State(__func__, location, count);
|
||||
}
|
||||
|
||||
void UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) {
|
||||
UniformMatrixNonSquarefv_State(__func__, location, count);
|
||||
}
|
||||
|
||||
void ProgramUniform1f(GLuint program, GLint location, GLfloat v0) {
|
||||
ProgramUniform1fv(program, location, 1, &v0);
|
||||
}
|
||||
@@ -1696,6 +1805,36 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
ProgramUniformMatrix4fv_State(program, location, count, transpose, value);
|
||||
}
|
||||
|
||||
void ProgramUniformMatrix2x3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose,
|
||||
const GLfloat* value) {
|
||||
ProgramUniformMatrixNonSquarefv_State(__func__, program, location, count);
|
||||
}
|
||||
|
||||
void ProgramUniformMatrix3x2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose,
|
||||
const GLfloat* value) {
|
||||
ProgramUniformMatrixNonSquarefv_State(__func__, program, location, count);
|
||||
}
|
||||
|
||||
void ProgramUniformMatrix2x4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose,
|
||||
const GLfloat* value) {
|
||||
ProgramUniformMatrixNonSquarefv_State(__func__, program, location, count);
|
||||
}
|
||||
|
||||
void ProgramUniformMatrix4x2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose,
|
||||
const GLfloat* value) {
|
||||
ProgramUniformMatrixNonSquarefv_State(__func__, program, location, count);
|
||||
}
|
||||
|
||||
void ProgramUniformMatrix3x4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose,
|
||||
const GLfloat* value) {
|
||||
ProgramUniformMatrixNonSquarefv_State(__func__, program, location, count);
|
||||
}
|
||||
|
||||
void ProgramUniformMatrix4x3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose,
|
||||
const GLfloat* value) {
|
||||
ProgramUniformMatrixNonSquarefv_State(__func__, program, location, count);
|
||||
}
|
||||
|
||||
GLuint GetUniformBlockIndex(GLuint program, const GLchar* uniformBlockName) {
|
||||
return GetUniformBlockIndex_State(program, uniformBlockName);
|
||||
}
|
||||
|
||||
@@ -99,6 +99,24 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
const GLfloat* value);
|
||||
void ProgramUniformMatrix4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose,
|
||||
const GLfloat* value);
|
||||
void UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
|
||||
void UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
|
||||
void UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
|
||||
void UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
|
||||
void UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
|
||||
void UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
|
||||
void ProgramUniformMatrix2x3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose,
|
||||
const GLfloat* value);
|
||||
void ProgramUniformMatrix3x2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose,
|
||||
const GLfloat* value);
|
||||
void ProgramUniformMatrix2x4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose,
|
||||
const GLfloat* value);
|
||||
void ProgramUniformMatrix4x2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose,
|
||||
const GLfloat* value);
|
||||
void ProgramUniformMatrix3x4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose,
|
||||
const GLfloat* value);
|
||||
void ProgramUniformMatrix4x3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose,
|
||||
const GLfloat* value);
|
||||
GLuint GetUniformBlockIndex(GLuint program, const GLchar* uniformBlockName);
|
||||
void UniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
|
||||
void GetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params);
|
||||
|
||||
@@ -231,6 +231,59 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
}
|
||||
}
|
||||
|
||||
Bool IsValidImageTextureFormat(GLenum format) {
|
||||
switch (format) {
|
||||
case GL_RGBA32F:
|
||||
case GL_RGBA16F:
|
||||
case GL_RG32F:
|
||||
case GL_RG16F:
|
||||
case GL_R11F_G11F_B10F:
|
||||
case GL_R32F:
|
||||
case GL_R16F:
|
||||
case GL_RGBA32UI:
|
||||
case GL_RGBA16UI:
|
||||
case GL_RGB10_A2UI:
|
||||
case GL_RGBA8UI:
|
||||
case GL_RG32UI:
|
||||
case GL_RG16UI:
|
||||
case GL_RG8UI:
|
||||
case GL_R32UI:
|
||||
case GL_R16UI:
|
||||
case GL_R8UI:
|
||||
case GL_RGBA32I:
|
||||
case GL_RGBA16I:
|
||||
case GL_RGBA8I:
|
||||
case GL_RG32I:
|
||||
case GL_RG16I:
|
||||
case GL_RG8I:
|
||||
case GL_R32I:
|
||||
case GL_R16I:
|
||||
case GL_R8I:
|
||||
case GL_RGBA16:
|
||||
case GL_RGB10_A2:
|
||||
case GL_RGBA8:
|
||||
case GL_RG16:
|
||||
case GL_RG8:
|
||||
case GL_R16:
|
||||
case GL_R8:
|
||||
case GL_RGBA16_SNORM:
|
||||
case GL_RGBA8_SNORM:
|
||||
case GL_RG16_SNORM:
|
||||
case GL_RG8_SNORM:
|
||||
case GL_R16_SNORM:
|
||||
case GL_R8_SNORM:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
GLuint GetAdvertisedImageUnitCount() {
|
||||
return static_cast<GLuint>(std::min<GLint>(
|
||||
MG_Backend::pActiveBackendObject->GetDynamicParameters().MaxImageUnits,
|
||||
MG_State::GLState::TextureState::MAX_TEXTURE_IMAGE_UNITS));
|
||||
}
|
||||
|
||||
Uint ComputeFullMipmapLevelCount(const IntVec3& baseTexelSize) {
|
||||
Int maxDimension = std::max<Int>(
|
||||
baseTexelSize.x(),
|
||||
@@ -1752,6 +1805,11 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
textureObject->GetSamplerObject()->GetSamplerCompareFunc());
|
||||
}
|
||||
break;
|
||||
case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE:
|
||||
if (params) {
|
||||
*params = GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
MG_State::pGLContext->RecordError(ErrorCode::InvalidEnum,
|
||||
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "GetTexParameteriv_State",
|
||||
@@ -3102,7 +3160,7 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
|
||||
void BindImageTexture(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access,
|
||||
GLenum format) {
|
||||
if (unit >= MG_State::GLState::TextureState::MAX_TEXTURE_IMAGE_UNITS) {
|
||||
if (unit >= GetAdvertisedImageUnitCount()) {
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidValue,
|
||||
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "Image texture unit is out of range."));
|
||||
@@ -3126,6 +3184,12 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "Invalid image texture access."));
|
||||
return;
|
||||
}
|
||||
if (!IsValidImageTextureFormat(format)) {
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidValue,
|
||||
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "Invalid image texture format."));
|
||||
return;
|
||||
}
|
||||
|
||||
SharedPtr<MG_State::GLState::ITextureObject> textureObject;
|
||||
if (texture != 0) {
|
||||
|
||||
@@ -321,12 +321,16 @@ namespace MobileGL::MG_State::GLState {
|
||||
// ------------ Uniforms (GL Plain) ----------------
|
||||
// Allocate uniform locations
|
||||
m_activeUniformCount = m_program->getNumUniformVariables();
|
||||
Int requiredUniformLocations = 0;
|
||||
MGLOG_D("ProgramObject %u: Reflection - active uniform count = %d", m_externalIndex, m_activeUniformCount);
|
||||
for (int i = 0; i < m_activeUniformCount; i++) {
|
||||
auto& uniform = m_program->getUniform(i);
|
||||
auto location = uniform.layoutLocation();
|
||||
const Int locationSpan =
|
||||
(uniform.getType() && uniform.getType()->isOpaque()) ? std::max(1, uniform.size) : 1;
|
||||
requiredUniformLocations += locationSpan;
|
||||
if (location != glslang::TQualifier::layoutLocationEnd) {
|
||||
m_maxUniformLocation = std::max(m_maxUniformLocation, location);
|
||||
m_maxUniformLocation = std::max(m_maxUniformLocation, location + locationSpan - 1);
|
||||
}
|
||||
m_uniformNameMaxLength = std::max(m_uniformNameMaxLength, (Int)uniform.name.length());
|
||||
m_uniformLocations[uniform.name] = location;
|
||||
@@ -337,13 +341,13 @@ namespace MobileGL::MG_State::GLState {
|
||||
MGLOG_D("ProgramObject %u: Reflection - computed m_maxUniformLocation=%u m_uniformNameMaxLength=%d",
|
||||
m_externalIndex, m_maxUniformLocation, m_uniformNameMaxLength);
|
||||
|
||||
if (m_maxUniformLocation + 1 < m_activeUniformCount) {
|
||||
MGLOG_D("ProgramObject %u: Reflection - maxUniformLocation+1 (%u) < activeUniformCount (%d), "
|
||||
if (m_maxUniformLocation + 1 < requiredUniformLocations) {
|
||||
MGLOG_D("ProgramObject %u: Reflection - maxUniformLocation+1 (%u) < requiredUniformLocations (%d), "
|
||||
"adjusting",
|
||||
m_externalIndex, m_maxUniformLocation + 1, m_activeUniformCount);
|
||||
m_externalIndex, m_maxUniformLocation + 1, requiredUniformLocations);
|
||||
// This means we have fewer than enough gaps to fit
|
||||
// unallocated uniforms
|
||||
m_maxUniformLocation = m_activeUniformCount;
|
||||
m_maxUniformLocation = requiredUniformLocations - 1;
|
||||
}
|
||||
|
||||
// i-th elements refers to uniform at layout(location = i, ...)
|
||||
@@ -362,9 +366,14 @@ namespace MobileGL::MG_State::GLState {
|
||||
m_externalIndex, uniform.name.c_str());
|
||||
continue; // will allocate unallocated uniforms later
|
||||
}
|
||||
m_uniformIndexInTProgram[location] = i;
|
||||
MGLOG_D("ProgramObject %u: Reflection - assigned uniform '%s' to location %d (indexInTProgram=%d)",
|
||||
m_externalIndex, uniform.name.c_str(), location, i);
|
||||
const Int locationSpan =
|
||||
(uniform.getType() && uniform.getType()->isOpaque()) ? std::max(1, uniform.size) : 1;
|
||||
for (Int element = 0; element < locationSpan; ++element) {
|
||||
m_uniformIndexInTProgram[location + element] = i;
|
||||
}
|
||||
MGLOG_D("ProgramObject %u: Reflection - assigned uniform '%s' to locations %d..%d "
|
||||
"(indexInTProgram=%d)",
|
||||
m_externalIndex, uniform.name.c_str(), location, location + locationSpan - 1, i);
|
||||
}
|
||||
|
||||
SizeT locNeedle = 0;
|
||||
@@ -375,15 +384,24 @@ namespace MobileGL::MG_State::GLState {
|
||||
});
|
||||
for (auto index : unallocatedUniformIndex) {
|
||||
auto& uniform = m_program->getUniform(index);
|
||||
const Int locationSpan =
|
||||
(uniform.getType() && uniform.getType()->isOpaque()) ? std::max(1, uniform.size) : 1;
|
||||
for (; locNeedle <= m_maxUniformLocation; locNeedle++) {
|
||||
if (m_uniformIndexInTProgram[locNeedle] != glslang::TQualifier::layoutLocationEnd) continue;
|
||||
bool hasRoom = locNeedle + locationSpan - 1 <= m_maxUniformLocation;
|
||||
for (Int element = 0; hasRoom && element < locationSpan; ++element) {
|
||||
hasRoom = m_uniformIndexInTProgram[locNeedle + element] ==
|
||||
glslang::TQualifier::layoutLocationEnd;
|
||||
}
|
||||
if (!hasRoom) continue;
|
||||
// Found a vacant location at locNeedle
|
||||
m_uniformIndexInTProgram[locNeedle] = index;
|
||||
for (Int element = 0; element < locationSpan; ++element) {
|
||||
m_uniformIndexInTProgram[locNeedle + element] = index;
|
||||
}
|
||||
m_uniformLocations[uniform.name] = locNeedle;
|
||||
MGLOG_D("ProgramObject %u: Reflection - assigned unallocated uniform '%s' to location %zu "
|
||||
MGLOG_D("ProgramObject %u: Reflection - assigned unallocated uniform '%s' to locations %zu..%zu "
|
||||
"(index %d)",
|
||||
m_externalIndex, uniform.name.c_str(), locNeedle, index);
|
||||
locNeedle++;
|
||||
m_externalIndex, uniform.name.c_str(), locNeedle, locNeedle + locationSpan - 1, index);
|
||||
locNeedle += locationSpan;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -404,9 +422,14 @@ namespace MobileGL::MG_State::GLState {
|
||||
const auto explicitBinding = m_explicitOpaqueUniformBindings.find(uniform.name);
|
||||
const int initialUnit =
|
||||
explicitBinding != m_explicitOpaqueUniformBindings.end() ? static_cast<int>(explicitBinding->second) : 0;
|
||||
m_uniformSamplerOrImageUnitIndex[location] = initialUnit;
|
||||
MGLOG_D("ProgramObject %u: Reflection - opaque uniform '%s' location=%u initialUnit=%d",
|
||||
m_externalIndex, uniform.name.c_str(), location, initialUnit);
|
||||
const Int locationSpan = std::max(1, uniform.size);
|
||||
for (Int element = 0; element < locationSpan &&
|
||||
location + element < m_uniformSamplerOrImageUnitIndex.size(); ++element) {
|
||||
m_uniformSamplerOrImageUnitIndex[location + element] =
|
||||
initialUnit + (explicitBinding != m_explicitOpaqueUniformBindings.end() ? element : 0);
|
||||
}
|
||||
MGLOG_D("ProgramObject %u: Reflection - opaque uniform '%s' locations=%u..%u initialUnit=%d",
|
||||
m_externalIndex, uniform.name.c_str(), location, location + locationSpan - 1, initialUnit);
|
||||
}
|
||||
|
||||
// ------------ attributes (vertex in) ---------------
|
||||
|
||||
Reference in New Issue
Block a user