nv30/shader: SSG, LIT only requires one source register
[mesa.git] / src / gallium / drivers / r600 / r600_texture.c
index 4687f7ef3c189a4092209a8672a5cae1521a4670..4673d86fd02d71089d12f4cf42793cadfa843eef 100644 (file)
  *      Jerome Glisse
  *      Corbin Simpson
  */
+#include "r600_formats.h"
+#include "r600d.h"
+
 #include <errno.h>
-#include "pipe/p_screen.h"
-#include "util/u_format.h"
 #include "util/u_format_s3tc.h"
-#include "util/u_math.h"
-#include "util/u_inlines.h"
 #include "util/u_memory.h"
-#include "pipebuffer/pb_buffer.h"
-#include "r600_pipe.h"
-#include "r600_resource.h"
-#include "r600d.h"
-#include "r600_formats.h"
 
 /* Copy from a full GPU texture to a transfer's staging one. */
 static void r600_copy_to_staging_texture(struct pipe_context *ctx, struct r600_transfer *rtransfer)
@@ -43,7 +37,7 @@ static void r600_copy_to_staging_texture(struct pipe_context *ctx, struct r600_t
        struct pipe_transfer *transfer = (struct pipe_transfer*)rtransfer;
        struct pipe_resource *texture = transfer->resource;
 
-       ctx->resource_copy_region(ctx, &rtransfer->staging->b.b.b,
+       ctx->resource_copy_region(ctx, &rtransfer->staging->b.b,
                                0, 0, 0, 0, texture, transfer->level,
                                &transfer->box);
 }
@@ -63,7 +57,7 @@ static void r600_copy_from_staging_texture(struct pipe_context *ctx, struct r600
        sbox.depth = 1;
        ctx->resource_copy_region(ctx, texture, transfer->level,
                                  transfer->box.x, transfer->box.y, transfer->box.z,
-                                 &rtransfer->staging->b.b.b,
+                                 &rtransfer->staging->b.b,
                                  0, &sbox);
 }
 
@@ -72,7 +66,7 @@ unsigned r600_texture_get_offset(struct r600_resource_texture *rtex,
 {
        unsigned offset = rtex->offset[level];
 
-       switch (rtex->resource.b.b.b.target) {
+       switch (rtex->resource.b.b.target) {
        case PIPE_TEXTURE_3D:
        case PIPE_TEXTURE_CUBE:
        default:
@@ -169,7 +163,7 @@ static unsigned r600_texture_get_nblocksx(struct pipe_screen *screen,
                                          struct r600_resource_texture *rtex,
                                          unsigned level)
 {
-       struct pipe_resource *ptex = &rtex->resource.b.b.b;
+       struct pipe_resource *ptex = &rtex->resource.b.b;
        unsigned nblocksx, block_align, width;
        unsigned blocksize = util_format_get_blocksize(rtex->real_format);
 
@@ -189,7 +183,7 @@ static unsigned r600_texture_get_nblocksy(struct pipe_screen *screen,
                                          struct r600_resource_texture *rtex,
                                          unsigned level)
 {
-       struct pipe_resource *ptex = &rtex->resource.b.b.b;
+       struct pipe_resource *ptex = &rtex->resource.b.b;
        unsigned height, tile_height;
 
        height = mip_minify(ptex->height0, level);
@@ -214,7 +208,7 @@ static void r600_texture_set_array_mode(struct pipe_screen *screen,
                                        struct r600_resource_texture *rtex,
                                        unsigned level, unsigned array_mode)
 {
-       struct pipe_resource *ptex = &rtex->resource.b.b.b;
+       struct pipe_resource *ptex = &rtex->resource.b.b;
 
        switch (array_mode) {
        case V_0280A0_ARRAY_LINEAR_GENERAL:
@@ -317,7 +311,7 @@ static int r600_setup_surface(struct pipe_screen *screen,
                              unsigned array_mode,
                              unsigned pitch_in_bytes_override)
 {
-       struct pipe_resource *ptex = &rtex->resource.b.b.b;
+       struct pipe_resource *ptex = &rtex->resource.b.b;
        struct r600_screen *rscreen = (struct r600_screen*)screen;
        unsigned i;
        int r;
@@ -370,7 +364,7 @@ static void r600_setup_miptree(struct pipe_screen *screen,
                               struct r600_resource_texture *rtex,
                               unsigned array_mode)
 {
-       struct pipe_resource *ptex = &rtex->resource.b.b.b;
+       struct pipe_resource *ptex = &rtex->resource.b.b;
        enum chip_class chipc = ((struct r600_screen*)screen)->chip_class;
        unsigned size, layer_size, i, offset;
        unsigned nblocksx, nblocksy;
@@ -444,14 +438,7 @@ static boolean permit_hardware_blit(struct pipe_screen *screen,
                                 PIPE_BIND_SAMPLER_VIEW))
                return FALSE;
 
-       switch (res->usage) {
-       case PIPE_USAGE_STREAM:
-       case PIPE_USAGE_STAGING:
-               return FALSE;
-
-       default:
-               return TRUE;
-       }
+       return TRUE;
 }
 
 static boolean r600_texture_get_handle(struct pipe_screen* screen,
@@ -489,9 +476,9 @@ static const struct u_resource_vtbl r600_texture_vtbl =
        r600_texture_get_transfer,      /* get_transfer */
        r600_texture_transfer_destroy,  /* transfer_destroy */
        r600_texture_transfer_map,      /* transfer_map */
-       u_default_transfer_flush_region,/* transfer_flush_region */
+       NULL,                           /* transfer_flush_region */
        r600_texture_transfer_unmap,    /* transfer_unmap */
-       u_default_transfer_inline_write /* transfer_inline_write */
+       NULL                            /* transfer_inline_write */
 };
 
 static struct r600_resource_texture *
@@ -514,10 +501,10 @@ r600_texture_create_object(struct pipe_screen *screen,
                return NULL;
 
        resource = &rtex->resource;
-       resource->b.b.b = *base;
-       resource->b.b.vtbl = &r600_texture_vtbl;
-       pipe_reference_init(&resource->b.b.b.reference, 1);
-       resource->b.b.b.screen = screen;
+       resource->b.b = *base;
+       resource->b.vtbl = &r600_texture_vtbl;
+       pipe_reference_init(&resource->b.b.reference, 1);
+       resource->b.b.screen = screen;
        rtex->pitch_override = pitch_in_bytes_override;
        rtex->real_format = base->format;
 
@@ -586,7 +573,7 @@ r600_texture_create_object(struct pipe_screen *screen,
                stencil_align = r600_get_base_alignment(screen, rtex->stencil->real_format, array_mode);
                stencil_offset = align(rtex->size, stencil_align);
 
-               for (unsigned i = 0; i <= rtex->stencil->resource.b.b.b.last_level; i++)
+               for (unsigned i = 0; i <= rtex->stencil->resource.b.b.last_level; i++)
                        rtex->stencil->offset[i] += stencil_offset;
 
                rtex->size = stencil_offset + rtex->stencil->size;
@@ -594,7 +581,7 @@ r600_texture_create_object(struct pipe_screen *screen,
 
        /* Now create the backing buffer. */
        if (!buf && alloc_bo) {
-               struct pipe_resource *ptex = &rtex->resource.b.b.b;
+               struct pipe_resource *ptex = &rtex->resource.b.b;
                unsigned base_align = r600_get_base_alignment(screen, ptex->format, array_mode);
 
                if (rscreen->use_surface_alloc) {
@@ -630,12 +617,13 @@ struct pipe_resource *r600_texture_create(struct pipe_screen *screen,
        unsigned array_mode = 0;
        int r;
 
-       if (!(templ->flags & R600_RESOURCE_FLAG_TRANSFER) &&
-           !(templ->bind & PIPE_BIND_SCANOUT)) {
-               if (rscreen->use_surface_alloc) {
-                       if (permit_hardware_blit(screen, templ)) {
-                               array_mode = V_038000_ARRAY_2D_TILED_THIN1;
-                       }
+       if (!(templ->flags & R600_RESOURCE_FLAG_TRANSFER)) {
+               if (rscreen->use_surface_alloc &&
+                   !(templ->bind & PIPE_BIND_SCANOUT) &&
+                   templ->usage != PIPE_USAGE_STAGING &&
+                   templ->usage != PIPE_USAGE_STREAM &&
+                   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;
                }
@@ -664,8 +652,6 @@ static struct pipe_surface *r600_create_surface(struct pipe_context *pipe,
        assert(surf_tmpl->u.tex.first_layer == surf_tmpl->u.tex.last_layer);
        if (surface == NULL)
                return NULL;
-       /* XXX no offset */
-/*     offset = r600_texture_get_offset(rtex, level, surf_tmpl->u.tex.first_layer);*/
        pipe_reference_init(&surface->base.reference, 1);
        pipe_resource_reference(&surface->base.texture, texture);
        surface->base.context = pipe;
@@ -790,10 +776,6 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx,
        int r;
        boolean use_staging_texture = FALSE;
 
-       if (usage & PIPE_TRANSFER_MAP_PERMANENTLY) {
-          return NULL;
-       }
-
        /* We cannot map a tiled texture directly because the data is
         * in a different order, therefore we do detiling using a blit.
         *
@@ -809,7 +791,7 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx,
 
        /* Use a staging texture for uploads if the underlying BO is busy. */
        if (!(usage & PIPE_TRANSFER_READ) &&
-           (rctx->ws->cs_is_buffer_referenced(rctx->cs, rtex->resource.cs_buf) ||
+           (rctx->ws->cs_is_buffer_referenced(rctx->cs, rtex->resource.cs_buf, RADEON_USAGE_READWRITE) ||
             rctx->ws->buffer_is_busy(rtex->resource.buf, RADEON_USAGE_READWRITE)))
                use_staging_texture = TRUE;
 
@@ -916,20 +898,20 @@ void* r600_texture_transfer_map(struct pipe_context *ctx,
 {
        struct r600_context *rctx = (struct r600_context *)ctx;
        struct r600_transfer *rtransfer = (struct r600_transfer*)transfer;
-       struct pb_buffer *buf;
+       struct radeon_winsys_cs_handle *buf;
        enum pipe_format format = transfer->resource->format;
        unsigned offset = 0;
        char *map;
 
        if (rtransfer->staging) {
-               buf = ((struct r600_resource *)rtransfer->staging)->buf;
+               buf = ((struct r600_resource *)rtransfer->staging)->cs_buf;
        } else {
                struct r600_resource_texture *rtex = (struct r600_resource_texture*)transfer->resource;
 
                if (rtex->flushed_depth_texture)
-                       buf = ((struct r600_resource *)rtex->flushed_depth_texture)->buf;
+                       buf = ((struct r600_resource *)rtex->flushed_depth_texture)->cs_buf;
                else
-                       buf = ((struct r600_resource *)transfer->resource)->buf;
+                       buf = ((struct r600_resource *)transfer->resource)->cs_buf;
 
                offset = rtransfer->offset +
                        transfer->box.y / util_format_get_blockheight(format) * transfer->stride +
@@ -948,17 +930,17 @@ void r600_texture_transfer_unmap(struct pipe_context *ctx,
 {
        struct r600_transfer *rtransfer = (struct r600_transfer*)transfer;
        struct r600_context *rctx = (struct r600_context*)ctx;
-       struct pb_buffer *buf;
+       struct radeon_winsys_cs_handle *buf;
 
        if (rtransfer->staging) {
-               buf = ((struct r600_resource *)rtransfer->staging)->buf;
+               buf = ((struct r600_resource *)rtransfer->staging)->cs_buf;
        } else {
                struct r600_resource_texture *rtex = (struct r600_resource_texture*)transfer->resource;
 
                if (rtex->flushed_depth_texture) {
-                       buf = ((struct r600_resource *)rtex->flushed_depth_texture)->buf;
+                       buf = ((struct r600_resource *)rtex->flushed_depth_texture)->cs_buf;
                } else {
-                       buf = ((struct r600_resource *)transfer->resource)->buf;
+                       buf = ((struct r600_resource *)transfer->resource)->cs_buf;
                }
        }
        rctx->ws->buffer_unmap(buf);
@@ -1079,7 +1061,7 @@ uint32_t r600_translate_texformat(struct pipe_screen *screen,
                default:
                        break;
                }
-               goto out_unknown; /* TODO */
+               goto out_unknown; /* XXX */
 
        case UTIL_FORMAT_COLORSPACE_SRGB:
                word4 |= S_038010_FORCE_DEGAMMA(1);
@@ -1153,6 +1135,21 @@ uint32_t r600_translate_texformat(struct pipe_screen *screen,
                }
        }
 
+       if (desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED) {
+               switch (format) {
+               case PIPE_FORMAT_R8G8_B8G8_UNORM:
+               case PIPE_FORMAT_G8R8_B8R8_UNORM:
+                       result = FMT_GB_GR;
+                       goto out_word4;
+               case PIPE_FORMAT_G8R8_G8B8_UNORM:
+               case PIPE_FORMAT_R8G8_R8B8_UNORM:
+                       result = FMT_BG_RG;
+                       goto out_word4;
+               default:
+                       goto out_unknown;
+               }
+       }
+
        if (format == PIPE_FORMAT_R9G9B9E5_FLOAT) {
                result = FMT_5_9_9_9_SHAREDEXP;
                goto out_word4;
@@ -1168,7 +1165,7 @@ uint32_t r600_translate_texformat(struct pipe_screen *screen,
                }
        }
 
-       /* R8G8Bx_SNORM - TODO CxV8U8 */
+       /* R8G8Bx_SNORM - XXX CxV8U8 */
 
        /* See whether the components are of the same size. */
        for (i = 1; i < desc->nr_channels; i++) {