diff --git a/src/compiler/glsl/gl_nir_linker.c b/src/compiler/glsl/gl_nir_linker.c index bd54a740420..e2166b7df72 100644 --- a/src/compiler/glsl/gl_nir_linker.c +++ b/src/compiler/glsl/gl_nir_linker.c @@ -22,6 +22,7 @@ */ #include "nir.h" +#include "nir_builder.h" #include "gl_nir.h" #include "gl_nir_linker.h" #include "linker_util.h" @@ -125,6 +126,39 @@ gl_nir_opts(nir_shader *nir) NIR_PASS_V(nir, nir_lower_var_copies); } +bool +gl_nir_can_add_pointsize_to_program(const struct gl_constants *consts, + struct gl_program *prog) +{ + nir_shader *nir = prog->nir; + if (!nir) + return true; /* fixedfunction */ + + assert(nir->info.stage == MESA_SHADER_VERTEX || + nir->info.stage == MESA_SHADER_TESS_EVAL || + nir->info.stage == MESA_SHADER_GEOMETRY); + if (nir->info.outputs_written & VARYING_BIT_PSIZ) + return false; + + unsigned max_components = nir->info.stage == MESA_SHADER_GEOMETRY ? + consts->MaxGeometryTotalOutputComponents : + consts->Program[nir->info.stage].MaxOutputComponents; + unsigned num_components = 0; + unsigned needed_components = nir->info.stage == MESA_SHADER_GEOMETRY ? nir->info.gs.vertices_out : 1; + nir_foreach_shader_out_variable(var, nir) { + num_components += glsl_count_dword_slots(var->type, false); + } + + /* Ensure that there is enough attribute space to emit at least one primitive */ + if (nir->info.stage == MESA_SHADER_GEOMETRY) { + if (num_components + needed_components > consts->Program[nir->info.stage].MaxOutputComponents) + return false; + num_components *= nir->info.gs.vertices_out; + } + + return num_components + needed_components <= max_components; +} + static void gl_nir_link_opts(nir_shader *producer, nir_shader *consumer) { @@ -752,6 +786,44 @@ nir_build_program_resource_list(const struct gl_constants *consts, _mesa_set_destroy(resource_set, NULL); } +/* - create a gl_PointSize variable + * - find every gl_Position write + * - store 1.0 to gl_PointSize after every gl_Position write + */ +void +gl_nir_add_point_size(nir_shader *nir) +{ + nir_variable *psiz = nir_create_variable_with_location(nir, nir_var_shader_out, + VARYING_SLOT_PSIZ, glsl_float_type()); + psiz->data.how_declared = nir_var_hidden; + + nir_function_impl *impl = nir_shader_get_entrypoint(nir); + nir_builder b = nir_builder_create(impl); + bool found = false; + nir_foreach_block_safe(block, impl) { + nir_foreach_instr_safe(instr, block) { + if (instr->type == nir_instr_type_intrinsic) { + nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr); + if (intr->intrinsic == nir_intrinsic_store_deref || + intr->intrinsic == nir_intrinsic_copy_deref) { + nir_variable *var = nir_intrinsic_get_var(intr, 0); + if (var->data.location == VARYING_SLOT_POS) { + b.cursor = nir_after_instr(instr); + nir_deref_instr *deref = nir_build_deref_var(&b, psiz); + nir_store_deref(&b, deref, nir_imm_float(&b, 1.0), BITFIELD_BIT(0)); + found = true; + } + } + } + } + } + if (!found) { + b.cursor = nir_before_cf_list(&impl->body); + nir_deref_instr *deref = nir_build_deref_var(&b, psiz); + nir_store_deref(&b, deref, nir_imm_float(&b, 1.0), BITFIELD_BIT(0)); + } +} + bool gl_nir_link_spirv(const struct gl_constants *consts, struct gl_shader_program *prog, diff --git a/src/compiler/glsl/gl_nir_linker.h b/src/compiler/glsl/gl_nir_linker.h index a24ae86113f..160978ce523 100644 --- a/src/compiler/glsl/gl_nir_linker.h +++ b/src/compiler/glsl/gl_nir_linker.h @@ -38,6 +38,7 @@ struct gl_constants; struct gl_extensions; struct gl_linked_shader; struct gl_shader_program; +struct gl_program; struct gl_transform_feedback_info; struct xfb_decl; struct nir_xfb_info; @@ -113,6 +114,13 @@ void gl_nir_link_assign_xfb_resources(const struct gl_constants *consts, bool gl_nir_link_uniform_blocks(struct gl_shader_program *prog); +bool +gl_nir_can_add_pointsize_to_program(const struct gl_constants *consts, + struct gl_program *prog); + +void +gl_nir_add_point_size(struct nir_shader *nir); + bool lower_packed_varying_needs_lowering(nir_shader *shader, nir_variable *var, bool xfb_enabled, bool disable_xfb_packing, diff --git a/src/mesa/state_tracker/st_glsl_to_nir.cpp b/src/mesa/state_tracker/st_glsl_to_nir.cpp index 7cccc024c4f..b3d1e5cf431 100644 --- a/src/mesa/state_tracker/st_glsl_to_nir.cpp +++ b/src/mesa/state_tracker/st_glsl_to_nir.cpp @@ -228,45 +228,6 @@ st_nir_assign_uniform_locations(struct gl_context *ctx, } } -/* - create a gl_PointSize variable - * - find every gl_Position write - * - store 1.0 to gl_PointSize after every gl_Position write - */ -void -st_nir_add_point_size(nir_shader *nir) -{ - nir_variable *psiz = nir_create_variable_with_location(nir, nir_var_shader_out, - VARYING_SLOT_PSIZ, glsl_float_type()); - psiz->data.how_declared = nir_var_hidden; - - nir_builder b; - nir_function_impl *impl = nir_shader_get_entrypoint(nir); - b = nir_builder_create(impl); - bool found = false; - nir_foreach_block_safe(block, impl) { - nir_foreach_instr_safe(instr, block) { - if (instr->type == nir_instr_type_intrinsic) { - nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr); - if (intr->intrinsic == nir_intrinsic_store_deref || - intr->intrinsic == nir_intrinsic_copy_deref) { - nir_variable *var = nir_intrinsic_get_var(intr, 0); - if (var->data.location == VARYING_SLOT_POS) { - b.cursor = nir_after_instr(instr); - nir_deref_instr *deref = nir_build_deref_var(&b, psiz); - nir_store_deref(&b, deref, nir_imm_float(&b, 1.0), BITFIELD_BIT(0)); - found = true; - } - } - } - } - } - if (!found) { - b.cursor = nir_before_cf_list(&impl->body); - nir_deref_instr *deref = nir_build_deref_var(&b, psiz); - nir_store_deref(&b, deref, nir_imm_float(&b, 1.0), BITFIELD_BIT(0)); - } -} - static void shared_type_info(const struct glsl_type *type, unsigned *size, unsigned *align) { @@ -377,8 +338,8 @@ st_nir_preprocess(struct st_context *st, struct gl_program *prog, prog->skip_pointsize_xfb = !(nir->info.outputs_written & VARYING_BIT_PSIZ); if (st->lower_point_size && prog->skip_pointsize_xfb && stage < MESA_SHADER_FRAGMENT && stage != MESA_SHADER_TESS_CTRL && - st_can_add_pointsize_to_program(st, prog)) { - NIR_PASS_V(nir, st_nir_add_point_size); + gl_nir_can_add_pointsize_to_program(&st->ctx->Const, prog)) { + NIR_PASS_V(nir, gl_nir_add_point_size); } if (stage < MESA_SHADER_FRAGMENT && stage != MESA_SHADER_TESS_CTRL && diff --git a/src/mesa/state_tracker/st_nir.h b/src/mesa/state_tracker/st_nir.h index be83eef6f94..3b69c520c5f 100644 --- a/src/mesa/state_tracker/st_nir.h +++ b/src/mesa/state_tracker/st_nir.h @@ -76,8 +76,6 @@ st_nir_make_passthrough_shader(struct st_context *st, const gl_varying_slot *output_locations, unsigned *interpolation_modes, unsigned sysval_mask); -void -st_nir_add_point_size(struct nir_shader *nir); struct pipe_shader_state * st_nir_make_clearcolor_shader(struct st_context *st); diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index adf4099987a..b6962ed1e4f 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -1228,35 +1228,6 @@ st_destroy_program_variants(struct st_context *st) destroy_shader_program_variants_cb, st); } -bool -st_can_add_pointsize_to_program(struct st_context *st, struct gl_program *prog) -{ - nir_shader *nir = prog->nir; - if (!nir) - return true; //fixedfunction - assert(nir->info.stage == MESA_SHADER_VERTEX || - nir->info.stage == MESA_SHADER_TESS_EVAL || - nir->info.stage == MESA_SHADER_GEOMETRY); - if (nir->info.outputs_written & VARYING_BIT_PSIZ) - return false; - unsigned max_components = nir->info.stage == MESA_SHADER_GEOMETRY ? - st->ctx->Const.MaxGeometryTotalOutputComponents : - st->ctx->Const.Program[nir->info.stage].MaxOutputComponents; - unsigned num_components = 0; - unsigned needed_components = nir->info.stage == MESA_SHADER_GEOMETRY ? nir->info.gs.vertices_out : 1; - nir_foreach_shader_out_variable(var, nir) { - num_components += glsl_count_dword_slots(var->type, false); - } - /* Ensure that there is enough attribute space to emit at least one primitive */ - if (nir->info.stage == MESA_SHADER_GEOMETRY) { - if (num_components + needed_components > st->ctx->Const.Program[nir->info.stage].MaxOutputComponents) - return false; - num_components *= nir->info.gs.vertices_out; - } - - return num_components + needed_components <= max_components; -} - /** * Compile one shader variant. */ @@ -1396,9 +1367,10 @@ st_program_string_notify( struct gl_context *ctx, } else if (target == GL_VERTEX_PROGRAM_ARB) { if (!st_translate_vertex_program(st, prog)) return false; - if (st->lower_point_size && st_can_add_pointsize_to_program(st, prog)) { + if (st->lower_point_size && + gl_nir_can_add_pointsize_to_program(&st->ctx->Const, prog)) { prog->skip_pointsize_xfb = true; - NIR_PASS_V(prog->nir, st_nir_add_point_size); + NIR_PASS_V(prog->nir, gl_nir_add_point_size); } } diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h index eb15f861e21..c86cafc0cc9 100644 --- a/src/mesa/state_tracker/st_program.h +++ b/src/mesa/state_tracker/st_program.h @@ -333,9 +333,6 @@ GLboolean st_program_string_notify(struct gl_context *ctx, GLenum target, struct gl_program *prog); -bool -st_can_add_pointsize_to_program(struct st_context *st, struct gl_program *prog); - #ifdef __cplusplus } #endif