r600g: fix depth hw resource copies.
[mesa.git] / src / gallium / drivers / r600 / r600_texture.c
index 91032e83825561398e7a4a280a2f38e08975cc3d..c773c4b84a6d6967b7c9198c61b1857050041ab6 100644 (file)
@@ -278,6 +278,36 @@ static void r600_setup_miptree(struct pipe_screen *screen,
        rtex->size = offset;
 }
 
+/* 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,
+                                       const 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;
+}
+
 static struct r600_resource_texture *
 r600_texture_create_object(struct pipe_screen *screen,
                           const struct pipe_resource *base,
@@ -301,6 +331,9 @@ r600_texture_create_object(struct pipe_screen *screen,
        resource->base.b.screen = screen;
        resource->bo = bo;
        rtex->pitch_override = pitch_in_bytes_override;
+       /* only mark depth textures the HW can hit as depth textures */
+       if (util_format_is_depth_or_stencil(base->format) && permit_hardware_blit(screen, base))
+               rtex->depth = 1;
 
        if (array_mode)
                rtex->tiled = 1;
@@ -332,7 +365,7 @@ struct pipe_resource *r600_texture_create(struct pipe_screen *screen,
        if (force_tiling == -1)
                force_tiling = debug_get_bool_option("R600_FORCE_TILING", FALSE);
 
-       if (force_tiling) {
+       if (force_tiling && permit_hardware_blit(screen, templ)) {
                if (!(templ->flags & R600_RESOURCE_FLAG_TRANSFER) &&
                    !(templ->bind & PIPE_BIND_SCANOUT)) {
                        array_mode = V_038000_ARRAY_2D_TILED_THIN1;
@@ -471,6 +504,7 @@ int r600_texture_depth_flush(struct pipe_context *ctx,
                return -ENOMEM;
        }
 
+       ((struct r600_resource_texture *)rtex->flushed_depth_texture)->is_flushing_texture = TRUE;
 out:
        /* XXX: only do this if the depth texture has actually changed:
         */
@@ -485,46 +519,6 @@ static INLINE unsigned u_box_volume( const struct pipe_box *box )
        return box->width * box->depth * box->height;
 };
 
-
-/* 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;
-
-       /* See r600_resource_copy_region: there is something wrong
-        * with depth resource copies at the moment so avoid them for
-        * now.
-        */
-       if (util_format_get_component_bits(res->format,
-                               UTIL_FORMAT_COLORSPACE_ZS,
-                               0) != 0)
-               return FALSE;
-
-       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,
                                                unsigned level,
@@ -584,6 +578,9 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx,
                        FREE(trans);
                        return NULL;
                }
+               trans->transfer.stride = rtex->flushed_depth_texture->pitch_in_bytes[level];
+               trans->offset = r600_texture_get_offset(rtex->flushed_depth_texture, level, box->z);
+               return &trans->transfer;
        } else if (use_staging_texture) {
                resource.target = PIPE_TEXTURE_2D;
                resource.format = texture->format;
@@ -633,7 +630,6 @@ void r600_texture_transfer_destroy(struct pipe_context *ctx,
                                   struct pipe_transfer *transfer)
 {
        struct r600_transfer *rtransfer = (struct r600_transfer*)transfer;
-       struct r600_resource_texture *rtex = (struct r600_resource_texture*)transfer->resource;
 
        if (rtransfer->staging_texture) {
                if (transfer->usage & PIPE_TRANSFER_WRITE) {
@@ -641,9 +637,6 @@ void r600_texture_transfer_destroy(struct pipe_context *ctx,
                }
                pipe_resource_reference(&rtransfer->staging_texture, NULL);
        }
-       if (rtex->flushed_depth_texture) {
-               pipe_resource_reference((struct pipe_resource **)&rtex->flushed_depth_texture, NULL);
-       }
        pipe_resource_reference(&transfer->resource, NULL);
        FREE(transfer);
 }
@@ -925,7 +918,7 @@ uint32_t r600_translate_texformat(enum pipe_format format,
                            desc->channel[1].size == 10 &&
                            desc->channel[2].size == 10 &&
                            desc->channel[3].size == 2) {
-                               result = FMT_10_10_10_2;
+                               result = FMT_2_10_10_10;
                                goto out_word4;
                        }
                        goto out_unknown;