}
bool
-vec4_visitor::run(gl_clip_plane *clip_planes)
+vec4_visitor::run()
{
bool use_vec4_nir =
compiler->glsl_compiler_options[stage].NirOptions != NULL;
}
base_ir = NULL;
- if (key->nr_userclip_plane_consts > 0)
- setup_uniform_clipplane_values(clip_planes);
-
emit_thread_end();
calculate_cfg();
prog_data->base.dispatch_mode = DISPATCH_MODE_4X2_DUAL_OBJECT;
vec4_vs_visitor v(brw->intelScreen->compiler, brw, key, prog_data,
- vp, prog, mem_ctx, st_index,
+ vp, prog, brw_select_clip_planes(&brw->ctx),
+ mem_ctx, st_index,
!_mesa_is_gles3(&brw->ctx));
- if (!v.run(brw_select_clip_planes(&brw->ctx))) {
+ if (!v.run()) {
if (prog) {
prog->LinkStatus = false;
ralloc_strcat(&prog->InfoLog, v.fail_msg);
struct hash_table *variable_ht;
- bool run(gl_clip_plane *clip_planes);
+ bool run();
void fail(const char *msg, ...);
- void setup_uniform_clipplane_values(gl_clip_plane *clip_planes);
virtual void setup_vec4_uniform_value(unsigned param_offset,
const gl_constant_value *values,
unsigned n);
void emit_ndc_computation();
void emit_psiz_and_flags(dst_reg reg);
- void emit_clip_distances(dst_reg reg, int offset);
vec4_instruction *emit_generic_urb_slot(dst_reg reg, int varying);
void emit_urb_slot(dst_reg reg, int varying);
vec4_gs_visitor v(brw->intelScreen->compiler, brw,
c, prog, mem_ctx, true /* no_spills */, st_index);
- if (v.run(NULL /* clip planes */)) {
+ if (v.run()) {
return generate_assembly(brw, prog, &c->gp->program.Base,
&c->prog_data.base, mem_ctx, v.cfg,
final_assembly_size);
c, prog, mem_ctx, false /* no_spills */,
st_index);
- if (!gs->run(NULL /* clip planes */)) {
+ if (!gs->run()) {
prog->LinkStatus = false;
ralloc_strcat(&prog->InfoLog, gs->fail_msg);
} else {
}
}
-void
-vec4_visitor::setup_uniform_clipplane_values(gl_clip_plane *clip_planes)
-{
- for (int i = 0; i < key->nr_userclip_plane_consts; ++i) {
- assert(this->uniforms < uniform_array_size);
- this->uniform_vector_size[this->uniforms] = 4;
- this->userplane[i] = dst_reg(UNIFORM, this->uniforms);
- this->userplane[i].type = BRW_REGISTER_TYPE_F;
- for (int j = 0; j < 4; ++j) {
- stage_prog_data->param[this->uniforms * 4 + j] =
- (gl_constant_value *) &clip_planes[i][j];
- }
- ++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.
}
}
-void
-vec4_visitor::emit_clip_distances(dst_reg reg, int offset)
-{
- /* From the GLSL 1.30 spec, section 7.1 (Vertex Shader Special Variables):
- *
- * "If a linked set of shaders forming the vertex stage contains no
- * static write to gl_ClipVertex or gl_ClipDistance, but the
- * application has requested clipping against user clip planes through
- * the API, then the coordinate written to gl_Position is used for
- * comparison against the user clip planes."
- *
- * This function is only called if the shader didn't write to
- * gl_ClipDistance. Accordingly, we use gl_ClipVertex to perform clipping
- * if the user wrote to it; otherwise we use gl_Position.
- */
- gl_varying_slot clip_vertex = VARYING_SLOT_CLIP_VERTEX;
- if (!(prog_data->vue_map.slots_valid & VARYING_BIT_CLIP_VERTEX)) {
- clip_vertex = VARYING_SLOT_POS;
- }
-
- for (int i = 0; i + offset < key->nr_userclip_plane_consts && i < 4;
- ++i) {
- reg.writemask = 1 << i;
- emit(DP4(reg,
- src_reg(output_reg[clip_vertex]),
- src_reg(this->userplane[i + offset])));
- }
-}
-
vec4_instruction *
vec4_visitor::emit_generic_urb_slot(dst_reg reg, int varying)
{
emit_ndc_computation();
}
- /* Lower legacy ff and ClipVertex clipping to clip distances */
- if (key->nr_userclip_plane_consts > 0) {
- current_annotation = "user clip distances";
-
- output_reg[VARYING_SLOT_CLIP_DIST0] = dst_reg(this, glsl_type::vec4_type);
- output_reg[VARYING_SLOT_CLIP_DIST1] = dst_reg(this, glsl_type::vec4_type);
-
- emit_clip_distances(output_reg[VARYING_SLOT_CLIP_DIST0], 0);
- emit_clip_distances(output_reg[VARYING_SLOT_CLIP_DIST1], 4);
- }
-
/* We may need to split this up into several URB writes, so do them in a
* loop.
*/
}
+void
+vec4_vs_visitor::emit_clip_distances(dst_reg reg, int offset)
+{
+ /* From the GLSL 1.30 spec, section 7.1 (Vertex Shader Special Variables):
+ *
+ * "If a linked set of shaders forming the vertex stage contains no
+ * static write to gl_ClipVertex or gl_ClipDistance, but the
+ * application has requested clipping against user clip planes through
+ * the API, then the coordinate written to gl_Position is used for
+ * comparison against the user clip planes."
+ *
+ * This function is only called if the shader didn't write to
+ * gl_ClipDistance. Accordingly, we use gl_ClipVertex to perform clipping
+ * if the user wrote to it; otherwise we use gl_Position.
+ */
+ gl_varying_slot clip_vertex = VARYING_SLOT_CLIP_VERTEX;
+ if (!(prog_data->vue_map.slots_valid & VARYING_BIT_CLIP_VERTEX)) {
+ clip_vertex = VARYING_SLOT_POS;
+ }
+
+ for (int i = 0; i + offset < key->base.nr_userclip_plane_consts && i < 4;
+ ++i) {
+ reg.writemask = 1 << i;
+ emit(DP4(reg,
+ src_reg(output_reg[clip_vertex]),
+ src_reg(this->userplane[i + offset])));
+ }
+}
+
+
+void
+vec4_vs_visitor::setup_uniform_clipplane_values()
+{
+ for (int i = 0; i < key->base.nr_userclip_plane_consts; ++i) {
+ assert(this->uniforms < uniform_array_size);
+ this->uniform_vector_size[this->uniforms] = 4;
+ this->userplane[i] = dst_reg(UNIFORM, this->uniforms);
+ this->userplane[i].type = BRW_REGISTER_TYPE_F;
+ for (int j = 0; j < 4; ++j) {
+ stage_prog_data->param[this->uniforms * 4 + j] =
+ (gl_constant_value *) &clip_planes[i][j];
+ }
+ ++this->uniforms;
+ }
+}
+
+
void
vec4_vs_visitor::emit_thread_end()
{
+ setup_uniform_clipplane_values();
+
+ /* Lower legacy ff and ClipVertex clipping to clip distances */
+ if (key->base.nr_userclip_plane_consts > 0) {
+ current_annotation = "user clip distances";
+
+ output_reg[VARYING_SLOT_CLIP_DIST0] = dst_reg(this, glsl_type::vec4_type);
+ output_reg[VARYING_SLOT_CLIP_DIST1] = dst_reg(this, glsl_type::vec4_type);
+
+ emit_clip_distances(output_reg[VARYING_SLOT_CLIP_DIST0], 0);
+ emit_clip_distances(output_reg[VARYING_SLOT_CLIP_DIST1], 4);
+ }
+
/* For VS, we always end the thread by emitting a single vertex.
* emit_urb_write_opcode() will take care of setting the eot flag on the
* SEND instruction.
struct brw_vs_prog_data *vs_prog_data,
struct gl_vertex_program *vp,
struct gl_shader_program *prog,
+ gl_clip_plane *clip_planes,
void *mem_ctx,
int shader_time_index,
bool use_legacy_snorm_formula)
key(key),
vs_prog_data(vs_prog_data),
vp(vp),
+ clip_planes(clip_planes),
use_legacy_snorm_formula(use_legacy_snorm_formula)
{
}
struct brw_vs_prog_data *vs_prog_data,
struct gl_vertex_program *vp,
struct gl_shader_program *prog,
+ gl_clip_plane *clip_planes,
void *mem_ctx,
int shader_time_index,
bool use_legacy_snorm_formula);
private:
int setup_attributes(int payload_reg);
void setup_vp_regs();
+ void setup_uniform_clipplane_values();
+ void emit_clip_distances(dst_reg reg, int offset);
dst_reg get_vp_dst_reg(const prog_dst_register &dst);
src_reg get_vp_src_reg(const prog_src_register &src);
src_reg *vp_temp_regs;
src_reg vp_addr_reg;
+ gl_clip_plane *clip_planes;
+
bool use_legacy_snorm_formula;
};