Merge branch '7.8'
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_blit.c
index 4abe7a2960de82da840e99d55d043d5699ad934f..143822361e1504b001a3899adc5de0b9e35adee9 100644 (file)
@@ -37,6 +37,31 @@ static inline uint32_t cmdpacket0(struct radeon_screen *rscrn,
     return CP_PACKET2;
 }
 
+/* common formats supported as both textures and render targets */
+unsigned r100_check_blit(gl_format mesa_format)
+{
+    /* XXX others?  BE/LE? */
+    switch (mesa_format) {
+    case MESA_FORMAT_ARGB8888:
+    case MESA_FORMAT_XRGB8888:
+    case MESA_FORMAT_RGB565:
+    case MESA_FORMAT_ARGB4444:
+    case MESA_FORMAT_ARGB1555:
+    case MESA_FORMAT_A8:
+    case MESA_FORMAT_L8:
+    case MESA_FORMAT_I8:
+           break;
+    default:
+           return 0;
+    }
+
+    /* ??? */
+    if (_mesa_get_format_bits(mesa_format, GL_DEPTH_BITS) > 0)
+           return 0;
+
+    return 1;
+}
+
 static inline void emit_vtx_state(struct r100_context *r100)
 {
     BATCH_LOCALS(&r100->radeon);
@@ -80,18 +105,31 @@ static void inline emit_tx_setup(struct r100_context *r100,
     case MESA_FORMAT_ARGB8888:
            txformat |= RADEON_TXFORMAT_ARGB8888 | RADEON_TXFORMAT_ALPHA_IN_MAP;
            break;
+    case MESA_FORMAT_RGBA8888:
+            txformat |= RADEON_TXFORMAT_RGBA8888 | RADEON_TXFORMAT_ALPHA_IN_MAP;
+            break;
     case MESA_FORMAT_XRGB8888:
            txformat |= RADEON_TXFORMAT_ARGB8888;
            break;
     case MESA_FORMAT_RGB565:
            txformat |= RADEON_TXFORMAT_RGB565;
            break;
+    case MESA_FORMAT_ARGB4444:
+           txformat |= RADEON_TXFORMAT_ARGB4444 | RADEON_TXFORMAT_ALPHA_IN_MAP;
+           break;
     case MESA_FORMAT_ARGB1555:
            txformat |= RADEON_TXFORMAT_ARGB1555 | RADEON_TXFORMAT_ALPHA_IN_MAP;
            break;
     case MESA_FORMAT_A8:
+    case MESA_FORMAT_I8:
            txformat |= RADEON_TXFORMAT_I8 | RADEON_TXFORMAT_ALPHA_IN_MAP;
            break;
+    case MESA_FORMAT_L8:
+            txformat |= RADEON_TXFORMAT_I8;
+            break;
+    case MESA_FORMAT_AL88:
+            txformat |= RADEON_TXFORMAT_AI88 | RADEON_TXFORMAT_ALPHA_IN_MAP;
+            break;
     default:
            break;
     }
@@ -115,7 +153,7 @@ static void inline emit_tx_setup(struct r100_context *r100,
     OUT_BATCH_REGVAL(RADEON_PP_TXFORMAT_0, txformat);
     OUT_BATCH_REGVAL(RADEON_PP_TEX_SIZE_0, ((width - 1) |
                                            ((height - 1) << RADEON_TEX_VSIZE_SHIFT)));
-    OUT_BATCH_REGVAL(RADEON_PP_TEX_PITCH_0, pitch - 32);
+    OUT_BATCH_REGVAL(RADEON_PP_TEX_PITCH_0, pitch * _mesa_get_format_bytes(mesa_format) - 32);
 
     OUT_BATCH_REGSEQ(RADEON_PP_TXOFFSET_0, 1);
     OUT_BATCH_RELOC(0, bo, 0, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
@@ -144,10 +182,15 @@ static inline void emit_cb_setup(struct r100_context *r100,
     case MESA_FORMAT_RGB565:
            dst_format = RADEON_COLOR_FORMAT_RGB565;
            break;
+    case MESA_FORMAT_ARGB4444:
+           dst_format = RADEON_COLOR_FORMAT_ARGB4444;
+           break;
     case MESA_FORMAT_ARGB1555:
            dst_format = RADEON_COLOR_FORMAT_ARGB1555;
            break;
     case MESA_FORMAT_A8:
+    case MESA_FORMAT_L8:
+    case MESA_FORMAT_I8:
            dst_format = RADEON_COLOR_FORMAT_RGB8;
            break;
     default:
@@ -175,15 +218,16 @@ static GLboolean validate_buffers(struct r100_context *r100,
                                   struct radeon_bo *dst_bo)
 {
     int ret;
-    radeon_cs_space_add_persistent_bo(r100->radeon.cmdbuf.cs,
-                                      src_bo, RADEON_GEM_DOMAIN_VRAM, 0);
 
-    radeon_cs_space_add_persistent_bo(r100->radeon.cmdbuf.cs,
-                                      dst_bo, 0, RADEON_GEM_DOMAIN_VRAM);
+    radeon_cs_space_reset_bos(r100->radeon.cmdbuf.cs);
+
+    ret = radeon_cs_space_check_with_bo(r100->radeon.cmdbuf.cs,
+                                        src_bo, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, 0);
+    if (ret)
+        return GL_FALSE;
 
     ret = radeon_cs_space_check_with_bo(r100->radeon.cmdbuf.cs,
-                                        first_elem(&r100->radeon.dma.reserved)->bo,
-                                        RADEON_GEM_DOMAIN_GTT, 0);
+                                        dst_bo, 0, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT);
     if (ret)
         return GL_FALSE;
 
@@ -205,9 +249,8 @@ static inline void calc_tex_coords(float img_width, float img_height,
     buf[3] = buf[2] + reg_height / img_height;
     if (flip_y)
     {
-        float tmp = buf[2];
-        buf[2] = 1.0 - buf[3];
-        buf[3] = 1.0 - tmp;
+        buf[2] = 1.0 - buf[2];
+        buf[3] = 1.0 - buf[3];
     }
 }
 
@@ -230,17 +273,17 @@ static inline void emit_draw_packet(struct r100_context *r100,
     verts[0] = dst_x_offset;
     verts[1] = dst_y_offset + reg_height;
     verts[2] = texcoords[0];
-    verts[3] = texcoords[2];
+    verts[3] = texcoords[3];
 
     verts[4] = dst_x_offset + reg_width;
     verts[5] = dst_y_offset + reg_height;
     verts[6] = texcoords[1];
-    verts[7] = texcoords[2];
+    verts[7] = texcoords[3];
 
     verts[8] = dst_x_offset + reg_width;
     verts[9] = dst_y_offset;
     verts[10] = texcoords[1];
-    verts[11] = texcoords[3];
+    verts[11] = texcoords[2];
 
     BEGIN_BATCH(15);
     OUT_BATCH(RADEON_CP_PACKET3_3D_DRAW_IMMD | (13 << 16));
@@ -278,28 +321,30 @@ static inline void emit_draw_packet(struct r100_context *r100,
  * @param[in] height region height
  * @param[in] flip_y set if y coords of the source image need to be flipped
  */
-GLboolean r100_blit(struct r100_context *r100,
-                    struct radeon_bo *src_bo,
-                    intptr_t src_offset,
-                    gl_format src_mesaformat,
-                    unsigned src_pitch,
-                    unsigned src_width,
-                    unsigned src_height,
-                    unsigned src_x_offset,
-                    unsigned src_y_offset,
-                    struct radeon_bo *dst_bo,
-                    intptr_t dst_offset,
-                    gl_format dst_mesaformat,
-                    unsigned dst_pitch,
-                    unsigned dst_width,
-                    unsigned dst_height,
-                    unsigned dst_x_offset,
-                    unsigned dst_y_offset,
-                    unsigned reg_width,
-                    unsigned reg_height,
-                    unsigned flip_y)
+unsigned r100_blit(GLcontext *ctx,
+                   struct radeon_bo *src_bo,
+                   intptr_t src_offset,
+                   gl_format src_mesaformat,
+                   unsigned src_pitch,
+                   unsigned src_width,
+                   unsigned src_height,
+                   unsigned src_x_offset,
+                   unsigned src_y_offset,
+                   struct radeon_bo *dst_bo,
+                   intptr_t dst_offset,
+                   gl_format dst_mesaformat,
+                   unsigned dst_pitch,
+                   unsigned dst_width,
+                   unsigned dst_height,
+                   unsigned dst_x_offset,
+                   unsigned dst_y_offset,
+                   unsigned reg_width,
+                   unsigned reg_height,
+                   unsigned flip_y)
 {
-    if (_mesa_get_format_bits(src_mesaformat, GL_DEPTH_BITS) > 0)
+    struct r100_context *r100 = R100_CONTEXT(ctx);
+
+    if (!r100_check_blit(dst_mesaformat))
         return GL_FALSE;
 
     /* Make sure that colorbuffer has even width - hw limitation */
@@ -329,6 +374,10 @@ GLboolean r100_blit(struct r100_context *r100,
         return GL_FALSE;
     }
 
+    if (src_offset % 32 || dst_offset % 32) {
+        return GL_FALSE;
+    }
+
     if (0) {
         fprintf(stderr, "src: size [%d x %d], pitch %d, "
                 "offset [%d x %d], format %s, bo %p\n",
@@ -343,7 +392,7 @@ GLboolean r100_blit(struct r100_context *r100,
     }
 
     /* Flush is needed to make sure that source buffer has correct data */
-    radeonFlush(r100->radeon.glCtx);
+    radeonFlush(ctx);
 
     rcommonEnsureCmdBufSpace(&r100->radeon, 59, __FUNCTION__);
 
@@ -363,7 +412,7 @@ GLboolean r100_blit(struct r100_context *r100,
                      reg_width, reg_height,
                      flip_y);
 
-    radeonFlush(r100->radeon.glCtx);
+    radeonFlush(ctx);
 
     return GL_TRUE;
 }