Fixed a bug with alignment. Also, we now fail the gles2 transfer
authorStanislav Vorobiov <s.vorobiov@samsung.com>
Mon, 18 Jun 2012 15:46:15 +0000 (19:46 +0400)
committerEvgeny Voevodin <e.voevodin@samsung.com>
Fri, 22 Jun 2012 05:30:38 +0000 (09:30 +0400)
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
hw/gles2_escommon_calls.c

index b5e9547..00928a7 100644 (file)
@@ -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) ||
index b1051a3..7e31424 100644 (file)
@@ -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);
     }