diff options
-rw-r--r-- | src/gallium/auxiliary/draw/draw_cliptest_tmp.h | 17 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_context.c | 10 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_llvm.c | 12 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_llvm.h | 10 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pipe_clip.c | 9 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_private.h | 4 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt_fetch.c | 4 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_vs.c | 9 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_vs.h | 1 |
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: */ |