mesa: s/FREE/free/
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_blit.c
index 0df4fbb33c530c7d9e3d81b569b4ad5323727a3d..2d4a2d67be45b6251895fc01e433be1fce6d9739 100644 (file)
@@ -38,7 +38,7 @@ static inline uint32_t cmdpacket0(struct radeon_screen *rscrn,
 }
 
 /* common formats supported as both textures and render targets */
-static unsigned is_blit_supported(gl_format mesa_format)
+unsigned r100_check_blit(gl_format mesa_format, uint32_t dst_pitch)
 {
     /* XXX others?  BE/LE? */
     switch (mesa_format) {
@@ -48,11 +48,19 @@ static unsigned is_blit_supported(gl_format mesa_format)
     case MESA_FORMAT_ARGB4444:
     case MESA_FORMAT_ARGB1555:
     case MESA_FORMAT_A8:
+    case MESA_FORMAT_L8:
+    case MESA_FORMAT_I8:
            break;
     default:
            return 0;
     }
 
+    /* Rendering to small buffer doesn't work.
+     * Looks like a hw limitation.
+     */
+    if (dst_pitch < 32)
+        return 0;
+
     /* ??? */
     if (_mesa_get_format_bits(mesa_format, GL_DEPTH_BITS) > 0)
            return 0;
@@ -94,8 +102,8 @@ static void inline emit_tx_setup(struct r100_context *r100,
     uint32_t txformat = RADEON_TXFORMAT_NON_POWER2;
     BATCH_LOCALS(&r100->radeon);
 
-    assert(width <= 2047);
-    assert(height <= 2047);
+    assert(width <= 2048);
+    assert(height <= 2048);
     assert(offset % 32 == 0);
 
     /* XXX others?  BE/LE? */
@@ -103,6 +111,9 @@ 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;
@@ -116,11 +127,23 @@ static void inline emit_tx_setup(struct r100_context *r100,
            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;
     }
+    
+    if (bo->flags & RADEON_BO_FLAGS_MACRO_TILE)
+       offset |= RADEON_TXO_MACRO_TILE;
+    if (bo->flags & RADEON_BO_FLAGS_MICRO_TILE)
+       offset |= RADEON_TXO_MICRO_TILE_X2;
 
     BEGIN_BATCH(18);
     OUT_BATCH_REGVAL(RADEON_PP_CNTL, RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE);
@@ -144,7 +167,7 @@ static void inline emit_tx_setup(struct r100_context *r100,
     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);
+    OUT_BATCH_RELOC(offset, bo, offset, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
 
     END_BATCH();
 }
@@ -177,22 +200,30 @@ static inline void emit_cb_setup(struct r100_context *r100,
            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:
            break;
     }
 
+    if (bo->flags & RADEON_BO_FLAGS_MACRO_TILE)
+        dst_pitch |= RADEON_COLOR_TILE_ENABLE;
+
+    if (bo->flags & RADEON_BO_FLAGS_MICRO_TILE)
+        dst_pitch |= RADEON_COLOR_MICROTILE_ENABLE;
+
     BEGIN_BATCH_NO_AUTOSTATE(18);
     OUT_BATCH_REGVAL(RADEON_RE_TOP_LEFT, 0);
-    OUT_BATCH_REGVAL(RADEON_RE_WIDTH_HEIGHT, ((width << RADEON_RE_WIDTH_SHIFT) |
-                                             (height << RADEON_RE_HEIGHT_SHIFT)));
+    OUT_BATCH_REGVAL(RADEON_RE_WIDTH_HEIGHT, (((width - 1) << RADEON_RE_WIDTH_SHIFT) |
+                                             ((height - 1) << RADEON_RE_HEIGHT_SHIFT)));
     OUT_BATCH_REGVAL(RADEON_RB3D_PLANEMASK, 0xffffffff);
     OUT_BATCH_REGVAL(RADEON_RB3D_BLENDCNTL, RADEON_SRC_BLEND_GL_ONE | RADEON_DST_BLEND_GL_ZERO);
     OUT_BATCH_REGVAL(RADEON_RB3D_CNTL, dst_format);
 
     OUT_BATCH_REGSEQ(RADEON_RB3D_COLOROFFSET, 1);
-    OUT_BATCH_RELOC(0, bo, 0, 0, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0);
+    OUT_BATCH_RELOC(offset, bo, offset, 0, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0);
     OUT_BATCH_REGSEQ(RADEON_RB3D_COLORPITCH, 1);
     OUT_BATCH_RELOC(dst_pitch, bo, dst_pitch, 0, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0);
 
@@ -204,15 +235,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,
-                                        first_elem(&r100->radeon.dma.reserved)->bo,
-                                        RADEON_GEM_DOMAIN_GTT, 0);
+                                        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,
+                                        dst_bo, 0, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT);
     if (ret)
         return GL_FALSE;
 
@@ -306,7 +338,7 @@ 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
  */
-unsigned r100_blit(GLcontext *ctx,
+unsigned r100_blit(struct gl_context *ctx,
                    struct radeon_bo *src_bo,
                    intptr_t src_offset,
                    gl_format src_mesaformat,
@@ -329,19 +361,13 @@ unsigned r100_blit(GLcontext *ctx,
 {
     struct r100_context *r100 = R100_CONTEXT(ctx);
 
-    if (!is_blit_supported(dst_mesaformat))
+    if (!r100_check_blit(dst_mesaformat, dst_pitch))
         return GL_FALSE;
 
     /* Make sure that colorbuffer has even width - hw limitation */
     if (dst_pitch % 2 > 0)
         ++dst_pitch;
 
-    /* Rendering to small buffer doesn't work.
-     * Looks like a hw limitation.
-     */
-    if (dst_pitch < 32)
-        return GL_FALSE;
-
     /* Need to clamp the region size to make sure
      * we don't read outside of the source buffer
      * or write outside of the destination buffer.
@@ -364,14 +390,14 @@ unsigned r100_blit(GLcontext *ctx,
     }
 
     if (0) {
-        fprintf(stderr, "src: size [%d x %d], pitch %d, "
+        fprintf(stderr, "src: size [%d x %d], pitch %d, offset %zd "
                 "offset [%d x %d], format %s, bo %p\n",
-                src_width, src_height, src_pitch,
+                src_width, src_height, src_pitch, src_offset,
                 src_x_offset, src_y_offset,
                 _mesa_get_format_name(src_mesaformat),
                 src_bo);
-        fprintf(stderr, "dst: pitch %d, offset[%d x %d], format %s, bo %p\n",
-                dst_pitch, dst_x_offset, dst_y_offset,
+        fprintf(stderr, "dst: pitch %d offset %zd, offset[%d x %d], format %s, bo %p\n",
+                dst_pitch, dst_offset,  dst_x_offset, dst_y_offset,
                 _mesa_get_format_name(dst_mesaformat), dst_bo);
         fprintf(stderr, "region: %d x %d\n", reg_width, reg_height);
     }