r600g: add support for common surface allocator for tiling v13
authorJerome Glisse <jglisse@redhat.com>
Mon, 30 Jan 2012 22:22:13 +0000 (17:22 -0500)
committerJerome Glisse <jglisse@redhat.com>
Mon, 6 Feb 2012 23:36:37 +0000 (18:36 -0500)
Tiled surface have all kind of alignment constraint that needs to
be met. Instead of having all this code duplicated btw ddx and
mesa use common code in libdrm_radeon this also ensure that both
ddx and mesa compute those alignment in the same way.

v2 fix evergreen
v3 fix compressed texture and workaround cube texture issue by
   disabling 2D array mode for cubemap (need to check if r7xx and
   newer are also affected by the issue)
v4 fix texture array
v5 fix evergreen and newer, split surface values computation from
   mipmap tree generation so that we can get them directly from the
   ddx
v6 final fix to evergreen tile split value
v7 fix mipmap offset to avoid to use random value, use color view
   depth view to address different layer as hardware is doing some
   magic rotation depending on the layer
v8 fix COLOR_VIEW on r6xx for linear array mode, use COLOR_VIEW on
   evergreen, align bytes per pixel to a multiple of a dword
v9 fix handling of stencil on evergreen, half fix for compressed
   texture
v10 fix evergreen compressed texture proper support for stencil
    tile split. Fix stencil issue when array mode was clear by
    the kernel, always program stencil bo. On evergreen depth
    buffer bo need to be big enough to hold depth buffer + stencil
    buffer as even with stencil disabled things get written there.
v11 rebase on top of mesa, fix pitch issue with 1d surface on evergreen,
    old ddx overestimate those. Fix linear case when pitch*height < 64.
    Fix r300g.
v12 Fix linear case when pitch*height < 64 for old path, adapt to
    libdrm API change
v13 add libdrm check

Signed-off-by: Jerome Glisse <jglisse@redhat.com>
23 files changed:
configure.ac
src/gallium/drivers/r300/r300_texture.c
src/gallium/drivers/r600/evergreen_state.c
src/gallium/drivers/r600/evergreend.h
src/gallium/drivers/r600/r600_blit.c
src/gallium/drivers/r600/r600_hw_context.c
src/gallium/drivers/r600/r600_pipe.h
src/gallium/drivers/r600/r600_resource.h
src/gallium/drivers/r600/r600_state.c
src/gallium/drivers/r600/r600_texture.c
src/gallium/targets/dri-r300/Makefile
src/gallium/targets/dri-r600/Makefile
src/gallium/targets/egl-static/Makefile
src/gallium/targets/va-r300/Makefile
src/gallium/targets/va-r600/Makefile
src/gallium/targets/vdpau-r300/Makefile
src/gallium/targets/vdpau-r600/Makefile
src/gallium/targets/xorg-r300/Makefile
src/gallium/targets/xorg-r600/Makefile
src/gallium/winsys/radeon/drm/radeon_drm_bo.c
src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
src/gallium/winsys/radeon/drm/radeon_drm_winsys.h
src/gallium/winsys/radeon/drm/radeon_winsys.h

index af1e914f35aebf24c4824e93804c9f9088be7333..b2b1ab8f41a131089b84325fef962f7d4d79bb8d 100644 (file)
@@ -36,7 +36,7 @@ USER_CXXFLAGS="$CXXFLAGS"
 
 dnl Versions for external dependencies
 LIBDRM_REQUIRED=2.4.24
-LIBDRM_RADEON_REQUIRED=2.4.24
+LIBDRM_RADEON_REQUIRED=2.4.31
 LIBDRM_INTEL_REQUIRED=2.4.30
 LIBDRM_NOUVEAU_REQUIRED=0.6
 DRI2PROTO_REQUIRED=2.6
@@ -1864,11 +1864,13 @@ if test "x$with_gallium_drivers" != x; then
             gallium_check_st "i915/drm" "dri-i915" "xorg-i915"
             ;;
         xr300)
+            PKG_CHECK_MODULES([RADEON], [libdrm_radeon >= $LIBDRM_RADEON_REQUIRED])
             gallium_require_llvm "Gallium R300"
             GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS r300"
             gallium_check_st "radeon/drm" "dri-r300" "xorg-r300" "" "xvmc-r300" "vdpau-r300" "va-r300"
             ;;
         xr600)
+            PKG_CHECK_MODULES([RADEON], [libdrm_radeon >= $LIBDRM_RADEON_REQUIRED])
             GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS r600"
             gallium_check_st "radeon/drm" "dri-r600" "xorg-r600" "" "xvmc-r600" "vdpau-r600" "va-r600"
             ;;
index 0b352e9dacac80b6925fc2b003b2d1279c116344..99678bc89a8292a92cc74e69ef518136210e03c0 100644 (file)
@@ -963,7 +963,7 @@ struct pipe_resource *r300_texture_from_handle(struct pipe_screen *screen,
     if (!buffer)
         return NULL;
 
-    rws->buffer_get_tiling(buffer, &microtile, &macrotile);
+    rws->buffer_get_tiling(buffer, &microtile, &macrotile, NULL, NULL, NULL, NULL, NULL);
 
     /* Enforce a microtiled zbuffer. */
     if (util_format_is_depth_or_stencil(base->format) &&
index 89f22153a7e8d44ddf68ca2b832d4c3e6de13061..dd67e4bf1d80542b1f5fb10db272837d38acd731 100644 (file)
 #include "r600_pipe.h"
 #include "r600_formats.h"
 
+static uint32_t eg_num_banks(uint32_t nbanks)
+{
+       switch (nbanks) {
+       case 2:
+               return 0;
+       case 4:
+               return 1;
+       case 8:
+       default:
+               return 2;
+       case 16:
+               return 3;
+       }
+}
+
+
+static unsigned eg_tile_split(unsigned tile_split)
+{
+       switch (tile_split) {
+       case 64:        tile_split = 0; break;
+       case 128:       tile_split = 1; break;
+       case 256:       tile_split = 2; break;
+       case 512:       tile_split = 3; break;
+       default:
+       case 1024:      tile_split = 4; break;
+       case 2048:      tile_split = 5; break;
+       case 4096:      tile_split = 6; break;
+       }
+       return tile_split;
+}
+
+static unsigned eg_macro_tile_aspect(unsigned macro_tile_aspect)
+{
+       switch (macro_tile_aspect) {
+       default:
+       case 1: macro_tile_aspect = 0;  break;
+       case 2: macro_tile_aspect = 1;  break;
+       case 4: macro_tile_aspect = 2;  break;
+       case 8: macro_tile_aspect = 3;  break;
+       }
+       return macro_tile_aspect;
+}
+
+static unsigned eg_bank_wh(unsigned bankwh)
+{
+       switch (bankwh) {
+       default:
+       case 1: bankwh = 0;     break;
+       case 2: bankwh = 1;     break;
+       case 4: bankwh = 2;     break;
+       case 8: bankwh = 3;     break;
+       }
+       return bankwh;
+}
+
 static uint32_t r600_translate_blend_function(int blend_func)
 {
        switch (blend_func) {
@@ -1035,13 +1090,15 @@ static struct pipe_sampler_view *evergreen_create_sampler_view(struct pipe_conte
                                                        struct pipe_resource *texture,
                                                        const struct pipe_sampler_view *state)
 {
+       struct r600_screen *rscreen = (struct r600_screen*)ctx->screen;
        struct r600_pipe_sampler_view *view = CALLOC_STRUCT(r600_pipe_sampler_view);
        struct r600_pipe_resource_state *rstate;
        struct r600_resource_texture *tmp = (struct r600_resource_texture*)texture;
        unsigned format, endian;
        uint32_t word4 = 0, yuv_format = 0, pitch = 0;
        unsigned char swizzle[4], array_mode = 0, tile_type = 0;
-       unsigned height, depth;
+       unsigned height, depth, width;
+       unsigned macro_aspect, tile_split, bankh, bankw, nbanks;
 
        if (view == NULL)
                return NULL;
@@ -1074,13 +1131,50 @@ static struct pipe_sampler_view *evergreen_create_sampler_view(struct pipe_conte
 
        endian = r600_colorformat_endian_swap(format);
 
-       height = texture->height0;
-       depth = texture->depth0;
-
-       pitch = align(tmp->pitch_in_blocks[0] *
-                     util_format_get_blockwidth(state->format), 8);
-       array_mode = tmp->array_mode[0];
-       tile_type = tmp->tile_type;
+       if (!rscreen->use_surface) {
+               height = texture->height0;
+               depth = texture->depth0;
+               width = texture->width0;
+               pitch = align(tmp->pitch_in_blocks[0] *
+                               util_format_get_blockwidth(state->format), 8);
+               array_mode = tmp->array_mode[0];
+               tile_type = tmp->tile_type;
+               tile_split = 0;
+               macro_aspect = 0;
+               bankw = 0;
+               bankh = 0;
+       } else {
+               width = tmp->surface.level[0].npix_x;
+               height = tmp->surface.level[0].npix_y;
+               depth = tmp->surface.level[0].npix_z;
+               pitch = tmp->surface.level[0].nblk_x * util_format_get_blockwidth(state->format);
+               tile_type = tmp->tile_type;
+
+               switch (tmp->surface.level[0].mode) {
+               case RADEON_SURF_MODE_LINEAR_ALIGNED:
+                       array_mode = V_028C70_ARRAY_LINEAR_ALIGNED;
+                       break;
+               case RADEON_SURF_MODE_2D:
+                       array_mode = V_028C70_ARRAY_2D_TILED_THIN1;
+                       break;
+               case RADEON_SURF_MODE_1D:
+                       array_mode = V_028C70_ARRAY_1D_TILED_THIN1;
+                       break;
+               case RADEON_SURF_MODE_LINEAR:
+               default:
+                       array_mode = V_028C70_ARRAY_LINEAR_GENERAL;
+                       break;
+               }
+               tile_split = tmp->surface.tile_split;
+               macro_aspect = tmp->surface.mtilea;
+               bankw = tmp->surface.bankw;
+               bankh = tmp->surface.bankh;
+               tile_split = eg_tile_split(tile_split);
+               macro_aspect = eg_macro_tile_aspect(macro_aspect);
+               bankw = eg_bank_wh(bankw);
+               bankh = eg_bank_wh(bankh);
+       }
+       nbanks = eg_num_banks(rscreen->tiling_info.num_banks);
 
        if (texture->target == PIPE_TEXTURE_1D_ARRAY) {
                height = 1;
@@ -1097,12 +1191,16 @@ static struct pipe_sampler_view *evergreen_create_sampler_view(struct pipe_conte
        rstate->val[0] = (S_030000_DIM(r600_tex_dim(texture->target)) |
                          S_030000_PITCH((pitch / 8) - 1) |
                          S_030000_NON_DISP_TILING_ORDER(tile_type) |
-                         S_030000_TEX_WIDTH(texture->width0 - 1));
+                         S_030000_TEX_WIDTH(width - 1));
        rstate->val[1] = (S_030004_TEX_HEIGHT(height - 1) |
                          S_030004_TEX_DEPTH(depth - 1) |
                          S_030004_ARRAY_MODE(array_mode));
        rstate->val[2] = (tmp->offset[0] + r600_resource_va(ctx->screen, texture)) >> 8;
-       rstate->val[3] = (tmp->offset[1] + r600_resource_va(ctx->screen, texture)) >> 8;
+       if (state->u.tex.last_level) {
+               rstate->val[3] = (tmp->offset[1] + r600_resource_va(ctx->screen, texture)) >> 8;
+       } else {
+               rstate->val[3] = (tmp->offset[0] + r600_resource_va(ctx->screen, texture)) >> 8;
+       }
        rstate->val[4] = (word4 |
                          S_030010_SRF_MODE_ALL(V_030010_SRF_MODE_ZERO_CLAMP_MINUS_ONE) |
                          S_030010_ENDIAN_SWAP(endian) |
@@ -1110,9 +1208,15 @@ static struct pipe_sampler_view *evergreen_create_sampler_view(struct pipe_conte
        rstate->val[5] = (S_030014_LAST_LEVEL(state->u.tex.last_level) |
                          S_030014_BASE_ARRAY(state->u.tex.first_layer) |
                          S_030014_LAST_ARRAY(state->u.tex.last_layer));
-       rstate->val[6] = (S_030018_MAX_ANISO(4 /* max 16 samples */));
-       rstate->val[7] = (S_03001C_DATA_FORMAT(format) |
-                         S_03001C_TYPE(V_03001C_SQ_TEX_VTX_VALID_TEXTURE));
+       /* aniso max 16 samples */
+       rstate->val[6] = (S_030018_MAX_ANISO(4)) |
+                        (S_030018_TILE_SPLIT(tile_split));
+       rstate->val[7] = S_03001C_DATA_FORMAT(format) |
+                        S_03001C_TYPE(V_03001C_SQ_TEX_VTX_VALID_TEXTURE) |
+                        S_03001C_BANK_WIDTH(bankw) |
+                        S_03001C_BANK_HEIGHT(bankh) |
+                        S_03001C_MACRO_TILE_ASPECT(macro_aspect) |
+                        S_03001C_NUM_BANKS(nbanks);
 
        return &view->base;
 }
@@ -1318,16 +1422,17 @@ static void evergreen_set_viewport_state(struct pipe_context *ctx,
 }
 
 static void evergreen_cb(struct r600_context *rctx, struct r600_pipe_state *rstate,
-                       const struct pipe_framebuffer_state *state, int cb)
+                        const struct pipe_framebuffer_state *state, int cb)
 {
+       struct r600_screen *rscreen = rctx->screen;
        struct r600_resource_texture *rtex;
        struct r600_surface *surf;
        unsigned level = state->cbufs[cb]->u.tex.level;
        unsigned pitch, slice;
-       unsigned color_info;
+       unsigned color_info, color_attrib;
        unsigned format, swap, ntype, endian;
        uint64_t offset;
-       unsigned tile_type;
+       unsigned tile_type, macro_aspect, tile_split, bankh, bankw, nbanks;
        const struct util_format_description *desc;
        int i;
        unsigned blend_clamp = 0, blend_bypass = 0;
@@ -1344,10 +1449,66 @@ static void evergreen_cb(struct r600_context *rctx, struct r600_pipe_state *rsta
        }
 
        /* XXX quite sure for dx10+ hw don't need any offset hacks */
-       offset = r600_texture_get_offset(rtex,
-                                        level, state->cbufs[cb]->u.tex.first_layer);
-       pitch = rtex->pitch_in_blocks[level] / 8 - 1;
-       slice = rtex->pitch_in_blocks[level] * surf->aligned_height / 64 - 1;
+       if (!rscreen->use_surface) {
+               offset = r600_texture_get_offset(rtex,
+                               level, state->cbufs[cb]->u.tex.first_layer);
+               pitch = rtex->pitch_in_blocks[level] / 8 - 1;
+               slice = rtex->pitch_in_blocks[level] * surf->aligned_height / 64;
+               if (slice) {
+                       slice = slice - 1;
+               }
+               color_info = S_028C70_ARRAY_MODE(rtex->array_mode[level]);
+               tile_split = 0;
+               macro_aspect = 0;
+               bankw = 0;
+               bankh = 0;
+               if (rtex->array_mode[level] > V_028C70_ARRAY_LINEAR_ALIGNED) {
+                       tile_type = rtex->tile_type;
+               } else {
+                       /* workaround for linear buffers */
+                       tile_type = 1;
+               }
+       } else {
+               offset = rtex->surface.level[level].offset;
+               if (rtex->surface.level[level].mode < RADEON_SURF_MODE_1D) {
+                       offset += rtex->surface.level[level].slice_size *
+                                 state->cbufs[cb]->u.tex.first_layer;
+               }
+               pitch = (rtex->surface.level[level].nblk_x) / 8 - 1;
+               slice = (rtex->surface.level[level].nblk_x * rtex->surface.level[level].nblk_y) / 64;
+               if (slice) {
+                       slice = slice - 1;
+               }
+               color_info = 0;
+               switch (rtex->surface.level[level].mode) {
+               case RADEON_SURF_MODE_LINEAR_ALIGNED:
+                       color_info = S_028C70_ARRAY_MODE(V_028C70_ARRAY_LINEAR_ALIGNED);
+                       tile_type = 1;
+                       break;
+               case RADEON_SURF_MODE_1D:
+                       color_info = S_028C70_ARRAY_MODE(V_028C70_ARRAY_1D_TILED_THIN1);
+                       tile_type = rtex->tile_type;
+                       break;
+               case RADEON_SURF_MODE_2D:
+                       color_info = S_028C70_ARRAY_MODE(V_028C70_ARRAY_2D_TILED_THIN1);
+                       tile_type = rtex->tile_type;
+                       break;
+               case RADEON_SURF_MODE_LINEAR:
+               default:
+                       color_info = S_028C70_ARRAY_MODE(V_028C70_ARRAY_LINEAR_GENERAL);
+                       tile_type = 1;
+                       break;
+               }
+               tile_split = rtex->surface.tile_split;
+               macro_aspect = rtex->surface.mtilea;
+               bankw = rtex->surface.bankw;
+               bankh = rtex->surface.bankh;
+               tile_split = eg_tile_split(tile_split);
+               macro_aspect = eg_macro_tile_aspect(macro_aspect);
+               bankw = eg_bank_wh(bankw);
+               bankh = eg_bank_wh(bankh);
+       }
+       nbanks = eg_num_banks(rscreen->tiling_info.num_banks);
        desc = util_format_description(surf->base.format);
        for (i = 0; i < 4; i++) {
                if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) {
@@ -1355,6 +1516,13 @@ static void evergreen_cb(struct r600_context *rctx, struct r600_pipe_state *rsta
                }
        }
 
+       color_attrib = S_028C74_TILE_SPLIT(tile_split)|
+                       S_028C74_NUM_BANKS(nbanks) |
+                       S_028C74_BANK_WIDTH(bankw) |
+                       S_028C74_BANK_HEIGHT(bankh) |
+                       S_028C74_MACRO_TILE_ASPECT(macro_aspect) |
+                       S_028C74_NON_DISP_TILING_ORDER(tile_type);
+
        ntype = V_028C70_NUMBER_UNORM;
        if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB)
                ntype = V_028C70_NUMBER_SRGB;
@@ -1392,9 +1560,8 @@ static void evergreen_cb(struct r600_context *rctx, struct r600_pipe_state *rsta
                blend_bypass = 1;
        }
 
-       color_info = S_028C70_FORMAT(format) |
+       color_info |= S_028C70_FORMAT(format) |
                S_028C70_COMP_SWAP(swap) |
-               S_028C70_ARRAY_MODE(rtex->array_mode[level]) |
                S_028C70_BLEND_CLAMP(blend_clamp) |
                S_028C70_BLEND_BYPASS(blend_bypass) |
                S_028C70_NUMBER_TYPE(ntype) |
@@ -1421,10 +1588,6 @@ static void evergreen_cb(struct r600_context *rctx, struct r600_pipe_state *rsta
        }
        rctx->alpha_ref_dirty = true;
 
-       if (rtex->array_mode[level] > V_028C70_ARRAY_LINEAR_ALIGNED) {
-               tile_type = rtex->tile_type;
-       } else /* workaround for linear buffers */
-               tile_type = 1;
 
        offset += r600_resource_va(rctx->context.screen, state->cbufs[cb]->texture);
        offset >>= 8;
@@ -1447,22 +1610,38 @@ static void evergreen_cb(struct r600_context *rctx, struct r600_pipe_state *rsta
                                R_028C68_CB_COLOR0_SLICE + cb * 0x3C,
                                S_028C68_SLICE_TILE_MAX(slice),
                                NULL, 0);
-       r600_pipe_state_add_reg(rstate,
-                               R_028C6C_CB_COLOR0_VIEW + cb * 0x3C,
-                               0x00000000, NULL, 0);
+       if (!rscreen->use_surface) {
+               r600_pipe_state_add_reg(rstate,
+                                       R_028C6C_CB_COLOR0_VIEW + cb * 0x3C,
+                                       0x00000000, NULL, 0);
+       } else {
+               if (rtex->surface.level[level].mode < RADEON_SURF_MODE_1D) {
+                       r600_pipe_state_add_reg(rstate,
+                                               R_028C6C_CB_COLOR0_VIEW + cb * 0x3C,
+                                               0x00000000, NULL, 0);
+               } else {
+                       r600_pipe_state_add_reg(rstate,
+                                               R_028C6C_CB_COLOR0_VIEW + cb * 0x3C,
+                                               S_028C6C_SLICE_START(state->cbufs[cb]->u.tex.first_layer) |
+                                               S_028C6C_SLICE_MAX(state->cbufs[cb]->u.tex.last_layer),
+                                               NULL, 0);
+               }
+       }
        r600_pipe_state_add_reg(rstate,
                                R_028C74_CB_COLOR0_ATTRIB + cb * 0x3C,
-                               S_028C74_NON_DISP_TILING_ORDER(tile_type),
+                               color_attrib,
                                &rtex->resource, RADEON_USAGE_READWRITE);
 }
 
 static void evergreen_db(struct r600_context *rctx, struct r600_pipe_state *rstate,
                         const struct pipe_framebuffer_state *state)
 {
+       struct r600_screen *rscreen = rctx->screen;
        struct r600_resource_texture *rtex;
        struct r600_surface *surf;
-       unsigned level, first_layer, pitch, slice, format, array_mode;
        uint64_t offset;
+       unsigned level, first_layer, pitch, slice, format, array_mode;
+       unsigned macro_aspect, tile_split, bankh, bankw, z_info, nbanks;
 
        if (state->zsbuf == NULL)
                return;
@@ -1470,30 +1649,84 @@ static void evergreen_db(struct r600_context *rctx, struct r600_pipe_state *rsta
        surf = (struct r600_surface *)state->zsbuf;
        level = surf->base.u.tex.level;
        rtex = (struct r600_resource_texture*)surf->base.texture;
-
-       /* XXX remove this once tiling is properly supported */
-       array_mode = rtex->array_mode[level] ? rtex->array_mode[level] :
-                                              V_028C70_ARRAY_1D_TILED_THIN1;
-
        first_layer = surf->base.u.tex.first_layer;
-       offset = r600_texture_get_offset(rtex, level, first_layer);
-       pitch = rtex->pitch_in_blocks[level] / 8 - 1;
-       slice = rtex->pitch_in_blocks[level] * surf->aligned_height / 64 - 1;
        format = r600_translate_dbformat(rtex->real_format);
 
-       offset += r600_resource_va(rctx->context.screen, surf->base.texture);
+       offset = r600_resource_va(rctx->context.screen, surf->base.texture);
+       /* XXX remove this once tiling is properly supported */
+       if (!rscreen->use_surface) {
+               /* XXX remove this once tiling is properly supported */
+               array_mode = rtex->array_mode[level] ? rtex->array_mode[level] :
+                               V_028C70_ARRAY_1D_TILED_THIN1;
+
+               offset += r600_texture_get_offset(rtex, level, first_layer);
+               pitch = (rtex->pitch_in_blocks[level] / 8) - 1;
+               slice = ((rtex->pitch_in_blocks[level] * surf->aligned_height) / 64);
+               if (slice) {
+                       slice = slice - 1;
+               }
+               tile_split = 0;
+               macro_aspect = 0;
+               bankw = 0;
+               bankh = 0;
+       } else {
+               offset += rtex->surface.level[level].offset;
+               pitch = (rtex->surface.level[level].nblk_x / 8) - 1;
+               slice = (rtex->surface.level[level].nblk_x * rtex->surface.level[level].nblk_y) / 64;
+               if (slice) {
+                       slice = slice - 1;
+               }
+               switch (rtex->surface.level[level].mode) {
+               case RADEON_SURF_MODE_2D:
+                       array_mode = V_028C70_ARRAY_2D_TILED_THIN1;
+                       break;
+               case RADEON_SURF_MODE_1D:
+               case RADEON_SURF_MODE_LINEAR_ALIGNED:
+               case RADEON_SURF_MODE_LINEAR:
+               default:
+                       array_mode = V_028C70_ARRAY_1D_TILED_THIN1;
+                       break;
+               }
+               tile_split = rtex->surface.tile_split;
+               macro_aspect = rtex->surface.mtilea;
+               bankw = rtex->surface.bankw;
+               bankh = rtex->surface.bankh;
+               tile_split = eg_tile_split(tile_split);
+               macro_aspect = eg_macro_tile_aspect(macro_aspect);
+               bankw = eg_bank_wh(bankw);
+               bankh = eg_bank_wh(bankh);
+       }
+       nbanks = eg_num_banks(rscreen->tiling_info.num_banks);
        offset >>= 8;
 
+       z_info = S_028040_ARRAY_MODE(array_mode) |
+                S_028040_FORMAT(format) |
+                S_028040_TILE_SPLIT(tile_split)|
+                S_028040_NUM_BANKS(nbanks) |
+                S_028040_BANK_WIDTH(bankw) |
+                S_028040_BANK_HEIGHT(bankh) |
+                S_028040_MACRO_TILE_ASPECT(macro_aspect);
+
        r600_pipe_state_add_reg(rstate, R_028048_DB_Z_READ_BASE,
                                offset, &rtex->resource, RADEON_USAGE_READWRITE);
        r600_pipe_state_add_reg(rstate, R_028050_DB_Z_WRITE_BASE,
                                offset, &rtex->resource, RADEON_USAGE_READWRITE);
-       r600_pipe_state_add_reg(rstate, R_028008_DB_DEPTH_VIEW, 0x00000000, NULL, 0);
+       if (!rscreen->use_surface) {
+               r600_pipe_state_add_reg(rstate, R_028008_DB_DEPTH_VIEW,
+                                       0x00000000, NULL, 0);
+       } else {
+               r600_pipe_state_add_reg(rstate, R_028008_DB_DEPTH_VIEW,
+                                       S_028008_SLICE_START(state->zsbuf->u.tex.first_layer) |
+                                       S_028008_SLICE_MAX(state->zsbuf->u.tex.last_layer),
+                                       NULL, 0);
+       }
 
        if (rtex->stencil) {
                uint64_t stencil_offset =
                        r600_texture_get_offset(rtex->stencil, level, first_layer);
+               unsigned stile_split;
 
+               stile_split = eg_tile_split(rtex->stencil->surface.tile_split);
                stencil_offset += r600_resource_va(rctx->context.screen, (void*)rtex->stencil);
                stencil_offset >>= 8;
 
@@ -1502,14 +1735,41 @@ static void evergreen_db(struct r600_context *rctx, struct r600_pipe_state *rsta
                r600_pipe_state_add_reg(rstate, R_028054_DB_STENCIL_WRITE_BASE,
                                        stencil_offset, &rtex->stencil->resource, RADEON_USAGE_READWRITE);
                r600_pipe_state_add_reg(rstate, R_028044_DB_STENCIL_INFO,
-                                       1, &rtex->stencil->resource, RADEON_USAGE_READWRITE);
+                                       1 | S_028044_TILE_SPLIT(stile_split),
+                                       &rtex->stencil->resource, RADEON_USAGE_READWRITE);
        } else {
-               r600_pipe_state_add_reg(rstate, R_028044_DB_STENCIL_INFO,
-                                       0, NULL, RADEON_USAGE_READWRITE);
+               if (rscreen->use_surface && rtex->surface.flags & RADEON_SURF_SBUFFER) {
+                       uint64_t stencil_offset = rtex->surface.stencil_offset;
+                       unsigned stile_split = rtex->surface.stencil_tile_split;
+
+                       stile_split = eg_tile_split(stile_split);
+                       stencil_offset += r600_resource_va(rctx->context.screen, surf->base.texture);
+                       stencil_offset += rtex->surface.level[level].offset / 4;
+                       stencil_offset >>= 8;
+
+                       r600_pipe_state_add_reg(rstate, R_02804C_DB_STENCIL_READ_BASE,
+                                               stencil_offset, &rtex->resource,
+                                               RADEON_USAGE_READWRITE);
+                       r600_pipe_state_add_reg(rstate, R_028054_DB_STENCIL_WRITE_BASE,
+                                               stencil_offset, &rtex->resource,
+                                               RADEON_USAGE_READWRITE);
+                       r600_pipe_state_add_reg(rstate, R_028044_DB_STENCIL_INFO,
+                                               1 | S_028044_TILE_SPLIT(stile_split),
+                                               &rtex->resource,
+                                               RADEON_USAGE_READWRITE);
+               } else {
+                       r600_pipe_state_add_reg(rstate, R_02804C_DB_STENCIL_READ_BASE,
+                                               offset, &rtex->resource,
+                                               RADEON_USAGE_READWRITE);
+                       r600_pipe_state_add_reg(rstate, R_028054_DB_STENCIL_WRITE_BASE,
+                                               offset, &rtex->resource,
+                                               RADEON_USAGE_READWRITE);
+                       r600_pipe_state_add_reg(rstate, R_028044_DB_STENCIL_INFO,
+                                               0, NULL, RADEON_USAGE_READWRITE);
+               }
        }
 
-       r600_pipe_state_add_reg(rstate, R_028040_DB_Z_INFO,
-                               S_028040_ARRAY_MODE(array_mode) | S_028040_FORMAT(format),
+       r600_pipe_state_add_reg(rstate, R_028040_DB_Z_INFO, z_info,
                                &rtex->resource, RADEON_USAGE_READWRITE);
        r600_pipe_state_add_reg(rstate, R_028058_DB_DEPTH_SIZE,
                                S_028058_PITCH_TILE_MAX(pitch),
index 3345ebf93108ea799d76e737d6e8559f5495a91b..1d870760f619d71c706db3f31c4d786b08814552 100644 (file)
 #define   S_028C74_NON_DISP_TILING_ORDER(x)            (((x) & 0x1) << 4)
 #define   G_028C74_NON_DISP_TILING_ORDER(x)            (((x) >> 4) & 0x1)
 #define   C_028C74_NON_DISP_TILING_ORDER               0xFFFFFFEF
+#define   S_028C74_TILE_SPLIT(x)                       (((x) & 0xf) << 5)
+#define   S_028C74_NUM_BANKS(x)                        (((x) & 0x3) << 10)
+#define   S_028C74_BANK_WIDTH(x)                       (((x) & 0x3) << 13)
+#define   S_028C74_BANK_HEIGHT(x)                      (((x) & 0x3) << 16)
+#define   S_028C74_MACRO_TILE_ASPECT(x)                (((x) & 0x3) << 19)
 
 #define R_028C78_CB_COLOR0_DIM                         0x028C78
 #define   S_028C78_WIDTH_MAX(x)                        (((x) & 0xFFFF) << 0)
 #define   S_028040_ZRANGE_PRECISION(x)                 (((x) & 0x1) << 31)
 #define   G_028040_ZRANGE_PRECISION(x)                 (((x) >> 31) & 0x1)
 #define   C_028040_ZRANGE_PRECISION                    0x7FFFFFFF
+#define   S_028040_TILE_SPLIT(x)                       (((x) & 0x7) << 8)
+#define   S_028040_NUM_BANKS(x)                        (((x) & 0x3) << 12)
+#define   S_028040_BANK_WIDTH(x)                       (((x) & 0x3) << 16)
+#define   S_028040_BANK_HEIGHT(x)                      (((x) & 0x3) << 20)
+#define   S_028040_MACRO_TILE_ASPECT(x)                (((x) & 0x3) << 24)
 
 #define R_028044_DB_STENCIL_INFO                     0x028044
 #define   S_028044_FORMAT(x)                           (((x) & 0x1) << 0)
 #define   G_028044_FORMAT(x)                           (((x) >> 0) & 0x1)
 #define   C_028044_FORMAT                              0xFFFFFFFE
+#define   S_028044_TILE_SPLIT(x)                       (((x) & 0x7) << 8)
 
 #define R_028058_DB_DEPTH_SIZE                       0x028058
 #define   S_028058_PITCH_TILE_MAX(x)                   (((x) & 0x7FF) << 0)
 #define   S_030018_INTERLACED(x)                       (((x) & 0x1) << 6)
 #define   G_030018_INTERLACED(x)                       (((x) >> 6) & 0x1)
 #define   C_030018_INTERLACED                          0xFFFFFFBF
+#define   S_030018_TILE_SPLIT(x)                       (((x) & 0x7) << 29)
 #define R_03001C_SQ_TEX_RESOURCE_WORD7_0             0x03001C
+#define   S_03001C_MACRO_TILE_ASPECT(x)                (((x) & 0x3) << 6)
+#define   S_03001C_BANK_WIDTH(x)                       (((x) & 0x3) << 8)
+#define   S_03001C_BANK_HEIGHT(x)                      (((x) & 0x3) << 10)
+#define   S_03001C_NUM_BANKS(x)                        (((x) & 0x3) << 16)
 #define   S_03001C_TYPE(x)                             (((x) & 0x3) << 30)
 #define   G_03001C_TYPE(x)                             (((x) >> 30) & 0x3)
 #define   C_03001C_TYPE                                0x3FFFFFFF
 #define R_028C3C_PA_SC_AA_MASK                       0x00028C3C
 #define R_028C60_CB_COLOR0_BASE                      0x00028C60
 #define R_028C6C_CB_COLOR0_VIEW                      0x00028C6C
+#define   S_028C6C_SLICE_START(x)                      (((x) & 0x7FF) << 0)
+#define   G_028C6C_SLICE_START(x)                      (((x) >> 0) & 0x7FF)
+#define   C_028C6C_SLICE_START                         0xFFFFF800
+#define   S_028C6C_SLICE_MAX(x)                        (((x) & 0x7FF) << 13)
+#define   G_028C6C_SLICE_MAX(x)                        (((x) >> 13) & 0x7FF)
+#define   C_028C6C_SLICE_MAX                           0xFF001FFF
 #define R_028C9C_CB_COLOR1_BASE                      0x00028C9C
 #define R_028CA0_CB_COLOR1_PITCH                     0x00028CA0
 #define R_028CA4_CB_COLOR1_SLICE                     0x00028CA4
index 93df1a2911de817ff2e6d9ec52d1c2934dd81aa2..ff720c9a028504665407c919100a361927c51f16 100644 (file)
@@ -202,7 +202,7 @@ static void r600_clear(struct pipe_context *ctx, unsigned buffers,
 {
        struct r600_context *rctx = (struct r600_context *)ctx;
        struct pipe_framebuffer_state *fb = &rctx->framebuffer;
-       
+
        r600_blitter_begin(ctx, R600_CLEAR);
        util_blitter_clear(rctx->blitter, fb->width, fb->height,
                           fb->nr_cbufs, buffers, fb->nr_cbufs ? fb->cbufs[0]->format : PIPE_FORMAT_NONE,
@@ -263,6 +263,10 @@ struct texture_orig_info {
        unsigned format;
        unsigned width0;
        unsigned height0;
+       unsigned npix_x;
+       unsigned npix_y;
+       unsigned npix0_x;
+       unsigned npix0_y;
 };
 
 static void r600_compressed_to_blittable(struct pipe_resource *tex,
@@ -270,6 +274,7 @@ static void r600_compressed_to_blittable(struct pipe_resource *tex,
                                   struct texture_orig_info *orig)
 {
        struct r600_resource_texture *rtex = (struct r600_resource_texture*)tex;
+       struct r600_screen *rscreen = (struct r600_screen *)tex->screen;
        unsigned pixsize = util_format_get_blocksize(rtex->real_format);
        int new_format;
        int new_height, new_width;
@@ -277,6 +282,10 @@ static void r600_compressed_to_blittable(struct pipe_resource *tex,
        orig->format = tex->format;
        orig->width0 = tex->width0;
        orig->height0 = tex->height0;
+       orig->npix0_x = rtex->surface.level[0].npix_x;
+       orig->npix0_y = rtex->surface.level[0].npix_y;
+       orig->npix_x = rtex->surface.level[level].npix_x;
+       orig->npix_y = rtex->surface.level[level].npix_y;
 
        if (pixsize == 8)
                new_format = PIPE_FORMAT_R16G16B16A16_UINT; /* 64-bit block */
@@ -289,14 +298,26 @@ static void r600_compressed_to_blittable(struct pipe_resource *tex,
        tex->width0 = new_width;
        tex->height0 = new_height;
        tex->format = new_format;
+       rtex->surface.level[0].npix_x = util_format_get_nblocksx(orig->format, orig->npix0_x);
+       rtex->surface.level[0].npix_y = util_format_get_nblocksy(orig->format, orig->npix0_y);
+       rtex->surface.level[level].npix_x = util_format_get_nblocksx(orig->format, orig->npix_x);
+       rtex->surface.level[level].npix_y = util_format_get_nblocksy(orig->format, orig->npix_y);
 }
 
 static void r600_reset_blittable_to_compressed(struct pipe_resource *tex,
+                                              unsigned level,
                                               struct texture_orig_info *orig)
 {
+       struct r600_resource_texture *rtex = (struct r600_resource_texture*)tex;
+       struct r600_screen *rscreen = (struct r600_screen *)tex->screen;
+
        tex->format = orig->format;
        tex->width0 = orig->width0;
        tex->height0 = orig->height0;
+       rtex->surface.level[0].npix_x = orig->npix0_x;
+       rtex->surface.level[0].npix_y = orig->npix0_y;
+       rtex->surface.level[level].npix_x = orig->npix_x;
+       rtex->surface.level[level].npix_y = orig->npix_y;
 }
 
 static void r600_resource_copy_region(struct pipe_context *ctx,
@@ -352,10 +373,10 @@ static void r600_resource_copy_region(struct pipe_context *ctx,
                            src, src_level, psbox);
 
        if (restore_orig[0])
-               r600_reset_blittable_to_compressed(src, &orig_info[0]);
+               r600_reset_blittable_to_compressed(src, src_level, &orig_info[0]);
 
        if (restore_orig[1])
-               r600_reset_blittable_to_compressed(dst, &orig_info[1]);
+               r600_reset_blittable_to_compressed(dst, dst_level, &orig_info[1]);
 }
 
 void r600_init_blit_functions(struct r600_context *rctx)
index ea15530e927f663e9fdf4544a729b88f1177be52..ab51b3e4c433170be191eadda9b2d8abc7630f29 100644 (file)
@@ -1439,6 +1439,9 @@ void r600_context_flush(struct r600_context *ctx, unsigned flags)
        cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE, 0, 0);
        cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_PS_PARTIAL_FLUSH) | EVENT_INDEX(4);
 
+       /* force to keep tiling flags */
+       flags |= RADEON_FLUSH_KEEP_TILING_FLAGS;
+
        /* Flush the CS. */
        ctx->ws->cs_flush(ctx->cs, flags);
 
index f11539a9875a240c5b26a5c406ba82515312eecb..f1306176b9413261c772e8b9d40789fb5ba66d81 100644 (file)
@@ -117,6 +117,7 @@ struct r600_screen {
        struct r600_pipe_fences         fences;
 
        unsigned                        num_contexts;
+       unsigned                        use_surface;
 
        /* for thread-safe write accessing to num_contexts */
        pipe_mutex                      mutex_num_contexts;
index 1a32c056dd47bc18bf53754a1ec17f8772412939..8b90b12e9575a52324f808b6798b8c93f55e542e 100644 (file)
@@ -60,6 +60,7 @@ struct r600_resource_texture {
        struct r600_resource_texture    *stencil; /* Stencil is in a separate buffer on Evergreen. */
        struct r600_resource_texture    *flushed_depth_texture;
        boolean                         is_flushing_texture;
+       struct radeon_surface           surface;
 };
 
 #define R600_TEX_IS_TILED(tex, level) ((tex)->array_mode[level] != V_038000_ARRAY_LINEAR_GENERAL && (tex)->array_mode[level] != V_038000_ARRAY_LINEAR_ALIGNED)
index e6362f935362943bb08c046209873474aed01319..0d83fa608fbb66eb47c53cbd6114d67fe1d75f2e 100644 (file)
@@ -1081,6 +1081,7 @@ static struct pipe_sampler_view *r600_create_sampler_view(struct pipe_context *c
                                                        struct pipe_resource *texture,
                                                        const struct pipe_sampler_view *state)
 {
+       struct r600_screen *rscreen = (struct r600_screen*)ctx->screen;
        struct r600_pipe_sampler_view *view = CALLOC_STRUCT(r600_pipe_sampler_view);
        struct r600_pipe_resource_state *rstate;
        struct r600_resource_texture *tmp = (struct r600_resource_texture*)texture;
@@ -1122,48 +1123,107 @@ static struct pipe_sampler_view *r600_create_sampler_view(struct pipe_context *c
 
        offset_level = state->u.tex.first_level;
        last_level = state->u.tex.last_level - offset_level;
-       width = u_minify(texture->width0, offset_level);
-       height = u_minify(texture->height0, offset_level);
-       depth = u_minify(texture->depth0, offset_level);
-
-       pitch = align(tmp->pitch_in_blocks[offset_level] *
-                     util_format_get_blockwidth(state->format), 8);
-       array_mode = tmp->array_mode[offset_level];
-       tile_type = tmp->tile_type;
-
-       if (texture->target == PIPE_TEXTURE_1D_ARRAY) {
-               height = 1;
-               depth = texture->array_size;
-       } else if (texture->target == PIPE_TEXTURE_2D_ARRAY) {
-               depth = texture->array_size;
-       }
-
-       rstate->bo[0] = &tmp->resource;
-       rstate->bo[1] = &tmp->resource;
-       rstate->bo_usage[0] = RADEON_USAGE_READ;
-       rstate->bo_usage[1] = RADEON_USAGE_READ;
-
-       rstate->val[0] = (S_038000_DIM(r600_tex_dim(texture->target)) |
-                         S_038000_TILE_MODE(array_mode) |
-                         S_038000_TILE_TYPE(tile_type) |
-                         S_038000_PITCH((pitch / 8) - 1) |
-                         S_038000_TEX_WIDTH(width - 1));
-       rstate->val[1] = (S_038004_TEX_HEIGHT(height - 1) |
-                         S_038004_TEX_DEPTH(depth - 1) |
-                         S_038004_DATA_FORMAT(format));
-       rstate->val[2] = tmp->offset[offset_level] >> 8;
-       rstate->val[3] = tmp->offset[offset_level+1] >> 8;
-       rstate->val[4] = (word4 |
-                         S_038010_SRF_MODE_ALL(V_038010_SRF_MODE_ZERO_CLAMP_MINUS_ONE) |
-                         S_038010_REQUEST_SIZE(1) |
-                         S_038010_ENDIAN_SWAP(endian) |
-                         S_038010_BASE_LEVEL(0));
-       rstate->val[5] = (S_038014_LAST_LEVEL(last_level) |
-                         S_038014_BASE_ARRAY(state->u.tex.first_layer) |
-                         S_038014_LAST_ARRAY(state->u.tex.last_layer));
-       rstate->val[6] = (S_038018_TYPE(V_038010_SQ_TEX_VTX_VALID_TEXTURE) |
-                         S_038018_MAX_ANISO(4 /* max 16 samples */));
+       if (!rscreen->use_surface) {
+               width = u_minify(texture->width0, offset_level);
+               height = u_minify(texture->height0, offset_level);
+               depth = u_minify(texture->depth0, offset_level);
+
+               pitch = align(tmp->pitch_in_blocks[offset_level] *
+                               util_format_get_blockwidth(state->format), 8);
+               array_mode = tmp->array_mode[offset_level];
+               tile_type = tmp->tile_type;
+
+               if (texture->target == PIPE_TEXTURE_1D_ARRAY) {
+                       height = 1;
+                       depth = texture->array_size;
+               } else if (texture->target == PIPE_TEXTURE_2D_ARRAY) {
+                       depth = texture->array_size;
+               }
 
+               rstate->bo[0] = &tmp->resource;
+               rstate->bo[1] = &tmp->resource;
+               rstate->bo_usage[0] = RADEON_USAGE_READ;
+               rstate->bo_usage[1] = RADEON_USAGE_READ;
+
+               rstate->val[0] = (S_038000_DIM(r600_tex_dim(texture->target)) |
+                               S_038000_TILE_MODE(array_mode) |
+                               S_038000_TILE_TYPE(tile_type) |
+                               S_038000_PITCH((pitch / 8) - 1) |
+                               S_038000_TEX_WIDTH(width - 1));
+               rstate->val[1] = (S_038004_TEX_HEIGHT(height - 1) |
+                               S_038004_TEX_DEPTH(depth - 1) |
+                               S_038004_DATA_FORMAT(format));
+               rstate->val[2] = tmp->offset[offset_level] >> 8;
+               rstate->val[3] = tmp->offset[offset_level+1] >> 8;
+               rstate->val[4] = (word4 |
+                               S_038010_SRF_MODE_ALL(V_038010_SRF_MODE_ZERO_CLAMP_MINUS_ONE) |
+                               S_038010_REQUEST_SIZE(1) |
+                               S_038010_ENDIAN_SWAP(endian) |
+                               S_038010_BASE_LEVEL(0));
+               rstate->val[5] = (S_038014_LAST_LEVEL(last_level) |
+                               S_038014_BASE_ARRAY(state->u.tex.first_layer) |
+                               S_038014_LAST_ARRAY(state->u.tex.last_layer));
+               rstate->val[6] = (S_038018_TYPE(V_038010_SQ_TEX_VTX_VALID_TEXTURE) |
+                               S_038018_MAX_ANISO(4 /* max 16 samples */));
+       } else {
+               width = tmp->surface.level[offset_level].npix_x;
+               height = tmp->surface.level[offset_level].npix_y;
+               depth = tmp->surface.level[offset_level].npix_z;
+               pitch = tmp->surface.level[offset_level].nblk_x * util_format_get_blockwidth(state->format);
+               tile_type = tmp->tile_type;
+
+               if (texture->target == PIPE_TEXTURE_1D_ARRAY) {
+                       height = 1;
+                       depth = texture->array_size;
+               } else if (texture->target == PIPE_TEXTURE_2D_ARRAY) {
+                       depth = texture->array_size;
+               }
+               switch (tmp->surface.level[offset_level].mode) {
+               case RADEON_SURF_MODE_LINEAR_ALIGNED:
+                       array_mode = V_038000_ARRAY_LINEAR_ALIGNED;
+                       break;
+               case RADEON_SURF_MODE_1D:
+                       array_mode = V_038000_ARRAY_1D_TILED_THIN1;
+                       break;
+               case RADEON_SURF_MODE_2D:
+                       array_mode = V_038000_ARRAY_2D_TILED_THIN1;
+                       break;
+               case RADEON_SURF_MODE_LINEAR:
+               default:
+                       array_mode = V_038000_ARRAY_LINEAR_GENERAL;
+                       break;
+               }
+
+               rstate->bo[0] = &tmp->resource;
+               rstate->bo[1] = &tmp->resource;
+               rstate->bo_usage[0] = RADEON_USAGE_READ;
+               rstate->bo_usage[1] = RADEON_USAGE_READ;
+
+               rstate->val[0] = (S_038000_DIM(r600_tex_dim(texture->target)) |
+                               S_038000_TILE_MODE(array_mode) |
+                               S_038000_TILE_TYPE(tile_type) |
+                               S_038000_PITCH((pitch / 8) - 1) |
+                               S_038000_TEX_WIDTH(width - 1));
+               rstate->val[1] = (S_038004_TEX_HEIGHT(height - 1) |
+                               S_038004_TEX_DEPTH(depth - 1) |
+                               S_038004_DATA_FORMAT(format));
+               rstate->val[2] = tmp->surface.level[offset_level].offset >> 8;
+               if (offset_level >= tmp->surface.last_level) {
+                       rstate->val[3] = tmp->surface.level[offset_level].offset >> 8;
+               } else {
+                       rstate->val[3] = tmp->surface.level[offset_level + 1].offset >> 8;
+               }
+               rstate->val[4] = (word4 |
+                               S_038010_SRF_MODE_ALL(V_038010_SRF_MODE_ZERO_CLAMP_MINUS_ONE) |
+                               S_038010_REQUEST_SIZE(1) |
+                               S_038010_ENDIAN_SWAP(endian) |
+                               S_038010_BASE_LEVEL(0));
+               rstate->val[5] = (S_038014_LAST_LEVEL(last_level) |
+                               S_038014_BASE_ARRAY(state->u.tex.first_layer) |
+                               S_038014_LAST_ARRAY(state->u.tex.last_layer));
+               rstate->val[6] = (S_038018_TYPE(V_038010_SQ_TEX_VTX_VALID_TEXTURE) |
+                               S_038018_MAX_ANISO(4 /* max 16 samples */));
+       }
        return &view->base;
 }
 
@@ -1433,6 +1493,7 @@ static void r600_set_viewport_state(struct pipe_context *ctx,
 static void r600_cb(struct r600_context *rctx, struct r600_pipe_state *rstate,
                        const struct pipe_framebuffer_state *state, int cb)
 {
+       struct r600_screen *rscreen = rctx->screen;
        struct r600_resource_texture *rtex;
        struct r600_surface *surf;
        unsigned level = state->cbufs[cb]->u.tex.level;
@@ -1451,15 +1512,47 @@ static void r600_cb(struct r600_context *rctx, struct r600_pipe_state *rstate,
                rctx->have_depth_fb = TRUE;
 
        if (rtex->depth && !rtex->is_flushing_texture) {
-               r600_texture_depth_flush(&rctx->context, state->cbufs[cb]->texture, TRUE);
                rtex = rtex->flushed_depth_texture;
        }
 
        /* XXX quite sure for dx10+ hw don't need any offset hacks */
-       offset = r600_texture_get_offset(rtex,
-                                        level, state->cbufs[cb]->u.tex.first_layer);
-       pitch = rtex->pitch_in_blocks[level] / 8 - 1;
-       slice = rtex->pitch_in_blocks[level] * surf->aligned_height / 64 - 1;
+       if (!rscreen->use_surface) {
+               offset = r600_texture_get_offset(rtex,
+                                                level, state->cbufs[cb]->u.tex.first_layer);
+               pitch = rtex->pitch_in_blocks[level] / 8 - 1;
+               slice = rtex->pitch_in_blocks[level] * surf->aligned_height / 64;
+               if (slice) {
+                       slice = slice - 1;
+               }
+               color_info = S_0280A0_ARRAY_MODE(rtex->array_mode[level]);
+       } else {
+               offset = rtex->surface.level[level].offset;
+               if (rtex->surface.level[level].mode < RADEON_SURF_MODE_1D) {
+                       offset += rtex->surface.level[level].slice_size *
+                                 state->cbufs[cb]->u.tex.first_layer;
+               }
+               pitch = rtex->surface.level[level].nblk_x / 8 - 1;
+               slice = (rtex->surface.level[level].nblk_x * rtex->surface.level[level].nblk_y) / 64;
+               if (slice) {
+                       slice = slice - 1;
+               }
+               color_info = 0;
+               switch (rtex->surface.level[level].mode) {
+               case RADEON_SURF_MODE_LINEAR_ALIGNED:
+                       color_info = S_0280A0_ARRAY_MODE(V_038000_ARRAY_LINEAR_ALIGNED);
+                       break;
+               case RADEON_SURF_MODE_1D:
+                       color_info = S_0280A0_ARRAY_MODE(V_038000_ARRAY_1D_TILED_THIN1);
+                       break;
+               case RADEON_SURF_MODE_2D:
+                       color_info = S_0280A0_ARRAY_MODE(V_038000_ARRAY_2D_TILED_THIN1);
+                       break;
+               case RADEON_SURF_MODE_LINEAR:
+               default:
+                       color_info = S_0280A0_ARRAY_MODE(V_038000_ARRAY_LINEAR_GENERAL);
+                       break;
+               }
+       }
        desc = util_format_description(surf->base.format);
 
        for (i = 0; i < 4; i++) {
@@ -1500,9 +1593,8 @@ static void r600_cb(struct r600_context *rctx, struct r600_pipe_state *rstate,
                blend_bypass = 1;
        }
 
-       color_info = S_0280A0_FORMAT(format) |
+       color_info |= S_0280A0_FORMAT(format) |
                S_0280A0_COMP_SWAP(swap) |
-               S_0280A0_ARRAY_MODE(rtex->array_mode[level]) |
                S_0280A0_BLEND_BYPASS(blend_bypass) |
                S_0280A0_BLEND_CLAMP(blend_clamp) |
                S_0280A0_NUMBER_TYPE(ntype) |
@@ -1550,9 +1642,23 @@ static void r600_cb(struct r600_context *rctx, struct r600_pipe_state *rstate,
                                S_028060_PITCH_TILE_MAX(pitch) |
                                S_028060_SLICE_TILE_MAX(slice),
                                NULL, 0);
-       r600_pipe_state_add_reg(rstate,
-                               R_028080_CB_COLOR0_VIEW + cb * 4,
-                               0x00000000, NULL, 0);
+       if (!rscreen->use_surface) {
+               r600_pipe_state_add_reg(rstate,
+                                       R_028080_CB_COLOR0_VIEW + cb * 4,
+                                       0x00000000, NULL, 0);
+       } else {
+               if (rtex->surface.level[level].mode < RADEON_SURF_MODE_1D) {
+                       r600_pipe_state_add_reg(rstate,
+                                               R_028080_CB_COLOR0_VIEW + cb * 4,
+                                               0x00000000, NULL, 0);
+               } else {
+                       r600_pipe_state_add_reg(rstate,
+                                               R_028080_CB_COLOR0_VIEW + cb * 4,
+                                               S_028080_SLICE_START(state->cbufs[cb]->u.tex.first_layer) |
+                                               S_028080_SLICE_MAX(state->cbufs[cb]->u.tex.last_layer),
+                                               NULL, 0);
+               }
+       }
        r600_pipe_state_add_reg(rstate,
                                R_0280E0_CB_COLOR0_FRAG + cb * 4,
                                0, &rtex->resource, RADEON_USAGE_READWRITE);
@@ -1567,6 +1673,7 @@ static void r600_cb(struct r600_context *rctx, struct r600_pipe_state *rstate,
 static void r600_db(struct r600_context *rctx, struct r600_pipe_state *rstate,
                        const struct pipe_framebuffer_state *state)
 {
+       struct r600_screen *rscreen = rctx->screen;
        struct r600_resource_texture *rtex;
        struct r600_surface *surf;
        unsigned level, pitch, slice, format, offset, array_mode;
@@ -1579,15 +1686,39 @@ static void r600_db(struct r600_context *rctx, struct r600_pipe_state *rstate,
        surf = (struct r600_surface *)state->zsbuf;
        rtex = (struct r600_resource_texture*)state->zsbuf->texture;
 
-       /* XXX remove this once tiling is properly supported */
-       array_mode = rtex->array_mode[level] ? rtex->array_mode[level] :
-                                              V_0280A0_ARRAY_1D_TILED_THIN1;
+       if (!rscreen->use_surface) {
+               /* XXX remove this once tiling is properly supported */
+               array_mode = rtex->array_mode[level] ? rtex->array_mode[level] :
+                       V_0280A0_ARRAY_1D_TILED_THIN1;
+
+               /* XXX quite sure for dx10+ hw don't need any offset hacks */
+               offset = r600_texture_get_offset((struct r600_resource_texture *)state->zsbuf->texture,
+                               level, state->zsbuf->u.tex.first_layer);
+               pitch = rtex->pitch_in_blocks[level] / 8 - 1;
+               slice = rtex->pitch_in_blocks[level] * surf->aligned_height / 64;
+               if (slice) {
+                       slice = slice - 1;
+               }
+       } else {
+               offset = rtex->surface.level[level].offset;
+               pitch = rtex->surface.level[level].nblk_x / 8 - 1;
+               slice = (rtex->surface.level[level].nblk_x * rtex->surface.level[level].nblk_y) / 64;
+               if (slice) {
+                       slice = slice - 1;
+               }
+               switch (rtex->surface.level[level].mode) {
+               case RADEON_SURF_MODE_2D:
+                       array_mode = V_0280A0_ARRAY_2D_TILED_THIN1;
+                       break;
+               case RADEON_SURF_MODE_1D:
+               case RADEON_SURF_MODE_LINEAR_ALIGNED:
+               case RADEON_SURF_MODE_LINEAR:
+               default:
+                       array_mode = V_0280A0_ARRAY_1D_TILED_THIN1;
+                       break;
+               }
+       }
 
-       /* XXX quite sure for dx10+ hw don't need any offset hacks */
-       offset = r600_texture_get_offset((struct r600_resource_texture *)state->zsbuf->texture,
-                                        level, state->zsbuf->u.tex.first_layer);
-       pitch = rtex->pitch_in_blocks[level] / 8 - 1;
-       slice = rtex->pitch_in_blocks[level] * surf->aligned_height / 64 - 1;
        format = r600_translate_dbformat(state->zsbuf->texture->format);
 
        r600_pipe_state_add_reg(rstate, R_02800C_DB_DEPTH_BASE,
@@ -1595,7 +1726,14 @@ static void r600_db(struct r600_context *rctx, struct r600_pipe_state *rstate,
        r600_pipe_state_add_reg(rstate, R_028000_DB_DEPTH_SIZE,
                                S_028000_PITCH_TILE_MAX(pitch) | S_028000_SLICE_TILE_MAX(slice),
                                NULL, 0);
-       r600_pipe_state_add_reg(rstate, R_028004_DB_DEPTH_VIEW, 0x00000000, NULL, 0);
+       if (!rscreen->use_surface) {
+               r600_pipe_state_add_reg(rstate, R_028004_DB_DEPTH_VIEW, 0x00000000, NULL, 0);
+       } else {
+               r600_pipe_state_add_reg(rstate, R_028004_DB_DEPTH_VIEW,
+                                       S_028004_SLICE_START(state->zsbuf->u.tex.first_layer) |
+                                       S_028004_SLICE_MAX(state->zsbuf->u.tex.last_layer),
+                                       NULL, 0);
+       }
        r600_pipe_state_add_reg(rstate, R_028010_DB_DEPTH_INFO,
                                S_028010_ARRAY_MODE(array_mode) | S_028010_FORMAT(format),
                                &rtex->resource, RADEON_USAGE_READWRITE);
index 47b440d70274db871e013416729dd3300025d7dc..4e2e600acc0bb1f76c88ce8da2ee014cad8c39b4 100644 (file)
@@ -241,6 +241,131 @@ static void r600_texture_set_array_mode(struct pipe_screen *screen,
        }
 }
 
+static int r600_init_surface(struct radeon_surface *surface,
+                            const struct pipe_resource *ptex,
+                            unsigned array_mode)
+{
+       surface->npix_x = ptex->width0;
+       surface->npix_y = ptex->height0;
+       surface->npix_z = ptex->depth0;
+       surface->blk_w = util_format_get_blockwidth(ptex->format);
+       surface->blk_h = util_format_get_blockheight(ptex->format);
+       surface->blk_d = 1;
+       surface->array_size = 1;
+       surface->last_level = ptex->last_level;
+       surface->bpe = util_format_get_blocksize(ptex->format);
+       /* align byte per element on dword */
+       if (surface->bpe == 3) {
+               surface->bpe = 4;
+       }
+       surface->nsamples = 1;
+       surface->flags = 0;
+       switch (array_mode) {
+       case V_038000_ARRAY_1D_TILED_THIN1:
+               surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
+               break;
+       case V_038000_ARRAY_2D_TILED_THIN1:
+               surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
+               break;
+       case V_038000_ARRAY_LINEAR_ALIGNED:
+               surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR_ALIGNED, MODE);
+               break;
+       case V_038000_ARRAY_LINEAR_GENERAL:
+       default:
+               surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR, MODE);
+               break;
+       }
+       switch (ptex->target) {
+       case PIPE_TEXTURE_1D:
+               surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D, TYPE);
+               break;
+       case PIPE_TEXTURE_RECT:
+       case PIPE_TEXTURE_2D:
+               surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE);
+               break;
+       case PIPE_TEXTURE_3D:
+               surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_3D, TYPE);
+               break;
+       case PIPE_TEXTURE_1D_ARRAY:
+               surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D_ARRAY, TYPE);
+               surface->array_size = ptex->array_size;
+               break;
+       case PIPE_TEXTURE_2D_ARRAY:
+               surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D_ARRAY, TYPE);
+               surface->array_size = ptex->array_size;
+               break;
+       case PIPE_TEXTURE_CUBE:
+               surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_CUBEMAP, TYPE);
+               break;
+       case PIPE_BUFFER:
+       default:
+               return -EINVAL;
+       }
+       if (ptex->bind & PIPE_BIND_SCANOUT) {
+               surface->flags |= RADEON_SURF_SCANOUT;
+       }
+       if (util_format_is_depth_and_stencil(ptex->format)) {
+               surface->flags |= RADEON_SURF_ZBUFFER;
+               surface->flags |= RADEON_SURF_SBUFFER;
+       }
+
+       return 0;
+}
+
+static int r600_setup_surface(struct pipe_screen *screen,
+                             struct r600_resource_texture *rtex,
+                             unsigned array_mode,
+                             unsigned pitch_in_bytes_override)
+{
+       struct pipe_resource *ptex = &rtex->resource.b.b.b;
+       struct r600_screen *rscreen = (struct r600_screen*)screen;
+       unsigned i;
+       int r;
+
+       if (util_format_is_depth_or_stencil(rtex->real_format)) {
+               rtex->surface.flags |= RADEON_SURF_ZBUFFER;
+               rtex->surface.flags |= RADEON_SURF_SBUFFER;
+       }
+
+       r = rscreen->ws->surface_init(rscreen->ws, &rtex->surface);
+       if (r) {
+               return r;
+       }
+       rtex->size = rtex->surface.bo_size;
+       if (pitch_in_bytes_override && pitch_in_bytes_override != rtex->surface.level[0].pitch_bytes) {
+               /* old ddx on evergreen over estimate alignment for 1d, only 1 level
+                * for those
+                */
+               rtex->surface.level[0].nblk_x = pitch_in_bytes_override / rtex->surface.bpe;
+               rtex->surface.level[0].pitch_bytes = pitch_in_bytes_override;
+               rtex->surface.level[0].slice_size = pitch_in_bytes_override * rtex->surface.level[0].nblk_y;
+               if (rtex->surface.flags & RADEON_SURF_SBUFFER) {
+                       rtex->surface.stencil_offset = rtex->surface.level[0].slice_size;
+               }
+       }
+       for (i = 0; i <= ptex->last_level; i++) {
+               rtex->offset[i] = rtex->surface.level[i].offset;
+               rtex->layer_size[i] = rtex->surface.level[i].slice_size;
+               rtex->pitch_in_bytes[i] = rtex->surface.level[i].pitch_bytes;
+               switch (rtex->surface.level[i].mode) {
+               case RADEON_SURF_MODE_LINEAR_ALIGNED:
+                       rtex->array_mode[i] = V_038000_ARRAY_LINEAR_ALIGNED;
+                       break;
+               case RADEON_SURF_MODE_1D:
+                       rtex->array_mode[i] = V_038000_ARRAY_1D_TILED_THIN1;
+                       break;
+               case RADEON_SURF_MODE_2D:
+                       rtex->array_mode[i] = V_038000_ARRAY_2D_TILED_THIN1;
+                       break;
+               default:
+               case RADEON_SURF_MODE_LINEAR:
+                       rtex->array_mode[i] = 0;
+                       break;
+               }
+       }
+       return 0;
+}
+
 static void r600_setup_miptree(struct pipe_screen *screen,
                               struct r600_resource_texture *rtex,
                               unsigned array_mode)
@@ -304,7 +429,7 @@ static boolean permit_hardware_blit(struct pipe_screen *screen,
        /* hackaround for S3TC */
        if (util_format_is_compressed(res->format))
                return TRUE;
-           
+
        if (!screen->is_format_supported(screen,
                                res->format,
                                res->target,
@@ -369,6 +494,8 @@ static const struct u_resource_vtbl r600_texture_vtbl =
        u_default_transfer_inline_write /* transfer_inline_write */
 };
 
+DEBUG_GET_ONCE_BOOL_OPTION(use_surface, "R600_SURF", TRUE);
+
 static struct r600_resource_texture *
 r600_texture_create_object(struct pipe_screen *screen,
                           const struct pipe_resource *base,
@@ -376,11 +503,20 @@ r600_texture_create_object(struct pipe_screen *screen,
                           unsigned pitch_in_bytes_override,
                           unsigned max_buffer_size,
                           struct pb_buffer *buf,
-                          boolean alloc_bo)
+                          boolean alloc_bo,
+                          struct radeon_surface *surface)
 {
        struct r600_resource_texture *rtex;
        struct r600_resource *resource;
        struct r600_screen *rscreen = (struct r600_screen*)screen;
+       int r;
+
+       /* FIXME ugly temporary hack to allow to switch btw current code
+        * and common surface allocator code
+        */
+       if (debug_get_option_use_surface()) {
+               rscreen->use_surface = 1;
+       }
 
        rtex = CALLOC_STRUCT(r600_resource_texture);
        if (rtex == NULL)
@@ -397,7 +533,8 @@ r600_texture_create_object(struct pipe_screen *screen,
        /* We must split depth and stencil into two separate buffers on Evergreen. */
        if (!(base->flags & R600_RESOURCE_FLAG_TRANSFER) &&
            ((struct r600_screen*)screen)->chip_class >= EVERGREEN &&
-           util_format_is_depth_and_stencil(base->format)) {
+           util_format_is_depth_and_stencil(base->format) &&
+           !rscreen->use_surface) {
                struct pipe_resource stencil;
                unsigned stencil_pitch_override = 0;
 
@@ -429,7 +566,7 @@ r600_texture_create_object(struct pipe_screen *screen,
                stencil.format = PIPE_FORMAT_S8_UINT;
                rtex->stencil = r600_texture_create_object(screen, &stencil, array_mode,
                                                           stencil_pitch_override,
-                                                          max_buffer_size, NULL, FALSE);
+                                                          max_buffer_size, NULL, FALSE, surface);
                if (!rtex->stencil) {
                        FREE(rtex);
                        return NULL;
@@ -442,6 +579,14 @@ r600_texture_create_object(struct pipe_screen *screen,
                rtex->depth = 1;
 
        r600_setup_miptree(screen, rtex, array_mode);
+       if (rscreen->use_surface) {
+               rtex->surface = *surface;
+               r = r600_setup_surface(screen, rtex, array_mode, pitch_in_bytes_override);
+               if (r) {
+                       FREE(rtex);
+                       return NULL;
+               }
+       }
 
        /* If we initialized separate stencil for Evergreen. place it after depth. */
        if (rtex->stencil) {
@@ -461,6 +606,12 @@ r600_texture_create_object(struct pipe_screen *screen,
                struct pipe_resource *ptex = &rtex->resource.b.b.b;
                unsigned base_align = r600_get_base_alignment(screen, ptex->format, array_mode);
 
+               if (rscreen->use_surface) {
+                       base_align = rtex->surface.bo_alignment;
+               } else if (util_format_is_depth_or_stencil(rtex->real_format)) {
+                       /* ugly work around depth buffer need stencil room at end of bo */
+                       rtex->size += ptex->width0 * ptex->height0;
+               }
                if (!r600_init_resource(rscreen, resource, rtex->size, base_align, base->bind, base->usage)) {
                        pipe_resource_reference((struct pipe_resource**)&rtex->stencil, NULL);
                        FREE(rtex);
@@ -480,28 +631,37 @@ r600_texture_create_object(struct pipe_screen *screen,
        return rtex;
 }
 
-DEBUG_GET_ONCE_BOOL_OPTION(tiling_enabled, "R600_TILING", FALSE);
+DEBUG_GET_ONCE_BOOL_OPTION(tiling_enabled, "R600_TILING", TRUE);
 
 struct pipe_resource *r600_texture_create(struct pipe_screen *screen,
                                                const struct pipe_resource *templ)
 {
        struct r600_screen *rscreen = (struct r600_screen*)screen;
+       struct radeon_surface surface;
        unsigned array_mode = 0;
+       int r;
 
        if (!(templ->flags & R600_RESOURCE_FLAG_TRANSFER) &&
            !(templ->bind & PIPE_BIND_SCANOUT)) {
-               if (util_format_is_compressed(templ->format)) {
+               if (rscreen->use_surface) {
+                       if (permit_hardware_blit(screen, templ)) {
+                               array_mode = V_038000_ARRAY_2D_TILED_THIN1;
+                       }
+               } else if (util_format_is_compressed(templ->format)) {
                        array_mode = V_038000_ARRAY_1D_TILED_THIN1;
                }
-               else if (debug_get_option_tiling_enabled() &&
-                        rscreen->info.drm_minor >= 9 &&
-                        permit_hardware_blit(screen, templ)) {
-                       array_mode = V_038000_ARRAY_2D_TILED_THIN1;
-               }
        }
 
+       r = r600_init_surface(&surface, templ, array_mode);
+       if (r) {
+               return NULL;
+       }
+       r = rscreen->ws->surface_best(rscreen->ws, &surface);
+       if (r) {
+               return NULL;
+       }
        return (struct pipe_resource *)r600_texture_create_object(screen, templ, array_mode,
-                                                                 0, 0, NULL, TRUE);
+                                                                 0, 0, NULL, TRUE, &surface);
 }
 
 static struct pipe_surface *r600_create_surface(struct pipe_context *pipe,
@@ -550,6 +710,8 @@ struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen,
        unsigned stride = 0;
        unsigned array_mode = 0;
        enum radeon_bo_layout micro, macro;
+       struct radeon_surface surface;
+       int r;
 
        /* Support only 2D textures without mipmaps */
        if ((templ->target != PIPE_TEXTURE_2D && templ->target != PIPE_TEXTURE_RECT) ||
@@ -560,7 +722,11 @@ struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen,
        if (!buf)
                return NULL;
 
-       rscreen->ws->buffer_get_tiling(buf, &micro, &macro);
+       rscreen->ws->buffer_get_tiling(buf, &micro, &macro,
+                                      &surface.bankw, &surface.bankh,
+                                      &surface.tile_split,
+                                      &surface.stencil_tile_split,
+                                      &surface.mtilea);
 
        if (macro == RADEON_LAYOUT_TILED)
                array_mode = V_0280A0_ARRAY_2D_TILED_THIN1;
@@ -569,8 +735,12 @@ struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen,
        else
                array_mode = 0;
 
+       r = r600_init_surface(&surface, templ, array_mode);
+       if (r) {
+               return NULL;
+       }
        return (struct pipe_resource *)r600_texture_create_object(screen, templ, array_mode,
-                                                                 stride, 0, buf, FALSE);
+                                                                 stride, 0, buf, FALSE, &surface);
 }
 
 int r600_texture_depth_flush(struct pipe_context *ctx,
index a1bb753f85991a35825d0f41b3c35b0326c465dd..6a8bf6635f7417a2e3e534bf654437a0087e2525 100644 (file)
@@ -21,4 +21,6 @@ DRIVER_DEFINES = \
 
 include ../Makefile.dri
 
+DRI_LIB_DEPS += -ldrm_radeon
+
 symlinks:
index 2995b58876b647c709fd51932d6e5f65e0059da1..9cc9cb9f63bf795fb92c8c3d197a289fc24afaae 100644 (file)
@@ -21,6 +21,6 @@ DRIVER_DEFINES = \
 
 include ../Makefile.dri
 
-DRI_LIB_DEPS +=
+DRI_LIB_DEPS += -ldrm_radeon
 
 symlinks:
index 70e4362ef1f75bdf56aa16e26135d93515b2562b..02a55eef160ee74c474942fe87151c65f3fea8a4 100644 (file)
@@ -115,6 +115,7 @@ egl_CPPFLAGS += -D_EGL_PIPE_R300=1
 egl_LIBS += \
        $(TOP)/src/gallium/winsys/radeon/drm/libradeonwinsys.a \
        $(TOP)/src/gallium/drivers/r300/libr300.a
+egl_SYS += -ldrm_radeon
 endif
 endif
 
@@ -125,6 +126,7 @@ egl_CPPFLAGS += -D_EGL_PIPE_R600=1
 egl_LIBS += \
        $(TOP)/src/gallium/winsys/radeon/drm/libradeonwinsys.a \
        $(TOP)/src/gallium/drivers/r600/libr600.a
+egl_SYS += -ldrm_radeon
 endif
 endif
 
index 3e0797b65a037412402d23bb6c9cd6818fe051a0..a270dfa7c995d8c4a5e6153063f16dae20ec47d0 100644 (file)
@@ -19,7 +19,7 @@ C_SOURCES = \
        $(COMMON_GALLIUM_SOURCES) \
        $(DRIVER_SOURCES)
 
-DRIVER_LIBS = $(shell $(PKG_CONFIG) libdrm --libs) -lXfixes
+DRIVER_LIBS = $(shell $(PKG_CONFIG) libdrm --libs) -lXfixes -ldrm_radeon
 
 include ../Makefile.va
 
index bab18fea2acd56227007820a54c0eeccd33084e1..afead84391b10be8cebd1324bc75409b6664712a 100644 (file)
@@ -19,7 +19,7 @@ C_SOURCES = \
        $(COMMON_GALLIUM_SOURCES) \
        $(DRIVER_SOURCES)
 
-DRIVER_LIBS = $(shell $(PKG_CONFIG) libdrm --libs) -lXfixes
+DRIVER_LIBS = $(shell $(PKG_CONFIG) libdrm --libs) -lXfixes -ldrm_radeon
 
 include ../Makefile.va
 
index 95988bdc65293838e27b9778f7c13c465dfb2bf0..849f72e03e8253d1410cf7ea4983a1025107089d 100644 (file)
@@ -20,7 +20,7 @@ C_SOURCES = \
        $(COMMON_GALLIUM_SOURCES) \
        $(DRIVER_SOURCES)
 
-DRIVER_LIBS = $(shell $(PKG_CONFIG) libdrm --libs) -lXfixes
+DRIVER_LIBS = $(shell $(PKG_CONFIG) libdrm --libs) -lXfixes -ldrm_radeon
 
 include ../Makefile.vdpau
 
index 466e80eadf9e9b927003a1ee023785c39b4e06c5..ef27b6572c2ff090e7a430e8a0604f6f8e7e7284 100644 (file)
@@ -15,7 +15,7 @@ C_SOURCES = \
        $(COMMON_GALLIUM_SOURCES) \
        $(DRIVER_SOURCES)
 
-DRIVER_LIBS = $(shell $(PKG_CONFIG) libdrm --libs) -lXfixes
+DRIVER_LIBS = $(shell $(PKG_CONFIG) libdrm --libs) -lXfixes -ldrm_radeon
 
 include ../Makefile.vdpau
 
index 26cc5590d7d869704448c337d3de0724e2b913cd..45bb3d7e7011d6f89f0a3fdeb0cd82024bbe9494 100644 (file)
@@ -19,6 +19,6 @@ DRIVER_PIPES = \
        $(TOP)/src/gallium/drivers/rbug/librbug.a
 
 DRIVER_LINKS = \
-       $(shell $(PKG_CONFIG) --libs libdrm)
+       $(shell $(PKG_CONFIG) --libs libdrm libdrm_radeon)
 
 include ../Makefile.xorg
index 3c0cc83711c7daa371c7c4c381103380a81971d1..fd973304f2ccb7cddf73b8990e3cad0753f61d62 100644 (file)
@@ -19,6 +19,6 @@ DRIVER_PIPES = \
        $(TOP)/src/gallium/drivers/rbug/librbug.a
 
 DRIVER_LINKS = \
-       $(shell $(PKG_CONFIG) --libs libdrm)
+       $(shell $(PKG_CONFIG) --libs libdrm libdrm_radeon)
 
 include ../Makefile.xorg
index de2906faef9eb2e621756923db68910658be3f76..adee7b20dbcd4277ea70fe1280106ff26c7ee057 100644 (file)
@@ -620,9 +620,28 @@ static void *radeon_bo_map(struct pb_buffer *buf,
     return pb_map(buf, get_pb_usage_from_transfer_flags(usage), cs);
 }
 
+static unsigned eg_tile_split(unsigned tile_split)
+{
+    switch (tile_split) {
+    case 0:     tile_split = 64;    break;
+    case 1:     tile_split = 128;   break;
+    case 2:     tile_split = 256;   break;
+    case 3:     tile_split = 512;   break;
+    default:
+    case 4:     tile_split = 1024;  break;
+    case 5:     tile_split = 2048;  break;
+    case 6:     tile_split = 4096;  break;
+    }
+    return tile_split;
+}
+
 static void radeon_bo_get_tiling(struct pb_buffer *_buf,
                                  enum radeon_bo_layout *microtiled,
-                                 enum radeon_bo_layout *macrotiled)
+                                 enum radeon_bo_layout *macrotiled,
+                                 unsigned *bankw, unsigned *bankh,
+                                 unsigned *tile_split,
+                                 unsigned *stencil_tile_split,
+                                 unsigned *mtilea)
 {
     struct radeon_bo *bo = get_radeon_bo(_buf);
     struct drm_radeon_gem_set_tiling args;
@@ -643,6 +662,14 @@ static void radeon_bo_get_tiling(struct pb_buffer *_buf,
 
     if (args.tiling_flags & RADEON_BO_FLAGS_MACRO_TILE)
         *macrotiled = RADEON_LAYOUT_TILED;
+    if (bankw && tile_split && stencil_tile_split && mtilea && tile_split) {
+        *bankw = (args.tiling_flags >> RADEON_TILING_EG_BANKW_SHIFT) & RADEON_TILING_EG_BANKW_MASK;
+        *bankh = (args.tiling_flags >> RADEON_TILING_EG_BANKH_SHIFT) & RADEON_TILING_EG_BANKH_MASK;
+        *tile_split = (args.tiling_flags >> RADEON_TILING_EG_TILE_SPLIT_SHIFT) & RADEON_TILING_EG_TILE_SPLIT_MASK;
+        *stencil_tile_split = (args.tiling_flags >> RADEON_TILING_EG_STENCIL_TILE_SPLIT_SHIFT) & RADEON_TILING_EG_STENCIL_TILE_SPLIT_MASK;
+        *mtilea = (args.tiling_flags >> RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT) & RADEON_TILING_EG_MACRO_TILE_ASPECT_MASK;
+        *tile_split = eg_tile_split(*tile_split);
+    }
 }
 
 static void radeon_bo_set_tiling(struct pb_buffer *_buf,
index 051a390ed2255bed501b5c41e35bf7e2a007f93d..dbec259d7f3f898abffbeadc1cbb4ccd186208e0 100644 (file)
@@ -302,6 +302,7 @@ static void radeon_winsys_destroy(struct radeon_winsys *rws)
 
     ws->cman->destroy(ws->cman);
     ws->kman->destroy(ws->kman);
+    radeon_surface_manager_free(ws->surf_man);
     FREE(rws);
 }
 
@@ -339,6 +340,22 @@ static boolean radeon_cs_request_feature(struct radeon_winsys_cs *rcs,
     return FALSE;
 }
 
+static int radeon_drm_winsys_surface_init(struct radeon_winsys *rws,
+                                          struct radeon_surface *surf)
+{
+    struct radeon_drm_winsys *ws = (struct radeon_drm_winsys*)rws;
+
+    return radeon_surface_init(ws->surf_man, surf);
+}
+
+static int radeon_drm_winsys_surface_best(struct radeon_winsys *rws,
+                                          struct radeon_surface *surf)
+{
+    struct radeon_drm_winsys *ws = (struct radeon_drm_winsys*)rws;
+
+    return radeon_surface_best(ws->surf_man, surf);
+}
+
 struct radeon_winsys *radeon_drm_winsys_create(int fd)
 {
     struct radeon_drm_winsys *ws = CALLOC_STRUCT(radeon_drm_winsys);
@@ -359,10 +376,17 @@ struct radeon_winsys *radeon_drm_winsys_create(int fd)
     if (!ws->cman)
         goto fail;
 
+    /* FIXME check for libdrm version ?? */
+    ws->surf_man = radeon_surface_manager_new(fd);
+    if (!ws->surf_man)
+        goto fail;
+
     /* Set functions. */
     ws->base.destroy = radeon_winsys_destroy;
     ws->base.query_info = radeon_query_info;
     ws->base.cs_request_feature = radeon_cs_request_feature;
+    ws->base.surface_init = radeon_drm_winsys_surface_init;
+    ws->base.surface_best = radeon_drm_winsys_surface_best;
 
     radeon_bomgr_init_functions(ws);
     radeon_drm_cs_init_functions(ws);
@@ -377,6 +401,8 @@ fail:
         ws->cman->destroy(ws->cman);
     if (ws->kman)
         ws->kman->destroy(ws->kman);
+    if (ws->surf_man)
+        radeon_surface_manager_free(ws->surf_man);
     FREE(ws);
     return NULL;
 }
index 69216448496ee4ee6533279a946ffb9d40f9aac3..6ac86bcfabb8a354058c6e9dcb383dad26dfbb6c 100644 (file)
@@ -49,6 +49,7 @@ struct radeon_drm_winsys {
 
     struct pb_manager *kman;
     struct pb_manager *cman;
+    struct radeon_surface_manager *surf_man;
 
     uint32_t num_cpus;      /* Number of CPUs. */
 
index 9afd7f8ac82cf06344c390de3fd31386392613dc..6fbe765d6b12dd39f7e7622b4090cb766ef4b0f8 100644 (file)
@@ -43,6 +43,7 @@
 #include "pipebuffer/pb_bufmgr.h"
 #include "pipe/p_defines.h"
 #include "pipe/p_state.h"
+#include "libdrm/radeon_surface.h"
 
 #define RADEON_MAX_CMDBUF_DWORDS (16 * 1024)
 
@@ -200,7 +201,11 @@ struct radeon_winsys {
      */
     void (*buffer_get_tiling)(struct pb_buffer *buf,
                               enum radeon_bo_layout *microtile,
-                              enum radeon_bo_layout *macrotile);
+                              enum radeon_bo_layout *macrotile,
+                              unsigned *bankw, unsigned *bankh,
+                              unsigned *tile_split,
+                              unsigned *stencil_tile_split,
+                              unsigned *mtilea);
 
     /**
      * Set tiling flags describing a memory layout of a buffer object.
@@ -347,6 +352,24 @@ struct radeon_winsys {
     boolean (*cs_request_feature)(struct radeon_winsys_cs *cs,
                                   enum radeon_feature_id fid,
                                   boolean enable);
+
+    /**
+     * Initialize surface
+     *
+     * \param ws        The winsys this function is called from.
+     * \param surf      Surface structure ptr
+     */
+    int (*surface_init)(struct radeon_winsys *ws,
+                        struct radeon_surface *surf);
+
+    /**
+     * Find best values for a surface
+     *
+     * \param ws        The winsys this function is called from.
+     * \param surf      Surface structure ptr
+     */
+    int (*surface_best)(struct radeon_winsys *ws,
+                        struct radeon_surface *surf);
 };
 
 #endif