diff options
Diffstat (limited to 'src/gallium')
-rw-r--r-- | src/gallium/drivers/radeon/r600_texture.c | 120 | ||||
-rw-r--r-- | src/gallium/drivers/radeon/radeon_winsys.h | 33 | ||||
-rw-r--r-- | src/gallium/winsys/amdgpu/drm/amdgpu_surface.c | 146 | ||||
-rw-r--r-- | src/gallium/winsys/radeon/drm/radeon_drm_surface.c | 73 |
4 files changed, 179 insertions, 193 deletions
diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c index daa743e6c22..a89b2850e4c 100644 --- a/src/gallium/drivers/radeon/r600_texture.c +++ b/src/gallium/drivers/radeon/r600_texture.c @@ -203,65 +203,25 @@ static int r600_init_surface(struct r600_common_screen *rscreen, const struct util_format_description *desc = util_format_description(ptex->format); bool is_depth, is_stencil; - int r, i; + int r; + unsigned i, bpe, flags = 0; is_depth = util_format_has_depth(desc); is_stencil = util_format_has_stencil(desc); - surface->npix_x = ptex->width0; - surface->npix_y = ptex->height0; - surface->npix_z = ptex->depth0; - surface->blk_w = util_format_get_blockwidth(ptex->format); - surface->blk_h = util_format_get_blockheight(ptex->format); - surface->blk_d = 1; - surface->array_size = 1; - surface->last_level = ptex->last_level; - if (rscreen->chip_class >= EVERGREEN && !is_flushed_depth && ptex->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) { - surface->bpe = 4; /* stencil is allocated separately on evergreen */ + bpe = 4; /* stencil is allocated separately on evergreen */ } else { - surface->bpe = util_format_get_blocksize(ptex->format); + bpe = util_format_get_blocksize(ptex->format); /* align byte per element on dword */ - if (surface->bpe == 3) { - surface->bpe = 4; + if (bpe == 3) { + bpe = 4; } } - surface->nsamples = ptex->nr_samples ? ptex->nr_samples : 1; - surface->flags = RADEON_SURF_SET(array_mode, MODE); - - switch (ptex->target) { - case PIPE_TEXTURE_1D: - surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D, TYPE); - break; - case PIPE_TEXTURE_RECT: - case PIPE_TEXTURE_2D: - surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE); - break; - case PIPE_TEXTURE_3D: - surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_3D, TYPE); - break; - case PIPE_TEXTURE_1D_ARRAY: - surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D_ARRAY, TYPE); - surface->array_size = ptex->array_size; - break; - case PIPE_TEXTURE_CUBE_ARRAY: /* cube array layout like 2d array */ - assert(ptex->array_size % 6 == 0); - case PIPE_TEXTURE_2D_ARRAY: - surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D_ARRAY, TYPE); - surface->array_size = ptex->array_size; - break; - case PIPE_TEXTURE_CUBE: - surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_CUBEMAP, TYPE); - break; - case PIPE_BUFFER: - default: - return -EINVAL; - } - if (!is_flushed_depth && is_depth) { - surface->flags |= RADEON_SURF_ZBUFFER; + flags |= RADEON_SURF_ZBUFFER; if (tc_compatible_htile && array_mode == RADEON_SURF_MODE_2D) { @@ -269,24 +229,24 @@ static int r600_init_surface(struct r600_common_screen *rscreen, * Promote Z16 to Z32. DB->CB copies will convert * the format for transfers. */ - surface->bpe = 4; - surface->flags |= RADEON_SURF_TC_COMPATIBLE_HTILE; + bpe = 4; + flags |= RADEON_SURF_TC_COMPATIBLE_HTILE; } if (is_stencil) { - surface->flags |= RADEON_SURF_SBUFFER | - RADEON_SURF_HAS_SBUFFER_MIPTREE; + flags |= RADEON_SURF_SBUFFER | + RADEON_SURF_HAS_SBUFFER_MIPTREE; } } if (rscreen->chip_class >= SI) { - surface->flags |= RADEON_SURF_HAS_TILE_MODE_INDEX; + flags |= RADEON_SURF_HAS_TILE_MODE_INDEX; } if (rscreen->chip_class >= VI && (ptex->flags & R600_RESOURCE_FLAG_DISABLE_DCC || ptex->format == PIPE_FORMAT_R9G9B9E5_FLOAT)) - surface->flags |= RADEON_SURF_DISABLE_DCC; + flags |= RADEON_SURF_DISABLE_DCC; if (ptex->bind & PIPE_BIND_SCANOUT || is_scanout) { /* This should catch bugs in gallium users setting incorrect flags. */ @@ -294,15 +254,16 @@ static int r600_init_surface(struct r600_common_screen *rscreen, ptex->array_size == 1 && ptex->depth0 == 1 && ptex->last_level == 0 && - !(surface->flags & RADEON_SURF_Z_OR_SBUFFER)); + !(flags & RADEON_SURF_Z_OR_SBUFFER)); - surface->flags |= RADEON_SURF_SCANOUT; + flags |= RADEON_SURF_SCANOUT; } if (is_imported) - surface->flags |= RADEON_SURF_IMPORTED; + flags |= RADEON_SURF_IMPORTED; - r = rscreen->ws->surface_init(rscreen->ws, surface); + r = rscreen->ws->surface_init(rscreen->ws, ptex, flags, bpe, + array_mode, surface); if (r) { return r; } @@ -311,7 +272,7 @@ static int r600_init_surface(struct r600_common_screen *rscreen, /* old ddx on evergreen over estimate alignment for 1d, only 1 level * for those */ - surface->level[0].nblk_x = pitch_in_bytes_override / surface->bpe; + surface->level[0].nblk_x = pitch_in_bytes_override / bpe; surface->level[0].pitch_bytes = pitch_in_bytes_override; surface->level[0].slice_size = pitch_in_bytes_override * surface->level[0].nblk_y; } @@ -629,35 +590,35 @@ void r600_texture_get_fmask_info(struct r600_common_screen *rscreen, struct r600_fmask_info *out) { /* FMASK is allocated like an ordinary texture. */ - struct radeon_surf fmask = rtex->surface; + struct pipe_resource templ = rtex->resource.b.b; + struct radeon_surf fmask = {}; + unsigned flags, bpe; memset(out, 0, sizeof(*out)); - fmask.bo_alignment = 0; - fmask.bo_size = 0; - fmask.nsamples = 1; - fmask.flags |= RADEON_SURF_FMASK; + templ.nr_samples = 1; + flags = rtex->surface.flags | RADEON_SURF_FMASK; - /* Force 2D tiling if it wasn't set. This may occur when creating - * FMASK for MSAA resolve on R6xx. On R6xx, the single-sample - * destination buffer must have an FMASK too. */ - fmask.flags = RADEON_SURF_CLR(fmask.flags, MODE); - fmask.flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE); + /* Use the same parameters and tile mode. */ + fmask.bankw = rtex->surface.bankw; + fmask.bankh = rtex->surface.bankh; + fmask.mtilea = rtex->surface.mtilea; + fmask.tile_split = rtex->surface.tile_split; if (rscreen->chip_class >= SI) { - fmask.flags |= RADEON_SURF_HAS_TILE_MODE_INDEX; + flags |= RADEON_SURF_HAS_TILE_MODE_INDEX; } switch (nr_samples) { case 2: case 4: - fmask.bpe = 1; + bpe = 1; if (rscreen->chip_class <= CAYMAN) { fmask.bankh = 4; } break; case 8: - fmask.bpe = 4; + bpe = 4; break; default: R600_ERR("Invalid sample count for FMASK allocation.\n"); @@ -668,10 +629,11 @@ void r600_texture_get_fmask_info(struct r600_common_screen *rscreen, * This can be fixed by writing a separate FMASK allocator specifically * for R600-R700 asics. */ if (rscreen->chip_class <= R700) { - fmask.bpe *= 2; + bpe *= 2; } - if (rscreen->ws->surface_init(rscreen->ws, &fmask)) { + if (rscreen->ws->surface_init(rscreen->ws, &templ, flags, bpe, + RADEON_SURF_MODE_2D, &fmask)) { R600_ERR("Got error in surface_init while allocating FMASK.\n"); return; } @@ -958,13 +920,13 @@ void r600_print_texture_info(struct r600_texture *rtex, FILE *f) int i; fprintf(f, " Info: npix_x=%u, npix_y=%u, npix_z=%u, blk_w=%u, " - "blk_h=%u, blk_d=%u, array_size=%u, last_level=%u, " + "blk_h=%u, array_size=%u, last_level=%u, " "bpe=%u, nsamples=%u, flags=0x%x, %s\n", - rtex->surface.npix_x, rtex->surface.npix_y, - rtex->surface.npix_z, rtex->surface.blk_w, - rtex->surface.blk_h, rtex->surface.blk_d, - rtex->surface.array_size, rtex->surface.last_level, - rtex->surface.bpe, rtex->surface.nsamples, + rtex->resource.b.b.width0, rtex->resource.b.b.height0, + rtex->resource.b.b.depth0, rtex->surface.blk_w, + rtex->surface.blk_h, + rtex->resource.b.b.array_size, rtex->resource.b.b.last_level, + rtex->surface.bpe, rtex->resource.b.b.nr_samples, rtex->surface.flags, util_format_short_name(rtex->resource.b.b.format)); fprintf(f, " Layout: size=%"PRIu64", alignment=%"PRIu64", bankw=%u, " diff --git a/src/gallium/drivers/radeon/radeon_winsys.h b/src/gallium/drivers/radeon/radeon_winsys.h index 3bd141ee510..4b79752c7e9 100644 --- a/src/gallium/drivers/radeon/radeon_winsys.h +++ b/src/gallium/drivers/radeon/radeon_winsys.h @@ -263,16 +263,7 @@ enum radeon_surf_mode { RADEON_SURF_MODE_2D = 3, }; -#define RADEON_SURF_TYPE_MASK 0xFF -#define RADEON_SURF_TYPE_SHIFT 0 -#define RADEON_SURF_TYPE_1D 0 -#define RADEON_SURF_TYPE_2D 1 -#define RADEON_SURF_TYPE_3D 2 -#define RADEON_SURF_TYPE_CUBEMAP 3 -#define RADEON_SURF_TYPE_1D_ARRAY 4 -#define RADEON_SURF_TYPE_2D_ARRAY 5 -#define RADEON_SURF_MODE_MASK 0xFF -#define RADEON_SURF_MODE_SHIFT 8 +/* the first 16 bits are reserved for libdrm_radeon, don't use them */ #define RADEON_SURF_SCANOUT (1 << 16) #define RADEON_SURF_ZBUFFER (1 << 17) #define RADEON_SURF_SBUFFER (1 << 18) @@ -284,10 +275,6 @@ enum radeon_surf_mode { #define RADEON_SURF_TC_COMPATIBLE_HTILE (1 << 23) #define RADEON_SURF_IMPORTED (1 << 24) -#define RADEON_SURF_GET(v, field) (((v) >> RADEON_SURF_ ## field ## _SHIFT) & RADEON_SURF_ ## field ## _MASK) -#define RADEON_SURF_SET(v, field) (((v) & RADEON_SURF_ ## field ## _MASK) << RADEON_SURF_ ## field ## _SHIFT) -#define RADEON_SURF_CLR(v, field) ((v) & ~(RADEON_SURF_ ## field ## _MASK << RADEON_SURF_ ## field ## _SHIFT)) - struct radeon_surf_level { uint64_t offset; uint64_t slice_size; @@ -305,17 +292,10 @@ struct radeon_surf_level { }; struct radeon_surf { - /* These are inputs to the calculator. */ - uint32_t npix_x; - uint32_t npix_y; - uint32_t npix_z; + /* Format properties. */ uint32_t blk_w; uint32_t blk_h; - uint32_t blk_d; - uint32_t array_size; - uint32_t last_level; uint32_t bpe; - uint32_t nsamples; uint32_t flags; /* These are return values. Some of them can be set by the caller, but @@ -743,9 +723,16 @@ struct radeon_winsys { * Initialize surface * * \param ws The winsys this function is called from. - * \param surf Surface structure ptr + * \param tex Input texture description + * \param flags Bitmask of RADEON_SURF_* flags + * \param bpe Bytes per pixel, it can be different for Z buffers. + * \param mode Preferred tile mode. (linear, 1D, or 2D) + * \param surf Output structure */ int (*surface_init)(struct radeon_winsys *ws, + const struct pipe_resource *tex, + unsigned flags, unsigned bpe, + enum radeon_surf_mode mode, struct radeon_surf *surf); uint64_t (*query_value)(struct radeon_winsys *ws, diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c b/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c index 94fe7d6d78c..3b4c13b6baf 100644 --- a/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c @@ -30,28 +30,22 @@ */ #include "amdgpu_winsys.h" +#include "util/u_format.h" #ifndef CIASICIDGFXENGINE_SOUTHERNISLAND #define CIASICIDGFXENGINE_SOUTHERNISLAND 0x0000000A #endif -static int amdgpu_surface_sanity(const struct radeon_surf *surf) +static int amdgpu_surface_sanity(const struct pipe_resource *tex) { - unsigned type = RADEON_SURF_GET(surf->flags, TYPE); - - if (!(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX)) - return -EINVAL; - /* all dimension must be at least 1 ! */ - if (!surf->npix_x || !surf->npix_y || !surf->npix_z || - !surf->array_size) + if (!tex->width0 || !tex->height0 || !tex->depth0 || + !tex->array_size) return -EINVAL; - if (!surf->blk_w || !surf->blk_h || !surf->blk_d) - return -EINVAL; - - switch (surf->nsamples) { + switch (tex->nr_samples) { + case 0: case 1: case 2: case 4: @@ -61,26 +55,28 @@ static int amdgpu_surface_sanity(const struct radeon_surf *surf) return -EINVAL; } - switch (type) { - case RADEON_SURF_TYPE_1D: - if (surf->npix_y > 1) + switch (tex->target) { + case PIPE_TEXTURE_1D: + if (tex->height0 > 1) return -EINVAL; /* fall through */ - case RADEON_SURF_TYPE_2D: - case RADEON_SURF_TYPE_CUBEMAP: - if (surf->npix_z > 1 || surf->array_size > 1) + case PIPE_TEXTURE_2D: + case PIPE_TEXTURE_RECT: + if (tex->depth0 > 1 || tex->array_size > 1) return -EINVAL; break; - case RADEON_SURF_TYPE_3D: - if (surf->array_size > 1) + case PIPE_TEXTURE_3D: + if (tex->array_size > 1) return -EINVAL; break; - case RADEON_SURF_TYPE_1D_ARRAY: - if (surf->npix_y > 1) + case PIPE_TEXTURE_1D_ARRAY: + if (tex->height0 > 1) return -EINVAL; /* fall through */ - case RADEON_SURF_TYPE_2D_ARRAY: - if (surf->npix_z > 1) + case PIPE_TEXTURE_CUBE: + case PIPE_TEXTURE_2D_ARRAY: + case PIPE_TEXTURE_CUBE_ARRAY: + if (tex->depth0 > 1) return -EINVAL; break; default: @@ -148,8 +144,9 @@ ADDR_HANDLE amdgpu_addr_create(struct amdgpu_winsys *ws) } static int compute_level(struct amdgpu_winsys *ws, + const struct pipe_resource *tex, struct radeon_surf *surf, bool is_stencil, - unsigned level, unsigned type, bool compressed, + unsigned level, bool compressed, ADDR_COMPUTE_SURFACE_INFO_INPUT *AddrSurfInfoIn, ADDR_COMPUTE_SURFACE_INFO_OUTPUT *AddrSurfInfoOut, ADDR_COMPUTE_DCCINFO_INPUT *AddrDccIn, @@ -161,15 +158,15 @@ static int compute_level(struct amdgpu_winsys *ws, ADDR_E_RETURNCODE ret; AddrSurfInfoIn->mipLevel = level; - AddrSurfInfoIn->width = u_minify(surf->npix_x, level); - AddrSurfInfoIn->height = u_minify(surf->npix_y, level); + AddrSurfInfoIn->width = u_minify(tex->width0, level); + AddrSurfInfoIn->height = u_minify(tex->height0, level); - if (type == RADEON_SURF_TYPE_3D) - AddrSurfInfoIn->numSlices = u_minify(surf->npix_z, level); - else if (type == RADEON_SURF_TYPE_CUBEMAP) + if (tex->target == PIPE_TEXTURE_3D) + AddrSurfInfoIn->numSlices = u_minify(tex->depth0, level); + else if (tex->target == PIPE_TEXTURE_CUBE) AddrSurfInfoIn->numSlices = 6; else - AddrSurfInfoIn->numSlices = surf->array_size; + AddrSurfInfoIn->numSlices = tex->array_size; if (level > 0) { /* Set the base level pitch. This is needed for calculation @@ -195,12 +192,12 @@ static int compute_level(struct amdgpu_winsys *ws, surf_level->offset = align64(surf->bo_size, AddrSurfInfoOut->baseAlign); surf_level->slice_size = AddrSurfInfoOut->sliceSize; surf_level->pitch_bytes = AddrSurfInfoOut->pitch * (is_stencil ? 1 : surf->bpe); - surf_level->npix_x = u_minify(surf->npix_x, level); - surf_level->npix_y = u_minify(surf->npix_y, level); - surf_level->npix_z = u_minify(surf->npix_z, level); + surf_level->npix_x = u_minify(tex->width0, level); + surf_level->npix_y = u_minify(tex->height0, level); + surf_level->npix_z = u_minify(tex->depth0, level); surf_level->nblk_x = AddrSurfInfoOut->pitch; surf_level->nblk_y = AddrSurfInfoOut->height; - if (type == RADEON_SURF_TYPE_3D) + if (tex->target == PIPE_TEXTURE_3D) surf_level->nblk_z = AddrSurfInfoOut->depth; else surf_level->nblk_z = 1; @@ -310,10 +307,13 @@ static unsigned cik_get_macro_tile_index(struct radeon_surf *surf) } static int amdgpu_surface_init(struct radeon_winsys *rws, + const struct pipe_resource *tex, + unsigned flags, unsigned bpe, + enum radeon_surf_mode mode, struct radeon_surf *surf) { struct amdgpu_winsys *ws = (struct amdgpu_winsys*)rws; - unsigned level, mode, type; + unsigned level; bool compressed; ADDR_COMPUTE_SURFACE_INFO_INPUT AddrSurfInfoIn = {0}; ADDR_COMPUTE_SURFACE_INFO_OUTPUT AddrSurfInfoOut = {0}; @@ -325,7 +325,7 @@ static int amdgpu_surface_init(struct radeon_winsys *rws, ADDR_TILEINFO AddrTileInfoOut = {0}; int r; - r = amdgpu_surface_sanity(surf); + r = amdgpu_surface_sanity(tex); if (r) return r; @@ -337,17 +337,20 @@ static int amdgpu_surface_init(struct radeon_winsys *rws, AddrHtileOut.size = sizeof(ADDR_COMPUTE_HTILE_INFO_OUTPUT); AddrSurfInfoOut.pTileInfo = &AddrTileInfoOut; - type = RADEON_SURF_GET(surf->flags, TYPE); - mode = RADEON_SURF_GET(surf->flags, MODE); + surf->blk_w = util_format_get_blockwidth(tex->format); + surf->blk_h = util_format_get_blockheight(tex->format); + surf->bpe = bpe; + surf->flags = flags; + compressed = surf->blk_w == 4 && surf->blk_h == 4; /* MSAA and FMASK require 2D tiling. */ - if (surf->nsamples > 1 || - (surf->flags & RADEON_SURF_FMASK)) + if (tex->nr_samples > 1 || + (flags & RADEON_SURF_FMASK)) mode = RADEON_SURF_MODE_2D; /* DB doesn't support linear layouts. */ - if (surf->flags & (RADEON_SURF_Z_OR_SBUFFER) && + if (flags & (RADEON_SURF_Z_OR_SBUFFER) && mode < RADEON_SURF_MODE_1D) mode = RADEON_SURF_MODE_1D; @@ -369,7 +372,7 @@ static int amdgpu_surface_init(struct radeon_winsys *rws, /* The format must be set correctly for the allocation of compressed * textures to work. In other cases, setting the bpp is sufficient. */ if (compressed) { - switch (surf->bpe) { + switch (bpe) { case 8: AddrSurfInfoIn.format = ADDR_FMT_BC1; break; @@ -381,26 +384,27 @@ static int amdgpu_surface_init(struct radeon_winsys *rws, } } else { - AddrDccIn.bpp = AddrSurfInfoIn.bpp = surf->bpe * 8; + AddrDccIn.bpp = AddrSurfInfoIn.bpp = bpe * 8; } - AddrDccIn.numSamples = AddrSurfInfoIn.numSamples = surf->nsamples; + AddrDccIn.numSamples = AddrSurfInfoIn.numSamples = + tex->nr_samples ? tex->nr_samples : 1; AddrSurfInfoIn.tileIndex = -1; /* Set the micro tile type. */ - if (surf->flags & RADEON_SURF_SCANOUT) + if (flags & RADEON_SURF_SCANOUT) AddrSurfInfoIn.tileType = ADDR_DISPLAYABLE; - else if (surf->flags & RADEON_SURF_Z_OR_SBUFFER) + else if (flags & RADEON_SURF_Z_OR_SBUFFER) AddrSurfInfoIn.tileType = ADDR_DEPTH_SAMPLE_ORDER; else AddrSurfInfoIn.tileType = ADDR_NON_DISPLAYABLE; - AddrSurfInfoIn.flags.color = !(surf->flags & RADEON_SURF_Z_OR_SBUFFER); - AddrSurfInfoIn.flags.depth = (surf->flags & RADEON_SURF_ZBUFFER) != 0; - AddrSurfInfoIn.flags.cube = type == RADEON_SURF_TYPE_CUBEMAP; - AddrSurfInfoIn.flags.display = (surf->flags & RADEON_SURF_SCANOUT) != 0; - AddrSurfInfoIn.flags.pow2Pad = surf->last_level > 0; - AddrSurfInfoIn.flags.tcCompatible = (surf->flags & RADEON_SURF_TC_COMPATIBLE_HTILE) != 0; + AddrSurfInfoIn.flags.color = !(flags & RADEON_SURF_Z_OR_SBUFFER); + AddrSurfInfoIn.flags.depth = (flags & RADEON_SURF_ZBUFFER) != 0; + AddrSurfInfoIn.flags.cube = tex->target == PIPE_TEXTURE_CUBE; + AddrSurfInfoIn.flags.display = (flags & RADEON_SURF_SCANOUT) != 0; + AddrSurfInfoIn.flags.pow2Pad = tex->last_level > 0; + AddrSurfInfoIn.flags.tcCompatible = (flags & RADEON_SURF_TC_COMPATIBLE_HTILE) != 0; /* Only degrade the tile mode for space if TC-compatible HTILE hasn't been * requested, because TC-compatible HTILE requires 2D tiling. @@ -414,13 +418,13 @@ static int amdgpu_surface_init(struct radeon_winsys *rws, * driver team). */ AddrSurfInfoIn.flags.dccCompatible = ws->info.chip_class >= VI && - !(surf->flags & RADEON_SURF_Z_OR_SBUFFER) && - !(surf->flags & RADEON_SURF_DISABLE_DCC) && + !(flags & RADEON_SURF_Z_OR_SBUFFER) && + !(flags & RADEON_SURF_DISABLE_DCC) && !compressed && AddrDccIn.numSamples <= 1 && - ((surf->array_size == 1 && surf->npix_z == 1) || - surf->last_level == 0); + ((tex->array_size == 1 && tex->depth0 == 1) || + tex->last_level == 0); - AddrSurfInfoIn.flags.noStencil = (surf->flags & RADEON_SURF_SBUFFER) == 0; + AddrSurfInfoIn.flags.noStencil = (flags & RADEON_SURF_SBUFFER) == 0; AddrSurfInfoIn.flags.compressZ = AddrSurfInfoIn.flags.depth; /* noStencil = 0 can result in a depth part that is incompatible with @@ -430,7 +434,7 @@ static int amdgpu_surface_init(struct radeon_winsys *rws, * TODO: update addrlib to a newer version, remove this, and * use flags.matchStencilTileCfg = 1 as an alternative fix. */ - if (surf->last_level > 0) + if (tex->last_level > 0) AddrSurfInfoIn.flags.noStencil = 1; /* Set preferred macrotile parameters. This is usually required @@ -456,21 +460,21 @@ static int amdgpu_surface_init(struct radeon_winsys *rws, * For now, just figure it out here. * Note that only 2D_TILE_THIN1 is handled here. */ - assert(!(surf->flags & RADEON_SURF_Z_OR_SBUFFER)); + assert(!(flags & RADEON_SURF_Z_OR_SBUFFER)); assert(AddrSurfInfoIn.tileMode == ADDR_TM_2D_TILED_THIN1); if (ws->info.chip_class == SI) { if (AddrSurfInfoIn.tileType == ADDR_DISPLAYABLE) { - if (surf->bpe == 2) + if (bpe == 2) AddrSurfInfoIn.tileIndex = 11; /* 16bpp */ else AddrSurfInfoIn.tileIndex = 12; /* 32bpp */ } else { - if (surf->bpe == 1) + if (bpe == 1) AddrSurfInfoIn.tileIndex = 14; /* 8bpp */ - else if (surf->bpe == 2) + else if (bpe == 2) AddrSurfInfoIn.tileIndex = 15; /* 16bpp */ - else if (surf->bpe == 4) + else if (bpe == 4) AddrSurfInfoIn.tileIndex = 16; /* 32bpp */ else AddrSurfInfoIn.tileIndex = 17; /* 64bpp (and 128bpp) */ @@ -494,8 +498,8 @@ static int amdgpu_surface_init(struct radeon_winsys *rws, surf->htile_alignment = 1; /* Calculate texture layout information. */ - for (level = 0; level <= surf->last_level; level++) { - r = compute_level(ws, surf, false, level, type, compressed, + for (level = 0; level <= tex->last_level; level++) { + r = compute_level(ws, tex, surf, false, level, compressed, &AddrSurfInfoIn, &AddrSurfInfoOut, &AddrDccIn, &AddrDccOut, &AddrHtileIn, &AddrHtileOut); if (r) @@ -521,7 +525,7 @@ static int amdgpu_surface_init(struct radeon_winsys *rws, } /* Calculate texture layout information for stencil. */ - if (surf->flags & RADEON_SURF_SBUFFER) { + if (flags & RADEON_SURF_SBUFFER) { AddrSurfInfoIn.bpp = 8; AddrSurfInfoIn.flags.depth = 0; AddrSurfInfoIn.flags.stencil = 1; @@ -529,8 +533,8 @@ static int amdgpu_surface_init(struct radeon_winsys *rws, /* This will be ignored if AddrSurfInfoIn.pTileInfo is NULL. */ AddrTileInfoIn.tileSplitBytes = surf->stencil_tile_split; - for (level = 0; level <= surf->last_level; level++) { - r = compute_level(ws, surf, true, level, type, compressed, + for (level = 0; level <= tex->last_level; level++) { + r = compute_level(ws, tex, surf, true, level, compressed, &AddrSurfInfoIn, &AddrSurfInfoOut, &AddrDccIn, &AddrDccOut, NULL, NULL); if (r) @@ -554,7 +558,7 @@ static int amdgpu_surface_init(struct radeon_winsys *rws, * This is what addrlib does, but calling addrlib would be a lot more * complicated. */ - if (surf->dcc_size && surf->last_level > 0) { + if (surf->dcc_size && tex->last_level > 0) { surf->dcc_size = align64(surf->bo_size >> 8, ws->info.pipe_interleave_bytes * ws->info.num_tile_pipes); @@ -563,7 +567,7 @@ static int amdgpu_surface_init(struct radeon_winsys *rws, /* Make sure HTILE covers the whole miptree, because the shader reads * TC-compatible HTILE even for levels where it's disabled by DB. */ - if (surf->htile_size && surf->last_level) + if (surf->htile_size && tex->last_level) surf->htile_size *= 2; return 0; diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_surface.c b/src/gallium/winsys/radeon/drm/radeon_drm_surface.c index 8a88ee55490..fafcee1857b 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_surface.c +++ b/src/gallium/winsys/radeon/drm/radeon_drm_surface.c @@ -28,7 +28,7 @@ */ #include "radeon_drm_winsys.h" - +#include "util/u_format.h" #include <radeon_surface.h> static unsigned cik_get_macro_tile_index(struct radeon_surf *surf) @@ -97,23 +97,60 @@ static void surf_level_drm_to_winsys(struct radeon_surf_level *level_ws, } static void surf_winsys_to_drm(struct radeon_surface *surf_drm, + const struct pipe_resource *tex, + unsigned flags, unsigned bpe, + enum radeon_surf_mode mode, const struct radeon_surf *surf_ws) { int i; memset(surf_drm, 0, sizeof(*surf_drm)); - surf_drm->npix_x = surf_ws->npix_x; - surf_drm->npix_y = surf_ws->npix_y; - surf_drm->npix_z = surf_ws->npix_z; - surf_drm->blk_w = surf_ws->blk_w; - surf_drm->blk_h = surf_ws->blk_h; - surf_drm->blk_d = surf_ws->blk_d; - surf_drm->array_size = surf_ws->array_size; - surf_drm->last_level = surf_ws->last_level; - surf_drm->bpe = surf_ws->bpe; - surf_drm->nsamples = surf_ws->nsamples; - surf_drm->flags = surf_ws->flags; + surf_drm->npix_x = tex->width0; + surf_drm->npix_y = tex->height0; + surf_drm->npix_z = tex->depth0; + surf_drm->blk_w = util_format_get_blockwidth(tex->format); + surf_drm->blk_h = util_format_get_blockheight(tex->format); + surf_drm->blk_d = 1; + surf_drm->array_size = 1; + surf_drm->last_level = tex->last_level; + surf_drm->bpe = bpe; + surf_drm->nsamples = tex->nr_samples ? tex->nr_samples : 1; + + surf_drm->flags = flags; + surf_drm->flags = RADEON_SURF_CLR(surf_drm->flags, TYPE); + surf_drm->flags = RADEON_SURF_CLR(surf_drm->flags, MODE); + surf_drm->flags |= RADEON_SURF_SET(mode, MODE); + + switch (tex->target) { + case PIPE_TEXTURE_1D: + surf_drm->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D, TYPE); + break; + case PIPE_TEXTURE_RECT: + case PIPE_TEXTURE_2D: + surf_drm->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE); + break; + case PIPE_TEXTURE_3D: + surf_drm->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_3D, TYPE); + break; + case PIPE_TEXTURE_1D_ARRAY: + surf_drm->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D_ARRAY, TYPE); + surf_drm->array_size = tex->array_size; + break; + case PIPE_TEXTURE_CUBE_ARRAY: /* cube array layout like 2d array */ + assert(tex->array_size % 6 == 0); + /* fall through */ + case PIPE_TEXTURE_2D_ARRAY: + surf_drm->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D_ARRAY, TYPE); + surf_drm->array_size = tex->array_size; + break; + case PIPE_TEXTURE_CUBE: + surf_drm->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_CUBEMAP, TYPE); + break; + case PIPE_BUFFER: + default: + assert(0); + } surf_drm->bo_size = surf_ws->bo_size; surf_drm->bo_alignment = surf_ws->bo_alignment; @@ -142,16 +179,9 @@ static void surf_drm_to_winsys(struct radeon_drm_winsys *ws, memset(surf_ws, 0, sizeof(*surf_ws)); - surf_ws->npix_x = surf_drm->npix_x; - surf_ws->npix_y = surf_drm->npix_y; - surf_ws->npix_z = surf_drm->npix_z; surf_ws->blk_w = surf_drm->blk_w; surf_ws->blk_h = surf_drm->blk_h; - surf_ws->blk_d = surf_drm->blk_d; - surf_ws->array_size = surf_drm->array_size; - surf_ws->last_level = surf_drm->last_level; surf_ws->bpe = surf_drm->bpe; - surf_ws->nsamples = surf_drm->nsamples; surf_ws->flags = surf_drm->flags; surf_ws->bo_size = surf_drm->bo_size; @@ -178,13 +208,16 @@ static void surf_drm_to_winsys(struct radeon_drm_winsys *ws, } static int radeon_winsys_surface_init(struct radeon_winsys *rws, + const struct pipe_resource *tex, + unsigned flags, unsigned bpe, + enum radeon_surf_mode mode, struct radeon_surf *surf_ws) { struct radeon_drm_winsys *ws = (struct radeon_drm_winsys*)rws; struct radeon_surface surf_drm; int r; - surf_winsys_to_drm(&surf_drm, surf_ws); + surf_winsys_to_drm(&surf_drm, tex, flags, bpe, mode, surf_ws); if (!(surf_ws->flags & RADEON_SURF_IMPORTED)) { r = radeon_surface_best(ws->surf_man, &surf_drm); |