mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-12 14:18:31 +09:00
[Feat] (MG_Impl): implement glGetNamedBufferSubData
The by-name read was a stub, so it left the caller's buffer untouched and a test comparing it against a reference saw whatever that memory already held. Its by-target sibling glGetBufferSubData was already implemented, so this is that function with the buffer resolved by name instead of through a binding: the same non-negative offset and size check, the same bound-by-the-buffer's-size check, the same refusal to read a buffer mapped without GL_MAP_PERSISTENT_BIT, and the same SyncGpuWrites before the download so a GPU-side write that has not landed yet is not missed. Resolving by name reports INVALID_OPERATION for a name that is not a buffer, which the by-target form expresses as "target is bound to no buffer object" instead. direct_state_access.buffers_get_named_buffer_subdata passes on both backends.
This commit is contained in:
@@ -38,6 +38,7 @@ namespace MobileGL::MG_Impl::GLImpl {
|
|||||||
GetNamedBufferParameteriv,
|
GetNamedBufferParameteriv,
|
||||||
GetNamedBufferParameteri64v,
|
GetNamedBufferParameteri64v,
|
||||||
GetNamedBufferPointerv,
|
GetNamedBufferPointerv,
|
||||||
|
GetNamedBufferSubData,
|
||||||
};
|
};
|
||||||
|
|
||||||
const char* GetBufferOpName(BufferOp op) {
|
const char* GetBufferOpName(BufferOp op) {
|
||||||
@@ -76,6 +77,8 @@ namespace MobileGL::MG_Impl::GLImpl {
|
|||||||
return "UnmapNamedBuffer";
|
return "UnmapNamedBuffer";
|
||||||
case BufferOp::FlushMappedNamedBufferRange:
|
case BufferOp::FlushMappedNamedBufferRange:
|
||||||
return "FlushMappedNamedBufferRange";
|
return "FlushMappedNamedBufferRange";
|
||||||
|
case BufferOp::GetNamedBufferSubData:
|
||||||
|
return "GetNamedBufferSubData";
|
||||||
case BufferOp::GetNamedBufferParameteriv:
|
case BufferOp::GetNamedBufferParameteriv:
|
||||||
return "GetNamedBufferParameteriv";
|
return "GetNamedBufferParameteriv";
|
||||||
case BufferOp::GetNamedBufferParameteri64v:
|
case BufferOp::GetNamedBufferParameteri64v:
|
||||||
@@ -891,6 +894,44 @@ namespace MobileGL::MG_Impl::GLImpl {
|
|||||||
bufferObject->DownloadSubData(data, static_cast<SizeT>(offset), static_cast<SizeT>(size));
|
bufferObject->DownloadSubData(data, static_cast<SizeT>(offset), static_cast<SizeT>(size));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GetNamedBufferSubData_State(GLuint buffer, GLintptr offset, GLsizeiptr size, void* data) {
|
||||||
|
if (!data) {
|
||||||
|
// Match GetBufferSubData_State: a null pointer is a caller bug, not a GL-specified error.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size < 0 || offset < 0) {
|
||||||
|
MG_State::pGLContext->RecordError(
|
||||||
|
ErrorCode::InvalidValue,
|
||||||
|
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "GetNamedBufferSubData_State",
|
||||||
|
"Offset and size must be non-negative."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto bufferObject = GetNamedBufferObject(buffer, BufferOp::GetNamedBufferSubData);
|
||||||
|
if (!bufferObject) return;
|
||||||
|
|
||||||
|
if (static_cast<SizeT>(offset) + static_cast<SizeT>(size) > bufferObject->GetSize()) {
|
||||||
|
MG_State::pGLContext->RecordError(
|
||||||
|
ErrorCode::InvalidValue,
|
||||||
|
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "GetNamedBufferSubData_State",
|
||||||
|
"Offset and size exceed buffer size."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bufferObject->IsMapped() &&
|
||||||
|
!(bufferObject->GetMappingAccess() & BufferMappingAccessBit::Persistent)) {
|
||||||
|
MG_State::pGLContext->RecordError(
|
||||||
|
ErrorCode::InvalidOperation,
|
||||||
|
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", "GetNamedBufferSubData_State",
|
||||||
|
"Cannot read from a buffer object mapped without GL_MAP_PERSISTENT_BIT."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bufferObject->SyncGpuWrites();
|
||||||
|
bufferObject->DownloadSubData(data, static_cast<SizeT>(offset), static_cast<SizeT>(size));
|
||||||
|
}
|
||||||
|
|
||||||
void BufferData_State(GLenum target, GLsizeiptr size, const void* data, GLenum usage) {
|
void BufferData_State(GLenum target, GLsizeiptr size, const void* data, GLenum usage) {
|
||||||
MGLOG_D("%s: %s, size = %d, data = %p, usage = %s", __func__, MG_Util::ConvertGLEnumToString(target).c_str(),
|
MGLOG_D("%s: %s, size = %d, data = %p, usage = %s", __func__, MG_Util::ConvertGLEnumToString(target).c_str(),
|
||||||
size, data, MG_Util::ConvertGLEnumToString(usage).c_str());
|
size, data, MG_Util::ConvertGLEnumToString(usage).c_str());
|
||||||
@@ -1553,6 +1594,10 @@ namespace MobileGL::MG_Impl::GLImpl {
|
|||||||
BufferSubData_State(target, offset, size, data);
|
BufferSubData_State(target, offset, size, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GetNamedBufferSubData(GLuint buffer, GLintptr offset, GLsizeiptr size, void* data) {
|
||||||
|
GetNamedBufferSubData_State(buffer, offset, size, data);
|
||||||
|
}
|
||||||
|
|
||||||
void GetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, void* data) {
|
void GetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, void* data) {
|
||||||
GetBufferSubData_State(target, offset, size, data);
|
GetBufferSubData_State(target, offset, size, data);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ namespace MobileGL::MG_Impl::GLImpl {
|
|||||||
GLsizeiptr size);
|
GLsizeiptr size);
|
||||||
void BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void* data);
|
void BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void* data);
|
||||||
void GetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, void* data);
|
void GetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, void* data);
|
||||||
|
void GetNamedBufferSubData(GLuint buffer, GLintptr offset, GLsizeiptr size, void* data);
|
||||||
void BufferData(GLenum target, GLsizeiptr size, const void* data, GLenum usage);
|
void BufferData(GLenum target, GLsizeiptr size, const void* data, GLenum usage);
|
||||||
void BindBuffer(GLenum target, GLuint buffer);
|
void BindBuffer(GLenum target, GLuint buffer);
|
||||||
void GenBuffers(GLsizei n, GLuint* buffers);
|
void GenBuffers(GLsizei n, GLuint* buffers);
|
||||||
|
|||||||
@@ -1025,7 +1025,7 @@ DECLARE_GL_FUNCTION_HEAD(void, FlushMappedNamedBufferRange, GLuint buffer, GLint
|
|||||||
DECLARE_GL_FUNCTION_HEAD(void, GetNamedBufferParameteriv, GLuint buffer, GLenum pname, GLint* params) DECLARE_GL_FUNCTION_END_NO_RETURN(void, GetNamedBufferParameteriv, buffer, pname, params)
|
DECLARE_GL_FUNCTION_HEAD(void, GetNamedBufferParameteriv, GLuint buffer, GLenum pname, GLint* params) DECLARE_GL_FUNCTION_END_NO_RETURN(void, GetNamedBufferParameteriv, buffer, pname, params)
|
||||||
DECLARE_GL_FUNCTION_HEAD(void, GetNamedBufferParameteri64v, GLuint buffer, GLenum pname, GLint64* params) DECLARE_GL_FUNCTION_END_NO_RETURN(void, GetNamedBufferParameteri64v, buffer, pname, params)
|
DECLARE_GL_FUNCTION_HEAD(void, GetNamedBufferParameteri64v, GLuint buffer, GLenum pname, GLint64* params) DECLARE_GL_FUNCTION_END_NO_RETURN(void, GetNamedBufferParameteri64v, buffer, pname, params)
|
||||||
DECLARE_GL_FUNCTION_HEAD(void, GetNamedBufferPointerv, GLuint buffer, GLenum pname, void** params) DECLARE_GL_FUNCTION_END_NO_RETURN(void, GetNamedBufferPointerv, buffer, pname, params)
|
DECLARE_GL_FUNCTION_HEAD(void, GetNamedBufferPointerv, GLuint buffer, GLenum pname, void** params) DECLARE_GL_FUNCTION_END_NO_RETURN(void, GetNamedBufferPointerv, buffer, pname, params)
|
||||||
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetNamedBufferSubData, GLuint buffer, GLintptr offset, GLsizeiptr size, void* data) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetNamedBufferSubData, buffer, offset, size, data)
|
DECLARE_GL_FUNCTION_HEAD(void, GetNamedBufferSubData, GLuint buffer, GLintptr offset, GLsizeiptr size, void* data) DECLARE_GL_FUNCTION_END_NO_RETURN(void, GetNamedBufferSubData, buffer, offset, size, data)
|
||||||
DECLARE_GL_FUNCTION_HEAD(void, CreateFramebuffers, GLsizei n, GLuint* framebuffers) DECLARE_GL_FUNCTION_END_NO_RETURN(void, CreateFramebuffers, n, framebuffers)
|
DECLARE_GL_FUNCTION_HEAD(void, CreateFramebuffers, GLsizei n, GLuint* framebuffers) DECLARE_GL_FUNCTION_END_NO_RETURN(void, CreateFramebuffers, n, framebuffers)
|
||||||
DECLARE_GL_FUNCTION_HEAD(void, NamedFramebufferRenderbuffer, GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) DECLARE_GL_FUNCTION_END_NO_RETURN(void, NamedFramebufferRenderbuffer, framebuffer, attachment, renderbuffertarget, renderbuffer)
|
DECLARE_GL_FUNCTION_HEAD(void, NamedFramebufferRenderbuffer, GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) DECLARE_GL_FUNCTION_END_NO_RETURN(void, NamedFramebufferRenderbuffer, framebuffer, attachment, renderbuffertarget, renderbuffer)
|
||||||
DECLARE_GL_FUNCTION_STUB_HEAD(void, NamedFramebufferParameteri, GLuint framebuffer, GLenum pname, GLint param) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, NamedFramebufferParameteri, framebuffer, pname, param)
|
DECLARE_GL_FUNCTION_STUB_HEAD(void, NamedFramebufferParameteri, GLuint framebuffer, GLenum pname, GLint param) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, NamedFramebufferParameteri, framebuffer, pname, param)
|
||||||
|
|||||||
Reference in New Issue
Block a user