diff --git a/docs/gallium/cso/rasterizer.rst b/docs/gallium/cso/rasterizer.rst index e75f5886d82a02fffa9a4f229b7dab61a98b83ec..48986c07f43fa162e58c82b419030f151effaed5 100644 --- a/docs/gallium/cso/rasterizer.rst +++ b/docs/gallium/cso/rasterizer.rst @@ -326,10 +326,15 @@ clip_halfz When true clip space in the z axis goes from [0..1] (D3D). When false [-1, 1] (GL) -depth_clip - When false, the near and far depth clipping planes of the view volume are - disabled and the depth value will be clamped at the per-pixel level, after - polygon offset has been applied and before depth testing. +depth_clip_near + When false, the near depth clipping plane of the view volume is disabled. +depth_clip_far + When false, the far depth clipping plane of the view volume is disabled. +depth_clamp + Whether the depth value will be clamped to the interval defined by the + near and far depth range at the per-pixel level, after polygon offset has + been applied and before depth testing. Note that a clamp to [0,1] according + to GL rules should always happen even if this is disabled. clip_plane_enable For each k in [0, PIPE_MAX_CLIP_PLANES), if bit k of this field is set, diff --git a/docs/gallium/screen.rst b/docs/gallium/screen.rst index 879714fd403f375791fda1671498a47b608492f0..279ef397f10e9eaf458a4fe507b07558afa5c5da 100644 --- a/docs/gallium/screen.rst +++ b/docs/gallium/screen.rst @@ -80,6 +80,9 @@ The integer capabilities: disabling depth clipping (through pipe_rasterizer_state) separately for the near and far plane. If not, depth_clip_near and depth_clip_far will be equal. + ``PIPE_CAP_DEPTH_CLAMP_ENABLE``: Whether the driver is capable of + enabling depth clamping (through pipe_rasterizer_state) separately from depth + clipping. If not, depth_clamp will be the inverse of depth_clip_far. * ``PIPE_CAP_SHADER_STENCIL_EXPORT``: Whether a stencil reference value can be written from a fragment shader. * ``PIPE_CAP_TGSI_INSTANCEID``: Whether TGSI_SEMANTIC_INSTANCEID is supported diff --git a/src/gallium/auxiliary/util/u_screen.c b/src/gallium/auxiliary/util/u_screen.c index f682eede34201ba2f390dde5c12e74552cb7defe..8c519ba4e5aa4ec4c7cddf5340fa907f221e78d5 100644 --- a/src/gallium/auxiliary/util/u_screen.c +++ b/src/gallium/auxiliary/util/u_screen.c @@ -77,6 +77,7 @@ u_pipe_screen_get_param_defaults(struct pipe_screen *pscreen, case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: case PIPE_CAP_DEPTH_CLIP_DISABLE: case PIPE_CAP_DEPTH_CLIP_DISABLE_SEPARATE: + case PIPE_CAP_DEPTH_CLAMP_ENABLE: case PIPE_CAP_SHADER_STENCIL_EXPORT: case PIPE_CAP_TGSI_INSTANCEID: case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c index bedf7bb6fb3291e62b5f030179b898777a545d5e..59d2cf633cf6c64a9a31afa8081b130d0fac93f6 100644 --- a/src/gallium/drivers/llvmpipe/lp_screen.c +++ b/src/gallium/drivers/llvmpipe/lp_screen.c @@ -170,6 +170,8 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param) return 1; case PIPE_CAP_DEPTH_CLIP_DISABLE: return 1; + case PIPE_CAP_DEPTH_CLAMP_ENABLE: + return 1; case PIPE_CAP_SHADER_STENCIL_EXPORT: return 1; case PIPE_CAP_TGSI_INSTANCEID: diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index 400eafe9e5a16ae3207c71bc426612fd49f81323..23416b958e3dd93c76e06b3f56c5fc05f510e8f8 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -4165,10 +4165,8 @@ make_variant_key(struct llvmpipe_context *lp, /* * Propagate the depth clamp setting from the rasterizer state. - * depth_clip == 0 implies depth clamping is enabled. - * */ - key->depth_clamp = (lp->rasterizer->depth_clip_near == 0) ? 1 : 0; + key->depth_clamp = lp->rasterizer->depth_clamp; /* alpha test only applies if render buffer 0 is non-integer (or does not exist) */ if (!lp->framebuffer.nr_cbufs || diff --git a/src/gallium/frontends/d3d10umd/Rasterizer.cpp b/src/gallium/frontends/d3d10umd/Rasterizer.cpp index df127c793c5b3a07d66e83dad343d6670b0b5b85..48c9f75a4e75fa9cafb0d61f4d5182675493d782 100644 --- a/src/gallium/frontends/d3d10umd/Rasterizer.cpp +++ b/src/gallium/frontends/d3d10umd/Rasterizer.cpp @@ -226,6 +226,7 @@ CreateRasterizerState( state.clip_halfz = 1; state.depth_clip_near = pRasterizerDesc->DepthClipEnable ? 1 : 0; state.depth_clip_far = pRasterizerDesc->DepthClipEnable ? 1 : 0; + state.depth_clamp = 1; state.point_quad_rasterization = 1; state.point_size = 1.0f; diff --git a/src/gallium/frontends/lavapipe/lvp_device.c b/src/gallium/frontends/lavapipe/lvp_device.c index 1f2bd6843b0e210fb0dc44d88bc1e81b169d6b95..f430874d668fd13daaee57ab90d0e9771355aec3 100644 --- a/src/gallium/frontends/lavapipe/lvp_device.c +++ b/src/gallium/frontends/lavapipe/lvp_device.c @@ -129,6 +129,7 @@ static const struct vk_device_extension_table lvp_device_extensions_supported = .EXT_calibrated_timestamps = true, .EXT_color_write_enable = true, .EXT_conditional_rendering = true, + .EXT_depth_clip_enable = true, .EXT_extended_dynamic_state = true, .EXT_extended_dynamic_state2 = true, .EXT_external_memory_host = true, @@ -668,6 +669,15 @@ VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceFeatures2( features->multiDraw = true; break; } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT: { + VkPhysicalDeviceDepthClipEnableFeaturesEXT *features = + (VkPhysicalDeviceDepthClipEnableFeaturesEXT *)ext; + if (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_DEPTH_CLAMP_ENABLE) != 0) + features->depthClipEnable = true; + else + features->depthClipEnable = false; + break; + } case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_2_FEATURES_EXT: { VkPhysicalDeviceExtendedDynamicState2FeaturesEXT *features = (VkPhysicalDeviceExtendedDynamicState2FeaturesEXT *)ext; features->extendedDynamicState2 = true; diff --git a/src/gallium/frontends/lavapipe/lvp_execute.c b/src/gallium/frontends/lavapipe/lvp_execute.c index 919b7ee08ce85594d054a642615e48cf951a0738..8d7dbcc5d6dce4ed517a165c8f507218c88940e4 100644 --- a/src/gallium/frontends/lavapipe/lvp_execute.c +++ b/src/gallium/frontends/lavapipe/lvp_execute.c @@ -526,7 +526,14 @@ static void handle_graphics_pipeline(struct vk_cmd_queue_entry *cmd, /* rasterization state */ if (pipeline->graphics_create_info.pRasterizationState) { const VkPipelineRasterizationStateCreateInfo *rsc = pipeline->graphics_create_info.pRasterizationState; - state->rs_state.depth_clip_near = state->rs_state.depth_clip_far = !rsc->depthClampEnable; + const VkPipelineRasterizationDepthClipStateCreateInfoEXT *depth_clip_state = + vk_find_struct_const(rsc->pNext, PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT); + state->rs_state.depth_clamp = rsc->depthClampEnable; + if (!depth_clip_state) + state->rs_state.depth_clip_near = state->rs_state.depth_clip_far = !rsc->depthClampEnable; + else + state->rs_state.depth_clip_near = state->rs_state.depth_clip_far = depth_clip_state->depthClipEnable; + if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT)]) state->rs_state.rasterizer_discard = rsc->rasterizerDiscardEnable; diff --git a/src/gallium/frontends/lavapipe/lvp_pipeline.c b/src/gallium/frontends/lavapipe/lvp_pipeline.c index 94002b8c451452c4ddeec974d2c2bd3229e075eb..07172fd789fd99e4c2d6b6669b568a47bb795ad7 100644 --- a/src/gallium/frontends/lavapipe/lvp_pipeline.c +++ b/src/gallium/frontends/lavapipe/lvp_pipeline.c @@ -127,7 +127,7 @@ deep_copy_vertex_input_state(void *mem_ctx, vk_foreach_struct(ext, src->pNext) { switch (ext->sType) { case VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT: { - VkPipelineVertexInputDivisorStateCreateInfoEXT *ext_src = (VkPipelineVertexInputDivisorStateCreateInfoEXT *)ext;; + VkPipelineVertexInputDivisorStateCreateInfoEXT *ext_src = (VkPipelineVertexInputDivisorStateCreateInfoEXT *)ext; VkPipelineVertexInputDivisorStateCreateInfoEXT *ext_dst = ralloc(mem_ctx, VkPipelineVertexInputDivisorStateCreateInfoEXT); ext_dst->sType = ext_src->sType; @@ -239,6 +239,35 @@ deep_copy_dynamic_state(void *mem_ctx, return VK_SUCCESS; } + +static VkResult +deep_copy_rasterization_state(void *mem_ctx, + VkPipelineRasterizationStateCreateInfo *dst, + const VkPipelineRasterizationStateCreateInfo *src) +{ + memcpy(dst, src, sizeof(VkPipelineRasterizationStateCreateInfo)); + dst->pNext = NULL; + + if (src->pNext) { + vk_foreach_struct(ext, src->pNext) { + switch (ext->sType) { + case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT: { + VkPipelineRasterizationDepthClipStateCreateInfoEXT *ext_src = (VkPipelineRasterizationDepthClipStateCreateInfoEXT *)ext; + VkPipelineRasterizationDepthClipStateCreateInfoEXT *ext_dst = ralloc(mem_ctx, VkPipelineRasterizationDepthClipStateCreateInfoEXT); + ext_dst->sType = ext_src->sType; + ext_dst->flags = ext_src->flags; + ext_dst->depthClipEnable = ext_src->depthClipEnable; + dst->pNext = ext_dst; + break; + } + default: + break; + } + } + } + return VK_SUCCESS; +} + static VkResult deep_copy_graphics_create_info(void *mem_ctx, VkGraphicsPipelineCreateInfo *dst, @@ -248,6 +277,7 @@ deep_copy_graphics_create_info(void *mem_ctx, VkResult result; VkPipelineShaderStageCreateInfo *stages; VkPipelineVertexInputStateCreateInfo *vertex_input; + VkPipelineRasterizationStateCreateInfo *rasterization_state; LVP_FROM_HANDLE(lvp_render_pass, pass, src->renderPass); dst->sType = src->sType; @@ -313,10 +343,11 @@ deep_copy_graphics_create_info(void *mem_ctx, dst->pViewportState = NULL; /* pRasterizationState */ - LVP_PIPELINE_DUP(dst->pRasterizationState, - src->pRasterizationState, - VkPipelineRasterizationStateCreateInfo, - 1); + rasterization_state = ralloc(mem_ctx, VkPipelineRasterizationStateCreateInfo); + if (!rasterization_state) + return VK_ERROR_OUT_OF_HOST_MEMORY; + deep_copy_rasterization_state(mem_ctx, rasterization_state, src->pRasterizationState); + dst->pRasterizationState = rasterization_state; /* pMultisampleState */ if (src->pMultisampleState && !rasterization_disabled) { diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index 6f4fd7e7e06a63177a762b2b69a640248c698250..908b74e85096b49bafeb2d09f056cb3d9571d49f 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -764,6 +764,7 @@ enum pipe_cap PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER, PIPE_CAP_DEPTH_CLIP_DISABLE, PIPE_CAP_DEPTH_CLIP_DISABLE_SEPARATE, + PIPE_CAP_DEPTH_CLAMP_ENABLE, PIPE_CAP_SHADER_STENCIL_EXPORT, PIPE_CAP_TGSI_INSTANCEID, PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR, diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 785a5906237a808eace187a811c360360f2d211d..63833a8b19f0b5b6d3d9046d5c08e4b1d332bb49 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -162,6 +162,13 @@ struct pipe_rasterizer_state unsigned depth_clip_near:1; unsigned depth_clip_far:1; + /** + * When true, depth clamp is enabled. + * If PIPE_CAP_DEPTH_CLAMP_ENABLE is unsupported, this is always the inverse + * of depth_clip_far. + */ + unsigned depth_clamp:1; + /** * When true clip space in the z axis goes from [0..1] (D3D). When false * [-1, 1] (GL). diff --git a/src/mesa/state_tracker/st_atom_rasterizer.c b/src/mesa/state_tracker/st_atom_rasterizer.c index d03b1b3f5c656167723a050f38dcd3efa50a1838..f4a788eea6585a67923e0bd220293b6a5c2c3d11 100644 --- a/src/mesa/state_tracker/st_atom_rasterizer.c +++ b/src/mesa/state_tracker/st_atom_rasterizer.c @@ -300,6 +300,7 @@ st_update_rasterizer(struct st_context *st) !ctx->Transform.DepthClampNear; raster->depth_clip_far = st->clamp_frag_depth_in_shader || !ctx->Transform.DepthClampFar; + raster->depth_clamp = !raster->depth_clip_far; 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 d3a392ca2c4f13289c2a32eec9d0544380f94405..c7c8f94aab4ee198f516c4c35273e96d36d5c7d2 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -789,6 +789,7 @@ draw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z, !ctx->Transform.DepthClampNear; rasterizer.depth_clip_far = st->clamp_frag_depth_in_shader || !ctx->Transform.DepthClampFar; + rasterizer.depth_clamp = !rasterizer.depth_clip_far; rasterizer.scissor = ctx->Scissor.EnableFlags; cso_set_rasterizer(cso, &rasterizer); }