Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a
  5.  * copy of this software and associated documentation files (the "Software"),
  6.  * to deal in the Software without restriction, including without limitation
  7.  * on the rights to use, copy, modify, merge, publish, distribute, sub
  8.  * license, and/or sell copies of the Software, and to permit persons to whom
  9.  * the Software is furnished to do so, subject to the following conditions:
  10.  *
  11.  * The above copyright notice and this permission notice (including the next
  12.  * paragraph) shall be included in all copies or substantial portions of the
  13.  * Software.
  14.  *
  15.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17.  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
  18.  * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
  19.  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  20.  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  21.  * USE OR OTHER DEALINGS IN THE SOFTWARE.
  22.  *
  23.  * Authors:
  24.  *      Jerome Glisse
  25.  *      Corbin Simpson
  26.  */
  27. #include "r600_formats.h"
  28. #include "evergreen_compute.h"
  29. #include "r600d.h"
  30.  
  31. #include <errno.h>
  32. #include "util/u_format_s3tc.h"
  33. #include "util/u_memory.h"
  34.  
  35.  
  36. /* Same as resource_copy_region, except that both upsampling and downsampling are allowed. */
  37. static void r600_copy_region_with_blit(struct pipe_context *pipe,
  38.                                        struct pipe_resource *dst,
  39.                                        unsigned dst_level,
  40.                                        unsigned dstx, unsigned dsty, unsigned dstz,
  41.                                        struct pipe_resource *src,
  42.                                        unsigned src_level,
  43.                                        const struct pipe_box *src_box)
  44. {
  45.         struct pipe_blit_info blit;
  46.  
  47.         memset(&blit, 0, sizeof(blit));
  48.         blit.src.resource = src;
  49.         blit.src.format = src->format;
  50.         blit.src.level = src_level;
  51.         blit.src.box = *src_box;
  52.         blit.dst.resource = dst;
  53.         blit.dst.format = dst->format;
  54.         blit.dst.level = dst_level;
  55.         blit.dst.box.x = dstx;
  56.         blit.dst.box.y = dsty;
  57.         blit.dst.box.z = dstz;
  58.         blit.dst.box.width = src_box->width;
  59.         blit.dst.box.height = src_box->height;
  60.         blit.dst.box.depth = src_box->depth;
  61.         blit.mask = util_format_get_mask(src->format) &
  62.                     util_format_get_mask(dst->format);
  63.         blit.filter = PIPE_TEX_FILTER_NEAREST;
  64.  
  65.         if (blit.mask) {
  66.                 pipe->blit(pipe, &blit);
  67.         }
  68. }
  69.  
  70. /* Copy from a full GPU texture to a transfer's staging one. */
  71. static void r600_copy_to_staging_texture(struct pipe_context *ctx, struct r600_transfer *rtransfer)
  72. {
  73.         struct r600_context *rctx = (struct r600_context*)ctx;
  74.         struct pipe_transfer *transfer = (struct pipe_transfer*)rtransfer;
  75.         struct pipe_resource *dst = &rtransfer->staging->b.b;
  76.         struct pipe_resource *src = transfer->resource;
  77.  
  78.         if (src->nr_samples > 1) {
  79.                 r600_copy_region_with_blit(ctx, dst, 0, 0, 0, 0,
  80.                                            src, transfer->level, &transfer->box);
  81.                 return;
  82.         }
  83.  
  84.         if (!rctx->screen->dma_blit(ctx, dst, 0, 0, 0, 0,
  85.                                     src, transfer->level,
  86.                                     &transfer->box)) {
  87.                 ctx->resource_copy_region(ctx, dst, 0, 0, 0, 0,
  88.                                           src, transfer->level, &transfer->box);
  89.         }
  90. }
  91.  
  92. /* Copy from a transfer's staging texture to a full GPU one. */
  93. static void r600_copy_from_staging_texture(struct pipe_context *ctx, struct r600_transfer *rtransfer)
  94. {
  95.         struct r600_context *rctx = (struct r600_context*)ctx;
  96.         struct pipe_transfer *transfer = (struct pipe_transfer*)rtransfer;
  97.         struct pipe_resource *dst = transfer->resource;
  98.         struct pipe_resource *src = &rtransfer->staging->b.b;
  99.         struct pipe_box sbox;
  100.  
  101.         u_box_3d(0, 0, 0, transfer->box.width, transfer->box.height, transfer->box.depth, &sbox);
  102.  
  103.         if (dst->nr_samples > 1) {
  104.                 r600_copy_region_with_blit(ctx, dst, transfer->level,
  105.                                            transfer->box.x, transfer->box.y, transfer->box.z,
  106.                                            src, 0, &sbox);
  107.                 return;
  108.         }
  109.  
  110.         if (!rctx->screen->dma_blit(ctx, dst, transfer->level,
  111.                                     transfer->box.x, transfer->box.y, transfer->box.z,
  112.                                     src, 0, &sbox)) {
  113.                 ctx->resource_copy_region(ctx, dst, transfer->level,
  114.                                           transfer->box.x, transfer->box.y, transfer->box.z,
  115.                                           src, 0, &sbox);
  116.         }
  117. }
  118.  
  119. static unsigned r600_texture_get_offset(struct r600_texture *rtex, unsigned level,
  120.                                         const struct pipe_box *box)
  121. {
  122.         enum pipe_format format = rtex->resource.b.b.format;
  123.  
  124.         return rtex->surface.level[level].offset +
  125.                box->z * rtex->surface.level[level].slice_size +
  126.                box->y / util_format_get_blockheight(format) * rtex->surface.level[level].pitch_bytes +
  127.                box->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
  128. }
  129.  
  130. static int r600_init_surface(struct r600_screen *rscreen,
  131.                              struct radeon_surface *surface,
  132.                              const struct pipe_resource *ptex,
  133.                              unsigned array_mode,
  134.                              bool is_flushed_depth)
  135. {
  136.         const struct util_format_description *desc =
  137.                 util_format_description(ptex->format);
  138.         bool is_depth, is_stencil;
  139.  
  140.         is_depth = util_format_has_depth(desc);
  141.         is_stencil = util_format_has_stencil(desc);
  142.  
  143.         surface->npix_x = ptex->width0;
  144.         surface->npix_y = ptex->height0;
  145.         surface->npix_z = ptex->depth0;
  146.         surface->blk_w = util_format_get_blockwidth(ptex->format);
  147.         surface->blk_h = util_format_get_blockheight(ptex->format);
  148.         surface->blk_d = 1;
  149.         surface->array_size = 1;
  150.         surface->last_level = ptex->last_level;
  151.  
  152.         if (rscreen->chip_class >= EVERGREEN && !is_flushed_depth &&
  153.             ptex->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) {
  154.                 surface->bpe = 4; /* stencil is allocated separately on evergreen */
  155.         } else {
  156.                 surface->bpe = util_format_get_blocksize(ptex->format);
  157.                 /* align byte per element on dword */
  158.                 if (surface->bpe == 3) {
  159.                         surface->bpe = 4;
  160.                 }
  161.         }
  162.  
  163.         surface->nsamples = ptex->nr_samples ? ptex->nr_samples : 1;
  164.         surface->flags = 0;
  165.  
  166.         switch (array_mode) {
  167.         case V_038000_ARRAY_1D_TILED_THIN1:
  168.                 surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
  169.                 break;
  170.         case V_038000_ARRAY_2D_TILED_THIN1:
  171.                 surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
  172.                 break;
  173.         case V_038000_ARRAY_LINEAR_ALIGNED:
  174.                 surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR_ALIGNED, MODE);
  175.                 break;
  176.         case V_038000_ARRAY_LINEAR_GENERAL:
  177.         default:
  178.                 surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR, MODE);
  179.                 break;
  180.         }
  181.         switch (ptex->target) {
  182.         case PIPE_TEXTURE_1D:
  183.                 surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D, TYPE);
  184.                 break;
  185.         case PIPE_TEXTURE_RECT:
  186.         case PIPE_TEXTURE_2D:
  187.                 surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE);
  188.                 break;
  189.         case PIPE_TEXTURE_3D:
  190.                 surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_3D, TYPE);
  191.                 break;
  192.         case PIPE_TEXTURE_1D_ARRAY:
  193.                 surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D_ARRAY, TYPE);
  194.                 surface->array_size = ptex->array_size;
  195.                 break;
  196.         case PIPE_TEXTURE_2D_ARRAY:
  197.         case PIPE_TEXTURE_CUBE_ARRAY: /* cube array layout like 2d layout for now */
  198.                 surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D_ARRAY, TYPE);
  199.                 surface->array_size = ptex->array_size;
  200.                 break;
  201.         case PIPE_TEXTURE_CUBE:
  202.                 surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_CUBEMAP, TYPE);
  203.                 break;
  204.         case PIPE_BUFFER:
  205.         default:
  206.                 return -EINVAL;
  207.         }
  208.         if (ptex->bind & PIPE_BIND_SCANOUT) {
  209.                 surface->flags |= RADEON_SURF_SCANOUT;
  210.         }
  211.  
  212.         if (!is_flushed_depth && is_depth) {
  213.                 surface->flags |= RADEON_SURF_ZBUFFER;
  214.  
  215.                 if (is_stencil) {
  216.                         surface->flags |= RADEON_SURF_SBUFFER |
  217.                                           RADEON_SURF_HAS_SBUFFER_MIPTREE;
  218.                 }
  219.         }
  220.         return 0;
  221. }
  222.  
  223. static int r600_setup_surface(struct pipe_screen *screen,
  224.                               struct r600_texture *rtex,
  225.                               unsigned pitch_in_bytes_override)
  226. {
  227.         struct pipe_resource *ptex = &rtex->resource.b.b;
  228.         struct r600_screen *rscreen = (struct r600_screen*)screen;
  229.         unsigned i;
  230.         int r;
  231.  
  232.         r = rscreen->ws->surface_init(rscreen->ws, &rtex->surface);
  233.         if (r) {
  234.                 return r;
  235.         }
  236.         rtex->size = rtex->surface.bo_size;
  237.         if (pitch_in_bytes_override && pitch_in_bytes_override != rtex->surface.level[0].pitch_bytes) {
  238.                 /* old ddx on evergreen over estimate alignment for 1d, only 1 level
  239.                  * for those
  240.                  */
  241.                 rtex->surface.level[0].nblk_x = pitch_in_bytes_override / rtex->surface.bpe;
  242.                 rtex->surface.level[0].pitch_bytes = pitch_in_bytes_override;
  243.                 rtex->surface.level[0].slice_size = pitch_in_bytes_override * rtex->surface.level[0].nblk_y;
  244.                 if (rtex->surface.flags & RADEON_SURF_SBUFFER) {
  245.                         rtex->surface.stencil_offset =
  246.                         rtex->surface.stencil_level[0].offset = rtex->surface.level[0].slice_size;
  247.                 }
  248.         }
  249.         for (i = 0; i <= ptex->last_level; i++) {
  250.                 switch (rtex->surface.level[i].mode) {
  251.                 case RADEON_SURF_MODE_LINEAR_ALIGNED:
  252.                         rtex->array_mode[i] = V_038000_ARRAY_LINEAR_ALIGNED;
  253.                         break;
  254.                 case RADEON_SURF_MODE_1D:
  255.                         rtex->array_mode[i] = V_038000_ARRAY_1D_TILED_THIN1;
  256.                         break;
  257.                 case RADEON_SURF_MODE_2D:
  258.                         rtex->array_mode[i] = V_038000_ARRAY_2D_TILED_THIN1;
  259.                         break;
  260.                 default:
  261.                 case RADEON_SURF_MODE_LINEAR:
  262.                         rtex->array_mode[i] = 0;
  263.                         break;
  264.                 }
  265.         }
  266.         return 0;
  267. }
  268.  
  269. static boolean r600_texture_get_handle(struct pipe_screen* screen,
  270.                                         struct pipe_resource *ptex,
  271.                                         struct winsys_handle *whandle)
  272. {
  273.         struct r600_texture *rtex = (struct r600_texture*)ptex;
  274.         struct r600_resource *resource = &rtex->resource;
  275.         struct radeon_surface *surface = &rtex->surface;
  276.         struct r600_screen *rscreen = (struct r600_screen*)screen;
  277.  
  278.         rscreen->ws->buffer_set_tiling(resource->buf,
  279.                                        NULL,
  280.                                        surface->level[0].mode >= RADEON_SURF_MODE_1D ?
  281.                                        RADEON_LAYOUT_TILED : RADEON_LAYOUT_LINEAR,
  282.                                        surface->level[0].mode >= RADEON_SURF_MODE_2D ?
  283.                                        RADEON_LAYOUT_TILED : RADEON_LAYOUT_LINEAR,
  284.                                        surface->bankw, surface->bankh,
  285.                                        surface->tile_split,
  286.                                        surface->stencil_tile_split,
  287.                                        surface->mtilea,
  288.                                        rtex->surface.level[0].pitch_bytes);
  289.  
  290.         return rscreen->ws->buffer_get_handle(resource->buf,
  291.                                               rtex->surface.level[0].pitch_bytes, whandle);
  292. }
  293.  
  294. static void r600_texture_destroy(struct pipe_screen *screen,
  295.                                  struct pipe_resource *ptex)
  296. {
  297.         struct r600_texture *rtex = (struct r600_texture*)ptex;
  298.         struct r600_resource *resource = &rtex->resource;
  299.  
  300.         if (rtex->flushed_depth_texture)
  301.                 pipe_resource_reference((struct pipe_resource **)&rtex->flushed_depth_texture, NULL);
  302.  
  303.         pipe_resource_reference((struct pipe_resource**)&rtex->htile, NULL);
  304.         pb_reference(&resource->buf, NULL);
  305.         FREE(rtex);
  306. }
  307.  
  308. static const struct u_resource_vtbl r600_texture_vtbl;
  309.  
  310. /* The number of samples can be specified independently of the texture. */
  311. void r600_texture_get_fmask_info(struct r600_screen *rscreen,
  312.                                  struct r600_texture *rtex,
  313.                                  unsigned nr_samples,
  314.                                  struct r600_fmask_info *out)
  315. {
  316.         /* FMASK is allocated like an ordinary texture. */
  317.         struct radeon_surface fmask = rtex->surface;
  318.  
  319.         memset(out, 0, sizeof(*out));
  320.  
  321.         fmask.bo_alignment = 0;
  322.         fmask.bo_size = 0;
  323.         fmask.nsamples = 1;
  324.         fmask.flags |= RADEON_SURF_FMASK;
  325.  
  326.         switch (nr_samples) {
  327.         case 2:
  328.         case 4:
  329.                 fmask.bpe = 1;
  330.                 fmask.bankh = 4;
  331.                 break;
  332.         case 8:
  333.                 fmask.bpe = 4;
  334.                 break;
  335.         default:
  336.                 R600_ERR("Invalid sample count for FMASK allocation.\n");
  337.                 return;
  338.         }
  339.  
  340.         /* Overallocate FMASK on R600-R700 to fix colorbuffer corruption.
  341.          * This can be fixed by writing a separate FMASK allocator specifically
  342.          * for R600-R700 asics. */
  343.         if (rscreen->chip_class <= R700) {
  344.                 fmask.bpe *= 2;
  345.         }
  346.  
  347.         if (rscreen->ws->surface_init(rscreen->ws, &fmask)) {
  348.                 R600_ERR("Got error in surface_init while allocating FMASK.\n");
  349.                 return;
  350.         }
  351.  
  352.         assert(fmask.level[0].mode == RADEON_SURF_MODE_2D);
  353.  
  354.         out->slice_tile_max = (fmask.level[0].nblk_x * fmask.level[0].nblk_y) / 64;
  355.         if (out->slice_tile_max)
  356.                 out->slice_tile_max -= 1;
  357.  
  358.         out->bank_height = fmask.bankh;
  359.         out->alignment = MAX2(256, fmask.bo_alignment);
  360.         out->size = fmask.bo_size;
  361. }
  362.  
  363. static void r600_texture_allocate_fmask(struct r600_screen *rscreen,
  364.                                         struct r600_texture *rtex)
  365. {
  366.         struct r600_fmask_info fmask;
  367.  
  368.         r600_texture_get_fmask_info(rscreen, rtex,
  369.                                     rtex->resource.b.b.nr_samples, &fmask);
  370.  
  371.         rtex->fmask_bank_height = fmask.bank_height;
  372.         rtex->fmask_slice_tile_max = fmask.slice_tile_max;
  373.         rtex->fmask_offset = align(rtex->size, fmask.alignment);
  374.         rtex->fmask_size = fmask.size;
  375.         rtex->size = rtex->fmask_offset + rtex->fmask_size;
  376. #if 0
  377.         printf("FMASK width=%u, height=%i, bits=%u, size=%u\n",
  378.                fmask.npix_x, fmask.npix_y, fmask.bpe * fmask.nsamples, rtex->fmask_size);
  379. #endif
  380. }
  381.  
  382. void r600_texture_get_cmask_info(struct r600_screen *rscreen,
  383.                                  struct r600_texture *rtex,
  384.                                  struct r600_cmask_info *out)
  385. {
  386.         unsigned cmask_tile_width = 8;
  387.         unsigned cmask_tile_height = 8;
  388.         unsigned cmask_tile_elements = cmask_tile_width * cmask_tile_height;
  389.         unsigned element_bits = 4;
  390.         unsigned cmask_cache_bits = 1024;
  391.         unsigned num_pipes = rscreen->tiling_info.num_channels;
  392.         unsigned pipe_interleave_bytes = rscreen->tiling_info.group_bytes;
  393.  
  394.         unsigned elements_per_macro_tile = (cmask_cache_bits / element_bits) * num_pipes;
  395.         unsigned pixels_per_macro_tile = elements_per_macro_tile * cmask_tile_elements;
  396.         unsigned sqrt_pixels_per_macro_tile = sqrt(pixels_per_macro_tile);
  397.         unsigned macro_tile_width = util_next_power_of_two(sqrt_pixels_per_macro_tile);
  398.         unsigned macro_tile_height = pixels_per_macro_tile / macro_tile_width;
  399.  
  400.         unsigned pitch_elements = align(rtex->surface.npix_x, macro_tile_width);
  401.         unsigned height = align(rtex->surface.npix_y, macro_tile_height);
  402.  
  403.         unsigned base_align = num_pipes * pipe_interleave_bytes;
  404.         unsigned slice_bytes =
  405.                 ((pitch_elements * height * element_bits + 7) / 8) / cmask_tile_elements;
  406.  
  407.         assert(macro_tile_width % 128 == 0);
  408.         assert(macro_tile_height % 128 == 0);
  409.  
  410.         out->slice_tile_max = ((pitch_elements * height) / (128*128)) - 1;
  411.         out->alignment = MAX2(256, base_align);
  412.         out->size = rtex->surface.array_size * align(slice_bytes, base_align);
  413. }
  414.  
  415. static void r600_texture_allocate_cmask(struct r600_screen *rscreen,
  416.                                         struct r600_texture *rtex)
  417. {
  418.         struct r600_cmask_info cmask;
  419.  
  420.         r600_texture_get_cmask_info(rscreen, rtex, &cmask);
  421.  
  422.         rtex->cmask_slice_tile_max = cmask.slice_tile_max;
  423.         rtex->cmask_offset = align(rtex->size, cmask.alignment);
  424.         rtex->cmask_size = cmask.size;
  425.         rtex->size = rtex->cmask_offset + rtex->cmask_size;
  426. #if 0
  427.         printf("CMASK: macro tile width = %u, macro tile height = %u, "
  428.                "pitch elements = %u, height = %u, slice tile max = %u\n",
  429.                macro_tile_width, macro_tile_height, pitch_elements, height,
  430.                rtex->cmask_slice_tile_max);
  431. #endif
  432. }
  433.  
  434. static struct r600_texture *
  435. r600_texture_create_object(struct pipe_screen *screen,
  436.                            const struct pipe_resource *base,
  437.                            unsigned pitch_in_bytes_override,
  438.                            struct pb_buffer *buf,
  439.                            struct radeon_surface *surface)
  440. {
  441.         struct r600_texture *rtex;
  442.         struct r600_resource *resource;
  443.         struct r600_screen *rscreen = (struct r600_screen*)screen;
  444.         int r;
  445.  
  446.         rtex = CALLOC_STRUCT(r600_texture);
  447.         if (rtex == NULL)
  448.                 return NULL;
  449.  
  450.         resource = &rtex->resource;
  451.         resource->b.b = *base;
  452.         resource->b.vtbl = &r600_texture_vtbl;
  453.         pipe_reference_init(&resource->b.b.reference, 1);
  454.         resource->b.b.screen = screen;
  455.         rtex->pitch_override = pitch_in_bytes_override;
  456.  
  457.         /* don't include stencil-only formats which we don't support for rendering */
  458.         rtex->is_depth = util_format_has_depth(util_format_description(rtex->resource.b.b.format));
  459.  
  460.         rtex->surface = *surface;
  461.         r = r600_setup_surface(screen, rtex,
  462.                                pitch_in_bytes_override);
  463.         if (r) {
  464.                 FREE(rtex);
  465.                 return NULL;
  466.         }
  467.  
  468.         if (base->nr_samples > 1 && !rtex->is_depth && !buf) {
  469.                 r600_texture_allocate_fmask(rscreen, rtex);
  470.                 r600_texture_allocate_cmask(rscreen, rtex);
  471.         }
  472.  
  473.         if (!rtex->is_depth && base->nr_samples > 1 &&
  474.             (!rtex->fmask_size || !rtex->cmask_size)) {
  475.                 FREE(rtex);
  476.                 return NULL;
  477.         }
  478.  
  479.         /* Tiled depth textures utilize the non-displayable tile order. */
  480.         rtex->non_disp_tiling = rtex->is_depth && rtex->surface.level[0].mode >= RADEON_SURF_MODE_1D;
  481.  
  482.         /* only enable hyperz for PIPE_TEXTURE_2D not for PIPE_TEXTURE_2D_ARRAY
  483.          * Thought it might still be interessting to use hyperz for texture
  484.          * array without using fast clear features
  485.          */
  486.         rtex->htile = NULL;
  487.         if (!(base->flags & (R600_RESOURCE_FLAG_TRANSFER | R600_RESOURCE_FLAG_FLUSHED_DEPTH)) &&
  488.             util_format_is_depth_or_stencil(base->format) &&
  489.             rscreen->info.drm_minor >= 26 &&
  490.             !(rscreen->debug_flags & DBG_NO_HYPERZ) &&
  491.             base->target == PIPE_TEXTURE_2D &&
  492.             rtex->surface.level[0].nblk_x >= 32 &&
  493.             rtex->surface.level[0].nblk_y >= 32) {
  494.                 unsigned sw = rtex->surface.level[0].nblk_x * rtex->surface.blk_w;
  495.                 unsigned sh = rtex->surface.level[0].nblk_y * rtex->surface.blk_h;
  496.                 unsigned htile_size;
  497.                 unsigned npipes = rscreen->info.r600_num_tile_pipes;
  498.  
  499.                 /* this alignment and htile size only apply to linear htile buffer */
  500.                 sw = align(sw, 16 << 3);
  501.                 sh = align(sh, npipes << 3);
  502.                 htile_size = (sw >> 3) * (sh >> 3) * 4;
  503.                 /* must be aligned with 2K * npipes */
  504.                 htile_size = align(htile_size, (2 << 10) * npipes);
  505.  
  506.                 rtex->htile = (struct r600_resource*)pipe_buffer_create(&rscreen->screen, PIPE_BIND_CUSTOM,
  507.                                                                         PIPE_USAGE_STATIC, htile_size);
  508.                 if (rtex->htile == NULL) {
  509.                         /* this is not a fatal error as we can still keep rendering
  510.                          * without htile buffer
  511.                          */
  512.                         R600_ERR("r600: failed to create bo for htile buffers\n");
  513.                 } else {
  514.                         r600_screen_clear_buffer(rscreen, &rtex->htile->b.b, 0, htile_size, 0);
  515.                 }
  516.         }
  517.  
  518.         /* Now create the backing buffer. */
  519.         if (!buf) {
  520.                 unsigned base_align = rtex->surface.bo_alignment;
  521.                 unsigned usage = R600_TEX_IS_TILED(rtex, 0) ? PIPE_USAGE_STATIC : base->usage;
  522.  
  523.                 if (!r600_init_resource(rscreen, resource, rtex->size, base_align, FALSE, usage)) {
  524.                         FREE(rtex);
  525.                         return NULL;
  526.                 }
  527.         } else {
  528.                 /* This is usually the window framebuffer. We want it in VRAM, always. */
  529.                 resource->buf = buf;
  530.                 resource->cs_buf = rscreen->ws->buffer_get_cs_handle(buf);
  531.                 resource->domains = RADEON_DOMAIN_VRAM;
  532.         }
  533.  
  534.         if (rtex->cmask_size) {
  535.                 /* Initialize the cmask to 0xCC (= compressed state). */
  536.                 r600_screen_clear_buffer(rscreen, &rtex->resource.b.b,
  537.                                          rtex->cmask_offset, rtex->cmask_size, 0xCC);
  538.         }
  539.  
  540.         if (rscreen->debug_flags & DBG_VM) {
  541.                 fprintf(stderr, "VM start=0x%llX  end=0x%llX | Texture %ix%ix%i, %i levels, %i samples, %s\n",
  542.                         r600_resource_va(screen, &rtex->resource.b.b),
  543.                         r600_resource_va(screen, &rtex->resource.b.b) + rtex->resource.buf->size,
  544.                         base->width0, base->height0, util_max_layer(base, 0)+1, base->last_level+1,
  545.                         base->nr_samples ? base->nr_samples : 1, util_format_short_name(base->format));
  546.         }
  547.  
  548.         if (rscreen->debug_flags & DBG_TEX_DEPTH && rtex->is_depth && rtex->non_disp_tiling) {
  549.                 printf("Texture: npix_x=%u, npix_y=%u, npix_z=%u, blk_w=%u, "
  550.                        "blk_h=%u, blk_d=%u, array_size=%u, last_level=%u, "
  551.                        "bpe=%u, nsamples=%u, flags=%u\n",
  552.                        rtex->surface.npix_x, rtex->surface.npix_y,
  553.                        rtex->surface.npix_z, rtex->surface.blk_w,
  554.                        rtex->surface.blk_h, rtex->surface.blk_d,
  555.                        rtex->surface.array_size, rtex->surface.last_level,
  556.                        rtex->surface.bpe, rtex->surface.nsamples,
  557.                        rtex->surface.flags);
  558.                 if (rtex->surface.flags & RADEON_SURF_ZBUFFER) {
  559.                         for (int i = 0; i <= rtex->surface.last_level; i++) {
  560.                                 printf("  Z %i: offset=%llu, slice_size=%llu, npix_x=%u, "
  561.                                        "npix_y=%u, npix_z=%u, nblk_x=%u, nblk_y=%u, "
  562.                                        "nblk_z=%u, pitch_bytes=%u, mode=%u\n",
  563.                                        i, (unsigned long long)rtex->surface.level[i].offset,
  564.                                        (unsigned long long)rtex->surface.level[i].slice_size,
  565.                                        u_minify(rtex->resource.b.b.width0, i),
  566.                                        u_minify(rtex->resource.b.b.height0, i),
  567.                                        u_minify(rtex->resource.b.b.depth0, i),
  568.                                        rtex->surface.level[i].nblk_x,
  569.                                        rtex->surface.level[i].nblk_y,
  570.                                        rtex->surface.level[i].nblk_z,
  571.                                        rtex->surface.level[i].pitch_bytes,
  572.                                        rtex->surface.level[i].mode);
  573.                         }
  574.                 }
  575.                 if (rtex->surface.flags & RADEON_SURF_SBUFFER) {
  576.                         for (int i = 0; i <= rtex->surface.last_level; i++) {
  577.                                 printf("  S %i: offset=%llu, slice_size=%llu, npix_x=%u, "
  578.                                        "npix_y=%u, npix_z=%u, nblk_x=%u, nblk_y=%u, "
  579.                                        "nblk_z=%u, pitch_bytes=%u, mode=%u\n",
  580.                                        i, (unsigned long long)rtex->surface.stencil_level[i].offset,
  581.                                        (unsigned long long)rtex->surface.stencil_level[i].slice_size,
  582.                                        u_minify(rtex->resource.b.b.width0, i),
  583.                                        u_minify(rtex->resource.b.b.height0, i),
  584.                                        u_minify(rtex->resource.b.b.depth0, i),
  585.                                        rtex->surface.stencil_level[i].nblk_x,
  586.                                        rtex->surface.stencil_level[i].nblk_y,
  587.                                        rtex->surface.stencil_level[i].nblk_z,
  588.                                        rtex->surface.stencil_level[i].pitch_bytes,
  589.                                        rtex->surface.stencil_level[i].mode);
  590.                         }
  591.                 }
  592.         }
  593.         return rtex;
  594. }
  595.  
  596. struct pipe_resource *r600_texture_create(struct pipe_screen *screen,
  597.                                                 const struct pipe_resource *templ)
  598. {
  599.         struct r600_screen *rscreen = (struct r600_screen*)screen;
  600.         struct radeon_surface surface;
  601.         const struct util_format_description *desc = util_format_description(templ->format);
  602.         unsigned array_mode;
  603.         int r;
  604.  
  605.         /* Default tiling mode for staging textures. */
  606.         array_mode = V_038000_ARRAY_LINEAR_ALIGNED;
  607.  
  608.         /* Tiling doesn't work with the 422 (SUBSAMPLED) formats. That's not an issue,
  609.          * because 422 formats are used for videos, which prefer linear buffers
  610.          * for fast uploads anyway. */
  611.         if (!(templ->flags & R600_RESOURCE_FLAG_TRANSFER) &&
  612.             desc->layout != UTIL_FORMAT_LAYOUT_SUBSAMPLED) {
  613.                 if (templ->flags & R600_RESOURCE_FLAG_FORCE_TILING) {
  614.                         array_mode = V_038000_ARRAY_2D_TILED_THIN1;
  615.                 } else if (!(templ->bind & PIPE_BIND_SCANOUT) &&
  616.                            templ->usage != PIPE_USAGE_STAGING &&
  617.                            templ->usage != PIPE_USAGE_STREAM &&
  618.                            templ->target != PIPE_TEXTURE_1D &&
  619.                            templ->target != PIPE_TEXTURE_1D_ARRAY &&
  620.                            templ->height0 > 3) {
  621.                         array_mode = V_038000_ARRAY_2D_TILED_THIN1;
  622.                 } else if (util_format_is_compressed(templ->format)) {
  623.                         array_mode = V_038000_ARRAY_1D_TILED_THIN1;
  624.                 }
  625.         }
  626.  
  627.         r = r600_init_surface(rscreen, &surface, templ, array_mode,
  628.                               templ->flags & R600_RESOURCE_FLAG_FLUSHED_DEPTH);
  629.         if (r) {
  630.                 return NULL;
  631.         }
  632.         r = rscreen->ws->surface_best(rscreen->ws, &surface);
  633.         if (r) {
  634.                 return NULL;
  635.         }
  636.         return (struct pipe_resource *)r600_texture_create_object(screen, templ,
  637.                                                                   0, NULL, &surface);
  638. }
  639.  
  640. struct pipe_surface *r600_create_surface_custom(struct pipe_context *pipe,
  641.                                                 struct pipe_resource *texture,
  642.                                                 const struct pipe_surface *templ,
  643.                                                 unsigned width, unsigned height)
  644. {
  645.         struct r600_surface *surface = CALLOC_STRUCT(r600_surface);
  646.  
  647.         assert(templ->u.tex.first_layer <= util_max_layer(texture, templ->u.tex.level));
  648.         assert(templ->u.tex.last_layer <= util_max_layer(texture, templ->u.tex.level));
  649.         assert(templ->u.tex.first_layer == templ->u.tex.last_layer);
  650.         if (surface == NULL)
  651.                 return NULL;
  652.         pipe_reference_init(&surface->base.reference, 1);
  653.         pipe_resource_reference(&surface->base.texture, texture);
  654.         surface->base.context = pipe;
  655.         surface->base.format = templ->format;
  656.         surface->base.width = width;
  657.         surface->base.height = height;
  658.         surface->base.u = templ->u;
  659.         return &surface->base;
  660. }
  661.  
  662. static struct pipe_surface *r600_create_surface(struct pipe_context *pipe,
  663.                                                 struct pipe_resource *tex,
  664.                                                 const struct pipe_surface *templ)
  665. {
  666.         unsigned level = templ->u.tex.level;
  667.  
  668.         return r600_create_surface_custom(pipe, tex, templ,
  669.                                           u_minify(tex->width0, level),
  670.                                           u_minify(tex->height0, level));
  671. }
  672.  
  673. static void r600_surface_destroy(struct pipe_context *pipe,
  674.                                  struct pipe_surface *surface)
  675. {
  676.         struct r600_surface *surf = (struct r600_surface*)surface;
  677.         pipe_resource_reference((struct pipe_resource**)&surf->cb_buffer_fmask, NULL);
  678.         pipe_resource_reference((struct pipe_resource**)&surf->cb_buffer_cmask, NULL);
  679.         pipe_resource_reference(&surface->texture, NULL);
  680.         FREE(surface);
  681. }
  682.  
  683. struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen,
  684.                                                const struct pipe_resource *templ,
  685.                                                struct winsys_handle *whandle)
  686. {
  687.         struct r600_screen *rscreen = (struct r600_screen*)screen;
  688.         struct pb_buffer *buf = NULL;
  689.         unsigned stride = 0;
  690.         unsigned array_mode = 0;
  691.         enum radeon_bo_layout micro, macro;
  692.         struct radeon_surface surface;
  693.         int r;
  694.  
  695.         /* Support only 2D textures without mipmaps */
  696.         if ((templ->target != PIPE_TEXTURE_2D && templ->target != PIPE_TEXTURE_RECT) ||
  697.               templ->depth0 != 1 || templ->last_level != 0)
  698.                 return NULL;
  699.  
  700.         buf = rscreen->ws->buffer_from_handle(rscreen->ws, whandle, &stride);
  701.         if (!buf)
  702.                 return NULL;
  703.  
  704.         rscreen->ws->buffer_get_tiling(buf, &micro, &macro,
  705.                                        &surface.bankw, &surface.bankh,
  706.                                        &surface.tile_split,
  707.                                        &surface.stencil_tile_split,
  708.                                        &surface.mtilea);
  709.  
  710.         if (macro == RADEON_LAYOUT_TILED)
  711.                 array_mode = V_0280A0_ARRAY_2D_TILED_THIN1;
  712.         else if (micro == RADEON_LAYOUT_TILED)
  713.                 array_mode = V_0280A0_ARRAY_1D_TILED_THIN1;
  714.         else
  715.                 array_mode = V_038000_ARRAY_LINEAR_ALIGNED;
  716.  
  717.         r = r600_init_surface(rscreen, &surface, templ, array_mode, false);
  718.         if (r) {
  719.                 return NULL;
  720.         }
  721.         return (struct pipe_resource *)r600_texture_create_object(screen, templ,
  722.                                                                   stride, buf, &surface);
  723. }
  724.  
  725. bool r600_init_flushed_depth_texture(struct pipe_context *ctx,
  726.                                      struct pipe_resource *texture,
  727.                                      struct r600_texture **staging)
  728. {
  729.         struct r600_texture *rtex = (struct r600_texture*)texture;
  730.         struct pipe_resource resource;
  731.         struct r600_texture **flushed_depth_texture = staging ?
  732.                         staging : &rtex->flushed_depth_texture;
  733.  
  734.         if (!staging && rtex->flushed_depth_texture)
  735.                 return true; /* it's ready */
  736.  
  737.         resource.target = texture->target;
  738.         resource.format = texture->format;
  739.         resource.width0 = texture->width0;
  740.         resource.height0 = texture->height0;
  741.         resource.depth0 = texture->depth0;
  742.         resource.array_size = texture->array_size;
  743.         resource.last_level = texture->last_level;
  744.         resource.nr_samples = texture->nr_samples;
  745.         resource.usage = staging ? PIPE_USAGE_STAGING : PIPE_USAGE_STATIC;
  746.         resource.bind = texture->bind & ~PIPE_BIND_DEPTH_STENCIL;
  747.         resource.flags = texture->flags | R600_RESOURCE_FLAG_FLUSHED_DEPTH;
  748.  
  749.         if (staging)
  750.                 resource.flags |= R600_RESOURCE_FLAG_TRANSFER;
  751.  
  752.         *flushed_depth_texture = (struct r600_texture *)ctx->screen->resource_create(ctx->screen, &resource);
  753.         if (*flushed_depth_texture == NULL) {
  754.                 R600_ERR("failed to create temporary texture to hold flushed depth\n");
  755.                 return false;
  756.         }
  757.  
  758.         (*flushed_depth_texture)->is_flushing_texture = TRUE;
  759.         (*flushed_depth_texture)->non_disp_tiling = false;
  760.         return true;
  761. }
  762.  
  763. /**
  764.  * Initialize the pipe_resource descriptor to be of the same size as the box,
  765.  * which is supposed to hold a subregion of the texture "orig" at the given
  766.  * mipmap level.
  767.  */
  768. static void r600_init_temp_resource_from_box(struct pipe_resource *res,
  769.                                              struct pipe_resource *orig,
  770.                                              const struct pipe_box *box,
  771.                                              unsigned level, unsigned flags)
  772. {
  773.         memset(res, 0, sizeof(*res));
  774.         res->format = orig->format;
  775.         res->width0 = box->width;
  776.         res->height0 = box->height;
  777.         res->depth0 = 1;
  778.         res->array_size = 1;
  779.         res->usage = flags & R600_RESOURCE_FLAG_TRANSFER ? PIPE_USAGE_STAGING : PIPE_USAGE_STATIC;
  780.         res->flags = flags;
  781.  
  782.         /* We must set the correct texture target and dimensions for a 3D box. */
  783.         if (box->depth > 1 && util_max_layer(orig, level) > 0)
  784.                 res->target = orig->target;
  785.         else
  786.                 res->target = PIPE_TEXTURE_2D;
  787.  
  788.         switch (res->target) {
  789.         case PIPE_TEXTURE_1D_ARRAY:
  790.         case PIPE_TEXTURE_2D_ARRAY:
  791.         case PIPE_TEXTURE_CUBE_ARRAY:
  792.                 res->array_size = box->depth;
  793.                 break;
  794.         case PIPE_TEXTURE_3D:
  795.                 res->depth0 = box->depth;
  796.                 break;
  797.         default:;
  798.         }
  799. }
  800.  
  801. static void *r600_texture_transfer_map(struct pipe_context *ctx,
  802.                                        struct pipe_resource *texture,
  803.                                        unsigned level,
  804.                                        unsigned usage,
  805.                                        const struct pipe_box *box,
  806.                                        struct pipe_transfer **ptransfer)
  807. {
  808.         struct r600_context *rctx = (struct r600_context*)ctx;
  809.         struct r600_texture *rtex = (struct r600_texture*)texture;
  810.         struct r600_transfer *trans;
  811.         boolean use_staging_texture = FALSE;
  812.         struct r600_resource *buf;
  813.         unsigned offset = 0;
  814.         char *map;
  815.  
  816.         if ((texture->bind & PIPE_BIND_GLOBAL) && texture->target == PIPE_BUFFER) {
  817.                 return r600_compute_global_transfer_map(ctx, texture, level, usage, box, ptransfer);
  818.         }
  819.  
  820.         /* We cannot map a tiled texture directly because the data is
  821.          * in a different order, therefore we do detiling using a blit.
  822.          *
  823.          * Also, use a temporary in GTT memory for read transfers, as
  824.          * the CPU is much happier reading out of cached system memory
  825.          * than uncached VRAM.
  826.          */
  827.         if (R600_TEX_IS_TILED(rtex, level)) {
  828.                 use_staging_texture = TRUE;
  829.         }
  830.  
  831.         /* Use a staging texture for uploads if the underlying BO is busy. */
  832.         if (!(usage & PIPE_TRANSFER_READ) &&
  833.             (r600_rings_is_buffer_referenced(rctx, rtex->resource.cs_buf, RADEON_USAGE_READWRITE) ||
  834.              rctx->ws->buffer_is_busy(rtex->resource.buf, RADEON_USAGE_READWRITE))) {
  835.                 use_staging_texture = TRUE;
  836.         }
  837.  
  838.         if (texture->flags & R600_RESOURCE_FLAG_TRANSFER) {
  839.                 use_staging_texture = FALSE;
  840.         }
  841.  
  842.         if (use_staging_texture && (usage & PIPE_TRANSFER_MAP_DIRECTLY)) {
  843.                 return NULL;
  844.         }
  845.  
  846.         trans = CALLOC_STRUCT(r600_transfer);
  847.         if (trans == NULL)
  848.                 return NULL;
  849.         trans->transfer.resource = texture;
  850.         trans->transfer.level = level;
  851.         trans->transfer.usage = usage;
  852.         trans->transfer.box = *box;
  853.  
  854.         if (rtex->is_depth) {
  855.                 struct r600_texture *staging_depth;
  856.  
  857.                 if (rtex->resource.b.b.nr_samples > 1) {
  858.                         /* MSAA depth buffers need to be converted to single sample buffers.
  859.                          *
  860.                          * Mapping MSAA depth buffers can occur if ReadPixels is called
  861.                          * with a multisample GLX visual.
  862.                          *
  863.                          * First downsample the depth buffer to a temporary texture,
  864.                          * then decompress the temporary one to staging.
  865.                          *
  866.                          * Only the region being mapped is transfered.
  867.                          */
  868.                         struct pipe_resource resource;
  869.  
  870.                         r600_init_temp_resource_from_box(&resource, texture, box, level, 0);
  871.  
  872.                         if (!r600_init_flushed_depth_texture(ctx, &resource, &staging_depth)) {
  873.                                 R600_ERR("failed to create temporary texture to hold untiled copy\n");
  874.                                 FREE(trans);
  875.                                 return NULL;
  876.                         }
  877.  
  878.                         if (usage & PIPE_TRANSFER_READ) {
  879.                                 struct pipe_resource *temp = ctx->screen->resource_create(ctx->screen, &resource);
  880.  
  881.                                 r600_copy_region_with_blit(ctx, temp, 0, 0, 0, 0, texture, level, box);
  882.                                 r600_blit_decompress_depth(ctx, (struct r600_texture*)temp, staging_depth,
  883.                                                            0, 0, 0, box->depth, 0, 0);
  884.                                 pipe_resource_reference((struct pipe_resource**)&temp, NULL);
  885.                         }
  886.                 }
  887.                 else {
  888.                         /* XXX: only readback the rectangle which is being mapped? */
  889.                         /* XXX: when discard is true, no need to read back from depth texture */
  890.                         if (!r600_init_flushed_depth_texture(ctx, texture, &staging_depth)) {
  891.                                 R600_ERR("failed to create temporary texture to hold untiled copy\n");
  892.                                 FREE(trans);
  893.                                 return NULL;
  894.                         }
  895.  
  896.                         r600_blit_decompress_depth(ctx, rtex, staging_depth,
  897.                                                    level, level,
  898.                                                    box->z, box->z + box->depth - 1,
  899.                                                    0, 0);
  900.  
  901.                         offset = r600_texture_get_offset(staging_depth, level, box);
  902.                 }
  903.  
  904.                 trans->transfer.stride = staging_depth->surface.level[level].pitch_bytes;
  905.                 trans->transfer.layer_stride = staging_depth->surface.level[level].slice_size;
  906.                 trans->staging = (struct r600_resource*)staging_depth;
  907.         } else if (use_staging_texture) {
  908.                 struct pipe_resource resource;
  909.                 struct r600_texture *staging;
  910.  
  911.                 r600_init_temp_resource_from_box(&resource, texture, box, level,
  912.                                                  R600_RESOURCE_FLAG_TRANSFER);
  913.  
  914.                 /* Create the temporary texture. */
  915.                 staging = (struct r600_texture*)ctx->screen->resource_create(ctx->screen, &resource);
  916.                 if (staging == NULL) {
  917.                         R600_ERR("failed to create temporary texture to hold untiled copy\n");
  918.                         FREE(trans);
  919.                         return NULL;
  920.                 }
  921.                 trans->staging = &staging->resource;
  922.                 trans->transfer.stride = staging->surface.level[0].pitch_bytes;
  923.                 trans->transfer.layer_stride = staging->surface.level[0].slice_size;
  924.                 if (usage & PIPE_TRANSFER_READ) {
  925.                         r600_copy_to_staging_texture(ctx, trans);
  926.                 }
  927.         } else {
  928.                 /* the resource is mapped directly */
  929.                 trans->transfer.stride = rtex->surface.level[level].pitch_bytes;
  930.                 trans->transfer.layer_stride = rtex->surface.level[level].slice_size;
  931.                 offset = r600_texture_get_offset(rtex, level, box);
  932.         }
  933.  
  934.         if (trans->staging) {
  935.                 buf = trans->staging;
  936.         } else {
  937.                 buf = &rtex->resource;
  938.         }
  939.  
  940.         if (!(map = r600_buffer_mmap_sync_with_rings(rctx, buf, usage))) {
  941.                 pipe_resource_reference((struct pipe_resource**)&trans->staging, NULL);
  942.                 FREE(trans);
  943.                 return NULL;
  944.         }
  945.  
  946.         *ptransfer = &trans->transfer;
  947.         return map + offset;
  948. }
  949.  
  950. static void r600_texture_transfer_unmap(struct pipe_context *ctx,
  951.                                         struct pipe_transfer* transfer)
  952. {
  953.         struct r600_transfer *rtransfer = (struct r600_transfer*)transfer;
  954.         struct r600_context *rctx = (struct r600_context*)ctx;
  955.         struct radeon_winsys_cs_handle *buf;
  956.         struct pipe_resource *texture = transfer->resource;
  957.         struct r600_texture *rtex = (struct r600_texture*)texture;
  958.  
  959.         if ((transfer->resource->bind & PIPE_BIND_GLOBAL) && transfer->resource->target == PIPE_BUFFER) {
  960.                 return r600_compute_global_transfer_unmap(ctx, transfer);
  961.         }
  962.  
  963.         if (rtransfer->staging) {
  964.                 buf = ((struct r600_resource *)rtransfer->staging)->cs_buf;
  965.         } else {
  966.                 buf = ((struct r600_resource *)transfer->resource)->cs_buf;
  967.         }
  968.         rctx->ws->buffer_unmap(buf);
  969.  
  970.         if ((transfer->usage & PIPE_TRANSFER_WRITE) && rtransfer->staging) {
  971.                 if (rtex->is_depth && rtex->resource.b.b.nr_samples <= 1) {
  972.                         ctx->resource_copy_region(ctx, texture, transfer->level,
  973.                                                   transfer->box.x, transfer->box.y, transfer->box.z,
  974.                                                   &rtransfer->staging->b.b, transfer->level,
  975.                                                   &transfer->box);
  976.                 } else {
  977.                         r600_copy_from_staging_texture(ctx, rtransfer);
  978.                 }
  979.         }
  980.  
  981.         if (rtransfer->staging)
  982.                 pipe_resource_reference((struct pipe_resource**)&rtransfer->staging, NULL);
  983.  
  984.         FREE(transfer);
  985. }
  986.  
  987. void r600_init_surface_functions(struct r600_context *r600)
  988. {
  989.         r600->context.create_surface = r600_create_surface;
  990.         r600->context.surface_destroy = r600_surface_destroy;
  991. }
  992.  
  993. unsigned r600_get_swizzle_combined(const unsigned char *swizzle_format,
  994.                                    const unsigned char *swizzle_view,
  995.                                    boolean vtx)
  996. {
  997.         unsigned i;
  998.         unsigned char swizzle[4];
  999.         unsigned result = 0;
  1000.         const uint32_t tex_swizzle_shift[4] = {
  1001.                 16, 19, 22, 25,
  1002.         };
  1003.         const uint32_t vtx_swizzle_shift[4] = {
  1004.                 3, 6, 9, 12,
  1005.         };
  1006.         const uint32_t swizzle_bit[4] = {
  1007.                 0, 1, 2, 3,
  1008.         };
  1009.         const uint32_t *swizzle_shift = tex_swizzle_shift;
  1010.  
  1011.         if (vtx)
  1012.                 swizzle_shift = vtx_swizzle_shift;
  1013.  
  1014.         if (swizzle_view) {
  1015.                 util_format_compose_swizzles(swizzle_format, swizzle_view, swizzle);
  1016.         } else {
  1017.                 memcpy(swizzle, swizzle_format, 4);
  1018.         }
  1019.  
  1020.         /* Get swizzle. */
  1021.         for (i = 0; i < 4; i++) {
  1022.                 switch (swizzle[i]) {
  1023.                 case UTIL_FORMAT_SWIZZLE_Y:
  1024.                         result |= swizzle_bit[1] << swizzle_shift[i];
  1025.                         break;
  1026.                 case UTIL_FORMAT_SWIZZLE_Z:
  1027.                         result |= swizzle_bit[2] << swizzle_shift[i];
  1028.                         break;
  1029.                 case UTIL_FORMAT_SWIZZLE_W:
  1030.                         result |= swizzle_bit[3] << swizzle_shift[i];
  1031.                         break;
  1032.                 case UTIL_FORMAT_SWIZZLE_0:
  1033.                         result |= V_038010_SQ_SEL_0 << swizzle_shift[i];
  1034.                         break;
  1035.                 case UTIL_FORMAT_SWIZZLE_1:
  1036.                         result |= V_038010_SQ_SEL_1 << swizzle_shift[i];
  1037.                         break;
  1038.                 default: /* UTIL_FORMAT_SWIZZLE_X */
  1039.                         result |= swizzle_bit[0] << swizzle_shift[i];
  1040.                 }
  1041.         }
  1042.         return result;
  1043. }
  1044.  
  1045. /* texture format translate */
  1046. uint32_t r600_translate_texformat(struct pipe_screen *screen,
  1047.                                   enum pipe_format format,
  1048.                                   const unsigned char *swizzle_view,
  1049.                                   uint32_t *word4_p, uint32_t *yuv_format_p)
  1050. {
  1051.         struct r600_screen *rscreen = (struct r600_screen *)screen;
  1052.         uint32_t result = 0, word4 = 0, yuv_format = 0;
  1053.         const struct util_format_description *desc;
  1054.         boolean uniform = TRUE;
  1055.         bool enable_s3tc = rscreen->info.drm_minor >= 9;
  1056.         bool is_srgb_valid = FALSE;
  1057.         const unsigned char swizzle_xxxx[4] = {0, 0, 0, 0};
  1058.         const unsigned char swizzle_yyyy[4] = {1, 1, 1, 1};
  1059.  
  1060.         int i;
  1061.         const uint32_t sign_bit[4] = {
  1062.                 S_038010_FORMAT_COMP_X(V_038010_SQ_FORMAT_COMP_SIGNED),
  1063.                 S_038010_FORMAT_COMP_Y(V_038010_SQ_FORMAT_COMP_SIGNED),
  1064.                 S_038010_FORMAT_COMP_Z(V_038010_SQ_FORMAT_COMP_SIGNED),
  1065.                 S_038010_FORMAT_COMP_W(V_038010_SQ_FORMAT_COMP_SIGNED)
  1066.         };
  1067.         desc = util_format_description(format);
  1068.  
  1069.         /* Depth and stencil swizzling is handled separately. */
  1070.         if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS) {
  1071.                 word4 |= r600_get_swizzle_combined(desc->swizzle, swizzle_view, FALSE);
  1072.         }
  1073.  
  1074.         /* Colorspace (return non-RGB formats directly). */
  1075.         switch (desc->colorspace) {
  1076.         /* Depth stencil formats */
  1077.         case UTIL_FORMAT_COLORSPACE_ZS:
  1078.                 switch (format) {
  1079.                 /* Depth sampler formats. */
  1080.                 case PIPE_FORMAT_Z16_UNORM:
  1081.                         word4 |= r600_get_swizzle_combined(swizzle_xxxx, swizzle_view, FALSE);
  1082.                         result = FMT_16;
  1083.                         goto out_word4;
  1084.                 case PIPE_FORMAT_Z24X8_UNORM:
  1085.                 case PIPE_FORMAT_Z24_UNORM_S8_UINT:
  1086.                         word4 |= r600_get_swizzle_combined(swizzle_xxxx, swizzle_view, FALSE);
  1087.                         result = FMT_8_24;
  1088.                         goto out_word4;
  1089.                 case PIPE_FORMAT_X8Z24_UNORM:
  1090.                 case PIPE_FORMAT_S8_UINT_Z24_UNORM:
  1091.                         if (rscreen->chip_class < EVERGREEN)
  1092.                                 goto out_unknown;
  1093.                         word4 |= r600_get_swizzle_combined(swizzle_yyyy, swizzle_view, FALSE);
  1094.                         result = FMT_24_8;
  1095.                         goto out_word4;
  1096.                 case PIPE_FORMAT_Z32_FLOAT:
  1097.                         word4 |= r600_get_swizzle_combined(swizzle_xxxx, swizzle_view, FALSE);
  1098.                         result = FMT_32_FLOAT;
  1099.                         goto out_word4;
  1100.                 case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
  1101.                         word4 |= r600_get_swizzle_combined(swizzle_xxxx, swizzle_view, FALSE);
  1102.                         result = FMT_X24_8_32_FLOAT;
  1103.                         goto out_word4;
  1104.                 /* Stencil sampler formats. */
  1105.                 case PIPE_FORMAT_S8_UINT:
  1106.                         word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT);
  1107.                         word4 |= r600_get_swizzle_combined(swizzle_xxxx, swizzle_view, FALSE);
  1108.                         result = FMT_8;
  1109.                         goto out_word4;
  1110.                 case PIPE_FORMAT_X24S8_UINT:
  1111.                         word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT);
  1112.                         word4 |= r600_get_swizzle_combined(swizzle_yyyy, swizzle_view, FALSE);
  1113.                         result = FMT_8_24;
  1114.                         goto out_word4;
  1115.                 case PIPE_FORMAT_S8X24_UINT:
  1116.                         if (rscreen->chip_class < EVERGREEN)
  1117.                                 goto out_unknown;
  1118.                         word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT);
  1119.                         word4 |= r600_get_swizzle_combined(swizzle_xxxx, swizzle_view, FALSE);
  1120.                         result = FMT_24_8;
  1121.                         goto out_word4;
  1122.                 case PIPE_FORMAT_X32_S8X24_UINT:
  1123.                         word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT);
  1124.                         word4 |= r600_get_swizzle_combined(swizzle_yyyy, swizzle_view, FALSE);
  1125.                         result = FMT_X24_8_32_FLOAT;
  1126.                         goto out_word4;
  1127.                 default:
  1128.                         goto out_unknown;
  1129.                 }
  1130.  
  1131.         case UTIL_FORMAT_COLORSPACE_YUV:
  1132.                 yuv_format |= (1 << 30);
  1133.                 switch (format) {
  1134.                 case PIPE_FORMAT_UYVY:
  1135.                 case PIPE_FORMAT_YUYV:
  1136.                 default:
  1137.                         break;
  1138.                 }
  1139.                 goto out_unknown; /* XXX */
  1140.  
  1141.         case UTIL_FORMAT_COLORSPACE_SRGB:
  1142.                 word4 |= S_038010_FORCE_DEGAMMA(1);
  1143.                 break;
  1144.  
  1145.         default:
  1146.                 break;
  1147.         }
  1148.  
  1149.         if (desc->layout == UTIL_FORMAT_LAYOUT_RGTC) {
  1150.                 if (!enable_s3tc)
  1151.                         goto out_unknown;
  1152.  
  1153.                 switch (format) {
  1154.                 case PIPE_FORMAT_RGTC1_SNORM:
  1155.                 case PIPE_FORMAT_LATC1_SNORM:
  1156.                         word4 |= sign_bit[0];
  1157.                 case PIPE_FORMAT_RGTC1_UNORM:
  1158.                 case PIPE_FORMAT_LATC1_UNORM:
  1159.                         result = FMT_BC4;
  1160.                         goto out_word4;
  1161.                 case PIPE_FORMAT_RGTC2_SNORM:
  1162.                 case PIPE_FORMAT_LATC2_SNORM:
  1163.                         word4 |= sign_bit[0] | sign_bit[1];
  1164.                 case PIPE_FORMAT_RGTC2_UNORM:
  1165.                 case PIPE_FORMAT_LATC2_UNORM:
  1166.                         result = FMT_BC5;
  1167.                         goto out_word4;
  1168.                 default:
  1169.                         goto out_unknown;
  1170.                 }
  1171.         }
  1172.  
  1173.         if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
  1174.  
  1175.                 if (!enable_s3tc)
  1176.                         goto out_unknown;
  1177.  
  1178.                 if (!util_format_s3tc_enabled) {
  1179.                         goto out_unknown;
  1180.                 }
  1181.  
  1182.                 switch (format) {
  1183.                 case PIPE_FORMAT_DXT1_RGB:
  1184.                 case PIPE_FORMAT_DXT1_RGBA:
  1185.                 case PIPE_FORMAT_DXT1_SRGB:
  1186.                 case PIPE_FORMAT_DXT1_SRGBA:
  1187.                         result = FMT_BC1;
  1188.                         is_srgb_valid = TRUE;
  1189.                         goto out_word4;
  1190.                 case PIPE_FORMAT_DXT3_RGBA:
  1191.                 case PIPE_FORMAT_DXT3_SRGBA:
  1192.                         result = FMT_BC2;
  1193.                         is_srgb_valid = TRUE;
  1194.                         goto out_word4;
  1195.                 case PIPE_FORMAT_DXT5_RGBA:
  1196.                 case PIPE_FORMAT_DXT5_SRGBA:
  1197.                         result = FMT_BC3;
  1198.                         is_srgb_valid = TRUE;
  1199.                         goto out_word4;
  1200.                 default:
  1201.                         goto out_unknown;
  1202.                 }
  1203.         }
  1204.  
  1205.         if (desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED) {
  1206.                 switch (format) {
  1207.                 case PIPE_FORMAT_R8G8_B8G8_UNORM:
  1208.                 case PIPE_FORMAT_G8R8_B8R8_UNORM:
  1209.                         result = FMT_GB_GR;
  1210.                         goto out_word4;
  1211.                 case PIPE_FORMAT_G8R8_G8B8_UNORM:
  1212.                 case PIPE_FORMAT_R8G8_R8B8_UNORM:
  1213.                         result = FMT_BG_RG;
  1214.                         goto out_word4;
  1215.                 default:
  1216.                         goto out_unknown;
  1217.                 }
  1218.         }
  1219.  
  1220.         if (format == PIPE_FORMAT_R9G9B9E5_FLOAT) {
  1221.                 result = FMT_5_9_9_9_SHAREDEXP;
  1222.                 goto out_word4;
  1223.         } else if (format == PIPE_FORMAT_R11G11B10_FLOAT) {
  1224.                 result = FMT_10_11_11_FLOAT;
  1225.                 goto out_word4;
  1226.         }
  1227.  
  1228.  
  1229.         for (i = 0; i < desc->nr_channels; i++) {
  1230.                 if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) {
  1231.                         word4 |= sign_bit[i];
  1232.                 }
  1233.         }
  1234.  
  1235.         /* R8G8Bx_SNORM - XXX CxV8U8 */
  1236.  
  1237.         /* See whether the components are of the same size. */
  1238.         for (i = 1; i < desc->nr_channels; i++) {
  1239.                 uniform = uniform && desc->channel[0].size == desc->channel[i].size;
  1240.         }
  1241.  
  1242.         /* Non-uniform formats. */
  1243.         if (!uniform) {
  1244.                 if (desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB &&
  1245.                     desc->channel[0].pure_integer)
  1246.                         word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT);
  1247.                 switch(desc->nr_channels) {
  1248.                 case 3:
  1249.                         if (desc->channel[0].size == 5 &&
  1250.                             desc->channel[1].size == 6 &&
  1251.                             desc->channel[2].size == 5) {
  1252.                                 result = FMT_5_6_5;
  1253.                                 goto out_word4;
  1254.                         }
  1255.                         goto out_unknown;
  1256.                 case 4:
  1257.                         if (desc->channel[0].size == 5 &&
  1258.                             desc->channel[1].size == 5 &&
  1259.                             desc->channel[2].size == 5 &&
  1260.                             desc->channel[3].size == 1) {
  1261.                                 result = FMT_1_5_5_5;
  1262.                                 goto out_word4;
  1263.                         }
  1264.                         if (desc->channel[0].size == 10 &&
  1265.                             desc->channel[1].size == 10 &&
  1266.                             desc->channel[2].size == 10 &&
  1267.                             desc->channel[3].size == 2) {
  1268.                                 result = FMT_2_10_10_10;
  1269.                                 goto out_word4;
  1270.                         }
  1271.                         goto out_unknown;
  1272.                 }
  1273.                 goto out_unknown;
  1274.         }
  1275.  
  1276.         /* Find the first non-VOID channel. */
  1277.         for (i = 0; i < 4; i++) {
  1278.                 if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) {
  1279.                         break;
  1280.                 }
  1281.         }
  1282.  
  1283.         if (i == 4)
  1284.                 goto out_unknown;
  1285.  
  1286.         /* uniform formats */
  1287.         switch (desc->channel[i].type) {
  1288.         case UTIL_FORMAT_TYPE_UNSIGNED:
  1289.         case UTIL_FORMAT_TYPE_SIGNED:
  1290. #if 0
  1291.                 if (!desc->channel[i].normalized &&
  1292.                     desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB) {
  1293.                         goto out_unknown;
  1294.                 }
  1295. #endif
  1296.                 if (desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB &&
  1297.                     desc->channel[i].pure_integer)
  1298.                         word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT);
  1299.  
  1300.                 switch (desc->channel[i].size) {
  1301.                 case 4:
  1302.                         switch (desc->nr_channels) {
  1303.                         case 2:
  1304.                                 result = FMT_4_4;
  1305.                                 goto out_word4;
  1306.                         case 4:
  1307.                                 result = FMT_4_4_4_4;
  1308.                                 goto out_word4;
  1309.                         }
  1310.                         goto out_unknown;
  1311.                 case 8:
  1312.                         switch (desc->nr_channels) {
  1313.                         case 1:
  1314.                                 result = FMT_8;
  1315.                                 goto out_word4;
  1316.                         case 2:
  1317.                                 result = FMT_8_8;
  1318.                                 goto out_word4;
  1319.                         case 4:
  1320.                                 result = FMT_8_8_8_8;
  1321.                                 is_srgb_valid = TRUE;
  1322.                                 goto out_word4;
  1323.                         }
  1324.                         goto out_unknown;
  1325.                 case 16:
  1326.                         switch (desc->nr_channels) {
  1327.                         case 1:
  1328.                                 result = FMT_16;
  1329.                                 goto out_word4;
  1330.                         case 2:
  1331.                                 result = FMT_16_16;
  1332.                                 goto out_word4;
  1333.                         case 4:
  1334.                                 result = FMT_16_16_16_16;
  1335.                                 goto out_word4;
  1336.                         }
  1337.                         goto out_unknown;
  1338.                 case 32:
  1339.                         switch (desc->nr_channels) {
  1340.                         case 1:
  1341.                                 result = FMT_32;
  1342.                                 goto out_word4;
  1343.                         case 2:
  1344.                                 result = FMT_32_32;
  1345.                                 goto out_word4;
  1346.                         case 4:
  1347.                                 result = FMT_32_32_32_32;
  1348.                                 goto out_word4;
  1349.                         }
  1350.                 }
  1351.                 goto out_unknown;
  1352.  
  1353.         case UTIL_FORMAT_TYPE_FLOAT:
  1354.                 switch (desc->channel[i].size) {
  1355.                 case 16:
  1356.                         switch (desc->nr_channels) {
  1357.                         case 1:
  1358.                                 result = FMT_16_FLOAT;
  1359.                                 goto out_word4;
  1360.                         case 2:
  1361.                                 result = FMT_16_16_FLOAT;
  1362.                                 goto out_word4;
  1363.                         case 4:
  1364.                                 result = FMT_16_16_16_16_FLOAT;
  1365.                                 goto out_word4;
  1366.                         }
  1367.                         goto out_unknown;
  1368.                 case 32:
  1369.                         switch (desc->nr_channels) {
  1370.                         case 1:
  1371.                                 result = FMT_32_FLOAT;
  1372.                                 goto out_word4;
  1373.                         case 2:
  1374.                                 result = FMT_32_32_FLOAT;
  1375.                                 goto out_word4;
  1376.                         case 4:
  1377.                                 result = FMT_32_32_32_32_FLOAT;
  1378.                                 goto out_word4;
  1379.                         }
  1380.                 }
  1381.                 goto out_unknown;
  1382.         }
  1383.  
  1384. out_word4:
  1385.  
  1386.         if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB && !is_srgb_valid)
  1387.                 return ~0;
  1388.         if (word4_p)
  1389.                 *word4_p = word4;
  1390.         if (yuv_format_p)
  1391.                 *yuv_format_p = yuv_format;
  1392.         return result;
  1393. out_unknown:
  1394.         /* R600_ERR("Unable to handle texformat %d %s\n", format, util_format_name(format)); */
  1395.         return ~0;
  1396. }
  1397.  
  1398. static const struct u_resource_vtbl r600_texture_vtbl =
  1399. {
  1400.         r600_texture_get_handle,        /* get_handle */
  1401.         r600_texture_destroy,           /* resource_destroy */
  1402.         r600_texture_transfer_map,      /* transfer_map */
  1403.         NULL,                           /* transfer_flush_region */
  1404.         r600_texture_transfer_unmap,    /* transfer_unmap */
  1405.         NULL                            /* transfer_inline_write */
  1406. };
  1407.