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