}
- /* The clipplanes are actually delivered to both CLIP and VS units.
- * VS uses them to calculate the outcode bitmasks.
+ /* When using the old VS backend, the clipplanes are actually delivered to
+ * both CLIP and VS units. VS uses them to calculate the outcode bitmasks.
+ *
+ * When using the new VS backend, it is responsible for setting up its own
+ * clipplane constants if it needs them. This results in a slight waste of
+ * of curbe space, but the advantage is that the new VS backend can use its
+ * general-purpose uniform layout code to store the clipplanes.
*/
if (brw->curbe.clip_size) {
GLuint offset = brw->curbe.clip_start * 16;
int first_non_payload_grf;
int *virtual_grf_def;
int *virtual_grf_use;
+ dst_reg userplane[MAX_CLIP_PLANES];
/**
* This is the size to be used for an array with an element per
void fail(const char *msg, ...);
int virtual_grf_alloc(int size);
+ void setup_uniform_clipplane_values();
int setup_uniform_values(int loc, const glsl_type *type);
void setup_builtin_uniform_values(ir_variable *ir);
int setup_attributes(int payload_reg);
int
vec4_visitor::setup_uniforms(int reg)
{
- /* User clip planes from curbe:
- */
- if (c->key.nr_userclip && !c->key.uses_clip_distance) {
- if (intel->gen >= 6) {
- for (int i = 0; i < c->key.nr_userclip; i++) {
- c->userplane[i] = stride(brw_vec4_grf(reg + i / 2,
- (i % 2) * 4), 0, 4, 1);
- }
- reg += ALIGN(c->key.nr_userclip, 2) / 2;
- } else {
- for (int i = 0; i < c->key.nr_userclip; i++) {
- c->userplane[i] = stride(brw_vec4_grf(reg + (6 + i) / 2,
- (i % 2) * 4), 0, 4, 1);
- }
- reg += (ALIGN(6 + c->key.nr_userclip, 4) / 4) * 2;
- }
- }
-
/* The pre-gen6 VS requires that some push constants get loaded no
* matter what, or the GPU would hang.
*/
bool
vec4_visitor::run()
{
+ if (c->key.nr_userclip && !c->key.uses_clip_distance)
+ setup_uniform_clipplane_values();
+
/* Generate VS IR for main(). (the visitor only descends into
* functions called "main").
*/
}
}
+void
+vec4_visitor::setup_uniform_clipplane_values()
+{
+ int compacted_clipplane_index = 0;
+ for (int i = 0; i < MAX_CLIP_PLANES; ++i) {
+ if (ctx->Transform.ClipPlanesEnabled & (1 << i)) {
+ this->uniform_vector_size[this->uniforms] = 4;
+ this->userplane[compacted_clipplane_index] = dst_reg(UNIFORM, this->uniforms);
+ this->userplane[compacted_clipplane_index].type = BRW_REGISTER_TYPE_F;
+ for (int j = 0; j < 4; ++j) {
+ c->prog_data.param[this->uniforms * 4 + j] = &ctx->Transform._ClipUserPlane[i][j];
+ }
+ ++compacted_clipplane_index;
+ ++this->uniforms;
+ }
+ }
+}
+
/* Our support for builtin uniforms is even scarier than non-builtin.
* It sits on top of the PROG_STATE_VAR parameters that are
* automatically updated from GL context state.
vec4_instruction *inst;
inst = emit(DP4(dst_null_f(), src_reg(output_reg[VERT_RESULT_HPOS]),
- src_reg(c->userplane[i])));
+ src_reg(this->userplane[i])));
inst->conditional_mod = BRW_CONDITIONAL_L;
emit(OR(header1, src_reg(header1), 1u << i));
for (int i = 0; i + offset < c->key.nr_userclip && i < 4; ++i) {
emit(DP4(dst_reg(brw_writemask(reg, 1 << i)),
src_reg(output_reg[VERT_RESULT_HPOS]),
- src_reg(c->userplane[i + offset])));
+ src_reg(this->userplane[i + offset])));
}
}
vs->thread3.dispatch_grf_start_reg = 1;
vs->thread3.urb_entry_read_offset = 0;
- /* BRW_NEW_CURBE_OFFSETS, _NEW_TRANSFORM */
- if (ctx->Transform.ClipPlanesEnabled) {
+ /* BRW_NEW_CURBE_OFFSETS, _NEW_TRANSFORM, BRW_NEW_VERTEX_PROGRAM */
+ if (ctx->Transform.ClipPlanesEnabled && !brw->vs.prog_data->uses_new_param_layout) {
/* Note that we read in the userclip planes as well, hence
* clip_start:
*/
BRW_NEW_PROGRAM_CACHE |
BRW_NEW_CURBE_OFFSETS |
BRW_NEW_NR_VS_SURFACES |
- BRW_NEW_URB_FENCE),
+ BRW_NEW_URB_FENCE |
+ BRW_NEW_VERTEX_PROGRAM),
.cache = CACHE_NEW_VS_PROG
},
.prepare = brw_prepare_vs_unit,
4 * sizeof(float),
32, &brw->vs.push_const_offset);
- /* This should be loaded like any other param, but it's ad-hoc
- * until we redo the VS backend.
- */
- if (!uses_clip_distance) {
- for (i = 0; i < MAX_CLIP_PLANES; i++) {
- if (ctx->Transform.ClipPlanesEnabled & (1 << i)) {
- memcpy(param, ctx->Transform._ClipUserPlane[i], 4 * sizeof(float));
- param += 4;
- params_uploaded++;
- }
- }
- }
- /* Align to a reg for convenience for brw_vs_emit.c */
- if (params_uploaded & 1) {
- param += 4;
- params_uploaded++;
- }
-
if (brw->vs.prog_data->uses_new_param_layout) {
for (i = 0; i < brw->vs.prog_data->nr_params; i++) {
*param = *brw->vs.prog_data->param[i];
}
params_uploaded += brw->vs.prog_data->nr_params / 4;
} else {
+ /* This should be loaded like any other param, but it's ad-hoc
+ * until we redo the VS backend.
+ */
+ if (!uses_clip_distance) {
+ for (i = 0; i < MAX_CLIP_PLANES; i++) {
+ if (ctx->Transform.ClipPlanesEnabled & (1 << i)) {
+ memcpy(param, ctx->Transform._ClipUserPlane[i], 4 * sizeof(float));
+ param += 4;
+ params_uploaded++;
+ }
+ }
+ }
+
+ /* Align to a reg for convenience for brw_vs_emit.c */
+ if (params_uploaded & 1) {
+ param += 4;
+ params_uploaded++;
+ }
+
for (i = 0; i < vp->program.Base.Parameters->NumParameters; i++) {
if (brw->vs.constant_map[i] != -1) {
memcpy(param + brw->vs.constant_map[i] * 4,