static nir_shader * build_resolve_fragment_shader(struct radv_device *dev, bool is_integer, int samples) { nir_builder b; char name[64]; const struct glsl_type *vec2 = glsl_vector_type(GLSL_TYPE_FLOAT, 2); const struct glsl_type *vec4 = glsl_vec4_type(); const struct glsl_type *sampler_type = glsl_sampler_type(GLSL_SAMPLER_DIM_MS, false, false, GLSL_TYPE_FLOAT); snprintf(name, 64, "meta_resolve_fs-%d-%s", samples, is_integer ? "int" : "float"); nir_builder_init_simple_shader(&b, NULL, MESA_SHADER_FRAGMENT, NULL); b.shader->info.name = ralloc_strdup(b.shader, name); nir_variable *input_img = nir_variable_create(b.shader, nir_var_uniform, sampler_type, "s_tex"); input_img->data.descriptor_set = 0; input_img->data.binding = 0; nir_variable *fs_pos_in = nir_variable_create(b.shader, nir_var_shader_in, vec2, "fs_pos_in"); fs_pos_in->data.location = VARYING_SLOT_POS; nir_variable *color_out = nir_variable_create(b.shader, nir_var_shader_out, vec4, "f_color"); color_out->data.location = FRAG_RESULT_DATA0; nir_ssa_def *pos_in = nir_load_var(&b, fs_pos_in); nir_intrinsic_instr *src_offset = nir_intrinsic_instr_create(b.shader, nir_intrinsic_load_push_constant); nir_intrinsic_set_base(src_offset, 0); nir_intrinsic_set_range(src_offset, 8); src_offset->src[0] = nir_src_for_ssa(nir_imm_int(&b, 0)); src_offset->num_components = 2; nir_ssa_dest_init(&src_offset->instr, &src_offset->dest, 2, 32, "src_offset"); nir_builder_instr_insert(&b, &src_offset->instr); nir_ssa_def *pos_int = nir_f2i32(&b, pos_in); nir_ssa_def *img_coord = nir_channels(&b, nir_iadd(&b, pos_int, &src_offset->dest.ssa), 0x3); nir_variable *color = nir_local_variable_create(b.impl, glsl_vec4_type(), "color"); radv_meta_build_resolve_shader_core(&b, is_integer, samples, input_img, color, img_coord); nir_ssa_def *outval = nir_load_var(&b, color); nir_store_var(&b, color_out, outval, 0xf); return b.shader; }
static nir_shader * build_resolve_compute_shader(struct radv_device *dev, bool is_integer, int samples) { nir_builder b; char name[64]; nir_if *outer_if = NULL; const struct glsl_type *sampler_type = glsl_sampler_type(GLSL_SAMPLER_DIM_MS, false, false, GLSL_TYPE_FLOAT); const struct glsl_type *img_type = glsl_sampler_type(GLSL_SAMPLER_DIM_2D, false, false, GLSL_TYPE_FLOAT); snprintf(name, 64, "meta_resolve_cs-%d-%s", samples, is_integer ? "int" : "float"); nir_builder_init_simple_shader(&b, NULL, MESA_SHADER_COMPUTE, NULL); b.shader->info->name = ralloc_strdup(b.shader, name); b.shader->info->cs.local_size[0] = 16; b.shader->info->cs.local_size[1] = 16; b.shader->info->cs.local_size[2] = 1; nir_variable *input_img = nir_variable_create(b.shader, nir_var_uniform, sampler_type, "s_tex"); input_img->data.descriptor_set = 0; input_img->data.binding = 0; nir_variable *output_img = nir_variable_create(b.shader, nir_var_uniform, img_type, "out_img"); output_img->data.descriptor_set = 0; output_img->data.binding = 1; nir_ssa_def *invoc_id = nir_load_system_value(&b, nir_intrinsic_load_local_invocation_id, 0); nir_ssa_def *wg_id = nir_load_system_value(&b, nir_intrinsic_load_work_group_id, 0); nir_ssa_def *block_size = nir_imm_ivec4(&b, b.shader->info->cs.local_size[0], b.shader->info->cs.local_size[1], b.shader->info->cs.local_size[2], 0); nir_ssa_def *global_id = nir_iadd(&b, nir_imul(&b, wg_id, block_size), invoc_id); nir_intrinsic_instr *src_offset = nir_intrinsic_instr_create(b.shader, nir_intrinsic_load_push_constant); src_offset->src[0] = nir_src_for_ssa(nir_imm_int(&b, 0)); src_offset->num_components = 2; nir_ssa_dest_init(&src_offset->instr, &src_offset->dest, 2, 32, "src_offset"); nir_builder_instr_insert(&b, &src_offset->instr); nir_intrinsic_instr *dst_offset = nir_intrinsic_instr_create(b.shader, nir_intrinsic_load_push_constant); dst_offset->src[0] = nir_src_for_ssa(nir_imm_int(&b, 8)); dst_offset->num_components = 2; nir_ssa_dest_init(&dst_offset->instr, &dst_offset->dest, 2, 32, "dst_offset"); nir_builder_instr_insert(&b, &dst_offset->instr); nir_ssa_def *img_coord = nir_iadd(&b, global_id, &src_offset->dest.ssa); /* do a txf_ms on each sample */ nir_ssa_def *tmp; nir_tex_instr *tex = nir_tex_instr_create(b.shader, 2); tex->sampler_dim = GLSL_SAMPLER_DIM_MS; tex->op = nir_texop_txf_ms; tex->src[0].src_type = nir_tex_src_coord; tex->src[0].src = nir_src_for_ssa(img_coord); tex->src[1].src_type = nir_tex_src_ms_index; tex->src[1].src = nir_src_for_ssa(nir_imm_int(&b, 0)); tex->dest_type = nir_type_float; tex->is_array = false; tex->coord_components = 2; tex->texture = nir_deref_var_create(tex, input_img); tex->sampler = NULL; nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, "tex"); nir_builder_instr_insert(&b, &tex->instr); tmp = &tex->dest.ssa; nir_variable *color = nir_local_variable_create(b.impl, glsl_vec4_type(), "color"); if (!is_integer && samples > 1) { nir_tex_instr *tex_all_same = nir_tex_instr_create(b.shader, 1); tex_all_same->sampler_dim = GLSL_SAMPLER_DIM_MS; tex_all_same->op = nir_texop_samples_identical; tex_all_same->src[0].src_type = nir_tex_src_coord; tex_all_same->src[0].src = nir_src_for_ssa(img_coord); tex_all_same->dest_type = nir_type_float; tex_all_same->is_array = false; tex_all_same->coord_components = 2; tex_all_same->texture = nir_deref_var_create(tex_all_same, input_img); tex_all_same->sampler = NULL; nir_ssa_dest_init(&tex_all_same->instr, &tex_all_same->dest, 1, 32, "tex"); nir_builder_instr_insert(&b, &tex_all_same->instr); nir_ssa_def *all_same = nir_ine(&b, &tex_all_same->dest.ssa, nir_imm_int(&b, 0)); nir_if *if_stmt = nir_if_create(b.shader); if_stmt->condition = nir_src_for_ssa(all_same); nir_cf_node_insert(b.cursor, &if_stmt->cf_node); b.cursor = nir_after_cf_list(&if_stmt->then_list); for (int i = 1; i < samples; i++) { nir_tex_instr *tex_add = nir_tex_instr_create(b.shader, 2); tex_add->sampler_dim = GLSL_SAMPLER_DIM_MS; tex_add->op = nir_texop_txf_ms; tex_add->src[0].src_type = nir_tex_src_coord; tex_add->src[0].src = nir_src_for_ssa(img_coord); tex_add->src[1].src_type = nir_tex_src_ms_index; tex_add->src[1].src = nir_src_for_ssa(nir_imm_int(&b, i)); tex_add->dest_type = nir_type_float; tex_add->is_array = false; tex_add->coord_components = 2; tex_add->texture = nir_deref_var_create(tex_add, input_img); tex_add->sampler = NULL; nir_ssa_dest_init(&tex_add->instr, &tex_add->dest, 4, 32, "tex"); nir_builder_instr_insert(&b, &tex_add->instr); tmp = nir_fadd(&b, tmp, &tex_add->dest.ssa); } tmp = nir_fdiv(&b, tmp, nir_imm_float(&b, samples)); nir_store_var(&b, color, tmp, 0xf); b.cursor = nir_after_cf_list(&if_stmt->else_list); outer_if = if_stmt; } nir_store_var(&b, color, &tex->dest.ssa, 0xf); if (outer_if) b.cursor = nir_after_cf_node(&outer_if->cf_node); nir_ssa_def *newv = nir_load_var(&b, color); nir_ssa_def *coord = nir_iadd(&b, global_id, &dst_offset->dest.ssa); nir_intrinsic_instr *store = nir_intrinsic_instr_create(b.shader, nir_intrinsic_image_store); store->src[0] = nir_src_for_ssa(coord); store->src[1] = nir_src_for_ssa(nir_ssa_undef(&b, 1, 32)); store->src[2] = nir_src_for_ssa(newv); store->variables[0] = nir_deref_var_create(store, output_img); nir_builder_instr_insert(&b, &store->instr); return b.shader; }