[Mesa-dev] [PATCH 03/30] r600: refactor texture resource words setup code.
eocallaghan at alterapraxis.com
eocallaghan at alterapraxis.com
Fri Apr 1 00:26:09 UTC 2016
Reviewed-by: Edward O'Callaghan <eocallaghan at alterapraxis.com>
On 2016-03-31 18:03, Dave Airlie wrote:
> From: Dave Airlie <airlied at redhat.com>
>
> This refactors out the code to setup a texture resource
> so we can reuse it later from the images code.
>
> Signed-off-by: Dave Airlie <airlied at redhat.com>
> ---
> src/gallium/drivers/r600/evergreen_state.c | 274
> +++++++++++++++++------------
> 1 file changed, 158 insertions(+), 116 deletions(-)
>
> diff --git a/src/gallium/drivers/r600/evergreen_state.c
> b/src/gallium/drivers/r600/evergreen_state.c
> index b68faed..356e708 100644
> --- a/src/gallium/drivers/r600/evergreen_state.c
> +++ b/src/gallium/drivers/r600/evergreen_state.c
> @@ -649,93 +649,55 @@ static void
> evergreen_fill_buffer_resource_words(struct r600_context *rctx,
> tex_resource_words[7] =
> S_03001C_TYPE(V_03001C_SQ_TEX_VTX_VALID_BUFFER);
> }
>
> -static struct pipe_sampler_view *
> -texture_buffer_sampler_view(struct r600_context *rctx,
> - struct r600_pipe_sampler_view *view,
> - unsigned width0, unsigned height0)
> -{
> - struct r600_texture *tmp = (struct r600_texture*)view->base.texture;
> - struct eg_buf_res_params params;
> -
> - memset(¶ms, 0, sizeof(params));
> -
> - params.pipe_format = view->base.format;
> - params.first_element = view->base.u.buf.first_element;
> - params.last_element = view->base.u.buf.last_element;
> - params.swizzle[0] = view->base.swizzle_r;
> - params.swizzle[1] = view->base.swizzle_g;
> - params.swizzle[2] = view->base.swizzle_b;
> - params.swizzle[3] = view->base.swizzle_a;
> -
> - evergreen_fill_buffer_resource_words(rctx, view->base.texture,
> - ¶ms, &view->skip_mip_address_reloc,
> - view->tex_resource_words);
> - view->tex_resource = &tmp->resource;
> -
> - if (tmp->resource.gpu_address)
> - LIST_ADDTAIL(&view->list, &rctx->b.texture_buffers);
> - return &view->base;
> -}
> +struct eg_tex_res_params {
> + enum pipe_format pipe_format;
> + int force_level;
> + unsigned width0;
> + unsigned height0;
> + unsigned first_level;
> + unsigned last_level;
> + unsigned first_layer;
> + unsigned last_layer;
> + unsigned target;
> + unsigned char swizzle[4];
> +};
>
> -struct pipe_sampler_view *
> -evergreen_create_sampler_view_custom(struct pipe_context *ctx,
> - struct pipe_resource *texture,
> - const struct pipe_sampler_view *state,
> - unsigned width0, unsigned height0,
> - unsigned force_level)
> +static int evergreen_fill_tex_resource_words(struct r600_context
> *rctx,
> + struct pipe_resource *texture,
> + struct eg_tex_res_params *params,
> + bool *skip_mip_address_reloc,
> + unsigned tex_resource_words[8])
> {
> - struct r600_context *rctx = (struct r600_context*)ctx;
> - struct r600_screen *rscreen = (struct r600_screen*)ctx->screen;
> - struct r600_pipe_sampler_view *view =
> CALLOC_STRUCT(r600_pipe_sampler_view);
> + struct r600_screen *rscreen = (struct r600_screen*)rctx->b.b.screen;
> struct r600_texture *tmp = (struct r600_texture*)texture;
> unsigned format, endian;
> uint32_t word4 = 0, yuv_format = 0, pitch = 0;
> - unsigned char swizzle[4], array_mode = 0, non_disp_tiling = 0;
> + unsigned char array_mode = 0, non_disp_tiling = 0;
> unsigned height, depth, width;
> unsigned macro_aspect, tile_split, bankh, bankw, nbanks, fmask_bankh;
> - enum pipe_format pipe_format = state->format;
> struct radeon_surf_level *surflevel;
> unsigned base_level, first_level, last_level;
> unsigned dim, last_layer;
> uint64_t va;
>
> - if (!view)
> - return NULL;
> -
> - /* initialize base object */
> - view->base = *state;
> - view->base.texture = NULL;
> - pipe_reference(NULL, &texture->reference);
> - view->base.texture = texture;
> - view->base.reference.count = 1;
> - view->base.context = ctx;
> -
> - if (state->target == PIPE_BUFFER)
> - return texture_buffer_sampler_view(rctx, view, width0, height0);
> -
> - swizzle[0] = state->swizzle_r;
> - swizzle[1] = state->swizzle_g;
> - swizzle[2] = state->swizzle_b;
> - swizzle[3] = state->swizzle_a;
> -
> tile_split = tmp->surface.tile_split;
> surflevel = tmp->surface.level;
>
> /* Texturing with separate depth and stencil. */
> if (tmp->is_depth && !tmp->is_flushing_texture) {
> - switch (pipe_format) {
> + switch (params->pipe_format) {
> case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
> - pipe_format = PIPE_FORMAT_Z32_FLOAT;
> + params->pipe_format = PIPE_FORMAT_Z32_FLOAT;
> break;
> case PIPE_FORMAT_X8Z24_UNORM:
> case PIPE_FORMAT_S8_UINT_Z24_UNORM:
> /* Z24 is always stored like this. */
> - pipe_format = PIPE_FORMAT_Z24X8_UNORM;
> + params->pipe_format = PIPE_FORMAT_Z24X8_UNORM;
> break;
> case PIPE_FORMAT_X24S8_UINT:
> case PIPE_FORMAT_S8X24_UINT:
> case PIPE_FORMAT_X32_S8X24_UINT:
> - pipe_format = PIPE_FORMAT_S8_UINT;
> + params->pipe_format = PIPE_FORMAT_S8_UINT;
> tile_split = tmp->surface.stencil_tile_split;
> surflevel = tmp->surface.stencil_level;
> break;
> @@ -743,34 +705,32 @@ evergreen_create_sampler_view_custom(struct
> pipe_context *ctx,
> }
> }
>
> - format = r600_translate_texformat(ctx->screen, pipe_format,
> - swizzle,
> + format = r600_translate_texformat(rctx->b.b.screen,
> params->pipe_format,
> + params->swizzle,
> &word4, &yuv_format);
> assert(format != ~0);
> if (format == ~0) {
> - FREE(view);
> - return NULL;
> + return -1;
> }
> -
> endian = r600_colorformat_endian_swap(format);
>
> base_level = 0;
> - first_level = state->u.tex.first_level;
> - last_level = state->u.tex.last_level;
> - width = width0;
> - height = height0;
> + first_level = params->first_level;
> + last_level = params->last_level;
> + width = params->width0;
> + height = params->height0;
> depth = texture->depth0;
>
> - if (force_level) {
> - base_level = force_level;
> + if (params->force_level) {
> + base_level = params->force_level;
> first_level = 0;
> last_level = 0;
> - width = u_minify(width, force_level);
> - height = u_minify(height, force_level);
> - depth = u_minify(depth, force_level);
> + width = u_minify(width, params->force_level);
> + height = u_minify(height, params->force_level);
> + depth = u_minify(depth, params->force_level);
> }
>
> - pitch = surflevel[base_level].nblk_x *
> util_format_get_blockwidth(pipe_format);
> + pitch = surflevel[base_level].nblk_x *
> util_format_get_blockwidth(params->pipe_format);
> non_disp_tiling = tmp->non_disp_tiling;
>
> switch (surflevel[base_level].mode) {
> @@ -799,94 +759,176 @@ evergreen_create_sampler_view_custom(struct
> pipe_context *ctx,
>
> /* 128 bit formats require tile type = 1 */
> if (rscreen->b.chip_class == CAYMAN) {
> - if (util_format_get_blocksize(pipe_format) >= 16)
> + if (util_format_get_blocksize(params->pipe_format) >= 16)
> non_disp_tiling = 1;
> }
> nbanks = eg_num_banks(rscreen->b.info.r600_num_banks);
>
> - if (state->target == PIPE_TEXTURE_1D_ARRAY) {
> + if (params->target == PIPE_TEXTURE_1D_ARRAY) {
> height = 1;
> depth = texture->array_size;
> - } else if (state->target == PIPE_TEXTURE_2D_ARRAY) {
> + } else if (params->target == PIPE_TEXTURE_2D_ARRAY) {
> depth = texture->array_size;
> - } else if (state->target == PIPE_TEXTURE_CUBE_ARRAY)
> + } else if (params->target == PIPE_TEXTURE_CUBE_ARRAY)
> depth = texture->array_size / 6;
>
> va = tmp->resource.gpu_address;
>
> - if (state->format == PIPE_FORMAT_X24S8_UINT ||
> - state->format == PIPE_FORMAT_S8X24_UINT ||
> - state->format == PIPE_FORMAT_X32_S8X24_UINT ||
> - state->format == PIPE_FORMAT_S8_UINT)
> - view->is_stencil_sampler = true;
> -
> - view->tex_resource = &tmp->resource;
> -
> /* array type views and views into array types need to use layer
> offset */
> - dim = state->target;
> - if (state->target != PIPE_TEXTURE_CUBE)
> - dim = MAX2(state->target, texture->target);
> + dim = params->target;
> + if (params->target != PIPE_TEXTURE_CUBE)
> + dim = MAX2(params->target, texture->target);
>
> - view->tex_resource_words[0] = (S_030000_DIM(r600_tex_dim(dim,
> texture->nr_samples)) |
> + tex_resource_words[0] = (S_030000_DIM(r600_tex_dim(dim,
> texture->nr_samples)) |
> S_030000_PITCH((pitch / 8) - 1) |
> S_030000_TEX_WIDTH(width - 1));
> if (rscreen->b.chip_class == CAYMAN)
> - view->tex_resource_words[0] |=
> CM_S_030000_NON_DISP_TILING_ORDER(non_disp_tiling);
> + tex_resource_words[0] |=
> CM_S_030000_NON_DISP_TILING_ORDER(non_disp_tiling);
> else
> - view->tex_resource_words[0] |=
> S_030000_NON_DISP_TILING_ORDER(non_disp_tiling);
> - view->tex_resource_words[1] = (S_030004_TEX_HEIGHT(height - 1) |
> + tex_resource_words[0] |=
> S_030000_NON_DISP_TILING_ORDER(non_disp_tiling);
> + tex_resource_words[1] = (S_030004_TEX_HEIGHT(height - 1) |
> S_030004_TEX_DEPTH(depth - 1) |
> S_030004_ARRAY_MODE(array_mode));
> - view->tex_resource_words[2] = (surflevel[base_level].offset + va) >>
> 8;
> + tex_resource_words[2] = (surflevel[base_level].offset + va) >> 8;
>
> + *skip_mip_address_reloc = false;
> /* TEX_RESOURCE_WORD3.MIP_ADDRESS */
> if (texture->nr_samples > 1 &&
> rscreen->has_compressed_msaa_texturing) {
> if (tmp->is_depth) {
> /* disable FMASK (0 = disabled) */
> - view->tex_resource_words[3] = 0;
> - view->skip_mip_address_reloc = true;
> + tex_resource_words[3] = 0;
> + *skip_mip_address_reloc = true;
> } else {
> /* FMASK should be in MIP_ADDRESS for multisample textures */
> - view->tex_resource_words[3] = (tmp->fmask.offset + va) >> 8;
> + tex_resource_words[3] = (tmp->fmask.offset + va) >> 8;
> }
> } else if (last_level && texture->nr_samples <= 1) {
> - view->tex_resource_words[3] = (surflevel[1].offset + va) >> 8;
> + tex_resource_words[3] = (surflevel[1].offset + va) >> 8;
> } else {
> - view->tex_resource_words[3] = (surflevel[base_level].offset + va) >>
> 8;
> + tex_resource_words[3] = (surflevel[base_level].offset + va) >> 8;
> }
>
> - last_layer = state->u.tex.last_layer;
> - if (state->target != texture->target && depth == 1) {
> - last_layer = state->u.tex.first_layer;
> + last_layer = params->last_layer;
> + if (params->target != texture->target && depth == 1) {
> + last_layer = params->first_layer;
> }
> - view->tex_resource_words[4] = (word4 |
> - S_030010_ENDIAN_SWAP(endian));
> - view->tex_resource_words[5] =
> S_030014_BASE_ARRAY(state->u.tex.first_layer) |
> - S_030014_LAST_ARRAY(last_layer);
> - view->tex_resource_words[6] = S_030018_TILE_SPLIT(tile_split);
> + tex_resource_words[4] = (word4 |
> + S_030010_ENDIAN_SWAP(endian));
> + tex_resource_words[5] = S_030014_BASE_ARRAY(params->first_layer) |
> + S_030014_LAST_ARRAY(last_layer);
> + tex_resource_words[6] = S_030018_TILE_SPLIT(tile_split);
>
> if (texture->nr_samples > 1) {
> unsigned log_samples = util_logbase2(texture->nr_samples);
> if (rscreen->b.chip_class == CAYMAN) {
> - view->tex_resource_words[4] |=
> S_030010_LOG2_NUM_FRAGMENTS(log_samples);
> + tex_resource_words[4] |= S_030010_LOG2_NUM_FRAGMENTS(log_samples);
> }
> /* LAST_LEVEL holds log2(nr_samples) for multisample textures */
> - view->tex_resource_words[5] |= S_030014_LAST_LEVEL(log_samples);
> - view->tex_resource_words[6] |=
> S_030018_FMASK_BANK_HEIGHT(fmask_bankh);
> + tex_resource_words[5] |= S_030014_LAST_LEVEL(log_samples);
> + tex_resource_words[6] |= S_030018_FMASK_BANK_HEIGHT(fmask_bankh);
> } else {
> - view->tex_resource_words[4] |= S_030010_BASE_LEVEL(first_level);
> - view->tex_resource_words[5] |= S_030014_LAST_LEVEL(last_level);
> + tex_resource_words[4] |= S_030010_BASE_LEVEL(first_level);
> + tex_resource_words[5] |= S_030014_LAST_LEVEL(last_level);
> /* aniso max 16 samples */
> - view->tex_resource_words[6] |= S_030018_MAX_ANISO(4);
> + tex_resource_words[6] |= S_030018_MAX_ANISO(4);
> }
>
> - view->tex_resource_words[7] = S_03001C_DATA_FORMAT(format) |
> + tex_resource_words[7] = S_03001C_DATA_FORMAT(format) |
> S_03001C_TYPE(V_03001C_SQ_TEX_VTX_VALID_TEXTURE) |
> S_03001C_BANK_WIDTH(bankw) |
> S_03001C_BANK_HEIGHT(bankh) |
> S_03001C_MACRO_TILE_ASPECT(macro_aspect) |
> S_03001C_NUM_BANKS(nbanks) |
> S_03001C_DEPTH_SAMPLE_ORDER(tmp->is_depth &&
> !tmp->is_flushing_texture);
> + return 0;
> +}
> +
> +static struct pipe_sampler_view *
> +texture_buffer_sampler_view(struct r600_context *rctx,
> + struct r600_pipe_sampler_view *view,
> + unsigned width0, unsigned height0)
> +{
> + struct r600_texture *tmp = (struct r600_texture*)view->base.texture;
> + struct eg_buf_res_params params;
> +
> + memset(¶ms, 0, sizeof(params));
> +
> + params.pipe_format = view->base.format;
> + params.first_element = view->base.u.buf.first_element;
> + params.last_element = view->base.u.buf.last_element;
> + params.swizzle[0] = view->base.swizzle_r;
> + params.swizzle[1] = view->base.swizzle_g;
> + params.swizzle[2] = view->base.swizzle_b;
> + params.swizzle[3] = view->base.swizzle_a;
> +
> + evergreen_fill_buffer_resource_words(rctx, view->base.texture,
> + ¶ms, &view->skip_mip_address_reloc,
> + view->tex_resource_words);
> + view->tex_resource = &tmp->resource;
> +
> + if (tmp->resource.gpu_address)
> + LIST_ADDTAIL(&view->list, &rctx->b.texture_buffers);
> + return &view->base;
> +}
> +
> +struct pipe_sampler_view *
> +evergreen_create_sampler_view_custom(struct pipe_context *ctx,
> + struct pipe_resource *texture,
> + const struct pipe_sampler_view *state,
> + unsigned width0, unsigned height0,
> + unsigned force_level)
> +{
> + struct r600_context *rctx = (struct r600_context*)ctx;
> + struct r600_pipe_sampler_view *view =
> CALLOC_STRUCT(r600_pipe_sampler_view);
> + struct r600_texture *tmp = (struct r600_texture*)texture;
> + struct eg_tex_res_params params;
> + int ret;
> +
> + if (!view)
> + return NULL;
> +
> + /* initialize base object */
> + view->base = *state;
> + view->base.texture = NULL;
> + pipe_reference(NULL, &texture->reference);
> + view->base.texture = texture;
> + view->base.reference.count = 1;
> + view->base.context = ctx;
> +
> + if (state->target == PIPE_BUFFER)
> + return texture_buffer_sampler_view(rctx, view, width0, height0);
> +
> + memset(¶ms, 0, sizeof(params));
> + params.pipe_format = state->format;
> + params.force_level = force_level;
> + params.width0 = width0;
> + params.height0 = height0;
> + params.first_level = state->u.tex.first_level;
> + params.last_level = state->u.tex.last_level;
> + params.first_layer = state->u.tex.first_layer;
> + params.last_layer = state->u.tex.last_layer;
> + params.target = state->target;
> + params.swizzle[0] = state->swizzle_r;
> + params.swizzle[1] = state->swizzle_g;
> + params.swizzle[2] = state->swizzle_b;
> + params.swizzle[3] = state->swizzle_a;
> +
> + ret = evergreen_fill_tex_resource_words(rctx, texture, ¶ms,
> + &view->skip_mip_address_reloc,
> + view->tex_resource_words);
> + if (ret != 0) {
> + FREE(view);
> + return NULL;
> + }
> +
> + if (state->format == PIPE_FORMAT_X24S8_UINT ||
> + state->format == PIPE_FORMAT_S8X24_UINT ||
> + state->format == PIPE_FORMAT_X32_S8X24_UINT ||
> + state->format == PIPE_FORMAT_S8_UINT)
> + view->is_stencil_sampler = true;
> +
> + view->tex_resource = &tmp->resource;
> +
> return &view->base;
> }
More information about the mesa-dev
mailing list