summaryrefslogtreecommitdiffstats
path: root/src/gallium/auxiliary/draw
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/auxiliary/draw')
-rw-r--r--src/gallium/auxiliary/draw/draw_cliptest_tmp.h17
-rw-r--r--src/gallium/auxiliary/draw/draw_context.c10
-rw-r--r--src/gallium/auxiliary/draw/draw_llvm.c12
-rw-r--r--src/gallium/auxiliary/draw/draw_llvm.h10
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_clip.c9
-rw-r--r--src/gallium/auxiliary/draw/draw_private.h4
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch.c4
-rw-r--r--src/gallium/auxiliary/draw/draw_vs.c9
-rw-r--r--src/gallium/auxiliary/draw/draw_vs.h1
9 files changed, 58 insertions, 18 deletions
diff --git a/src/gallium/auxiliary/draw/draw_cliptest_tmp.h b/src/gallium/auxiliary/draw/draw_cliptest_tmp.h
index 9e6827cc452..7dba49b2870 100644
--- a/src/gallium/auxiliary/draw/draw_cliptest_tmp.h
+++ b/src/gallium/auxiliary/draw/draw_cliptest_tmp.h
@@ -35,11 +35,13 @@ static boolean TAG(do_cliptest)( struct pt_post_vs *pvs,
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];
@@ -49,10 +51,15 @@ static boolean TAG(do_cliptest)( struct pt_post_vs *pvs,
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:
*/
@@ -88,7 +95,7 @@ static boolean TAG(do_cliptest)( struct pt_post_vs *pvs,
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;
}
}
diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c
index 10a20f76178..6d7075e5452 100644
--- a/src/gallium/auxiliary/draw/draw_context.c
+++ b/src/gallium/auxiliary/draw/draw_context.c
@@ -692,6 +692,16 @@ draw_current_shader_position_output(const struct draw_context *draw)
/**
+ * 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
diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c
index cf97e82a63c..50c7e254deb 100644
--- a/src/gallium/auxiliary/draw/draw_llvm.c
+++ b/src/gallium/auxiliary/draw/draw_llvm.c
@@ -268,15 +268,16 @@ static LLVMTypeRef
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);
@@ -307,6 +308,9 @@ create_jit_vertex_header(struct gallivm_state *gallivm, int data_elems)
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);
diff --git a/src/gallium/auxiliary/draw/draw_llvm.h b/src/gallium/auxiliary/draw/draw_llvm.h
index edd1a08e3db..31fc2db05bd 100644
--- a/src/gallium/auxiliary/draw/draw_llvm.h
+++ b/src/gallium/auxiliary/draw/draw_llvm.h
@@ -80,6 +80,7 @@ enum {
enum {
DRAW_JIT_VERTEX_VERTEX_ID = 0,
DRAW_JIT_VERTEX_CLIP,
+ DRAW_JIT_VERTEX_PRE_CLIP_POS,
DRAW_JIT_VERTEX_DATA
};
@@ -123,13 +124,16 @@ struct draw_jit_context
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) \
diff --git a/src/gallium/auxiliary/draw/draw_pipe_clip.c b/src/gallium/auxiliary/draw/draw_pipe_clip.c
index e1eabe22288..fbc8f675129 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_clip.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_clip.c
@@ -118,6 +118,7 @@ static void interp( const struct clip_stage *clip,
{
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.
@@ -130,12 +131,14 @@ static void interp( const struct clip_stage *clip,
/* 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];
@@ -149,8 +152,8 @@ static void interp( const struct clip_stage *clip,
/* 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]);
}
}
diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h
index 91112eb96b4..aa9b602a353 100644
--- a/src/gallium/auxiliary/draw/draw_private.h
+++ b/src/gallium/auxiliary/draw/draw_private.h
@@ -76,6 +76,7 @@ struct vertex_header {
unsigned vertex_id:16;
float clip[4];
+ float pre_clip_pos[4];
/* This will probably become float (*data)[4] soon:
*/
@@ -230,6 +231,7 @@ struct draw_context
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;
@@ -378,7 +380,7 @@ void draw_gs_destroy( struct draw_context *draw );
*/
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);
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch.c b/src/gallium/auxiliary/draw/draw_pt_fetch.c
index b0032e5ad0e..a6cc1834e6c 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch.c
@@ -74,9 +74,9 @@ draw_pt_fetch_prepare(struct pt_fetch *fetch,
/* 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++;
diff --git a/src/gallium/auxiliary/draw/draw_vs.c b/src/gallium/auxiliary/draw/draw_vs.c
index bc1c90b0f3a..150653c669a 100644
--- a/src/gallium/auxiliary/draw/draw_vs.c
+++ b/src/gallium/auxiliary/draw/draw_vs.c
@@ -120,6 +120,7 @@ draw_create_vertex_shader(struct draw_context *draw,
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)
@@ -127,7 +128,14 @@ draw_create_vertex_shader(struct draw_context *draw,
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);
@@ -147,6 +155,7 @@ draw_bind_vertex_shader(struct draw_context *draw,
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 {
diff --git a/src/gallium/auxiliary/draw/draw_vs.h b/src/gallium/auxiliary/draw/draw_vs.h
index 49229f8164b..a3b90faa24b 100644
--- a/src/gallium/auxiliary/draw/draw_vs.h
+++ b/src/gallium/auxiliary/draw/draw_vs.h
@@ -111,6 +111,7 @@ struct draw_vertex_shader {
struct tgsi_shader_info info;
unsigned position_output;
unsigned edgeflag_output;
+ unsigned clipvertex_output;
/* Extracted from shader:
*/