case GL_UNSIGNED_INT: return uint_types_scale[size];
case GL_UNSIGNED_SHORT: return ushort_types_scale[size];
case GL_UNSIGNED_BYTE: return ubyte_types_scale[size];
+ /* This produces GL_FIXED inputs as values between INT32_MIN and
+ * INT32_MAX, which will be scaled down by 1/65536 by the VS.
+ */
+ case GL_FIXED: return int_types_scale[size];
default: assert(0); return 0;
}
}
case GL_UNSIGNED_INT: return sizeof(GLuint);
case GL_UNSIGNED_SHORT: return sizeof(GLushort);
case GL_UNSIGNED_BYTE: return sizeof(GLubyte);
+ case GL_FIXED: return sizeof(GLuint);
default: assert(0); return 0;
}
}
}
}
+ /* BRW_NEW_VERTICES */
+ for (i = 0; i < VERT_ATTRIB_MAX; i++) {
+ if (vp->program.Base.InputsRead & (1 << i) &&
+ brw->vb.inputs[i].glarray->Type == GL_FIXED) {
+ key.gl_fixed_input_size[i] = brw->vb.inputs[i].glarray->Size;
+ }
+ }
+
/* Make an early check for the key.
*/
drm_intel_bo_unreference(brw->vs.prog_bo);
.dirty = {
.mesa = (_NEW_TRANSFORM | _NEW_POLYGON | _NEW_POINT | _NEW_LIGHT |
_NEW_BUFFERS),
- .brw = BRW_NEW_VERTEX_PROGRAM,
+ .brw = (BRW_NEW_VERTEX_PROGRAM |
+ BRW_NEW_VERTICES),
.cache = 0
},
.prepare = brw_upload_vs_prog
struct brw_vs_prog_key {
GLuint program_string_id;
+ /**
+ * Number of channels of the vertex attribute that need GL_FIXED rescaling
+ */
+ uint8_t gl_fixed_input_size[VERT_ATTRIB_MAX];
GLuint nr_userclip:4;
GLuint copy_edgeflag:1;
GLuint point_coord_replace:8;
}
}
+static void
+brw_vs_rescale_gl_fixed(struct brw_vs_compile *c)
+{
+ struct brw_compile *p = &c->func;
+ int i;
+
+ for (i = 0; i < VERT_ATTRIB_MAX; i++) {
+ if (!(c->prog_data.inputs_read & (1 << i)))
+ continue;
+
+ if (c->key.gl_fixed_input_size[i] != 0) {
+ struct brw_reg reg = c->regs[PROGRAM_INPUT][i];
+
+ brw_MUL(p,
+ brw_writemask(reg, (1 << c->key.gl_fixed_input_size[i]) - 1),
+ reg, brw_imm_f(1.0 / 65536.0));
+ }
+ }
+}
+
/* Emit the vertex program instructions here.
*/
void brw_vs_emit(struct brw_vs_compile *c )
*/
brw_vs_alloc_regs(c);
+ brw_vs_rescale_gl_fixed(c);
+
if (c->needs_stack)
brw_MOV(p, get_addr_reg(stack_index), brw_address(c->stack));