radeon/winsys: add offset support for BO import/export
[mesa.git] / src / gallium / drivers / radeon / r600_texture.c
index b8c4c795b3cab4318458c4f32dddfae4dbdfa985..15818aaae6f519867cfdf9f64b63d24636b30334 100644 (file)
@@ -201,9 +201,11 @@ static int r600_init_surface(struct r600_common_screen *rscreen,
 
 static int r600_setup_surface(struct pipe_screen *screen,
                              struct r600_texture *rtex,
-                             unsigned pitch_in_bytes_override)
+                             unsigned pitch_in_bytes_override,
+                             unsigned offset)
 {
        struct r600_common_screen *rscreen = (struct r600_common_screen*)screen;
+       unsigned i;
        int r;
 
        r = rscreen->ws->surface_init(rscreen->ws, &rtex->surface);
@@ -225,6 +227,11 @@ static int r600_setup_surface(struct pipe_screen *screen,
                        rtex->surface.stencil_level[0].offset = rtex->surface.level[0].slice_size;
                }
        }
+
+       if (offset) {
+               for (i = 0; i < Elements(rtex->surface.level); ++i)
+                       rtex->surface.level[i].offset += offset;
+       }
        return 0;
 }
 
@@ -287,6 +294,7 @@ static void r600_texture_disable_cmask(struct r600_common_screen *rscreen,
 
        /* Notify all contexts about the change. */
        r600_dirty_all_framebuffer_states(rscreen);
+       p_atomic_inc(&rscreen->compressed_colortex_counter);
 }
 
 static void r600_texture_disable_dcc(struct r600_common_screen *rscreen,
@@ -310,8 +318,6 @@ static void r600_texture_disable_dcc(struct r600_common_screen *rscreen,
 
        /* Notify all contexts about the change. */
        r600_dirty_all_framebuffer_states(rscreen);
-
-       /* TODO: re-set all sampler views and images, but how? */
 }
 
 static boolean r600_texture_get_handle(struct pipe_screen* screen,
@@ -355,6 +361,10 @@ static boolean r600_texture_get_handle(struct pipe_screen* screen,
 
                        /* Set metadata. */
                        r600_texture_init_metadata(rtex, &metadata);
+                       if (rscreen->query_opaque_metadata)
+                               rscreen->query_opaque_metadata(rscreen, rtex,
+                                                              &metadata);
+
                        rscreen->ws->buffer_set_metadata(res->buf, &metadata);
                }
        } else {
@@ -363,6 +373,7 @@ static boolean r600_texture_get_handle(struct pipe_screen* screen,
 
        return rscreen->ws->buffer_get_handle(res->buf,
                                              rtex->surface.level[0].pitch_bytes,
+                                             rtex->surface.level[0].offset,
                                              whandle);
 }
 
@@ -599,6 +610,8 @@ static void r600_texture_alloc_cmask_separate(struct r600_common_screen *rscreen
                rtex->cb_color_info |= SI_S_028C70_FAST_CLEAR(1);
        else
                rtex->cb_color_info |= EG_S_028C70_FAST_CLEAR(1);
+
+       p_atomic_inc(&rscreen->compressed_colortex_counter);
 }
 
 static unsigned r600_texture_get_htile_size(struct r600_common_screen *rscreen,
@@ -786,6 +799,7 @@ static struct r600_texture *
 r600_texture_create_object(struct pipe_screen *screen,
                           const struct pipe_resource *base,
                           unsigned pitch_in_bytes_override,
+                          unsigned offset,
                           struct pb_buffer *buf,
                           struct radeon_surf *surface)
 {
@@ -807,7 +821,7 @@ r600_texture_create_object(struct pipe_screen *screen,
        rtex->is_depth = util_format_has_depth(util_format_description(rtex->resource.b.b.format));
 
        rtex->surface = *surface;
-       if (r600_setup_surface(screen, rtex, pitch_in_bytes_override)) {
+       if (r600_setup_surface(screen, rtex, pitch_in_bytes_override, offset)) {
                FREE(rtex);
                return NULL;
        }
@@ -974,7 +988,7 @@ struct pipe_resource *r600_texture_create(struct pipe_screen *screen,
        if (r) {
                return NULL;
        }
-       return (struct pipe_resource *)r600_texture_create_object(screen, templ,
+       return (struct pipe_resource *)r600_texture_create_object(screen, templ, 0,
                                                                  0, NULL, &surface);
 }
 
@@ -985,7 +999,7 @@ static struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen
 {
        struct r600_common_screen *rscreen = (struct r600_common_screen*)screen;
        struct pb_buffer *buf = NULL;
-       unsigned stride = 0;
+       unsigned stride = 0, offset = 0;
        unsigned array_mode;
        struct radeon_surf surface;
        int r;
@@ -997,7 +1011,7 @@ static struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen
              templ->depth0 != 1 || templ->last_level != 0)
                return NULL;
 
-       buf = rscreen->ws->buffer_from_handle(rscreen->ws, whandle, &stride);
+       buf = rscreen->ws->buffer_from_handle(rscreen->ws, whandle, &stride, &offset);
        if (!buf)
                return NULL;
 
@@ -1024,8 +1038,8 @@ static struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen
        if (metadata.scanout)
                surface.flags |= RADEON_SURF_SCANOUT;
 
-       rtex = r600_texture_create_object(screen, templ,
-                                         stride, buf, &surface);
+       rtex = r600_texture_create_object(screen, templ, stride,
+                                         offset, buf, &surface);
        if (!rtex)
                return NULL;