Path: blob/21.2-virgl/src/gallium/drivers/lima/lima_texture.c
4565 views
/*1* Copyright (c) 2011-2013 Luc Verhaegen <[email protected]>2* Copyright (c) 2018-2019 Lima Project3*4* Permission is hereby granted, free of charge, to any person obtaining a5* copy of this software and associated documentation files (the "Software"),6* to deal in the Software without restriction, including without limitation7* the rights to use, copy, modify, merge, publish, distribute, sub license,8* and/or sell copies of the Software, and to permit persons to whom the9* Software is furnished to do so, subject to the following conditions:10*11* The above copyright notice and this permission notice (including the12* next paragraph) shall be included in all copies or substantial portions13* of the Software.14*15* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR16* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,17* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL18* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER19* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING20* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER21* DEALINGS IN THE SOFTWARE.22*23*/2425#include "util/u_memory.h"26#include "util/u_upload_mgr.h"27#include "util/u_math.h"28#include "util/u_debug.h"29#include "util/u_transfer.h"3031#include "lima_bo.h"32#include "lima_context.h"33#include "lima_screen.h"34#include "lima_texture.h"35#include "lima_resource.h"36#include "lima_job.h"37#include "lima_util.h"38#include "lima_format.h"3940#include <drm-uapi/lima_drm.h>414243#define lima_tex_list_size 644445static_assert(offsetof(lima_tex_desc, va) == 24, "lima_tex_desc->va offset isn't 24");464748static void49lima_texture_desc_set_va(lima_tex_desc *desc,50int idx,51uint32_t va)52{53unsigned va_bit_idx = VA_BIT_OFFSET + (VA_BIT_SIZE * idx);54unsigned va_idx = va_bit_idx / 32;55va_bit_idx %= 32;5657va >>= 6;5859desc->va[va_idx] |= va << va_bit_idx;60if (va_bit_idx <= 6)61return;62desc->va[va_idx + 1] |= va >> (32 - va_bit_idx);63}6465/*66* Note: this function is used by both draw and flush code path,67* make sure no lima_job_get() is called inside this.68*/69void70lima_texture_desc_set_res(struct lima_context *ctx, lima_tex_desc *desc,71struct pipe_resource *prsc,72unsigned first_level, unsigned last_level, unsigned first_layer)73{74unsigned width, height, layout, i;75struct lima_resource *lima_res = lima_resource(prsc);7677width = prsc->width0;78height = prsc->height0;79if (first_level != 0) {80width = u_minify(width, first_level);81height = u_minify(height, first_level);82}8384desc->format = lima_format_get_texel(prsc->format);85desc->swap_r_b = lima_format_get_texel_swap_rb(prsc->format);86desc->width = width;87desc->height = height;88desc->unknown_3_1 = 1;8990if (lima_res->tiled)91layout = 3;92else {93desc->stride = lima_res->levels[first_level].stride;94desc->has_stride = 1;95layout = 0;96}9798uint32_t base_va = lima_res->bo->va;99100/* attach first level */101uint32_t first_va = base_va + lima_res->levels[first_level].offset + first_layer * lima_res->levels[first_level].layer_stride;102desc->va_s.va_0 = first_va >> 6;103desc->va_s.layout = layout;104105/* Attach remaining levels.106* Each subsequent mipmap address is specified using the 26 msbs.107* These addresses are then packed continuously in memory */108for (i = 1; i <= (last_level - first_level); i++) {109uint32_t address = base_va + lima_res->levels[first_level + i].offset;110lima_texture_desc_set_va(desc, i, address);111}112}113114static void115lima_update_tex_desc(struct lima_context *ctx, struct lima_sampler_state *sampler,116struct lima_sampler_view *texture, void *pdesc,117unsigned desc_size)118{119/* unit is 1/16 since lod_bias is in fixed format */120int lod_bias_delta = 0;121lima_tex_desc *desc = pdesc;122unsigned first_level;123unsigned last_level;124unsigned first_layer;125float max_lod;126127memset(desc, 0, desc_size);128129switch (texture->base.target) {130case PIPE_TEXTURE_2D:131case PIPE_TEXTURE_RECT:132desc->texture_type = LIMA_TEXTURE_TYPE_2D;133break;134case PIPE_TEXTURE_CUBE:135desc->texture_type = LIMA_TEXTURE_TYPE_CUBE;136break;137default:138break;139}140141if (!sampler->base.normalized_coords)142desc->unnorm_coords = 1;143144first_level = texture->base.u.tex.first_level;145last_level = texture->base.u.tex.last_level;146first_layer = texture->base.u.tex.first_layer;147if (last_level - first_level >= LIMA_MAX_MIP_LEVELS)148last_level = first_level + LIMA_MAX_MIP_LEVELS - 1;149150desc->min_lod = lima_float_to_fixed8(sampler->base.min_lod);151max_lod = MIN2(sampler->base.max_lod, sampler->base.min_lod +152(last_level - first_level));153desc->max_lod = lima_float_to_fixed8(max_lod);154desc->lod_bias = lima_float_to_fixed8(sampler->base.lod_bias);155156switch (sampler->base.min_mip_filter) {157case PIPE_TEX_MIPFILTER_LINEAR:158desc->min_mipfilter_2 = 3;159break;160case PIPE_TEX_MIPFILTER_NEAREST:161desc->min_mipfilter_2 = 0;162break;163case PIPE_TEX_MIPFILTER_NONE:164desc->max_lod = desc->min_lod;165break;166default:167break;168}169170switch (sampler->base.mag_img_filter) {171case PIPE_TEX_FILTER_LINEAR:172desc->mag_img_filter_nearest = 0;173break;174case PIPE_TEX_FILTER_NEAREST:175default:176desc->mag_img_filter_nearest = 1;177break;178}179180switch (sampler->base.min_img_filter) {181break;182case PIPE_TEX_FILTER_LINEAR:183desc->min_img_filter_nearest = 0;184break;185case PIPE_TEX_FILTER_NEAREST:186default:187lod_bias_delta = 8;188desc->min_img_filter_nearest = 1;189break;190}191192/* Only clamp, clamp to edge, repeat and mirror repeat are supported */193switch (sampler->base.wrap_s) {194case PIPE_TEX_WRAP_CLAMP:195desc->wrap_s_clamp = 1;196break;197case PIPE_TEX_WRAP_CLAMP_TO_EDGE:198case PIPE_TEX_WRAP_CLAMP_TO_BORDER:199desc->wrap_s_clamp_to_edge = 1;200break;201case PIPE_TEX_WRAP_MIRROR_REPEAT:202desc->wrap_s_mirror_repeat = 1;203break;204case PIPE_TEX_WRAP_REPEAT:205default:206break;207}208209/* Only clamp, clamp to edge, repeat and mirror repeat are supported */210switch (sampler->base.wrap_t) {211case PIPE_TEX_WRAP_CLAMP:212desc->wrap_t_clamp = 1;213break;214case PIPE_TEX_WRAP_CLAMP_TO_EDGE:215case PIPE_TEX_WRAP_CLAMP_TO_BORDER:216desc->wrap_t_clamp_to_edge = 1;217break;218case PIPE_TEX_WRAP_MIRROR_REPEAT:219desc->wrap_t_mirror_repeat = 1;220break;221case PIPE_TEX_WRAP_REPEAT:222default:223break;224}225226if (desc->min_img_filter_nearest && desc->mag_img_filter_nearest &&227desc->min_mipfilter_2 == 0 &&228(desc->min_lod != desc->max_lod))229lod_bias_delta = -1;230231desc->lod_bias += lod_bias_delta;232233lima_texture_desc_set_res(ctx, desc, texture->base.texture,234first_level, last_level, first_layer);235}236237static unsigned238lima_calc_tex_desc_size(struct lima_sampler_view *texture)239{240unsigned size = offsetof(lima_tex_desc, va);241unsigned va_bit_size;242unsigned first_level = texture->base.u.tex.first_level;243unsigned last_level = texture->base.u.tex.last_level;244245if (last_level - first_level >= LIMA_MAX_MIP_LEVELS)246last_level = first_level + LIMA_MAX_MIP_LEVELS - 1;247248va_bit_size = VA_BIT_OFFSET + VA_BIT_SIZE * (last_level - first_level + 1);249size += (va_bit_size + 7) >> 3;250size = align(size, lima_min_tex_desc_size);251252return size;253}254255void256lima_update_textures(struct lima_context *ctx)257{258struct lima_job *job = lima_job_get(ctx);259struct lima_texture_stateobj *lima_tex = &ctx->tex_stateobj;260261assert (lima_tex->num_samplers <= 16);262263/* Nothing to do - we have no samplers or textures */264if (!lima_tex->num_samplers || !lima_tex->num_textures)265return;266267/* we always need to add texture bo to job */268for (int i = 0; i < lima_tex->num_samplers; i++) {269struct lima_sampler_view *texture = lima_sampler_view(lima_tex->textures[i]);270struct lima_resource *rsc = lima_resource(texture->base.texture);271lima_flush_previous_job_writing_resource(ctx, texture->base.texture);272lima_job_add_bo(job, LIMA_PIPE_PP, rsc->bo, LIMA_SUBMIT_BO_READ);273}274275/* do not regenerate texture desc if no change */276if (!(ctx->dirty & LIMA_CONTEXT_DIRTY_TEXTURES))277return;278279unsigned size = lima_tex_list_size;280for (int i = 0; i < lima_tex->num_samplers; i++) {281struct lima_sampler_view *texture = lima_sampler_view(lima_tex->textures[i]);282size += lima_calc_tex_desc_size(texture);283}284285uint32_t *descs =286lima_ctx_buff_alloc(ctx, lima_ctx_buff_pp_tex_desc, size);287288off_t offset = lima_tex_list_size;289for (int i = 0; i < lima_tex->num_samplers; i++) {290struct lima_sampler_state *sampler = lima_sampler_state(lima_tex->samplers[i]);291struct lima_sampler_view *texture = lima_sampler_view(lima_tex->textures[i]);292unsigned desc_size = lima_calc_tex_desc_size(texture);293294descs[i] = lima_ctx_buff_va(ctx, lima_ctx_buff_pp_tex_desc) + offset;295lima_update_tex_desc(ctx, sampler, texture, (void *)descs + offset, desc_size);296offset += desc_size;297}298299lima_dump_command_stream_print(300job->dump, descs, size, false, "add textures_desc at va %x\n",301lima_ctx_buff_va(ctx, lima_ctx_buff_pp_tex_desc));302303lima_dump_texture_descriptor(304job->dump, descs, size,305lima_ctx_buff_va(ctx, lima_ctx_buff_pp_tex_desc) + lima_tex_list_size,306lima_tex_list_size);307}308309310