From 56424f93423dc784af28a117fa84b55679908dbb Mon Sep 17 00:00:00 2001 From: Stanislav Vorobiov Date: Mon, 18 Jun 2012 19:46:15 +0400 Subject: [PATCH] Fixed a bug with alignment. Also, we now fail the gles2 transfer if we meet at least one virtual address which is not mapped to any physical page, target seems to feed us such addresses sometimes, this is to be studied --- hw/gles2.c | 16 ++++++++++++++++ hw/gles2_escommon_calls.c | 15 ++++++++++----- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/hw/gles2.c b/hw/gles2.c index b5e9547312..00928a7bb4 100644 --- a/hw/gles2.c +++ b/hw/gles2.c @@ -79,6 +79,10 @@ int gles2_transfer_compile(gles2_CompiledTransfer* tfr, gles2_State *s, while (len) { target_ulong start_page = TARGET_PAGE(start_addr); target_ulong start_pa = gles2_pa(s, start_page, 0); + if (!start_pa) + { + return 0; + } #if (GLES2_DEBUG == 1) target_ulong end_pa = start_pa; #endif // GLES2_DEBUG == 1 @@ -88,6 +92,10 @@ int gles2_transfer_compile(gles2_CompiledTransfer* tfr, gles2_State *s, while(end_page < last_page) { target_ulong next_page = end_page + TARGET_PAGE_SIZE; target_ulong next_pa = gles2_pa(s, next_page, 0); + if (!next_pa) + { + return 0; + } // If the target pages are not linearly spaced, stop.. if((next_pa < start_pa) || @@ -181,6 +189,10 @@ int gles2_transfer(gles2_State *s, target_ulong va, target_ulong len, while (len) { target_ulong start_page = TARGET_PAGE(start_addr); target_ulong start_pa = gles2_pa(s, start_page, access_type); + if (!start_pa) + { + return 0; + } #if (GLES2_DEBUG == 1) target_ulong end_pa = start_pa; #endif // GLES2_DEBUG == 1 @@ -190,6 +202,10 @@ int gles2_transfer(gles2_State *s, target_ulong va, target_ulong len, while(end_page < last_page) { target_ulong next_page = end_page + TARGET_PAGE_SIZE; target_ulong next_pa = gles2_pa(s, next_page, access_type); + if (!next_pa) + { + return 0; + } // If the target pages are not linearly spaced, stop.. if ((next_pa < start_pa) || diff --git a/hw/gles2_escommon_calls.c b/hw/gles2_escommon_calls.c index b1051a3f82..7e31424a72 100644 --- a/hw/gles2_escommon_calls.c +++ b/hw/gles2_escommon_calls.c @@ -16,13 +16,18 @@ static unsigned gles2_glTexParameterCount(TGLenum pname) return count; } -static unsigned gles2_get_stride(unsigned bpp) +static unsigned gles2_get_stride(unsigned width, unsigned bpp) { unsigned alignment = 0; hgl.glGetIntegerv(GL_UNPACK_ALIGNMENT, (GLint *)&alignment); - return (alignment > bpp) ? alignment : bpp; + if (!alignment) + { + alignment = 1; + } + + return ((width * bpp) + alignment - 1) & ~(alignment - 1); } static void gles2_TransferArrays(gles2_State *s, gles2_Context *c, @@ -840,7 +845,7 @@ GLES2_CB(glReadPixels) GLES2_PRINT("Reading %dx%dx%d image at %d,%d...\n", width, height, bpp, x, y); - nbytes = width*height*gles2_get_stride(bpp); + nbytes = height*gles2_get_stride(width, bpp); pixels = malloc(nbytes); } hgl.glReadPixels(x, y, width, height, format, type, pixels); @@ -928,7 +933,7 @@ GLES2_CB(glTexImage2D) GLES2_PRINT("Uploading %dx%dx%d image...\n", width, height, bpp); char* pixels = NULL; if (pixelsp && width > 0 && height > 0) { - TGLsizei nbytes = width*height*gles2_get_stride(bpp); + TGLsizei nbytes = height*gles2_get_stride(width, bpp); pixels = malloc(nbytes); gles2_transfer(s, pixelsp, nbytes, pixels, 0); } @@ -1034,7 +1039,7 @@ GLES2_CB(glTexSubImage2D) char *pixels = NULL; if (pixelsp && width > 0 && height > 0) { - TGLsizei nbytes = width*height*gles2_get_stride(bpp); + TGLsizei nbytes = height*gles2_get_stride(width, bpp); pixels = malloc(nbytes); gles2_transfer(s, pixelsp, nbytes, pixels, 0); } -- 2.34.1