Add DMA support for glMapBufferRange
Bug: 116046430
Test: run antutu and 3dmark
Change-Id: I3f204bac889d75cdeba21fd88f0920c04c5d589a
Signed-off-by: Roman Kiryanov <rkir@google.com>
diff --git a/system/GLESv2_enc/GL2Encoder.cpp b/system/GLESv2_enc/GL2Encoder.cpp
index 3512a3b..220f198 100755
--- a/system/GLESv2_enc/GL2Encoder.cpp
+++ b/system/GLESv2_enc/GL2Encoder.cpp
@@ -2818,6 +2818,20 @@
return ctx->glUnmapBuffer(ctx, target);
}
+void* GL2Encoder::s_glMapBufferRangeAEMUImpl(GL2Encoder* ctx, GLenum target,
+ GLintptr offset, GLsizeiptr length,
+ GLbitfield access, BufferData* buf) {
+ char* bits = (char*)buf->m_fixedBuffer.ptr() + offset;
+
+ ctx->glMapBufferRangeAEMU(
+ ctx, target,
+ offset, length,
+ access,
+ bits);
+
+ return bits;
+}
+
void* GL2Encoder::s_glMapBufferRange(void* self, GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) {
GL2Encoder* ctx = (GL2Encoder*)self;
GLClientState* state = ctx->m_state;
@@ -2856,14 +2870,37 @@
buf->m_mappedOffset = offset;
buf->m_mappedLength = length;
- char* todo = (char*)buf->m_fixedBuffer.ptr() + offset;
- ctx->glMapBufferRangeAEMU(
- ctx, target,
- offset, length,
- access,
- todo);
+ if (ctx->hasExtension("ANDROID_EMU_dma_v2")) {
+ if (buf->dma_buffer.get().size < length) {
+ goldfish_dma_context region;
- return todo;
+ const int PAGE_BITS = 12;
+ GLsizeiptr aligned_length = (length + (1 << PAGE_BITS) - 1) & ~((1 << PAGE_BITS) - 1);
+
+ if (goldfish_dma_create_region(aligned_length, ®ion)) {
+ buf->dma_buffer.reset(NULL);
+ return s_glMapBufferRangeAEMUImpl(ctx, target, offset, length, access, buf);
+ }
+
+ if (!goldfish_dma_map(®ion)) {
+ buf->dma_buffer.reset(NULL);
+ return s_glMapBufferRangeAEMUImpl(ctx, target, offset, length, access, buf);
+ }
+
+ buf->m_guest_paddr = goldfish_dma_guest_paddr(®ion);
+ buf->dma_buffer.reset(®ion);
+ }
+
+ ctx->glMapBufferRangeDMA(
+ ctx, target,
+ offset, length,
+ access,
+ buf->m_guest_paddr);
+
+ return reinterpret_cast<void*>(buf->dma_buffer.get().mapped_addr);
+ } else {
+ return s_glMapBufferRangeAEMUImpl(ctx, target, offset, length, access, buf);
+ }
}
GLboolean GL2Encoder::s_glUnmapBuffer(void* self, GLenum target) {
@@ -2891,13 +2928,27 @@
GLboolean host_res = GL_TRUE;
- ctx->glUnmapBufferAEMU(
- ctx, target,
- buf->m_mappedOffset,
- buf->m_mappedLength,
- buf->m_mappedAccess,
- (void*)((char*)buf->m_fixedBuffer.ptr() + buf->m_mappedOffset),
- &host_res);
+ if (buf->dma_buffer.get().mapped_addr) {
+ memcpy(static_cast<char*>(buf->m_fixedBuffer.ptr()) + buf->m_mappedOffset,
+ reinterpret_cast<void*>(buf->dma_buffer.get().mapped_addr),
+ buf->m_mappedLength);
+
+ ctx->glUnmapBufferDMA(
+ ctx, target,
+ buf->m_mappedOffset,
+ buf->m_mappedLength,
+ buf->m_mappedAccess,
+ goldfish_dma_guest_paddr(&buf->dma_buffer.get()),
+ &host_res);
+ } else {
+ ctx->glUnmapBufferAEMU(
+ ctx, target,
+ buf->m_mappedOffset,
+ buf->m_mappedLength,
+ buf->m_mappedAccess,
+ (void*)((char*)buf->m_fixedBuffer.ptr() + buf->m_mappedOffset),
+ &host_res);
+ }
buf->m_mapped = false;
buf->m_mappedAccess = 0;
diff --git a/system/GLESv2_enc/GL2Encoder.h b/system/GLESv2_enc/GL2Encoder.h
index 5a5d038..5b51f7b 100644
--- a/system/GLESv2_enc/GL2Encoder.h
+++ b/system/GLESv2_enc/GL2Encoder.h
@@ -414,6 +414,9 @@
static void* s_glMapBufferOES(void* self, GLenum target, GLenum access);
static GLboolean s_glUnmapBufferOES(void* self, GLenum target);
static void* s_glMapBufferRange(void* self, GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
+ static void* s_glMapBufferRangeAEMUImpl(GL2Encoder* ctx, GLenum target,
+ GLintptr offset, GLsizeiptr length,
+ GLbitfield access, BufferData* buf);
static GLboolean s_glUnmapBuffer(void* self, GLenum target);
static void s_glFlushMappedBufferRange(void* self, GLenum target, GLintptr offset, GLsizeiptr length);
diff --git a/system/GLESv2_enc/gl2_client_context.cpp b/system/GLESv2_enc/gl2_client_context.cpp
index 9eb4ac4..7da3e33 100644
--- a/system/GLESv2_enc/gl2_client_context.cpp
+++ b/system/GLESv2_enc/gl2_client_context.cpp
@@ -421,6 +421,8 @@
glGetFramebufferParameteriv = (glGetFramebufferParameteriv_client_proc_t) getProc("glGetFramebufferParameteriv", userData);
glGetTexLevelParameterfv = (glGetTexLevelParameterfv_client_proc_t) getProc("glGetTexLevelParameterfv", userData);
glGetTexLevelParameteriv = (glGetTexLevelParameteriv_client_proc_t) getProc("glGetTexLevelParameteriv", userData);
+ glMapBufferRangeDMA = (glMapBufferRangeDMA_client_proc_t) getProc("glMapBufferRangeDMA", userData);
+ glUnmapBufferDMA = (glUnmapBufferDMA_client_proc_t) getProc("glUnmapBufferDMA", userData);
return 0;
}
diff --git a/system/GLESv2_enc/gl2_client_context.h b/system/GLESv2_enc/gl2_client_context.h
index 6616e53..e2400a9 100644
--- a/system/GLESv2_enc/gl2_client_context.h
+++ b/system/GLESv2_enc/gl2_client_context.h
@@ -421,6 +421,8 @@
glGetFramebufferParameteriv_client_proc_t glGetFramebufferParameteriv;
glGetTexLevelParameterfv_client_proc_t glGetTexLevelParameterfv;
glGetTexLevelParameteriv_client_proc_t glGetTexLevelParameteriv;
+ glMapBufferRangeDMA_client_proc_t glMapBufferRangeDMA;
+ glUnmapBufferDMA_client_proc_t glUnmapBufferDMA;
virtual ~gl2_client_context_t() {}
typedef gl2_client_context_t *CONTEXT_ACCESSOR_TYPE(void);
diff --git a/system/GLESv2_enc/gl2_client_proc.h b/system/GLESv2_enc/gl2_client_proc.h
index 8c88678..8829c58 100644
--- a/system/GLESv2_enc/gl2_client_proc.h
+++ b/system/GLESv2_enc/gl2_client_proc.h
@@ -420,6 +420,8 @@
typedef void (gl2_APIENTRY *glGetFramebufferParameteriv_client_proc_t) (void * ctx, GLenum, GLenum, GLint*);
typedef void (gl2_APIENTRY *glGetTexLevelParameterfv_client_proc_t) (void * ctx, GLenum, GLint, GLenum, GLfloat*);
typedef void (gl2_APIENTRY *glGetTexLevelParameteriv_client_proc_t) (void * ctx, GLenum, GLint, GLenum, GLint*);
+typedef void (gl2_APIENTRY *glMapBufferRangeDMA_client_proc_t) (void * ctx, GLenum, GLintptr, GLsizeiptr, GLbitfield, uint64_t);
+typedef void (gl2_APIENTRY *glUnmapBufferDMA_client_proc_t) (void * ctx, GLenum, GLintptr, GLsizeiptr, GLbitfield, uint64_t, GLboolean*);
#endif
diff --git a/system/GLESv2_enc/gl2_enc.cpp b/system/GLESv2_enc/gl2_enc.cpp
index ffffa49..d5ae4b5 100644
--- a/system/GLESv2_enc/gl2_enc.cpp
+++ b/system/GLESv2_enc/gl2_enc.cpp
@@ -11044,6 +11044,78 @@
}
}
+void glMapBufferRangeDMA_enc(void *self , GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access, uint64_t paddr)
+{
+
+ gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+ IOStream *stream = ctx->m_stream;
+ ChecksumCalculator *checksumCalculator = ctx->m_checksumCalculator;
+ bool useChecksum = checksumCalculator->getVersion() > 0;
+
+ unsigned char *ptr;
+ unsigned char *buf;
+ const size_t sizeWithoutChecksum = 8 + 4 + 4 + 4 + 4 + 8;
+ const size_t checksumSize = checksumCalculator->checksumByteSize();
+ const size_t totalSize = sizeWithoutChecksum + checksumSize;
+ buf = stream->alloc(totalSize);
+ ptr = buf;
+ int tmp = OP_glMapBufferRangeDMA;memcpy(ptr, &tmp, 4); ptr += 4;
+ memcpy(ptr, &totalSize, 4); ptr += 4;
+
+ memcpy(ptr, &target, 4); ptr += 4;
+ memcpy(ptr, &offset, 4); ptr += 4;
+ memcpy(ptr, &length, 4); ptr += 4;
+ memcpy(ptr, &access, 4); ptr += 4;
+ memcpy(ptr, &paddr, 8); ptr += 8;
+
+ if (useChecksum) checksumCalculator->addBuffer(buf, ptr-buf);
+ if (useChecksum) checksumCalculator->writeChecksum(ptr, checksumSize); ptr += checksumSize;
+
+}
+
+void glUnmapBufferDMA_enc(void *self , GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access, uint64_t paddr, GLboolean* out_res)
+{
+
+ gl2_encoder_context_t *ctx = (gl2_encoder_context_t *)self;
+ IOStream *stream = ctx->m_stream;
+ ChecksumCalculator *checksumCalculator = ctx->m_checksumCalculator;
+ bool useChecksum = checksumCalculator->getVersion() > 0;
+
+ const unsigned int __size_out_res = (sizeof(GLboolean));
+ unsigned char *ptr;
+ unsigned char *buf;
+ const size_t sizeWithoutChecksum = 8 + 4 + 4 + 4 + 4 + 8 + 0 + 1*4;
+ const size_t checksumSize = checksumCalculator->checksumByteSize();
+ const size_t totalSize = sizeWithoutChecksum + checksumSize;
+ buf = stream->alloc(totalSize);
+ ptr = buf;
+ int tmp = OP_glUnmapBufferDMA;memcpy(ptr, &tmp, 4); ptr += 4;
+ memcpy(ptr, &totalSize, 4); ptr += 4;
+
+ memcpy(ptr, &target, 4); ptr += 4;
+ memcpy(ptr, &offset, 4); ptr += 4;
+ memcpy(ptr, &length, 4); ptr += 4;
+ memcpy(ptr, &access, 4); ptr += 4;
+ memcpy(ptr, &paddr, 8); ptr += 8;
+ *(unsigned int *)(ptr) = __size_out_res; ptr += 4;
+
+ if (useChecksum) checksumCalculator->addBuffer(buf, ptr-buf);
+ if (useChecksum) checksumCalculator->writeChecksum(ptr, checksumSize); ptr += checksumSize;
+
+ stream->readback(out_res, __size_out_res);
+ if (useChecksum) checksumCalculator->addBuffer(out_res, __size_out_res);
+ if (useChecksum) {
+ unsigned char *checksumBufPtr = NULL;
+ unsigned char checksumBuf[ChecksumCalculator::kMaxChecksumSize];
+ if (checksumSize > 0) checksumBufPtr = &checksumBuf[0];
+ stream->readback(checksumBufPtr, checksumSize);
+ if (!checksumCalculator->validate(checksumBufPtr, checksumSize)) {
+ ALOGE("glUnmapBufferDMA: GL communication error, please report this issue to b.android.com.\n");
+ abort();
+ }
+ }
+}
+
} // namespace
gl2_encoder_context_t::gl2_encoder_context_t(IOStream *stream, ChecksumCalculator *checksumCalculator)
@@ -11462,5 +11534,7 @@
this->glGetFramebufferParameteriv = &glGetFramebufferParameteriv_enc;
this->glGetTexLevelParameterfv = &glGetTexLevelParameterfv_enc;
this->glGetTexLevelParameteriv = &glGetTexLevelParameteriv_enc;
+ this->glMapBufferRangeDMA = &glMapBufferRangeDMA_enc;
+ this->glUnmapBufferDMA = &glUnmapBufferDMA_enc;
}
diff --git a/system/GLESv2_enc/gl2_entry.cpp b/system/GLESv2_enc/gl2_entry.cpp
index 5713921..f60eb44 100644
--- a/system/GLESv2_enc/gl2_entry.cpp
+++ b/system/GLESv2_enc/gl2_entry.cpp
@@ -416,6 +416,8 @@
void glGetFramebufferParameteriv(GLenum target, GLenum pname, GLint* params);
void glGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat* params);
void glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint* params);
+ void glMapBufferRangeDMA(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access, uint64_t paddr);
+ void glUnmapBufferDMA(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access, uint64_t paddr, GLboolean* out_res);
};
#ifndef GET_CONTEXT
@@ -2927,3 +2929,15 @@
ctx->glGetTexLevelParameteriv(ctx, target, level, pname, params);
}
+void glMapBufferRangeDMA(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access, uint64_t paddr)
+{
+ GET_CONTEXT;
+ ctx->glMapBufferRangeDMA(ctx, target, offset, length, access, paddr);
+}
+
+void glUnmapBufferDMA(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access, uint64_t paddr, GLboolean* out_res)
+{
+ GET_CONTEXT;
+ ctx->glUnmapBufferDMA(ctx, target, offset, length, access, paddr, out_res);
+}
+
diff --git a/system/GLESv2_enc/gl2_opcodes.h b/system/GLESv2_enc/gl2_opcodes.h
index 497ebfb..2affe0e 100644
--- a/system/GLESv2_enc/gl2_opcodes.h
+++ b/system/GLESv2_enc/gl2_opcodes.h
@@ -414,7 +414,9 @@
#define OP_glGetFramebufferParameteriv 2456
#define OP_glGetTexLevelParameterfv 2457
#define OP_glGetTexLevelParameteriv 2458
-#define OP_last 2459
+#define OP_glMapBufferRangeDMA 2459
+#define OP_glUnmapBufferDMA 2460
+#define OP_last 2461
#endif