bool has_tex_txf_lz;
bool precise;
bool need_uarl;
+ bool tg4_component_in_swizzle;
variable_storage *find_variable_storage(ir_variable *var);
virtual void visit(ir_call *);
virtual void visit(ir_return *);
virtual void visit(ir_discard *);
+ virtual void visit(ir_demote *);
virtual void visit(ir_texture *);
virtual void visit(ir_if *);
virtual void visit(ir_emit_vertex *);
case ir_binop_carry:
case ir_binop_borrow:
case ir_unop_ssbo_unsized_array_length:
+ case ir_unop_atan:
+ case ir_binop_atan2:
/* This operation is not supported, or should have already been handled.
*/
assert(!"Invalid ir opcode in glsl_to_tgsi_visitor::visit()");
case ir_intrinsic_image_atomic_comp_swap:
opcode = TGSI_OPCODE_ATOMCAS;
break;
- case ir_intrinsic_image_atomic_inc_wrap:
+ case ir_intrinsic_image_atomic_inc_wrap: {
+ /* There's a bit of disagreement between GLSL and the hardware. The
+ * hardware wants to wrap after the given wrap value, while GLSL
+ * wants to wrap at the value. Subtract 1 to make up the difference.
+ */
+ st_src_reg wrap = get_temp(glsl_type::uint_type);
+ emit_asm(ir, TGSI_OPCODE_ADD, st_dst_reg(wrap),
+ arg1, st_src_reg_for_int(-1));
+ arg1 = wrap;
opcode = TGSI_OPCODE_ATOMINC_WRAP;
break;
+ }
case ir_intrinsic_image_atomic_dec_wrap:
opcode = TGSI_OPCODE_ATOMDEC_WRAP;
break;
visit_generic_intrinsic(ir, TGSI_OPCODE_READ_INVOC);
return;
+ case ir_intrinsic_helper_invocation:
+ visit_generic_intrinsic(ir, TGSI_OPCODE_READ_HELPER);
+ return;
+
case ir_intrinsic_invalid:
case ir_intrinsic_generic_load:
case ir_intrinsic_generic_store:
if (is_cube_array && ir->shadow_comparator) {
inst = emit_asm(ir, opcode, result_dst, coord, cube_sc);
} else {
- inst = emit_asm(ir, opcode, result_dst, coord, component);
+ if (this->tg4_component_in_swizzle) {
+ inst = emit_asm(ir, opcode, result_dst, coord);
+ int idx = 0;
+ foreach_in_list(immediate_storage, entry, &this->immediates) {
+ if (component.index == idx) {
+ gl_constant_value value = entry->values[component.swizzle];
+ inst->gather_component = value.i;
+ break;
+ }
+ idx++;
+ }
+ } else {
+ inst = emit_asm(ir, opcode, result_dst, coord, component);
+ }
}
} else
inst = emit_asm(ir, opcode, result_dst, coord);
}
}
+void
+glsl_to_tgsi_visitor::visit(ir_demote *ir)
+{
+ emit_asm(ir, TGSI_OPCODE_DEMOTE);
+}
+
void
glsl_to_tgsi_visitor::visit(ir_if *ir)
{
prog = NULL;
precise = 0;
need_uarl = false;
+ tg4_component_in_swizzle = false;
shader_program = NULL;
shader = NULL;
options = NULL;
enum pipe_shader_type procType; /**< PIPE_SHADER_VERTEX/FRAGMENT */
bool need_uarl;
+ bool tg4_component_in_swizzle;
};
/** Map Mesa's SYSTEM_VALUE_x to TGSI_SEMANTIC_x */
case TGSI_OPCODE_SAMP2HND:
if (inst->resource.file == PROGRAM_SAMPLER) {
src[num_src] = t->samplers[inst->resource.index];
+ if (t->tg4_component_in_swizzle && inst->op == TGSI_OPCODE_TG4)
+ src[num_src].SwizzleX = inst->gather_component;
} else {
/* Bindless samplers. */
src[num_src] = translate_src(t, &inst->resource);
t->procType = procType;
t->need_uarl = !screen->get_param(screen, PIPE_CAP_TGSI_ANY_REG_AS_ADDRESS);
+ t->tg4_component_in_swizzle = screen->get_param(screen, PIPE_CAP_TGSI_TG4_COMPONENT_IN_SWIZZLE);
t->inputMapping = inputMapping;
t->outputMapping = outputMapping;
t->ureg = ureg;
PIPE_CAP_TGSI_TEX_TXF_LZ);
v->need_uarl = !pscreen->get_param(pscreen, PIPE_CAP_TGSI_ANY_REG_AS_ADDRESS);
+ v->tg4_component_in_swizzle = pscreen->get_param(pscreen, PIPE_CAP_TGSI_TG4_COMPONENT_IN_SWIZZLE);
v->variables = _mesa_hash_table_create(v->mem_ctx, _mesa_hash_pointer,
_mesa_key_pointer_equal);
skip_merge_registers =
}
struct st_vertex_program *stvp;
- struct st_fragment_program *stfp;
struct st_common_program *stp;
- struct st_compute_program *stcp;
switch (shader->Stage) {
case MESA_SHADER_VERTEX:
stvp->glsl_to_tgsi = v;
break;
case MESA_SHADER_FRAGMENT:
- stfp = (struct st_fragment_program *)prog;
- stfp->glsl_to_tgsi = v;
- break;
case MESA_SHADER_TESS_CTRL:
case MESA_SHADER_TESS_EVAL:
case MESA_SHADER_GEOMETRY:
+ case MESA_SHADER_COMPUTE:
stp = st_common_program(prog);
stp->glsl_to_tgsi = v;
break;
- case MESA_SHADER_COMPUTE:
- stcp = (struct st_compute_program *)prog;
- stcp->glsl_to_tgsi = v;
- break;
default:
assert(!"should not be reached");
return NULL;
return GL_TRUE;
}
-
-extern "C" {
-
-void
-st_translate_stream_output_info(struct gl_transform_feedback_info *info,
- const ubyte outputMapping[],
- struct pipe_stream_output_info *so)
-{
- unsigned i;
-
- if (!info) {
- so->num_outputs = 0;
- return;
- }
-
- for (i = 0; i < info->NumOutputs; i++) {
- so->output[i].register_index =
- outputMapping[info->Outputs[i].OutputRegister];
- so->output[i].start_component = info->Outputs[i].ComponentOffset;
- so->output[i].num_components = info->Outputs[i].NumComponents;
- so->output[i].output_buffer = info->Outputs[i].OutputBuffer;
- so->output[i].dst_offset = info->Outputs[i].DstOffset;
- so->output[i].stream = info->Outputs[i].StreamId;
- }
-
- for (i = 0; i < PIPE_MAX_SO_BUFFERS; i++) {
- so->stride[i] = info->Buffers[i].Stride;
- }
- so->num_outputs = info->NumOutputs;
-}
-
-} /* extern "C" */