From 4e2c5ba10075b3527904a98aea501f87acd2fff7 Mon Sep 17 00:00:00 2001 From: Jesse Natalie Date: Thu, 20 Apr 2023 10:21:55 -0700 Subject: [PATCH] dzn: Use narrow quadrilateral lines when supported This lets us follow the Vulkan spec requirements for MSAA line rasterization, using a width of 1.0 instead of D3D's proscribed width of 1.4. There's no reason to predicate this on MSAA being enabled, since quadrilateral lines with a width of 1.0 are actually the most desired type of line rasterization for Vulkan. Follow-ups: - We can probably turn on 'strict lines' when this is supported. - We should enable the line rasterization mode extension. Part-of: --- src/microsoft/vulkan/dzn_pipeline.c | 74 ++++++++++++++++++----------- src/microsoft/vulkan/dzn_private.h | 3 +- 2 files changed, 48 insertions(+), 29 deletions(-) diff --git a/src/microsoft/vulkan/dzn_pipeline.c b/src/microsoft/vulkan/dzn_pipeline.c index a8611462a83..8181de24618 100644 --- a/src/microsoft/vulkan/dzn_pipeline.c +++ b/src/microsoft/vulkan/dzn_pipeline.c @@ -1312,35 +1312,53 @@ dzn_graphics_pipeline_translate_rast(struct dzn_device *device, } } - static_assert(sizeof(D3D12_RASTERIZER_DESC) == sizeof(D3D12_RASTERIZER_DESC1), "Casting between these"); - D3D12_PIPELINE_STATE_SUBOBJECT_TYPE rast_type = pdev->options16.DynamicDepthBiasSupported ? - D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RASTERIZER1 : - D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RASTERIZER; - d3d12_pipeline_state_stream_new_desc(out, MAX_GFX_PIPELINE_STATE_STREAM_SIZE, rast_type, D3D12_RASTERIZER_DESC, desc); - pipeline->templates.desc_offsets.rast = - (uintptr_t)desc - (uintptr_t)out->pPipelineStateSubobjectStream; - desc->DepthClipEnable = !in_rast->depthClampEnable; - desc->FillMode = translate_polygon_mode(in_rast->polygonMode); - desc->CullMode = translate_cull_mode(in_rast->cullMode); - desc->FrontCounterClockwise = - in_rast->frontFace == VK_FRONT_FACE_COUNTER_CLOCKWISE; - if (in_rast->depthBiasEnable) { - if (rast_type == D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RASTERIZER1) - ((D3D12_RASTERIZER_DESC1 *)desc)->DepthBias = in_rast->depthBiasConstantFactor; - else - desc->DepthBias = translate_depth_bias(in_rast->depthBiasConstantFactor); - desc->SlopeScaledDepthBias = in_rast->depthBiasSlopeFactor; - desc->DepthBiasClamp = in_rast->depthBiasClamp; - } + if (pdev->options19.NarrowQuadrilateralLinesSupported) { + assert(pdev->options16.DynamicDepthBiasSupported); + d3d12_gfx_pipeline_state_stream_new_desc(out, RASTERIZER2, D3D12_RASTERIZER_DESC2, desc); + pipeline->templates.desc_offsets.rast = + (uintptr_t)desc - (uintptr_t)out->pPipelineStateSubobjectStream; + desc->DepthClipEnable = !in_rast->depthClampEnable; + desc->FillMode = translate_polygon_mode(in_rast->polygonMode); + desc->CullMode = translate_cull_mode(in_rast->cullMode); + desc->FrontCounterClockwise = + in_rast->frontFace == VK_FRONT_FACE_COUNTER_CLOCKWISE; + if (in_rast->depthBiasEnable) { + desc->DepthBias = in_rast->depthBiasConstantFactor; + desc->SlopeScaledDepthBias = in_rast->depthBiasSlopeFactor; + desc->DepthBiasClamp = in_rast->depthBiasClamp; + } + desc->LineRasterizationMode = D3D12_LINE_RASTERIZATION_MODE_QUADRILATERAL_NARROW; + } else { + static_assert(sizeof(D3D12_RASTERIZER_DESC) == sizeof(D3D12_RASTERIZER_DESC1), "Casting between these"); + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE rast_type = pdev->options16.DynamicDepthBiasSupported ? + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RASTERIZER1 : + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RASTERIZER; + d3d12_pipeline_state_stream_new_desc(out, MAX_GFX_PIPELINE_STATE_STREAM_SIZE, rast_type, D3D12_RASTERIZER_DESC, desc); + pipeline->templates.desc_offsets.rast = + (uintptr_t)desc - (uintptr_t)out->pPipelineStateSubobjectStream; + desc->DepthClipEnable = !in_rast->depthClampEnable; + desc->FillMode = translate_polygon_mode(in_rast->polygonMode); + desc->CullMode = translate_cull_mode(in_rast->cullMode); + desc->FrontCounterClockwise = + in_rast->frontFace == VK_FRONT_FACE_COUNTER_CLOCKWISE; + if (in_rast->depthBiasEnable) { + if (rast_type == D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RASTERIZER1) + ((D3D12_RASTERIZER_DESC1 *)desc)->DepthBias = in_rast->depthBiasConstantFactor; + else + desc->DepthBias = translate_depth_bias(in_rast->depthBiasConstantFactor); + desc->SlopeScaledDepthBias = in_rast->depthBiasSlopeFactor; + desc->DepthBiasClamp = in_rast->depthBiasClamp; + } - /* The Vulkan conformance tests use different reference rasterizers for single-sampled - * and multi-sampled lines. The single-sampled lines can be bresenham lines, but multi- - * sampled need to be quadrilateral lines. This still isn't *quite* sufficient, because - * D3D only supports a line width of 1.4 (per spec), but Vulkan requires us to support - * 1.0 (and without claiming wide lines, that's all we can support). - */ - if (in_ms && in_ms->rasterizationSamples > 1) - desc->MultisampleEnable = true; + /* The Vulkan conformance tests use different reference rasterizers for single-sampled + * and multi-sampled lines. The single-sampled lines can be bresenham lines, but multi- + * sampled need to be quadrilateral lines. This still isn't *quite* sufficient, because + * D3D only supports a line width of 1.4 (per spec), but Vulkan requires us to support + * 1.0 (and without claiming wide lines, that's all we can support). + */ + if (in_ms && in_ms->rasterizationSamples > 1) + desc->MultisampleEnable = true; + } assert(in_rast->lineWidth == 1.0f); } diff --git a/src/microsoft/vulkan/dzn_private.h b/src/microsoft/vulkan/dzn_private.h index f60365b1fb5..3a93b5d8218 100644 --- a/src/microsoft/vulkan/dzn_private.h +++ b/src/microsoft/vulkan/dzn_private.h @@ -869,7 +869,8 @@ enum dzn_register_space { static_assert(sizeof(D3D12_DEPTH_STENCIL_DESC2) > sizeof(D3D12_DEPTH_STENCIL_DESC1), "Using just one of these descs in the max size calculation"); -static_assert(sizeof(D3D12_RASTERIZER_DESC) == sizeof(D3D12_RASTERIZER_DESC1), +static_assert(sizeof(D3D12_RASTERIZER_DESC) >= sizeof(D3D12_RASTERIZER_DESC1) && + sizeof(D3D12_RASTERIZER_DESC) >= sizeof(D3D12_RASTERIZER_DESC2), "Using just one of these descs in the max size calculation"); #define MAX_GFX_PIPELINE_STATE_STREAM_SIZE \