* USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "r600_sq.h"
-#include "r600_llvm.h"
#include "r600_formats.h"
#include "r600_opcodes.h"
#include "r600_shader.h"
The compiler must issue the source argument to slots z, y, and x
*/
+/* Contents of r0 on entry to various shaders
+
+ VS - .x = VertexID
+ .y = RelVertexID (??)
+ .w = InstanceID
+
+ GS - r0.xyw, r1.xyz = per-vertex offsets
+ r0.z = PrimitiveID
+
+ TCS - .x = PatchID
+ .y = RelPatchID (??)
+ .z = InvocationID
+ .w = tess factor base.
+
+ TES - .x = TessCoord.x
+ - .y = TessCoord.y
+ - .z = RelPatchID (??)
+ - .w = PrimitiveID
+
+ PS - face_gpr.z = SampleMask
+ face_gpr.w = SampleID
+*/
#define R600_SHADER_BUFFER_INFO_SEL (512 + R600_BUFFER_INFO_OFFSET / 16)
static int r600_shader_from_tgsi(struct r600_context *rctx,
struct r600_pipe_shader *pipeshader,
union r600_shader_key key);
-
static void r600_add_gpr_array(struct r600_shader *ps, int start_gpr,
int size, unsigned comp_mask) {
} else {
memcpy(ptr, shader->shader.bc.bytecode, shader->shader.bc.ndw * sizeof(*ptr));
}
- rctx->b.ws->buffer_unmap(shader->bo->cs_buf);
+ rctx->b.ws->buffer_unmap(shader->bo->buf);
}
return 0;
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, sel->tokens);
+ 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);
unsigned sb_disasm = use_sb || (rctx->screen->b.debug_flags & DBG_SB_DISASM);
unsigned export_shader;
R600_ERR("translation from TGSI failed !\n");
goto error;
}
- if (shader->shader.processor_type == TGSI_PROCESSOR_VERTEX) {
+ if (shader->shader.processor_type == PIPE_SHADER_VERTEX) {
/* only disable for vertex shaders in tess paths */
if (key.vs.as_ls)
use_sb = 0;
}
- use_sb &= (shader->shader.processor_type != TGSI_PROCESSOR_TESS_CTRL);
- use_sb &= (shader->shader.processor_type != TGSI_PROCESSOR_TESS_EVAL);
+ use_sb &= (shader->shader.processor_type != PIPE_SHADER_TESS_CTRL);
+ use_sb &= (shader->shader.processor_type != PIPE_SHADER_TESS_EVAL);
/* disable SB for shaders using doubles */
use_sb &= !shader->shader.uses_doubles;
- /* Check if the bytecode has already been built. When using the llvm
- * backend, r600_shader_from_tgsi() will take care of building the
- * bytecode.
- */
+ /* Check if the bytecode has already been built. */
if (!shader->shader.bc.bytecode) {
r = r600_bytecode_build(&shader->shader.bc);
if (r) {
/* Build state. */
switch (shader->shader.processor_type) {
- case TGSI_PROCESSOR_TESS_CTRL:
+ case PIPE_SHADER_TESS_CTRL:
evergreen_update_hs_state(ctx, shader);
break;
- case TGSI_PROCESSOR_TESS_EVAL:
+ case PIPE_SHADER_TESS_EVAL:
if (key.tes.as_es)
evergreen_update_es_state(ctx, shader);
else
evergreen_update_vs_state(ctx, shader);
break;
- case TGSI_PROCESSOR_GEOMETRY:
+ case PIPE_SHADER_GEOMETRY:
if (rctx->b.chip_class >= EVERGREEN) {
evergreen_update_gs_state(ctx, shader);
evergreen_update_vs_state(ctx, shader->gs_copy_shader);
r600_update_vs_state(ctx, shader->gs_copy_shader);
}
break;
- case TGSI_PROCESSOR_VERTEX:
+ case PIPE_SHADER_VERTEX:
export_shader = key.vs.as_es;
if (rctx->b.chip_class >= EVERGREEN) {
if (key.vs.as_ls)
r600_update_vs_state(ctx, shader);
}
break;
- case TGSI_PROCESSOR_FRAGMENT:
+ case PIPE_SHADER_FRAGMENT:
if (rctx->b.chip_class >= EVERGREEN) {
evergreen_update_ps_state(ctx, shader);
} else {
uint32_t *literals;
uint32_t nliterals;
uint32_t max_driver_temp_used;
- boolean use_llvm;
/* needed for evergreen interpolation */
struct eg_interp eg_interpolators[6]; // indexed by Persp/Linear * 3 + sample/center/centroid
/* evergreen/cayman also store sample mask in face register */
static void r600_bytecode_src(struct r600_bytecode_alu_src *bc_src,
const struct r600_shader_src *shader_src,
unsigned chan);
+static int do_lds_fetch_values(struct r600_shader_ctx *ctx, unsigned temp_reg,
+ unsigned dst_reg);
static int tgsi_last_instruction(unsigned writemask)
{
static int tgsi_is_supported(struct r600_shader_ctx *ctx)
{
struct tgsi_full_instruction *i = &ctx->parse.FullToken.FullInstruction;
- int j;
+ unsigned j;
if (i->Instruction.NumDstRegs > 1 && i->Instruction.Opcode != TGSI_OPCODE_DFRACEXP) {
R600_ERR("too many dst (%d)\n", i->Instruction.NumDstRegs);
case TGSI_FILE_CONSTANT:
break;
case TGSI_FILE_INPUT:
- if (ctx->type == TGSI_PROCESSOR_GEOMETRY ||
- ctx->type == TGSI_PROCESSOR_TESS_CTRL ||
- ctx->type == TGSI_PROCESSOR_TESS_EVAL)
+ if (ctx->type == PIPE_SHADER_GEOMETRY ||
+ ctx->type == PIPE_SHADER_TESS_CTRL ||
+ ctx->type == PIPE_SHADER_TESS_EVAL)
break;
case TGSI_FILE_OUTPUT:
- if (ctx->type == TGSI_PROCESSOR_TESS_CTRL)
+ if (ctx->type == PIPE_SHADER_TESS_CTRL)
break;
default:
R600_ERR("unsupported src %d (file %d, dimension %d)\n", j,
}
for (j = 0; j < i->Instruction.NumDstRegs; j++) {
if (i->Dst[j].Register.Dimension) {
- if (ctx->type == TGSI_PROCESSOR_TESS_CTRL)
+ if (ctx->type == PIPE_SHADER_TESS_CTRL)
continue;
R600_ERR("unsupported dst (dimension)\n");
return -EINVAL;
ctx->shader->input[index].lds_pos = ctx->shader->nlds++;
if (ctx->shader->input[index].interpolate > 0) {
evergreen_interp_assign_ij_index(ctx, index);
- if (!ctx->use_llvm)
- r = evergreen_interp_alu(ctx, index);
+ r = evergreen_interp_alu(ctx, index);
} else {
- if (!ctx->use_llvm)
- r = evergreen_interp_flat(ctx, index);
+ r = evergreen_interp_flat(ctx, index);
}
}
return r;
return 0;
}
+static int tgsi_barrier(struct r600_shader_ctx *ctx)
+{
+ struct r600_bytecode_alu alu;
+ int r;
+
+ memset(&alu, 0, sizeof(struct r600_bytecode_alu));
+ alu.op = ctx->inst_info->op;
+ alu.last = 1;
+
+ r = r600_bytecode_add_alu(ctx->bc, &alu);
+ if (r)
+ return r;
+ return 0;
+}
+
static int tgsi_declaration(struct r600_shader_ctx *ctx)
{
struct tgsi_full_declaration *d = &ctx->parse.FullToken.FullDeclaration;
ctx->shader->input[i].interpolate = d->Interp.Interpolate;
ctx->shader->input[i].interpolate_location = d->Interp.Location;
ctx->shader->input[i].gpr = ctx->file_offset[TGSI_FILE_INPUT] + d->Range.First + j;
- if (ctx->type == TGSI_PROCESSOR_FRAGMENT) {
+ if (ctx->type == PIPE_SHADER_FRAGMENT) {
ctx->shader->input[i].spi_sid = r600_spi_sid(&ctx->shader->input[i]);
switch (ctx->shader->input[i].name) {
case TGSI_SEMANTIC_FACE:
if ((r = evergreen_interp_input(ctx, i)))
return r;
}
- } else if (ctx->type == TGSI_PROCESSOR_GEOMETRY) {
+ } else if (ctx->type == PIPE_SHADER_GEOMETRY) {
/* FIXME probably skip inputs if they aren't passed in the ring */
ctx->shader->input[i].ring_offset = ctx->next_ring_offset;
ctx->next_ring_offset += 16;
ctx->shader->output[i].gpr = ctx->file_offset[TGSI_FILE_OUTPUT] + d->Range.First + j;
ctx->shader->output[i].interpolate = d->Interp.Interpolate;
ctx->shader->output[i].write_mask = d->Declaration.UsageMask;
- if (ctx->type == TGSI_PROCESSOR_VERTEX ||
- ctx->type == TGSI_PROCESSOR_GEOMETRY ||
- ctx->type == TGSI_PROCESSOR_TESS_EVAL) {
+ if (ctx->type == PIPE_SHADER_VERTEX ||
+ ctx->type == PIPE_SHADER_GEOMETRY ||
+ ctx->type == PIPE_SHADER_TESS_EVAL) {
ctx->shader->output[i].spi_sid = r600_spi_sid(&ctx->shader->output[i]);
switch (d->Semantic.Name) {
case TGSI_SEMANTIC_CLIPDIST:
ctx->cv_output = i;
break;
}
- if (ctx->type == TGSI_PROCESSOR_GEOMETRY) {
+ if (ctx->type == PIPE_SHADER_GEOMETRY) {
ctx->gs_out_ring_offset += 16;
}
- } else if (ctx->type == TGSI_PROCESSOR_FRAGMENT) {
+ } else if (ctx->type == PIPE_SHADER_FRAGMENT) {
switch (d->Semantic.Name) {
case TGSI_SEMANTIC_COLOR:
ctx->shader->nr_ps_max_color_exports++;
break;
else if (d->Semantic.Name == TGSI_SEMANTIC_INVOCATIONID)
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 dreg = d->Semantic.Name == TGSI_SEMANTIC_TESSINNER ? 3 : 2;
+ unsigned temp_reg = r600_get_temp(ctx);
+
+ r = get_lds_offset0(ctx, 2, temp_reg, true);
+ if (r)
+ return r;
+
+ r = single_alu_op2(ctx, ALU_OP2_ADD_INT,
+ temp_reg, 0,
+ temp_reg, 0,
+ V_SQ_ALU_SRC_LITERAL, param * 16);
+ if (r)
+ return r;
+
+ do_lds_fetch_values(ctx, temp_reg, dreg);
+ }
+ else if (d->Semantic.Name == TGSI_SEMANTIC_TESSCOORD) {
+ /* MOV r1.x, r0.x;
+ MOV r1.y, r0.y;
+ */
+ for (i = 0; i < 2; i++) {
+ struct r600_bytecode_alu alu;
+ memset(&alu, 0, sizeof(struct r600_bytecode_alu));
+ alu.op = ALU_OP1_MOV;
+ alu.src[0].sel = 0;
+ alu.src[0].chan = 0 + i;
+ alu.dst.sel = 1;
+ alu.dst.chan = 0 + i;
+ alu.dst.write = 1;
+ alu.last = (i == 1) ? 1 : 0;
+ if ((r = r600_bytecode_add_alu(ctx->bc, &alu)))
+ return r;
+ }
+ /* ADD r1.z, 1.0f, -r0.x */
+ struct r600_bytecode_alu alu;
+ memset(&alu, 0, sizeof(struct r600_bytecode_alu));
+ alu.op = ALU_OP2_ADD;
+ alu.src[0].sel = V_SQ_ALU_SRC_1;
+ alu.src[1].sel = 1;
+ alu.src[1].chan = 0;
+ alu.src[1].neg = 1;
+ alu.dst.sel = 1;
+ alu.dst.chan = 2;
+ alu.dst.write = 1;
+ alu.last = 1;
+ if ((r = r600_bytecode_add_alu(ctx->bc, &alu)))
+ return r;
+
+ /* ADD r1.z, r1.z, -r1.y */
+ alu.op = ALU_OP2_ADD;
+ alu.src[0].sel = 1;
+ alu.src[0].chan = 2;
+ alu.src[1].sel = 1;
+ alu.src[1].chan = 1;
+ alu.src[1].neg = 1;
+ alu.dst.sel = 1;
+ alu.dst.chan = 2;
+ alu.dst.write = 1;
+ alu.last = 1;
+ if ((r = r600_bytecode_add_alu(ctx->bc, &alu)))
+ return r;
+ break;
+ }
+ break;
default:
R600_ERR("unsupported file %d declaration\n", d->Declaration.File);
return -EINVAL;
*/
static int evergreen_gpr_count(struct r600_shader_ctx *ctx)
{
- int i;
+ unsigned i;
int num_baryc;
struct tgsi_parse_context parse;
r600_src->swizzle[2] = 0;
r600_src->swizzle[3] = 0;
r600_src->sel = 0;
- } else if (ctx->info.system_value_semantic_name[tgsi_src->Register.Index] == TGSI_SEMANTIC_INVOCATIONID) {
+ } else if (ctx->type != PIPE_SHADER_TESS_CTRL && ctx->info.system_value_semantic_name[tgsi_src->Register.Index] == TGSI_SEMANTIC_INVOCATIONID) {
r600_src->swizzle[0] = 3;
r600_src->swizzle[1] = 3;
r600_src->swizzle[2] = 3;
r600_src->swizzle[3] = 3;
r600_src->sel = 1;
+ } else if (ctx->info.system_value_semantic_name[tgsi_src->Register.Index] == TGSI_SEMANTIC_INVOCATIONID) {
+ r600_src->swizzle[0] = 2;
+ r600_src->swizzle[1] = 2;
+ r600_src->swizzle[2] = 2;
+ r600_src->swizzle[3] = 2;
+ r600_src->sel = 0;
+ } else if (ctx->info.system_value_semantic_name[tgsi_src->Register.Index] == TGSI_SEMANTIC_TESSCOORD) {
+ r600_src->sel = 1;
+ } else if (ctx->info.system_value_semantic_name[tgsi_src->Register.Index] == TGSI_SEMANTIC_TESSINNER) {
+ r600_src->sel = 3;
+ } 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;
+ }
+ } 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;
+ r600_src->swizzle[1] = 0;
+ r600_src->swizzle[2] = 0;
+ r600_src->swizzle[3] = 0;
+ } else if (ctx->type == PIPE_SHADER_TESS_EVAL && ctx->info.system_value_semantic_name[tgsi_src->Register.Index] == TGSI_SEMANTIC_PRIMID) {
+ r600_src->sel = 0;
+ r600_src->swizzle[0] = 3;
+ r600_src->swizzle[1] = 3;
+ r600_src->swizzle[2] = 3;
+ r600_src->swizzle[3] = 3;
}
} else {
if (tgsi_src->Register.Indirect)
unsigned vtx_id = src->Dimension.Index;
int offset_reg = vtx_id / 3;
int offset_chan = vtx_id % 3;
+ int t2 = 0;
/* offsets of per-vertex data in ESGS ring are passed to GS in R0.x, R0.y,
* R0.w, R1.x, R1.y, R1.z (it seems R0.z is used for PrimitiveID) */
if (offset_reg == 0 && offset_chan == 2)
offset_chan = 3;
+ if (src->Dimension.Indirect || src->Register.Indirect)
+ t2 = r600_get_temp(ctx);
+
if (src->Dimension.Indirect) {
int treg[3];
- int t2;
struct r600_bytecode_alu alu;
int r, i;
-
- /* you have got to be shitting me -
+ unsigned addr_reg;
+ addr_reg = get_address_file_reg(ctx, src->DimIndirect.Index);
+ if (src->DimIndirect.Index > 0) {
+ r = single_alu_op2(ctx, ALU_OP1_MOV,
+ ctx->bc->ar_reg, 0,
+ addr_reg, 0,
+ 0, 0);
+ if (r)
+ return r;
+ }
+ /*
we have to put the R0.x/y/w into Rt.x Rt+1.x Rt+2.x then index reg from Rt.
at least this is what fglrx seems to do. */
for (i = 0; i < 3; i++) {
}
r600_add_gpr_array(ctx->shader, treg[0], 3, 0x0F);
- t2 = r600_get_temp(ctx);
for (i = 0; i < 3; i++) {
memset(&alu, 0, sizeof(struct r600_bytecode_alu));
alu.op = ALU_OP1_MOV;
if (r)
return r;
offset_reg = t2;
+ offset_chan = 0;
}
+ if (src->Register.Indirect) {
+ int addr_reg;
+ unsigned first = ctx->info.input_array_first[src->Indirect.ArrayID];
+
+ addr_reg = get_address_file_reg(ctx, src->Indirect.Index);
+
+ /* pull the value from index_reg */
+ r = single_alu_op2(ctx, ALU_OP2_ADD_INT,
+ t2, 1,
+ addr_reg, 0,
+ V_SQ_ALU_SRC_LITERAL, first);
+ if (r)
+ return r;
+ r = single_alu_op3(ctx, ALU_OP3_MULADD_UINT24,
+ t2, 0,
+ t2, 1,
+ V_SQ_ALU_SRC_LITERAL, 4,
+ offset_reg, offset_chan);
+ if (r)
+ return r;
+ offset_reg = t2;
+ offset_chan = 0;
+ index = src->Register.Index - first;
+ }
memset(&vtx, 0, sizeof(vtx));
vtx.buffer_id = R600_GS_RING_CONST_BUFFER;
static int tgsi_split_gs_inputs(struct r600_shader_ctx *ctx)
{
struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction;
- int i;
+ unsigned i;
for (i = 0; i < inst->Instruction.NumSrcRegs; i++) {
struct tgsi_full_src_register *src = &inst->Src[i];
fetch_gs_input(ctx, src, treg);
ctx->src[i].sel = treg;
+ ctx->src[i].rel = 0;
}
}
return 0;
temp_reg, i,
temp_reg, 0,
V_SQ_ALU_SRC_LITERAL, 4 * i);
+ if (r)
+ return r;
}
for (i = 0; i < 4; i++) {
/* emit an LDS_READ_RET */
static int tgsi_split_lds_inputs(struct r600_shader_ctx *ctx)
{
struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction;
- int i;
+ unsigned i;
for (i = 0; i < inst->Instruction.NumSrcRegs; i++) {
struct tgsi_full_src_register *src = &inst->Src[i];
- if (ctx->type == TGSI_PROCESSOR_TESS_EVAL && src->Register.File == TGSI_FILE_INPUT) {
+ if (ctx->type == PIPE_SHADER_TESS_EVAL && src->Register.File == TGSI_FILE_INPUT) {
int treg = r600_get_temp(ctx);
fetch_tes_input(ctx, src, treg);
ctx->src[i].sel = treg;
ctx->src[i].rel = 0;
}
- if (ctx->type == TGSI_PROCESSOR_TESS_CTRL && src->Register.File == TGSI_FILE_INPUT) {
+ if (ctx->type == PIPE_SHADER_TESS_CTRL && src->Register.File == TGSI_FILE_INPUT) {
int treg = r600_get_temp(ctx);
fetch_tcs_input(ctx, src, treg);
ctx->src[i].sel = treg;
ctx->src[i].rel = 0;
}
- if (ctx->type == TGSI_PROCESSOR_TESS_CTRL && src->Register.File == TGSI_FILE_OUTPUT) {
+ if (ctx->type == PIPE_SHADER_TESS_CTRL && src->Register.File == TGSI_FILE_OUTPUT) {
int treg = r600_get_temp(ctx);
fetch_tcs_output(ctx, src, treg);
ctx->src[i].sel = treg;
*last_exp_pos = NULL, *last_exp_param = NULL;
int i, j, next_clip_pos = 61, next_param = 0;
int ring;
-
+ bool only_ring_0 = true;
cshader = calloc(1, sizeof(struct r600_pipe_shader));
if (!cshader)
return 0;
ctx.shader = &cshader->shader;
ctx.bc = &ctx.shader->bc;
- ctx.type = ctx.bc->type = TGSI_PROCESSOR_VERTEX;
+ ctx.type = ctx.bc->type = PIPE_SHADER_VERTEX;
r600_bytecode_init(ctx.bc, rctx->b.chip_class, rctx->b.family,
rctx->screen->has_compressed_msaa_texturing);
for (i = 0; i < so->num_outputs; i++) {
if (so->output[i].stream == ring) {
enabled = true;
+ if (ring > 0)
+ only_ring_0 = false;
break;
}
}
cf_jump = ctx.bc->cf_last;
if (enabled)
- emit_streamout(&ctx, so, ring, &cshader->shader.ring_item_sizes[ring]);
+ emit_streamout(&ctx, so, only_ring_0 ? -1 : ring, &cshader->shader.ring_item_sizes[ring]);
cshader->shader.ring_item_sizes[ring] = ocnt * 16;
}
static int r600_emit_tess_factor(struct r600_shader_ctx *ctx)
{
- int i;
+ unsigned i;
int stride, outer_comps, inner_comps;
int tessinner_idx = -1, tessouter_idx = -1;
int r;
int i, j, k, r = 0;
int next_param_base = 0, next_clip_base;
int max_color_exports = MAX2(key.ps.nr_cbufs, 1);
- /* Declarations used by llvm code */
- bool use_llvm = false;
bool indirect_gprs;
bool ring_outputs = false;
bool lds_outputs = false;
bool lds_inputs = false;
bool pos_emitted = false;
-#ifdef R600_USE_LLVM
- use_llvm = rscreen->b.debug_flags & DBG_LLVM;
-#endif
ctx.bc = &shader->bc;
ctx.shader = shader;
ctx.native_integers = true;
-
r600_bytecode_init(ctx.bc, rscreen->b.chip_class, rscreen->b.family,
rscreen->has_compressed_msaa_texturing);
ctx.tokens = tokens;
ctx.bc->type = shader->processor_type;
switch (ctx.type) {
- case TGSI_PROCESSOR_VERTEX:
+ case PIPE_SHADER_VERTEX:
shader->vs_as_gs_a = key.vs.as_gs_a;
shader->vs_as_es = key.vs.as_es;
shader->vs_as_ls = key.vs.as_ls;
if (shader->vs_as_ls)
lds_outputs = true;
break;
- case TGSI_PROCESSOR_GEOMETRY:
+ case PIPE_SHADER_GEOMETRY:
ring_outputs = true;
break;
- case TGSI_PROCESSOR_TESS_CTRL:
+ case PIPE_SHADER_TESS_CTRL:
shader->tcs_prim_mode = key.tcs.prim_mode;
lds_outputs = true;
lds_inputs = true;
break;
- case TGSI_PROCESSOR_TESS_EVAL:
+ case PIPE_SHADER_TESS_EVAL:
shader->tes_as_es = key.tes.as_es;
lds_inputs = true;
if (shader->tes_as_es)
ring_outputs = true;
break;
- case TGSI_PROCESSOR_FRAGMENT:
+ case PIPE_SHADER_FRAGMENT:
shader->two_side = key.ps.color_two_side;
break;
default:
ctx.file_offset[i] = 0;
}
-#ifdef R600_USE_LLVM
- if (use_llvm && ctx.info.indirect_files && (ctx.info.indirect_files & (1 << TGSI_FILE_CONSTANT)) != ctx.info.indirect_files) {
- fprintf(stderr, "Warning: R600 LLVM backend does not support "
- "indirect adressing. Falling back to TGSI "
- "backend.\n");
- use_llvm = 0;
- }
-#endif
- if (ctx.type == TGSI_PROCESSOR_VERTEX) {
+ if (ctx.type == PIPE_SHADER_VERTEX) {
ctx.file_offset[TGSI_FILE_INPUT] = 1;
- if (!use_llvm) {
- r600_bytecode_add_cfinst(ctx.bc, CF_OP_CALL_FS);
- }
+ r600_bytecode_add_cfinst(ctx.bc, CF_OP_CALL_FS);
}
- if (ctx.type == TGSI_PROCESSOR_FRAGMENT) {
+ if (ctx.type == PIPE_SHADER_FRAGMENT) {
if (ctx.bc->chip_class >= EVERGREEN)
ctx.file_offset[TGSI_FILE_INPUT] = evergreen_gpr_count(&ctx);
else
ctx.file_offset[TGSI_FILE_INPUT] = allocate_system_value_inputs(&ctx, ctx.file_offset[TGSI_FILE_INPUT]);
}
- if (ctx.type == TGSI_PROCESSOR_GEOMETRY) {
+ if (ctx.type == PIPE_SHADER_GEOMETRY) {
/* FIXME 1 would be enough in some cases (3 or less input vertices) */
ctx.file_offset[TGSI_FILE_INPUT] = 2;
}
- ctx.use_llvm = use_llvm;
+ if (ctx.type == PIPE_SHADER_TESS_CTRL)
+ ctx.file_offset[TGSI_FILE_INPUT] = 1;
+ if (ctx.type == PIPE_SHADER_TESS_EVAL) {
+ bool add_tesscoord = false, add_tess_inout = false;
+ ctx.file_offset[TGSI_FILE_INPUT] = 1;
+ for (i = 0; i < PIPE_MAX_SHADER_INPUTS; i++) {
+ /* if we have tesscoord save one reg */
+ if (ctx.info.system_value_semantic_name[i] == TGSI_SEMANTIC_TESSCOORD)
+ add_tesscoord = true;
+ if (ctx.info.system_value_semantic_name[i] == TGSI_SEMANTIC_TESSINNER ||
+ ctx.info.system_value_semantic_name[i] == TGSI_SEMANTIC_TESSOUTER)
+ add_tess_inout = true;
+ }
+ if (add_tesscoord || add_tess_inout)
+ ctx.file_offset[TGSI_FILE_INPUT]++;
+ if (add_tess_inout)
+ ctx.file_offset[TGSI_FILE_INPUT]+=2;
+ }
- if (use_llvm) {
- ctx.file_offset[TGSI_FILE_OUTPUT] =
- ctx.file_offset[TGSI_FILE_INPUT];
- } else {
- ctx.file_offset[TGSI_FILE_OUTPUT] =
+ ctx.file_offset[TGSI_FILE_OUTPUT] =
ctx.file_offset[TGSI_FILE_INPUT] +
ctx.info.file_max[TGSI_FILE_INPUT] + 1;
- }
ctx.file_offset[TGSI_FILE_TEMPORARY] = ctx.file_offset[TGSI_FILE_OUTPUT] +
ctx.info.file_max[TGSI_FILE_OUTPUT] + 1;
ctx.bc->index_reg[0] = ctx.bc->ar_reg + 1;
ctx.bc->index_reg[1] = ctx.bc->ar_reg + 2;
- if (ctx.type == TGSI_PROCESSOR_TESS_CTRL) {
+ if (ctx.type == PIPE_SHADER_TESS_CTRL) {
ctx.tess_input_info = ctx.bc->ar_reg + 3;
ctx.tess_output_info = ctx.bc->ar_reg + 4;
ctx.temp_reg = ctx.bc->ar_reg + 5;
- } else if (ctx.type == TGSI_PROCESSOR_TESS_EVAL) {
+ } else if (ctx.type == PIPE_SHADER_TESS_EVAL) {
ctx.tess_input_info = 0;
ctx.tess_output_info = ctx.bc->ar_reg + 3;
ctx.temp_reg = ctx.bc->ar_reg + 4;
- } else if (ctx.type == TGSI_PROCESSOR_GEOMETRY) {
+ } else if (ctx.type == PIPE_SHADER_GEOMETRY) {
ctx.gs_export_gpr_tregs[0] = ctx.bc->ar_reg + 3;
ctx.gs_export_gpr_tregs[1] = ctx.bc->ar_reg + 4;
ctx.gs_export_gpr_tregs[2] = ctx.bc->ar_reg + 5;
ctx.nliterals = 0;
ctx.literals = NULL;
- shader->fs_write_all = ctx.info.properties[TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS];
+ shader->fs_write_all = ctx.info.properties[TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS] &&
+ ctx.info.colors_written == 1;
shader->vs_position_window_space = ctx.info.properties[TGSI_PROPERTY_VS_WINDOW_SPACE_POSITION];
shader->ps_conservative_z = (uint8_t)ctx.info.properties[TGSI_PROPERTY_FS_DEPTH_LAYOUT];
if (shader->vs_as_gs_a)
vs_add_primid_output(&ctx, key.vs.prim_id_out);
- if (ctx.type == TGSI_PROCESSOR_TESS_EVAL)
+ if (ctx.type == PIPE_SHADER_TESS_EVAL)
r600_fetch_tess_io_info(&ctx);
while (!tgsi_parse_end_of_tokens(&ctx.parse)) {
}
}
-/* LLVM backend setup */
-#ifdef R600_USE_LLVM
- if (use_llvm) {
- struct radeon_llvm_context radeon_llvm_ctx;
- LLVMModuleRef mod;
- bool dump = r600_can_dump_shader(&rscreen->b, tokens);
- boolean use_kill = false;
-
- memset(&radeon_llvm_ctx, 0, sizeof(radeon_llvm_ctx));
- radeon_llvm_ctx.type = ctx.type;
- radeon_llvm_ctx.two_side = shader->two_side;
- radeon_llvm_ctx.face_gpr = ctx.face_gpr;
- radeon_llvm_ctx.inputs_count = ctx.shader->ninput + 1;
- radeon_llvm_ctx.r600_inputs = ctx.shader->input;
- radeon_llvm_ctx.r600_outputs = ctx.shader->output;
- radeon_llvm_ctx.color_buffer_count = max_color_exports;
- radeon_llvm_ctx.chip_class = ctx.bc->chip_class;
- radeon_llvm_ctx.fs_color_all = shader->fs_write_all && (rscreen->b.chip_class >= EVERGREEN);
- radeon_llvm_ctx.stream_outputs = &so;
- radeon_llvm_ctx.alpha_to_one = key.ps.alpha_to_one;
- radeon_llvm_ctx.has_compressed_msaa_texturing =
- ctx.bc->has_compressed_msaa_texturing;
- mod = r600_tgsi_llvm(&radeon_llvm_ctx, tokens);
- ctx.shader->has_txq_cube_array_z_comp = radeon_llvm_ctx.has_txq_cube_array_z_comp;
- ctx.shader->uses_tex_buffers = radeon_llvm_ctx.uses_tex_buffers;
-
- if (r600_llvm_compile(mod, rscreen->b.family, ctx.bc, &use_kill, dump)) {
- radeon_llvm_dispose(&radeon_llvm_ctx);
- use_llvm = 0;
- fprintf(stderr, "R600 LLVM backend failed to compile "
- "shader. Falling back to TGSI\n");
- } else {
- ctx.file_offset[TGSI_FILE_OUTPUT] =
- ctx.file_offset[TGSI_FILE_INPUT];
- }
- if (use_kill)
- ctx.shader->uses_kill = use_kill;
- radeon_llvm_dispose(&radeon_llvm_ctx);
- }
-#endif
-/* End of LLVM backend setup */
-
if (shader->fs_write_all && rscreen->b.chip_class >= EVERGREEN)
shader->nr_ps_max_color_exports = 8;
- if (!use_llvm) {
- if (ctx.fragcoord_input >= 0) {
- if (ctx.bc->chip_class == CAYMAN) {
- for (j = 0 ; j < 4; j++) {
- struct r600_bytecode_alu alu;
- memset(&alu, 0, sizeof(struct r600_bytecode_alu));
- alu.op = ALU_OP1_RECIP_IEEE;
- alu.src[0].sel = shader->input[ctx.fragcoord_input].gpr;
- alu.src[0].chan = 3;
-
- alu.dst.sel = shader->input[ctx.fragcoord_input].gpr;
- alu.dst.chan = j;
- alu.dst.write = (j == 3);
- alu.last = 1;
- if ((r = r600_bytecode_add_alu(ctx.bc, &alu)))
- return r;
- }
- } else {
+ if (ctx.fragcoord_input >= 0) {
+ if (ctx.bc->chip_class == CAYMAN) {
+ for (j = 0 ; j < 4; j++) {
struct r600_bytecode_alu alu;
memset(&alu, 0, sizeof(struct r600_bytecode_alu));
alu.op = ALU_OP1_RECIP_IEEE;
alu.src[0].chan = 3;
alu.dst.sel = shader->input[ctx.fragcoord_input].gpr;
- alu.dst.chan = 3;
- alu.dst.write = 1;
+ alu.dst.chan = j;
+ alu.dst.write = (j == 3);
alu.last = 1;
if ((r = r600_bytecode_add_alu(ctx.bc, &alu)))
return r;
}
- }
-
- if (ctx.type == TGSI_PROCESSOR_GEOMETRY) {
+ } else {
struct r600_bytecode_alu alu;
- int r;
-
- /* GS thread with no output workaround - emit a cut at start of GS */
- if (ctx.bc->chip_class == R600)
- r600_bytecode_add_cfinst(ctx.bc, CF_OP_CUT_VERTEX);
+ memset(&alu, 0, sizeof(struct r600_bytecode_alu));
+ alu.op = ALU_OP1_RECIP_IEEE;
+ alu.src[0].sel = shader->input[ctx.fragcoord_input].gpr;
+ alu.src[0].chan = 3;
- for (j = 0; j < 4; j++) {
- memset(&alu, 0, sizeof(struct r600_bytecode_alu));
- alu.op = ALU_OP1_MOV;
- alu.src[0].sel = V_SQ_ALU_SRC_LITERAL;
- alu.src[0].value = 0;
- alu.dst.sel = ctx.gs_export_gpr_tregs[j];
- alu.dst.write = 1;
- alu.last = 1;
- r = r600_bytecode_add_alu(ctx.bc, &alu);
- if (r)
- return r;
- }
+ alu.dst.sel = shader->input[ctx.fragcoord_input].gpr;
+ alu.dst.chan = 3;
+ alu.dst.write = 1;
+ alu.last = 1;
+ if ((r = r600_bytecode_add_alu(ctx.bc, &alu)))
+ return r;
}
+ }
+
+ if (ctx.type == PIPE_SHADER_GEOMETRY) {
+ struct r600_bytecode_alu alu;
+ int r;
- if (ctx.type == TGSI_PROCESSOR_TESS_CTRL)
- r600_fetch_tess_io_info(&ctx);
+ /* GS thread with no output workaround - emit a cut at start of GS */
+ if (ctx.bc->chip_class == R600)
+ r600_bytecode_add_cfinst(ctx.bc, CF_OP_CUT_VERTEX);
- if (shader->two_side && ctx.colors_used) {
- if ((r = process_twoside_color_inputs(&ctx)))
+ for (j = 0; j < 4; j++) {
+ memset(&alu, 0, sizeof(struct r600_bytecode_alu));
+ alu.op = ALU_OP1_MOV;
+ alu.src[0].sel = V_SQ_ALU_SRC_LITERAL;
+ alu.src[0].value = 0;
+ alu.dst.sel = ctx.gs_export_gpr_tregs[j];
+ alu.dst.write = 1;
+ alu.last = 1;
+ r = r600_bytecode_add_alu(ctx.bc, &alu);
+ if (r)
return r;
}
+ }
- tgsi_parse_init(&ctx.parse, tokens);
- while (!tgsi_parse_end_of_tokens(&ctx.parse)) {
- tgsi_parse_token(&ctx.parse);
- switch (ctx.parse.FullToken.Token.Type) {
- case TGSI_TOKEN_TYPE_INSTRUCTION:
- r = tgsi_is_supported(&ctx);
- if (r)
- goto out_err;
- ctx.max_driver_temp_used = 0;
- /* reserve first tmp for everyone */
- r600_get_temp(&ctx);
+ if (ctx.type == PIPE_SHADER_TESS_CTRL)
+ r600_fetch_tess_io_info(&ctx);
+
+ if (shader->two_side && ctx.colors_used) {
+ if ((r = process_twoside_color_inputs(&ctx)))
+ return r;
+ }
+
+ tgsi_parse_init(&ctx.parse, tokens);
+ while (!tgsi_parse_end_of_tokens(&ctx.parse)) {
+ tgsi_parse_token(&ctx.parse);
+ switch (ctx.parse.FullToken.Token.Type) {
+ case TGSI_TOKEN_TYPE_INSTRUCTION:
+ r = tgsi_is_supported(&ctx);
+ if (r)
+ goto out_err;
+ ctx.max_driver_temp_used = 0;
+ /* reserve first tmp for everyone */
+ r600_get_temp(&ctx);
- opcode = ctx.parse.FullToken.FullInstruction.Instruction.Opcode;
- if ((r = tgsi_split_constant(&ctx)))
+ opcode = ctx.parse.FullToken.FullInstruction.Instruction.Opcode;
+ if ((r = tgsi_split_constant(&ctx)))
+ goto out_err;
+ if ((r = tgsi_split_literal_constant(&ctx)))
+ goto out_err;
+ if (ctx.type == PIPE_SHADER_GEOMETRY) {
+ if ((r = tgsi_split_gs_inputs(&ctx)))
goto out_err;
- if ((r = tgsi_split_literal_constant(&ctx)))
+ } else if (lds_inputs) {
+ if ((r = tgsi_split_lds_inputs(&ctx)))
goto out_err;
- if (ctx.type == TGSI_PROCESSOR_GEOMETRY) {
- if ((r = tgsi_split_gs_inputs(&ctx)))
- goto out_err;
- } else if (lds_inputs) {
- if ((r = tgsi_split_lds_inputs(&ctx)))
- goto out_err;
- }
- if (ctx.bc->chip_class == CAYMAN)
- ctx.inst_info = &cm_shader_tgsi_instruction[opcode];
- else if (ctx.bc->chip_class >= EVERGREEN)
- ctx.inst_info = &eg_shader_tgsi_instruction[opcode];
- else
- ctx.inst_info = &r600_shader_tgsi_instruction[opcode];
- r = ctx.inst_info->process(&ctx);
+ }
+ if (ctx.bc->chip_class == CAYMAN)
+ ctx.inst_info = &cm_shader_tgsi_instruction[opcode];
+ else if (ctx.bc->chip_class >= EVERGREEN)
+ ctx.inst_info = &eg_shader_tgsi_instruction[opcode];
+ else
+ ctx.inst_info = &r600_shader_tgsi_instruction[opcode];
+ r = ctx.inst_info->process(&ctx);
+ if (r)
+ goto out_err;
+
+ if (ctx.type == PIPE_SHADER_TESS_CTRL) {
+ r = r600_store_tcs_output(&ctx);
if (r)
goto out_err;
-
- if (ctx.type == TGSI_PROCESSOR_TESS_CTRL) {
- r = r600_store_tcs_output(&ctx);
- if (r)
- goto out_err;
- }
- break;
- default:
- break;
}
+ break;
+ default:
+ break;
}
}
alu.dst.write = (j == ochan);
if (j == 3)
alu.last = 1;
- if (!use_llvm)
- r = r600_bytecode_add_alu(ctx.bc, &alu);
+ r = r600_bytecode_add_alu(ctx.bc, &alu);
if (r)
return r;
}
}
/* Add stream outputs. */
- if (!use_llvm && so.num_outputs) {
+ if (so.num_outputs) {
bool emit = false;
- if (!lds_outputs && !ring_outputs && ctx.type == TGSI_PROCESSOR_VERTEX)
+ if (!lds_outputs && !ring_outputs && ctx.type == PIPE_SHADER_VERTEX)
emit = true;
- if (!ring_outputs && ctx.type == TGSI_PROCESSOR_TESS_EVAL)
+ if (!ring_outputs && ctx.type == PIPE_SHADER_TESS_EVAL)
emit = true;
if (emit)
emit_streamout(&ctx, &so, -1, NULL);
pipeshader->enabled_stream_buffers_mask = ctx.enabled_stream_buffers_mask;
convert_edgeflag_to_int(&ctx);
- if (ctx.type == TGSI_PROCESSOR_TESS_CTRL)
+ if (ctx.type == PIPE_SHADER_TESS_CTRL)
r600_emit_tess_factor(&ctx);
if (lds_outputs) {
- if (ctx.type == TGSI_PROCESSOR_VERTEX) {
+ if (ctx.type == PIPE_SHADER_VERTEX) {
if (ctx.shader->noutput)
emit_lds_vs_writes(&ctx);
}
output[j].type = -1;
output[j].op = CF_OP_EXPORT;
switch (ctx.type) {
- case TGSI_PROCESSOR_VERTEX:
- case TGSI_PROCESSOR_TESS_EVAL:
+ case PIPE_SHADER_VERTEX:
+ case PIPE_SHADER_TESS_EVAL:
switch (shader->output[i].name) {
case TGSI_SEMANTIC_POSITION:
output[j].array_base = 60;
}
break;
- case TGSI_PROCESSOR_FRAGMENT:
+ case PIPE_SHADER_FRAGMENT:
if (shader->output[i].name == TGSI_SEMANTIC_COLOR) {
/* never export more colors than the number of CBs */
if (shader->output[i].sid >= max_color_exports) {
goto out_err;
}
break;
- case TGSI_PROCESSOR_TESS_CTRL:
+ case PIPE_SHADER_TESS_CTRL:
break;
default:
R600_ERR("unsupported processor type %d\n", ctx.type);
}
/* add fake position export */
- if ((ctx.type == TGSI_PROCESSOR_VERTEX || ctx.type == TGSI_PROCESSOR_TESS_EVAL) && pos_emitted == false) {
+ if ((ctx.type == PIPE_SHADER_VERTEX || ctx.type == PIPE_SHADER_TESS_EVAL) && pos_emitted == false) {
memset(&output[j], 0, sizeof(struct r600_bytecode_output));
output[j].gpr = 0;
output[j].elem_size = 3;
}
/* add fake param output for vertex shader if no param is exported */
- if ((ctx.type == TGSI_PROCESSOR_VERTEX || ctx.type == TGSI_PROCESSOR_TESS_EVAL) && next_param_base == 0) {
+ if ((ctx.type == PIPE_SHADER_VERTEX || ctx.type == PIPE_SHADER_TESS_EVAL) && next_param_base == 0) {
memset(&output[j], 0, sizeof(struct r600_bytecode_output));
output[j].gpr = 0;
output[j].elem_size = 3;
}
/* add fake pixel export */
- if (ctx.type == TGSI_PROCESSOR_FRAGMENT && shader->nr_ps_color_exports == 0) {
+ if (ctx.type == PIPE_SHADER_FRAGMENT && shader->nr_ps_color_exports == 0) {
memset(&output[j], 0, sizeof(struct r600_bytecode_output));
output[j].gpr = 0;
output[j].elem_size = 3;
}
}
/* add output to bytecode */
- if (!use_llvm) {
- for (i = 0; i < noutput; i++) {
- r = r600_bytecode_add_output(ctx.bc, &output[i]);
- if (r)
- goto out_err;
- }
+ for (i = 0; i < noutput; i++) {
+ r = r600_bytecode_add_output(ctx.bc, &output[i]);
+ if (r)
+ goto out_err;
}
}
/* add program end */
- if (!use_llvm) {
- if (ctx.bc->chip_class == CAYMAN)
- cm_bytecode_add_cf_end(ctx.bc);
- else {
- const struct cf_op_info *last = NULL;
+ if (ctx.bc->chip_class == CAYMAN)
+ cm_bytecode_add_cf_end(ctx.bc);
+ else {
+ const struct cf_op_info *last = NULL;
- if (ctx.bc->cf_last)
- last = r600_isa_cf(ctx.bc->cf_last->op);
+ if (ctx.bc->cf_last)
+ last = r600_isa_cf(ctx.bc->cf_last->op);
- /* alu clause instructions don't have EOP bit, so add NOP */
- if (!last || last->flags & CF_ALU || ctx.bc->cf_last->op == CF_OP_LOOP_END || ctx.bc->cf_last->op == CF_OP_CALL_FS || ctx.bc->cf_last->op == CF_OP_POP || ctx.bc->cf_last->op == CF_OP_GDS)
- r600_bytecode_add_cfinst(ctx.bc, CF_OP_NOP);
+ /* alu clause instructions don't have EOP bit, so add NOP */
+ if (!last || last->flags & CF_ALU || ctx.bc->cf_last->op == CF_OP_LOOP_END || ctx.bc->cf_last->op == CF_OP_CALL_FS || ctx.bc->cf_last->op == CF_OP_POP || ctx.bc->cf_last->op == CF_OP_GDS)
+ r600_bytecode_add_cfinst(ctx.bc, CF_OP_NOP);
- ctx.bc->cf_last->end_of_program = 1;
- }
+ ctx.bc->cf_last->end_of_program = 1;
}
/* check GPR limit - we have 124 = 128 - 4
goto out_err;
}
- if (ctx.type == TGSI_PROCESSOR_GEOMETRY) {
+ if (ctx.type == PIPE_SHADER_GEOMETRY) {
if ((r = generate_gs_copy_shader(rctx, pipeshader, &so)))
return r;
}
if (inst->Instruction.Saturate) {
r600_dst->clamp = 1;
}
- if (ctx->type == TGSI_PROCESSOR_TESS_CTRL) {
+ if (ctx->type == PIPE_SHADER_TESS_CTRL) {
if (tgsi_dst->Register.File == TGSI_FILE_OUTPUT) {
return;
}
memset(&alu, 0, sizeof(struct r600_bytecode_alu));
alu.op = ctx->inst_info->op;
for (j = 0; j < inst->Instruction.NumSrcRegs; j++) {
- r600_bytecode_src(&alu.src[j], &ctx->src[j], k * 2 + ((i == 3) ? 0 : 1));;
+ r600_bytecode_src(&alu.src[j], &ctx->src[j], k * 2 + ((i == 3) ? 0 : 1));
}
alu.dst.sel = t1;
alu.dst.chan = i;
{
int chan;
int sel;
- int i;
+ unsigned i;
if (ctx->bc->chip_class == CAYMAN) {
for (i = 0; i < 3; i++) {
inst->Src[index].Register.File != TGSI_FILE_INPUT &&
inst->Src[index].Register.File != TGSI_FILE_OUTPUT) ||
ctx->src[index].neg || ctx->src[index].abs ||
- (inst->Src[index].Register.File == TGSI_FILE_INPUT && ctx->type == TGSI_PROCESSOR_GEOMETRY);
+ (inst->Src[index].Register.File == TGSI_FILE_INPUT && ctx->type == PIPE_SHADER_GEOMETRY);
}
static inline unsigned tgsi_tex_get_src_gpr(struct r600_shader_ctx *ctx,
struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction;
struct r600_bytecode_alu alu;
int r;
- int i;
+ unsigned i;
/* result.x = 2^floor(src); */
if (inst->Dst[0].Register.WriteMask & 1) {
struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction;
struct r600_bytecode_alu alu;
int r;
- int i;
+ unsigned i;
/* result.x = floor(log2(|src|)); */
if (inst->Dst[0].Register.WriteMask & 1) {
static int tgsi_endloop(struct r600_shader_ctx *ctx)
{
- int i;
+ unsigned i;
r600_bytecode_add_cfinst(ctx->bc, CF_OP_LOOP_END);
r = r600_bytecode_add_cfinst(ctx->bc, ctx->inst_info->op);
if (!r) {
ctx->bc->cf_last->count = stream; // Count field for CUT/EMIT_VERTEX indicates which stream
- return emit_inc_ring_offset(ctx, stream, TRUE);
+ if (ctx->inst_info->op == CF_OP_EMIT_VERTEX)
+ return emit_inc_ring_offset(ctx, stream, TRUE);
}
return r;
}
[TGSI_OPCODE_MFENCE] = { ALU_OP0_NOP, tgsi_unsupported},
[TGSI_OPCODE_LFENCE] = { ALU_OP0_NOP, tgsi_unsupported},
[TGSI_OPCODE_SFENCE] = { ALU_OP0_NOP, tgsi_unsupported},
- [TGSI_OPCODE_BARRIER] = { ALU_OP0_NOP, tgsi_unsupported},
+ [TGSI_OPCODE_BARRIER] = { ALU_OP0_GROUP_BARRIER, tgsi_barrier},
[TGSI_OPCODE_ATOMUADD] = { ALU_OP0_NOP, tgsi_unsupported},
[TGSI_OPCODE_ATOMXCHG] = { ALU_OP0_NOP, tgsi_unsupported},
[TGSI_OPCODE_ATOMCAS] = { ALU_OP0_NOP, tgsi_unsupported},
[TGSI_OPCODE_MFENCE] = { ALU_OP0_NOP, tgsi_unsupported},
[TGSI_OPCODE_LFENCE] = { ALU_OP0_NOP, tgsi_unsupported},
[TGSI_OPCODE_SFENCE] = { ALU_OP0_NOP, tgsi_unsupported},
- [TGSI_OPCODE_BARRIER] = { ALU_OP0_NOP, tgsi_unsupported},
+ [TGSI_OPCODE_BARRIER] = { ALU_OP0_GROUP_BARRIER, tgsi_barrier},
[TGSI_OPCODE_ATOMUADD] = { ALU_OP0_NOP, tgsi_unsupported},
[TGSI_OPCODE_ATOMXCHG] = { ALU_OP0_NOP, tgsi_unsupported},
[TGSI_OPCODE_ATOMCAS] = { ALU_OP0_NOP, tgsi_unsupported},