[Mesa-dev] [PATCH v2 20/73] radeonsi: scan NIR shaders to obtain required info
Marek Olšák
maraeo at gmail.com
Fri Jul 28 05:10:58 UTC 2017
On Wed, Jul 5, 2017 at 12:48 PM, Nicolai Hähnle <nhaehnle at gmail.com> wrote:
> From: Nicolai Hähnle <nicolai.haehnle at amd.com>
>
> ---
> src/gallium/drivers/radeonsi/Makefile.sources | 1 +
> src/gallium/drivers/radeonsi/si_shader.c | 1 +
> src/gallium/drivers/radeonsi/si_shader.h | 4 +
> src/gallium/drivers/radeonsi/si_shader_nir.c | 312 ++++++++++++++++++++++++
> src/gallium/drivers/radeonsi/si_state_shaders.c | 23 +-
> 5 files changed, 335 insertions(+), 6 deletions(-)
> create mode 100644 src/gallium/drivers/radeonsi/si_shader_nir.c
>
> diff --git a/src/gallium/drivers/radeonsi/Makefile.sources b/src/gallium/drivers/radeonsi/Makefile.sources
> index 626fe6f..1587d64 100644
> --- a/src/gallium/drivers/radeonsi/Makefile.sources
> +++ b/src/gallium/drivers/radeonsi/Makefile.sources
> @@ -10,18 +10,19 @@ C_SOURCES := \
> si_hw_context.c \
> si_pipe.c \
> si_pipe.h \
> si_pm4.c \
> si_pm4.h \
> si_perfcounter.c \
> si_public.h \
> si_shader.c \
> si_shader.h \
> si_shader_internal.h \
> + si_shader_nir.c \
> si_shader_tgsi_alu.c \
> si_shader_tgsi_mem.c \
> si_shader_tgsi_setup.c \
> si_state.c \
> si_state_draw.c \
> si_state_shaders.c \
> si_state.h \
> si_uvd.c
> diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
> index d8bacdb..5ff16f5 100644
> --- a/src/gallium/drivers/radeonsi/si_shader.c
> +++ b/src/gallium/drivers/radeonsi/si_shader.c
> @@ -5518,20 +5518,21 @@ static void si_init_exec_from_input(struct si_shader_context *ctx,
> ctx->voidt, args, 2, LP_FUNC_ATTR_CONVERGENT);
> }
>
> static bool si_compile_tgsi_main(struct si_shader_context *ctx,
> bool is_monolithic)
> {
> struct si_shader *shader = ctx->shader;
> struct si_shader_selector *sel = shader->selector;
> struct lp_build_tgsi_context *bld_base = &ctx->bld_base;
>
> + // TODO clean all this up!
> switch (ctx->type) {
> case PIPE_SHADER_VERTEX:
> ctx->load_input = declare_input_vs;
> if (shader->key.as_ls)
> bld_base->emit_epilogue = si_llvm_emit_ls_epilogue;
> else if (shader->key.as_es)
> bld_base->emit_epilogue = si_llvm_emit_es_epilogue;
> else
> bld_base->emit_epilogue = si_llvm_emit_vs_epilogue;
> break;
> diff --git a/src/gallium/drivers/radeonsi/si_shader.h b/src/gallium/drivers/radeonsi/si_shader.h
> index 6de7b69..339e156 100644
> --- a/src/gallium/drivers/radeonsi/si_shader.h
> +++ b/src/gallium/drivers/radeonsi/si_shader.h
> @@ -625,20 +625,24 @@ void si_multiwave_lds_size_workaround(struct si_screen *sscreen,
> unsigned *lds_size);
> void si_shader_apply_scratch_relocs(struct si_shader *shader,
> uint64_t scratch_va);
> void si_shader_binary_read_config(struct ac_shader_binary *binary,
> struct si_shader_config *conf,
> unsigned symbol_offset);
> unsigned si_get_spi_shader_z_format(bool writes_z, bool writes_stencil,
> bool writes_samplemask);
> const char *si_get_shader_name(const struct si_shader *shader, unsigned processor);
>
> +/* si_shader_nir.c */
> +void si_nir_scan_shader(const struct nir_shader *nir,
> + struct tgsi_shader_info *info);
> +
> /* Inline helpers. */
>
> /* Return the pointer to the main shader part's pointer. */
> static inline struct si_shader **
> si_get_main_shader_part(struct si_shader_selector *sel,
> struct si_shader_key *key)
> {
> if (key->as_ls)
> return &sel->main_shader_part_ls;
> if (key->as_es)
> diff --git a/src/gallium/drivers/radeonsi/si_shader_nir.c b/src/gallium/drivers/radeonsi/si_shader_nir.c
> new file mode 100644
> index 0000000..2278c62
> --- /dev/null
> +++ b/src/gallium/drivers/radeonsi/si_shader_nir.c
> @@ -0,0 +1,312 @@
> +/*
> + * Copyright 2017 Advanced Micro Devices, Inc.
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * on the rights to use, copy, modify, merge, publish, distribute, sub
> + * license, and/or sell copies of the Software, and to permit persons to whom
> + * the Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the next
> + * paragraph) shall be included in all copies or substantial portions of the
> + * Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
> + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
> + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
> + * USE OR OTHER DEALINGS IN THE SOFTWARE.
> + */
> +
> +#include "si_shader.h"
> +
> +#include "tgsi/tgsi_from_mesa.h"
> +
> +#include "compiler/nir/nir.h"
> +#include "compiler/nir_types.h"
> +
> +
> +static void scan_instruction(struct tgsi_shader_info *info,
> + nir_instr *instr)
> +{
> + if (instr->type == nir_instr_type_alu) {
> + nir_alu_instr *alu = nir_instr_as_alu(instr);
> +
> + switch (alu->op) {
> + case nir_op_fddx:
> + case nir_op_fddy:
> + case nir_op_fddx_fine:
> + case nir_op_fddy_fine:
> + case nir_op_fddx_coarse:
> + case nir_op_fddy_coarse:
> + info->uses_derivatives = true;
> + break;
> + default:
> + break;
> + }
> + } else if (instr->type == nir_instr_type_tex) {
> + nir_tex_instr *tex = nir_instr_as_tex(instr);
> +
> + switch (tex->op) {
> + case nir_texop_tex:
> + case nir_texop_txb:
> + case nir_texop_lod:
> + info->uses_derivatives = true;
> + break;
> + default:
> + break;
> + }
> + } else if (instr->type == nir_instr_type_intrinsic) {
> + nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
> +
> + switch (intr->intrinsic) {
> + case nir_intrinsic_load_front_face:
> + info->uses_frontface = 1;
> + break;
> + case nir_intrinsic_load_instance_id:
> + info->uses_instanceid = 1;
> + break;
> + case nir_intrinsic_load_vertex_id:
> + info->uses_vertexid = 1;
> + break;
> + case nir_intrinsic_load_vertex_id_zero_base:
> + info->uses_vertexid_nobase = 1;
> + break;
> + case nir_intrinsic_load_base_vertex:
> + info->uses_basevertex = 1;
> + break;
> + case nir_intrinsic_load_primitive_id:
> + info->uses_primid = 1;
> + break;
> + case nir_intrinsic_image_store:
> + case nir_intrinsic_image_atomic_add:
> + case nir_intrinsic_image_atomic_min:
> + case nir_intrinsic_image_atomic_max:
> + case nir_intrinsic_image_atomic_and:
> + case nir_intrinsic_image_atomic_or:
> + case nir_intrinsic_image_atomic_xor:
> + case nir_intrinsic_image_atomic_exchange:
> + case nir_intrinsic_image_atomic_comp_swap:
> + case nir_intrinsic_store_ssbo:
> + case nir_intrinsic_ssbo_atomic_add:
> + case nir_intrinsic_ssbo_atomic_imin:
> + case nir_intrinsic_ssbo_atomic_umin:
> + case nir_intrinsic_ssbo_atomic_imax:
> + case nir_intrinsic_ssbo_atomic_umax:
> + case nir_intrinsic_ssbo_atomic_and:
> + case nir_intrinsic_ssbo_atomic_or:
> + case nir_intrinsic_ssbo_atomic_xor:
> + case nir_intrinsic_ssbo_atomic_exchange:
> + case nir_intrinsic_ssbo_atomic_comp_swap:
> + info->writes_memory = true;
> + break;
> + default:
> + break;
> + }
> + }
> +}
> +
> +void si_nir_scan_shader(const struct nir_shader *nir,
> + struct tgsi_shader_info *info)
> +{
> + nir_function *func;
> + unsigned i;
> +
> + assert(nir->stage == MESA_SHADER_VERTEX ||
> + nir->stage == MESA_SHADER_FRAGMENT);
> +
> + info->processor = pipe_shader_type_from_mesa(nir->stage);
> + info->num_tokens = 1; /* indicate that the shader is non-empty */
> + info->num_instructions = 1;
This should be 2. 1 means there is only END.
Marek
More information about the mesa-dev
mailing list