Path: blob/21.2-virgl/src/freedreno/ir3/ir3_image.c
4565 views
/*1* Copyright (C) 2017-2018 Rob Clark <[email protected]>2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,19* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE20* SOFTWARE.21*22* Authors:23* Rob Clark <[email protected]>24*/2526#include "ir3_image.h"2728/*29* SSBO/Image to/from IBO/tex hw mapping table:30*/3132void33ir3_ibo_mapping_init(struct ir3_ibo_mapping *mapping, unsigned num_textures)34{35memset(mapping, IBO_INVALID, sizeof(*mapping));36mapping->num_tex = 0;37mapping->tex_base = num_textures;38}3940struct ir3_instruction *41ir3_ssbo_to_ibo(struct ir3_context *ctx, nir_src src)42{43if (ir3_bindless_resource(src)) {44ctx->so->bindless_ibo = true;45return ir3_get_src(ctx, &src)[0];46} else {47/* can this be non-const buffer_index? how do we handle that? */48int ssbo_idx = nir_src_as_uint(src);49return create_immed(ctx->block, ssbo_idx);50}51}5253unsigned54ir3_ssbo_to_tex(struct ir3_ibo_mapping *mapping, unsigned ssbo)55{56if (mapping->ssbo_to_tex[ssbo] == IBO_INVALID) {57unsigned tex = mapping->num_tex++;58mapping->ssbo_to_tex[ssbo] = tex;59mapping->tex_to_image[tex] = IBO_SSBO | ssbo;60}61return mapping->ssbo_to_tex[ssbo] + mapping->tex_base;62}6364struct ir3_instruction *65ir3_image_to_ibo(struct ir3_context *ctx, nir_src src)66{67if (ir3_bindless_resource(src)) {68ctx->so->bindless_ibo = true;69return ir3_get_src(ctx, &src)[0];70} else {71/* can this be non-const buffer_index? how do we handle that? */72int image_idx = nir_src_as_uint(src);73return create_immed(ctx->block, ctx->s->info.num_ssbos + image_idx);74}75}7677unsigned78ir3_image_to_tex(struct ir3_ibo_mapping *mapping, unsigned image)79{80if (mapping->image_to_tex[image] == IBO_INVALID) {81unsigned tex = mapping->num_tex++;82mapping->image_to_tex[image] = tex;83mapping->tex_to_image[tex] = image;84}85return mapping->image_to_tex[image] + mapping->tex_base;86}8788/* see tex_info() for equiv logic for texture instructions.. it would be89* nice if this could be better unified..90*/91unsigned92ir3_get_image_coords(const nir_intrinsic_instr *instr, unsigned *flagsp)93{94unsigned coords = nir_image_intrinsic_coord_components(instr);95unsigned flags = 0;9697if (coords == 3)98flags |= IR3_INSTR_3D;99100if (nir_intrinsic_image_array(instr))101flags |= IR3_INSTR_A;102103if (flagsp)104*flagsp = flags;105106return coords;107}108109type_t110ir3_get_type_for_image_intrinsic(const nir_intrinsic_instr *instr)111{112const nir_intrinsic_info *info = &nir_intrinsic_infos[instr->intrinsic];113int bit_size = info->has_dest ? nir_dest_bit_size(instr->dest) : 32;114115nir_alu_type type = nir_type_uint;116switch (instr->intrinsic) {117case nir_intrinsic_image_load:118case nir_intrinsic_bindless_image_load:119type = nir_alu_type_get_base_type(nir_intrinsic_dest_type(instr));120/* SpvOpAtomicLoad doesn't have dest type */121if (type == nir_type_invalid)122type = nir_type_uint;123break;124125case nir_intrinsic_image_store:126case nir_intrinsic_bindless_image_store:127type = nir_alu_type_get_base_type(nir_intrinsic_src_type(instr));128/* SpvOpAtomicStore doesn't have src type */129if (type == nir_type_invalid)130type = nir_type_uint;131break;132133case nir_intrinsic_image_atomic_add:134case nir_intrinsic_bindless_image_atomic_add:135case nir_intrinsic_image_atomic_umin:136case nir_intrinsic_bindless_image_atomic_umin:137case nir_intrinsic_image_atomic_umax:138case nir_intrinsic_bindless_image_atomic_umax:139case nir_intrinsic_image_atomic_and:140case nir_intrinsic_bindless_image_atomic_and:141case nir_intrinsic_image_atomic_or:142case nir_intrinsic_bindless_image_atomic_or:143case nir_intrinsic_image_atomic_xor:144case nir_intrinsic_bindless_image_atomic_xor:145case nir_intrinsic_image_atomic_exchange:146case nir_intrinsic_bindless_image_atomic_exchange:147case nir_intrinsic_image_atomic_comp_swap:148case nir_intrinsic_bindless_image_atomic_comp_swap:149case nir_intrinsic_image_atomic_inc_wrap:150case nir_intrinsic_bindless_image_atomic_inc_wrap:151type = nir_type_uint;152break;153154case nir_intrinsic_image_atomic_imin:155case nir_intrinsic_bindless_image_atomic_imin:156case nir_intrinsic_image_atomic_imax:157case nir_intrinsic_bindless_image_atomic_imax:158type = nir_type_int;159break;160161default:162unreachable("Unhandled NIR image intrinsic");163}164165switch (type) {166case nir_type_uint:167return bit_size == 16 ? TYPE_U16 : TYPE_U32;168case nir_type_int:169return bit_size == 16 ? TYPE_S16 : TYPE_S32;170case nir_type_float:171return bit_size == 16 ? TYPE_F16 : TYPE_F32;172default:173unreachable("bad type");174}175}176177/* Returns the number of components for the different image formats178* supported by the GLES 3.1 spec, plus those added by the179* GL_NV_image_formats extension.180*/181unsigned182ir3_get_num_components_for_image_format(enum pipe_format format)183{184if (format == PIPE_FORMAT_NONE)185return 4;186else187return util_format_get_nr_components(format);188}189190191