r600g: guard experimental s3tc code with R600_ENABLE_S3TC
[mesa.git] / src / gallium / drivers / r600 / r600_texture.c
index a63990fbffe9054340593b4256e4a68bc5e0afb5..a590858c85287c7d936c5de457e9915a9c369521 100644 (file)
@@ -341,6 +341,18 @@ static void r600_texture_destroy(struct pipe_screen *screen,
        FREE(rtex);
 }
 
+static boolean r600_texture_get_handle(struct pipe_screen* screen,
+                                       struct pipe_resource *ptex,
+                                       struct winsys_handle *whandle)
+{
+       struct r600_resource_texture *rtex = (struct r600_resource_texture*)ptex;
+       struct r600_resource *resource = &rtex->resource;
+       struct radeon *radeon = (struct radeon *)screen->winsys;
+
+       return r600_bo_get_winsys_handle(radeon, resource->bo,
+                       rtex->pitch_in_bytes[0], whandle);
+}
+
 static struct pipe_surface *r600_get_tex_surface(struct pipe_screen *screen,
                                                struct pipe_resource *texture,
                                                unsigned face, unsigned level,
@@ -454,6 +466,36 @@ static INLINE unsigned u_box_volume( const struct pipe_box *box )
 };
 
 
+/* Figure out whether u_blitter will fallback to a transfer operation.
+ * If so, don't use a staging resource.
+ */
+static boolean permit_hardware_blit(struct pipe_screen *screen,
+                                    struct pipe_resource *res)
+{
+        unsigned bind;
+
+        if (util_format_is_depth_or_stencil(res->format))
+                bind = PIPE_BIND_DEPTH_STENCIL;
+        else
+                bind = PIPE_BIND_RENDER_TARGET;
+
+        if (!screen->is_format_supported(screen,
+                                         res->format,
+                                         res->target,
+                                         res->nr_samples,
+                                         bind, 0))
+                return FALSE;
+
+        if (!screen->is_format_supported(screen,
+                                         res->format,
+                                         res->target,
+                                         res->nr_samples,
+                                         PIPE_BIND_SAMPLER_VIEW, 0))
+                return FALSE;
+
+        return TRUE;
+}
+
 struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx,
                                                struct pipe_resource *texture,
                                                struct pipe_subresource sr,
@@ -465,10 +507,6 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx,
        struct r600_transfer *trans;
        int r;
        boolean use_staging_texture = FALSE;
-       boolean discard = FALSE;
-
-       if (!(usage & PIPE_TRANSFER_READ) && (usage & PIPE_TRANSFER_DISCARD))
-               discard = TRUE;
 
        /* We cannot map a tiled texture directly because the data is
         * in a different order, therefore we do detiling using a blit.
@@ -480,7 +518,7 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx,
        if (rtex->tiled)
                use_staging_texture = TRUE;
 
-        if (usage & PIPE_TRANSFER_READ &&
+       if ((usage & PIPE_TRANSFER_READ) &&
             u_box_volume(box) > 1024)
                 use_staging_texture = TRUE;
 
@@ -490,10 +528,15 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx,
          * and might block.
          */
         if ((usage & PIPE_TRANSFER_WRITE) &&
-            discard &&
-            !(usage & (PIPE_TRANSFER_DONTBLOCK | PIPE_TRANSFER_UNSYNCHRONIZED)))
+            !(usage & (PIPE_TRANSFER_READ |
+                       PIPE_TRANSFER_DONTBLOCK |
+                       PIPE_TRANSFER_UNSYNCHRONIZED)))
                 use_staging_texture = TRUE;
 
+        if (!permit_hardware_blit(ctx->screen, texture) ||
+            (texture->flags & R600_RESOURCE_FLAG_TRANSFER))
+                use_staging_texture = FALSE;
+
        trans = CALLOC_STRUCT(r600_transfer);
        if (trans == NULL)
                return NULL;
@@ -545,7 +588,7 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx,
 
                trans->transfer.stride =
                         ((struct r600_resource_texture *)trans->staging_texture)->pitch_in_bytes[0];
-               if (!discard) {
+               if (usage & PIPE_TRANSFER_READ) {
                        r600_copy_to_staging_texture(ctx, trans);
                        /* Always referenced in the blit. */
                        ctx->flush(ctx, 0, NULL);
@@ -655,7 +698,7 @@ void r600_texture_transfer_unmap(struct pipe_context *ctx,
 
 struct u_resource_vtbl r600_texture_vtbl =
 {
-       u_default_resource_get_handle,  /* get_handle */
+       r600_texture_get_handle,        /* get_handle */
        r600_texture_destroy,           /* resource_destroy */
        r600_texture_is_referenced,     /* is_resource_referenced */
        r600_texture_get_transfer,      /* get_transfer */
@@ -760,7 +803,7 @@ uint32_t r600_translate_texformat(enum pipe_format format,
                        result = FMT_24_8;
                        goto out_word4;
                case PIPE_FORMAT_S8_USCALED:
-                       result = V_0280A0_COLOR_8;
+                       result = FMT_8;
                        word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT);
                        goto out_word4;
                default:
@@ -789,7 +832,29 @@ uint32_t r600_translate_texformat(enum pipe_format format,
 
        /* S3TC formats. TODO */
        if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
-               goto out_unknown;
+                static int r600_enable_s3tc = -1;
+
+                if (r600_enable_s3tc == -1)
+                        r600_enable_s3tc = 
+                                debug_get_bool_option("R600_ENABLE_S3TC", FALSE);
+
+                if (!r600_enable_s3tc)
+                        goto out_unknown;
+
+               switch (format) {
+               case PIPE_FORMAT_DXT1_RGB:
+               case PIPE_FORMAT_DXT1_RGBA:
+                        result = FMT_BC1;
+                        goto out_word4;
+               case PIPE_FORMAT_DXT3_RGBA:
+                        result = FMT_BC2;
+                        goto out_word4;
+               case PIPE_FORMAT_DXT5_RGBA:
+                        result = FMT_BC3;
+                        goto out_word4;
+                default:
+                        goto out_unknown;
+                }
        }