const float *trans = pvs->draw->viewport.translate;
/* const */ float (*plane)[4] = pvs->draw->plane;
const unsigned pos = draw_current_shader_position_output(pvs->draw);
+ const unsigned cv = draw_current_shader_clipvertex_output(pvs->draw);
const unsigned ef = pvs->draw->vs.edgeflag_output;
const unsigned ucp_enable = pvs->draw->rasterizer->clip_plane_enable;
const unsigned flags = (FLAGS);
unsigned need_pipeline = 0;
unsigned j;
+ unsigned i;
for (j = 0; j < info->count; j++) {
float *position = out->data[pos];
if (flags & (DO_CLIP_XY | DO_CLIP_XY_GUARD_BAND |
DO_CLIP_FULL_Z | DO_CLIP_HALF_Z | DO_CLIP_USER)) {
- out->clip[0] = position[0];
- out->clip[1] = position[1];
- out->clip[2] = position[2];
- out->clip[3] = position[3];
+ float *clipvertex = position;
+
+ if ((flags & DO_CLIP_USER) && cv != pos)
+ clipvertex = out->data[cv];
+
+ for (i = 0; i < 4; i++) {
+ out->clip[i] = clipvertex[i];
+ out->pre_clip_pos[i] = position[i];
+ }
/* Do the hardwired planes first:
*/
ucp_mask &= ~(1 << plane_idx);
plane_idx += 6;
- if (dot4(position, plane[plane_idx]) < 0) {
+ if (dot4(clipvertex, plane[plane_idx]) < 0) {
mask |= 1 << plane_idx;
}
}
/**
+ * Return the index of the shader output which will contain the
+ * vertex position.
+ */
+uint
+draw_current_shader_clipvertex_output(const struct draw_context *draw)
+{
+ return draw->vs.clipvertex_output;
+}
+
+/**
* Return a pointer/handle for a driver/CSO rasterizer object which
* disabled culling, stippling, unfilled tris, etc.
* This is used by some pipeline stages (such as wide_point, aa_line
create_jit_vertex_header(struct gallivm_state *gallivm, int data_elems)
{
LLVMTargetDataRef target = gallivm->target;
- LLVMTypeRef elem_types[3];
+ LLVMTypeRef elem_types[4];
LLVMTypeRef vertex_header;
char struct_name[24];
util_snprintf(struct_name, 23, "vertex_header%d", data_elems);
- elem_types[0] = LLVMIntTypeInContext(gallivm->context, 32);
- elem_types[1] = LLVMArrayType(LLVMFloatTypeInContext(gallivm->context), 4);
- elem_types[2] = LLVMArrayType(elem_types[1], data_elems);
+ elem_types[DRAW_JIT_VERTEX_VERTEX_ID] = LLVMIntTypeInContext(gallivm->context, 32);
+ elem_types[DRAW_JIT_VERTEX_CLIP] = LLVMArrayType(LLVMFloatTypeInContext(gallivm->context), 4);
+ elem_types[DRAW_JIT_VERTEX_PRE_CLIP_POS] = LLVMArrayType(LLVMFloatTypeInContext(gallivm->context), 4);
+ elem_types[DRAW_JIT_VERTEX_DATA] = LLVMArrayType(elem_types[1], data_elems);
#if HAVE_LLVM >= 0x0300
vertex_header = LLVMStructCreateNamed(gallivm->context, struct_name);
LP_CHECK_MEMBER_OFFSET(struct vertex_header, clip,
target, vertex_header,
DRAW_JIT_VERTEX_CLIP);
+ LP_CHECK_MEMBER_OFFSET(struct vertex_header, pre_clip_pos,
+ target, vertex_header,
+ DRAW_JIT_VERTEX_PRE_CLIP_POS);
LP_CHECK_MEMBER_OFFSET(struct vertex_header, data,
target, vertex_header,
DRAW_JIT_VERTEX_DATA);
enum {
DRAW_JIT_VERTEX_VERTEX_ID = 0,
DRAW_JIT_VERTEX_CLIP,
+ DRAW_JIT_VERTEX_PRE_CLIP_POS,
DRAW_JIT_VERTEX_DATA
};
lp_build_struct_get_ptr(_gallivm, _ptr, DRAW_JIT_CTX_TEXTURES, "textures")
#define draw_jit_header_id(_gallivm, _ptr) \
- lp_build_struct_get_ptr(_gallivm, _ptr, 0, "id")
+ lp_build_struct_get_ptr(_gallivm, _ptr, DRAW_JIT_VERTEX_VERTEX_ID, "id")
#define draw_jit_header_clip(_gallivm, _ptr) \
- lp_build_struct_get_ptr(_gallivm, _ptr, 1, "clip")
+ lp_build_struct_get_ptr(_gallivm, _ptr, DRAW_JIT_VERTEX_CLIP, "clip")
+
+#define draw_jit_header_pre_clip_pos(_gallivm, _ptr) \
+ lp_build_struct_get_ptr(_gallivm, _ptr, DRAW_JIT_VERTEX_PRE_CLIP_POS, "pre_clip_pos")
#define draw_jit_header_data(_gallivm, _ptr) \
- lp_build_struct_get_ptr(_gallivm, _ptr, 2, "data")
+ lp_build_struct_get_ptr(_gallivm, _ptr, DRAW_JIT_VERTEX_DATA, "data")
#define draw_jit_vbuffer_stride(_gallivm, _ptr) \
{
const unsigned nr_attrs = draw_current_shader_outputs(clip->stage.draw);
const unsigned pos_attr = draw_current_shader_position_output(clip->stage.draw);
+ const unsigned clip_attr = draw_current_shader_clipvertex_output(clip->stage.draw);
unsigned j;
/* Vertex header.
/* Interpolate the clip-space coords.
*/
interp_attr(dst->clip, t, in->clip, out->clip);
+ /* interpolate the clip-space position */
+ interp_attr(dst->pre_clip_pos, t, in->pre_clip_pos, out->pre_clip_pos);
/* Do the projective divide and viewport transformation to get
* new window coordinates:
*/
{
- const float *pos = dst->clip;
+ const float *pos = dst->pre_clip_pos;
const float *scale = clip->stage.draw->viewport.scale;
const float *trans = clip->stage.draw->viewport.translate;
const float oow = 1.0f / pos[3];
/* Other attributes
*/
for (j = 0; j < nr_attrs; j++) {
- if (j != pos_attr)
- interp_attr(dst->data[j], t, in->data[j], out->data[j]);
+ if (j != pos_attr && j != clip_attr)
+ interp_attr(dst->data[j], t, in->data[j], out->data[j]);
}
}
unsigned vertex_id:16;
float clip[4];
+ float pre_clip_pos[4];
/* This will probably become float (*data)[4] soon:
*/
uint num_vs_outputs; /**< convenience, from vertex_shader */
uint position_output;
uint edgeflag_output;
+ uint clipvertex_output;
/** TGSI program interpreter runtime state */
struct tgsi_exec_machine *machine;
*/
uint draw_current_shader_outputs(const struct draw_context *draw);
uint draw_current_shader_position_output(const struct draw_context *draw);
-
+uint draw_current_shader_clipvertex_output(const struct draw_context *draw);
int draw_alloc_extra_vertex_attrib(struct draw_context *draw,
uint semantic_name, uint semantic_index);
void draw_remove_extra_vertex_attribs(struct draw_context *draw);
/* Leave the clipmask/edgeflags/pad/vertex_id untouched
*/
dst_offset += 1 * sizeof(float);
- /* Just leave the clip[] array untouched.
+ /* Just leave the clip[] and pre_clip_pos[] array untouched.
*/
- dst_offset += 4 * sizeof(float);
+ dst_offset += 8 * sizeof(float);
if (instance_id_index != ~0) {
num_extra_inputs++;
if (vs)
{
uint i;
+ bool found_clipvertex = FALSE;
for (i = 0; i < vs->info.num_outputs; i++) {
if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_POSITION &&
vs->info.output_semantic_index[i] == 0)
else if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_EDGEFLAG &&
vs->info.output_semantic_index[i] == 0)
vs->edgeflag_output = i;
+ else if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_CLIPVERTEX &&
+ vs->info.output_semantic_index[i] == 0) {
+ found_clipvertex = TRUE;
+ vs->clipvertex_output = i;
+ }
}
+ if (!found_clipvertex)
+ vs->clipvertex_output = vs->position_output;
}
assert(vs);
draw->vs.num_vs_outputs = dvs->info.num_outputs;
draw->vs.position_output = dvs->position_output;
draw->vs.edgeflag_output = dvs->edgeflag_output;
+ draw->vs.clipvertex_output = dvs->clipvertex_output;
dvs->prepare( dvs, draw );
}
else {
struct tgsi_shader_info info;
unsigned position_output;
unsigned edgeflag_output;
+ unsigned clipvertex_output;
/* Extracted from shader:
*/