1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © 2021 Google 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 13bf215546Sopenharmony_ci * Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21bf215546Sopenharmony_ci * IN THE SOFTWARE. 22bf215546Sopenharmony_ci */ 23bf215546Sopenharmony_ci 24bf215546Sopenharmony_ci#include <assert.h> 25bf215546Sopenharmony_ci#include <stdbool.h> 26bf215546Sopenharmony_ci 27bf215546Sopenharmony_ci#include "nir/nir_builder.h" 28bf215546Sopenharmony_ci#include "radv_meta.h" 29bf215546Sopenharmony_ci#include "radv_private.h" 30bf215546Sopenharmony_ci#include "sid.h" 31bf215546Sopenharmony_ci#include "vk_format.h" 32bf215546Sopenharmony_ci 33bf215546Sopenharmony_ci/* Based on 34bf215546Sopenharmony_ci * https://github.com/Themaister/Granite/blob/master/assets/shaders/decode/etc2.comp 35bf215546Sopenharmony_ci * https://github.com/Themaister/Granite/blob/master/assets/shaders/decode/eac.comp 36bf215546Sopenharmony_ci * 37bf215546Sopenharmony_ci * With some differences: 38bf215546Sopenharmony_ci * - Use the vk format to do all the settings. 39bf215546Sopenharmony_ci * - Combine the ETC2 and EAC shaders. 40bf215546Sopenharmony_ci * - Since we combined the above, reuse the function for the ETC2 A8 component. 41bf215546Sopenharmony_ci * - the EAC shader doesn't do SNORM correctly, so this has that fixed. 42bf215546Sopenharmony_ci */ 43bf215546Sopenharmony_ci 44bf215546Sopenharmony_cistatic nir_ssa_def * 45bf215546Sopenharmony_ciflip_endian(nir_builder *b, nir_ssa_def *src, unsigned cnt) 46bf215546Sopenharmony_ci{ 47bf215546Sopenharmony_ci nir_ssa_def *v[2]; 48bf215546Sopenharmony_ci for (unsigned i = 0; i < cnt; ++i) { 49bf215546Sopenharmony_ci nir_ssa_def *intermediate[4]; 50bf215546Sopenharmony_ci nir_ssa_def *chan = cnt == 1 ? src : nir_channel(b, src, i); 51bf215546Sopenharmony_ci for (unsigned j = 0; j < 4; ++j) 52bf215546Sopenharmony_ci intermediate[j] = nir_ubfe_imm(b, chan, 8 * j, 8); 53bf215546Sopenharmony_ci v[i] = nir_ior( 54bf215546Sopenharmony_ci b, nir_ior(b, nir_ishl_imm(b, intermediate[0], 24), nir_ishl_imm(b, intermediate[1], 16)), 55bf215546Sopenharmony_ci nir_ior(b, nir_ishl_imm(b, intermediate[2], 8), nir_ishl_imm(b, intermediate[3], 0))); 56bf215546Sopenharmony_ci } 57bf215546Sopenharmony_ci return cnt == 1 ? v[0] : nir_vec(b, v, cnt); 58bf215546Sopenharmony_ci} 59bf215546Sopenharmony_ci 60bf215546Sopenharmony_cistatic nir_ssa_def * 61bf215546Sopenharmony_cietc1_color_modifier_lookup(nir_builder *b, nir_ssa_def *x, nir_ssa_def *y) 62bf215546Sopenharmony_ci{ 63bf215546Sopenharmony_ci const unsigned table[8][2] = {{2, 8}, {5, 17}, {9, 29}, {13, 42}, 64bf215546Sopenharmony_ci {18, 60}, {24, 80}, {33, 106}, {47, 183}}; 65bf215546Sopenharmony_ci nir_ssa_def *upper = nir_ieq_imm(b, y, 1); 66bf215546Sopenharmony_ci nir_ssa_def *result = NULL; 67bf215546Sopenharmony_ci for (unsigned i = 0; i < 8; ++i) { 68bf215546Sopenharmony_ci nir_ssa_def *tmp = 69bf215546Sopenharmony_ci nir_bcsel(b, upper, nir_imm_int(b, table[i][1]), nir_imm_int(b, table[i][0])); 70bf215546Sopenharmony_ci if (result) 71bf215546Sopenharmony_ci result = nir_bcsel(b, nir_ieq_imm(b, x, i), tmp, result); 72bf215546Sopenharmony_ci else 73bf215546Sopenharmony_ci result = tmp; 74bf215546Sopenharmony_ci } 75bf215546Sopenharmony_ci return result; 76bf215546Sopenharmony_ci} 77bf215546Sopenharmony_ci 78bf215546Sopenharmony_cistatic nir_ssa_def * 79bf215546Sopenharmony_cietc2_distance_lookup(nir_builder *b, nir_ssa_def *x) 80bf215546Sopenharmony_ci{ 81bf215546Sopenharmony_ci const unsigned table[8] = {3, 6, 11, 16, 23, 32, 41, 64}; 82bf215546Sopenharmony_ci nir_ssa_def *result = NULL; 83bf215546Sopenharmony_ci for (unsigned i = 0; i < 8; ++i) { 84bf215546Sopenharmony_ci if (result) 85bf215546Sopenharmony_ci result = nir_bcsel(b, nir_ieq_imm(b, x, i), nir_imm_int(b, table[i]), result); 86bf215546Sopenharmony_ci else 87bf215546Sopenharmony_ci result = nir_imm_int(b, table[i]); 88bf215546Sopenharmony_ci } 89bf215546Sopenharmony_ci return result; 90bf215546Sopenharmony_ci} 91bf215546Sopenharmony_ci 92bf215546Sopenharmony_cistatic nir_ssa_def * 93bf215546Sopenharmony_cietc1_alpha_modifier_lookup(nir_builder *b, nir_ssa_def *x, nir_ssa_def *y) 94bf215546Sopenharmony_ci{ 95bf215546Sopenharmony_ci const unsigned table[16] = {0xe852, 0xc962, 0xc741, 0xc531, 0xb752, 0xa862, 0xa763, 0xa742, 96bf215546Sopenharmony_ci 0x9751, 0x9741, 0x9731, 0x9641, 0x9632, 0x9210, 0x8753, 0x8642}; 97bf215546Sopenharmony_ci nir_ssa_def *result = NULL; 98bf215546Sopenharmony_ci for (unsigned i = 0; i < 16; ++i) { 99bf215546Sopenharmony_ci nir_ssa_def *tmp = nir_imm_int(b, table[i]); 100bf215546Sopenharmony_ci if (result) 101bf215546Sopenharmony_ci result = nir_bcsel(b, nir_ieq_imm(b, x, i), tmp, result); 102bf215546Sopenharmony_ci else 103bf215546Sopenharmony_ci result = tmp; 104bf215546Sopenharmony_ci } 105bf215546Sopenharmony_ci return nir_ubfe(b, result, nir_imul_imm(b, y, 4), nir_imm_int(b, 4)); 106bf215546Sopenharmony_ci} 107bf215546Sopenharmony_ci 108bf215546Sopenharmony_cistatic nir_ssa_def * 109bf215546Sopenharmony_cietc_extend(nir_builder *b, nir_ssa_def *v, int bits) 110bf215546Sopenharmony_ci{ 111bf215546Sopenharmony_ci if (bits == 4) 112bf215546Sopenharmony_ci return nir_imul_imm(b, v, 0x11); 113bf215546Sopenharmony_ci return nir_ior(b, nir_ishl_imm(b, v, 8 - bits), nir_ushr_imm(b, v, bits - (8 - bits))); 114bf215546Sopenharmony_ci} 115bf215546Sopenharmony_ci 116bf215546Sopenharmony_cistatic nir_ssa_def * 117bf215546Sopenharmony_cidecode_etc2_alpha(struct nir_builder *b, nir_ssa_def *alpha_payload, nir_ssa_def *linear_pixel, 118bf215546Sopenharmony_ci bool eac, nir_ssa_def *is_signed) 119bf215546Sopenharmony_ci{ 120bf215546Sopenharmony_ci alpha_payload = flip_endian(b, alpha_payload, 2); 121bf215546Sopenharmony_ci nir_ssa_def *alpha_x = nir_channel(b, alpha_payload, 1); 122bf215546Sopenharmony_ci nir_ssa_def *alpha_y = nir_channel(b, alpha_payload, 0); 123bf215546Sopenharmony_ci nir_ssa_def *bit_offset = nir_isub_imm(b, 45, nir_imul_imm(b, linear_pixel, 3)); 124bf215546Sopenharmony_ci nir_ssa_def *base = nir_ubfe_imm(b, alpha_y, 24, 8); 125bf215546Sopenharmony_ci nir_ssa_def *multiplier = nir_ubfe_imm(b, alpha_y, 20, 4); 126bf215546Sopenharmony_ci nir_ssa_def *table = nir_ubfe_imm(b, alpha_y, 16, 4); 127bf215546Sopenharmony_ci 128bf215546Sopenharmony_ci if (eac) { 129bf215546Sopenharmony_ci nir_ssa_def *signed_base = nir_ibfe_imm(b, alpha_y, 24, 8); 130bf215546Sopenharmony_ci signed_base = nir_imul_imm(b, signed_base, 8); 131bf215546Sopenharmony_ci base = nir_iadd_imm(b, nir_imul_imm(b, base, 8), 4); 132bf215546Sopenharmony_ci base = nir_bcsel(b, is_signed, signed_base, base); 133bf215546Sopenharmony_ci multiplier = nir_imax(b, nir_imul_imm(b, multiplier, 8), nir_imm_int(b, 1)); 134bf215546Sopenharmony_ci } 135bf215546Sopenharmony_ci 136bf215546Sopenharmony_ci nir_ssa_def *lsb_index = 137bf215546Sopenharmony_ci nir_ubfe(b, nir_bcsel(b, nir_uge(b, bit_offset, nir_imm_int(b, 32)), alpha_y, alpha_x), 138bf215546Sopenharmony_ci nir_iand_imm(b, bit_offset, 31), nir_imm_int(b, 2)); 139bf215546Sopenharmony_ci bit_offset = nir_iadd_imm(b, bit_offset, 2); 140bf215546Sopenharmony_ci nir_ssa_def *msb = 141bf215546Sopenharmony_ci nir_ubfe(b, nir_bcsel(b, nir_uge(b, bit_offset, nir_imm_int(b, 32)), alpha_y, alpha_x), 142bf215546Sopenharmony_ci nir_iand_imm(b, bit_offset, 31), nir_imm_int(b, 1)); 143bf215546Sopenharmony_ci nir_ssa_def *mod = 144bf215546Sopenharmony_ci nir_ixor(b, etc1_alpha_modifier_lookup(b, table, lsb_index), nir_iadd_imm(b, msb, -1)); 145bf215546Sopenharmony_ci nir_ssa_def *a = nir_iadd(b, base, nir_imul(b, mod, multiplier)); 146bf215546Sopenharmony_ci 147bf215546Sopenharmony_ci nir_ssa_def *low_bound = nir_imm_int(b, 0); 148bf215546Sopenharmony_ci nir_ssa_def *high_bound = nir_imm_int(b, 255); 149bf215546Sopenharmony_ci nir_ssa_def *final_mult = nir_imm_float(b, 1 / 255.0); 150bf215546Sopenharmony_ci if (eac) { 151bf215546Sopenharmony_ci low_bound = nir_bcsel(b, is_signed, nir_imm_int(b, -1023), low_bound); 152bf215546Sopenharmony_ci high_bound = nir_bcsel(b, is_signed, nir_imm_int(b, 1023), nir_imm_int(b, 2047)); 153bf215546Sopenharmony_ci final_mult = 154bf215546Sopenharmony_ci nir_bcsel(b, is_signed, nir_imm_float(b, 1 / 1023.0), nir_imm_float(b, 1 / 2047.0)); 155bf215546Sopenharmony_ci } 156bf215546Sopenharmony_ci 157bf215546Sopenharmony_ci return nir_fmul(b, nir_i2f32(b, nir_iclamp(b, a, low_bound, high_bound)), final_mult); 158bf215546Sopenharmony_ci} 159bf215546Sopenharmony_ci 160bf215546Sopenharmony_cistatic nir_shader * 161bf215546Sopenharmony_cibuild_shader(struct radv_device *dev) 162bf215546Sopenharmony_ci{ 163bf215546Sopenharmony_ci const struct glsl_type *sampler_type_2d = 164bf215546Sopenharmony_ci glsl_sampler_type(GLSL_SAMPLER_DIM_2D, false, true, GLSL_TYPE_FLOAT); 165bf215546Sopenharmony_ci const struct glsl_type *sampler_type_3d = 166bf215546Sopenharmony_ci glsl_sampler_type(GLSL_SAMPLER_DIM_3D, false, false, GLSL_TYPE_FLOAT); 167bf215546Sopenharmony_ci const struct glsl_type *img_type_2d = 168bf215546Sopenharmony_ci glsl_image_type(GLSL_SAMPLER_DIM_2D, true, GLSL_TYPE_FLOAT); 169bf215546Sopenharmony_ci const struct glsl_type *img_type_3d = 170bf215546Sopenharmony_ci glsl_image_type(GLSL_SAMPLER_DIM_3D, false, GLSL_TYPE_FLOAT); 171bf215546Sopenharmony_ci nir_builder b = radv_meta_init_shader(dev, MESA_SHADER_COMPUTE, "meta_decode_etc"); 172bf215546Sopenharmony_ci b.shader->info.workgroup_size[0] = 8; 173bf215546Sopenharmony_ci b.shader->info.workgroup_size[1] = 8; 174bf215546Sopenharmony_ci 175bf215546Sopenharmony_ci nir_variable *input_img_2d = 176bf215546Sopenharmony_ci nir_variable_create(b.shader, nir_var_uniform, sampler_type_2d, "s_tex_2d"); 177bf215546Sopenharmony_ci input_img_2d->data.descriptor_set = 0; 178bf215546Sopenharmony_ci input_img_2d->data.binding = 0; 179bf215546Sopenharmony_ci 180bf215546Sopenharmony_ci nir_variable *input_img_3d = 181bf215546Sopenharmony_ci nir_variable_create(b.shader, nir_var_uniform, sampler_type_3d, "s_tex_3d"); 182bf215546Sopenharmony_ci input_img_2d->data.descriptor_set = 0; 183bf215546Sopenharmony_ci input_img_2d->data.binding = 0; 184bf215546Sopenharmony_ci 185bf215546Sopenharmony_ci nir_variable *output_img_2d = 186bf215546Sopenharmony_ci nir_variable_create(b.shader, nir_var_image, img_type_2d, "out_img_2d"); 187bf215546Sopenharmony_ci output_img_2d->data.descriptor_set = 0; 188bf215546Sopenharmony_ci output_img_2d->data.binding = 1; 189bf215546Sopenharmony_ci 190bf215546Sopenharmony_ci nir_variable *output_img_3d = 191bf215546Sopenharmony_ci nir_variable_create(b.shader, nir_var_image, img_type_3d, "out_img_3d"); 192bf215546Sopenharmony_ci output_img_3d->data.descriptor_set = 0; 193bf215546Sopenharmony_ci output_img_3d->data.binding = 1; 194bf215546Sopenharmony_ci 195bf215546Sopenharmony_ci nir_ssa_def *global_id = get_global_ids(&b, 3); 196bf215546Sopenharmony_ci 197bf215546Sopenharmony_ci nir_ssa_def *consts = nir_load_push_constant(&b, 4, 32, nir_imm_int(&b, 0), .range = 16); 198bf215546Sopenharmony_ci nir_ssa_def *consts2 = 199bf215546Sopenharmony_ci nir_load_push_constant(&b, 1, 32, nir_imm_int(&b, 0), .base = 0, .range = 4); 200bf215546Sopenharmony_ci nir_ssa_def *offset = nir_channels(&b, consts, 7); 201bf215546Sopenharmony_ci nir_ssa_def *format = nir_channel(&b, consts, 3); 202bf215546Sopenharmony_ci nir_ssa_def *image_type = nir_channel(&b, consts2, 0); 203bf215546Sopenharmony_ci nir_ssa_def *is_3d = nir_ieq_imm(&b, image_type, VK_IMAGE_TYPE_3D); 204bf215546Sopenharmony_ci nir_ssa_def *coord = nir_iadd(&b, global_id, offset); 205bf215546Sopenharmony_ci nir_ssa_def *src_coord = 206bf215546Sopenharmony_ci nir_vec3(&b, nir_ushr_imm(&b, nir_channel(&b, coord, 0), 2), 207bf215546Sopenharmony_ci nir_ushr_imm(&b, nir_channel(&b, coord, 1), 2), nir_channel(&b, coord, 2)); 208bf215546Sopenharmony_ci 209bf215546Sopenharmony_ci nir_variable *payload_var = 210bf215546Sopenharmony_ci nir_variable_create(b.shader, nir_var_shader_temp, glsl_vec4_type(), "payload"); 211bf215546Sopenharmony_ci nir_push_if(&b, is_3d); 212bf215546Sopenharmony_ci { 213bf215546Sopenharmony_ci nir_ssa_def *tex_deref = &nir_build_deref_var(&b, input_img_3d)->dest.ssa; 214bf215546Sopenharmony_ci 215bf215546Sopenharmony_ci nir_tex_instr *tex = nir_tex_instr_create(b.shader, 3); 216bf215546Sopenharmony_ci tex->sampler_dim = GLSL_SAMPLER_DIM_3D; 217bf215546Sopenharmony_ci tex->op = nir_texop_txf; 218bf215546Sopenharmony_ci tex->src[0].src_type = nir_tex_src_coord; 219bf215546Sopenharmony_ci tex->src[0].src = nir_src_for_ssa(src_coord); 220bf215546Sopenharmony_ci tex->src[1].src_type = nir_tex_src_lod; 221bf215546Sopenharmony_ci tex->src[1].src = nir_src_for_ssa(nir_imm_int(&b, 0)); 222bf215546Sopenharmony_ci tex->src[2].src_type = nir_tex_src_texture_deref; 223bf215546Sopenharmony_ci tex->src[2].src = nir_src_for_ssa(tex_deref); 224bf215546Sopenharmony_ci tex->dest_type = nir_type_uint32; 225bf215546Sopenharmony_ci tex->is_array = false; 226bf215546Sopenharmony_ci tex->coord_components = 3; 227bf215546Sopenharmony_ci 228bf215546Sopenharmony_ci nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, "tex"); 229bf215546Sopenharmony_ci nir_builder_instr_insert(&b, &tex->instr); 230bf215546Sopenharmony_ci nir_store_var(&b, payload_var, &tex->dest.ssa, 0xf); 231bf215546Sopenharmony_ci } 232bf215546Sopenharmony_ci nir_push_else(&b, NULL); 233bf215546Sopenharmony_ci { 234bf215546Sopenharmony_ci nir_ssa_def *tex_deref = &nir_build_deref_var(&b, input_img_2d)->dest.ssa; 235bf215546Sopenharmony_ci 236bf215546Sopenharmony_ci nir_tex_instr *tex = nir_tex_instr_create(b.shader, 3); 237bf215546Sopenharmony_ci tex->sampler_dim = GLSL_SAMPLER_DIM_2D; 238bf215546Sopenharmony_ci tex->op = nir_texop_txf; 239bf215546Sopenharmony_ci tex->src[0].src_type = nir_tex_src_coord; 240bf215546Sopenharmony_ci tex->src[0].src = nir_src_for_ssa(src_coord); 241bf215546Sopenharmony_ci tex->src[1].src_type = nir_tex_src_lod; 242bf215546Sopenharmony_ci tex->src[1].src = nir_src_for_ssa(nir_imm_int(&b, 0)); 243bf215546Sopenharmony_ci tex->src[2].src_type = nir_tex_src_texture_deref; 244bf215546Sopenharmony_ci tex->src[2].src = nir_src_for_ssa(tex_deref); 245bf215546Sopenharmony_ci tex->dest_type = nir_type_uint32; 246bf215546Sopenharmony_ci tex->is_array = true; 247bf215546Sopenharmony_ci tex->coord_components = 3; 248bf215546Sopenharmony_ci 249bf215546Sopenharmony_ci nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, "tex"); 250bf215546Sopenharmony_ci nir_builder_instr_insert(&b, &tex->instr); 251bf215546Sopenharmony_ci nir_store_var(&b, payload_var, &tex->dest.ssa, 0xf); 252bf215546Sopenharmony_ci } 253bf215546Sopenharmony_ci nir_pop_if(&b, NULL); 254bf215546Sopenharmony_ci 255bf215546Sopenharmony_ci nir_ssa_def *pixel_coord = nir_iand_imm(&b, nir_channels(&b, coord, 3), 3); 256bf215546Sopenharmony_ci nir_ssa_def *linear_pixel = nir_iadd(&b, nir_imul_imm(&b, nir_channel(&b, pixel_coord, 0), 4), 257bf215546Sopenharmony_ci nir_channel(&b, pixel_coord, 1)); 258bf215546Sopenharmony_ci 259bf215546Sopenharmony_ci nir_ssa_def *payload = nir_load_var(&b, payload_var); 260bf215546Sopenharmony_ci nir_variable *color = 261bf215546Sopenharmony_ci nir_variable_create(b.shader, nir_var_shader_temp, glsl_vec4_type(), "color"); 262bf215546Sopenharmony_ci nir_store_var(&b, color, nir_imm_vec4(&b, 1.0, 0.0, 0.0, 1.0), 0xf); 263bf215546Sopenharmony_ci nir_push_if(&b, nir_ilt(&b, format, nir_imm_int(&b, VK_FORMAT_EAC_R11_UNORM_BLOCK))); 264bf215546Sopenharmony_ci { 265bf215546Sopenharmony_ci nir_ssa_def *alpha_bits_8 = 266bf215546Sopenharmony_ci nir_ige(&b, format, nir_imm_int(&b, VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK)); 267bf215546Sopenharmony_ci nir_ssa_def *alpha_bits_1 = 268bf215546Sopenharmony_ci nir_iand(&b, nir_ige(&b, format, nir_imm_int(&b, VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK)), 269bf215546Sopenharmony_ci nir_ilt(&b, format, nir_imm_int(&b, VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK))); 270bf215546Sopenharmony_ci 271bf215546Sopenharmony_ci nir_ssa_def *color_payload = 272bf215546Sopenharmony_ci nir_bcsel(&b, alpha_bits_8, nir_channels(&b, payload, 0xC), nir_channels(&b, payload, 3)); 273bf215546Sopenharmony_ci color_payload = flip_endian(&b, color_payload, 2); 274bf215546Sopenharmony_ci nir_ssa_def *color_y = nir_channel(&b, color_payload, 0); 275bf215546Sopenharmony_ci nir_ssa_def *color_x = nir_channel(&b, color_payload, 1); 276bf215546Sopenharmony_ci nir_ssa_def *flip = nir_test_mask(&b, color_y, 1); 277bf215546Sopenharmony_ci nir_ssa_def *subblock = nir_ushr_imm( 278bf215546Sopenharmony_ci &b, nir_bcsel(&b, flip, nir_channel(&b, pixel_coord, 1), nir_channel(&b, pixel_coord, 0)), 279bf215546Sopenharmony_ci 1); 280bf215546Sopenharmony_ci 281bf215546Sopenharmony_ci nir_variable *punchthrough = 282bf215546Sopenharmony_ci nir_variable_create(b.shader, nir_var_shader_temp, glsl_bool_type(), "punchthrough"); 283bf215546Sopenharmony_ci nir_ssa_def *punchthrough_init = 284bf215546Sopenharmony_ci nir_iand(&b, alpha_bits_1, nir_inot(&b, nir_test_mask(&b, color_y, 2))); 285bf215546Sopenharmony_ci nir_store_var(&b, punchthrough, punchthrough_init, 0x1); 286bf215546Sopenharmony_ci 287bf215546Sopenharmony_ci nir_variable *etc1_compat = 288bf215546Sopenharmony_ci nir_variable_create(b.shader, nir_var_shader_temp, glsl_bool_type(), "etc1_compat"); 289bf215546Sopenharmony_ci nir_store_var(&b, etc1_compat, nir_imm_bool(&b, false), 0x1); 290bf215546Sopenharmony_ci 291bf215546Sopenharmony_ci nir_variable *alpha_result = 292bf215546Sopenharmony_ci nir_variable_create(b.shader, nir_var_shader_temp, glsl_float_type(), "alpha_result"); 293bf215546Sopenharmony_ci nir_push_if(&b, alpha_bits_8); 294bf215546Sopenharmony_ci { 295bf215546Sopenharmony_ci nir_store_var( 296bf215546Sopenharmony_ci &b, alpha_result, 297bf215546Sopenharmony_ci decode_etc2_alpha(&b, nir_channels(&b, payload, 3), linear_pixel, false, NULL), 1); 298bf215546Sopenharmony_ci } 299bf215546Sopenharmony_ci nir_push_else(&b, NULL); 300bf215546Sopenharmony_ci { 301bf215546Sopenharmony_ci nir_store_var(&b, alpha_result, nir_imm_float(&b, 1.0), 1); 302bf215546Sopenharmony_ci } 303bf215546Sopenharmony_ci nir_pop_if(&b, NULL); 304bf215546Sopenharmony_ci 305bf215546Sopenharmony_ci const struct glsl_type *uvec3_type = glsl_vector_type(GLSL_TYPE_UINT, 3); 306bf215546Sopenharmony_ci nir_variable *rgb_result = 307bf215546Sopenharmony_ci nir_variable_create(b.shader, nir_var_shader_temp, uvec3_type, "rgb_result"); 308bf215546Sopenharmony_ci nir_variable *base_rgb = 309bf215546Sopenharmony_ci nir_variable_create(b.shader, nir_var_shader_temp, uvec3_type, "base_rgb"); 310bf215546Sopenharmony_ci nir_store_var(&b, rgb_result, nir_imm_ivec3(&b, 255, 0, 0), 0x7); 311bf215546Sopenharmony_ci 312bf215546Sopenharmony_ci nir_ssa_def *msb = 313bf215546Sopenharmony_ci nir_iand_imm(&b, nir_ushr(&b, color_x, nir_iadd_imm(&b, linear_pixel, 15)), 2); 314bf215546Sopenharmony_ci nir_ssa_def *lsb = nir_iand_imm(&b, nir_ushr(&b, color_x, linear_pixel), 1); 315bf215546Sopenharmony_ci 316bf215546Sopenharmony_ci nir_push_if( 317bf215546Sopenharmony_ci &b, nir_iand(&b, nir_inot(&b, alpha_bits_1), nir_inot(&b, nir_test_mask(&b, color_y, 2)))); 318bf215546Sopenharmony_ci { 319bf215546Sopenharmony_ci nir_store_var(&b, etc1_compat, nir_imm_bool(&b, true), 1); 320bf215546Sopenharmony_ci nir_ssa_def *tmp[3]; 321bf215546Sopenharmony_ci for (unsigned i = 0; i < 3; ++i) 322bf215546Sopenharmony_ci tmp[i] = etc_extend( 323bf215546Sopenharmony_ci &b, 324bf215546Sopenharmony_ci nir_iand_imm(&b, 325bf215546Sopenharmony_ci nir_ushr(&b, color_y, 326bf215546Sopenharmony_ci nir_isub_imm(&b, 28 - 8 * i, nir_imul_imm(&b, subblock, 4))), 327bf215546Sopenharmony_ci 0xf), 328bf215546Sopenharmony_ci 4); 329bf215546Sopenharmony_ci nir_store_var(&b, base_rgb, nir_vec(&b, tmp, 3), 0x7); 330bf215546Sopenharmony_ci } 331bf215546Sopenharmony_ci nir_push_else(&b, NULL); 332bf215546Sopenharmony_ci { 333bf215546Sopenharmony_ci nir_ssa_def *rb = nir_ubfe_imm(&b, color_y, 27, 5); 334bf215546Sopenharmony_ci nir_ssa_def *rd = nir_ibfe_imm(&b, color_y, 24, 3); 335bf215546Sopenharmony_ci nir_ssa_def *gb = nir_ubfe_imm(&b, color_y, 19, 5); 336bf215546Sopenharmony_ci nir_ssa_def *gd = nir_ibfe_imm(&b, color_y, 16, 3); 337bf215546Sopenharmony_ci nir_ssa_def *bb = nir_ubfe_imm(&b, color_y, 11, 5); 338bf215546Sopenharmony_ci nir_ssa_def *bd = nir_ibfe_imm(&b, color_y, 8, 3); 339bf215546Sopenharmony_ci nir_ssa_def *r1 = nir_iadd(&b, rb, rd); 340bf215546Sopenharmony_ci nir_ssa_def *g1 = nir_iadd(&b, gb, gd); 341bf215546Sopenharmony_ci nir_ssa_def *b1 = nir_iadd(&b, bb, bd); 342bf215546Sopenharmony_ci 343bf215546Sopenharmony_ci nir_push_if(&b, nir_ult(&b, nir_imm_int(&b, 31), r1)); 344bf215546Sopenharmony_ci { 345bf215546Sopenharmony_ci nir_ssa_def *r0 = nir_ior(&b, nir_ubfe_imm(&b, color_y, 24, 2), 346bf215546Sopenharmony_ci nir_ishl_imm(&b, nir_ubfe_imm(&b, color_y, 27, 2), 2)); 347bf215546Sopenharmony_ci nir_ssa_def *g0 = nir_ubfe_imm(&b, color_y, 20, 4); 348bf215546Sopenharmony_ci nir_ssa_def *b0 = nir_ubfe_imm(&b, color_y, 16, 4); 349bf215546Sopenharmony_ci nir_ssa_def *r2 = nir_ubfe_imm(&b, color_y, 12, 4); 350bf215546Sopenharmony_ci nir_ssa_def *g2 = nir_ubfe_imm(&b, color_y, 8, 4); 351bf215546Sopenharmony_ci nir_ssa_def *b2 = nir_ubfe_imm(&b, color_y, 4, 4); 352bf215546Sopenharmony_ci nir_ssa_def *da = nir_ior(&b, nir_ishl_imm(&b, nir_ubfe_imm(&b, color_y, 2, 2), 1), 353bf215546Sopenharmony_ci nir_iand_imm(&b, color_y, 1)); 354bf215546Sopenharmony_ci nir_ssa_def *dist = etc2_distance_lookup(&b, da); 355bf215546Sopenharmony_ci nir_ssa_def *index = nir_ior(&b, lsb, msb); 356bf215546Sopenharmony_ci 357bf215546Sopenharmony_ci nir_store_var(&b, punchthrough, 358bf215546Sopenharmony_ci nir_iand(&b, nir_load_var(&b, punchthrough), 359bf215546Sopenharmony_ci nir_ieq_imm(&b, nir_iadd(&b, lsb, msb), 2)), 360bf215546Sopenharmony_ci 0x1); 361bf215546Sopenharmony_ci nir_push_if(&b, nir_ieq_imm(&b, index, 0)); 362bf215546Sopenharmony_ci { 363bf215546Sopenharmony_ci nir_store_var(&b, rgb_result, etc_extend(&b, nir_vec3(&b, r0, g0, b0), 4), 0x7); 364bf215546Sopenharmony_ci } 365bf215546Sopenharmony_ci nir_push_else(&b, NULL); 366bf215546Sopenharmony_ci { 367bf215546Sopenharmony_ci 368bf215546Sopenharmony_ci nir_ssa_def *tmp = nir_iadd(&b, etc_extend(&b, nir_vec3(&b, r2, g2, b2), 4), 369bf215546Sopenharmony_ci nir_imul(&b, dist, nir_isub_imm(&b, 2, index))); 370bf215546Sopenharmony_ci nir_store_var(&b, rgb_result, tmp, 0x7); 371bf215546Sopenharmony_ci } 372bf215546Sopenharmony_ci nir_pop_if(&b, NULL); 373bf215546Sopenharmony_ci } 374bf215546Sopenharmony_ci nir_push_else(&b, NULL); 375bf215546Sopenharmony_ci nir_push_if(&b, nir_ult(&b, nir_imm_int(&b, 31), g1)); 376bf215546Sopenharmony_ci { 377bf215546Sopenharmony_ci nir_ssa_def *r0 = nir_ubfe_imm(&b, color_y, 27, 4); 378bf215546Sopenharmony_ci nir_ssa_def *g0 = nir_ior(&b, nir_ishl_imm(&b, nir_ubfe_imm(&b, color_y, 24, 3), 1), 379bf215546Sopenharmony_ci nir_iand_imm(&b, nir_ushr_imm(&b, color_y, 20), 1)); 380bf215546Sopenharmony_ci nir_ssa_def *b0 = nir_ior(&b, nir_ubfe_imm(&b, color_y, 15, 3), 381bf215546Sopenharmony_ci nir_iand_imm(&b, nir_ushr_imm(&b, color_y, 16), 8)); 382bf215546Sopenharmony_ci nir_ssa_def *r2 = nir_ubfe_imm(&b, color_y, 11, 4); 383bf215546Sopenharmony_ci nir_ssa_def *g2 = nir_ubfe_imm(&b, color_y, 7, 4); 384bf215546Sopenharmony_ci nir_ssa_def *b2 = nir_ubfe_imm(&b, color_y, 3, 4); 385bf215546Sopenharmony_ci nir_ssa_def *da = nir_iand_imm(&b, color_y, 4); 386bf215546Sopenharmony_ci nir_ssa_def *db = nir_iand_imm(&b, color_y, 1); 387bf215546Sopenharmony_ci nir_ssa_def *d = nir_iadd(&b, da, nir_imul_imm(&b, db, 2)); 388bf215546Sopenharmony_ci nir_ssa_def *d0 = 389bf215546Sopenharmony_ci nir_iadd(&b, nir_ishl_imm(&b, r0, 16), nir_iadd(&b, nir_ishl_imm(&b, g0, 8), b0)); 390bf215546Sopenharmony_ci nir_ssa_def *d2 = 391bf215546Sopenharmony_ci nir_iadd(&b, nir_ishl_imm(&b, r2, 16), nir_iadd(&b, nir_ishl_imm(&b, g2, 8), b2)); 392bf215546Sopenharmony_ci d = nir_bcsel(&b, nir_uge(&b, d0, d2), nir_iadd_imm(&b, d, 1), d); 393bf215546Sopenharmony_ci nir_ssa_def *dist = etc2_distance_lookup(&b, d); 394bf215546Sopenharmony_ci nir_ssa_def *base = nir_bcsel(&b, nir_ine_imm(&b, msb, 0), nir_vec3(&b, r2, g2, b2), 395bf215546Sopenharmony_ci nir_vec3(&b, r0, g0, b0)); 396bf215546Sopenharmony_ci base = etc_extend(&b, base, 4); 397bf215546Sopenharmony_ci base = nir_iadd(&b, base, 398bf215546Sopenharmony_ci nir_imul(&b, dist, nir_isub_imm(&b, 1, nir_imul_imm(&b, lsb, 2)))); 399bf215546Sopenharmony_ci nir_store_var(&b, rgb_result, base, 0x7); 400bf215546Sopenharmony_ci nir_store_var(&b, punchthrough, 401bf215546Sopenharmony_ci nir_iand(&b, nir_load_var(&b, punchthrough), 402bf215546Sopenharmony_ci nir_ieq_imm(&b, nir_iadd(&b, lsb, msb), 2)), 403bf215546Sopenharmony_ci 0x1); 404bf215546Sopenharmony_ci } 405bf215546Sopenharmony_ci nir_push_else(&b, NULL); 406bf215546Sopenharmony_ci nir_push_if(&b, nir_ult(&b, nir_imm_int(&b, 31), b1)); 407bf215546Sopenharmony_ci { 408bf215546Sopenharmony_ci nir_ssa_def *r0 = nir_ubfe_imm(&b, color_y, 25, 6); 409bf215546Sopenharmony_ci nir_ssa_def *g0 = nir_ior(&b, nir_ubfe_imm(&b, color_y, 17, 6), 410bf215546Sopenharmony_ci nir_iand_imm(&b, nir_ushr_imm(&b, color_y, 18), 0x40)); 411bf215546Sopenharmony_ci nir_ssa_def *b0 = 412bf215546Sopenharmony_ci nir_ior(&b, nir_ishl_imm(&b, nir_ubfe_imm(&b, color_y, 11, 2), 3), 413bf215546Sopenharmony_ci nir_ior(&b, nir_iand_imm(&b, nir_ushr_imm(&b, color_y, 11), 0x20), 414bf215546Sopenharmony_ci nir_ubfe_imm(&b, color_y, 7, 3))); 415bf215546Sopenharmony_ci nir_ssa_def *rh = nir_ior(&b, nir_iand_imm(&b, color_y, 1), 416bf215546Sopenharmony_ci nir_ishl_imm(&b, nir_ubfe_imm(&b, color_y, 2, 5), 1)); 417bf215546Sopenharmony_ci nir_ssa_def *rv = nir_ubfe_imm(&b, color_x, 13, 6); 418bf215546Sopenharmony_ci nir_ssa_def *gh = nir_ubfe_imm(&b, color_x, 25, 7); 419bf215546Sopenharmony_ci nir_ssa_def *gv = nir_ubfe_imm(&b, color_x, 6, 7); 420bf215546Sopenharmony_ci nir_ssa_def *bh = nir_ubfe_imm(&b, color_x, 19, 6); 421bf215546Sopenharmony_ci nir_ssa_def *bv = nir_ubfe_imm(&b, color_x, 0, 6); 422bf215546Sopenharmony_ci 423bf215546Sopenharmony_ci r0 = etc_extend(&b, r0, 6); 424bf215546Sopenharmony_ci g0 = etc_extend(&b, g0, 7); 425bf215546Sopenharmony_ci b0 = etc_extend(&b, b0, 6); 426bf215546Sopenharmony_ci rh = etc_extend(&b, rh, 6); 427bf215546Sopenharmony_ci rv = etc_extend(&b, rv, 6); 428bf215546Sopenharmony_ci gh = etc_extend(&b, gh, 7); 429bf215546Sopenharmony_ci gv = etc_extend(&b, gv, 7); 430bf215546Sopenharmony_ci bh = etc_extend(&b, bh, 6); 431bf215546Sopenharmony_ci bv = etc_extend(&b, bv, 6); 432bf215546Sopenharmony_ci 433bf215546Sopenharmony_ci nir_ssa_def *rgb = nir_vec3(&b, r0, g0, b0); 434bf215546Sopenharmony_ci nir_ssa_def *dx = nir_imul(&b, nir_isub(&b, nir_vec3(&b, rh, gh, bh), rgb), 435bf215546Sopenharmony_ci nir_channel(&b, pixel_coord, 0)); 436bf215546Sopenharmony_ci nir_ssa_def *dy = nir_imul(&b, nir_isub(&b, nir_vec3(&b, rv, gv, bv), rgb), 437bf215546Sopenharmony_ci nir_channel(&b, pixel_coord, 1)); 438bf215546Sopenharmony_ci rgb = nir_iadd(&b, rgb, nir_ishr_imm(&b, nir_iadd_imm(&b, nir_iadd(&b, dx, dy), 2), 2)); 439bf215546Sopenharmony_ci nir_store_var(&b, rgb_result, rgb, 0x7); 440bf215546Sopenharmony_ci nir_store_var(&b, punchthrough, nir_imm_bool(&b, false), 0x1); 441bf215546Sopenharmony_ci } 442bf215546Sopenharmony_ci nir_push_else(&b, NULL); 443bf215546Sopenharmony_ci { 444bf215546Sopenharmony_ci nir_store_var(&b, etc1_compat, nir_imm_bool(&b, true), 1); 445bf215546Sopenharmony_ci nir_ssa_def *subblock_b = nir_ine_imm(&b, subblock, 0); 446bf215546Sopenharmony_ci nir_ssa_def *tmp[] = { 447bf215546Sopenharmony_ci nir_bcsel(&b, subblock_b, r1, rb), 448bf215546Sopenharmony_ci nir_bcsel(&b, subblock_b, g1, gb), 449bf215546Sopenharmony_ci nir_bcsel(&b, subblock_b, b1, bb), 450bf215546Sopenharmony_ci }; 451bf215546Sopenharmony_ci nir_store_var(&b, base_rgb, etc_extend(&b, nir_vec(&b, tmp, 3), 5), 0x7); 452bf215546Sopenharmony_ci } 453bf215546Sopenharmony_ci nir_pop_if(&b, NULL); 454bf215546Sopenharmony_ci nir_pop_if(&b, NULL); 455bf215546Sopenharmony_ci nir_pop_if(&b, NULL); 456bf215546Sopenharmony_ci } 457bf215546Sopenharmony_ci nir_pop_if(&b, NULL); 458bf215546Sopenharmony_ci nir_push_if(&b, nir_load_var(&b, etc1_compat)); 459bf215546Sopenharmony_ci { 460bf215546Sopenharmony_ci nir_ssa_def *etc1_table_index = nir_ubfe( 461bf215546Sopenharmony_ci &b, color_y, nir_isub_imm(&b, 5, nir_imul_imm(&b, subblock, 3)), nir_imm_int(&b, 3)); 462bf215546Sopenharmony_ci nir_ssa_def *sgn = nir_isub_imm(&b, 1, msb); 463bf215546Sopenharmony_ci sgn = nir_bcsel(&b, nir_load_var(&b, punchthrough), nir_imul(&b, sgn, lsb), sgn); 464bf215546Sopenharmony_ci nir_store_var(&b, punchthrough, 465bf215546Sopenharmony_ci nir_iand(&b, nir_load_var(&b, punchthrough), 466bf215546Sopenharmony_ci nir_ieq_imm(&b, nir_iadd(&b, lsb, msb), 2)), 467bf215546Sopenharmony_ci 0x1); 468bf215546Sopenharmony_ci nir_ssa_def *off = 469bf215546Sopenharmony_ci nir_imul(&b, etc1_color_modifier_lookup(&b, etc1_table_index, lsb), sgn); 470bf215546Sopenharmony_ci nir_ssa_def *result = nir_iadd(&b, nir_load_var(&b, base_rgb), off); 471bf215546Sopenharmony_ci nir_store_var(&b, rgb_result, result, 0x7); 472bf215546Sopenharmony_ci } 473bf215546Sopenharmony_ci nir_pop_if(&b, NULL); 474bf215546Sopenharmony_ci nir_push_if(&b, nir_load_var(&b, punchthrough)); 475bf215546Sopenharmony_ci { 476bf215546Sopenharmony_ci nir_store_var(&b, alpha_result, nir_imm_float(&b, 0), 0x1); 477bf215546Sopenharmony_ci nir_store_var(&b, rgb_result, nir_imm_ivec3(&b, 0, 0, 0), 0x7); 478bf215546Sopenharmony_ci } 479bf215546Sopenharmony_ci nir_pop_if(&b, NULL); 480bf215546Sopenharmony_ci nir_ssa_def *col[4]; 481bf215546Sopenharmony_ci for (unsigned i = 0; i < 3; ++i) 482bf215546Sopenharmony_ci col[i] = nir_fdiv(&b, nir_i2f32(&b, nir_channel(&b, nir_load_var(&b, rgb_result), i)), 483bf215546Sopenharmony_ci nir_imm_float(&b, 255.0)); 484bf215546Sopenharmony_ci col[3] = nir_load_var(&b, alpha_result); 485bf215546Sopenharmony_ci nir_store_var(&b, color, nir_vec(&b, col, 4), 0xf); 486bf215546Sopenharmony_ci } 487bf215546Sopenharmony_ci nir_push_else(&b, NULL); 488bf215546Sopenharmony_ci { /* EAC */ 489bf215546Sopenharmony_ci nir_ssa_def *is_signed = nir_ior(&b, nir_ieq_imm(&b, format, VK_FORMAT_EAC_R11_SNORM_BLOCK), 490bf215546Sopenharmony_ci nir_ieq_imm(&b, format, VK_FORMAT_EAC_R11G11_SNORM_BLOCK)); 491bf215546Sopenharmony_ci nir_ssa_def *val[4]; 492bf215546Sopenharmony_ci for (int i = 0; i < 2; ++i) { 493bf215546Sopenharmony_ci val[i] = decode_etc2_alpha(&b, nir_channels(&b, payload, 3 << (2 * i)), linear_pixel, true, 494bf215546Sopenharmony_ci is_signed); 495bf215546Sopenharmony_ci } 496bf215546Sopenharmony_ci val[2] = nir_imm_float(&b, 0.0); 497bf215546Sopenharmony_ci val[3] = nir_imm_float(&b, 1.0); 498bf215546Sopenharmony_ci nir_store_var(&b, color, nir_vec(&b, val, 4), 0xf); 499bf215546Sopenharmony_ci } 500bf215546Sopenharmony_ci nir_pop_if(&b, NULL); 501bf215546Sopenharmony_ci 502bf215546Sopenharmony_ci nir_ssa_def *outval = nir_load_var(&b, color); 503bf215546Sopenharmony_ci nir_ssa_def *img_coord = nir_vec4(&b, nir_channel(&b, coord, 0), nir_channel(&b, coord, 1), 504bf215546Sopenharmony_ci nir_channel(&b, coord, 2), nir_ssa_undef(&b, 1, 32)); 505bf215546Sopenharmony_ci 506bf215546Sopenharmony_ci nir_push_if(&b, is_3d); 507bf215546Sopenharmony_ci { 508bf215546Sopenharmony_ci nir_image_deref_store(&b, &nir_build_deref_var(&b, output_img_3d)->dest.ssa, img_coord, 509bf215546Sopenharmony_ci nir_ssa_undef(&b, 1, 32), outval, nir_imm_int(&b, 0), 510bf215546Sopenharmony_ci .image_dim = GLSL_SAMPLER_DIM_3D); 511bf215546Sopenharmony_ci } 512bf215546Sopenharmony_ci nir_push_else(&b, NULL); 513bf215546Sopenharmony_ci { 514bf215546Sopenharmony_ci nir_image_deref_store(&b, &nir_build_deref_var(&b, output_img_2d)->dest.ssa, img_coord, 515bf215546Sopenharmony_ci nir_ssa_undef(&b, 1, 32), outval, nir_imm_int(&b, 0), 516bf215546Sopenharmony_ci .image_dim = GLSL_SAMPLER_DIM_2D, .image_array = true); 517bf215546Sopenharmony_ci } 518bf215546Sopenharmony_ci nir_pop_if(&b, NULL); 519bf215546Sopenharmony_ci return b.shader; 520bf215546Sopenharmony_ci} 521bf215546Sopenharmony_ci 522bf215546Sopenharmony_cistatic VkResult 523bf215546Sopenharmony_cicreate_layout(struct radv_device *device) 524bf215546Sopenharmony_ci{ 525bf215546Sopenharmony_ci VkResult result; 526bf215546Sopenharmony_ci VkDescriptorSetLayoutCreateInfo ds_create_info = { 527bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, 528bf215546Sopenharmony_ci .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR, 529bf215546Sopenharmony_ci .bindingCount = 2, 530bf215546Sopenharmony_ci .pBindings = (VkDescriptorSetLayoutBinding[]){ 531bf215546Sopenharmony_ci {.binding = 0, 532bf215546Sopenharmony_ci .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 533bf215546Sopenharmony_ci .descriptorCount = 1, 534bf215546Sopenharmony_ci .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT, 535bf215546Sopenharmony_ci .pImmutableSamplers = NULL}, 536bf215546Sopenharmony_ci {.binding = 1, 537bf215546Sopenharmony_ci .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 538bf215546Sopenharmony_ci .descriptorCount = 1, 539bf215546Sopenharmony_ci .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT, 540bf215546Sopenharmony_ci .pImmutableSamplers = NULL}, 541bf215546Sopenharmony_ci }}; 542bf215546Sopenharmony_ci 543bf215546Sopenharmony_ci result = radv_CreateDescriptorSetLayout(radv_device_to_handle(device), &ds_create_info, 544bf215546Sopenharmony_ci &device->meta_state.alloc, 545bf215546Sopenharmony_ci &device->meta_state.etc_decode.ds_layout); 546bf215546Sopenharmony_ci if (result != VK_SUCCESS) 547bf215546Sopenharmony_ci goto fail; 548bf215546Sopenharmony_ci 549bf215546Sopenharmony_ci VkPipelineLayoutCreateInfo pl_create_info = { 550bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, 551bf215546Sopenharmony_ci .setLayoutCount = 1, 552bf215546Sopenharmony_ci .pSetLayouts = &device->meta_state.etc_decode.ds_layout, 553bf215546Sopenharmony_ci .pushConstantRangeCount = 1, 554bf215546Sopenharmony_ci .pPushConstantRanges = &(VkPushConstantRange){VK_SHADER_STAGE_COMPUTE_BIT, 0, 20}, 555bf215546Sopenharmony_ci }; 556bf215546Sopenharmony_ci 557bf215546Sopenharmony_ci result = 558bf215546Sopenharmony_ci radv_CreatePipelineLayout(radv_device_to_handle(device), &pl_create_info, 559bf215546Sopenharmony_ci &device->meta_state.alloc, &device->meta_state.etc_decode.p_layout); 560bf215546Sopenharmony_ci if (result != VK_SUCCESS) 561bf215546Sopenharmony_ci goto fail; 562bf215546Sopenharmony_ci return VK_SUCCESS; 563bf215546Sopenharmony_cifail: 564bf215546Sopenharmony_ci return result; 565bf215546Sopenharmony_ci} 566bf215546Sopenharmony_ci 567bf215546Sopenharmony_cistatic VkResult 568bf215546Sopenharmony_cicreate_decode_pipeline(struct radv_device *device, VkPipeline *pipeline) 569bf215546Sopenharmony_ci{ 570bf215546Sopenharmony_ci VkResult result; 571bf215546Sopenharmony_ci 572bf215546Sopenharmony_ci mtx_lock(&device->meta_state.mtx); 573bf215546Sopenharmony_ci if (*pipeline) { 574bf215546Sopenharmony_ci mtx_unlock(&device->meta_state.mtx); 575bf215546Sopenharmony_ci return VK_SUCCESS; 576bf215546Sopenharmony_ci } 577bf215546Sopenharmony_ci 578bf215546Sopenharmony_ci nir_shader *cs = build_shader(device); 579bf215546Sopenharmony_ci 580bf215546Sopenharmony_ci /* compute shader */ 581bf215546Sopenharmony_ci 582bf215546Sopenharmony_ci VkPipelineShaderStageCreateInfo pipeline_shader_stage = { 583bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, 584bf215546Sopenharmony_ci .stage = VK_SHADER_STAGE_COMPUTE_BIT, 585bf215546Sopenharmony_ci .module = vk_shader_module_handle_from_nir(cs), 586bf215546Sopenharmony_ci .pName = "main", 587bf215546Sopenharmony_ci .pSpecializationInfo = NULL, 588bf215546Sopenharmony_ci }; 589bf215546Sopenharmony_ci 590bf215546Sopenharmony_ci VkComputePipelineCreateInfo vk_pipeline_info = { 591bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, 592bf215546Sopenharmony_ci .stage = pipeline_shader_stage, 593bf215546Sopenharmony_ci .flags = 0, 594bf215546Sopenharmony_ci .layout = device->meta_state.resolve_compute.p_layout, 595bf215546Sopenharmony_ci }; 596bf215546Sopenharmony_ci 597bf215546Sopenharmony_ci result = radv_CreateComputePipelines(radv_device_to_handle(device), 598bf215546Sopenharmony_ci radv_pipeline_cache_to_handle(&device->meta_state.cache), 1, 599bf215546Sopenharmony_ci &vk_pipeline_info, NULL, pipeline); 600bf215546Sopenharmony_ci if (result != VK_SUCCESS) 601bf215546Sopenharmony_ci goto fail; 602bf215546Sopenharmony_ci 603bf215546Sopenharmony_ci ralloc_free(cs); 604bf215546Sopenharmony_ci mtx_unlock(&device->meta_state.mtx); 605bf215546Sopenharmony_ci return VK_SUCCESS; 606bf215546Sopenharmony_cifail: 607bf215546Sopenharmony_ci ralloc_free(cs); 608bf215546Sopenharmony_ci mtx_unlock(&device->meta_state.mtx); 609bf215546Sopenharmony_ci return result; 610bf215546Sopenharmony_ci} 611bf215546Sopenharmony_ci 612bf215546Sopenharmony_ciVkResult 613bf215546Sopenharmony_ciradv_device_init_meta_etc_decode_state(struct radv_device *device, bool on_demand) 614bf215546Sopenharmony_ci{ 615bf215546Sopenharmony_ci struct radv_meta_state *state = &device->meta_state; 616bf215546Sopenharmony_ci VkResult res; 617bf215546Sopenharmony_ci 618bf215546Sopenharmony_ci if (!device->physical_device->emulate_etc2) 619bf215546Sopenharmony_ci return VK_SUCCESS; 620bf215546Sopenharmony_ci 621bf215546Sopenharmony_ci res = create_layout(device); 622bf215546Sopenharmony_ci if (res != VK_SUCCESS) 623bf215546Sopenharmony_ci return res; 624bf215546Sopenharmony_ci 625bf215546Sopenharmony_ci if (on_demand) 626bf215546Sopenharmony_ci return VK_SUCCESS; 627bf215546Sopenharmony_ci 628bf215546Sopenharmony_ci return create_decode_pipeline(device, &state->etc_decode.pipeline); 629bf215546Sopenharmony_ci} 630bf215546Sopenharmony_ci 631bf215546Sopenharmony_civoid 632bf215546Sopenharmony_ciradv_device_finish_meta_etc_decode_state(struct radv_device *device) 633bf215546Sopenharmony_ci{ 634bf215546Sopenharmony_ci struct radv_meta_state *state = &device->meta_state; 635bf215546Sopenharmony_ci radv_DestroyPipeline(radv_device_to_handle(device), state->etc_decode.pipeline, &state->alloc); 636bf215546Sopenharmony_ci radv_DestroyPipelineLayout(radv_device_to_handle(device), state->etc_decode.p_layout, 637bf215546Sopenharmony_ci &state->alloc); 638bf215546Sopenharmony_ci device->vk.dispatch_table.DestroyDescriptorSetLayout(radv_device_to_handle(device), 639bf215546Sopenharmony_ci state->etc_decode.ds_layout, &state->alloc); 640bf215546Sopenharmony_ci} 641bf215546Sopenharmony_ci 642bf215546Sopenharmony_cistatic VkPipeline 643bf215546Sopenharmony_ciradv_get_etc_decode_pipeline(struct radv_cmd_buffer *cmd_buffer) 644bf215546Sopenharmony_ci{ 645bf215546Sopenharmony_ci struct radv_device *device = cmd_buffer->device; 646bf215546Sopenharmony_ci VkPipeline *pipeline = &device->meta_state.etc_decode.pipeline; 647bf215546Sopenharmony_ci 648bf215546Sopenharmony_ci if (!*pipeline) { 649bf215546Sopenharmony_ci VkResult ret; 650bf215546Sopenharmony_ci 651bf215546Sopenharmony_ci ret = create_decode_pipeline(device, pipeline); 652bf215546Sopenharmony_ci if (ret != VK_SUCCESS) { 653bf215546Sopenharmony_ci cmd_buffer->record_result = ret; 654bf215546Sopenharmony_ci return VK_NULL_HANDLE; 655bf215546Sopenharmony_ci } 656bf215546Sopenharmony_ci } 657bf215546Sopenharmony_ci 658bf215546Sopenharmony_ci return *pipeline; 659bf215546Sopenharmony_ci} 660bf215546Sopenharmony_ci 661bf215546Sopenharmony_cistatic void 662bf215546Sopenharmony_cidecode_etc(struct radv_cmd_buffer *cmd_buffer, struct radv_image_view *src_iview, 663bf215546Sopenharmony_ci struct radv_image_view *dest_iview, const VkOffset3D *offset, const VkExtent3D *extent) 664bf215546Sopenharmony_ci{ 665bf215546Sopenharmony_ci struct radv_device *device = cmd_buffer->device; 666bf215546Sopenharmony_ci 667bf215546Sopenharmony_ci radv_meta_push_descriptor_set( 668bf215546Sopenharmony_ci cmd_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, device->meta_state.resolve_compute.p_layout, 669bf215546Sopenharmony_ci 0, /* set */ 670bf215546Sopenharmony_ci 2, /* descriptorWriteCount */ 671bf215546Sopenharmony_ci (VkWriteDescriptorSet[]){{.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 672bf215546Sopenharmony_ci .dstBinding = 0, 673bf215546Sopenharmony_ci .dstArrayElement = 0, 674bf215546Sopenharmony_ci .descriptorCount = 1, 675bf215546Sopenharmony_ci .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 676bf215546Sopenharmony_ci .pImageInfo = 677bf215546Sopenharmony_ci (VkDescriptorImageInfo[]){ 678bf215546Sopenharmony_ci {.sampler = VK_NULL_HANDLE, 679bf215546Sopenharmony_ci .imageView = radv_image_view_to_handle(src_iview), 680bf215546Sopenharmony_ci .imageLayout = VK_IMAGE_LAYOUT_GENERAL}, 681bf215546Sopenharmony_ci }}, 682bf215546Sopenharmony_ci {.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 683bf215546Sopenharmony_ci .dstBinding = 1, 684bf215546Sopenharmony_ci .dstArrayElement = 0, 685bf215546Sopenharmony_ci .descriptorCount = 1, 686bf215546Sopenharmony_ci .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 687bf215546Sopenharmony_ci .pImageInfo = (VkDescriptorImageInfo[]){ 688bf215546Sopenharmony_ci { 689bf215546Sopenharmony_ci .sampler = VK_NULL_HANDLE, 690bf215546Sopenharmony_ci .imageView = radv_image_view_to_handle(dest_iview), 691bf215546Sopenharmony_ci .imageLayout = VK_IMAGE_LAYOUT_GENERAL, 692bf215546Sopenharmony_ci }, 693bf215546Sopenharmony_ci }}}); 694bf215546Sopenharmony_ci 695bf215546Sopenharmony_ci VkPipeline pipeline = radv_get_etc_decode_pipeline(cmd_buffer); 696bf215546Sopenharmony_ci 697bf215546Sopenharmony_ci radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_COMPUTE, 698bf215546Sopenharmony_ci pipeline); 699bf215546Sopenharmony_ci 700bf215546Sopenharmony_ci unsigned push_constants[5] = { 701bf215546Sopenharmony_ci offset->x, offset->y, offset->z, src_iview->image->vk.format, src_iview->image->vk.image_type, 702bf215546Sopenharmony_ci }; 703bf215546Sopenharmony_ci 704bf215546Sopenharmony_ci radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer), 705bf215546Sopenharmony_ci device->meta_state.resolve_compute.p_layout, VK_SHADER_STAGE_COMPUTE_BIT, 706bf215546Sopenharmony_ci 0, 20, push_constants); 707bf215546Sopenharmony_ci radv_unaligned_dispatch(cmd_buffer, extent->width, extent->height, extent->depth); 708bf215546Sopenharmony_ci} 709bf215546Sopenharmony_ci 710bf215546Sopenharmony_civoid 711bf215546Sopenharmony_ciradv_meta_decode_etc(struct radv_cmd_buffer *cmd_buffer, struct radv_image *image, 712bf215546Sopenharmony_ci VkImageLayout layout, const VkImageSubresourceLayers *subresource, 713bf215546Sopenharmony_ci VkOffset3D offset, VkExtent3D extent) 714bf215546Sopenharmony_ci{ 715bf215546Sopenharmony_ci struct radv_meta_saved_state saved_state; 716bf215546Sopenharmony_ci radv_meta_save(&saved_state, cmd_buffer, 717bf215546Sopenharmony_ci RADV_META_SAVE_COMPUTE_PIPELINE | RADV_META_SAVE_CONSTANTS | 718bf215546Sopenharmony_ci RADV_META_SAVE_DESCRIPTORS | RADV_META_SUSPEND_PREDICATING); 719bf215546Sopenharmony_ci 720bf215546Sopenharmony_ci uint32_t base_slice = radv_meta_get_iview_layer(image, subresource, &offset); 721bf215546Sopenharmony_ci uint32_t slice_count = image->vk.image_type == VK_IMAGE_TYPE_3D ? extent.depth : subresource->layerCount; 722bf215546Sopenharmony_ci 723bf215546Sopenharmony_ci extent = vk_image_sanitize_extent(&image->vk, extent); 724bf215546Sopenharmony_ci offset = vk_image_sanitize_offset(&image->vk, offset); 725bf215546Sopenharmony_ci 726bf215546Sopenharmony_ci VkFormat load_format = vk_format_get_blocksize(image->vk.format) == 16 727bf215546Sopenharmony_ci ? VK_FORMAT_R32G32B32A32_UINT 728bf215546Sopenharmony_ci : VK_FORMAT_R32G32_UINT; 729bf215546Sopenharmony_ci struct radv_image_view src_iview; 730bf215546Sopenharmony_ci radv_image_view_init( 731bf215546Sopenharmony_ci &src_iview, cmd_buffer->device, 732bf215546Sopenharmony_ci &(VkImageViewCreateInfo){ 733bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, 734bf215546Sopenharmony_ci .image = radv_image_to_handle(image), 735bf215546Sopenharmony_ci .viewType = radv_meta_get_view_type(image), 736bf215546Sopenharmony_ci .format = load_format, 737bf215546Sopenharmony_ci .subresourceRange = 738bf215546Sopenharmony_ci { 739bf215546Sopenharmony_ci .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, 740bf215546Sopenharmony_ci .baseMipLevel = subresource->mipLevel, 741bf215546Sopenharmony_ci .levelCount = 1, 742bf215546Sopenharmony_ci .baseArrayLayer = 0, 743bf215546Sopenharmony_ci .layerCount = subresource->baseArrayLayer + subresource->layerCount, 744bf215546Sopenharmony_ci }, 745bf215546Sopenharmony_ci }, 746bf215546Sopenharmony_ci 0, NULL); 747bf215546Sopenharmony_ci 748bf215546Sopenharmony_ci VkFormat store_format; 749bf215546Sopenharmony_ci switch (image->vk.format) { 750bf215546Sopenharmony_ci case VK_FORMAT_EAC_R11_UNORM_BLOCK: 751bf215546Sopenharmony_ci store_format = VK_FORMAT_R16_UNORM; 752bf215546Sopenharmony_ci break; 753bf215546Sopenharmony_ci case VK_FORMAT_EAC_R11_SNORM_BLOCK: 754bf215546Sopenharmony_ci store_format = VK_FORMAT_R16_SNORM; 755bf215546Sopenharmony_ci break; 756bf215546Sopenharmony_ci case VK_FORMAT_EAC_R11G11_UNORM_BLOCK: 757bf215546Sopenharmony_ci store_format = VK_FORMAT_R16G16_UNORM; 758bf215546Sopenharmony_ci break; 759bf215546Sopenharmony_ci case VK_FORMAT_EAC_R11G11_SNORM_BLOCK: 760bf215546Sopenharmony_ci store_format = VK_FORMAT_R16G16_SNORM; 761bf215546Sopenharmony_ci break; 762bf215546Sopenharmony_ci default: 763bf215546Sopenharmony_ci store_format = VK_FORMAT_R8G8B8A8_UNORM; 764bf215546Sopenharmony_ci } 765bf215546Sopenharmony_ci struct radv_image_view dest_iview; 766bf215546Sopenharmony_ci radv_image_view_init( 767bf215546Sopenharmony_ci &dest_iview, cmd_buffer->device, 768bf215546Sopenharmony_ci &(VkImageViewCreateInfo){ 769bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, 770bf215546Sopenharmony_ci .image = radv_image_to_handle(image), 771bf215546Sopenharmony_ci .viewType = radv_meta_get_view_type(image), 772bf215546Sopenharmony_ci .format = store_format, 773bf215546Sopenharmony_ci .subresourceRange = 774bf215546Sopenharmony_ci { 775bf215546Sopenharmony_ci .aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT, 776bf215546Sopenharmony_ci .baseMipLevel = subresource->mipLevel, 777bf215546Sopenharmony_ci .levelCount = 1, 778bf215546Sopenharmony_ci .baseArrayLayer = 0, 779bf215546Sopenharmony_ci .layerCount = subresource->baseArrayLayer + subresource->layerCount, 780bf215546Sopenharmony_ci }, 781bf215546Sopenharmony_ci }, 782bf215546Sopenharmony_ci 0, NULL); 783bf215546Sopenharmony_ci 784bf215546Sopenharmony_ci decode_etc(cmd_buffer, &src_iview, &dest_iview, &(VkOffset3D){offset.x, offset.y, base_slice}, 785bf215546Sopenharmony_ci &(VkExtent3D){extent.width, extent.height, slice_count}); 786bf215546Sopenharmony_ci 787bf215546Sopenharmony_ci radv_image_view_finish(&src_iview); 788bf215546Sopenharmony_ci radv_image_view_finish(&dest_iview); 789bf215546Sopenharmony_ci 790bf215546Sopenharmony_ci radv_meta_restore(&saved_state, cmd_buffer); 791bf215546Sopenharmony_ci} 792