switch (var->data.interpolation) {
case INTERP_MODE_NONE:
+ /* If a gl_FrontColor or gl_BackColor input has no interp
+ * qualifier, then flag it for glShadeModel() handling by the
+ * driver.
+ */
+ switch (var->data.location) {
+ case VARYING_SLOT_COL0:
+ case VARYING_SLOT_COL1:
+ case VARYING_SLOT_BFC0:
+ case VARYING_SLOT_BFC1:
+ BITSET_SET(c->shade_model_flags, i);
+ break;
+ default:
+ break;
+ }
+ /* FALLTHROUGH */
case INTERP_MODE_SMOOTH:
if (var->data.centroid) {
return vir_FADD(c, vir_FMUL(c, vary,
* uniform setup
*/
- if (c->output_color_var) {
- nir_variable *var = c->output_color_var;
+ for (int rt = 0; rt < c->fs_key->nr_cbufs; rt++) {
+ if (!c->output_color_var[rt])
+ continue;
+
+ nir_variable *var = c->output_color_var[rt];
struct qreg *color = &c->outputs[var->data.driver_location * 4];
int num_components = glsl_get_vector_elements(var->type);
- uint32_t conf = ~0;
+ uint32_t conf = 0xffffff00;
struct qinst *inst;
+ conf |= TLB_SAMPLE_MODE_PER_PIXEL;
+ conf |= (7 - rt) << TLB_RENDER_TARGET_SHIFT;
+
assert(num_components != 0);
switch (glsl_get_base_type(var->type)) {
case GLSL_TYPE_UINT:
case GLSL_TYPE_INT:
- conf = (TLB_TYPE_I32_COLOR |
- TLB_SAMPLE_MODE_PER_PIXEL |
- ((7 - 0) << TLB_RENDER_TARGET_SHIFT) |
- ((num_components - 1) <<
- TLB_VEC_SIZE_MINUS_1_SHIFT) |
- 0xffffff00);
-
+ conf |= TLB_TYPE_I32_COLOR;
+ conf |= ((num_components - 1) <<
+ TLB_VEC_SIZE_MINUS_1_SHIFT);
inst = vir_MOV_dest(c, vir_reg(QFILE_TLBU, 0), color[0]);
vir_set_cond(inst, discard_cond);
struct qreg b = color[2];
struct qreg a = color[3];
- if (c->fs_key->swap_color_rb) {
+ if (c->fs_key->f32_color_rb) {
+ conf |= TLB_TYPE_F32_COLOR;
+ conf |= ((num_components - 1) <<
+ TLB_VEC_SIZE_MINUS_1_SHIFT);
+ } else {
+ conf |= TLB_TYPE_F16_COLOR;
+ conf |= TLB_F16_SWAP_HI_LO;
+ if (num_components >= 3)
+ conf |= TLB_VEC_SIZE_4_F16;
+ else
+ conf |= TLB_VEC_SIZE_2_F16;
+ }
+
+ if (c->fs_key->swap_color_rb & (1 << rt)) {
r = color[2];
b = color[0];
}
- inst = vir_VFPACK_dest(c, vir_reg(QFILE_TLB, 0), r, g);
- vir_set_cond(inst, discard_cond);
- inst = vir_VFPACK_dest(c, vir_reg(QFILE_TLB, 0), b, a);
- vir_set_cond(inst, discard_cond);
+ if (c->fs_key->f32_color_rb & (1 << rt)) {
+ inst = vir_MOV_dest(c, vir_reg(QFILE_TLBU, 0), color[0]);
+ vir_set_cond(inst, discard_cond);
+ inst->src[vir_get_implicit_uniform_src(inst)] =
+ vir_uniform_ui(c, conf);
+
+ for (int i = 1; i < num_components; i++) {
+ inst = vir_MOV_dest(c, vir_reg(QFILE_TLB, 0),
+ color[i]);
+ vir_set_cond(inst, discard_cond);
+ }
+ } else {
+ inst = vir_VFPACK_dest(c, vir_reg(QFILE_TLB, 0), r, g);
+ if (conf != ~0) {
+ inst->dst.file = QFILE_TLBU;
+ inst->src[vir_get_implicit_uniform_src(inst)] =
+ vir_uniform_ui(c, conf);
+ }
+ vir_set_cond(inst, discard_cond);
+
+ inst = vir_VFPACK_dest(c, vir_reg(QFILE_TLB, 0), b, a);
+ vir_set_cond(inst, discard_cond);
+ }
break;
}
}
if (c->s->stage == MESA_SHADER_FRAGMENT) {
switch (var->data.location) {
case FRAG_RESULT_COLOR:
+ c->output_color_var[0] = var;
+ c->output_color_var[1] = var;
+ c->output_color_var[2] = var;
+ c->output_color_var[3] = var;
+ break;
case FRAG_RESULT_DATA0:
- c->output_color_var = var;
+ case FRAG_RESULT_DATA1:
+ case FRAG_RESULT_DATA2:
+ case FRAG_RESULT_DATA3:
+ c->output_color_var[var->data.location -
+ FRAG_RESULT_DATA0] = var;
break;
case FRAG_RESULT_DEPTH:
c->output_position_index = loc;