From 15469b0a6339b821aaed49bd0d73822063e79696 Mon Sep 17 00:00:00 2001 From: Caio Oliveira Date: Thu, 15 Feb 2024 00:03:56 -0800 Subject: [PATCH] intel/brw: Remove unused legacy shader stages CLIP, STRIP-FAN and FF Geometry don't apply to Gfx9+. Reviewed-by: Kenneth Graunke Part-of: --- src/intel/compiler/brw_clip.h | 163 ----- src/intel/compiler/brw_clip_line.c | 303 --------- src/intel/compiler/brw_clip_point.c | 45 -- src/intel/compiler/brw_clip_tri.c | 659 ------------------ src/intel/compiler/brw_clip_unfilled.c | 528 --------------- src/intel/compiler/brw_clip_util.c | 464 ------------- src/intel/compiler/brw_compile_clip.c | 97 --- src/intel/compiler/brw_compile_ff_gs.c | 662 ------------------- src/intel/compiler/brw_compile_sf.c | 881 ------------------------- src/intel/compiler/brw_compiler.h | 182 ----- src/intel/compiler/brw_vue_map.c | 1 - src/intel/compiler/meson.build | 9 - 12 files changed, 3994 deletions(-) delete mode 100644 src/intel/compiler/brw_clip.h delete mode 100644 src/intel/compiler/brw_clip_line.c delete mode 100644 src/intel/compiler/brw_clip_point.c delete mode 100644 src/intel/compiler/brw_clip_tri.c delete mode 100644 src/intel/compiler/brw_clip_unfilled.c delete mode 100644 src/intel/compiler/brw_clip_util.c delete mode 100644 src/intel/compiler/brw_compile_clip.c delete mode 100644 src/intel/compiler/brw_compile_ff_gs.c delete mode 100644 src/intel/compiler/brw_compile_sf.c diff --git a/src/intel/compiler/brw_clip.h b/src/intel/compiler/brw_clip.h deleted file mode 100644 index 4ca89455963..00000000000 --- a/src/intel/compiler/brw_clip.h +++ /dev/null @@ -1,163 +0,0 @@ -/* - Copyright (C) Intel Corp. 2006. All Rights Reserved. - Intel funded Tungsten Graphics to - develop this 3D driver. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice (including the - next paragraph) shall be included in all copies or substantial - portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - **********************************************************************/ - /* - * Authors: - * Keith Whitwell - */ - -#ifndef BRW_CLIP_H -#define BRW_CLIP_H - -#include "brw_compiler.h" -#include "brw_eu.h" - -/* Initial 3 verts, plus at most 6 additional verts from intersections - * with fixed planes, plus at most 8 additional verts from intersections - * with user clip planes - */ -#define MAX_VERTS (3+6+8) - -#define PRIM_MASK (0x1f) - -struct brw_clip_compile { - struct brw_codegen func; - struct brw_clip_prog_key key; - struct brw_clip_prog_data prog_data; - - struct { - struct brw_reg R0; - struct brw_reg vertex[MAX_VERTS]; - - struct brw_reg t; - struct brw_reg t0, t1; - struct brw_reg dp0, dp1; - - struct brw_reg dpPrev; - struct brw_reg dp; - struct brw_reg loopcount; - struct brw_reg nr_verts; - struct brw_reg planemask; - - struct brw_reg inlist; - struct brw_reg outlist; - struct brw_reg freelist; - - struct brw_reg dir; - struct brw_reg tmp0, tmp1; - struct brw_reg offset; - - struct brw_reg fixed_planes; - struct brw_reg plane_equation; - - struct brw_reg ff_sync; - - /* Bitmask indicating which coordinate attribute should be used for - * comparison to each clipping plane. A 0 indicates that VARYING_SLOT_POS - * should be used, because it's one of the fixed +/- x/y/z planes that - * constitute the bounds of the view volume. A 1 indicates that - * VARYING_SLOT_CLIP_VERTEX should be used (if available) since it's a user- - * defined clipping plane. - */ - struct brw_reg vertex_src_mask; - - /* Offset into the vertex of the current plane's clipdistance value */ - struct brw_reg clipdistance_offset; - } reg; - - /* Number of registers storing VUE data */ - GLuint nr_regs; - - GLuint first_tmp; - GLuint last_tmp; - - bool need_direction; - - struct intel_vue_map vue_map; -}; - -/** - * True if the given varying is one of the outputs of the vertex shader. - */ -static inline bool brw_clip_have_varying(struct brw_clip_compile *c, - GLuint varying) -{ - return (c->key.attrs & BITFIELD64_BIT(varying)) ? 1 : 0; -} - -/* Points are only culled, so no need for a clip routine, however it - * works out easier to have a dummy one. - */ -void brw_emit_unfilled_clip( struct brw_clip_compile *c ); -void brw_emit_tri_clip( struct brw_clip_compile *c ); -void brw_emit_line_clip( struct brw_clip_compile *c ); -void brw_emit_point_clip( struct brw_clip_compile *c ); - -/* brw_clip_tri.c, for use by the unfilled clip routine: - */ -void brw_clip_tri_init_vertices( struct brw_clip_compile *c ); -void brw_clip_tri_flat_shade( struct brw_clip_compile *c ); -void brw_clip_tri( struct brw_clip_compile *c ); -void brw_clip_tri_emit_polygon( struct brw_clip_compile *c ); -void brw_clip_tri_alloc_regs( struct brw_clip_compile *c, - GLuint nr_verts ); - - -/* Utils: - */ - -void brw_clip_interp_vertex( struct brw_clip_compile *c, - struct brw_indirect dest_ptr, - struct brw_indirect v0_ptr, /* from */ - struct brw_indirect v1_ptr, /* to */ - struct brw_reg t0, - bool force_edgeflag ); - -void brw_clip_init_planes( struct brw_clip_compile *c ); - -void brw_clip_emit_vue(struct brw_clip_compile *c, - struct brw_indirect vert, - enum brw_urb_write_flags flags, - GLuint header); - -void brw_clip_kill_thread(struct brw_clip_compile *c); - -struct brw_reg brw_clip_plane_stride( struct brw_clip_compile *c ); -struct brw_reg brw_clip_plane0_address( struct brw_clip_compile *c ); - -void brw_clip_copy_flatshaded_attributes( struct brw_clip_compile *c, - GLuint to, GLuint from ); - -void brw_clip_init_clipmask( struct brw_clip_compile *c ); - -struct brw_reg get_tmp( struct brw_clip_compile *c ); - -void brw_clip_project_position(struct brw_clip_compile *c, - struct brw_reg pos ); -void brw_clip_ff_sync(struct brw_clip_compile *c); -void brw_clip_init_ff_sync(struct brw_clip_compile *c); - -#endif diff --git a/src/intel/compiler/brw_clip_line.c b/src/intel/compiler/brw_clip_line.c deleted file mode 100644 index b71173277d9..00000000000 --- a/src/intel/compiler/brw_clip_line.c +++ /dev/null @@ -1,303 +0,0 @@ -/* - Copyright (C) Intel Corp. 2006. All Rights Reserved. - Intel funded Tungsten Graphics to - develop this 3D driver. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice (including the - next paragraph) shall be included in all copies or substantial - portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - **********************************************************************/ - /* - * Authors: - * Keith Whitwell - */ - -#include "brw_clip.h" -#include "brw_prim.h" - -static void brw_clip_line_alloc_regs( struct brw_clip_compile *c ) -{ - const struct intel_device_info *devinfo = c->func.devinfo; - GLuint i = 0,j; - - /* Register usage is static, precompute here: - */ - c->reg.R0 = retype(brw_vec8_grf(i, 0), BRW_REGISTER_TYPE_UD); i++; - - if (c->key.nr_userclip) { - c->reg.fixed_planes = brw_vec4_grf(i, 0); - i += (6 + c->key.nr_userclip + 1) / 2; - - c->prog_data.curb_read_length = (6 + c->key.nr_userclip + 1) / 2; - } - else - c->prog_data.curb_read_length = 0; - - - /* Payload vertices plus space for more generated vertices: - */ - for (j = 0; j < 4; j++) { - c->reg.vertex[j] = brw_vec4_grf(i, 0); - i += c->nr_regs; - } - - c->reg.t = brw_vec1_grf(i, 0); - c->reg.t0 = brw_vec1_grf(i, 1); - c->reg.t1 = brw_vec1_grf(i, 2); - c->reg.planemask = retype(brw_vec1_grf(i, 3), BRW_REGISTER_TYPE_UD); - c->reg.plane_equation = brw_vec4_grf(i, 4); - i++; - - c->reg.dp0 = brw_vec1_grf(i, 0); /* fixme - dp4 will clobber r.1,2,3 */ - c->reg.dp1 = brw_vec1_grf(i, 4); - i++; - - if (!c->key.nr_userclip) { - c->reg.fixed_planes = brw_vec8_grf(i, 0); - i++; - } - - c->reg.vertex_src_mask = retype(brw_vec1_grf(i, 0), BRW_REGISTER_TYPE_UD); - c->reg.clipdistance_offset = retype(brw_vec1_grf(i, 1), BRW_REGISTER_TYPE_W); - i++; - - if (devinfo->ver == 5) { - c->reg.ff_sync = retype(brw_vec1_grf(i, 0), BRW_REGISTER_TYPE_UD); - i++; - } - - c->first_tmp = i; - c->last_tmp = i; - - c->prog_data.urb_read_length = c->nr_regs; /* ? */ - c->prog_data.total_grf = i; -} - - -/* Line clipping, more or less following the following algorithm: - * - * for (p=0;p t1) t1 = t; - * } else { - * GLfloat t = dp0 / (dp0 - dp1); - * if (t > t0) t0 = t; - * } - * - * if (t0 + t1 >= 1.0) - * return; - * } - * } - * - * interp( ctx, newvtx0, vtx0, vtx1, t0 ); - * interp( ctx, newvtx1, vtx1, vtx0, t1 ); - * - */ -static void clip_and_emit_line( struct brw_clip_compile *c ) -{ - struct brw_codegen *p = &c->func; - struct brw_indirect vtx0 = brw_indirect(0, 0); - struct brw_indirect vtx1 = brw_indirect(1, 0); - struct brw_indirect newvtx0 = brw_indirect(2, 0); - struct brw_indirect newvtx1 = brw_indirect(3, 0); - struct brw_indirect plane_ptr = brw_indirect(4, 0); - struct brw_reg v1_null_ud = retype(vec1(brw_null_reg()), BRW_REGISTER_TYPE_UD); - GLuint hpos_offset = brw_varying_to_offset(&c->vue_map, VARYING_SLOT_POS); - GLint clipdist0_offset = c->key.nr_userclip - ? brw_varying_to_offset(&c->vue_map, VARYING_SLOT_CLIP_DIST0) - : 0; - - brw_MOV(p, get_addr_reg(vtx0), brw_address(c->reg.vertex[0])); - brw_MOV(p, get_addr_reg(vtx1), brw_address(c->reg.vertex[1])); - brw_MOV(p, get_addr_reg(newvtx0), brw_address(c->reg.vertex[2])); - brw_MOV(p, get_addr_reg(newvtx1), brw_address(c->reg.vertex[3])); - brw_MOV(p, get_addr_reg(plane_ptr), brw_clip_plane0_address(c)); - - /* Note: init t0, t1 together: - */ - brw_MOV(p, vec2(c->reg.t0), brw_imm_f(0)); - - brw_clip_init_planes(c); - brw_clip_init_clipmask(c); - - /* -ve rhw workaround */ - if (p->devinfo->has_negative_rhw_bug) { - brw_AND(p, brw_null_reg(), get_element_ud(c->reg.R0, 2), - brw_imm_ud(1<<20)); - brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ); - brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(0x3f)); - brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL); - } - - /* Set the initial vertex source mask: The first 6 planes are the bounds - * of the view volume; the next 8 planes are the user clipping planes. - */ - brw_MOV(p, c->reg.vertex_src_mask, brw_imm_ud(0x3fc0)); - - /* Set the initial clipdistance offset to be 6 floats before gl_ClipDistance[0]. - * We'll increment 6 times before we start hitting actual user clipping. */ - brw_MOV(p, c->reg.clipdistance_offset, brw_imm_d(clipdist0_offset - 6*sizeof(float))); - - brw_DO(p, BRW_EXECUTE_1); - { - /* if (planemask & 1) - */ - brw_AND(p, v1_null_ud, c->reg.planemask, brw_imm_ud(1)); - brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ); - - brw_IF(p, BRW_EXECUTE_1); - { - brw_AND(p, v1_null_ud, c->reg.vertex_src_mask, brw_imm_ud(1)); - brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ); - brw_IF(p, BRW_EXECUTE_1); - { - /* user clip distance: just fetch the correct float from each vertex */ - struct brw_indirect temp_ptr = brw_indirect(7, 0); - brw_ADD(p, get_addr_reg(temp_ptr), get_addr_reg(vtx0), c->reg.clipdistance_offset); - brw_MOV(p, c->reg.dp0, deref_1f(temp_ptr, 0)); - brw_ADD(p, get_addr_reg(temp_ptr), get_addr_reg(vtx1), c->reg.clipdistance_offset); - brw_MOV(p, c->reg.dp1, deref_1f(temp_ptr, 0)); - } - brw_ELSE(p); - { - /* fixed plane: fetch the hpos, dp4 against the plane. */ - if (c->key.nr_userclip) - brw_MOV(p, c->reg.plane_equation, deref_4f(plane_ptr, 0)); - else - brw_MOV(p, c->reg.plane_equation, deref_4b(plane_ptr, 0)); - - brw_DP4(p, vec4(c->reg.dp0), deref_4f(vtx0, hpos_offset), c->reg.plane_equation); - brw_DP4(p, vec4(c->reg.dp1), deref_4f(vtx1, hpos_offset), c->reg.plane_equation); - } - brw_ENDIF(p); - - brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, vec1(c->reg.dp1), brw_imm_f(0.0f)); - - brw_IF(p, BRW_EXECUTE_1); - { - /* - * Both can be negative on GM965/G965 due to RHW workaround - * if so, this object should be rejected. - */ - if (p->devinfo->has_negative_rhw_bug) { - brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_LE, c->reg.dp0, brw_imm_f(0.0)); - brw_IF(p, BRW_EXECUTE_1); - { - brw_clip_kill_thread(c); - } - brw_ENDIF(p); - } - - brw_ADD(p, c->reg.t, c->reg.dp1, negate(c->reg.dp0)); - brw_math_invert(p, c->reg.t, c->reg.t); - brw_MUL(p, c->reg.t, c->reg.t, c->reg.dp1); - - brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_G, c->reg.t, c->reg.t1 ); - brw_MOV(p, c->reg.t1, c->reg.t); - brw_inst_set_pred_control(p->devinfo, brw_last_inst, - BRW_PREDICATE_NORMAL); - } - brw_ELSE(p); - { - /* Coming back in. We know that both cannot be negative - * because the line would have been culled in that case. - */ - - /* If both are positive, do nothing */ - /* Only on GM965/G965 */ - if (p->devinfo->has_negative_rhw_bug) { - brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.dp0, brw_imm_f(0.0)); - brw_IF(p, BRW_EXECUTE_1); - } - - { - brw_ADD(p, c->reg.t, c->reg.dp0, negate(c->reg.dp1)); - brw_math_invert(p, c->reg.t, c->reg.t); - brw_MUL(p, c->reg.t, c->reg.t, c->reg.dp0); - - brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_G, c->reg.t, c->reg.t0 ); - brw_MOV(p, c->reg.t0, c->reg.t); - brw_inst_set_pred_control(p->devinfo, brw_last_inst, - BRW_PREDICATE_NORMAL); - } - - if (p->devinfo->has_negative_rhw_bug) { - brw_ENDIF(p); - } - } - brw_ENDIF(p); - } - brw_ENDIF(p); - - /* plane_ptr++; - */ - brw_ADD(p, get_addr_reg(plane_ptr), get_addr_reg(plane_ptr), brw_clip_plane_stride(c)); - - /* while (planemask>>=1) != 0 - */ - brw_SHR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(1)); - brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ); - brw_SHR(p, c->reg.vertex_src_mask, c->reg.vertex_src_mask, brw_imm_ud(1)); - brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL); - brw_ADD(p, c->reg.clipdistance_offset, c->reg.clipdistance_offset, brw_imm_w(sizeof(float))); - brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL); - } - brw_WHILE(p); - brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL); - - brw_ADD(p, c->reg.t, c->reg.t0, c->reg.t1); - brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.t, brw_imm_f(1.0)); - brw_IF(p, BRW_EXECUTE_1); - { - brw_clip_interp_vertex(c, newvtx0, vtx0, vtx1, c->reg.t0, false); - brw_clip_interp_vertex(c, newvtx1, vtx1, vtx0, c->reg.t1, false); - - brw_clip_emit_vue(c, newvtx0, BRW_URB_WRITE_ALLOCATE_COMPLETE, - (_3DPRIM_LINESTRIP << URB_WRITE_PRIM_TYPE_SHIFT) - | URB_WRITE_PRIM_START); - brw_clip_emit_vue(c, newvtx1, BRW_URB_WRITE_EOT_COMPLETE, - (_3DPRIM_LINESTRIP << URB_WRITE_PRIM_TYPE_SHIFT) - | URB_WRITE_PRIM_END); - } - brw_ENDIF(p); - brw_clip_kill_thread(c); -} - - - -void brw_emit_line_clip( struct brw_clip_compile *c ) -{ - brw_clip_line_alloc_regs(c); - brw_clip_init_ff_sync(c); - - if (c->key.contains_flat_varying) { - if (c->key.pv_first) - brw_clip_copy_flatshaded_attributes(c, 1, 0); - else - brw_clip_copy_flatshaded_attributes(c, 0, 1); - } - - clip_and_emit_line(c); -} diff --git a/src/intel/compiler/brw_clip_point.c b/src/intel/compiler/brw_clip_point.c deleted file mode 100644 index 1cfb5f23357..00000000000 --- a/src/intel/compiler/brw_clip_point.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - Copyright (C) Intel Corp. 2006. All Rights Reserved. - Intel funded Tungsten Graphics to - develop this 3D driver. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice (including the - next paragraph) shall be included in all copies or substantial - portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - **********************************************************************/ - /* - * Authors: - * Keith Whitwell - */ - -#include "brw_clip.h" - - -/* Point clipping, nothing to do? - */ -void brw_emit_point_clip( struct brw_clip_compile *c ) -{ - /* Send an empty message to kill the thread: - */ - brw_clip_tri_alloc_regs(c, 0); - brw_clip_init_ff_sync(c); - - brw_clip_kill_thread(c); -} diff --git a/src/intel/compiler/brw_clip_tri.c b/src/intel/compiler/brw_clip_tri.c deleted file mode 100644 index a5bc2b85c12..00000000000 --- a/src/intel/compiler/brw_clip_tri.c +++ /dev/null @@ -1,659 +0,0 @@ -/* - Copyright (C) Intel Corp. 2006. All Rights Reserved. - Intel funded Tungsten Graphics to - develop this 3D driver. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice (including the - next paragraph) shall be included in all copies or substantial - portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - **********************************************************************/ - /* - * Authors: - * Keith Whitwell - */ - -#include "brw_clip.h" -#include "brw_prim.h" - -static void release_tmps( struct brw_clip_compile *c ) -{ - c->last_tmp = c->first_tmp; -} - - -void brw_clip_tri_alloc_regs( struct brw_clip_compile *c, - GLuint nr_verts ) -{ - const struct intel_device_info *devinfo = c->func.devinfo; - GLuint i = 0,j; - - /* Register usage is static, precompute here: - */ - c->reg.R0 = retype(brw_vec8_grf(i, 0), BRW_REGISTER_TYPE_UD); i++; - - if (c->key.nr_userclip) { - c->reg.fixed_planes = brw_vec4_grf(i, 0); - i += (6 + c->key.nr_userclip + 1) / 2; - - c->prog_data.curb_read_length = (6 + c->key.nr_userclip + 1) / 2; - } - else - c->prog_data.curb_read_length = 0; - - - /* Payload vertices plus space for more generated vertices: - */ - for (j = 0; j < nr_verts; j++) { - c->reg.vertex[j] = brw_vec4_grf(i, 0); - i += c->nr_regs; - } - - if (c->vue_map.num_slots % 2 && nr_verts > 0) { - /* The VUE has an odd number of slots so the last register is only half - * used. Fill the second half with zero. - */ - for (j = 0; j < 3; j++) { - GLuint delta = brw_vue_slot_to_offset(c->vue_map.num_slots); - - brw_MOV(&c->func, byte_offset(c->reg.vertex[j], delta), brw_imm_f(0)); - } - } - - c->reg.t = brw_vec1_grf(i, 0); - c->reg.loopcount = retype(brw_vec1_grf(i, 1), BRW_REGISTER_TYPE_D); - c->reg.nr_verts = retype(brw_vec1_grf(i, 2), BRW_REGISTER_TYPE_UD); - c->reg.planemask = retype(brw_vec1_grf(i, 3), BRW_REGISTER_TYPE_UD); - c->reg.plane_equation = brw_vec4_grf(i, 4); - i++; - - c->reg.dpPrev = brw_vec1_grf(i, 0); /* fixme - dp4 will clobber r.1,2,3 */ - c->reg.dp = brw_vec1_grf(i, 4); - i++; - - c->reg.inlist = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, i, 0); - i++; - - c->reg.outlist = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, i, 0); - i++; - - c->reg.freelist = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, i, 0); - i++; - - if (!c->key.nr_userclip) { - c->reg.fixed_planes = brw_vec8_grf(i, 0); - i++; - } - - if (c->key.do_unfilled) { - c->reg.dir = brw_vec4_grf(i, 0); - c->reg.offset = brw_vec4_grf(i, 4); - i++; - c->reg.tmp0 = brw_vec4_grf(i, 0); - c->reg.tmp1 = brw_vec4_grf(i, 4); - i++; - } - - c->reg.vertex_src_mask = retype(brw_vec1_grf(i, 0), BRW_REGISTER_TYPE_UD); - c->reg.clipdistance_offset = retype(brw_vec1_grf(i, 1), BRW_REGISTER_TYPE_W); - i++; - - if (devinfo->ver == 5) { - c->reg.ff_sync = retype(brw_vec1_grf(i, 0), BRW_REGISTER_TYPE_UD); - i++; - } - - c->first_tmp = i; - c->last_tmp = i; - - c->prog_data.urb_read_length = c->nr_regs; /* ? */ - c->prog_data.total_grf = i; -} - - - -void brw_clip_tri_init_vertices( struct brw_clip_compile *c ) -{ - struct brw_codegen *p = &c->func; - struct brw_reg tmp0 = c->reg.loopcount; /* handy temporary */ - - /* Initial list of indices for incoming vertices: - */ - brw_AND(p, tmp0, get_element_ud(c->reg.R0, 2), brw_imm_ud(PRIM_MASK)); - brw_CMP(p, - vec1(brw_null_reg()), - BRW_CONDITIONAL_EQ, - tmp0, - brw_imm_ud(_3DPRIM_TRISTRIP_REVERSE)); - - /* XXX: Is there an easier way to do this? Need to reverse every - * second tristrip element: Can ignore sometimes? - */ - brw_IF(p, BRW_EXECUTE_1); - { - brw_MOV(p, get_element(c->reg.inlist, 0), brw_address(c->reg.vertex[1]) ); - brw_MOV(p, get_element(c->reg.inlist, 1), brw_address(c->reg.vertex[0]) ); - if (c->need_direction) - brw_MOV(p, c->reg.dir, brw_imm_f(-1)); - } - brw_ELSE(p); - { - brw_MOV(p, get_element(c->reg.inlist, 0), brw_address(c->reg.vertex[0]) ); - brw_MOV(p, get_element(c->reg.inlist, 1), brw_address(c->reg.vertex[1]) ); - if (c->need_direction) - brw_MOV(p, c->reg.dir, brw_imm_f(1)); - } - brw_ENDIF(p); - - brw_MOV(p, get_element(c->reg.inlist, 2), brw_address(c->reg.vertex[2]) ); - brw_MOV(p, brw_vec8_grf(c->reg.outlist.nr, 0), brw_imm_f(0)); - brw_MOV(p, c->reg.nr_verts, brw_imm_ud(3)); -} - - - -void brw_clip_tri_flat_shade( struct brw_clip_compile *c ) -{ - struct brw_codegen *p = &c->func; - struct brw_reg tmp0 = c->reg.loopcount; /* handy temporary */ - - brw_AND(p, tmp0, get_element_ud(c->reg.R0, 2), brw_imm_ud(PRIM_MASK)); - brw_CMP(p, - vec1(brw_null_reg()), - BRW_CONDITIONAL_EQ, - tmp0, - brw_imm_ud(_3DPRIM_POLYGON)); - - brw_IF(p, BRW_EXECUTE_1); - { - brw_clip_copy_flatshaded_attributes(c, 1, 0); - brw_clip_copy_flatshaded_attributes(c, 2, 0); - } - brw_ELSE(p); - { - if (c->key.pv_first) { - brw_CMP(p, - vec1(brw_null_reg()), - BRW_CONDITIONAL_EQ, - tmp0, - brw_imm_ud(_3DPRIM_TRIFAN)); - brw_IF(p, BRW_EXECUTE_1); - { - brw_clip_copy_flatshaded_attributes(c, 0, 1); - brw_clip_copy_flatshaded_attributes(c, 2, 1); - } - brw_ELSE(p); - { - brw_clip_copy_flatshaded_attributes(c, 1, 0); - brw_clip_copy_flatshaded_attributes(c, 2, 0); - } - brw_ENDIF(p); - } - else { - brw_clip_copy_flatshaded_attributes(c, 0, 2); - brw_clip_copy_flatshaded_attributes(c, 1, 2); - } - } - brw_ENDIF(p); -} - - -/** - * Loads the clip distance for a vertex into `dst`, and ends with - * a comparison of it to zero with the condition `cond`. - * - * - If using a fixed plane, the distance is dot(hpos, plane). - * - If using a user clip plane, the distance is directly available in the vertex. - */ -static inline void -load_clip_distance(struct brw_clip_compile *c, struct brw_indirect vtx, - struct brw_reg dst, GLuint hpos_offset, int cond) -{ - struct brw_codegen *p = &c->func; - - dst = vec4(dst); - brw_AND(p, vec1(brw_null_reg()), c->reg.vertex_src_mask, brw_imm_ud(1)); - brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ); - brw_IF(p, BRW_EXECUTE_1); - { - struct brw_indirect temp_ptr = brw_indirect(7, 0); - brw_ADD(p, get_addr_reg(temp_ptr), get_addr_reg(vtx), c->reg.clipdistance_offset); - brw_MOV(p, vec1(dst), deref_1f(temp_ptr, 0)); - } - brw_ELSE(p); - { - brw_MOV(p, dst, deref_4f(vtx, hpos_offset)); - brw_DP4(p, dst, dst, c->reg.plane_equation); - } - brw_ENDIF(p); - - brw_CMP(p, brw_null_reg(), cond, vec1(dst), brw_imm_f(0.0f)); -} - - -/* Use mesa's clipping algorithms, translated to GFX4 assembly. - */ -void brw_clip_tri( struct brw_clip_compile *c ) -{ - struct brw_codegen *p = &c->func; - struct brw_indirect vtx = brw_indirect(0, 0); - struct brw_indirect vtxPrev = brw_indirect(1, 0); - struct brw_indirect vtxOut = brw_indirect(2, 0); - struct brw_indirect plane_ptr = brw_indirect(3, 0); - struct brw_indirect inlist_ptr = brw_indirect(4, 0); - struct brw_indirect outlist_ptr = brw_indirect(5, 0); - struct brw_indirect freelist_ptr = brw_indirect(6, 0); - GLuint hpos_offset = brw_varying_to_offset(&c->vue_map, VARYING_SLOT_POS); - GLint clipdist0_offset = c->key.nr_userclip - ? brw_varying_to_offset(&c->vue_map, VARYING_SLOT_CLIP_DIST0) - : 0; - - brw_MOV(p, get_addr_reg(vtxPrev), brw_address(c->reg.vertex[2]) ); - brw_MOV(p, get_addr_reg(plane_ptr), brw_clip_plane0_address(c)); - brw_MOV(p, get_addr_reg(inlist_ptr), brw_address(c->reg.inlist)); - brw_MOV(p, get_addr_reg(outlist_ptr), brw_address(c->reg.outlist)); - - brw_MOV(p, get_addr_reg(freelist_ptr), brw_address(c->reg.vertex[3]) ); - - /* Set the initial vertex source mask: The first 6 planes are the bounds - * of the view volume; the next 8 planes are the user clipping planes. - */ - brw_MOV(p, c->reg.vertex_src_mask, brw_imm_ud(0x3fc0)); - - /* Set the initial clipdistance offset to be 6 floats before gl_ClipDistance[0]. - * We'll increment 6 times before we start hitting actual user clipping. */ - brw_MOV(p, c->reg.clipdistance_offset, brw_imm_d(clipdist0_offset - 6*sizeof(float))); - - brw_DO(p, BRW_EXECUTE_1); - { - /* if (planemask & 1) - */ - brw_AND(p, vec1(brw_null_reg()), c->reg.planemask, brw_imm_ud(1)); - brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ); - - brw_IF(p, BRW_EXECUTE_1); - { - /* vtxOut = freelist_ptr++ - */ - brw_MOV(p, get_addr_reg(vtxOut), get_addr_reg(freelist_ptr) ); - brw_ADD(p, get_addr_reg(freelist_ptr), get_addr_reg(freelist_ptr), brw_imm_uw(c->nr_regs * REG_SIZE)); - - if (c->key.nr_userclip) - brw_MOV(p, c->reg.plane_equation, deref_4f(plane_ptr, 0)); - else - brw_MOV(p, c->reg.plane_equation, deref_4b(plane_ptr, 0)); - - brw_MOV(p, c->reg.loopcount, c->reg.nr_verts); - brw_MOV(p, c->reg.nr_verts, brw_imm_ud(0)); - - brw_DO(p, BRW_EXECUTE_1); - { - /* vtx = *input_ptr; - */ - brw_MOV(p, get_addr_reg(vtx), deref_1uw(inlist_ptr, 0)); - - load_clip_distance(c, vtxPrev, c->reg.dpPrev, hpos_offset, BRW_CONDITIONAL_L); - /* (prev < 0.0f) */ - brw_IF(p, BRW_EXECUTE_1); - { - load_clip_distance(c, vtx, c->reg.dp, hpos_offset, BRW_CONDITIONAL_GE); - /* IS_POSITIVE(next) - */ - brw_IF(p, BRW_EXECUTE_1); - { - - /* Coming back in. - */ - brw_ADD(p, c->reg.t, c->reg.dpPrev, negate(c->reg.dp)); - brw_math_invert(p, c->reg.t, c->reg.t); - brw_MUL(p, c->reg.t, c->reg.t, c->reg.dpPrev); - - /* If (vtxOut == 0) vtxOut = vtxPrev - */ - brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_EQ, get_addr_reg(vtxOut), brw_imm_uw(0) ); - brw_MOV(p, get_addr_reg(vtxOut), get_addr_reg(vtxPrev)); - brw_inst_set_pred_control(p->devinfo, brw_last_inst, - BRW_PREDICATE_NORMAL); - - brw_clip_interp_vertex(c, vtxOut, vtxPrev, vtx, c->reg.t, false); - - /* *outlist_ptr++ = vtxOut; - * nr_verts++; - * vtxOut = 0; - */ - brw_MOV(p, deref_1uw(outlist_ptr, 0), get_addr_reg(vtxOut)); - brw_ADD(p, get_addr_reg(outlist_ptr), get_addr_reg(outlist_ptr), brw_imm_uw(sizeof(short))); - brw_ADD(p, c->reg.nr_verts, c->reg.nr_verts, brw_imm_ud(1)); - brw_MOV(p, get_addr_reg(vtxOut), brw_imm_uw(0) ); - } - brw_ENDIF(p); - - } - brw_ELSE(p); - { - /* *outlist_ptr++ = vtxPrev; - * nr_verts++; - */ - brw_MOV(p, deref_1uw(outlist_ptr, 0), get_addr_reg(vtxPrev)); - brw_ADD(p, get_addr_reg(outlist_ptr), get_addr_reg(outlist_ptr), brw_imm_uw(sizeof(short))); - brw_ADD(p, c->reg.nr_verts, c->reg.nr_verts, brw_imm_ud(1)); - - load_clip_distance(c, vtx, c->reg.dp, hpos_offset, BRW_CONDITIONAL_L); - /* (next < 0.0f) - */ - brw_IF(p, BRW_EXECUTE_1); - { - /* Going out of bounds. Avoid division by zero as we - * know dp != dpPrev from DIFFERENT_SIGNS, above. - */ - brw_ADD(p, c->reg.t, c->reg.dp, negate(c->reg.dpPrev)); - brw_math_invert(p, c->reg.t, c->reg.t); - brw_MUL(p, c->reg.t, c->reg.t, c->reg.dp); - - /* If (vtxOut == 0) vtxOut = vtx - */ - brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_EQ, get_addr_reg(vtxOut), brw_imm_uw(0) ); - brw_MOV(p, get_addr_reg(vtxOut), get_addr_reg(vtx)); - brw_inst_set_pred_control(p->devinfo, brw_last_inst, - BRW_PREDICATE_NORMAL); - - brw_clip_interp_vertex(c, vtxOut, vtx, vtxPrev, c->reg.t, true); - - /* *outlist_ptr++ = vtxOut; - * nr_verts++; - * vtxOut = 0; - */ - brw_MOV(p, deref_1uw(outlist_ptr, 0), get_addr_reg(vtxOut)); - brw_ADD(p, get_addr_reg(outlist_ptr), get_addr_reg(outlist_ptr), brw_imm_uw(sizeof(short))); - brw_ADD(p, c->reg.nr_verts, c->reg.nr_verts, brw_imm_ud(1)); - brw_MOV(p, get_addr_reg(vtxOut), brw_imm_uw(0) ); - } - brw_ENDIF(p); - } - brw_ENDIF(p); - - /* vtxPrev = vtx; - * inlist_ptr++; - */ - brw_MOV(p, get_addr_reg(vtxPrev), get_addr_reg(vtx)); - brw_ADD(p, get_addr_reg(inlist_ptr), get_addr_reg(inlist_ptr), brw_imm_uw(sizeof(short))); - - /* while (--loopcount != 0) - */ - brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1)); - brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ); - } - brw_WHILE(p); - brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL); - - /* vtxPrev = *(outlist_ptr-1) OR: outlist[nr_verts-1] - * inlist = outlist - * inlist_ptr = &inlist[0] - * outlist_ptr = &outlist[0] - */ - brw_ADD(p, get_addr_reg(outlist_ptr), get_addr_reg(outlist_ptr), brw_imm_w(-2)); - brw_MOV(p, get_addr_reg(vtxPrev), deref_1uw(outlist_ptr, 0)); - brw_MOV(p, brw_vec8_grf(c->reg.inlist.nr, 0), brw_vec8_grf(c->reg.outlist.nr, 0)); - brw_MOV(p, get_addr_reg(inlist_ptr), brw_address(c->reg.inlist)); - brw_MOV(p, get_addr_reg(outlist_ptr), brw_address(c->reg.outlist)); - } - brw_ENDIF(p); - - /* plane_ptr++; - */ - brw_ADD(p, get_addr_reg(plane_ptr), get_addr_reg(plane_ptr), brw_clip_plane_stride(c)); - - /* nr_verts >= 3 - */ - brw_CMP(p, - vec1(brw_null_reg()), - BRW_CONDITIONAL_GE, - c->reg.nr_verts, - brw_imm_ud(3)); - brw_set_default_predicate_control(p, BRW_PREDICATE_NORMAL); - - /* && (planemask>>=1) != 0 - */ - brw_SHR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(1)); - brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ); - brw_SHR(p, c->reg.vertex_src_mask, c->reg.vertex_src_mask, brw_imm_ud(1)); - brw_ADD(p, c->reg.clipdistance_offset, c->reg.clipdistance_offset, brw_imm_w(sizeof(float))); - } - brw_WHILE(p); - brw_set_default_predicate_control(p, BRW_PREDICATE_NONE); -} - - - -void brw_clip_tri_emit_polygon(struct brw_clip_compile *c) -{ - struct brw_codegen *p = &c->func; - - /* for (loopcount = nr_verts-2; loopcount > 0; loopcount--) - */ - brw_ADD(p, - c->reg.loopcount, - c->reg.nr_verts, - brw_imm_d(-2)); - brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_G); - - brw_IF(p, BRW_EXECUTE_1); - { - struct brw_indirect v0 = brw_indirect(0, 0); - struct brw_indirect vptr = brw_indirect(1, 0); - - brw_MOV(p, get_addr_reg(vptr), brw_address(c->reg.inlist)); - brw_MOV(p, get_addr_reg(v0), deref_1uw(vptr, 0)); - - brw_clip_emit_vue(c, v0, BRW_URB_WRITE_ALLOCATE_COMPLETE, - ((_3DPRIM_TRIFAN << URB_WRITE_PRIM_TYPE_SHIFT) - | URB_WRITE_PRIM_START)); - - brw_ADD(p, get_addr_reg(vptr), get_addr_reg(vptr), brw_imm_uw(2)); - brw_MOV(p, get_addr_reg(v0), deref_1uw(vptr, 0)); - - brw_DO(p, BRW_EXECUTE_1); - { - brw_clip_emit_vue(c, v0, BRW_URB_WRITE_ALLOCATE_COMPLETE, - (_3DPRIM_TRIFAN << URB_WRITE_PRIM_TYPE_SHIFT)); - - brw_ADD(p, get_addr_reg(vptr), get_addr_reg(vptr), brw_imm_uw(2)); - brw_MOV(p, get_addr_reg(v0), deref_1uw(vptr, 0)); - - brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1)); - brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ); - } - brw_WHILE(p); - brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL); - - brw_clip_emit_vue(c, v0, BRW_URB_WRITE_EOT_COMPLETE, - ((_3DPRIM_TRIFAN << URB_WRITE_PRIM_TYPE_SHIFT) - | URB_WRITE_PRIM_END)); - } - brw_ENDIF(p); -} - -static void do_clip_tri( struct brw_clip_compile *c ) -{ - brw_clip_init_planes(c); - - brw_clip_tri(c); -} - - -static void maybe_do_clip_tri( struct brw_clip_compile *c ) -{ - struct brw_codegen *p = &c->func; - - brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_NZ, c->reg.planemask, brw_imm_ud(0)); - brw_IF(p, BRW_EXECUTE_1); - { - do_clip_tri(c); - } - brw_ENDIF(p); -} - -static void brw_clip_test( struct brw_clip_compile *c ) -{ - struct brw_reg t = retype(get_tmp(c), BRW_REGISTER_TYPE_UD); - struct brw_reg t1 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD); - struct brw_reg t2 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD); - struct brw_reg t3 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD); - - struct brw_reg v0 = get_tmp(c); - struct brw_reg v1 = get_tmp(c); - struct brw_reg v2 = get_tmp(c); - - struct brw_indirect vt0 = brw_indirect(0, 0); - struct brw_indirect vt1 = brw_indirect(1, 0); - struct brw_indirect vt2 = brw_indirect(2, 0); - - struct brw_codegen *p = &c->func; - struct brw_reg tmp0 = c->reg.loopcount; /* handy temporary */ - - GLuint hpos_offset = brw_varying_to_offset(&c->vue_map, - VARYING_SLOT_POS); - - brw_MOV(p, get_addr_reg(vt0), brw_address(c->reg.vertex[0])); - brw_MOV(p, get_addr_reg(vt1), brw_address(c->reg.vertex[1])); - brw_MOV(p, get_addr_reg(vt2), brw_address(c->reg.vertex[2])); - brw_MOV(p, v0, deref_4f(vt0, hpos_offset)); - brw_MOV(p, v1, deref_4f(vt1, hpos_offset)); - brw_MOV(p, v2, deref_4f(vt2, hpos_offset)); - brw_AND(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(~0x3f)); - - /* test nearz, xmin, ymin plane */ - /* clip.xyz < -clip.w */ - brw_CMP(p, t1, BRW_CONDITIONAL_L, v0, negate(get_element(v0, 3))); - brw_CMP(p, t2, BRW_CONDITIONAL_L, v1, negate(get_element(v1, 3))); - brw_CMP(p, t3, BRW_CONDITIONAL_L, v2, negate(get_element(v2, 3))); - - /* All vertices are outside of a plane, rejected */ - brw_AND(p, t, t1, t2); - brw_AND(p, t, t, t3); - brw_OR(p, tmp0, get_element(t, 0), get_element(t, 1)); - brw_OR(p, tmp0, tmp0, get_element(t, 2)); - brw_AND(p, brw_null_reg(), tmp0, brw_imm_ud(0x1)); - brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ); - brw_IF(p, BRW_EXECUTE_1); - { - brw_clip_kill_thread(c); - } - brw_ENDIF(p); - brw_set_default_predicate_control(p, BRW_PREDICATE_NONE); - - /* some vertices are inside a plane, some are outside,need to clip */ - brw_XOR(p, t, t1, t2); - brw_XOR(p, t1, t2, t3); - brw_OR(p, t, t, t1); - brw_AND(p, t, t, brw_imm_ud(0x1)); - brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ, - get_element(t, 0), brw_imm_ud(0)); - brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<5))); - brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL); - brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ, - get_element(t, 1), brw_imm_ud(0)); - brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<3))); - brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL); - brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ, - get_element(t, 2), brw_imm_ud(0)); - brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<1))); - brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL); - - /* test farz, xmax, ymax plane */ - /* clip.xyz > clip.w */ - brw_CMP(p, t1, BRW_CONDITIONAL_G, v0, get_element(v0, 3)); - brw_CMP(p, t2, BRW_CONDITIONAL_G, v1, get_element(v1, 3)); - brw_CMP(p, t3, BRW_CONDITIONAL_G, v2, get_element(v2, 3)); - - /* All vertices are outside of a plane, rejected */ - brw_AND(p, t, t1, t2); - brw_AND(p, t, t, t3); - brw_OR(p, tmp0, get_element(t, 0), get_element(t, 1)); - brw_OR(p, tmp0, tmp0, get_element(t, 2)); - brw_AND(p, brw_null_reg(), tmp0, brw_imm_ud(0x1)); - brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ); - brw_IF(p, BRW_EXECUTE_1); - { - brw_clip_kill_thread(c); - } - brw_ENDIF(p); - brw_set_default_predicate_control(p, BRW_PREDICATE_NONE); - - /* some vertices are inside a plane, some are outside,need to clip */ - brw_XOR(p, t, t1, t2); - brw_XOR(p, t1, t2, t3); - brw_OR(p, t, t, t1); - brw_AND(p, t, t, brw_imm_ud(0x1)); - brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ, - get_element(t, 0), brw_imm_ud(0)); - brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<4))); - brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL); - brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ, - get_element(t, 1), brw_imm_ud(0)); - brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<2))); - brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL); - brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ, - get_element(t, 2), brw_imm_ud(0)); - brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<0))); - brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL); - - release_tmps(c); -} - - -void brw_emit_tri_clip( struct brw_clip_compile *c ) -{ - struct brw_codegen *p = &c->func; - brw_clip_tri_alloc_regs(c, 3 + c->key.nr_userclip + 6); - brw_clip_tri_init_vertices(c); - brw_clip_init_clipmask(c); - brw_clip_init_ff_sync(c); - - /* if -ve rhw workaround bit is set, - do cliptest */ - if (p->devinfo->has_negative_rhw_bug) { - brw_AND(p, brw_null_reg(), get_element_ud(c->reg.R0, 2), - brw_imm_ud(1<<20)); - brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ); - brw_IF(p, BRW_EXECUTE_1); - { - brw_clip_test(c); - } - brw_ENDIF(p); - } - /* Can't push into do_clip_tri because with polygon (or quad) - * flatshading, need to apply the flatshade here because we don't - * respect the PV when converting to trifan for emit: - */ - if (c->key.contains_flat_varying) - brw_clip_tri_flat_shade(c); - - if ((c->key.clip_mode == BRW_CLIP_MODE_NORMAL) || - (c->key.clip_mode == BRW_CLIP_MODE_KERNEL_CLIP)) - do_clip_tri(c); - else - maybe_do_clip_tri(c); - - brw_clip_tri_emit_polygon(c); - - /* Send an empty message to kill the thread: - */ - brw_clip_kill_thread(c); -} diff --git a/src/intel/compiler/brw_clip_unfilled.c b/src/intel/compiler/brw_clip_unfilled.c deleted file mode 100644 index c0e78acc7e8..00000000000 --- a/src/intel/compiler/brw_clip_unfilled.c +++ /dev/null @@ -1,528 +0,0 @@ -/* - Copyright (C) Intel Corp. 2006. All Rights Reserved. - Intel funded Tungsten Graphics to - develop this 3D driver. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice (including the - next paragraph) shall be included in all copies or substantial - portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - **********************************************************************/ - /* - * Authors: - * Keith Whitwell - */ - -#include "brw_clip.h" -#include "brw_prim.h" - - -/* This is performed against the original triangles, so no indirection - * required: -BZZZT! - */ -static void compute_tri_direction( struct brw_clip_compile *c ) -{ - struct brw_codegen *p = &c->func; - struct brw_reg e = c->reg.tmp0; - struct brw_reg f = c->reg.tmp1; - GLuint hpos_offset = brw_varying_to_offset(&c->vue_map, VARYING_SLOT_POS); - struct brw_reg v0 = byte_offset(c->reg.vertex[0], hpos_offset); - struct brw_reg v1 = byte_offset(c->reg.vertex[1], hpos_offset); - struct brw_reg v2 = byte_offset(c->reg.vertex[2], hpos_offset); - - - struct brw_reg v0n = get_tmp(c); - struct brw_reg v1n = get_tmp(c); - struct brw_reg v2n = get_tmp(c); - - /* Convert to NDC. - * NOTE: We can't modify the original vertex coordinates, - * as it may impact further operations. - * So, we have to keep normalized coordinates in temp registers. - * - * TBD-KC - * Try to optimize unnecessary MOV's. - */ - brw_MOV(p, v0n, v0); - brw_MOV(p, v1n, v1); - brw_MOV(p, v2n, v2); - - brw_clip_project_position(c, v0n); - brw_clip_project_position(c, v1n); - brw_clip_project_position(c, v2n); - - /* Calculate the vectors of two edges of the triangle: - */ - brw_ADD(p, e, v0n, negate(v2n)); - brw_ADD(p, f, v1n, negate(v2n)); - - /* Take their crossproduct: - */ - brw_set_default_access_mode(p, BRW_ALIGN_16); - brw_MUL(p, vec4(brw_null_reg()), brw_swizzle(e, BRW_SWIZZLE_YZXW), - brw_swizzle(f, BRW_SWIZZLE_ZXYW)); - brw_MAC(p, vec4(e), negate(brw_swizzle(e, BRW_SWIZZLE_ZXYW)), - brw_swizzle(f, BRW_SWIZZLE_YZXW)); - brw_set_default_access_mode(p, BRW_ALIGN_1); - - brw_MUL(p, c->reg.dir, c->reg.dir, vec4(e)); -} - - -static void cull_direction( struct brw_clip_compile *c ) -{ - struct brw_codegen *p = &c->func; - GLuint conditional; - - assert (!(c->key.fill_ccw == BRW_CLIP_FILL_MODE_CULL && - c->key.fill_cw == BRW_CLIP_FILL_MODE_CULL)); - - if (c->key.fill_ccw == BRW_CLIP_FILL_MODE_CULL) - conditional = BRW_CONDITIONAL_GE; - else - conditional = BRW_CONDITIONAL_L; - - brw_CMP(p, - vec1(brw_null_reg()), - conditional, - get_element(c->reg.dir, 2), - brw_imm_f(0)); - - brw_IF(p, BRW_EXECUTE_1); - { - brw_clip_kill_thread(c); - } - brw_ENDIF(p); -} - - - -static void copy_bfc( struct brw_clip_compile *c ) -{ - struct brw_codegen *p = &c->func; - GLuint conditional; - - /* Do we have any colors to copy? - */ - if (!(brw_clip_have_varying(c, VARYING_SLOT_COL0) && - brw_clip_have_varying(c, VARYING_SLOT_BFC0)) && - !(brw_clip_have_varying(c, VARYING_SLOT_COL1) && - brw_clip_have_varying(c, VARYING_SLOT_BFC1))) - return; - - /* In some weird degenerate cases we can end up testing the - * direction twice, once for culling and once for bfc copying. Oh - * well, that's what you get for setting weird GL state. - */ - if (c->key.copy_bfc_ccw) - conditional = BRW_CONDITIONAL_GE; - else - conditional = BRW_CONDITIONAL_L; - - brw_CMP(p, - vec1(brw_null_reg()), - conditional, - get_element(c->reg.dir, 2), - brw_imm_f(0)); - - brw_IF(p, BRW_EXECUTE_1); - { - GLuint i; - - for (i = 0; i < 3; i++) { - if (brw_clip_have_varying(c, VARYING_SLOT_COL0) && - brw_clip_have_varying(c, VARYING_SLOT_BFC0)) - brw_MOV(p, - byte_offset(c->reg.vertex[i], - brw_varying_to_offset(&c->vue_map, - VARYING_SLOT_COL0)), - byte_offset(c->reg.vertex[i], - brw_varying_to_offset(&c->vue_map, - VARYING_SLOT_BFC0))); - - if (brw_clip_have_varying(c, VARYING_SLOT_COL1) && - brw_clip_have_varying(c, VARYING_SLOT_BFC1)) - brw_MOV(p, - byte_offset(c->reg.vertex[i], - brw_varying_to_offset(&c->vue_map, - VARYING_SLOT_COL1)), - byte_offset(c->reg.vertex[i], - brw_varying_to_offset(&c->vue_map, - VARYING_SLOT_BFC1))); - } - } - brw_ENDIF(p); -} - - - - -/* - GLfloat iz = 1.0 / dir.z; - GLfloat ac = dir.x * iz; - GLfloat bc = dir.y * iz; - offset = ctx->Polygon.OffsetUnits * DEPTH_SCALE; - offset += MAX2( abs(ac), abs(bc) ) * ctx->Polygon.OffsetFactor; - if (ctx->Polygon.OffsetClamp && isfinite(ctx->Polygon.OffsetClamp)) { - if (ctx->Polygon.OffsetClamp < 0) - offset = MAX2( offset, ctx->Polygon.OffsetClamp ); - else - offset = MIN2( offset, ctx->Polygon.OffsetClamp ); - } - offset *= MRD; -*/ -static void compute_offset( struct brw_clip_compile *c ) -{ - struct brw_codegen *p = &c->func; - struct brw_reg off = c->reg.offset; - struct brw_reg dir = c->reg.dir; - - brw_math_invert(p, get_element(off, 2), get_element(dir, 2)); - brw_MUL(p, vec2(off), vec2(dir), get_element(off, 2)); - - brw_CMP(p, - vec1(brw_null_reg()), - BRW_CONDITIONAL_GE, - brw_abs(get_element(off, 0)), - brw_abs(get_element(off, 1))); - - brw_SEL(p, vec1(off), - brw_abs(get_element(off, 0)), brw_abs(get_element(off, 1))); - brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL); - - brw_MUL(p, vec1(off), vec1(off), brw_imm_f(c->key.offset_factor)); - brw_ADD(p, vec1(off), vec1(off), brw_imm_f(c->key.offset_units)); - if (c->key.offset_clamp && isfinite(c->key.offset_clamp)) { - brw_CMP(p, - vec1(brw_null_reg()), - c->key.offset_clamp < 0 ? BRW_CONDITIONAL_GE : BRW_CONDITIONAL_L, - vec1(off), - brw_imm_f(c->key.offset_clamp)); - brw_SEL(p, vec1(off), vec1(off), brw_imm_f(c->key.offset_clamp)); - } -} - - -static void merge_edgeflags( struct brw_clip_compile *c ) -{ - struct brw_codegen *p = &c->func; - struct brw_reg tmp0 = get_element_ud(c->reg.tmp0, 0); - - brw_AND(p, tmp0, get_element_ud(c->reg.R0, 2), brw_imm_ud(PRIM_MASK)); - brw_CMP(p, - vec1(brw_null_reg()), - BRW_CONDITIONAL_EQ, - tmp0, - brw_imm_ud(_3DPRIM_POLYGON)); - - /* Get away with using reg.vertex because we know that this is not - * a _3DPRIM_TRISTRIP_REVERSE: - */ - brw_IF(p, BRW_EXECUTE_1); - { - brw_AND(p, vec1(brw_null_reg()), get_element_ud(c->reg.R0, 2), brw_imm_ud(1<<8)); - brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_EQ); - brw_MOV(p, byte_offset(c->reg.vertex[0], - brw_varying_to_offset(&c->vue_map, - VARYING_SLOT_EDGE)), - brw_imm_f(0)); - brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL); - - brw_AND(p, vec1(brw_null_reg()), get_element_ud(c->reg.R0, 2), brw_imm_ud(1<<9)); - brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_EQ); - brw_MOV(p, byte_offset(c->reg.vertex[2], - brw_varying_to_offset(&c->vue_map, - VARYING_SLOT_EDGE)), - brw_imm_f(0)); - brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL); - } - brw_ENDIF(p); -} - - - -static void apply_one_offset( struct brw_clip_compile *c, - struct brw_indirect vert ) -{ - struct brw_codegen *p = &c->func; - GLuint ndc_offset = brw_varying_to_offset(&c->vue_map, - BRW_VARYING_SLOT_NDC); - struct brw_reg z = deref_1f(vert, ndc_offset + - 2 * type_sz(BRW_REGISTER_TYPE_F)); - - brw_ADD(p, z, z, vec1(c->reg.offset)); -} - - - -/*********************************************************************** - * Output clipped polygon as an unfilled primitive: - */ -static void emit_lines(struct brw_clip_compile *c, - bool do_offset) -{ - struct brw_codegen *p = &c->func; - struct brw_indirect v0 = brw_indirect(0, 0); - struct brw_indirect v1 = brw_indirect(1, 0); - struct brw_indirect v0ptr = brw_indirect(2, 0); - struct brw_indirect v1ptr = brw_indirect(3, 0); - - /* Need a separate loop for offset: - */ - if (do_offset) { - brw_MOV(p, c->reg.loopcount, c->reg.nr_verts); - brw_MOV(p, get_addr_reg(v0ptr), brw_address(c->reg.inlist)); - - brw_DO(p, BRW_EXECUTE_1); - { - brw_MOV(p, get_addr_reg(v0), deref_1uw(v0ptr, 0)); - brw_ADD(p, get_addr_reg(v0ptr), get_addr_reg(v0ptr), brw_imm_uw(2)); - - apply_one_offset(c, v0); - - brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1)); - brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_G); - } - brw_WHILE(p); - brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL); - } - - /* v1ptr = &inlist[nr_verts] - * *v1ptr = v0 - */ - brw_MOV(p, c->reg.loopcount, c->reg.nr_verts); - brw_MOV(p, get_addr_reg(v0ptr), brw_address(c->reg.inlist)); - brw_ADD(p, get_addr_reg(v1ptr), get_addr_reg(v0ptr), retype(c->reg.nr_verts, BRW_REGISTER_TYPE_UW)); - brw_ADD(p, get_addr_reg(v1ptr), get_addr_reg(v1ptr), retype(c->reg.nr_verts, BRW_REGISTER_TYPE_UW)); - brw_MOV(p, deref_1uw(v1ptr, 0), deref_1uw(v0ptr, 0)); - - brw_DO(p, BRW_EXECUTE_1); - { - brw_MOV(p, get_addr_reg(v0), deref_1uw(v0ptr, 0)); - brw_MOV(p, get_addr_reg(v1), deref_1uw(v0ptr, 2)); - brw_ADD(p, get_addr_reg(v0ptr), get_addr_reg(v0ptr), brw_imm_uw(2)); - - /* draw edge if edgeflag != 0 */ - brw_CMP(p, - vec1(brw_null_reg()), BRW_CONDITIONAL_NZ, - deref_1f(v0, brw_varying_to_offset(&c->vue_map, - VARYING_SLOT_EDGE)), - brw_imm_f(0)); - brw_IF(p, BRW_EXECUTE_1); - { - brw_clip_emit_vue(c, v0, BRW_URB_WRITE_ALLOCATE_COMPLETE, - (_3DPRIM_LINESTRIP << URB_WRITE_PRIM_TYPE_SHIFT) - | URB_WRITE_PRIM_START); - brw_clip_emit_vue(c, v1, BRW_URB_WRITE_ALLOCATE_COMPLETE, - (_3DPRIM_LINESTRIP << URB_WRITE_PRIM_TYPE_SHIFT) - | URB_WRITE_PRIM_END); - } - brw_ENDIF(p); - - brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1)); - brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ); - } - brw_WHILE(p); - brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL); -} - - - -static void emit_points(struct brw_clip_compile *c, - bool do_offset ) -{ - struct brw_codegen *p = &c->func; - - struct brw_indirect v0 = brw_indirect(0, 0); - struct brw_indirect v0ptr = brw_indirect(2, 0); - - brw_MOV(p, c->reg.loopcount, c->reg.nr_verts); - brw_MOV(p, get_addr_reg(v0ptr), brw_address(c->reg.inlist)); - - brw_DO(p, BRW_EXECUTE_1); - { - brw_MOV(p, get_addr_reg(v0), deref_1uw(v0ptr, 0)); - brw_ADD(p, get_addr_reg(v0ptr), get_addr_reg(v0ptr), brw_imm_uw(2)); - - /* draw if edgeflag != 0 - */ - brw_CMP(p, - vec1(brw_null_reg()), BRW_CONDITIONAL_NZ, - deref_1f(v0, brw_varying_to_offset(&c->vue_map, - VARYING_SLOT_EDGE)), - brw_imm_f(0)); - brw_IF(p, BRW_EXECUTE_1); - { - if (do_offset) - apply_one_offset(c, v0); - - brw_clip_emit_vue(c, v0, BRW_URB_WRITE_ALLOCATE_COMPLETE, - (_3DPRIM_POINTLIST << URB_WRITE_PRIM_TYPE_SHIFT) - | URB_WRITE_PRIM_START | URB_WRITE_PRIM_END); - } - brw_ENDIF(p); - - brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1)); - brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ); - } - brw_WHILE(p); - brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL); -} - - - - - - - -static void emit_primitives( struct brw_clip_compile *c, - GLuint mode, - bool do_offset ) -{ - switch (mode) { - case BRW_CLIP_FILL_MODE_FILL: - brw_clip_tri_emit_polygon(c); - break; - - case BRW_CLIP_FILL_MODE_LINE: - emit_lines(c, do_offset); - break; - - case BRW_CLIP_FILL_MODE_POINT: - emit_points(c, do_offset); - break; - - case BRW_CLIP_FILL_MODE_CULL: - unreachable("not reached"); - } -} - - - -static void emit_unfilled_primitives( struct brw_clip_compile *c ) -{ - struct brw_codegen *p = &c->func; - - /* Direction culling has already been done. - */ - if (c->key.fill_ccw != c->key.fill_cw && - c->key.fill_ccw != BRW_CLIP_FILL_MODE_CULL && - c->key.fill_cw != BRW_CLIP_FILL_MODE_CULL) - { - brw_CMP(p, - vec1(brw_null_reg()), - BRW_CONDITIONAL_GE, - get_element(c->reg.dir, 2), - brw_imm_f(0)); - - brw_IF(p, BRW_EXECUTE_1); - { - emit_primitives(c, c->key.fill_ccw, c->key.offset_ccw); - } - brw_ELSE(p); - { - emit_primitives(c, c->key.fill_cw, c->key.offset_cw); - } - brw_ENDIF(p); - } - else if (c->key.fill_cw != BRW_CLIP_FILL_MODE_CULL) { - emit_primitives(c, c->key.fill_cw, c->key.offset_cw); - } - else if (c->key.fill_ccw != BRW_CLIP_FILL_MODE_CULL) { - emit_primitives(c, c->key.fill_ccw, c->key.offset_ccw); - } -} - - - - -static void check_nr_verts( struct brw_clip_compile *c ) -{ - struct brw_codegen *p = &c->func; - - brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.nr_verts, brw_imm_d(3)); - brw_IF(p, BRW_EXECUTE_1); - { - brw_clip_kill_thread(c); - } - brw_ENDIF(p); -} - - -void brw_emit_unfilled_clip( struct brw_clip_compile *c ) -{ - struct brw_codegen *p = &c->func; - - c->need_direction = ((c->key.offset_ccw || c->key.offset_cw) || - (c->key.fill_ccw != c->key.fill_cw) || - c->key.fill_ccw == BRW_CLIP_FILL_MODE_CULL || - c->key.fill_cw == BRW_CLIP_FILL_MODE_CULL || - c->key.copy_bfc_cw || - c->key.copy_bfc_ccw); - - brw_clip_tri_alloc_regs(c, 3 + c->key.nr_userclip + 6); - brw_clip_tri_init_vertices(c); - brw_clip_init_ff_sync(c); - - assert(brw_clip_have_varying(c, VARYING_SLOT_EDGE)); - - if (c->key.fill_ccw == BRW_CLIP_FILL_MODE_CULL && - c->key.fill_cw == BRW_CLIP_FILL_MODE_CULL) { - brw_clip_kill_thread(c); - return; - } - - merge_edgeflags(c); - - /* Need to use the inlist indirection here: - */ - if (c->need_direction) - compute_tri_direction(c); - - if (c->key.fill_ccw == BRW_CLIP_FILL_MODE_CULL || - c->key.fill_cw == BRW_CLIP_FILL_MODE_CULL) - cull_direction(c); - - if (c->key.offset_ccw || - c->key.offset_cw) - compute_offset(c); - - if (c->key.copy_bfc_ccw || - c->key.copy_bfc_cw) - copy_bfc(c); - - /* Need to do this whether we clip or not: - */ - if (c->key.contains_flat_varying) - brw_clip_tri_flat_shade(c); - - brw_clip_init_clipmask(c); - brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_NZ, c->reg.planemask, brw_imm_ud(0)); - brw_IF(p, BRW_EXECUTE_1); - { - brw_clip_init_planes(c); - brw_clip_tri(c); - check_nr_verts(c); - } - brw_ENDIF(p); - - emit_unfilled_primitives(c); - brw_clip_kill_thread(c); -} diff --git a/src/intel/compiler/brw_clip_util.c b/src/intel/compiler/brw_clip_util.c deleted file mode 100644 index 270a6dc3225..00000000000 --- a/src/intel/compiler/brw_clip_util.c +++ /dev/null @@ -1,464 +0,0 @@ -/* - Copyright (C) Intel Corp. 2006. All Rights Reserved. - Intel funded Tungsten Graphics to - develop this 3D driver. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice (including the - next paragraph) shall be included in all copies or substantial - portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - **********************************************************************/ - /* - * Authors: - * Keith Whitwell - */ - -#include "brw_clip.h" - - -struct brw_reg get_tmp( struct brw_clip_compile *c ) -{ - struct brw_reg tmp = brw_vec4_grf(c->last_tmp, 0); - - if (++c->last_tmp > c->prog_data.total_grf) - c->prog_data.total_grf = c->last_tmp; - - return tmp; -} - -static void release_tmp( struct brw_clip_compile *c, struct brw_reg tmp ) -{ - if (tmp.nr == c->last_tmp-1) - c->last_tmp--; -} - - -static struct brw_reg make_plane_ud(GLuint x, GLuint y, GLuint z, GLuint w) -{ - return brw_imm_ud((w<<24) | (z<<16) | (y<<8) | x); -} - - -void brw_clip_init_planes( struct brw_clip_compile *c ) -{ - struct brw_codegen *p = &c->func; - - if (!c->key.nr_userclip) { - brw_MOV(p, get_element_ud(c->reg.fixed_planes, 0), make_plane_ud( 0, 0, 0xff, 1)); - brw_MOV(p, get_element_ud(c->reg.fixed_planes, 1), make_plane_ud( 0, 0, 1, 1)); - brw_MOV(p, get_element_ud(c->reg.fixed_planes, 2), make_plane_ud( 0, 0xff, 0, 1)); - brw_MOV(p, get_element_ud(c->reg.fixed_planes, 3), make_plane_ud( 0, 1, 0, 1)); - brw_MOV(p, get_element_ud(c->reg.fixed_planes, 4), make_plane_ud(0xff, 0, 0, 1)); - brw_MOV(p, get_element_ud(c->reg.fixed_planes, 5), make_plane_ud( 1, 0, 0, 1)); - } -} - - - -#define W 3 - -/* Project 'pos' to screen space (or back again), overwrite with results: - */ -void brw_clip_project_position(struct brw_clip_compile *c, struct brw_reg pos ) -{ - struct brw_codegen *p = &c->func; - - /* calc rhw - */ - brw_math_invert(p, get_element(pos, W), get_element(pos, W)); - - /* value.xyz *= value.rhw - */ - brw_set_default_access_mode(p, BRW_ALIGN_16); - brw_MUL(p, brw_writemask(pos, WRITEMASK_XYZ), pos, - brw_swizzle(pos, BRW_SWIZZLE_WWWW)); - brw_set_default_access_mode(p, BRW_ALIGN_1); -} - - -static void brw_clip_project_vertex( struct brw_clip_compile *c, - struct brw_indirect vert_addr ) -{ - struct brw_codegen *p = &c->func; - struct brw_reg tmp = get_tmp(c); - GLuint hpos_offset = brw_varying_to_offset(&c->vue_map, VARYING_SLOT_POS); - GLuint ndc_offset = brw_varying_to_offset(&c->vue_map, - BRW_VARYING_SLOT_NDC); - - /* Fixup position. Extract from the original vertex and re-project - * to screen space: - */ - brw_MOV(p, tmp, deref_4f(vert_addr, hpos_offset)); - brw_clip_project_position(c, tmp); - brw_MOV(p, deref_4f(vert_addr, ndc_offset), tmp); - - release_tmp(c, tmp); -} - - - - -/* Interpolate between two vertices and put the result into a0.0. - * Increment a0.0 accordingly. - * - * Beware that dest_ptr can be equal to v0_ptr! - */ -void brw_clip_interp_vertex( struct brw_clip_compile *c, - struct brw_indirect dest_ptr, - struct brw_indirect v0_ptr, /* from */ - struct brw_indirect v1_ptr, /* to */ - struct brw_reg t0, - bool force_edgeflag) -{ - struct brw_codegen *p = &c->func; - struct brw_reg t_nopersp, v0_ndc_copy; - GLuint slot; - - /* Just copy the vertex header: - */ - /* - * After CLIP stage, only first 256 bits of the VUE are read - * back on Ironlake, so needn't change it - */ - brw_copy_indirect_to_indirect(p, dest_ptr, v0_ptr, 1); - - - /* First handle the 3D and NDC interpolation, in case we - * need noperspective interpolation. Doing it early has no - * performance impact in any case. - */ - - /* Take a copy of the v0 NDC coordinates, in case dest == v0. */ - if (c->key.contains_noperspective_varying) { - GLuint offset = brw_varying_to_offset(&c->vue_map, - BRW_VARYING_SLOT_NDC); - v0_ndc_copy = get_tmp(c); - brw_MOV(p, v0_ndc_copy, deref_4f(v0_ptr, offset)); - } - - /* Compute the new 3D position - * - * dest_hpos = v0_hpos * (1 - t0) + v1_hpos * t0 - */ - { - GLuint delta = brw_varying_to_offset(&c->vue_map, VARYING_SLOT_POS); - struct brw_reg tmp = get_tmp(c); - brw_MUL(p, vec4(brw_null_reg()), deref_4f(v1_ptr, delta), t0); - brw_MAC(p, tmp, negate(deref_4f(v0_ptr, delta)), t0); - brw_ADD(p, deref_4f(dest_ptr, delta), deref_4f(v0_ptr, delta), tmp); - release_tmp(c, tmp); - } - - /* Recreate the projected (NDC) coordinate in the new vertex header */ - brw_clip_project_vertex(c, dest_ptr); - - /* If we have noperspective attributes, - * we need to compute the screen-space t - */ - if (c->key.contains_noperspective_varying) { - GLuint delta = brw_varying_to_offset(&c->vue_map, - BRW_VARYING_SLOT_NDC); - struct brw_reg tmp = get_tmp(c); - t_nopersp = get_tmp(c); - - /* t_nopersp = vec4(v1.xy, dest.xy) */ - brw_MOV(p, t_nopersp, deref_4f(v1_ptr, delta)); - brw_MOV(p, tmp, deref_4f(dest_ptr, delta)); - brw_set_default_access_mode(p, BRW_ALIGN_16); - brw_MOV(p, - brw_writemask(t_nopersp, WRITEMASK_ZW), - brw_swizzle(tmp, BRW_SWIZZLE_XYXY)); - - /* t_nopersp = vec4(v1.xy, dest.xy) - v0.xyxy */ - brw_ADD(p, t_nopersp, t_nopersp, - negate(brw_swizzle(v0_ndc_copy, BRW_SWIZZLE_XYXY))); - - /* Add the absolute values of the X and Y deltas so that if - * the points aren't in the same place on the screen we get - * nonzero values to divide. - * - * After that, we have vert1 - vert0 in t_nopersp.x and - * vertnew - vert0 in t_nopersp.y - * - * t_nopersp = vec2(|v1.x -v0.x| + |v1.y -v0.y|, - * |dest.x-v0.x| + |dest.y-v0.y|) - */ - brw_ADD(p, - brw_writemask(t_nopersp, WRITEMASK_XY), - brw_abs(brw_swizzle(t_nopersp, BRW_SWIZZLE_XZXZ)), - brw_abs(brw_swizzle(t_nopersp, BRW_SWIZZLE_YWYW))); - brw_set_default_access_mode(p, BRW_ALIGN_1); - - /* If the points are in the same place, just substitute a - * value to avoid divide-by-zero - */ - brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_EQ, - vec1(t_nopersp), - brw_imm_f(0)); - brw_IF(p, BRW_EXECUTE_1); - brw_MOV(p, t_nopersp, brw_imm_vf4(brw_float_to_vf(1.0), - brw_float_to_vf(0.0), - brw_float_to_vf(0.0), - brw_float_to_vf(0.0))); - brw_ENDIF(p); - - /* Now compute t_nopersp = t_nopersp.y/t_nopersp.x and broadcast it. */ - brw_math_invert(p, get_element(t_nopersp, 0), get_element(t_nopersp, 0)); - brw_MUL(p, vec1(t_nopersp), vec1(t_nopersp), - vec1(suboffset(t_nopersp, 1))); - brw_set_default_access_mode(p, BRW_ALIGN_16); - brw_MOV(p, t_nopersp, brw_swizzle(t_nopersp, BRW_SWIZZLE_XXXX)); - brw_set_default_access_mode(p, BRW_ALIGN_1); - - release_tmp(c, tmp); - release_tmp(c, v0_ndc_copy); - } - - /* Now we can iterate over each attribute - * (could be done in pairs?) - */ - for (slot = 0; slot < c->vue_map.num_slots; slot++) { - int varying = c->vue_map.slot_to_varying[slot]; - GLuint delta = brw_vue_slot_to_offset(slot); - - /* HPOS, NDC already handled above */ - if (varying == VARYING_SLOT_POS || varying == BRW_VARYING_SLOT_NDC) - continue; - - - if (varying == VARYING_SLOT_EDGE) { - if (force_edgeflag) - brw_MOV(p, deref_4f(dest_ptr, delta), brw_imm_f(1)); - else - brw_MOV(p, deref_4f(dest_ptr, delta), deref_4f(v0_ptr, delta)); - } else if (varying == VARYING_SLOT_PSIZ) { - /* PSIZ doesn't need interpolation because it isn't used by the - * fragment shader. - */ - } else if (varying < VARYING_SLOT_MAX) { - /* This is a true vertex result (and not a special value for the VUE - * header), so interpolate: - * - * New = attr0 + t*attr1 - t*attr0 - * - * Unless the attribute is flat shaded -- in which case just copy - * from one of the sources (doesn't matter which; already copied from pv) - */ - GLuint interp = c->key.interp_mode[slot]; - - if (interp != INTERP_MODE_FLAT) { - struct brw_reg tmp = get_tmp(c); - struct brw_reg t = - interp == INTERP_MODE_NOPERSPECTIVE ? t_nopersp : t0; - - brw_MUL(p, - vec4(brw_null_reg()), - deref_4f(v1_ptr, delta), - t); - - brw_MAC(p, - tmp, - negate(deref_4f(v0_ptr, delta)), - t); - - brw_ADD(p, - deref_4f(dest_ptr, delta), - deref_4f(v0_ptr, delta), - tmp); - - release_tmp(c, tmp); - } - else { - brw_MOV(p, - deref_4f(dest_ptr, delta), - deref_4f(v0_ptr, delta)); - } - } - } - - if (c->vue_map.num_slots % 2) { - GLuint delta = brw_vue_slot_to_offset(c->vue_map.num_slots); - - brw_MOV(p, deref_4f(dest_ptr, delta), brw_imm_f(0)); - } - - if (c->key.contains_noperspective_varying) - release_tmp(c, t_nopersp); -} - -void brw_clip_emit_vue(struct brw_clip_compile *c, - struct brw_indirect vert, - enum brw_urb_write_flags flags, - GLuint header) -{ - struct brw_codegen *p = &c->func; - bool allocate = flags & BRW_URB_WRITE_ALLOCATE; - - brw_clip_ff_sync(c); - - /* Any URB entry that is allocated must subsequently be used or discarded, - * so it doesn't make sense to mark EOT and ALLOCATE at the same time. - */ - assert(!(allocate && (flags & BRW_URB_WRITE_EOT))); - - /* Copy the vertex from vertn into m1..mN+1: - */ - brw_copy_from_indirect(p, brw_message_reg(1), vert, c->nr_regs); - - /* Overwrite PrimType and PrimStart in the message header, for - * each vertex in turn: - */ - brw_MOV(p, get_element_ud(c->reg.R0, 2), brw_imm_ud(header)); - - - /* Send each vertex as a separate write to the urb. This - * is different to the concept in brw_sf_emit.c, where - * subsequent writes are used to build up a single urb - * entry. Each of these writes instantiates a separate - * urb entry - (I think... what about 'allocate'?) - */ - brw_urb_WRITE(p, - allocate ? c->reg.R0 : retype(brw_null_reg(), BRW_REGISTER_TYPE_UD), - 0, - c->reg.R0, - flags, - c->nr_regs + 1, /* msg length */ - allocate ? 1 : 0, /* response_length */ - 0, /* urb offset */ - BRW_URB_SWIZZLE_NONE); -} - - - -void brw_clip_kill_thread(struct brw_clip_compile *c) -{ - struct brw_codegen *p = &c->func; - - brw_clip_ff_sync(c); - /* Send an empty message to kill the thread and release any - * allocated urb entry: - */ - brw_urb_WRITE(p, - retype(brw_null_reg(), BRW_REGISTER_TYPE_UD), - 0, - c->reg.R0, - BRW_URB_WRITE_UNUSED | BRW_URB_WRITE_EOT_COMPLETE, - 1, /* msg len */ - 0, /* response len */ - 0, - BRW_URB_SWIZZLE_NONE); -} - - - - -struct brw_reg brw_clip_plane0_address( struct brw_clip_compile *c ) -{ - return brw_address(c->reg.fixed_planes); -} - - -struct brw_reg brw_clip_plane_stride( struct brw_clip_compile *c ) -{ - if (c->key.nr_userclip) { - return brw_imm_uw(16); - } - else { - return brw_imm_uw(4); - } -} - - -/* Distribute flatshaded attributes from provoking vertex prior to - * clipping. - */ -void brw_clip_copy_flatshaded_attributes( struct brw_clip_compile *c, - GLuint to, GLuint from ) -{ - struct brw_codegen *p = &c->func; - - for (int i = 0; i < c->vue_map.num_slots; i++) { - if (c->key.interp_mode[i] == INTERP_MODE_FLAT) { - brw_MOV(p, - byte_offset(c->reg.vertex[to], brw_vue_slot_to_offset(i)), - byte_offset(c->reg.vertex[from], brw_vue_slot_to_offset(i))); - } - } -} - - - -void brw_clip_init_clipmask( struct brw_clip_compile *c ) -{ - struct brw_codegen *p = &c->func; - struct brw_reg incoming = get_element_ud(c->reg.R0, 2); - - /* Shift so that lowest outcode bit is rightmost: - */ - brw_SHR(p, c->reg.planemask, incoming, brw_imm_ud(26)); - - if (c->key.nr_userclip) { - struct brw_reg tmp = retype(vec1(get_tmp(c)), BRW_REGISTER_TYPE_UD); - - /* Rearrange userclip outcodes so that they come directly after - * the fixed plane bits. - */ - if (p->devinfo->ver == 5 || p->devinfo->verx10 == 45) - brw_AND(p, tmp, incoming, brw_imm_ud(0xff<<14)); - else - brw_AND(p, tmp, incoming, brw_imm_ud(0x3f<<14)); - - brw_SHR(p, tmp, tmp, brw_imm_ud(8)); - brw_OR(p, c->reg.planemask, c->reg.planemask, tmp); - - release_tmp(c, tmp); - } -} - -void brw_clip_ff_sync(struct brw_clip_compile *c) -{ - struct brw_codegen *p = &c->func; - - if (p->devinfo->ver == 5) { - brw_AND(p, brw_null_reg(), c->reg.ff_sync, brw_imm_ud(0x1)); - brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_Z); - brw_IF(p, BRW_EXECUTE_1); - { - brw_OR(p, c->reg.ff_sync, c->reg.ff_sync, brw_imm_ud(0x1)); - brw_ff_sync(p, - c->reg.R0, - 0, - c->reg.R0, - 1, /* allocate */ - 1, /* response length */ - 0 /* eot */); - } - brw_ENDIF(p); - brw_set_default_predicate_control(p, BRW_PREDICATE_NONE); - } -} - -void brw_clip_init_ff_sync(struct brw_clip_compile *c) -{ - struct brw_codegen *p = &c->func; - - if (p->devinfo->ver == 5) { - brw_MOV(p, c->reg.ff_sync, brw_imm_ud(0)); - } -} diff --git a/src/intel/compiler/brw_compile_clip.c b/src/intel/compiler/brw_compile_clip.c deleted file mode 100644 index 25f476d4066..00000000000 --- a/src/intel/compiler/brw_compile_clip.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright © 2006 - 2017 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "brw_clip.h" -#include "brw_disasm.h" - -#include "dev/intel_debug.h" - -const unsigned * -brw_compile_clip(const struct brw_compiler *compiler, - void *mem_ctx, - const struct brw_clip_prog_key *key, - struct brw_clip_prog_data *prog_data, - struct intel_vue_map *vue_map, - unsigned *final_assembly_size) -{ - struct brw_clip_compile c; - memset(&c, 0, sizeof(c)); - - /* Begin the compilation: - */ - brw_init_codegen(&compiler->isa, &c.func, mem_ctx); - - c.func.single_program_flow = 1; - - c.key = *key; - c.vue_map = *vue_map; - - /* nr_regs is the number of registers filled by reading data from the VUE. - * This program accesses the entire VUE, so nr_regs needs to be the size of - * the VUE (measured in pairs, since two slots are stored in each - * register). - */ - c.nr_regs = (c.vue_map.num_slots + 1)/2; - - c.prog_data.clip_mode = c.key.clip_mode; /* XXX */ - - /* For some reason the thread is spawned with only 4 channels - * unmasked. - */ - brw_set_default_mask_control(&c.func, BRW_MASK_DISABLE); - - /* Would ideally have the option of producing a program which could - * do all three: - */ - switch (key->primitive) { - case MESA_PRIM_TRIANGLES: - if (key->do_unfilled) - brw_emit_unfilled_clip( &c ); - else - brw_emit_tri_clip( &c ); - break; - case MESA_PRIM_LINES: - brw_emit_line_clip( &c ); - break; - case MESA_PRIM_POINTS: - brw_emit_point_clip( &c ); - break; - default: - unreachable("not reached"); - } - - brw_compact_instructions(&c.func, 0, NULL); - - *prog_data = c.prog_data; - - const unsigned *program = brw_get_program(&c.func, final_assembly_size); - - if (INTEL_DEBUG(DEBUG_CLIP)) { - fprintf(stderr, "clip:\n"); - brw_disassemble_with_labels(&compiler->isa, - program, 0, *final_assembly_size, stderr); - fprintf(stderr, "\n"); - } - - return program; -} diff --git a/src/intel/compiler/brw_compile_ff_gs.c b/src/intel/compiler/brw_compile_ff_gs.c deleted file mode 100644 index 200a1dd0415..00000000000 --- a/src/intel/compiler/brw_compile_ff_gs.c +++ /dev/null @@ -1,662 +0,0 @@ -/* - Copyright (C) Intel Corp. 2006. All Rights Reserved. - Intel funded Tungsten Graphics to - develop this 3D driver. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice (including the - next paragraph) shall be included in all copies or substantial - portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - **********************************************************************/ - /* - * Authors: - * Keith Whitwell - */ - -#include "brw_compiler.h" -#include "brw_disasm.h" -#include "brw_eu.h" -#include "brw_prim.h" - -#include "dev/intel_debug.h" - -#define MAX_GS_VERTS (4) - -struct brw_ff_gs_compile { - struct brw_codegen func; - struct brw_ff_gs_prog_key key; - struct brw_ff_gs_prog_data *prog_data; - - struct { - struct brw_reg R0; - - /** - * Register holding streamed vertex buffer pointers -- see the Sandy - * Bridge PRM, volume 2 part 1, section 4.4.2 (GS Thread Payload - * [DevSNB]). These pointers are delivered in GRF 1. - */ - struct brw_reg SVBI; - - struct brw_reg vertex[MAX_GS_VERTS]; - struct brw_reg header; - struct brw_reg temp; - - /** - * Register holding destination indices for streamed buffer writes. - * Only used for SOL programs. - */ - struct brw_reg destination_indices; - } reg; - - /* Number of registers used to store vertex data */ - GLuint nr_regs; - - struct intel_vue_map vue_map; -}; - -/** - * Allocate registers for GS. - * - * If sol_program is true, then: - * - * - The thread will be spawned with the "SVBI Payload Enable" bit set, so GRF - * 1 needs to be set aside to hold the streamed vertex buffer indices. - * - * - The thread will need to use the destination_indices register. - */ -static void brw_ff_gs_alloc_regs(struct brw_ff_gs_compile *c, - GLuint nr_verts, - bool sol_program) -{ - GLuint i = 0,j; - - /* Register usage is static, precompute here: - */ - c->reg.R0 = retype(brw_vec8_grf(i, 0), BRW_REGISTER_TYPE_UD); i++; - - /* Streamed vertex buffer indices */ - if (sol_program) - c->reg.SVBI = retype(brw_vec8_grf(i++, 0), BRW_REGISTER_TYPE_UD); - - /* Payload vertices plus space for more generated vertices: - */ - for (j = 0; j < nr_verts; j++) { - c->reg.vertex[j] = brw_vec4_grf(i, 0); - i += c->nr_regs; - } - - c->reg.header = retype(brw_vec8_grf(i++, 0), BRW_REGISTER_TYPE_UD); - c->reg.temp = retype(brw_vec8_grf(i++, 0), BRW_REGISTER_TYPE_UD); - - if (sol_program) { - c->reg.destination_indices = - retype(brw_vec4_grf(i++, 0), BRW_REGISTER_TYPE_UD); - } - - c->prog_data->urb_read_length = c->nr_regs; - c->prog_data->total_grf = i; -} - - -/** - * Set up the initial value of c->reg.header register based on c->reg.R0. - * - * The following information is passed to the GS thread in R0, and needs to be - * included in the first URB_WRITE or FF_SYNC message sent by the GS: - * - * - DWORD 0 [31:0] handle info (Gen4 only) - * - DWORD 5 [7:0] FFTID - * - DWORD 6 [31:0] Debug info - * - DWORD 7 [31:0] Debug info - * - * This function sets up the above data by copying by copying the contents of - * R0 to the header register. - */ -static void brw_ff_gs_initialize_header(struct brw_ff_gs_compile *c) -{ - struct brw_codegen *p = &c->func; - brw_MOV(p, c->reg.header, c->reg.R0); -} - -/** - * Overwrite DWORD 2 of c->reg.header with the given immediate unsigned value. - * - * In URB_WRITE messages, DWORD 2 contains the fields PrimType, PrimStart, - * PrimEnd, Increment CL_INVOCATIONS, and SONumPrimsWritten, many of which we - * need to be able to update on a per-vertex basis. - */ -static void brw_ff_gs_overwrite_header_dw2(struct brw_ff_gs_compile *c, - unsigned dw2) -{ - struct brw_codegen *p = &c->func; - brw_MOV(p, get_element_ud(c->reg.header, 2), brw_imm_ud(dw2)); -} - -/** - * Overwrite DWORD 2 of c->reg.header with the primitive type from c->reg.R0. - * - * When the thread is spawned, GRF 0 contains the primitive type in bits 4:0 - * of DWORD 2. URB_WRITE messages need the primitive type in bits 6:2 of - * DWORD 2. So this function extracts the primitive type field, bitshifts it - * appropriately, and stores it in c->reg.header. - */ -static void brw_ff_gs_overwrite_header_dw2_from_r0(struct brw_ff_gs_compile *c) -{ - struct brw_codegen *p = &c->func; - brw_AND(p, get_element_ud(c->reg.header, 2), get_element_ud(c->reg.R0, 2), - brw_imm_ud(0x1f)); - brw_SHL(p, get_element_ud(c->reg.header, 2), - get_element_ud(c->reg.header, 2), brw_imm_ud(2)); -} - -/** - * Apply an additive offset to DWORD 2 of c->reg.header. - * - * This is used to set/unset the "PrimStart" and "PrimEnd" flags appropriately - * for each vertex. - */ -static void brw_ff_gs_offset_header_dw2(struct brw_ff_gs_compile *c, - int offset) -{ - struct brw_codegen *p = &c->func; - brw_ADD(p, get_element_d(c->reg.header, 2), get_element_d(c->reg.header, 2), - brw_imm_d(offset)); -} - - -/** - * Emit a vertex using the URB_WRITE message. Use the contents of - * c->reg.header for the message header, and the registers starting at \c vert - * for the vertex data. - * - * If \c last is true, then this is the last vertex, so no further URB space - * should be allocated, and this message should end the thread. - * - * If \c last is false, then a new URB entry will be allocated, and its handle - * will be stored in DWORD 0 of c->reg.header for use in the next URB_WRITE - * message. - */ -static void brw_ff_gs_emit_vue(struct brw_ff_gs_compile *c, - struct brw_reg vert, - bool last) -{ - struct brw_codegen *p = &c->func; - int write_offset = 0; - bool complete = false; - - do { - /* We can't write more than 14 registers at a time to the URB */ - int write_len = MIN2(c->nr_regs - write_offset, 14); - if (write_len == c->nr_regs - write_offset) - complete = true; - - /* Copy the vertex from vertn into m1..mN+1: - */ - brw_copy8(p, brw_message_reg(1), offset(vert, write_offset), write_len); - - /* Send the vertex data to the URB. If this is the last write for this - * vertex, then we mark it as complete, and either end the thread or - * allocate another vertex URB entry (depending whether this is the last - * vertex). - */ - enum brw_urb_write_flags flags; - if (!complete) - flags = BRW_URB_WRITE_NO_FLAGS; - else if (last) - flags = BRW_URB_WRITE_EOT_COMPLETE; - else - flags = BRW_URB_WRITE_ALLOCATE_COMPLETE; - brw_urb_WRITE(p, - (flags & BRW_URB_WRITE_ALLOCATE) ? c->reg.temp - : retype(brw_null_reg(), BRW_REGISTER_TYPE_UD), - 0, - c->reg.header, - flags, - write_len + 1, /* msg length */ - (flags & BRW_URB_WRITE_ALLOCATE) ? 1 - : 0, /* response length */ - write_offset, /* urb offset */ - BRW_URB_SWIZZLE_NONE); - write_offset += write_len; - } while (!complete); - - if (!last) { - brw_MOV(p, get_element_ud(c->reg.header, 0), - get_element_ud(c->reg.temp, 0)); - } -} - -/** - * Send an FF_SYNC message to ensure that all previously spawned GS threads - * have finished sending primitives down the pipeline, and to allocate a URB - * entry for the first output vertex. Only needed on Ironlake+. - * - * This function modifies c->reg.header: in DWORD 1, it stores num_prim (which - * is needed by the FF_SYNC message), and in DWORD 0, it stores the handle to - * the allocated URB entry (which will be needed by the URB_WRITE meesage that - * follows). - */ -static void brw_ff_gs_ff_sync(struct brw_ff_gs_compile *c, int num_prim) -{ - struct brw_codegen *p = &c->func; - - brw_MOV(p, get_element_ud(c->reg.header, 1), brw_imm_ud(num_prim)); - brw_ff_sync(p, - c->reg.temp, - 0, - c->reg.header, - 1, /* allocate */ - 1, /* response length */ - 0 /* eot */); - brw_MOV(p, get_element_ud(c->reg.header, 0), - get_element_ud(c->reg.temp, 0)); -} - - -static void -brw_ff_gs_quads(struct brw_ff_gs_compile *c, - const struct brw_ff_gs_prog_key *key) -{ - brw_ff_gs_alloc_regs(c, 4, false); - brw_ff_gs_initialize_header(c); - /* Use polygons for correct edgeflag behaviour. Note that vertex 3 - * is the PV for quads, but vertex 0 for polygons: - */ - if (c->func.devinfo->ver == 5) - brw_ff_gs_ff_sync(c, 1); - brw_ff_gs_overwrite_header_dw2( - c, ((_3DPRIM_POLYGON << URB_WRITE_PRIM_TYPE_SHIFT) - | URB_WRITE_PRIM_START)); - if (key->pv_first) { - brw_ff_gs_emit_vue(c, c->reg.vertex[0], 0); - brw_ff_gs_overwrite_header_dw2( - c, _3DPRIM_POLYGON << URB_WRITE_PRIM_TYPE_SHIFT); - brw_ff_gs_emit_vue(c, c->reg.vertex[1], 0); - brw_ff_gs_emit_vue(c, c->reg.vertex[2], 0); - brw_ff_gs_overwrite_header_dw2( - c, ((_3DPRIM_POLYGON << URB_WRITE_PRIM_TYPE_SHIFT) - | URB_WRITE_PRIM_END)); - brw_ff_gs_emit_vue(c, c->reg.vertex[3], 1); - } - else { - brw_ff_gs_emit_vue(c, c->reg.vertex[3], 0); - brw_ff_gs_overwrite_header_dw2( - c, _3DPRIM_POLYGON << URB_WRITE_PRIM_TYPE_SHIFT); - brw_ff_gs_emit_vue(c, c->reg.vertex[0], 0); - brw_ff_gs_emit_vue(c, c->reg.vertex[1], 0); - brw_ff_gs_overwrite_header_dw2( - c, ((_3DPRIM_POLYGON << URB_WRITE_PRIM_TYPE_SHIFT) - | URB_WRITE_PRIM_END)); - brw_ff_gs_emit_vue(c, c->reg.vertex[2], 1); - } -} - -static void -brw_ff_gs_quad_strip(struct brw_ff_gs_compile *c, - const struct brw_ff_gs_prog_key *key) -{ - brw_ff_gs_alloc_regs(c, 4, false); - brw_ff_gs_initialize_header(c); - - if (c->func.devinfo->ver == 5) - brw_ff_gs_ff_sync(c, 1); - brw_ff_gs_overwrite_header_dw2( - c, ((_3DPRIM_POLYGON << URB_WRITE_PRIM_TYPE_SHIFT) - | URB_WRITE_PRIM_START)); - if (key->pv_first) { - brw_ff_gs_emit_vue(c, c->reg.vertex[0], 0); - brw_ff_gs_overwrite_header_dw2( - c, _3DPRIM_POLYGON << URB_WRITE_PRIM_TYPE_SHIFT); - brw_ff_gs_emit_vue(c, c->reg.vertex[1], 0); - brw_ff_gs_emit_vue(c, c->reg.vertex[2], 0); - brw_ff_gs_overwrite_header_dw2( - c, ((_3DPRIM_POLYGON << URB_WRITE_PRIM_TYPE_SHIFT) - | URB_WRITE_PRIM_END)); - brw_ff_gs_emit_vue(c, c->reg.vertex[3], 1); - } - else { - brw_ff_gs_emit_vue(c, c->reg.vertex[2], 0); - brw_ff_gs_overwrite_header_dw2( - c, _3DPRIM_POLYGON << URB_WRITE_PRIM_TYPE_SHIFT); - brw_ff_gs_emit_vue(c, c->reg.vertex[3], 0); - brw_ff_gs_emit_vue(c, c->reg.vertex[0], 0); - brw_ff_gs_overwrite_header_dw2( - c, ((_3DPRIM_POLYGON << URB_WRITE_PRIM_TYPE_SHIFT) - | URB_WRITE_PRIM_END)); - brw_ff_gs_emit_vue(c, c->reg.vertex[1], 1); - } -} - -static void brw_ff_gs_lines(struct brw_ff_gs_compile *c) -{ - brw_ff_gs_alloc_regs(c, 2, false); - brw_ff_gs_initialize_header(c); - - if (c->func.devinfo->ver == 5) - brw_ff_gs_ff_sync(c, 1); - brw_ff_gs_overwrite_header_dw2( - c, ((_3DPRIM_LINESTRIP << URB_WRITE_PRIM_TYPE_SHIFT) - | URB_WRITE_PRIM_START)); - brw_ff_gs_emit_vue(c, c->reg.vertex[0], 0); - brw_ff_gs_overwrite_header_dw2( - c, ((_3DPRIM_LINESTRIP << URB_WRITE_PRIM_TYPE_SHIFT) - | URB_WRITE_PRIM_END)); - brw_ff_gs_emit_vue(c, c->reg.vertex[1], 1); -} - -/** - * Generate the geometry shader program used on Gen6 to perform stream output - * (transform feedback). - */ -static void -gfx6_sol_program(struct brw_ff_gs_compile *c, const struct brw_ff_gs_prog_key *key, - unsigned num_verts, bool check_edge_flags) -{ - struct brw_codegen *p = &c->func; - brw_inst *inst; - c->prog_data->svbi_postincrement_value = num_verts; - - brw_ff_gs_alloc_regs(c, num_verts, true); - brw_ff_gs_initialize_header(c); - - if (key->num_transform_feedback_bindings > 0) { - unsigned vertex, binding; - struct brw_reg destination_indices_uw = - vec8(retype(c->reg.destination_indices, BRW_REGISTER_TYPE_UW)); - - /* Note: since we use the binding table to keep track of buffer offsets - * and stride, the GS doesn't need to keep track of a separate pointer - * into each buffer; it uses a single pointer which increments by 1 for - * each vertex. So we use SVBI0 for this pointer, regardless of whether - * transform feedback is in interleaved or separate attribs mode. - * - * Make sure that the buffers have enough room for all the vertices. - */ - brw_ADD(p, get_element_ud(c->reg.temp, 0), - get_element_ud(c->reg.SVBI, 0), brw_imm_ud(num_verts)); - brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_LE, - get_element_ud(c->reg.temp, 0), - get_element_ud(c->reg.SVBI, 4)); - brw_IF(p, BRW_EXECUTE_1); - - /* Compute the destination indices to write to. Usually we use SVBI[0] - * + (0, 1, 2). However, for odd-numbered triangles in tristrips, the - * vertices come down the pipeline in reversed winding order, so we need - * to flip the order when writing to the transform feedback buffer. To - * ensure that flatshading accuracy is preserved, we need to write them - * in order SVBI[0] + (0, 2, 1) if we're using the first provoking - * vertex convention, and in order SVBI[0] + (1, 0, 2) if we're using - * the last provoking vertex convention. - * - * Note: since brw_imm_v can only be used in instructions in - * packed-word execution mode, and SVBI is a double-word, we need to - * first move the appropriate immediate constant ((0, 1, 2), (0, 2, 1), - * or (1, 0, 2)) to the destination_indices register, and then add SVBI - * using a separate instruction. Also, since the immediate constant is - * expressed as packed words, and we need to load double-words into - * destination_indices, we need to intersperse zeros to fill the upper - * halves of each double-word. - */ - brw_MOV(p, destination_indices_uw, - brw_imm_v(0x00020100)); /* (0, 1, 2) */ - if (num_verts == 3) { - /* Get primitive type into temp register. */ - brw_AND(p, get_element_ud(c->reg.temp, 0), - get_element_ud(c->reg.R0, 2), brw_imm_ud(0x1f)); - - /* Test if primitive type is TRISTRIP_REVERSE. We need to do this as - * an 8-wide comparison so that the conditional MOV that follows - * moves all 8 words correctly. - */ - brw_CMP(p, vec8(brw_null_reg()), BRW_CONDITIONAL_EQ, - get_element_ud(c->reg.temp, 0), - brw_imm_ud(_3DPRIM_TRISTRIP_REVERSE)); - - /* If so, then overwrite destination_indices_uw with the appropriate - * reordering. - */ - inst = brw_MOV(p, destination_indices_uw, - brw_imm_v(key->pv_first ? 0x00010200 /* (0, 2, 1) */ - : 0x00020001)); /* (1, 0, 2) */ - brw_inst_set_pred_control(p->devinfo, inst, BRW_PREDICATE_NORMAL); - } - - assert(c->reg.destination_indices.width == BRW_EXECUTE_4); - brw_push_insn_state(p); - brw_set_default_exec_size(p, BRW_EXECUTE_4); - brw_ADD(p, c->reg.destination_indices, - c->reg.destination_indices, get_element_ud(c->reg.SVBI, 0)); - brw_pop_insn_state(p); - /* For each vertex, generate code to output each varying using the - * appropriate binding table entry. - */ - for (vertex = 0; vertex < num_verts; ++vertex) { - /* Set up the correct destination index for this vertex */ - brw_MOV(p, get_element_ud(c->reg.header, 5), - get_element_ud(c->reg.destination_indices, vertex)); - - for (binding = 0; binding < key->num_transform_feedback_bindings; - ++binding) { - unsigned char varying = - key->transform_feedback_bindings[binding]; - unsigned char slot = c->vue_map.varying_to_slot[varying]; - /* From the Sandybridge PRM, Volume 2, Part 1, Section 4.5.1: - * - * "Prior to End of Thread with a URB_WRITE, the kernel must - * ensure that all writes are complete by sending the final - * write as a committed write." - */ - bool final_write = - binding == key->num_transform_feedback_bindings - 1 && - vertex == num_verts - 1; - struct brw_reg vertex_slot = c->reg.vertex[vertex]; - vertex_slot.nr += slot / 2; - vertex_slot.subnr = (slot % 2) * 16; - /* gl_PointSize is stored in VARYING_SLOT_PSIZ.w. */ - vertex_slot.swizzle = varying == VARYING_SLOT_PSIZ - ? BRW_SWIZZLE_WWWW : key->transform_feedback_swizzles[binding]; - brw_set_default_access_mode(p, BRW_ALIGN_16); - brw_push_insn_state(p); - brw_set_default_exec_size(p, BRW_EXECUTE_4); - - brw_MOV(p, stride(c->reg.header, 4, 4, 1), - retype(vertex_slot, BRW_REGISTER_TYPE_UD)); - brw_pop_insn_state(p); - - brw_set_default_access_mode(p, BRW_ALIGN_1); - brw_svb_write(p, - final_write ? c->reg.temp : brw_null_reg(), /* dest */ - 1, /* msg_reg_nr */ - c->reg.header, /* src0 */ - BRW_GFX6_SOL_BINDING_START + binding, /* binding_table_index */ - final_write); /* send_commit_msg */ - } - } - brw_ENDIF(p); - - /* Now, reinitialize the header register from R0 to restore the parts of - * the register that we overwrote while streaming out transform feedback - * data. - */ - brw_ff_gs_initialize_header(c); - - /* Finally, wait for the write commit to occur so that we can proceed to - * other things safely. - * - * From the Sandybridge PRM, Volume 4, Part 1, Section 3.3: - * - * The write commit does not modify the destination register, but - * merely clears the dependency associated with the destination - * register. Thus, a simple “mov” instruction using the register as a - * source is sufficient to wait for the write commit to occur. - */ - brw_MOV(p, c->reg.temp, c->reg.temp); - } - - brw_ff_gs_ff_sync(c, 1); - - brw_ff_gs_overwrite_header_dw2_from_r0(c); - switch (num_verts) { - case 1: - brw_ff_gs_offset_header_dw2(c, - URB_WRITE_PRIM_START | URB_WRITE_PRIM_END); - brw_ff_gs_emit_vue(c, c->reg.vertex[0], true); - break; - case 2: - brw_ff_gs_offset_header_dw2(c, URB_WRITE_PRIM_START); - brw_ff_gs_emit_vue(c, c->reg.vertex[0], false); - brw_ff_gs_offset_header_dw2(c, - URB_WRITE_PRIM_END - URB_WRITE_PRIM_START); - brw_ff_gs_emit_vue(c, c->reg.vertex[1], true); - break; - case 3: - if (check_edge_flags) { - /* Only emit vertices 0 and 1 if this is the first triangle of the - * polygon. Otherwise they are redundant. - */ - brw_AND(p, retype(brw_null_reg(), BRW_REGISTER_TYPE_UD), - get_element_ud(c->reg.R0, 2), - brw_imm_ud(BRW_GS_EDGE_INDICATOR_0)); - brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ); - brw_IF(p, BRW_EXECUTE_1); - } - brw_ff_gs_offset_header_dw2(c, URB_WRITE_PRIM_START); - brw_ff_gs_emit_vue(c, c->reg.vertex[0], false); - brw_ff_gs_offset_header_dw2(c, -URB_WRITE_PRIM_START); - brw_ff_gs_emit_vue(c, c->reg.vertex[1], false); - if (check_edge_flags) { - brw_ENDIF(p); - /* Only emit vertex 2 in PRIM_END mode if this is the last triangle - * of the polygon. Otherwise leave the primitive incomplete because - * there are more polygon vertices coming. - */ - brw_AND(p, retype(brw_null_reg(), BRW_REGISTER_TYPE_UD), - get_element_ud(c->reg.R0, 2), - brw_imm_ud(BRW_GS_EDGE_INDICATOR_1)); - brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ); - brw_set_default_predicate_control(p, BRW_PREDICATE_NORMAL); - } - brw_ff_gs_offset_header_dw2(c, URB_WRITE_PRIM_END); - brw_set_default_predicate_control(p, BRW_PREDICATE_NONE); - brw_ff_gs_emit_vue(c, c->reg.vertex[2], true); - break; - } -} - -const unsigned * -brw_compile_ff_gs_prog(struct brw_compiler *compiler, - void *mem_ctx, - const struct brw_ff_gs_prog_key *key, - struct brw_ff_gs_prog_data *prog_data, - struct intel_vue_map *vue_map, - unsigned *final_assembly_size) -{ - struct brw_ff_gs_compile c; - const GLuint *program; - - memset(&c, 0, sizeof(c)); - - c.key = *key; - c.vue_map = *vue_map; - c.nr_regs = (c.vue_map.num_slots + 1)/2; - c.prog_data = prog_data; - - mem_ctx = ralloc_context(NULL); - - /* Begin the compilation: - */ - brw_init_codegen(&compiler->isa, &c.func, mem_ctx); - - c.func.single_program_flow = 1; - - /* For some reason the thread is spawned with only 4 channels - * unmasked. - */ - brw_set_default_mask_control(&c.func, BRW_MASK_DISABLE); - - if (compiler->devinfo->ver >= 6) { - unsigned num_verts; - bool check_edge_flag; - /* On Sandybridge, we use the GS for implementing transform feedback - * (called "Stream Out" in the PRM). - */ - switch (key->primitive) { - case _3DPRIM_POINTLIST: - num_verts = 1; - check_edge_flag = false; - break; - case _3DPRIM_LINELIST: - case _3DPRIM_LINESTRIP: - case _3DPRIM_LINELOOP: - num_verts = 2; - check_edge_flag = false; - break; - case _3DPRIM_TRILIST: - case _3DPRIM_TRIFAN: - case _3DPRIM_TRISTRIP: - case _3DPRIM_RECTLIST: - num_verts = 3; - check_edge_flag = false; - break; - case _3DPRIM_QUADLIST: - case _3DPRIM_QUADSTRIP: - case _3DPRIM_POLYGON: - num_verts = 3; - check_edge_flag = true; - break; - default: - unreachable("Unexpected primitive type in Gen6 SOL program."); - } - gfx6_sol_program(&c, key, num_verts, check_edge_flag); - } else { - /* On Gen4-5, we use the GS to decompose certain types of primitives. - * Note that primitives which don't require a GS program have already - * been weeded out by now. - */ - switch (key->primitive) { - case _3DPRIM_QUADLIST: - brw_ff_gs_quads( &c, key ); - break; - case _3DPRIM_QUADSTRIP: - brw_ff_gs_quad_strip( &c, key ); - break; - case _3DPRIM_LINELOOP: - brw_ff_gs_lines( &c ); - break; - default: - return NULL; - } - } - - brw_compact_instructions(&c.func, 0, NULL); - - /* get the program - */ - program = brw_get_program(&c.func, final_assembly_size); - - if (INTEL_DEBUG(DEBUG_GS)) { - fprintf(stderr, "gs:\n"); - brw_disassemble_with_labels(&compiler->isa, c.func.store, - 0, *final_assembly_size, stderr); - fprintf(stderr, "\n"); - } - - return program; -} - diff --git a/src/intel/compiler/brw_compile_sf.c b/src/intel/compiler/brw_compile_sf.c deleted file mode 100644 index f9f23e3d2c9..00000000000 --- a/src/intel/compiler/brw_compile_sf.c +++ /dev/null @@ -1,881 +0,0 @@ -/* - * Copyright © 2006 - 2017 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "brw_compiler.h" -#include "brw_disasm.h" -#include "brw_eu.h" -#include "brw_prim.h" - -#include "dev/intel_debug.h" - -struct brw_sf_compile { - struct brw_codegen func; - struct brw_sf_prog_key key; - struct brw_sf_prog_data prog_data; - - struct brw_reg pv; - struct brw_reg det; - struct brw_reg dx0; - struct brw_reg dx2; - struct brw_reg dy0; - struct brw_reg dy2; - - /* z and 1/w passed in separately: - */ - struct brw_reg z[3]; - struct brw_reg inv_w[3]; - - /* The vertices: - */ - struct brw_reg vert[3]; - - /* Temporaries, allocated after last vertex reg. - */ - struct brw_reg inv_det; - struct brw_reg a1_sub_a0; - struct brw_reg a2_sub_a0; - struct brw_reg tmp; - - struct brw_reg m1Cx; - struct brw_reg m2Cy; - struct brw_reg m3C0; - - GLuint nr_verts; - GLuint nr_attr_regs; - GLuint nr_setup_regs; - int urb_entry_read_offset; - - /** The last known value of the f0.0 flag register. */ - unsigned flag_value; - - struct intel_vue_map vue_map; -}; - -/** - * Determine the vue slot corresponding to the given half of the given register. - */ -static inline int vert_reg_to_vue_slot(struct brw_sf_compile *c, GLuint reg, - int half) -{ - return (reg + c->urb_entry_read_offset) * 2 + half; -} - -/** - * Determine the varying corresponding to the given half of the given - * register. half=0 means the first half of a register, half=1 means the - * second half. - */ -static inline int vert_reg_to_varying(struct brw_sf_compile *c, GLuint reg, - int half) -{ - int vue_slot = vert_reg_to_vue_slot(c, reg, half); - return c->vue_map.slot_to_varying[vue_slot]; -} - -/** - * Determine the register corresponding to the given vue slot - */ -static struct brw_reg get_vue_slot(struct brw_sf_compile *c, - struct brw_reg vert, - int vue_slot) -{ - GLuint off = vue_slot / 2 - c->urb_entry_read_offset; - GLuint sub = vue_slot % 2; - - return brw_vec4_grf(vert.nr + off, sub * 4); -} - -/** - * Determine the register corresponding to the given varying. - */ -static struct brw_reg get_varying(struct brw_sf_compile *c, - struct brw_reg vert, - GLuint varying) -{ - int vue_slot = c->vue_map.varying_to_slot[varying]; - assert (vue_slot >= c->urb_entry_read_offset); - return get_vue_slot(c, vert, vue_slot); -} - -static bool -have_attr(struct brw_sf_compile *c, GLuint attr) -{ - return (c->key.attrs & BITFIELD64_BIT(attr)) ? 1 : 0; -} - -/*********************************************************************** - * Twoside lighting - */ -static void copy_bfc( struct brw_sf_compile *c, - struct brw_reg vert ) -{ - struct brw_codegen *p = &c->func; - GLuint i; - - for (i = 0; i < 2; i++) { - if (have_attr(c, VARYING_SLOT_COL0+i) && - have_attr(c, VARYING_SLOT_BFC0+i)) - brw_MOV(p, - get_varying(c, vert, VARYING_SLOT_COL0+i), - get_varying(c, vert, VARYING_SLOT_BFC0+i)); - } -} - - -static void do_twoside_color( struct brw_sf_compile *c ) -{ - struct brw_codegen *p = &c->func; - GLuint backface_conditional = c->key.frontface_ccw ? BRW_CONDITIONAL_G : BRW_CONDITIONAL_L; - - /* Already done in clip program: - */ - if (c->key.primitive == BRW_SF_PRIM_UNFILLED_TRIS) - return; - - /* If the vertex shader provides backface color, do the selection. The VS - * promises to set up the front color if the backface color is provided, but - * it may contain junk if never written to. - */ - if (!(have_attr(c, VARYING_SLOT_COL0) && have_attr(c, VARYING_SLOT_BFC0)) && - !(have_attr(c, VARYING_SLOT_COL1) && have_attr(c, VARYING_SLOT_BFC1))) - return; - - /* Need to use BRW_EXECUTE_4 and also do an 4-wide compare in order - * to get all channels active inside the IF. In the clipping code - * we run with NoMask, so it's not an option and we can use - * BRW_EXECUTE_1 for all comparisons. - */ - brw_CMP(p, vec4(brw_null_reg()), backface_conditional, c->det, brw_imm_f(0)); - brw_IF(p, BRW_EXECUTE_4); - { - switch (c->nr_verts) { - case 3: copy_bfc(c, c->vert[2]); FALLTHROUGH; - case 2: copy_bfc(c, c->vert[1]); FALLTHROUGH; - case 1: copy_bfc(c, c->vert[0]); - } - } - brw_ENDIF(p); -} - - - -/*********************************************************************** - * Flat shading - */ - -static void copy_flatshaded_attributes(struct brw_sf_compile *c, - struct brw_reg dst, - struct brw_reg src) -{ - struct brw_codegen *p = &c->func; - int i; - - for (i = 0; i < c->vue_map.num_slots; i++) { - if (c->key.interp_mode[i] == INTERP_MODE_FLAT) { - brw_MOV(p, - get_vue_slot(c, dst, i), - get_vue_slot(c, src, i)); - } - } -} - -static int count_flatshaded_attributes(struct brw_sf_compile *c) -{ - int i; - int count = 0; - - for (i = 0; i < c->vue_map.num_slots; i++) - if (c->key.interp_mode[i] == INTERP_MODE_FLAT) - count++; - - return count; -} - - - -/* Need to use a computed jump to copy flatshaded attributes as the - * vertices are ordered according to y-coordinate before reaching this - * point, so the PV could be anywhere. - */ -static void do_flatshade_triangle( struct brw_sf_compile *c ) -{ - struct brw_codegen *p = &c->func; - GLuint nr; - GLuint jmpi = 1; - - /* Already done in clip program: - */ - if (c->key.primitive == BRW_SF_PRIM_UNFILLED_TRIS) - return; - - if (p->devinfo->ver == 5) - jmpi = 2; - - nr = count_flatshaded_attributes(c); - - brw_MUL(p, c->pv, c->pv, brw_imm_d(jmpi*(nr*2+1))); - brw_JMPI(p, c->pv, BRW_PREDICATE_NONE); - - copy_flatshaded_attributes(c, c->vert[1], c->vert[0]); - copy_flatshaded_attributes(c, c->vert[2], c->vert[0]); - brw_JMPI(p, brw_imm_d(jmpi*(nr*4+1)), BRW_PREDICATE_NONE); - - copy_flatshaded_attributes(c, c->vert[0], c->vert[1]); - copy_flatshaded_attributes(c, c->vert[2], c->vert[1]); - brw_JMPI(p, brw_imm_d(jmpi*nr*2), BRW_PREDICATE_NONE); - - copy_flatshaded_attributes(c, c->vert[0], c->vert[2]); - copy_flatshaded_attributes(c, c->vert[1], c->vert[2]); -} - - -static void do_flatshade_line( struct brw_sf_compile *c ) -{ - struct brw_codegen *p = &c->func; - GLuint nr; - GLuint jmpi = 1; - - /* Already done in clip program: - */ - if (c->key.primitive == BRW_SF_PRIM_UNFILLED_TRIS) - return; - - if (p->devinfo->ver == 5) - jmpi = 2; - - nr = count_flatshaded_attributes(c); - - brw_MUL(p, c->pv, c->pv, brw_imm_d(jmpi*(nr+1))); - brw_JMPI(p, c->pv, BRW_PREDICATE_NONE); - copy_flatshaded_attributes(c, c->vert[1], c->vert[0]); - - brw_JMPI(p, brw_imm_ud(jmpi*nr), BRW_PREDICATE_NONE); - copy_flatshaded_attributes(c, c->vert[0], c->vert[1]); -} - - -/*********************************************************************** - * Triangle setup. - */ - - -static void alloc_regs( struct brw_sf_compile *c ) -{ - GLuint reg, i; - - /* Values computed by fixed function unit: - */ - c->pv = retype(brw_vec1_grf(1, 1), BRW_REGISTER_TYPE_D); - c->det = brw_vec1_grf(1, 2); - c->dx0 = brw_vec1_grf(1, 3); - c->dx2 = brw_vec1_grf(1, 4); - c->dy0 = brw_vec1_grf(1, 5); - c->dy2 = brw_vec1_grf(1, 6); - - /* z and 1/w passed in separately: - */ - c->z[0] = brw_vec1_grf(2, 0); - c->inv_w[0] = brw_vec1_grf(2, 1); - c->z[1] = brw_vec1_grf(2, 2); - c->inv_w[1] = brw_vec1_grf(2, 3); - c->z[2] = brw_vec1_grf(2, 4); - c->inv_w[2] = brw_vec1_grf(2, 5); - - /* The vertices: - */ - reg = 3; - for (i = 0; i < c->nr_verts; i++) { - c->vert[i] = brw_vec8_grf(reg, 0); - reg += c->nr_attr_regs; - } - - /* Temporaries, allocated after last vertex reg. - */ - c->inv_det = brw_vec1_grf(reg, 0); reg++; - c->a1_sub_a0 = brw_vec8_grf(reg, 0); reg++; - c->a2_sub_a0 = brw_vec8_grf(reg, 0); reg++; - c->tmp = brw_vec8_grf(reg, 0); reg++; - - /* Note grf allocation: - */ - c->prog_data.total_grf = reg; - - - /* Outputs of this program - interpolation coefficients for - * rasterization: - */ - c->m1Cx = brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, 1, 0); - c->m2Cy = brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, 2, 0); - c->m3C0 = brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, 3, 0); -} - - -static void copy_z_inv_w( struct brw_sf_compile *c ) -{ - struct brw_codegen *p = &c->func; - GLuint i; - - /* Copy both scalars with a single MOV: - */ - for (i = 0; i < c->nr_verts; i++) - brw_MOV(p, vec2(suboffset(c->vert[i], 2)), vec2(c->z[i])); -} - - -static void invert_det( struct brw_sf_compile *c) -{ - /* Looks like we invert all 8 elements just to get 1/det in - * position 2 !?! - */ - gfx4_math(&c->func, - c->inv_det, - BRW_MATH_FUNCTION_INV, - 0, - c->det, - BRW_MATH_PRECISION_FULL); - -} - - -static bool -calculate_masks(struct brw_sf_compile *c, - GLuint reg, - GLushort *pc, - GLushort *pc_persp, - GLushort *pc_linear) -{ - bool is_last_attr = (reg == c->nr_setup_regs - 1); - enum glsl_interp_mode interp; - - *pc_persp = 0; - *pc_linear = 0; - *pc = 0xf; - - interp = c->key.interp_mode[vert_reg_to_vue_slot(c, reg, 0)]; - if (interp == INTERP_MODE_SMOOTH) { - *pc_linear = 0xf; - *pc_persp = 0xf; - } else if (interp == INTERP_MODE_NOPERSPECTIVE) - *pc_linear = 0xf; - - /* Maybe only process one attribute on the final round: - */ - if (vert_reg_to_varying(c, reg, 1) != BRW_VARYING_SLOT_COUNT) { - *pc |= 0xf0; - - interp = c->key.interp_mode[vert_reg_to_vue_slot(c, reg, 1)]; - if (interp == INTERP_MODE_SMOOTH) { - *pc_linear |= 0xf0; - *pc_persp |= 0xf0; - } else if (interp == INTERP_MODE_NOPERSPECTIVE) - *pc_linear |= 0xf0; - } - - return is_last_attr; -} - -/* Calculates the predicate control for which channels of a reg - * (containing 2 attrs) to do point sprite coordinate replacement on. - */ -static uint16_t -calculate_point_sprite_mask(struct brw_sf_compile *c, GLuint reg) -{ - int varying1, varying2; - uint16_t pc = 0; - - varying1 = vert_reg_to_varying(c, reg, 0); - if (varying1 >= VARYING_SLOT_TEX0 && varying1 <= VARYING_SLOT_TEX7) { - if (c->key.point_sprite_coord_replace & (1 << (varying1 - VARYING_SLOT_TEX0))) - pc |= 0x0f; - } - if (varying1 == BRW_VARYING_SLOT_PNTC) - pc |= 0x0f; - - varying2 = vert_reg_to_varying(c, reg, 1); - if (varying2 >= VARYING_SLOT_TEX0 && varying2 <= VARYING_SLOT_TEX7) { - if (c->key.point_sprite_coord_replace & (1 << (varying2 - - VARYING_SLOT_TEX0))) - pc |= 0xf0; - } - if (varying2 == BRW_VARYING_SLOT_PNTC) - pc |= 0xf0; - - return pc; -} - -static void -set_predicate_control_flag_value(struct brw_codegen *p, - struct brw_sf_compile *c, - unsigned value) -{ - brw_set_default_predicate_control(p, BRW_PREDICATE_NONE); - - if (value != 0xff) { - if (value != c->flag_value) { - brw_MOV(p, brw_flag_reg(0, 0), brw_imm_uw(value)); - c->flag_value = value; - } - - brw_set_default_predicate_control(p, BRW_PREDICATE_NORMAL); - } -} - -static void brw_emit_tri_setup(struct brw_sf_compile *c, bool allocate) -{ - struct brw_codegen *p = &c->func; - GLuint i; - - c->flag_value = 0xff; - c->nr_verts = 3; - - if (allocate) - alloc_regs(c); - - invert_det(c); - copy_z_inv_w(c); - - if (c->key.do_twoside_color) - do_twoside_color(c); - - if (c->key.contains_flat_varying) - do_flatshade_triangle(c); - - - for (i = 0; i < c->nr_setup_regs; i++) - { - /* Pair of incoming attributes: - */ - struct brw_reg a0 = offset(c->vert[0], i); - struct brw_reg a1 = offset(c->vert[1], i); - struct brw_reg a2 = offset(c->vert[2], i); - GLushort pc, pc_persp, pc_linear; - bool last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear); - - if (pc_persp) - { - set_predicate_control_flag_value(p, c, pc_persp); - brw_MUL(p, a0, a0, c->inv_w[0]); - brw_MUL(p, a1, a1, c->inv_w[1]); - brw_MUL(p, a2, a2, c->inv_w[2]); - } - - - /* Calculate coefficients for interpolated values: - */ - if (pc_linear) - { - set_predicate_control_flag_value(p, c, pc_linear); - - brw_ADD(p, c->a1_sub_a0, a1, negate(a0)); - brw_ADD(p, c->a2_sub_a0, a2, negate(a0)); - - /* calculate dA/dx - */ - brw_MUL(p, brw_null_reg(), c->a1_sub_a0, c->dy2); - brw_MAC(p, c->tmp, c->a2_sub_a0, negate(c->dy0)); - brw_MUL(p, c->m1Cx, c->tmp, c->inv_det); - - /* calculate dA/dy - */ - brw_MUL(p, brw_null_reg(), c->a2_sub_a0, c->dx0); - brw_MAC(p, c->tmp, c->a1_sub_a0, negate(c->dx2)); - brw_MUL(p, c->m2Cy, c->tmp, c->inv_det); - } - - { - set_predicate_control_flag_value(p, c, pc); - /* start point for interpolation - */ - brw_MOV(p, c->m3C0, a0); - - /* Copy m0..m3 to URB. m0 is implicitly copied from r0 in - * the send instruction: - */ - brw_urb_WRITE(p, - brw_null_reg(), - 0, - brw_vec8_grf(0, 0), /* r0, will be copied to m0 */ - last ? BRW_URB_WRITE_EOT_COMPLETE - : BRW_URB_WRITE_NO_FLAGS, - 4, /* msg len */ - 0, /* response len */ - i*4, /* offset */ - BRW_URB_SWIZZLE_TRANSPOSE); /* XXX: Swizzle control "SF to windower" */ - } - } - - brw_set_default_predicate_control(p, BRW_PREDICATE_NONE); -} - - - -static void brw_emit_line_setup(struct brw_sf_compile *c, bool allocate) -{ - struct brw_codegen *p = &c->func; - GLuint i; - - c->flag_value = 0xff; - c->nr_verts = 2; - - if (allocate) - alloc_regs(c); - - invert_det(c); - copy_z_inv_w(c); - - if (c->key.contains_flat_varying) - do_flatshade_line(c); - - for (i = 0; i < c->nr_setup_regs; i++) - { - /* Pair of incoming attributes: - */ - struct brw_reg a0 = offset(c->vert[0], i); - struct brw_reg a1 = offset(c->vert[1], i); - GLushort pc, pc_persp, pc_linear; - bool last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear); - - if (pc_persp) - { - set_predicate_control_flag_value(p, c, pc_persp); - brw_MUL(p, a0, a0, c->inv_w[0]); - brw_MUL(p, a1, a1, c->inv_w[1]); - } - - /* Calculate coefficients for position, color: - */ - if (pc_linear) { - set_predicate_control_flag_value(p, c, pc_linear); - - brw_ADD(p, c->a1_sub_a0, a1, negate(a0)); - - brw_MUL(p, c->tmp, c->a1_sub_a0, c->dx0); - brw_MUL(p, c->m1Cx, c->tmp, c->inv_det); - - brw_MUL(p, c->tmp, c->a1_sub_a0, c->dy0); - brw_MUL(p, c->m2Cy, c->tmp, c->inv_det); - } - - { - set_predicate_control_flag_value(p, c, pc); - - /* start point for interpolation - */ - brw_MOV(p, c->m3C0, a0); - - /* Copy m0..m3 to URB. - */ - brw_urb_WRITE(p, - brw_null_reg(), - 0, - brw_vec8_grf(0, 0), - last ? BRW_URB_WRITE_EOT_COMPLETE - : BRW_URB_WRITE_NO_FLAGS, - 4, /* msg len */ - 0, /* response len */ - i*4, /* urb destination offset */ - BRW_URB_SWIZZLE_TRANSPOSE); - } - } - - brw_set_default_predicate_control(p, BRW_PREDICATE_NONE); -} - -static void brw_emit_point_sprite_setup(struct brw_sf_compile *c, bool allocate) -{ - struct brw_codegen *p = &c->func; - GLuint i; - - c->flag_value = 0xff; - c->nr_verts = 1; - - if (allocate) - alloc_regs(c); - - copy_z_inv_w(c); - for (i = 0; i < c->nr_setup_regs; i++) - { - struct brw_reg a0 = offset(c->vert[0], i); - GLushort pc, pc_persp, pc_linear, pc_coord_replace; - bool last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear); - - pc_coord_replace = calculate_point_sprite_mask(c, i); - pc_persp &= ~pc_coord_replace; - - if (pc_persp) { - set_predicate_control_flag_value(p, c, pc_persp); - brw_MUL(p, a0, a0, c->inv_w[0]); - } - - /* Point sprite coordinate replacement: A texcoord with this - * enabled gets replaced with the value (x, y, 0, 1) where x and - * y vary from 0 to 1 across the horizontal and vertical of the - * point. - */ - if (pc_coord_replace) { - set_predicate_control_flag_value(p, c, pc_coord_replace); - /* Calculate 1.0/PointWidth */ - gfx4_math(&c->func, - c->tmp, - BRW_MATH_FUNCTION_INV, - 0, - c->dx0, - BRW_MATH_PRECISION_FULL); - - brw_set_default_access_mode(p, BRW_ALIGN_16); - - /* dA/dx, dA/dy */ - brw_MOV(p, c->m1Cx, brw_imm_f(0.0)); - brw_MOV(p, c->m2Cy, brw_imm_f(0.0)); - brw_MOV(p, brw_writemask(c->m1Cx, WRITEMASK_X), c->tmp); - if (c->key.sprite_origin_lower_left) { - brw_MOV(p, brw_writemask(c->m2Cy, WRITEMASK_Y), negate(c->tmp)); - } else { - brw_MOV(p, brw_writemask(c->m2Cy, WRITEMASK_Y), c->tmp); - } - - /* attribute constant offset */ - brw_MOV(p, c->m3C0, brw_imm_f(0.0)); - if (c->key.sprite_origin_lower_left) { - brw_MOV(p, brw_writemask(c->m3C0, WRITEMASK_YW), brw_imm_f(1.0)); - } else { - brw_MOV(p, brw_writemask(c->m3C0, WRITEMASK_W), brw_imm_f(1.0)); - } - - brw_set_default_access_mode(p, BRW_ALIGN_1); - } - - if (pc & ~pc_coord_replace) { - set_predicate_control_flag_value(p, c, pc & ~pc_coord_replace); - brw_MOV(p, c->m1Cx, brw_imm_ud(0)); - brw_MOV(p, c->m2Cy, brw_imm_ud(0)); - brw_MOV(p, c->m3C0, a0); /* constant value */ - } - - - set_predicate_control_flag_value(p, c, pc); - /* Copy m0..m3 to URB. */ - brw_urb_WRITE(p, - brw_null_reg(), - 0, - brw_vec8_grf(0, 0), - last ? BRW_URB_WRITE_EOT_COMPLETE - : BRW_URB_WRITE_NO_FLAGS, - 4, /* msg len */ - 0, /* response len */ - i*4, /* urb destination offset */ - BRW_URB_SWIZZLE_TRANSPOSE); - } - - brw_set_default_predicate_control(p, BRW_PREDICATE_NONE); -} - -/* Points setup - several simplifications as all attributes are - * constant across the face of the point (point sprites excluded!) - */ -static void brw_emit_point_setup(struct brw_sf_compile *c, bool allocate) -{ - struct brw_codegen *p = &c->func; - GLuint i; - - c->flag_value = 0xff; - c->nr_verts = 1; - - if (allocate) - alloc_regs(c); - - copy_z_inv_w(c); - - brw_MOV(p, c->m1Cx, brw_imm_ud(0)); /* zero - move out of loop */ - brw_MOV(p, c->m2Cy, brw_imm_ud(0)); /* zero - move out of loop */ - - for (i = 0; i < c->nr_setup_regs; i++) - { - struct brw_reg a0 = offset(c->vert[0], i); - GLushort pc, pc_persp, pc_linear; - bool last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear); - - if (pc_persp) - { - /* This seems odd as the values are all constant, but the - * fragment shader will be expecting it: - */ - set_predicate_control_flag_value(p, c, pc_persp); - brw_MUL(p, a0, a0, c->inv_w[0]); - } - - - /* The delta values are always zero, just send the starting - * coordinate. Again, this is to fit in with the interpolation - * code in the fragment shader. - */ - { - set_predicate_control_flag_value(p, c, pc); - - brw_MOV(p, c->m3C0, a0); /* constant value */ - - /* Copy m0..m3 to URB. - */ - brw_urb_WRITE(p, - brw_null_reg(), - 0, - brw_vec8_grf(0, 0), - last ? BRW_URB_WRITE_EOT_COMPLETE - : BRW_URB_WRITE_NO_FLAGS, - 4, /* msg len */ - 0, /* response len */ - i*4, /* urb destination offset */ - BRW_URB_SWIZZLE_TRANSPOSE); - } - } - - brw_set_default_predicate_control(p, BRW_PREDICATE_NONE); -} - -static void brw_emit_anyprim_setup( struct brw_sf_compile *c ) -{ - struct brw_codegen *p = &c->func; - struct brw_reg payload_prim = brw_uw1_reg(BRW_GENERAL_REGISTER_FILE, 1, 0); - struct brw_reg payload_attr = get_element_ud(brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, 1, 0), 0); - struct brw_reg primmask; - int jmp; - struct brw_reg v1_null_ud = vec1(retype(brw_null_reg(), BRW_REGISTER_TYPE_UD)); - - c->nr_verts = 3; - alloc_regs(c); - - primmask = retype(get_element(c->tmp, 0), BRW_REGISTER_TYPE_UD); - - brw_MOV(p, primmask, brw_imm_ud(1)); - brw_SHL(p, primmask, primmask, payload_prim); - - brw_AND(p, v1_null_ud, primmask, brw_imm_ud((1<<_3DPRIM_TRILIST) | - (1<<_3DPRIM_TRISTRIP) | - (1<<_3DPRIM_TRIFAN) | - (1<<_3DPRIM_TRISTRIP_REVERSE) | - (1<<_3DPRIM_POLYGON) | - (1<<_3DPRIM_RECTLIST) | - (1<<_3DPRIM_TRIFAN_NOSTIPPLE))); - brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_Z); - jmp = brw_JMPI(p, brw_imm_d(0), BRW_PREDICATE_NORMAL) - p->store; - brw_emit_tri_setup(c, false); - brw_land_fwd_jump(p, jmp); - - brw_AND(p, v1_null_ud, primmask, brw_imm_ud((1<<_3DPRIM_LINELIST) | - (1<<_3DPRIM_LINESTRIP) | - (1<<_3DPRIM_LINELOOP) | - (1<<_3DPRIM_LINESTRIP_CONT) | - (1<<_3DPRIM_LINESTRIP_BF) | - (1<<_3DPRIM_LINESTRIP_CONT_BF))); - brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_Z); - jmp = brw_JMPI(p, brw_imm_d(0), BRW_PREDICATE_NORMAL) - p->store; - brw_emit_line_setup(c, false); - brw_land_fwd_jump(p, jmp); - - brw_AND(p, v1_null_ud, payload_attr, brw_imm_ud(1<devinfo, brw_last_inst, BRW_CONDITIONAL_Z); - jmp = brw_JMPI(p, brw_imm_d(0), BRW_PREDICATE_NORMAL) - p->store; - brw_emit_point_sprite_setup(c, false); - brw_land_fwd_jump(p, jmp); - - brw_emit_point_setup( c, false ); -} - -const unsigned * -brw_compile_sf(const struct brw_compiler *compiler, - void *mem_ctx, - const struct brw_sf_prog_key *key, - struct brw_sf_prog_data *prog_data, - struct intel_vue_map *vue_map, - unsigned *final_assembly_size) -{ - struct brw_sf_compile c; - memset(&c, 0, sizeof(c)); - - /* Begin the compilation: - */ - brw_init_codegen(&compiler->isa, &c.func, mem_ctx); - - c.key = *key; - c.vue_map = *vue_map; - if (c.key.do_point_coord) { - /* - * gl_PointCoord is a FS instead of VS builtin variable, thus it's - * not included in c.vue_map generated in VS stage. Here we add - * it manually to let SF shader generate the needed interpolation - * coefficient for FS shader. - */ - c.vue_map.varying_to_slot[BRW_VARYING_SLOT_PNTC] = c.vue_map.num_slots; - c.vue_map.slot_to_varying[c.vue_map.num_slots++] = BRW_VARYING_SLOT_PNTC; - } - c.urb_entry_read_offset = BRW_SF_URB_ENTRY_READ_OFFSET; - c.nr_attr_regs = (c.vue_map.num_slots + 1)/2 - c.urb_entry_read_offset; - c.nr_setup_regs = c.nr_attr_regs; - - c.prog_data.urb_read_length = c.nr_attr_regs; - c.prog_data.urb_entry_size = c.nr_setup_regs * 2; - - /* Which primitive? Or all three? - */ - switch (key->primitive) { - case BRW_SF_PRIM_TRIANGLES: - c.nr_verts = 3; - brw_emit_tri_setup( &c, true ); - break; - case BRW_SF_PRIM_LINES: - c.nr_verts = 2; - brw_emit_line_setup( &c, true ); - break; - case BRW_SF_PRIM_POINTS: - c.nr_verts = 1; - if (key->do_point_sprite) - brw_emit_point_sprite_setup( &c, true ); - else - brw_emit_point_setup( &c, true ); - break; - case BRW_SF_PRIM_UNFILLED_TRIS: - c.nr_verts = 3; - brw_emit_anyprim_setup( &c ); - break; - default: - unreachable("not reached"); - } - - /* FINISHME: SF programs use calculated jumps (i.e., JMPI with a register - * source). Compacting would be difficult. - */ - /* brw_compact_instructions(&c.func, 0, 0, NULL); */ - - *prog_data = c.prog_data; - - const unsigned *program = brw_get_program(&c.func, final_assembly_size); - - if (INTEL_DEBUG(DEBUG_SF)) { - fprintf(stderr, "sf:\n"); - brw_disassemble_with_labels(&compiler->isa, - program, 0, *final_assembly_size, stderr); - fprintf(stderr, "\n"); - } - - return program; -} diff --git a/src/intel/compiler/brw_compiler.h b/src/intel/compiler/brw_compiler.h index 3628a2eab75..765a6cb3416 100644 --- a/src/intel/compiler/brw_compiler.h +++ b/src/intel/compiler/brw_compiler.h @@ -431,69 +431,6 @@ struct brw_mesh_prog_key unsigned padding:31; }; -enum brw_sf_primitive { - BRW_SF_PRIM_POINTS = 0, - BRW_SF_PRIM_LINES = 1, - BRW_SF_PRIM_TRIANGLES = 2, - BRW_SF_PRIM_UNFILLED_TRIS = 3, -}; - -struct brw_sf_prog_key { - uint64_t attrs; - bool contains_flat_varying; - unsigned char interp_mode[65]; /* BRW_VARYING_SLOT_COUNT */ - uint8_t point_sprite_coord_replace; - enum brw_sf_primitive primitive:2; - bool do_twoside_color:1; - bool frontface_ccw:1; - bool do_point_sprite:1; - bool do_point_coord:1; - bool sprite_origin_lower_left:1; - bool userclip_active:1; - unsigned padding: 32; -}; - -enum brw_clip_mode { - BRW_CLIP_MODE_NORMAL = 0, - BRW_CLIP_MODE_CLIP_ALL = 1, - BRW_CLIP_MODE_CLIP_NON_REJECTED = 2, - BRW_CLIP_MODE_REJECT_ALL = 3, - BRW_CLIP_MODE_ACCEPT_ALL = 4, - BRW_CLIP_MODE_KERNEL_CLIP = 5, -}; - -enum brw_clip_fill_mode { - BRW_CLIP_FILL_MODE_LINE = 0, - BRW_CLIP_FILL_MODE_POINT = 1, - BRW_CLIP_FILL_MODE_FILL = 2, - BRW_CLIP_FILL_MODE_CULL = 3, -}; - -/* Note that if unfilled primitives are being emitted, we have to fix - * up polygon offset and flatshading at this point: - */ -struct brw_clip_prog_key { - uint64_t attrs; - float offset_factor; - float offset_units; - float offset_clamp; - bool contains_flat_varying; - bool contains_noperspective_varying; - unsigned char interp_mode[65]; /* BRW_VARYING_SLOT_COUNT */ - unsigned primitive:4; - unsigned nr_userclip:4; - bool pv_first:1; - bool do_unfilled:1; - enum brw_clip_fill_mode fill_cw:2; /* includes cull information */ - enum brw_clip_fill_mode fill_ccw:2; /* includes cull information */ - bool offset_cw:1; - bool offset_ccw:1; - bool copy_bfc_cw:1; - bool copy_bfc_ccw:1; - enum brw_clip_mode clip_mode:3; - uint64_t padding:51; -}; - /* A big lookup table is used to figure out which and how many * additional regs will inserted before the main payload in the WM * program execution. These mainly relate to depth and stencil @@ -581,38 +518,6 @@ struct brw_bs_prog_key { uint32_t pipeline_ray_flags; }; -struct brw_ff_gs_prog_key { - uint64_t attrs; - - /** - * Map from the index of a transform feedback binding table entry to the - * gl_varying_slot that should be streamed out through that binding table - * entry. - */ - unsigned char transform_feedback_bindings[BRW_MAX_SOL_BINDINGS]; - - /** - * Map from the index of a transform feedback binding table entry to the - * swizzles that should be used when streaming out data through that - * binding table entry. - */ - unsigned char transform_feedback_swizzles[BRW_MAX_SOL_BINDINGS]; - - /** - * Hardware primitive type being drawn, e.g. _3DPRIM_TRILIST. - */ - unsigned primitive:8; - - unsigned pv_first:1; - unsigned need_gs_prog:1; - - /** - * Number of varyings that are output to transform feedback. - */ - unsigned num_transform_feedback_bindings:7; /* 0-BRW_MAX_SOL_BINDINGS */ - uint64_t padding:47; -}; - /* brw_any_prog_key is any of the keys that map to an API stage */ union brw_any_prog_key { struct brw_base_prog_key base; @@ -1302,17 +1207,6 @@ struct brw_bs_prog_data { uint32_t num_resume_shaders; }; -struct brw_ff_gs_prog_data { - unsigned urb_read_length; - unsigned total_grf; - - /** - * Gfx6 transform feedback: Amount by which the streaming vertex buffer - * indices should be incremented each time the GS is invoked. - */ - unsigned svbi_postincrement_value; -}; - /** * Enum representing the i965-specific vertex results that don't correspond * exactly to any element of gl_varying_slot. The values of this enum are @@ -1322,13 +1216,6 @@ typedef enum { BRW_VARYING_SLOT_NDC = VARYING_SLOT_MAX, BRW_VARYING_SLOT_PAD, - /** - * Technically this is not a varying but just a placeholder that - * compile_sf_prog() inserts into its VUE map to cause the gl_PointCoord - * builtin variable to be compiled correctly. see compile_sf_prog() for - * more info. - */ - BRW_VARYING_SLOT_PNTC, BRW_VARYING_SLOT_COUNT } brw_varying_slot; @@ -1509,26 +1396,6 @@ struct brw_gs_prog_data unsigned char transform_feedback_swizzles[64 /* BRW_MAX_SOL_BINDINGS */]; }; -struct brw_sf_prog_data { - uint32_t urb_read_length; - uint32_t total_grf; - - /* Each vertex may have up to 12 attributes, 4 components each, - * except WPOS which requires only 2. (11*4 + 2) == 44 ==> 11 - * rows. - * - * Actually we use 4 for each, so call it 12 rows. - */ - unsigned urb_entry_size; -}; - -struct brw_clip_prog_data { - uint32_t curb_read_length; /* user planes? */ - uint32_t clip_mode; - uint32_t urb_read_length; - uint32_t total_grf; -}; - struct brw_tue_map { uint32_t size_dw; @@ -1628,10 +1495,6 @@ DEFINE_PROG_DATA_DOWNCAST(vue, prog_data->stage == MESA_SHADER_VERTEX || DEFINE_PROG_DATA_DOWNCAST(task, prog_data->stage == MESA_SHADER_TASK) DEFINE_PROG_DATA_DOWNCAST(mesh, prog_data->stage == MESA_SHADER_MESH) -/* These are not really brw_stage_prog_data. */ -DEFINE_PROG_DATA_DOWNCAST(ff_gs, true) -DEFINE_PROG_DATA_DOWNCAST(clip, true) -DEFINE_PROG_DATA_DOWNCAST(sf, true) #undef DEFINE_PROG_DATA_DOWNCAST struct brw_compile_stats { @@ -1787,38 +1650,6 @@ const unsigned * brw_compile_gs(const struct brw_compiler *compiler, struct brw_compile_gs_params *params); -/** - * Compile a strips and fans shader. - * - * This is a fixed-function shader determined entirely by the shader key and - * a VUE map. - * - * Returns the final assembly and the program's size. - */ -const unsigned * -brw_compile_sf(const struct brw_compiler *compiler, - void *mem_ctx, - const struct brw_sf_prog_key *key, - struct brw_sf_prog_data *prog_data, - struct intel_vue_map *vue_map, - unsigned *final_assembly_size); - -/** - * Compile a clipper shader. - * - * This is a fixed-function shader determined entirely by the shader key and - * a VUE map. - * - * Returns the final assembly and the program's size. - */ -const unsigned * -brw_compile_clip(const struct brw_compiler *compiler, - void *mem_ctx, - const struct brw_clip_prog_key *key, - struct brw_clip_prog_data *prog_data, - struct intel_vue_map *vue_map, - unsigned *final_assembly_size); - struct brw_compile_task_params { struct brw_compile_params base; @@ -1915,19 +1746,6 @@ const unsigned * brw_compile_bs(const struct brw_compiler *compiler, struct brw_compile_bs_params *params); -/** - * Compile a fixed function geometry shader. - * - * Returns the final assembly and the program's size. - */ -const unsigned * -brw_compile_ff_gs_prog(struct brw_compiler *compiler, - void *mem_ctx, - const struct brw_ff_gs_prog_key *key, - struct brw_ff_gs_prog_data *prog_data, - struct intel_vue_map *vue_map, - unsigned *final_assembly_size); - void brw_debug_key_recompile(const struct brw_compiler *c, void *log, gl_shader_stage stage, const struct brw_base_prog_key *old_key, diff --git a/src/intel/compiler/brw_vue_map.c b/src/intel/compiler/brw_vue_map.c index 56cb560f1e4..68f4e3472fb 100644 --- a/src/intel/compiler/brw_vue_map.c +++ b/src/intel/compiler/brw_vue_map.c @@ -291,7 +291,6 @@ varying_name(brw_varying_slot slot, gl_shader_stage stage) static const char *brw_names[] = { [BRW_VARYING_SLOT_NDC - VARYING_SLOT_MAX] = "BRW_VARYING_SLOT_NDC", [BRW_VARYING_SLOT_PAD - VARYING_SLOT_MAX] = "BRW_VARYING_SLOT_PAD", - [BRW_VARYING_SLOT_PNTC - VARYING_SLOT_MAX] = "BRW_VARYING_SLOT_PNTC", }; return brw_names[slot - VARYING_SLOT_MAX]; diff --git a/src/intel/compiler/meson.build b/src/intel/compiler/meson.build index d61e98405ee..6a55f59568c 100644 --- a/src/intel/compiler/meson.build +++ b/src/intel/compiler/meson.build @@ -39,16 +39,7 @@ intel_nir_files = files( libintel_compiler_brw_files = files( 'brw_cfg.cpp', 'brw_cfg.h', - 'brw_clip.h', - 'brw_clip_line.c', - 'brw_clip_point.c', - 'brw_clip_tri.c', - 'brw_clip_unfilled.c', - 'brw_clip_util.c', - 'brw_compile_clip.c', - 'brw_compile_ff_gs.c', 'brw_compile_gs.cpp', - 'brw_compile_sf.c', 'brw_compile_tcs.cpp', 'brw_compile_vs.cpp', 'brw_compiler.c',