[Mesa-dev] [PATCH v2 3/7] mesa: Add support for AMD_depth_clamp_separate
Sagar Ghuge
sagar.ghuge at intel.com
Thu Aug 23 00:14:03 UTC 2018
On 08/22/2018 04:31 PM, Marek Olšák wrote:
> On Wed, Aug 22, 2018 at 5:52 PM Sagar Ghuge <sagar.ghuge at intel.com> wrote:
>>
>> Enable _mesa_PushAttrib() and _mesa_PopAttrib() to handle
>> GL_DEPTH_CLAMP_NEAR_AMD and GL_DEPTH_CLAMP_FAR_AMD tokens.
>>
>> Remove DepthClamp, because DepthClampNear + DepthClampFar replaces it,
>> as suggested by Marek Olsak.
>>
>> Driver that enables AMD_depth_clamp_separate will only ever look at
>> DepthClampNear and DepthClampFar, as suggested by Ian Romanick.
>>
>> v2: 1) Remove unnecessary parentheses (Marek Olsak)
>> 2) if AMD_depth_clamp_separate is unsupported, TEST_AND_UPDATE
>> GL_DEPTH_CLAMP only (Marek Olsak)
>> 3) Clamp against near and far plane separately (Marek Olsak)
>> 4) Clip point separately for near and far Z clipping plane (Marek
>> Olsak)
>>
>> Signed-off-by: Sagar Ghuge <sagar.ghuge at intel.com>
>> ---
>> src/mesa/drivers/dri/i965/genX_state_upload.c | 11 ++--
>> src/mesa/main/attrib.c | 40 +++++++++++---
>> src/mesa/main/enable.c | 9 ++-
>> src/mesa/main/get.c | 4 ++
>> src/mesa/main/get_hash_params.py | 2 +-
>> src/mesa/main/mtypes.h | 1 -
>> src/mesa/main/rastpos.c | 55 ++++++++++++++++---
>> src/mesa/state_tracker/st_atom_rasterizer.c | 3 +-
>> src/mesa/state_tracker/st_cb_drawpixels.c | 3 +-
>> src/mesa/swrast/s_span.c | 2 +-
>> src/mesa/tnl/t_vb_program.c | 6 +-
>> src/mesa/tnl/t_vb_vertex.c | 8 ++-
>> 12 files changed, 111 insertions(+), 33 deletions(-)
>>
>> diff --git a/src/mesa/drivers/dri/i965/genX_state_upload.c b/src/mesa/drivers/dri/i965/genX_state_upload.c
>> index c051848985..dc54cb67af 100644
>> --- a/src/mesa/drivers/dri/i965/genX_state_upload.c
>> +++ b/src/mesa/drivers/dri/i965/genX_state_upload.c
>> @@ -1399,7 +1399,8 @@ genX(upload_clip_state)(struct brw_context *brw)
>> clip.ScreenSpaceViewportYMax = 1;
>>
>> clip.ViewportXYClipTestEnable = true;
>> - clip.ViewportZClipTestEnable = !ctx->Transform.DepthClamp;
>> + clip.ViewportZClipTestEnable = !(ctx->Transform.DepthClampNear &&
>> + ctx->Transform.DepthClampFar);
>>
>> /* _NEW_TRANSFORM */
>> if (GEN_GEN == 5 || GEN_IS_G4X) {
>> @@ -1493,7 +1494,8 @@ genX(upload_clip_state)(struct brw_context *brw)
>> clip.UserClipDistanceCullTestEnableBitmask =
>> brw_vue_prog_data(brw->vs.base.prog_data)->cull_distance_mask;
>>
>> - clip.ViewportZClipTestEnable = !ctx->Transform.DepthClamp;
>> + clip.ViewportZClipTestEnable = !(ctx->Transform.DepthClampNear &&
>> + ctx->Transform.DepthClampFar);
>> #endif
>>
>> /* _NEW_LIGHT */
>> @@ -2338,7 +2340,7 @@ genX(upload_cc_viewport)(struct brw_context *brw)
>> for (unsigned i = 0; i < viewport_count; i++) {
>> /* _NEW_VIEWPORT | _NEW_TRANSFORM */
>> const struct gl_viewport_attrib *vp = &ctx->ViewportArray[i];
>> - if (ctx->Transform.DepthClamp) {
>> + if (ctx->Transform.DepthClampNear && ctx->Transform.DepthClampFar) {
>> ccv.MinimumDepth = MIN2(vp->Near, vp->Far);
>> ccv.MaximumDepth = MAX2(vp->Near, vp->Far);
>> } else {
>> @@ -4605,7 +4607,8 @@ genX(upload_raster)(struct brw_context *brw)
>> raster.ScissorRectangleEnable = ctx->Scissor.EnableFlags;
>>
>> /* _NEW_TRANSFORM */
>> - if (!ctx->Transform.DepthClamp) {
>> + if (!(ctx->Transform.DepthClampNear &&
>> + ctx->Transform.DepthClampFar)) {
>> #if GEN_GEN >= 9
>> raster.ViewportZFarClipTestEnable = true;
>> raster.ViewportZNearClipTestEnable = true;
>> diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c
>> index cbe93ab6fa..a46fec73fd 100644
>> --- a/src/mesa/main/attrib.c
>> +++ b/src/mesa/main/attrib.c
>> @@ -72,7 +72,8 @@ struct gl_enable_attrib
>> GLbitfield ClipPlanes;
>> GLboolean ColorMaterial;
>> GLboolean CullFace;
>> - GLboolean DepthClamp;
>> + GLboolean DepthClampNear;
>> + GLboolean DepthClampFar;
>> GLboolean DepthTest;
>> GLboolean Dither;
>> GLboolean Fog;
>> @@ -336,7 +337,8 @@ _mesa_PushAttrib(GLbitfield mask)
>> attr->ClipPlanes = ctx->Transform.ClipPlanesEnabled;
>> attr->ColorMaterial = ctx->Light.ColorMaterialEnabled;
>> attr->CullFace = ctx->Polygon.CullFlag;
>> - attr->DepthClamp = ctx->Transform.DepthClamp;
>> + attr->DepthClampNear = ctx->Transform.DepthClampNear;
>> + attr->DepthClampFar = ctx->Transform.DepthClampFar;
>> attr->DepthTest = ctx->Depth.Test;
>> attr->Dither = ctx->Color.DitherFlag;
>> attr->Fog = ctx->Fog.Enabled;
>> @@ -627,8 +629,18 @@ pop_enable_group(struct gl_context *ctx, const struct gl_enable_attrib *enable)
>> TEST_AND_UPDATE(ctx->Light.ColorMaterialEnabled, enable->ColorMaterial,
>> GL_COLOR_MATERIAL);
>> TEST_AND_UPDATE(ctx->Polygon.CullFlag, enable->CullFace, GL_CULL_FACE);
>> - TEST_AND_UPDATE(ctx->Transform.DepthClamp, enable->DepthClamp,
>> - GL_DEPTH_CLAMP);
>> +
>> + if (!ctx->Extensions.AMD_depth_clamp_separate) {
>> + TEST_AND_UPDATE(ctx->Transform.DepthClampNear && ctx->Transform.DepthClampFar,
>> + enable->DepthClampNear && enable->DepthClampFar,
>> + GL_DEPTH_CLAMP);
>> + } else {
>> + TEST_AND_UPDATE(ctx->Transform.DepthClampNear, enable->DepthClampNear,
>> + GL_DEPTH_CLAMP_NEAR_AMD);
>> + TEST_AND_UPDATE(ctx->Transform.DepthClampFar, enable->DepthClampFar,
>> + GL_DEPTH_CLAMP_FAR_AMD);
>> + }
>> +
>> TEST_AND_UPDATE(ctx->Depth.Test, enable->DepthTest, GL_DEPTH_TEST);
>> TEST_AND_UPDATE(ctx->Color.DitherFlag, enable->Dither, GL_DITHER);
>> TEST_AND_UPDATE(ctx->Fog.Enabled, enable->Fog, GL_FOG);
>> @@ -1433,9 +1445,23 @@ _mesa_PopAttrib(void)
>> if (xform->RescaleNormals != ctx->Transform.RescaleNormals)
>> _mesa_set_enable(ctx, GL_RESCALE_NORMAL_EXT,
>> ctx->Transform.RescaleNormals);
>> - if (xform->DepthClamp != ctx->Transform.DepthClamp)
>> - _mesa_set_enable(ctx, GL_DEPTH_CLAMP,
>> - ctx->Transform.DepthClamp);
>> +
>> + if (!ctx->Extensions.AMD_depth_clamp_separate) {
>> + if (xform->DepthClampNear != ctx->Transform.DepthClampNear &&
>> + xform->DepthClampFar != ctx->Transform.DepthClampFar) {
>> + _mesa_set_enable(ctx, GL_DEPTH_CLAMP,
>> + ctx->Transform.DepthClampNear &&
>> + ctx->Transform.DepthClampFar);
>> + }
>> + } else {
>> + if (xform->DepthClampNear != ctx->Transform.DepthClampNear)
>> + _mesa_set_enable(ctx, GL_DEPTH_CLAMP_NEAR_AMD,
>> + ctx->Transform.DepthClampNear);
>> + if (xform->DepthClampFar != ctx->Transform.DepthClampFar)
>> + _mesa_set_enable(ctx, GL_DEPTH_CLAMP_FAR_AMD,
>> + ctx->Transform.DepthClampFar);
>> + }
>> +
>> if (ctx->Extensions.ARB_clip_control)
>> _mesa_ClipControl(xform->ClipOrigin, xform->ClipDepthMode);
>> }
>> diff --git a/src/mesa/main/enable.c b/src/mesa/main/enable.c
>> index d1b2f3a962..30d275075d 100644
>> --- a/src/mesa/main/enable.c
>> +++ b/src/mesa/main/enable.c
>> @@ -1007,12 +1007,14 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state)
>> if (!_mesa_is_desktop_gl(ctx))
>> goto invalid_enum_error;
>> CHECK_EXTENSION(ARB_depth_clamp, cap);
>> - if (ctx->Transform.DepthClamp == state)
>> + if (ctx->Transform.DepthClampNear == state &&
>> + ctx->Transform.DepthClampFar == state)
>> return;
>> FLUSH_VERTICES(ctx, ctx->DriverFlags.NewDepthClamp ? 0 :
>> _NEW_TRANSFORM);
>> ctx->NewDriverState |= ctx->DriverFlags.NewDepthClamp;
>> - ctx->Transform.DepthClamp = state;
>> + ctx->Transform.DepthClampNear = state;
>> + ctx->Transform.DepthClampFar = state;
>> break;
>>
>> case GL_FRAGMENT_SHADER_ATI:
>> @@ -1684,7 +1686,8 @@ _mesa_IsEnabled( GLenum cap )
>> if (!_mesa_is_desktop_gl(ctx))
>> goto invalid_enum_error;
>> CHECK_EXTENSION(ARB_depth_clamp);
>> - return ctx->Transform.DepthClamp;
>> + return ctx->Transform.DepthClampNear ||
>> + ctx->Transform.DepthClampFar;
>>
>> case GL_FRAGMENT_SHADER_ATI:
>> if (ctx->API != API_OPENGL_COMPAT)
>> diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c
>> index f870b217db..16625e92e2 100644
>> --- a/src/mesa/main/get.c
>> +++ b/src/mesa/main/get.c
>> @@ -698,6 +698,10 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu
>> v->value_int_4[3] = GET_COLORMASK_BIT(ctx->Color.ColorMask, 0, 3);
>> break;
>>
>> + case GL_DEPTH_CLAMP:
>> + v->value_bool = ctx->Transform.DepthClampNear || ctx->Transform.DepthClampFar;
>> + break;
>> +
>> case GL_EDGE_FLAG:
>> v->value_bool = ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG][0] == 1.0F;
>> break;
>> diff --git a/src/mesa/main/get_hash_params.py b/src/mesa/main/get_hash_params.py
>> index 5c672a3312..ae1fc6f062 100644
>> --- a/src/mesa/main/get_hash_params.py
>> +++ b/src/mesa/main/get_hash_params.py
>> @@ -903,7 +903,7 @@ descriptor=[
>> [ "DEPTH_BOUNDS_EXT", "CONTEXT_FLOAT2(Depth.BoundsMin), extra_EXT_depth_bounds_test" ],
>>
>> # GL_ARB_depth_clamp
>> - [ "DEPTH_CLAMP", "CONTEXT_BOOL(Transform.DepthClamp), extra_ARB_depth_clamp" ],
>> + [ "DEPTH_CLAMP", "LOC_CUSTOM, TYPE_BOOLEAN, 0, extra_ARB_depth_clamp" ],
>>
>> # GL_ATI_fragment_shader
>> [ "FRAGMENT_SHADER_ATI", "CONTEXT_BOOL(ATIFragmentShader.Enabled), extra_ATI_fragment_shader" ],
>> diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
>> index 3df657cc5d..eb4ccc1804 100644
>> --- a/src/mesa/main/mtypes.h
>> +++ b/src/mesa/main/mtypes.h
>> @@ -1282,7 +1282,6 @@ struct gl_transform_attrib
>> GLboolean Normalize; /**< Normalize all normals? */
>> GLboolean RescaleNormals; /**< GL_EXT_rescale_normal */
>> GLboolean RasterPositionUnclipped; /**< GL_IBM_rasterpos_clip */
>> - GLboolean DepthClamp; /**< GL_ARB_depth_clamp */
>> GLboolean DepthClampNear; /**< GL_AMD_depth_clamp_separate */
>> GLboolean DepthClampFar; /**< GL_AMD_depth_clamp_separate */
>> /** GL_ARB_clip_control */
>> diff --git a/src/mesa/main/rastpos.c b/src/mesa/main/rastpos.c
>> index 1ca83c78b0..7dd984caa1 100644
>> --- a/src/mesa/main/rastpos.c
>> +++ b/src/mesa/main/rastpos.c
>> @@ -61,16 +61,35 @@ viewclip_point_xy( const GLfloat v[] )
>>
>>
>> /**
>> - * Clip a point against the far/near Z clipping planes.
>> + * Clip a point against the near Z clipping planes.
>> *
>> * \param v vertex vector describing the point to clip.
>> *
>> * \return zero if outside view volume, or one if inside.
>> */
>> static GLuint
>> -viewclip_point_z( const GLfloat v[] )
>> +viewclip_point_near_z( const GLfloat v[] )
>> {
>> - if (v[2] > v[3] || v[2] < -v[3] ) {
>> + if (v[2] < -v[3]) {
>> + return 0;
>> + }
>> + else {
>> + return 1;
>> + }
>> +}
>> +
>> +
>> +/**
>> + * Clip a point against the far Z clipping planes.
>> + *
>> + * \param v vertex vector describing the point to clip.
>> + *
>> + * \return zero if outside view volume, or one if inside.
>> + */
>> +static GLuint
>> +viewclip_point_far_z( const GLfloat v[] )
>> +{
>> + if (v[2] > v[3]) {
>> return 0;
>> }
>> else {
>> @@ -389,8 +408,14 @@ _mesa_RasterPos(struct gl_context *ctx, const GLfloat vObj[4])
>> TRANSFORM_POINT( clip, ctx->ProjectionMatrixStack.Top->m, eye );
>>
>> /* clip to view volume. */
>> - if (!ctx->Transform.DepthClamp) {
>> - if (viewclip_point_z(clip) == 0) {
>> + if (!ctx->Transform.DepthClampNear) {
>> + if (viewclip_point_near_z(clip) == 0) {
>> + ctx->Current.RasterPosValid = GL_FALSE;
>> + return;
>> + }
>> + }
>> + if (!ctx->Transform.DepthClampFar) {
>> + if (viewclip_point_far_z(clip) == 0) {
>> ctx->Current.RasterPosValid = GL_FALSE;
>> return;
>> }
>> @@ -420,10 +445,22 @@ _mesa_RasterPos(struct gl_context *ctx, const GLfloat vObj[4])
>> ctx->Current.RasterPos[2] = ndc[2] * scale[2] + translate[2];
>> ctx->Current.RasterPos[3] = clip[3];
>>
>> - if (ctx->Transform.DepthClamp) {
>> - ctx->Current.RasterPos[3] = CLAMP(ctx->Current.RasterPos[3],
>> - ctx->ViewportArray[0].Near,
>> - ctx->ViewportArray[0].Far);
>> + if (ctx->Transform.DepthClampNear &&
>> + ctx->Transform.DepthClampFar) {
>> + ctx->Current.RasterPos[3] = CLAMP(ctx->Current.RasterPos[3],
>> + ctx->ViewportArray[0].Near,
>> + ctx->ViewportArray[0].Far);
>> + } else {
>> + /* Clamp against near and far plane separately */
>> + if (ctx->Transform.DepthClampNear) {
>> + ctx->Current.RasterPos[3] = MIN2(ctx->ViewportArray[0].Near,
>> + ctx->ViewportArray[0].Far);
>> + }
>> +
>> + if (ctx->Transform.DepthClampFar) {
>> + ctx->Current.RasterPos[3] = MAX2(ctx->ViewportArray[0].Near,
>> + ctx->ViewportArray[0].Far);
>> + }
>
> This doesn't clamp RasterPos correctly.
>
Ohh, I see. I am just setting RasterPos to MIN and MAX. I should have handled the ranges [min(n,f), 0] for near and [0, max(n,f)] for far plane. My bad. I will also include tests to catch this case.
Thanks for pointing this out.
> Marek
>
>> }
>>
>> /* compute raster distance */
>> diff --git a/src/mesa/state_tracker/st_atom_rasterizer.c b/src/mesa/state_tracker/st_atom_rasterizer.c
>> index 0383b8ac4a..1f66b9d059 100644
>> --- a/src/mesa/state_tracker/st_atom_rasterizer.c
>> +++ b/src/mesa/state_tracker/st_atom_rasterizer.c
>> @@ -294,7 +294,8 @@ st_update_rasterizer(struct st_context *st)
>> }
>>
>> /* _NEW_TRANSFORM */
>> - raster->depth_clip = !ctx->Transform.DepthClamp;
>> + raster->depth_clip = !(ctx->Transform.DepthClampNear &&
>> + ctx->Transform.DepthClampFar);
>> raster->clip_plane_enable = ctx->Transform.ClipPlanesEnabled;
>> raster->clip_halfz = (ctx->Transform.ClipDepthMode == GL_ZERO_TO_ONE);
>>
>> diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
>> index b8895684bc..67bbb35850 100644
>> --- a/src/mesa/state_tracker/st_cb_drawpixels.c
>> +++ b/src/mesa/state_tracker/st_cb_drawpixels.c
>> @@ -677,7 +677,8 @@ draw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
>> ctx->Color._ClampFragmentColor;
>> rasterizer.half_pixel_center = 1;
>> rasterizer.bottom_edge_rule = 1;
>> - rasterizer.depth_clip = !ctx->Transform.DepthClamp;
>> + rasterizer.depth_clip = !(ctx->Transform.DepthClampNear &&
>> + ctx->Transform.DepthClampFar);
>> rasterizer.scissor = ctx->Scissor.EnableFlags;
>> cso_set_rasterizer(cso, &rasterizer);
>> }
>> diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c
>> index 87b72e8197..f50b549a97 100644
>> --- a/src/mesa/swrast/s_span.c
>> +++ b/src/mesa/swrast/s_span.c
>> @@ -1219,7 +1219,7 @@ _swrast_write_rgba_span( struct gl_context *ctx, SWspan *span)
>> if (!(span->arrayMask & SPAN_Z))
>> _swrast_span_interpolate_z(ctx, span);
>>
>> - if (ctx->Transform.DepthClamp)
>> + if (ctx->Transform.DepthClampNear && ctx->Transform.DepthClampFar)
>> _swrast_depth_clamp_span(ctx, span);
>>
>> if (_mesa_stencil_is_enabled(ctx)) {
>> diff --git a/src/mesa/tnl/t_vb_program.c b/src/mesa/tnl/t_vb_program.c
>> index 19be5eed63..8d8aca614e 100644
>> --- a/src/mesa/tnl/t_vb_program.c
>> +++ b/src/mesa/tnl/t_vb_program.c
>> @@ -143,7 +143,8 @@ do_ndc_cliptest(struct gl_context *ctx, struct vp_stage_data *store)
>> store->clipmask,
>> &store->ormask,
>> &store->andmask,
>> - !ctx->Transform.DepthClamp );
>> + !(ctx->Transform.DepthClampNear &&
>> + ctx->Transform.DepthClampFar) );
>> }
>> else {
>> VB->NdcPtr = NULL;
>> @@ -152,7 +153,8 @@ do_ndc_cliptest(struct gl_context *ctx, struct vp_stage_data *store)
>> store->clipmask,
>> &store->ormask,
>> &store->andmask,
>> - !ctx->Transform.DepthClamp );
>> + !(ctx->Transform.DepthClampNear &&
>> + ctx->Transform.DepthClampFar) );
>> }
>>
>> if (store->andmask) {
>> diff --git a/src/mesa/tnl/t_vb_vertex.c b/src/mesa/tnl/t_vb_vertex.c
>> index 71a32b4952..4fb3659a35 100644
>> --- a/src/mesa/tnl/t_vb_vertex.c
>> +++ b/src/mesa/tnl/t_vb_vertex.c
>> @@ -123,7 +123,7 @@ tnl_clip_prepare(struct gl_context *ctx)
>> /* Neither the x86 nor sparc asm cliptest functions have been updated
>> * for ARB_depth_clamp, so force the C paths.
>> */
>> - if (ctx->Transform.DepthClamp) {
>> + if (ctx->Transform.DepthClampNear && ctx->Transform.DepthClampFar) {
>> static GLboolean c_funcs_installed = GL_FALSE;
>> if (!c_funcs_installed) {
>> init_c_cliptest();
>> @@ -191,7 +191,8 @@ static GLboolean run_vertex_stage( struct gl_context *ctx,
>> store->clipmask,
>> &store->ormask,
>> &store->andmask,
>> - !ctx->Transform.DepthClamp );
>> + !(ctx->Transform.DepthClampNear &&
>> + ctx->Transform.DepthClampFar) );
>> }
>> else {
>> VB->NdcPtr = NULL;
>> @@ -200,7 +201,8 @@ static GLboolean run_vertex_stage( struct gl_context *ctx,
>> store->clipmask,
>> &store->ormask,
>> &store->andmask,
>> - !ctx->Transform.DepthClamp );
>> + !(ctx->Transform.DepthClampNear &&
>> + ctx->Transform.DepthClampFar) );
>> }
>>
>> if (store->andmask)
>> --
>> 2.17.1
>>
More information about the mesa-dev
mailing list