r600: Update state code to accept NIR shaders
authorGert Wollny <gw.fossdev@gmail.com>
Sun, 1 Dec 2019 18:11:19 +0000 (19:11 +0100)
committerMarge Bot <eric+marge@anholt.net>
Mon, 10 Feb 2020 19:09:08 +0000 (19:09 +0000)
v2: Correct commit message (Konstantin Kharlamov)

Signed-off-by: Gert Wollny <gert.wollny@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3225>

src/gallium/drivers/r600/evergreen_compute.c
src/gallium/drivers/r600/r600_pipe.h
src/gallium/drivers/r600/r600_pipe_common.c
src/gallium/drivers/r600/r600_state_common.c

index 419738eec7029f560a030950af7a4e59374a24a7..98d4b97d7fc00014d5bf78761ae8a00f0a842299 100644 (file)
@@ -441,8 +441,9 @@ static void *evergreen_create_compute_state(struct pipe_context *ctx,
 
        shader->ir_type = cso->ir_type;
 
-       if (shader->ir_type == PIPE_SHADER_IR_TGSI) {
-               shader->sel = r600_create_shader_state_tokens(ctx, cso->prog, PIPE_SHADER_COMPUTE);
+       if (shader->ir_type == PIPE_SHADER_IR_TGSI ||
+           shader->ir_type == PIPE_SHADER_IR_NIR) {
+               shader->sel = r600_create_shader_state_tokens(ctx, cso->prog, cso->ir_type, PIPE_SHADER_COMPUTE);
                return shader;
        }
 #ifdef HAVE_OPENCL
@@ -476,7 +477,8 @@ static void evergreen_delete_compute_state(struct pipe_context *ctx, void *state
        if (!shader)
                return;
 
-       if (shader->ir_type == PIPE_SHADER_IR_TGSI) {
+       if (shader->ir_type == PIPE_SHADER_IR_TGSI ||
+           shader->ir_type == PIPE_SHADER_IR_NIR) {
                r600_delete_shader_selector(ctx, shader->sel);
        } else {
 #ifdef HAVE_OPENCL
@@ -500,12 +502,14 @@ static void evergreen_bind_compute_state(struct pipe_context *ctx, void *state)
                return;
        }
 
-       if (cstate->ir_type == PIPE_SHADER_IR_TGSI) {
+       if (cstate->ir_type == PIPE_SHADER_IR_TGSI ||
+           cstate->ir_type == PIPE_SHADER_IR_NIR) {
                bool compute_dirty;
-
-               r600_shader_select(ctx, cstate->sel, &compute_dirty);
+               cstate->sel->ir_type = cstate->ir_type;
+               if (r600_shader_select(ctx, cstate->sel, &compute_dirty))
+                       R600_ERR("Failed to select compute shader\n");
        }
-
+       
        rctx->cs_shader_state.shader = (struct r600_pipe_compute *)state;
 }
 
@@ -604,9 +608,10 @@ static void evergreen_emit_dispatch(struct r600_context *rctx,
        int grid_size = 1;
        unsigned lds_size = shader->local_size / 4;
 
-       if (shader->ir_type != PIPE_SHADER_IR_TGSI)
+       if (shader->ir_type != PIPE_SHADER_IR_TGSI &&
+           shader->ir_type != PIPE_SHADER_IR_NIR)
                lds_size += shader->bc.nlds_dw;
-
+       
        /* Calculate group_size/grid_size */
        for (i = 0; i < 3; i++) {
                group_size *= info->block[i];
@@ -734,8 +739,13 @@ static void compute_emit_cs(struct r600_context *rctx,
                rctx->cmd_buf_is_compute = true;
        }
 
-       if (rctx->cs_shader_state.shader->ir_type == PIPE_SHADER_IR_TGSI) {
-               r600_shader_select(&rctx->b.b, rctx->cs_shader_state.shader->sel, &compute_dirty);
+       if (rctx->cs_shader_state.shader->ir_type == PIPE_SHADER_IR_TGSI||
+           rctx->cs_shader_state.shader->ir_type == PIPE_SHADER_IR_NIR) {
+               if (r600_shader_select(&rctx->b.b, rctx->cs_shader_state.shader->sel, &compute_dirty)) {
+                       R600_ERR("Failed to select compute shader\n");
+                       return;
+               }
+               
                current = rctx->cs_shader_state.shader->sel->current;
                if (compute_dirty) {
                        rctx->cs_shader_state.atom.num_dw = current->command_buffer.num_dw;
@@ -786,7 +796,8 @@ static void compute_emit_cs(struct r600_context *rctx,
 
        /* emit config state */
        if (rctx->b.chip_class == EVERGREEN) {
-               if (rctx->cs_shader_state.shader->ir_type == PIPE_SHADER_IR_TGSI) {
+               if (rctx->cs_shader_state.shader->ir_type == PIPE_SHADER_IR_TGSI||
+                   rctx->cs_shader_state.shader->ir_type == PIPE_SHADER_IR_NIR) {
                        radeon_set_config_reg_seq(cs, R_008C04_SQ_GPR_RESOURCE_MGMT_1, 3);
                        radeon_emit(cs, S_008C04_NUM_CLAUSE_TEMP_GPRS(rctx->r6xx_num_clause_temp_gprs));
                        radeon_emit(cs, 0);
@@ -799,7 +810,8 @@ static void compute_emit_cs(struct r600_context *rctx,
        rctx->b.flags |= R600_CONTEXT_WAIT_3D_IDLE | R600_CONTEXT_FLUSH_AND_INV;
        r600_flush_emit(rctx);
 
-       if (rctx->cs_shader_state.shader->ir_type != PIPE_SHADER_IR_TGSI) {
+       if (rctx->cs_shader_state.shader->ir_type != PIPE_SHADER_IR_TGSI &&
+           rctx->cs_shader_state.shader->ir_type != PIPE_SHADER_IR_NIR) {
 
                compute_setup_cbs(rctx);
 
@@ -855,7 +867,8 @@ static void compute_emit_cs(struct r600_context *rctx,
                radeon_emit(cs, PKT3C(PKT3_DEALLOC_STATE, 0, 0));
                radeon_emit(cs, 0);
        }
-       if (rctx->cs_shader_state.shader->ir_type == PIPE_SHADER_IR_TGSI)
+       if (rctx->cs_shader_state.shader->ir_type == PIPE_SHADER_IR_TGSI ||
+           rctx->cs_shader_state.shader->ir_type == PIPE_SHADER_IR_NIR)
                evergreen_emit_atomic_buffer_save(rctx, true, combined_atomics, &atomic_used_mask);
 
 #if 0
@@ -882,7 +895,8 @@ void evergreen_emit_cs_shader(struct r600_context *rctx,
        struct r600_resource *code_bo;
        unsigned ngpr, nstack;
 
-       if (shader->ir_type == PIPE_SHADER_IR_TGSI) {
+       if (shader->ir_type == PIPE_SHADER_IR_TGSI ||
+           shader->ir_type == PIPE_SHADER_IR_NIR) {
                code_bo = shader->sel->current->bo;
                va = shader->sel->current->bo->gpu_address;
                ngpr = shader->sel->current->shader.bc.ngpr;
@@ -916,7 +930,8 @@ static void evergreen_launch_grid(struct pipe_context *ctx,
        struct r600_pipe_compute *shader = rctx->cs_shader_state.shader;
        boolean use_kill;
 
-       if (shader->ir_type != PIPE_SHADER_IR_TGSI) {
+       if (shader->ir_type != PIPE_SHADER_IR_TGSI &&
+           shader->ir_type != PIPE_SHADER_IR_NIR) {
                rctx->cs_shader_state.pc = info->pc;
                /* Get the config information for this kernel. */
                r600_shader_binary_read_config(&shader->binary, &shader->bc,
index 11c16957ad517d63b6ffdfca92c0d31c8c3fe76c..e2c34d7807049aaaf7f18a0cbde1e6fb9c263b90 100644 (file)
@@ -343,12 +343,14 @@ struct r600_pipe_shader_selector {
        struct r600_pipe_shader *current;
 
        struct tgsi_token       *tokens;
+        struct nir_shader       *nir;
        struct pipe_stream_output_info  so;
        struct tgsi_shader_info         info;
 
        unsigned        num_shaders;
 
        enum pipe_shader_type   type;
+        enum pipe_shader_ir ir_type;
 
        /* geometry shader properties */
        enum pipe_prim_type     gs_output_prim;
@@ -1055,7 +1057,8 @@ void eg_dump_debug_state(struct pipe_context *ctx, FILE *f,
                         unsigned flags);
 
 struct r600_pipe_shader_selector *r600_create_shader_state_tokens(struct pipe_context *ctx,
-                                                                 const struct tgsi_token *tokens,
+                                                                 const void *tokens,
+                                                                 enum pipe_shader_ir,
                                                                  unsigned pipe_shader_type);
 int r600_shader_select(struct pipe_context *ctx,
                       struct r600_pipe_shader_selector* sel,
index df6e7bcaeb01906da0652835719216c44cf52780..13544826d0b2acd29fc5287404740a2c99420f8f 100644 (file)
@@ -910,7 +910,8 @@ const char *r600_get_llvm_processor_name(enum radeon_family family)
 static unsigned get_max_threads_per_block(struct r600_common_screen *screen,
                                          enum pipe_shader_ir ir_type)
 {
-       if (ir_type != PIPE_SHADER_IR_TGSI)
+       if (ir_type != PIPE_SHADER_IR_TGSI &&
+           ir_type != PIPE_SHADER_IR_NIR)
                return 256;
        if (screen->chip_class >= EVERGREEN)
                return 1024;
index 4718286bd2b81d8bcb55d21e781dad7a2b9ddf0d..16d73f619dc717fdd095daba5f6dc53246a2e8be 100644 (file)
 #include "tgsi/tgsi_scan.h"
 #include "tgsi/tgsi_ureg.h"
 
+#include "nir.h"
+#include "nir/nir_to_tgsi_info.h"
+#include "tgsi/tgsi_from_mesa.h"
+
 void r600_init_command_buffer(struct r600_command_buffer *cb, unsigned num_dw)
 {
        assert(!cb->buf);
@@ -906,14 +910,19 @@ int r600_shader_select(struct pipe_context *ctx,
 }
 
 struct r600_pipe_shader_selector *r600_create_shader_state_tokens(struct pipe_context *ctx,
-                                                                 const struct tgsi_token *tokens,
+                                                                 const void *prog, enum pipe_shader_ir ir,
                                                                  unsigned pipe_shader_type)
 {
        struct r600_pipe_shader_selector *sel = CALLOC_STRUCT(r600_pipe_shader_selector);
 
        sel->type = pipe_shader_type;
-       sel->tokens = tgsi_dup_tokens(tokens);
-       tgsi_scan_shader(tokens, &sel->info);
+       if (ir == PIPE_SHADER_IR_TGSI) {
+               sel->tokens = tgsi_dup_tokens((const struct tgsi_token *)prog);
+               tgsi_scan_shader(sel->tokens, &sel->info);
+       } else if (ir == PIPE_SHADER_IR_NIR){
+               sel->nir = nir_shader_clone(NULL, (const nir_shader *)prog);
+               nir_tgsi_scan_shader(sel->nir, &sel->info, true);
+       }
        return sel;
 }
 
@@ -922,8 +931,16 @@ static void *r600_create_shader_state(struct pipe_context *ctx,
                               unsigned pipe_shader_type)
 {
        int i;
-       struct r600_pipe_shader_selector *sel = r600_create_shader_state_tokens(ctx, state->tokens, pipe_shader_type);
-
+       struct r600_pipe_shader_selector *sel;
+       
+       if (state->type == PIPE_SHADER_IR_TGSI)
+               sel = r600_create_shader_state_tokens(ctx, state->tokens, state->type, pipe_shader_type);
+       else if (state->type == PIPE_SHADER_IR_NIR) {
+               sel = r600_create_shader_state_tokens(ctx, state->ir.nir, state->type, pipe_shader_type);
+       } else
+               assert(0 && "Unknown shader type\n");
+       
+       sel->ir_type = state->type;
        sel->so = state->stream_output;
 
        switch (pipe_shader_type) {
@@ -1082,7 +1099,14 @@ void r600_delete_shader_selector(struct pipe_context *ctx,
                p = c;
        }
 
-       free(sel->tokens);
+       if (sel->ir_type == PIPE_SHADER_IR_TGSI) {
+               free(sel->tokens);
+               /* We might have converted the TGSI shader to a NIR shader */
+               if (sel->nir)
+                       ralloc_free(sel->nir);
+       }
+       else if (sel->ir_type == PIPE_SHADER_IR_NIR)
+               ralloc_free(sel->nir);
        free(sel);
 }