GLboolean
brw_link_shader(GLcontext *ctx, struct gl_shader_program *prog)
{
+ struct intel_context *intel = intel_context(ctx);
if (using_new_fs == -1)
using_new_fs = getenv("INTEL_NEW_FS") != NULL;
do_sub_to_add_neg(shader->ir);
do_explog_to_explog2(shader->ir);
do_lower_texture_projection(shader->ir);
+ brw_do_cubemap_normalize(shader->ir);
do {
progress = false;
GL_TRUE, /* temp */
GL_TRUE /* uniform */
) || progress;
+ if (intel->gen == 6) {
+ progress = do_if_to_cond_assign(shader->ir) || progress;
+ }
} while (progress);
validate_ir_tree(shader->ir);
this->sampler = 0;
this->target = 0;
this->eot = false;
+ this->header_present = false;
this->shadow_compare = false;
}
int sampler;
int target; /**< MRT target. */
bool eot;
+ bool header_present;
bool shadow_compare;
/** @{
this->virtual_grf_array_size = 0;
this->virtual_grf_def = NULL;
this->virtual_grf_use = NULL;
+
+ this->kill_emitted = false;
}
+
~fs_visitor()
{
talloc_free(this->mem_ctx);
void generate_ddy(fs_inst *inst, struct brw_reg dst, struct brw_reg src);
void emit_dummy_fs();
- void emit_fragcoord_interpolation(ir_variable *ir);
- void emit_general_interpolation(ir_variable *ir);
+ fs_reg *emit_fragcoord_interpolation(ir_variable *ir);
+ fs_reg *emit_frontfacing_interpolation(ir_variable *ir);
+ fs_reg *emit_general_interpolation(ir_variable *ir);
void emit_interpolation_setup_gen4();
void emit_interpolation_setup_gen6();
fs_inst *emit_texture_gen4(ir_texture *ir, fs_reg dst, fs_reg coordinate);
ir_variable *frag_color, *frag_data, *frag_depth;
int first_non_payload_grf;
int urb_setup[FRAG_ATTRIB_MAX];
+ bool kill_emitted;
/** @{ debug annotation info */
const char *current_annotation;
}
}
-void
+fs_reg *
fs_visitor::emit_fragcoord_interpolation(ir_variable *ir)
{
fs_reg *reg = new(this->mem_ctx) fs_reg(this, ir->type);
/* gl_FragCoord.w: Already set up in emit_interpolation */
emit(fs_inst(BRW_OPCODE_MOV, wpos, this->wpos_w));
- hash_table_insert(this->variable_ht, reg, ir);
+ return reg;
}
-
-void
+fs_reg *
fs_visitor::emit_general_interpolation(ir_variable *ir)
{
fs_reg *reg = new(this->mem_ctx) fs_reg(this, ir->type);
fs_reg(interp)));
attr.reg_offset++;
}
- attr.reg_offset -= type->vector_elements;
- for (unsigned int c = 0; c < type->vector_elements; c++) {
- emit(fs_inst(BRW_OPCODE_MUL,
- attr,
- attr,
- this->pixel_w));
- attr.reg_offset++;
+ if (intel->gen < 6) {
+ attr.reg_offset -= type->vector_elements;
+ for (unsigned int c = 0; c < type->vector_elements; c++) {
+ emit(fs_inst(BRW_OPCODE_MUL,
+ attr,
+ attr,
+ this->pixel_w));
+ attr.reg_offset++;
+ }
}
location++;
}
}
- hash_table_insert(this->variable_ht, reg, ir);
+ return reg;
+}
+
+fs_reg *
+fs_visitor::emit_frontfacing_interpolation(ir_variable *ir)
+{
+ fs_reg *reg = new(this->mem_ctx) fs_reg(this, ir->type);
+
+ /* The frontfacing comes in as a bit in the thread payload. */
+ if (intel->gen >= 6) {
+ emit(fs_inst(BRW_OPCODE_ASR,
+ *reg,
+ fs_reg(retype(brw_vec1_grf(0, 0), BRW_REGISTER_TYPE_D)),
+ fs_reg(15)));
+ emit(fs_inst(BRW_OPCODE_NOT,
+ *reg,
+ *reg));
+ emit(fs_inst(BRW_OPCODE_AND,
+ *reg,
+ *reg,
+ fs_reg(1)));
+ } else {
+ fs_reg *reg = new(this->mem_ctx) fs_reg(this, ir->type);
+ struct brw_reg r1_6ud = retype(brw_vec1_grf(1, 6), BRW_REGISTER_TYPE_UD);
+ /* bit 31 is "primitive is back face", so checking < (1 << 31) gives
+ * us front face
+ */
+ fs_inst *inst = emit(fs_inst(BRW_OPCODE_CMP,
+ *reg,
+ fs_reg(r1_6ud),
+ fs_reg(1u << 31)));
+ inst->conditional_mod = BRW_CONDITIONAL_L;
+ emit(fs_inst(BRW_OPCODE_AND, *reg, *reg, fs_reg(1u)));
+ }
+
+ return reg;
}
void
if (ir->mode == ir_var_in) {
if (!strcmp(ir->name, "gl_FragCoord")) {
- emit_fragcoord_interpolation(ir);
- return;
+ reg = emit_fragcoord_interpolation(ir);
} else if (!strcmp(ir->name, "gl_FrontFacing")) {
- reg = new(this->mem_ctx) fs_reg(this, ir->type);
- struct brw_reg r1_6ud = retype(brw_vec1_grf(1, 6), BRW_REGISTER_TYPE_UD);
- /* bit 31 is "primitive is back face", so checking < (1 << 31) gives
- * us front face
- */
- fs_inst *inst = emit(fs_inst(BRW_OPCODE_CMP,
- *reg,
- fs_reg(r1_6ud),
- fs_reg(1u << 31)));
- inst->conditional_mod = BRW_CONDITIONAL_L;
- emit(fs_inst(BRW_OPCODE_AND, *reg, *reg, fs_reg(1u)));
+ reg = emit_frontfacing_interpolation(ir);
} else {
- emit_general_interpolation(ir);
- return;
+ reg = emit_general_interpolation(ir);
}
+ assert(reg);
+ hash_table_insert(this->variable_ht, reg, ir);
+ return;
}
if (ir->mode == ir_var_uniform) {
assert(ir->condition == NULL); /* FINISHME */
emit(fs_inst(FS_OPCODE_DISCARD, temp, temp));
+ kill_emitted = true;
}
void
fs_visitor::emit_fb_writes()
{
this->current_annotation = "FB write header";
+ GLboolean header_present = GL_TRUE;
int nr = 0;
- /* m0, m1 header */
- nr += 2;
+ if (intel->gen >= 6 &&
+ !this->kill_emitted &&
+ c->key.nr_color_regions == 1) {
+ header_present = false;
+ }
+
+ if (header_present) {
+ /* m0, m1 header */
+ nr += 2;
+ }
if (c->key.aa_dest_stencil_reg) {
emit(fs_inst(BRW_OPCODE_MOV, fs_reg(MRF, nr++),
inst->mlen = nr;
if (target == c->key.nr_color_regions - 1)
inst->eot = true;
+ inst->header_present = header_present;
}
if (c->key.nr_color_regions == 0) {
reg_undef, reg_undef));
inst->mlen = nr;
inst->eot = true;
+ inst->header_present = header_present;
}
this->current_annotation = NULL;
brw_set_mask_control(p, BRW_MASK_DISABLE);
brw_set_compression_control(p, BRW_COMPRESSION_NONE);
- if (intel->gen >= 6) {
+ if (inst->header_present) {
+ if (intel->gen >= 6) {
+ brw_MOV(p,
+ brw_message_reg(0),
+ brw_vec8_grf(0, 0));
+ implied_header = brw_null_reg();
+ } else {
+ implied_header = retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW);
+ }
+
brw_MOV(p,
- brw_message_reg(0),
- brw_vec8_grf(0, 0));
- implied_header = brw_null_reg();
+ brw_message_reg(1),
+ brw_vec8_grf(1, 0));
} else {
- implied_header = retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW);
+ implied_header = brw_null_reg();
}
- brw_MOV(p,
- brw_message_reg(1),
- brw_vec8_grf(1, 0));
-
brw_pop_insn_state(p);
brw_fb_WRITE(p,
int rlen = 4;
uint32_t simd_mode = BRW_SAMPLER_SIMD_MODE_SIMD8;
- if (intel->gen == 5) {
+ if (intel->gen >= 5) {
switch (inst->opcode) {
case FS_OPCODE_TEX:
if (inst->shadow_compare) {
/* Figure out where each of the incoming setup attributes lands. */
if (intel->gen >= 6) {
for (unsigned int i = 0; i < FRAG_ATTRIB_MAX; i++) {
- if (i == FRAG_ATTRIB_WPOS ||
- (brw->fragment_program->Base.InputsRead & BITFIELD64_BIT(i))) {
+ if (brw->fragment_program->Base.InputsRead & BITFIELD64_BIT(i)) {
urb_setup[i] = urb_next++;
}
}
{
bool progress = false;
- return false;
-
foreach_iter(exec_list_iterator, iter, this->instructions) {
fs_inst *inst = (fs_inst *)iter.get();
scan_inst->src[1] = inst->src[0];
}
break;
+ case BRW_OPCODE_CMP:
+ if (i == 1) {
+ scan_inst->src[i] = inst->src[0];
+ progress = true;
+ }
}
}
case BRW_OPCODE_XOR:
brw_XOR(p, dst, src[0], src[1]);
break;
+ case BRW_OPCODE_NOT:
+ brw_NOT(p, dst, src[0]);
+ break;
+ case BRW_OPCODE_ASR:
+ brw_ASR(p, dst, src[0], src[1]);
+ break;
+ case BRW_OPCODE_SHR:
+ brw_SHR(p, dst, src[0], src[1]);
+ break;
+ case BRW_OPCODE_SHL:
+ brw_SHL(p, dst, src[0], src[1]);
+ break;
case BRW_OPCODE_CMP:
brw_CMP(p, dst, inst->conditional_mod, src[0], src[1]);