From: Marek Olšák <marek.ol...@amd.com> This removes input-only parameters from the radeon_surf structure.
Some of the translation logic from pipe_resource to radeon_surf is moved to winsys/radeon. --- src/gallium/drivers/radeon/r600_texture.c | 120 ++++++----------- src/gallium/drivers/radeon/radeon_winsys.h | 33 ++--- src/gallium/winsys/amdgpu/drm/amdgpu_surface.c | 146 +++++++++++---------- 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 daa743e..a89b285 100644 --- a/src/gallium/drivers/radeon/r600_texture.c +++ b/src/gallium/drivers/radeon/r600_texture.c @@ -196,129 +196,90 @@ static int r600_init_surface(struct r600_common_screen *rscreen, unsigned pitch_in_bytes_override, unsigned offset, bool is_imported, bool is_scanout, bool is_flushed_depth, bool tc_compatible_htile) { 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) { /* TC-compatible HTILE only supports Z32_FLOAT. * 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. */ assert(ptex->nr_samples <= 1 && 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; } if (pitch_in_bytes_override && pitch_in_bytes_override != surface->level[0].pitch_bytes) { /* 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; } if (offset) { for (i = 0; i < ARRAY_SIZE(surface->level); ++i) surface->level[i].offset += offset; } return 0; } @@ -622,63 +583,64 @@ static void r600_texture_destroy(struct pipe_screen *screen, static const struct u_resource_vtbl r600_texture_vtbl; /* The number of samples can be specified independently of the texture. */ void r600_texture_get_fmask_info(struct r600_common_screen *rscreen, struct r600_texture *rtex, unsigned nr_samples, 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"); return; } /* Overallocate FMASK on R600-R700 to fix colorbuffer corruption. * 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; } assert(fmask.level[0].mode == RADEON_SURF_MODE_2D); out->slice_tile_max = (fmask.level[0].nblk_x * fmask.level[0].nblk_y) / 64; if (out->slice_tile_max) out->slice_tile_max -= 1; @@ -951,27 +913,27 @@ static void r600_texture_allocate_htile(struct r600_common_screen *rscreen, 0, htile_size, clear_value, R600_COHERENCY_NONE); } } 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, " "bankh=%u, nbanks=%u, mtilea=%u, tilesplit=%u, pipeconfig=%u, scanout=%u\n", rtex->surface.bo_size, rtex->surface.bo_alignment, rtex->surface.bankw, rtex->surface.bankh, rtex->surface.num_banks, rtex->surface.mtilea, rtex->surface.tile_split, rtex->surface.pipe_config, (rtex->surface.flags & RADEON_SURF_SCANOUT) != 0); if (rtex->fmask.size) diff --git a/src/gallium/drivers/radeon/radeon_winsys.h b/src/gallium/drivers/radeon/radeon_winsys.h index 3bd141e..4b79752 100644 --- a/src/gallium/drivers/radeon/radeon_winsys.h +++ b/src/gallium/drivers/radeon/radeon_winsys.h @@ -256,73 +256,53 @@ enum radeon_feature_id { }; #define RADEON_SURF_MAX_LEVEL 32 enum radeon_surf_mode { RADEON_SURF_MODE_LINEAR_ALIGNED = 1, RADEON_SURF_MODE_1D = 2, 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) #define RADEON_SURF_Z_OR_SBUFFER (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER) #define RADEON_SURF_HAS_SBUFFER_MIPTREE (1 << 19) #define RADEON_SURF_HAS_TILE_MODE_INDEX (1 << 20) #define RADEON_SURF_FMASK (1 << 21) #define RADEON_SURF_DISABLE_DCC (1 << 22) #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; uint32_t npix_x; uint32_t npix_y; uint32_t npix_z; uint32_t nblk_x; uint32_t nblk_y; uint32_t nblk_z; uint32_t pitch_bytes; enum radeon_surf_mode mode; uint64_t dcc_offset; uint64_t dcc_fast_clear_size; bool dcc_enabled; }; 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 * they will be treated as hints (e.g. bankw, bankh) and might be * changed by the calculator. */ uint64_t bo_size; uint64_t bo_alignment; /* This applies to EG and later. */ uint32_t bankw; @@ -736,23 +716,30 @@ struct radeon_winsys { /** * Reference counting for fences. */ void (*fence_reference)(struct pipe_fence_handle **dst, struct pipe_fence_handle *src); /** * 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, enum radeon_value_id value); bool (*read_registers)(struct radeon_winsys *ws, unsigned reg_offset, unsigned num_registers, uint32_t *out); }; static inline bool radeon_emitted(struct radeon_winsys_cs *cs, unsigned num_dw) diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c b/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c index 94fe7d6..3b4c13b 100644 --- a/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c @@ -23,71 +23,67 @@ * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. */ /* Contact: * Marek Olšák <mar...@gmail.com> */ #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: case 8: break; default: 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: return -EINVAL; } return 0; } static void *ADDR_API allocSysMem(const ADDR_ALLOCSYSMEM_INPUT * pInput) { @@ -141,42 +137,43 @@ ADDR_HANDLE amdgpu_addr_create(struct amdgpu_winsys *ws) addrCreateInput.regValue = regValue; addrRet = AddrCreate(&addrCreateInput, &addrCreateOutput); if (addrRet != ADDR_OK) return NULL; return addrCreateOutput.hLib; } 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, ADDR_COMPUTE_DCCINFO_OUTPUT *AddrDccOut, ADDR_COMPUTE_HTILE_INFO_INPUT *AddrHtileIn, ADDR_COMPUTE_HTILE_INFO_OUTPUT *AddrHtileOut) { struct radeon_surf_level *surf_level; 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 * of non-zero levels. */ if (is_stencil) AddrSurfInfoIn->basePitch = surf->stencil_level[0].nblk_x; else AddrSurfInfoIn->basePitch = surf->level[0].nblk_x; /* Convert blocks to pixels for compressed formats. */ @@ -188,26 +185,26 @@ static int compute_level(struct amdgpu_winsys *ws, AddrSurfInfoIn, AddrSurfInfoOut); if (ret != ADDR_OK) { return ret; } surf_level = is_stencil ? &surf->stencil_level[level] : &surf->level[level]; 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; switch (AddrSurfInfoOut->tileMode) { case ADDR_TM_LINEAR_ALIGNED: surf_level->mode = RADEON_SURF_MODE_LINEAR_ALIGNED; break; case ADDR_TM_1D_TILED_THIN1: surf_level->mode = RADEON_SURF_MODE_1D; @@ -303,58 +300,64 @@ static unsigned cik_get_macro_tile_index(struct radeon_surf *surf) tileb = MIN2(surf->tile_split, tileb); for (index = 0; tileb > 64; index++) tileb >>= 1; assert(index < 16); return index; } 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}; ADDR_COMPUTE_DCCINFO_INPUT AddrDccIn = {0}; ADDR_COMPUTE_DCCINFO_OUTPUT AddrDccOut = {0}; ADDR_COMPUTE_HTILE_INFO_INPUT AddrHtileIn = {0}; ADDR_COMPUTE_HTILE_INFO_OUTPUT AddrHtileOut = {0}; ADDR_TILEINFO AddrTileInfoIn = {0}; ADDR_TILEINFO AddrTileInfoOut = {0}; int r; - r = amdgpu_surface_sanity(surf); + r = amdgpu_surface_sanity(tex); if (r) return r; AddrSurfInfoIn.size = sizeof(ADDR_COMPUTE_SURFACE_INFO_INPUT); AddrSurfInfoOut.size = sizeof(ADDR_COMPUTE_SURFACE_INFO_OUTPUT); AddrDccIn.size = sizeof(ADDR_COMPUTE_DCCINFO_INPUT); AddrDccOut.size = sizeof(ADDR_COMPUTE_DCCINFO_OUTPUT); AddrHtileIn.size = sizeof(ADDR_COMPUTE_HTILE_INFO_INPUT); 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; /* Set the requested tiling mode. */ switch (mode) { case RADEON_SURF_MODE_LINEAR_ALIGNED: AddrSurfInfoIn.tileMode = ADDR_TM_LINEAR_ALIGNED; break; case RADEON_SURF_MODE_1D: AddrSurfInfoIn.tileMode = ADDR_TM_1D_TILED_THIN1; @@ -362,82 +365,83 @@ static int amdgpu_surface_init(struct radeon_winsys *rws, case RADEON_SURF_MODE_2D: AddrSurfInfoIn.tileMode = ADDR_TM_2D_TILED_THIN1; break; default: assert(0); } /* 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; case 16: AddrSurfInfoIn.format = ADDR_FMT_BC3; break; default: assert(0); } } 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. */ AddrSurfInfoIn.flags.degrade4Space = !AddrSurfInfoIn.flags.tcCompatible; /* DCC notes: * - If we add MSAA support, keep in mind that CB can't decompress 8bpp * with samples >= 4. * - Mipmapped array textures have low performance (discovered by a closed * 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 * mipmapped texturing. So set noStencil = 1 when mipmaps are requested (in * this case, we may end up setting stencil_adjusted). * * 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 * for shared resources. This is for 2D tiling only. */ if (AddrSurfInfoIn.tileMode >= ADDR_TM_2D_TILED_THIN1 && surf->bankw && surf->bankh && surf->mtilea && surf->tile_split) { /* If any of these parameters are incorrect, the calculation * will fail. */ AddrTileInfoIn.banks = surf->num_banks; AddrTileInfoIn.bankWidth = surf->bankw; @@ -449,35 +453,35 @@ static int amdgpu_surface_init(struct radeon_winsys *rws, AddrSurfInfoIn.pTileInfo = &AddrTileInfoIn; /* If AddrSurfInfoIn.pTileInfo is set, Addrlib doesn't set * the tile index, because we are expected to know it if * we know the other parameters. * * This is something that can easily be fixed in Addrlib. * 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) */ } } else { /* CIK - VI */ if (AddrSurfInfoIn.tileType == ADDR_DISPLAYABLE) AddrSurfInfoIn.tileIndex = 10; /* 2D displayable */ else AddrSurfInfoIn.tileIndex = 14; /* 2D non-displayable */ @@ -487,22 +491,22 @@ static int amdgpu_surface_init(struct radeon_winsys *rws, } } surf->bo_size = 0; surf->dcc_size = 0; surf->dcc_alignment = 1; surf->htile_size = 0; 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) return r; if (level == 0) { surf->bo_alignment = AddrSurfInfoOut.baseAlign; surf->pipe_config = AddrSurfInfoOut.pTileInfo->pipeConfig - 1; set_micro_tile_mode(surf, &ws->info); @@ -514,30 +518,30 @@ static int amdgpu_surface_init(struct radeon_winsys *rws, surf->tile_split = AddrSurfInfoOut.pTileInfo->tileSplitBytes; surf->num_banks = AddrSurfInfoOut.pTileInfo->banks; surf->macro_tile_index = AddrSurfInfoOut.macroModeIndex; } else { surf->macro_tile_index = 0; } } } /* 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; AddrSurfInfoIn.flags.tcCompatible = 0; /* 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) return r; /* DB uses the depth pitch for both stencil and depth. */ if (surf->stencil_level[level].nblk_x != surf->level[level].nblk_x) surf->stencil_adjusted = true; if (level == 0) { @@ -547,29 +551,29 @@ static int amdgpu_surface_init(struct radeon_winsys *rws, AddrSurfInfoOut.pTileInfo->tileSplitBytes; } } } } /* Recalculate the whole DCC miptree size including disabled levels. * 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); } /* 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; } void amdgpu_surface_init_functions(struct amdgpu_winsys *ws) { ws->base.surface_init = amdgpu_surface_init; } diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_surface.c b/src/gallium/winsys/radeon/drm/radeon_drm_surface.c index 8a88ee5..fafcee1 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_surface.c +++ b/src/gallium/winsys/radeon/drm/radeon_drm_surface.c @@ -21,21 +21,21 @@ * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. * * Authors: * Marek Olšák <mar...@gmail.com> */ #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) { unsigned index, tileb; tileb = 8 * 8 * surf->bpe; tileb = MIN2(surf->tile_split, tileb); for (index = 0; tileb > 64; index++) @@ -90,37 +90,74 @@ static void surf_level_drm_to_winsys(struct radeon_surf_level *level_ws, level_ws->npix_y = level_drm->npix_y; level_ws->npix_z = level_drm->npix_z; level_ws->nblk_x = level_drm->nblk_x; level_ws->nblk_y = level_drm->nblk_y; level_ws->nblk_z = level_drm->nblk_z; level_ws->pitch_bytes = level_drm->pitch_bytes; level_ws->mode = level_drm->mode; } 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; surf_drm->bankw = surf_ws->bankw; surf_drm->bankh = surf_ws->bankh; surf_drm->mtilea = surf_ws->mtilea; surf_drm->tile_split = surf_ws->tile_split; surf_drm->stencil_tile_split = surf_ws->stencil_tile_split; @@ -135,30 +172,23 @@ static void surf_winsys_to_drm(struct radeon_surface *surf_drm, } static void surf_drm_to_winsys(struct radeon_drm_winsys *ws, struct radeon_surf *surf_ws, const struct radeon_surface *surf_drm) { int i; 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; surf_ws->bo_alignment = surf_drm->bo_alignment; surf_ws->bankw = surf_drm->bankw; surf_ws->bankh = surf_drm->bankh; surf_ws->mtilea = surf_drm->mtilea; surf_ws->tile_split = surf_drm->tile_split; surf_ws->stencil_tile_split = surf_drm->stencil_tile_split; @@ -171,27 +201,30 @@ static void surf_drm_to_winsys(struct radeon_drm_winsys *ws, &surf_drm->stencil_level[i]); surf_ws->tiling_index[i] = surf_drm->tiling_index[i]; surf_ws->stencil_tiling_index[i] = surf_drm->stencil_tiling_index[i]; } set_micro_tile_mode(surf_ws, &ws->info); } 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); if (r) return r; } r = radeon_surface_init(ws->surf_man, &surf_drm); if (r) return r; -- 2.7.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev