X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fprogram%2Fprog_to_nir.c;h=ed80d46dc4dec2422053d11e021d4219ec20d789;hb=8ce53d4a2f3f44b8fa00a6a04ec0816f38d788db;hp=d54f934247da773eb22768a5ccb49df9dcc29f46;hpb=6ee082718fca884fbda73001e0ecb32095409549;p=mesa.git diff --git a/src/mesa/program/prog_to_nir.c b/src/mesa/program/prog_to_nir.c index d54f934247d..ed80d46dc4d 100644 --- a/src/mesa/program/prog_to_nir.c +++ b/src/mesa/program/prog_to_nir.c @@ -23,9 +23,9 @@ * IN THE SOFTWARE. */ -#include "nir/nir.h" -#include "nir/nir_builder.h" -#include "glsl/list.h" +#include "compiler/nir/nir.h" +#include "compiler/nir/nir_builder.h" +#include "compiler/glsl/list.h" #include "main/imports.h" #include "util/ralloc.h" @@ -33,6 +33,7 @@ #include "prog_instruction.h" #include "prog_parameter.h" #include "prog_print.h" +#include "program.h" /** * \file prog_to_nir.c @@ -58,7 +59,6 @@ struct ptn_compile { #define SWIZ(X, Y, Z, W) \ (unsigned[4]){ SWIZZLE_##X, SWIZZLE_##Y, SWIZZLE_##Z, SWIZZLE_##W } -#define ptn_swizzle(b, src, x, y, z, w) nir_swizzle(b, src, SWIZ(x, y, z, w), 4, true) #define ptn_channel(b, src, ch) nir_swizzle(b, src, SWIZ(ch, ch, ch, ch), 1, true) static nir_ssa_def * @@ -141,8 +141,8 @@ ptn_get_src(struct ptn_compile *c, const struct prog_src_register *prog_src) load->num_components = 4; load->variables[0] = nir_deref_var_create(load, c->input_vars[prog_src->Index]); - nir_ssa_dest_init(&load->instr, &load->dest, 4, NULL); - nir_instr_insert_after_cf_list(b->cf_node_list, &load->instr); + nir_ssa_dest_init(&load->instr, &load->dest, 4, 32, NULL); + nir_builder_instr_insert(b, &load->instr); src.src = nir_src_for_ssa(&load->dest.ssa); break; @@ -159,16 +159,19 @@ ptn_get_src(struct ptn_compile *c, const struct prog_src_register *prog_src) switch (file) { case PROGRAM_CONSTANT: - if ((c->prog->IndirectRegisterFiles & (1 << PROGRAM_CONSTANT)) == 0) { + if ((c->prog->arb.IndirectRegisterFiles & + (1 << PROGRAM_CONSTANT)) == 0) { float *v = (float *) plist->ParameterValues[prog_src->Index]; src.src = nir_src_for_ssa(nir_imm_vec4(b, v[0], v[1], v[2], v[3])); break; } /* FALLTHROUGH */ case PROGRAM_STATE_VAR: { + assert(c->parameters != NULL); + nir_intrinsic_instr *load = nir_intrinsic_instr_create(b->shader, nir_intrinsic_load_var); - nir_ssa_dest_init(&load->instr, &load->dest, 4, NULL); + nir_ssa_dest_init(&load->instr, &load->dest, 4, 32, NULL); load->num_components = 4; load->variables[0] = nir_deref_var_create(load, c->parameters); @@ -200,7 +203,7 @@ ptn_get_src(struct ptn_compile *c, const struct prog_src_register *prog_src) deref_arr->base_offset = prog_src->Index; } - nir_instr_insert_after_cf_list(b->cf_node_list, &load->instr); + nir_builder_instr_insert(b, &load->instr); src.src = nir_src_for_ssa(&load->dest.ssa); break; @@ -227,9 +230,6 @@ ptn_get_src(struct ptn_compile *c, const struct prog_src_register *prog_src) def = nir_fmov_alu(b, src, 4); - if (prog_src->Abs) - def = nir_fabs(b, def); - if (prog_src->Negate) def = nir_fneg(b, def); } else { @@ -246,18 +246,15 @@ ptn_get_src(struct ptn_compile *c, const struct prog_src_register *prog_src) } else { assert(swizzle != SWIZZLE_NIL); nir_alu_instr *mov = nir_alu_instr_create(b->shader, nir_op_fmov); - nir_ssa_dest_init(&mov->instr, &mov->dest.dest, 1, NULL); + nir_ssa_dest_init(&mov->instr, &mov->dest.dest, 1, 32, NULL); mov->dest.write_mask = 0x1; mov->src[0] = src; mov->src[0].swizzle[0] = swizzle; - nir_instr_insert_after_cf_list(b->cf_node_list, &mov->instr); + nir_builder_instr_insert(b, &mov->instr); chans[i] = &mov->dest.dest.ssa; } - if (prog_src->Abs) - chans[i] = nir_fabs(b, chans[i]); - if (prog_src->Negate & (1 << i)) chans[i] = nir_fneg(b, chans[i]); } @@ -278,7 +275,7 @@ ptn_alu(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src) instr->src[i].src = nir_src_for_ssa(src[i]); instr->dest = dest; - nir_instr_insert_after_cf_list(b->cf_node_list, &instr->instr); + nir_builder_instr_insert(b, &instr->instr); } static void @@ -297,7 +294,7 @@ ptn_move_dest_masked(nir_builder *b, nir_alu_dest dest, mov->src[0].src = nir_src_for_ssa(def); for (unsigned i = def->num_components; i < 4; i++) mov->src[0].swizzle[i] = def->num_components - 1; - nir_instr_insert_after_cf_list(b->cf_node_list, &mov->instr); + nir_builder_instr_insert(b, &mov->instr); } static void @@ -448,57 +445,17 @@ ptn_sge(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src) } } -static void -ptn_sle(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src) -{ - nir_ssa_def *commuted[] = { src[1], src[0] }; - ptn_sge(b, dest, commuted); -} - -static void -ptn_sgt(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src) -{ - nir_ssa_def *commuted[] = { src[1], src[0] }; - ptn_slt(b, dest, commuted); -} - -/** - * Emit SEQ. For platforms with integers, prefer b2f(feq(...)). - */ -static void -ptn_seq(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src) -{ - if (b->shader->options->native_integers) { - ptn_move_dest(b, dest, nir_b2f(b, nir_feq(b, src[0], src[1]))); - } else { - ptn_move_dest(b, dest, nir_seq(b, src[0], src[1])); - } -} - -/** - * Emit SNE. For platforms with integers, prefer b2f(fne(...)). - */ -static void -ptn_sne(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src) -{ - if (b->shader->options->native_integers) { - ptn_move_dest(b, dest, nir_b2f(b, nir_fne(b, src[0], src[1]))); - } else { - ptn_move_dest(b, dest, nir_sne(b, src[0], src[1])); - } -} - static void ptn_xpd(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src) { ptn_move_dest_masked(b, dest, nir_fsub(b, nir_fmul(b, - ptn_swizzle(b, src[0], Y, Z, X, X), - ptn_swizzle(b, src[1], Z, X, Y, X)), + nir_swizzle(b, src[0], SWIZ(Y, Z, X, W), 3, true), + nir_swizzle(b, src[1], SWIZ(Z, X, Y, W), 3, true)), nir_fmul(b, - ptn_swizzle(b, src[1], Y, Z, X, X), - ptn_swizzle(b, src[0], Z, X, Y, X))), + nir_swizzle(b, src[1], SWIZ(Y, Z, X, W), 3, true), + nir_swizzle(b, src[0], SWIZ(Z, X, Y, W), 3, true))), WRITEMASK_XYZ); ptn_move_dest_masked(b, dest, nir_imm_float(b, 1.0), WRITEMASK_W); } @@ -524,8 +481,7 @@ ptn_dp4(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src) static void ptn_dph(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src) { - nir_ssa_def *dp3 = nir_fdot3(b, src[0], src[1]); - ptn_move_dest(b, dest, nir_fadd(b, dp3, ptn_channel(b, src[1], W))); + ptn_move_dest(b, dest, nir_fdph(b, src[0], src[1])); } static void @@ -549,16 +505,16 @@ ptn_lrp(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src) } static void -ptn_kil(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src) +ptn_kil(nir_builder *b, nir_ssa_def **src) { nir_ssa_def *cmp = b->shader->options->native_integers ? - nir_bany4(b, nir_flt(b, src[0], nir_imm_float(b, 0.0))) : - nir_fany4(b, nir_slt(b, src[0], nir_imm_float(b, 0.0))); + nir_bany_inequal4(b, nir_flt(b, src[0], nir_imm_float(b, 0.0)), nir_imm_int(b, 0)) : + nir_fany_nequal4(b, nir_slt(b, src[0], nir_imm_float(b, 0.0)), nir_imm_float(b, 0.0)); nir_intrinsic_instr *discard = nir_intrinsic_instr_create(b->shader, nir_intrinsic_discard_if); discard->src[0] = nir_src_for_ssa(cmp); - nir_instr_insert_after_cf_list(b->cf_node_list, &discard->instr); + nir_builder_instr_insert(b, &discard->instr); } static void @@ -590,11 +546,6 @@ ptn_tex(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src, op = nir_texop_tex; num_srcs = 2; break; - case OPCODE_TXP_NV: - assert(!"not handled"); - op = nir_texop_tex; - num_srcs = 2; - break; default: fprintf(stderr, "unknown tex op %d\n", prog_inst->Opcode); abort(); @@ -607,6 +558,7 @@ ptn_tex(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src, instr->op = op; instr->dest_type = nir_type_float; instr->is_shadow = prog_inst->TexShadow; + instr->texture_index = prog_inst->TexSrcUnit; instr->sampler_index = prog_inst->TexSrcUnit; switch (prog_inst->TexSrcTarget) { @@ -645,12 +597,16 @@ ptn_tex(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src, case GLSL_SAMPLER_DIM_CUBE: instr->coord_components = 3; break; + case GLSL_SAMPLER_DIM_SUBPASS: + case GLSL_SAMPLER_DIM_SUBPASS_MS: + unreachable("can't reach"); } unsigned src_number = 0; instr->src[src_number].src = - nir_src_for_ssa(ptn_swizzle(b, src[0], X, Y, Z, W)); + nir_src_for_ssa(nir_swizzle(b, src[0], SWIZ(X, Y, Z, W), + instr->coord_components, true)); instr->src[src_number].src_type = nir_tex_src_coord; src_number++; @@ -678,14 +634,14 @@ ptn_tex(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src, else instr->src[src_number].src = nir_src_for_ssa(ptn_channel(b, src[0], W)); - instr->src[src_number].src_type = nir_tex_src_comparitor; + instr->src[src_number].src_type = nir_tex_src_comparator; src_number++; } assert(src_number == num_srcs); - nir_ssa_dest_init(&instr->instr, &instr->dest, 4, NULL); - nir_instr_insert_after_cf_list(b->cf_node_list, &instr->instr); + nir_ssa_dest_init(&instr->instr, &instr->dest, 4, 32, NULL); + nir_builder_instr_insert(b, &instr->instr); /* Resolve the writemask on the texture op. */ ptn_move_dest(b, dest, &instr->dest.ssa); @@ -714,7 +670,7 @@ static const nir_op op_trans[MAX_OPCODE] = { [OPCODE_LIT] = 0, [OPCODE_LOG] = 0, [OPCODE_LRP] = 0, - [OPCODE_MAD] = nir_op_ffma, + [OPCODE_MAD] = 0, [OPCODE_MAX] = nir_op_fmax, [OPCODE_MIN] = nir_op_fmin, [OPCODE_MOV] = nir_op_fmov, @@ -724,13 +680,9 @@ static const nir_op op_trans[MAX_OPCODE] = { [OPCODE_RSQ] = 0, [OPCODE_SCS] = 0, - [OPCODE_SEQ] = 0, [OPCODE_SGE] = 0, - [OPCODE_SGT] = 0, [OPCODE_SIN] = 0, - [OPCODE_SLE] = 0, [OPCODE_SLT] = 0, - [OPCODE_SNE] = 0, [OPCODE_SSG] = nir_op_fsign, [OPCODE_SUB] = nir_op_fsub, [OPCODE_SWZ] = 0, @@ -740,7 +692,6 @@ static const nir_op op_trans[MAX_OPCODE] = { [OPCODE_TXD] = 0, [OPCODE_TXL] = 0, [OPCODE_TXP] = 0, - [OPCODE_TXP_NV] = 0, [OPCODE_XPD] = 0, }; @@ -810,6 +761,10 @@ ptn_emit_instruction(struct ptn_compile *c, struct prog_instruction *prog_inst) ptn_lrp(b, dest, src); break; + case OPCODE_MAD: + ptn_move_dest(b, dest, nir_fadd(b, nir_fmul(b, src[0], src[1]), src[2])); + break; + case OPCODE_DST: ptn_dst(b, dest, src); break; @@ -839,7 +794,7 @@ ptn_emit_instruction(struct ptn_compile *c, struct prog_instruction *prog_inst) break; case OPCODE_KIL: - ptn_kil(b, dest, src); + ptn_kil(b, src); break; case OPCODE_CMP: @@ -854,32 +809,15 @@ ptn_emit_instruction(struct ptn_compile *c, struct prog_instruction *prog_inst) ptn_slt(b, dest, src); break; - case OPCODE_SGT: - ptn_sgt(b, dest, src); - break; - - case OPCODE_SLE: - ptn_sle(b, dest, src); - break; - case OPCODE_SGE: ptn_sge(b, dest, src); break; - case OPCODE_SEQ: - ptn_seq(b, dest, src); - break; - - case OPCODE_SNE: - ptn_sne(b, dest, src); - break; - case OPCODE_TEX: case OPCODE_TXB: case OPCODE_TXD: case OPCODE_TXL: case OPCODE_TXP: - case OPCODE_TXP_NV: ptn_tex(b, dest, src, prog_inst); break; @@ -921,10 +859,11 @@ ptn_add_output_stores(struct ptn_compile *c) { nir_builder *b = &c->build; - foreach_list_typed(nir_variable, var, node, &b->shader->outputs) { + nir_foreach_variable(var, &b->shader->outputs) { nir_intrinsic_instr *store = nir_intrinsic_instr_create(b->shader, nir_intrinsic_store_var); store->num_components = glsl_get_vector_elements(var->type); + nir_intrinsic_set_write_mask(store, (1 << store->num_components) - 1); store->variables[0] = nir_deref_var_create(store, c->output_vars[var->data.location]); @@ -941,7 +880,7 @@ ptn_add_output_stores(struct ptn_compile *c) } else { store->src[0].reg.reg = c->output_regs[var->data.location]; } - nir_instr_insert_after_cf_list(c->build.cf_node_list, &store->instr); + nir_builder_instr_insert(b, &store->instr); } } @@ -952,27 +891,21 @@ setup_registers_and_variables(struct ptn_compile *c) struct nir_shader *shader = b->shader; /* Create input variables. */ - const int num_inputs = _mesa_flsll(c->prog->InputsRead); + const int num_inputs = util_last_bit64(c->prog->info.inputs_read); for (int i = 0; i < num_inputs; i++) { - if (!(c->prog->InputsRead & BITFIELD64_BIT(i))) + if (!(c->prog->info.inputs_read & BITFIELD64_BIT(i))) continue; - nir_variable *var = rzalloc(shader, nir_variable); - var->type = glsl_vec4_type(); - var->data.read_only = true; - var->data.mode = nir_var_shader_in; - var->name = ralloc_asprintf(var, "in_%d", i); + + nir_variable *var = + nir_variable_create(shader, nir_var_shader_in, glsl_vec4_type(), + ralloc_asprintf(shader, "in_%d", i)); var->data.location = i; var->data.index = 0; if (c->prog->Target == GL_FRAGMENT_PROGRAM_ARB) { - struct gl_fragment_program *fp = - (struct gl_fragment_program *) c->prog; - - var->data.interpolation = fp->InterpQualifier[i]; - if (i == VARYING_SLOT_POS) { - var->data.origin_upper_left = fp->OriginUpperLeft; - var->data.pixel_center_integer = fp->PixelCenterInteger; + var->data.origin_upper_left = c->prog->OriginUpperLeft; + var->data.pixel_center_integer = c->prog->PixelCenterInteger; } else if (i == VARYING_SLOT_FOGC) { /* fogcoord is defined as . Make the actual * input variable a float, and create a local containing the @@ -984,45 +917,41 @@ setup_registers_and_variables(struct ptn_compile *c) nir_intrinsic_instr_create(shader, nir_intrinsic_load_var); load_x->num_components = 1; load_x->variables[0] = nir_deref_var_create(load_x, var); - nir_ssa_dest_init(&load_x->instr, &load_x->dest, 1, NULL); - nir_instr_insert_after_cf_list(b->cf_node_list, &load_x->instr); + nir_ssa_dest_init(&load_x->instr, &load_x->dest, 1, 32, NULL); + nir_builder_instr_insert(b, &load_x->instr); nir_ssa_def *f001 = nir_vec4(b, &load_x->dest.ssa, nir_imm_float(b, 0.0), nir_imm_float(b, 0.0), nir_imm_float(b, 1.0)); - nir_variable *fullvar = rzalloc(shader, nir_variable); - fullvar->type = glsl_vec4_type(); - fullvar->data.mode = nir_var_local; - fullvar->name = "fogcoord_tmp"; - exec_list_push_tail(&b->impl->locals, &fullvar->node); - + nir_variable *fullvar = + nir_local_variable_create(b->impl, glsl_vec4_type(), + "fogcoord_tmp"); nir_intrinsic_instr *store = nir_intrinsic_instr_create(shader, nir_intrinsic_store_var); store->num_components = 4; + nir_intrinsic_set_write_mask(store, WRITEMASK_XYZW); store->variables[0] = nir_deref_var_create(store, fullvar); store->src[0] = nir_src_for_ssa(f001); - nir_instr_insert_after_cf_list(b->cf_node_list, &store->instr); + nir_builder_instr_insert(b, &store->instr); - /* Insert the real input into the list so the driver has real - * inputs, but set c->input_vars[i] to the temporary so we use + /* We inserted the real input into the list so the driver has real + * inputs, but we set c->input_vars[i] to the temporary so we use * the splatted value. */ - exec_list_push_tail(&shader->inputs, &var->node); c->input_vars[i] = fullvar; continue; } } - exec_list_push_tail(&shader->inputs, &var->node); c->input_vars[i] = var; } /* Create output registers and variables. */ - int max_outputs = _mesa_fls(c->prog->OutputsWritten); + int max_outputs = util_last_bit(c->prog->info.outputs_written); c->output_regs = rzalloc_array(c, nir_register *, max_outputs); for (int i = 0; i < max_outputs; i++) { - if (!(c->prog->OutputsWritten & BITFIELD64_BIT(i))) + if (!(c->prog->info.outputs_written & BITFIELD64_BIT(i))) continue; /* Since we can't load from outputs in the IR, we make temporaries @@ -1050,10 +979,11 @@ setup_registers_and_variables(struct ptn_compile *c) } /* Create temporary registers. */ - c->temp_regs = rzalloc_array(c, nir_register *, c->prog->NumTemporaries); + c->temp_regs = rzalloc_array(c, nir_register *, + c->prog->arb.NumTemporaries); nir_register *reg; - for (int i = 0; i < c->prog->NumTemporaries; i++) { + for (unsigned i = 0; i < c->prog->arb.NumTemporaries; i++) { reg = nir_local_reg_create(b->impl); if (!reg) { c->error = true; @@ -1079,37 +1009,38 @@ prog_to_nir(const struct gl_program *prog, { struct ptn_compile *c; struct nir_shader *s; + gl_shader_stage stage = _mesa_program_enum_to_shader_stage(prog->Target); c = rzalloc(NULL, struct ptn_compile); if (!c) return NULL; - s = nir_shader_create(NULL, options); - if (!s) - goto fail; c->prog = prog; - c->parameters = rzalloc(s, nir_variable); - c->parameters->type = glsl_array_type(glsl_vec4_type(), - prog->Parameters->NumParameters); - c->parameters->name = "parameters"; - c->parameters->data.read_only = true; - c->parameters->data.mode = nir_var_uniform; - exec_list_push_tail(&s->uniforms, &c->parameters->node); + nir_builder_init_simple_shader(&c->build, NULL, stage, options); - nir_function *func = nir_function_create(s, "main"); - nir_function_overload *overload = nir_function_overload_create(func); - nir_function_impl *impl = nir_function_impl_create(overload); + /* Use the shader_info from gl_program rather than the one nir_builder + * created for us. nir_sweep should clean up the other one for us. + */ + c->build.shader->info = (shader_info *) &prog->info; - c->build.shader = s; - c->build.impl = impl; - c->build.cf_node_list = &impl->body; + s = c->build.shader; + + if (prog->Parameters->NumParameters > 0) { + c->parameters = rzalloc(s, nir_variable); + c->parameters->type = + glsl_array_type(glsl_vec4_type(), prog->Parameters->NumParameters); + c->parameters->name = "parameters"; + c->parameters->data.read_only = true; + c->parameters->data.mode = nir_var_uniform; + exec_list_push_tail(&s->uniforms, &c->parameters->node); + } setup_registers_and_variables(c); if (unlikely(c->error)) goto fail; - for (unsigned int i = 0; i < prog->NumInstructions; i++) { - ptn_emit_instruction(c, &prog->Instructions[i]); + for (unsigned int i = 0; i < prog->arb.NumInstructions; i++) { + ptn_emit_instruction(c, &prog->arb.Instructions[i]); if (unlikely(c->error)) break; @@ -1117,6 +1048,17 @@ prog_to_nir(const struct gl_program *prog, ptn_add_output_stores(c); + s->info->name = ralloc_asprintf(s, "ARB%d", prog->Id); + s->info->num_textures = util_last_bit(prog->SamplersUsed); + s->info->num_ubos = 0; + s->info->num_abos = 0; + s->info->num_ssbos = 0; + s->info->num_images = 0; + s->info->uses_texture_gather = false; + s->info->clip_distance_array_size = 0; + s->info->cull_distance_array_size = 0; + s->info->separate_shader = false; + fail: if (c->error) { ralloc_free(s);