#include "r600_formats.h"
#include "r600_opcodes.h"
#include "r600_shader.h"
+#include "r600_dump.h"
#include "r600d.h"
+#include "sfn/sfn_nir.h"
#include "sb/sb_public.h"
#include "tgsi/tgsi_parse.h"
#include "tgsi/tgsi_scan.h"
#include "tgsi/tgsi_dump.h"
+#include "tgsi/tgsi_from_mesa.h"
+#include "nir/tgsi_to_nir.h"
+#include "nir/nir_to_tgsi_info.h"
+#include "compiler/nir/nir.h"
#include "util/u_bitcast.h"
#include "util/u_memory.h"
#include "util/u_math.h"
if (shader->bo == NULL) {
return -ENOMEM;
}
- ptr = r600_buffer_map_sync_with_rings(&rctx->b, shader->bo, PIPE_TRANSFER_WRITE);
+ ptr = r600_buffer_map_sync_with_rings(
+ &rctx->b, shader->bo,
+ PIPE_TRANSFER_WRITE | RADEON_TRANSFER_TEMPORARY);
if (R600_BIG_ENDIAN) {
for (i = 0; i < shader->shader.bc.ndw; ++i) {
ptr[i] = util_cpu_to_le32(shader->shader.bc.bytecode[i]);
return 0;
}
+extern const struct nir_shader_compiler_options r600_nir_options;
+static int nshader = 0;
int r600_pipe_shader_create(struct pipe_context *ctx,
struct r600_pipe_shader *shader,
union r600_shader_key key)
struct r600_context *rctx = (struct r600_context *)ctx;
struct r600_pipe_shader_selector *sel = shader->selector;
int r;
- bool dump = r600_can_dump_shader(&rctx->screen->b,
- tgsi_get_processor_type(sel->tokens));
- unsigned use_sb = !(rctx->screen->b.debug_flags & DBG_NO_SB);
+ struct r600_screen *rscreen = (struct r600_screen *)ctx->screen;
+
+ int processor = sel->ir_type == PIPE_SHADER_IR_TGSI ?
+ tgsi_get_processor_type(sel->tokens):
+ pipe_shader_type_from_mesa(sel->nir->info.stage);
+
+ bool dump = r600_can_dump_shader(&rctx->screen->b, processor);
+ unsigned use_sb = !(rctx->screen->b.debug_flags & DBG_NO_SB) &&
+ !(rscreen->b.debug_flags & DBG_NIR);
unsigned sb_disasm;
unsigned export_shader;
-
+
shader->shader.bc.isa = rctx->isa;
-
+
+ if (!(rscreen->b.debug_flags & DBG_NIR)) {
+ assert(sel->ir_type == PIPE_SHADER_IR_TGSI);
+ r = r600_shader_from_tgsi(rctx, shader, key);
+ if (r) {
+ R600_ERR("translation from TGSI failed !\n");
+ goto error;
+ }
+ } else {
+ if (sel->ir_type == PIPE_SHADER_IR_TGSI)
+ sel->nir = tgsi_to_nir_noscreen(sel->tokens, &r600_nir_options);
+ nir_tgsi_scan_shader(sel->nir, &sel->info, true);
+ r = r600_shader_from_nir(rctx, shader, &key);
+ if (r) {
+ fprintf(stderr, "--Failed shader--------------------------------------------------\n");
+
+ if (sel->ir_type == PIPE_SHADER_IR_TGSI) {
+ fprintf(stderr, "--TGSI--------------------------------------------------------\n");
+ tgsi_dump(sel->tokens, 0);
+ }
+
+ if (rscreen->b.debug_flags & DBG_NIR) {
+ fprintf(stderr, "--NIR --------------------------------------------------------\n");
+ nir_print_shader(sel->nir, stderr);
+ }
+
+ R600_ERR("translation from NIR failed !\n");
+ goto error;
+ }
+ }
+
if (dump) {
- fprintf(stderr, "--------------------------------------------------------------\n");
- tgsi_dump(sel->tokens, 0);
-
+ if (sel->ir_type == PIPE_SHADER_IR_TGSI) {
+ fprintf(stderr, "--TGSI--------------------------------------------------------\n");
+ tgsi_dump(sel->tokens, 0);
+ }
+
if (sel->so.num_outputs) {
r600_dump_streamout(&sel->so);
}
}
- r = r600_shader_from_tgsi(rctx, shader, key);
- if (r) {
- R600_ERR("translation from TGSI failed !\n");
- goto error;
- }
+
if (shader->shader.processor_type == PIPE_SHADER_VERTEX) {
/* only disable for vertex shaders in tess paths */
if (key.vs.as_ls)
r600_bytecode_disasm(&shader->shader.bc);
fprintf(stderr, "______________________________________________________________\n");
} else if ((dump && sb_disasm) || use_sb) {
- r = r600_sb_bytecode_process(rctx, &shader->shader.bc, &shader->shader,
+ r = r600_sb_bytecode_process(rctx, &shader->shader.bc, &shader->shader,
dump, use_sb);
if (r) {
R600_ERR("r600_sb_bytecode_process failed !\n");
}
}
+ if (dump) {
+ FILE *f;
+ char fname[1024];
+ snprintf(fname, 1024, "shader_from_%s_%d.cpp",
+ (sel->ir_type == PIPE_SHADER_IR_TGSI ?
+ (rscreen->b.debug_flags & DBG_NIR ? "tgsi-nir" : "tgsi")
+ : "nir"), nshader);
+ f = fopen(fname, "w");
+ print_shader_info(f, nshader++, &shader->shader);
+ print_shader_info(stderr, nshader++, &shader->shader);
+ print_pipe_info(stderr, &sel->info);
+ if (sel->ir_type == PIPE_SHADER_IR_TGSI) {
+ fprintf(f, "/****TGSI**********************************\n");
+ tgsi_dump_to_file(sel->tokens, 0, f);
+ }
+
+ if (rscreen->b.debug_flags & DBG_NIR){
+ fprintf(f, "/****NIR **********************************\n");
+ nir_print_shader(sel->nir, f);
+ }
+ fprintf(f, "******************************************/\n");
+ fclose(f);
+ }
+
if (shader->gs_copy_shader) {
if (dump) {
// dump copy shader
void r600_pipe_shader_destroy(struct pipe_context *ctx UNUSED, struct r600_pipe_shader *shader)
{
r600_resource_reference(&shader->bo, NULL);
- r600_bytecode_clear(&shader->shader.bc);
+ if (shader->shader.bc.cf.next)
+ r600_bytecode_clear(&shader->shader.bc);
r600_release_command_buffer(&shader->command_buffer);
}
};
/* we need this to get a common lds index for vs/tcs/tes input/outputs */
-int r600_get_lds_unique_index(unsigned semantic_name, unsigned index)
+int r600_get_lds_unique_index(unsigned semantic_name, unsigned index, bool texcoord_semantics)
{
switch (semantic_name) {
case TGSI_SEMANTIC_POSITION:
return 2 + index;
case TGSI_SEMANTIC_GENERIC:
if (index <= 63-4)
- return 4 + index - 9;
+ return 4 + index - (texcoord_semantics ? 0 : 9);
else
/* same explanation as in the default statement,
* the only user hitting this is st/nine.
break;
else if (d->Semantic.Name == TGSI_SEMANTIC_TESSINNER ||
d->Semantic.Name == TGSI_SEMANTIC_TESSOUTER) {
- int param = r600_get_lds_unique_index(d->Semantic.Name, 0);
+ int param = r600_get_lds_unique_index(d->Semantic.Name, 0, false);
int dreg = d->Semantic.Name == TGSI_SEMANTIC_TESSINNER ? 3 : 2;
unsigned temp_reg = r600_get_temp(ctx);
} else if (ctx->info.system_value_semantic_name[tgsi_src->Register.Index] == TGSI_SEMANTIC_TESSOUTER) {
r600_src->sel = 2;
} else if (ctx->info.system_value_semantic_name[tgsi_src->Register.Index] == TGSI_SEMANTIC_VERTICESIN) {
- if (ctx->type == PIPE_SHADER_TESS_CTRL) {
- r600_src->sel = ctx->tess_input_info;
- r600_src->swizzle[0] = 2;
- r600_src->swizzle[1] = 2;
- r600_src->swizzle[2] = 2;
- r600_src->swizzle[3] = 2;
- } else {
- r600_src->sel = ctx->tess_input_info;
- r600_src->swizzle[0] = 3;
- r600_src->swizzle[1] = 3;
- r600_src->swizzle[2] = 3;
- r600_src->swizzle[3] = 3;
- }
+ r600_src->sel = ctx->tess_input_info;
+ r600_src->swizzle[0] = 2;
+ r600_src->swizzle[1] = 2;
+ r600_src->swizzle[2] = 2;
+ r600_src->swizzle[3] = 2;
} else if (ctx->type == PIPE_SHADER_TESS_CTRL && ctx->info.system_value_semantic_name[tgsi_src->Register.Index] == TGSI_SEMANTIC_PRIMID) {
r600_src->sel = 0;
r600_src->swizzle[0] = 0;
return r;
param = r600_get_lds_unique_index(name[first],
- index[first]);
+ index[first], false);
} else {
param = r600_get_lds_unique_index(name[reg.Register.Index],
- index[reg.Register.Index]);
+ index[reg.Register.Index], false);
}
/* add to base_addr - passed in temp_reg.x */
r600_bytecode_add_alu(ctx->bc, &alu);
}
-static int generate_gs_copy_shader(struct r600_context *rctx,
- struct r600_pipe_shader *gs,
- struct pipe_stream_output_info *so)
+int generate_gs_copy_shader(struct r600_context *rctx,
+ struct r600_pipe_shader *gs,
+ struct pipe_stream_output_info *so)
{
struct r600_shader_ctx ctx = {};
struct r600_shader *gs_shader = &gs->shader;
for (i = 0; i < ctx->shader->noutput; i++) {
struct r600_bytecode_alu alu;
- int param = r600_get_lds_unique_index(ctx->shader->output[i].name, ctx->shader->output[i].sid);
+ int param = r600_get_lds_unique_index(ctx->shader->output[i].name,
+ ctx->shader->output[i].sid, false);
if (param) {
r = single_alu_op2(ctx, ALU_OP2_ADD_INT,
int dreg = ctx->shader->output[output_idx].gpr;
int r;
- param = r600_get_lds_unique_index(name, 0);
+ param = r600_get_lds_unique_index(name, 0, false);
r = get_lds_offset0(ctx, 1, temp_reg, true);
if (r)
return r;
ctx.tess_input_info = ++regno;
ctx.tess_output_info = ++regno;
} else if (ctx.type == PIPE_SHADER_TESS_EVAL) {
- ctx.tess_input_info = 0;
+ ctx.tess_input_info = ++regno;
ctx.tess_output_info = ++regno;
} else if (ctx.type == PIPE_SHADER_GEOMETRY) {
ctx.gs_export_gpr_tregs[0] = ++regno;
ctx.inst_info = &eg_shader_tgsi_instruction[opcode];
else
ctx.inst_info = &r600_shader_tgsi_instruction[opcode];
+
+ ctx.bc->precise |= ctx.parse.FullToken.FullInstruction.Instruction.Precise;
+
r = ctx.inst_info->process(&ctx);
if (r)
goto out_err;
}
else {
location = TGSI_INTERPOLATE_LOC_CENTROID;
+ ctx->shader->input[input].uses_interpolate_at_centroid = 1;
}
k = eg_get_interpolator_index(ctx->shader->input[input].interpolate, location);
if (r)
return r;
+ /* Evaluate the array index according to floor(idx + 0.5). This
+ * needs to be done before merging the face select value, because
+ * otherwise the fractional part of the array index will interfere
+ * with the face select value */
+ memset(&alu, 0, sizeof(struct r600_bytecode_alu));
+ r600_bytecode_src(&alu.src[0], &ctx->src[0], 3);
+ alu.op = ALU_OP1_RNDNE;
+ alu.dst.sel = ctx->temp_reg;
+ alu.dst.chan = 3;
+ alu.dst.write = 1;
+ alu.last = 1;
+ r = r600_bytecode_add_alu(ctx->bc, &alu);
+ if (r)
+ return r;
+
+ /* Because the array slice index and the cube face index are merged
+ * into one value we have to make sure the array slice index is >= 0,
+ * otherwise the face selection will fail */
+ memset(&alu, 0, sizeof(struct r600_bytecode_alu));
+ alu.op = ALU_OP2_MAX;
+ alu.src[0].sel = ctx->temp_reg;
+ alu.src[0].chan = 3;
+ alu.src[1].sel = V_SQ_ALU_SRC_0;
+ alu.dst.sel = ctx->temp_reg;
+ alu.dst.chan = 3;
+ alu.dst.write = 1;
+ alu.last = 1;
+ r = r600_bytecode_add_alu(ctx->bc, &alu);
+ if (r)
+ return r;
+
/* have to multiply original layer by 8 and add to face id (temp.w) in Z */
memset(&alu, 0, sizeof(struct r600_bytecode_alu));
alu.op = ALU_OP3_MULADD;
alu.is_op3 = 1;
- r600_bytecode_src(&alu.src[0], &ctx->src[0], 3);
+ alu.src[0].sel = ctx->temp_reg;
+ alu.src[0].chan = 3;
alu.src[1].sel = V_SQ_ALU_SRC_LITERAL;
alu.src[1].chan = 0;
alu.src[1].value = u_bitcast_f2u(8.0f);