From 65ef78e8611556780fce0bee1feba805347ec627 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Mon, 17 Nov 2014 22:30:31 +0100 Subject: [PATCH] draw: implement TGSI_PROPERTY_VS_WINDOW_SPACE_POSITION Required by Nine. Tested with util_run_tests. It's added to softpipe, llvmpipe, and r300g/swtcl. Tested-by: David Heidelberg --- src/gallium/auxiliary/draw/draw_context.c | 40 ++++++++++++++++--- src/gallium/auxiliary/draw/draw_llvm.c | 2 +- src/gallium/auxiliary/draw/draw_private.h | 4 ++ .../auxiliary/draw/draw_pt_fetch_shade_emit.c | 2 +- .../draw/draw_pt_fetch_shade_pipeline.c | 2 +- .../draw/draw_pt_fetch_shade_pipeline_llvm.c | 2 +- src/gallium/auxiliary/draw/draw_vs.c | 2 + src/gallium/drivers/llvmpipe/lp_screen.c | 2 + src/gallium/drivers/r300/r300_screen.c | 2 +- src/gallium/drivers/softpipe/sp_screen.c | 2 + 10 files changed, 49 insertions(+), 11 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 7bd2d393bf6..04cf5b7630e 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -254,21 +254,48 @@ void draw_set_zs_format(struct draw_context *draw, enum pipe_format format) } -static void update_clip_flags( struct draw_context *draw ) +static bool +draw_is_vs_window_space(struct draw_context *draw) { - draw->clip_xy = !draw->driver.bypass_clip_xy; + if (draw->vs.vertex_shader) { + struct tgsi_shader_info *info = &draw->vs.vertex_shader->info; + + return info->properties[TGSI_PROPERTY_VS_WINDOW_SPACE_POSITION] != 0; + } + return false; +} + + +void +draw_update_clip_flags(struct draw_context *draw) +{ + bool window_space = draw_is_vs_window_space(draw); + + draw->clip_xy = !draw->driver.bypass_clip_xy && !window_space; draw->guard_band_xy = (!draw->driver.bypass_clip_xy && draw->driver.guard_band_xy); draw->clip_z = (!draw->driver.bypass_clip_z && - draw->rasterizer && draw->rasterizer->depth_clip); + draw->rasterizer && draw->rasterizer->depth_clip) && + !window_space; draw->clip_user = draw->rasterizer && - draw->rasterizer->clip_plane_enable != 0; + draw->rasterizer->clip_plane_enable != 0 && + !window_space; draw->guard_band_points_xy = draw->guard_band_xy || (draw->driver.bypass_clip_points && (draw->rasterizer && draw->rasterizer->point_tri_clip)); } + +void +draw_update_viewport_flags(struct draw_context *draw) +{ + bool window_space = draw_is_vs_window_space(draw); + + draw->bypass_viewport = window_space || draw->identity_viewport; +} + + /** * Register new primitive rasterization/rendering state. * This causes the drawing pipeline to be rebuilt. @@ -282,7 +309,7 @@ void draw_set_rasterizer_state( struct draw_context *draw, draw->rasterizer = raster; draw->rast_handle = rast_handle; - update_clip_flags(draw); + draw_update_clip_flags(draw); } } @@ -309,7 +336,7 @@ void draw_set_driver_clipping( struct draw_context *draw, draw->driver.bypass_clip_z = bypass_clip_z; draw->driver.guard_band_xy = guard_band_xy; draw->driver.bypass_clip_points = bypass_clip_points; - update_clip_flags(draw); + draw_update_clip_flags(draw); } @@ -363,6 +390,7 @@ void draw_set_viewport_states( struct draw_context *draw, viewport->translate[0] == 0.0f && viewport->translate[1] == 0.0f && viewport->translate[2] == 0.0f); + draw_update_viewport_flags(draw); } diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c index dbaece3ab35..832607251d7 100644 --- a/src/gallium/auxiliary/draw/draw_llvm.c +++ b/src/gallium/auxiliary/draw/draw_llvm.c @@ -1836,7 +1836,7 @@ draw_llvm_make_variant_key(struct draw_llvm *llvm, char *store) key->clip_xy = llvm->draw->clip_xy; key->clip_z = llvm->draw->clip_z; key->clip_user = llvm->draw->clip_user; - key->bypass_viewport = llvm->draw->identity_viewport; + key->bypass_viewport = llvm->draw->bypass_viewport; key->clip_halfz = llvm->draw->rasterizer->clip_halfz; key->need_edgeflags = (llvm->draw->vs.edgeflag_output ? TRUE : FALSE); key->ucp_enable = llvm->draw->rasterizer->clip_plane_enable; diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 37045ebb029..7b893cb2692 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -252,6 +252,7 @@ struct draw_context struct pipe_viewport_state viewports[PIPE_MAX_VIEWPORTS]; boolean identity_viewport; + boolean bypass_viewport; /** Vertex shader state */ struct { @@ -478,6 +479,9 @@ void draw_stats_clipper_primitives(struct draw_context *draw, const struct draw_prim_info *prim_info); +void draw_update_clip_flags(struct draw_context *draw); +void draw_update_viewport_flags(struct draw_context *draw); + /** * Return index i from the index buffer. * If the index buffer would overflow we return the diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c index c675321f355..50f438ce0b1 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c @@ -95,7 +95,7 @@ fse_prepare(struct draw_pt_middle_end *middle, fse->key.nr_elements = MAX2(fse->key.nr_outputs, /* outputs - translate to hw format */ fse->key.nr_inputs); /* inputs - fetch from api format */ - fse->key.viewport = !draw->identity_viewport; + fse->key.viewport = !draw->bypass_viewport; fse->key.clip = draw->clip_xy || draw->clip_z || draw->clip_user; fse->key.const_vbuffers = 0; diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index f518deef27d..5af845ff938 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -117,7 +117,7 @@ fetch_pipeline_prepare(struct draw_pt_middle_end *middle, draw->clip_user, point_clip ? draw->guard_band_points_xy : draw->guard_band_xy, - draw->identity_viewport, + draw->bypass_viewport, draw->rasterizer->clip_halfz, (draw->vs.edgeflag_output ? TRUE : FALSE) ); diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c index cc837366ae9..0dfafdca51a 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c @@ -162,7 +162,7 @@ llvm_middle_end_prepare( struct draw_pt_middle_end *middle, draw->clip_user, point_clip ? draw->guard_band_points_xy : draw->guard_band_xy, - draw->identity_viewport, + draw->bypass_viewport, draw->rasterizer->clip_halfz, (draw->vs.edgeflag_output ? TRUE : FALSE) ); diff --git a/src/gallium/auxiliary/draw/draw_vs.c b/src/gallium/auxiliary/draw/draw_vs.c index f24354e9d51..1501942eb44 100644 --- a/src/gallium/auxiliary/draw/draw_vs.c +++ b/src/gallium/auxiliary/draw/draw_vs.c @@ -122,6 +122,8 @@ draw_bind_vertex_shader(struct draw_context *draw, draw->vs.clipdistance_output[0] = dvs->clipdistance_output[0]; draw->vs.clipdistance_output[1] = dvs->clipdistance_output[1]; dvs->prepare( dvs, draw ); + draw_update_clip_flags(draw); + draw_update_viewport_flags(draw); } else { draw->vs.vertex_shader = NULL; diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c index e10e83ebb1d..6af43ccf581 100644 --- a/src/gallium/drivers/llvmpipe/lp_screen.c +++ b/src/gallium/drivers/llvmpipe/lp_screen.c @@ -252,7 +252,9 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_TEXTURE_QUERY_LOD: case PIPE_CAP_SAMPLE_SHADING: case PIPE_CAP_TEXTURE_GATHER_OFFSETS: + return 0; case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION: + return 1; case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE: case PIPE_CAP_SAMPLER_VIEW_TARGET: return 0; diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index 47616f65f3d..e653eab184e 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -177,7 +177,6 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_FAKE_SW_MSAA: case PIPE_CAP_SAMPLE_SHADING: case PIPE_CAP_TEXTURE_GATHER_OFFSETS: - case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION: case PIPE_CAP_DRAW_INDIRECT: case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE: case PIPE_CAP_CONDITIONAL_RENDER_INVERTED: @@ -187,6 +186,7 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param) /* SWTCL-only features. */ case PIPE_CAP_PRIMITIVE_RESTART: case PIPE_CAP_USER_VERTEX_BUFFERS: + case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION: return !r300screen->caps.has_tcl; /* HWTCL-only features / limitations. */ diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index 47126eff180..57cd9b632df 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -196,7 +196,9 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_TEXTURE_QUERY_LOD: case PIPE_CAP_SAMPLE_SHADING: case PIPE_CAP_TEXTURE_GATHER_OFFSETS: + return 0; case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION: + return 1; case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE: case PIPE_CAP_SAMPLER_VIEW_TARGET: return 0; -- 2.30.2