From 8cc6f058ce30d77e45bc26d4769a7adde46deb11 Mon Sep 17 00:00:00 2001 From: Chad Versace Date: Tue, 26 Jan 2016 10:56:06 -0800 Subject: [PATCH] anv/gen8: Begin enabling pipeline multisample state As far as I can tell, this patch sets all pipeline multisample state except: - alpha to coverage - alpha to one - the dispatch count for per-sample dispatch --- src/vulkan/anv_device.c | 2 +- src/vulkan/anv_pipeline.c | 3 - src/vulkan/gen7_pipeline.c | 4 + src/vulkan/gen8_pipeline.c | 146 +++++++++++++++++++++++++++++++++---- 4 files changed, 137 insertions(+), 18 deletions(-) diff --git a/src/vulkan/anv_device.c b/src/vulkan/anv_device.c index f116f9a7354..adf33a84cf4 100644 --- a/src/vulkan/anv_device.c +++ b/src/vulkan/anv_device.c @@ -502,7 +502,7 @@ void anv_GetPhysicalDeviceProperties( .pointSizeGranularity = (1.0 / 8.0), .lineWidthGranularity = (1.0 / 128.0), .strictLines = false, /* FINISHME */ - .standardSampleLocations = true, /* FINISHME */ + .standardSampleLocations = true, .optimalBufferCopyOffsetAlignment = 128, .optimalBufferCopyRowPitchAlignment = 128, .nonCoherentAtomSize = 64, diff --git a/src/vulkan/anv_pipeline.c b/src/vulkan/anv_pipeline.c index e879b35388d..106b9221dd7 100644 --- a/src/vulkan/anv_pipeline.c +++ b/src/vulkan/anv_pipeline.c @@ -1077,9 +1077,6 @@ anv_pipeline_init(struct anv_pipeline *pipeline, if (pCreateInfo->pTessellationState) anv_finishme("VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO"); - if (pCreateInfo->pMultisampleState && - pCreateInfo->pMultisampleState->rasterizationSamples > 1) - anv_finishme("VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO"); pipeline->use_repclear = extra && extra->use_repclear; pipeline->writes_point_size = false; diff --git a/src/vulkan/gen7_pipeline.c b/src/vulkan/gen7_pipeline.c index ea5b3401121..7b5330e7448 100644 --- a/src/vulkan/gen7_pipeline.c +++ b/src/vulkan/gen7_pipeline.c @@ -269,6 +269,10 @@ genX(graphics_pipeline_create)( .MaximumPointWidth = 255.875, .MaximumVPIndex = pCreateInfo->pViewportState->viewportCount - 1); + if (pCreateInfo->pMultisampleState && + pCreateInfo->pMultisampleState->rasterizationSamples > 1) + anv_finishme("VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO"); + uint32_t samples = 1; uint32_t log2_samples = __builtin_ffs(samples) - 1; diff --git a/src/vulkan/gen8_pipeline.c b/src/vulkan/gen8_pipeline.c index 5d6b87064e9..1e9aa0e12bc 100644 --- a/src/vulkan/gen8_pipeline.c +++ b/src/vulkan/gen8_pipeline.c @@ -46,8 +46,14 @@ emit_ia_state(struct anv_pipeline *pipeline, static void emit_rs_state(struct anv_pipeline *pipeline, const VkPipelineRasterizationStateCreateInfo *info, + const VkPipelineMultisampleStateCreateInfo *ms_info, const struct anv_graphics_pipeline_create_info *extra) { + uint32_t samples = 1; + + if (ms_info) + samples = ms_info->rasterizationSamples; + struct GENX(3DSTATE_SF) sf = { GENX(3DSTATE_SF_header), .ViewportTransformEnable = !(extra && extra->disable_viewport), @@ -64,6 +70,14 @@ emit_rs_state(struct anv_pipeline *pipeline, struct GENX(3DSTATE_RASTER) raster = { GENX(3DSTATE_RASTER_header), + + /* For details on 3DSTATE_RASTER multisample state, see the BSpec table + * "Multisample Modes State". + */ + .DXMultisampleRasterizationEnable = samples > 1, + .ForcedSampleCount = FSC_NUMRASTSAMPLES_0, + .ForceMultisampling = false, + .FrontWinding = vk_to_gen_front_face[info->frontFace], .CullMode = vk_to_gen_cullmode[info->cullMode], .FrontFaceFillMode = vk_to_gen_fillmode[info->polygonMode], @@ -193,6 +207,118 @@ emit_ds_state(struct anv_pipeline *pipeline, GENX(3DSTATE_WM_DEPTH_STENCIL_pack)(NULL, dw, &wm_depth_stencil); } +static void +emit_ms_state(struct anv_pipeline *pipeline, + const VkPipelineMultisampleStateCreateInfo *info) +{ + uint32_t samples = 1; + uint32_t log2_samples = 0; + + /* From the Vulkan 1.0 spec: + * If pSampleMask is NULL, it is treated as if the mask has all bits + * enabled, i.e. no coverage is removed from fragments. + * + * 3DSTATE_SAMPLE_MASK.SampleMask is 16 bits. + */ + uint32_t sample_mask = 0xffff; + + if (info) { + samples = info->rasterizationSamples; + log2_samples = __builtin_ffs(samples) - 1; + } + + if (info && info->pSampleMask) + sample_mask &= info->pSampleMask[0]; + + if (info && info->sampleShadingEnable) + anv_finishme("VkPipelineMultisampleStateCreateInfo::sampleShadingEnable"); + + anv_batch_emit(&pipeline->batch, GENX(3DSTATE_MULTISAMPLE), + + /* The PRM says that this bit is valid only for DX9: + * + * SW can choose to set this bit only for DX9 API. DX10/OGL API's + * should not have any effect by setting or not setting this bit. + */ + .PixelPositionOffsetEnable = false, + + .PixelLocation = CENTER, + .NumberofMultisamples = log2_samples); + + anv_batch_emit(&pipeline->batch, GENX(3DSTATE_SAMPLE_MASK), + .SampleMask = sample_mask); + + /* See the Vulkan 1.0 spec Table 24.1 "Standard sample locations" and + * VkPhysicalDeviceFeatures::standardSampleLocations. + */ + anv_batch_emit(&pipeline->batch, GENX(3DSTATE_SAMPLE_PATTERN), + ._1xSample0XOffset = 0.5, + ._1xSample0YOffset = 0.5, + ._2xSample0XOffset = 0.25, + ._2xSample0YOffset = 0.25, + ._2xSample1XOffset = 0.75, + ._2xSample1YOffset = 0.75, + ._4xSample0XOffset = 0.375, + ._4xSample0YOffset = 0.125, + ._4xSample1XOffset = 0.875, + ._4xSample1YOffset = 0.375, + ._4xSample2XOffset = 0.125, + ._4xSample2YOffset = 0.625, + ._4xSample3XOffset = 0.625, + ._4xSample3YOffset = 0.875, + ._8xSample0XOffset = 0.5625, + ._8xSample0YOffset = 0.3125, + ._8xSample1XOffset = 0.4375, + ._8xSample1YOffset = 0.6875, + ._8xSample2XOffset = 0.8125, + ._8xSample2YOffset = 0.5625, + ._8xSample3XOffset = 0.3125, + ._8xSample3YOffset = 0.1875, + ._8xSample4XOffset = 0.1875, + ._8xSample4YOffset = 0.8125, + ._8xSample5XOffset = 0.0625, + ._8xSample5YOffset = 0.4375, + ._8xSample6XOffset = 0.6875, + ._8xSample6YOffset = 0.9375, + ._8xSample7XOffset = 0.9375, + ._8xSample7YOffset = 0.0625, +#if ANV_GEN >= 9 + ._16xSample0XOffset = 0.5625, + ._16xSample0YOffset = 0.5625, + ._16xSample1XOffset = 0.4375, + ._16xSample1YOffset = 0.3125, + ._16xSample2XOffset = 0.3125, + ._16xSample2YOffset = 0.6250, + ._16xSample3XOffset = 0.7500, + ._16xSample3YOffset = 0.4375, + ._16xSample4XOffset = 0.1875, + ._16xSample4YOffset = 0.3750, + ._16xSample5XOffset = 0.6250, + ._16xSample5YOffset = 0.8125, + ._16xSample6XOffset = 0.8125, + ._16xSample6YOffset = 0.6875, + ._16xSample7XOffset = 0.6875, + ._16xSample7YOffset = 0.1875, + ._16xSample8XOffset = 0.3750, + ._16xSample8YOffset = 0.8750, + ._16xSample9XOffset = 0.5000, + ._16xSample9YOffset = 0.0625, + ._16xSample10XOffset = 0.2500, + ._16xSample10YOffset = 0.1250, + ._16xSample11XOffset = 0.1250, + ._16xSample11YOffset = 0.7500, + ._16xSample12XOffset = 0.0000, + ._16xSample12YOffset = 0.5000, + ._16xSample13XOffset = 0.9375, + ._16xSample13YOffset = 0.2500, + ._16xSample14XOffset = 0.8750, + ._16xSample14YOffset = 0.9375, + ._16xSample15XOffset = 0.0625, + ._16xSample15YOffset = 0.0000, +#endif + ); +} + VkResult genX(graphics_pipeline_create)( VkDevice _device, @@ -226,7 +352,9 @@ genX(graphics_pipeline_create)( assert(pCreateInfo->pInputAssemblyState); emit_ia_state(pipeline, pCreateInfo->pInputAssemblyState, extra); assert(pCreateInfo->pRasterizationState); - emit_rs_state(pipeline, pCreateInfo->pRasterizationState, extra); + emit_rs_state(pipeline, pCreateInfo->pRasterizationState, + pCreateInfo->pMultisampleState, extra); + emit_ms_state(pipeline, pCreateInfo->pMultisampleState); emit_ds_state(pipeline, pCreateInfo->pDepthStencilState); emit_cb_state(pipeline, pCreateInfo->pColorBlendState, pCreateInfo->pMultisampleState); @@ -270,18 +398,6 @@ genX(graphics_pipeline_create)( pipeline->ps_ksp0 == NO_KERNEL ? 0 : pipeline->wm_prog_data.barycentric_interp_modes); - uint32_t samples = 1; - uint32_t log2_samples = __builtin_ffs(samples) - 1; - bool enable_sampling = samples > 1 ? true : false; - - anv_batch_emit(&pipeline->batch, GENX(3DSTATE_MULTISAMPLE), - .PixelPositionOffsetEnable = enable_sampling, - .PixelLocation = CENTER, - .NumberofMultisamples = log2_samples); - - anv_batch_emit(&pipeline->batch, GENX(3DSTATE_SAMPLE_MASK), - .SampleMask = 0xffff); - anv_batch_emit(&pipeline->batch, GENX(3DSTATE_URB_VS), .VSURBStartingAddress = pipeline->urb.vs_start, .VSURBEntryAllocationSize = pipeline->urb.vs_size - 1, @@ -530,7 +646,9 @@ genX(graphics_pipeline_create)( .KernelStartPointer1 = 0, .KernelStartPointer2 = pipeline->ps_ksp2); - bool per_sample_ps = false; + bool per_sample_ps = pCreateInfo->pMultisampleState && + pCreateInfo->pMultisampleState->sampleShadingEnable; + anv_batch_emit(&pipeline->batch, GENX(3DSTATE_PS_EXTRA), .PixelShaderValid = true, .PixelShaderKillsPixel = wm_prog_data->uses_kill, -- 2.30.2