From: Jason Ekstrand Date: Fri, 15 Jul 2016 01:00:50 +0000 (-0700) Subject: anv/pipeline: Unify blend state setup between gen7 and gen8 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a2e7b2e6538a87c60219319456f55cb42298745c;p=mesa.git anv/pipeline: Unify blend state setup between gen7 and gen8 This fixes all 674 broken dEQP-VK.pipeline.blend Vulkan CTS tests on Haswell. Signed-off-by: Jason Ekstrand Reviewed-by: Kenneth Graunke Cc: "12.0" --- diff --git a/src/intel/vulkan/gen7_pipeline.c b/src/intel/vulkan/gen7_pipeline.c index dba24e78ac1..01c04f3fe77 100644 --- a/src/intel/vulkan/gen7_pipeline.c +++ b/src/intel/vulkan/gen7_pipeline.c @@ -75,77 +75,6 @@ gen7_emit_rs_state(struct anv_pipeline *pipeline, GENX(3DSTATE_SF_pack)(NULL, &pipeline->gen7.sf, &sf); } -static void -gen7_emit_cb_state(struct anv_pipeline *pipeline, - const VkPipelineColorBlendStateCreateInfo *info, - const VkPipelineMultisampleStateCreateInfo *ms_info) -{ - struct anv_device *device = pipeline->device; - - if (info == NULL || info->attachmentCount == 0) { - pipeline->blend_state = - anv_state_pool_emit(&device->dynamic_state_pool, - GENX(BLEND_STATE), 64, - .Entry = { { - .ColorBufferBlendEnable = false, - .WriteDisableAlpha = true, - .WriteDisableRed = true, - .WriteDisableGreen = true, - .WriteDisableBlue = true - } }); - } else { - const VkPipelineColorBlendAttachmentState *a = &info->pAttachments[0]; - struct GENX(BLEND_STATE) blend = { .Entry = { { - .AlphaToCoverageEnable = ms_info && ms_info->alphaToCoverageEnable, - .AlphaToOneEnable = ms_info && ms_info->alphaToOneEnable, - .LogicOpEnable = info->logicOpEnable, - .LogicOpFunction = vk_to_gen_logic_op[info->logicOp], - .ColorBufferBlendEnable = a->blendEnable, - .ColorClampRange = COLORCLAMP_RTFORMAT, - .PreBlendColorClampEnable = true, - .PostBlendColorClampEnable = true, - .SourceBlendFactor = vk_to_gen_blend[a->srcColorBlendFactor], - .DestinationBlendFactor = vk_to_gen_blend[a->dstColorBlendFactor], - .ColorBlendFunction = vk_to_gen_blend_op[a->colorBlendOp], - .SourceAlphaBlendFactor = vk_to_gen_blend[a->srcAlphaBlendFactor], - .DestinationAlphaBlendFactor = vk_to_gen_blend[a->dstAlphaBlendFactor], - .AlphaBlendFunction = vk_to_gen_blend_op[a->alphaBlendOp], - .WriteDisableAlpha = !(a->colorWriteMask & VK_COLOR_COMPONENT_A_BIT), - .WriteDisableRed = !(a->colorWriteMask & VK_COLOR_COMPONENT_R_BIT), - .WriteDisableGreen = !(a->colorWriteMask & VK_COLOR_COMPONENT_G_BIT), - .WriteDisableBlue = !(a->colorWriteMask & VK_COLOR_COMPONENT_B_BIT), - } } }; - - /* Our hardware applies the blend factor prior to the blend function - * regardless of what function is used. Technically, this means the - * hardware can do MORE than GL or Vulkan specify. However, it also - * means that, for MIN and MAX, we have to stomp the blend factor to - * ONE to make it a no-op. - */ - if (a->colorBlendOp == VK_BLEND_OP_MIN || - a->colorBlendOp == VK_BLEND_OP_MAX) { - blend.Entry[0].SourceBlendFactor = BLENDFACTOR_ONE; - blend.Entry[0].DestinationBlendFactor = BLENDFACTOR_ONE; - } - if (a->alphaBlendOp == VK_BLEND_OP_MIN || - a->alphaBlendOp == VK_BLEND_OP_MAX) { - blend.Entry[0].SourceAlphaBlendFactor = BLENDFACTOR_ONE; - blend.Entry[0].DestinationAlphaBlendFactor = BLENDFACTOR_ONE; - } - - pipeline->blend_state = anv_state_pool_alloc(&device->dynamic_state_pool, - GENX(BLEND_STATE_length) * 4, - 64); - GENX(BLEND_STATE_pack)(NULL, pipeline->blend_state.map, &blend); - if (pipeline->device->info.has_llc) - anv_state_clflush(pipeline->blend_state); - } - - anv_batch_emit(&pipeline->batch, GENX(3DSTATE_BLEND_STATE_POINTERS), bsp) { - bsp.BlendStatePointer = pipeline->blend_state.offset; - } -} - VkResult genX(graphics_pipeline_create)( VkDevice _device, @@ -183,8 +112,8 @@ genX(graphics_pipeline_create)( emit_ds_state(pipeline, pCreateInfo->pDepthStencilState, pass, subpass); - gen7_emit_cb_state(pipeline, pCreateInfo->pColorBlendState, - pCreateInfo->pMultisampleState); + emit_cb_state(pipeline, pCreateInfo->pColorBlendState, + pCreateInfo->pMultisampleState); emit_urb_setup(pipeline); diff --git a/src/intel/vulkan/gen8_pipeline.c b/src/intel/vulkan/gen8_pipeline.c index 6d70df6921c..4908bbd796d 100644 --- a/src/intel/vulkan/gen8_pipeline.c +++ b/src/intel/vulkan/gen8_pipeline.c @@ -99,123 +99,6 @@ emit_rs_state(struct anv_pipeline *pipeline, GENX(3DSTATE_RASTER_pack)(NULL, pipeline->gen8.raster, &raster); } -static void -emit_cb_state(struct anv_pipeline *pipeline, - const VkPipelineColorBlendStateCreateInfo *info, - const VkPipelineMultisampleStateCreateInfo *ms_info) -{ - struct anv_device *device = pipeline->device; - - uint32_t num_dwords = GENX(BLEND_STATE_length); - pipeline->blend_state = - anv_state_pool_alloc(&device->dynamic_state_pool, num_dwords * 4, 64); - - struct GENX(BLEND_STATE) blend_state = { - .AlphaToCoverageEnable = ms_info && ms_info->alphaToCoverageEnable, - .AlphaToOneEnable = ms_info && ms_info->alphaToOneEnable, - }; - - /* Default everything to disabled */ - for (uint32_t i = 0; i < 8; i++) { - blend_state.Entry[i].WriteDisableAlpha = true; - blend_state.Entry[i].WriteDisableRed = true; - blend_state.Entry[i].WriteDisableGreen = true; - blend_state.Entry[i].WriteDisableBlue = true; - } - - struct anv_pipeline_bind_map *map = - &pipeline->bindings[MESA_SHADER_FRAGMENT]; - - bool has_writeable_rt = false; - for (unsigned i = 0; i < map->surface_count; i++) { - struct anv_pipeline_binding *binding = &map->surface_to_descriptor[i]; - - /* All color attachments are at the beginning of the binding table */ - if (binding->set != ANV_DESCRIPTOR_SET_COLOR_ATTACHMENTS) - break; - - /* We can have at most 8 attachments */ - assert(i < 8); - - if (binding->index >= info->attachmentCount) - continue; - - assert(binding->binding == 0); - const VkPipelineColorBlendAttachmentState *a = - &info->pAttachments[binding->index]; - - if (a->srcColorBlendFactor != a->srcAlphaBlendFactor || - a->dstColorBlendFactor != a->dstAlphaBlendFactor || - a->colorBlendOp != a->alphaBlendOp) { - blend_state.IndependentAlphaBlendEnable = true; - } - - blend_state.Entry[i] = (struct GENX(BLEND_STATE_ENTRY)) { - .LogicOpEnable = info->logicOpEnable, - .LogicOpFunction = vk_to_gen_logic_op[info->logicOp], - .ColorBufferBlendEnable = a->blendEnable, - .PreBlendSourceOnlyClampEnable = false, - .ColorClampRange = COLORCLAMP_RTFORMAT, - .PreBlendColorClampEnable = true, - .PostBlendColorClampEnable = true, - .SourceBlendFactor = vk_to_gen_blend[a->srcColorBlendFactor], - .DestinationBlendFactor = vk_to_gen_blend[a->dstColorBlendFactor], - .ColorBlendFunction = vk_to_gen_blend_op[a->colorBlendOp], - .SourceAlphaBlendFactor = vk_to_gen_blend[a->srcAlphaBlendFactor], - .DestinationAlphaBlendFactor = vk_to_gen_blend[a->dstAlphaBlendFactor], - .AlphaBlendFunction = vk_to_gen_blend_op[a->alphaBlendOp], - .WriteDisableAlpha = !(a->colorWriteMask & VK_COLOR_COMPONENT_A_BIT), - .WriteDisableRed = !(a->colorWriteMask & VK_COLOR_COMPONENT_R_BIT), - .WriteDisableGreen = !(a->colorWriteMask & VK_COLOR_COMPONENT_G_BIT), - .WriteDisableBlue = !(a->colorWriteMask & VK_COLOR_COMPONENT_B_BIT), - }; - - if (a->colorWriteMask != 0) - has_writeable_rt = true; - - /* Our hardware applies the blend factor prior to the blend function - * regardless of what function is used. Technically, this means the - * hardware can do MORE than GL or Vulkan specify. However, it also - * means that, for MIN and MAX, we have to stomp the blend factor to - * ONE to make it a no-op. - */ - if (a->colorBlendOp == VK_BLEND_OP_MIN || - a->colorBlendOp == VK_BLEND_OP_MAX) { - blend_state.Entry[i].SourceBlendFactor = BLENDFACTOR_ONE; - blend_state.Entry[i].DestinationBlendFactor = BLENDFACTOR_ONE; - } - if (a->alphaBlendOp == VK_BLEND_OP_MIN || - a->alphaBlendOp == VK_BLEND_OP_MAX) { - blend_state.Entry[i].SourceAlphaBlendFactor = BLENDFACTOR_ONE; - blend_state.Entry[i].DestinationAlphaBlendFactor = BLENDFACTOR_ONE; - } - } - - struct GENX(BLEND_STATE_ENTRY) *bs0 = &blend_state.Entry[0]; - - anv_batch_emit(&pipeline->batch, GENX(3DSTATE_PS_BLEND), blend) { - blend.AlphaToCoverageEnable = blend_state.AlphaToCoverageEnable; - blend.HasWriteableRT = has_writeable_rt; - blend.ColorBufferBlendEnable = bs0->ColorBufferBlendEnable; - blend.SourceAlphaBlendFactor = bs0->SourceAlphaBlendFactor; - blend.DestinationAlphaBlendFactor = bs0->DestinationAlphaBlendFactor; - blend.SourceBlendFactor = bs0->SourceBlendFactor; - blend.DestinationBlendFactor = bs0->DestinationBlendFactor; - blend.AlphaTestEnable = false; - blend.IndependentAlphaBlendEnable = - blend_state.IndependentAlphaBlendEnable; - } - - GENX(BLEND_STATE_pack)(NULL, pipeline->blend_state.map, &blend_state); - if (!device->info.has_llc) - anv_state_clflush(pipeline->blend_state); - - anv_batch_emit(&pipeline->batch, GENX(3DSTATE_BLEND_STATE_POINTERS), bsp) { - bsp.BlendStatePointer = pipeline->blend_state.offset; - bsp.BlendStatePointerValid = true; - } -} - static void emit_ms_state(struct anv_pipeline *pipeline, const VkPipelineMultisampleStateCreateInfo *info) diff --git a/src/intel/vulkan/genX_pipeline_util.h b/src/intel/vulkan/genX_pipeline_util.h index 669b456860e..4385112b421 100644 --- a/src/intel/vulkan/genX_pipeline_util.h +++ b/src/intel/vulkan/genX_pipeline_util.h @@ -512,3 +512,137 @@ emit_ds_state(struct anv_pipeline *pipeline, GENX(3DSTATE_WM_DEPTH_STENCIL_pack)(NULL, depth_stencil_dw, &depth_stencil); #endif } + +static void +emit_cb_state(struct anv_pipeline *pipeline, + const VkPipelineColorBlendStateCreateInfo *info, + const VkPipelineMultisampleStateCreateInfo *ms_info) +{ + struct anv_device *device = pipeline->device; + + const uint32_t num_dwords = GENX(BLEND_STATE_length); + pipeline->blend_state = + anv_state_pool_alloc(&device->dynamic_state_pool, num_dwords * 4, 64); + + struct GENX(BLEND_STATE) blend_state = { +#if GEN_GEN >= 8 + .AlphaToCoverageEnable = ms_info && ms_info->alphaToCoverageEnable, + .AlphaToOneEnable = ms_info && ms_info->alphaToOneEnable, +#else + /* Make sure it gets zeroed */ + .Entry = { { 0, }, }, +#endif + }; + + /* Default everything to disabled */ + for (uint32_t i = 0; i < 8; i++) { + blend_state.Entry[i].WriteDisableAlpha = true; + blend_state.Entry[i].WriteDisableRed = true; + blend_state.Entry[i].WriteDisableGreen = true; + blend_state.Entry[i].WriteDisableBlue = true; + } + + struct anv_pipeline_bind_map *map = + &pipeline->bindings[MESA_SHADER_FRAGMENT]; + + bool has_writeable_rt = false; + for (unsigned i = 0; i < map->surface_count; i++) { + struct anv_pipeline_binding *binding = &map->surface_to_descriptor[i]; + + /* All color attachments are at the beginning of the binding table */ + if (binding->set != ANV_DESCRIPTOR_SET_COLOR_ATTACHMENTS) + break; + + /* We can have at most 8 attachments */ + assert(i < 8); + + if (binding->index >= info->attachmentCount) + continue; + + assert(binding->binding == 0); + const VkPipelineColorBlendAttachmentState *a = + &info->pAttachments[binding->index]; + + blend_state.Entry[i] = (struct GENX(BLEND_STATE_ENTRY)) { +#if GEN_GEN < 8 + .AlphaToCoverageEnable = ms_info && ms_info->alphaToCoverageEnable, + .AlphaToOneEnable = ms_info && ms_info->alphaToOneEnable, +#endif + .LogicOpEnable = info->logicOpEnable, + .LogicOpFunction = vk_to_gen_logic_op[info->logicOp], + .ColorBufferBlendEnable = a->blendEnable, + .ColorClampRange = COLORCLAMP_RTFORMAT, + .PreBlendColorClampEnable = true, + .PostBlendColorClampEnable = true, + .SourceBlendFactor = vk_to_gen_blend[a->srcColorBlendFactor], + .DestinationBlendFactor = vk_to_gen_blend[a->dstColorBlendFactor], + .ColorBlendFunction = vk_to_gen_blend_op[a->colorBlendOp], + .SourceAlphaBlendFactor = vk_to_gen_blend[a->srcAlphaBlendFactor], + .DestinationAlphaBlendFactor = vk_to_gen_blend[a->dstAlphaBlendFactor], + .AlphaBlendFunction = vk_to_gen_blend_op[a->alphaBlendOp], + .WriteDisableAlpha = !(a->colorWriteMask & VK_COLOR_COMPONENT_A_BIT), + .WriteDisableRed = !(a->colorWriteMask & VK_COLOR_COMPONENT_R_BIT), + .WriteDisableGreen = !(a->colorWriteMask & VK_COLOR_COMPONENT_G_BIT), + .WriteDisableBlue = !(a->colorWriteMask & VK_COLOR_COMPONENT_B_BIT), + }; + + if (a->srcColorBlendFactor != a->srcAlphaBlendFactor || + a->dstColorBlendFactor != a->dstAlphaBlendFactor || + a->colorBlendOp != a->alphaBlendOp) { +#if GEN_GEN >= 8 + blend_state.IndependentAlphaBlendEnable = true; +#else + blend_state.Entry[i].IndependentAlphaBlendEnable = true; +#endif + } + + if (a->colorWriteMask != 0) + has_writeable_rt = true; + + /* Our hardware applies the blend factor prior to the blend function + * regardless of what function is used. Technically, this means the + * hardware can do MORE than GL or Vulkan specify. However, it also + * means that, for MIN and MAX, we have to stomp the blend factor to + * ONE to make it a no-op. + */ + if (a->colorBlendOp == VK_BLEND_OP_MIN || + a->colorBlendOp == VK_BLEND_OP_MAX) { + blend_state.Entry[i].SourceBlendFactor = BLENDFACTOR_ONE; + blend_state.Entry[i].DestinationBlendFactor = BLENDFACTOR_ONE; + } + if (a->alphaBlendOp == VK_BLEND_OP_MIN || + a->alphaBlendOp == VK_BLEND_OP_MAX) { + blend_state.Entry[i].SourceAlphaBlendFactor = BLENDFACTOR_ONE; + blend_state.Entry[i].DestinationAlphaBlendFactor = BLENDFACTOR_ONE; + } + } + +#if GEN_GEN >= 8 + struct GENX(BLEND_STATE_ENTRY) *bs0 = &blend_state.Entry[0]; + anv_batch_emit(&pipeline->batch, GENX(3DSTATE_PS_BLEND), blend) { + blend.AlphaToCoverageEnable = blend_state.AlphaToCoverageEnable; + blend.HasWriteableRT = has_writeable_rt; + blend.ColorBufferBlendEnable = bs0->ColorBufferBlendEnable; + blend.SourceAlphaBlendFactor = bs0->SourceAlphaBlendFactor; + blend.DestinationAlphaBlendFactor = bs0->DestinationAlphaBlendFactor; + blend.SourceBlendFactor = bs0->SourceBlendFactor; + blend.DestinationBlendFactor = bs0->DestinationBlendFactor; + blend.AlphaTestEnable = false; + blend.IndependentAlphaBlendEnable = + blend_state.IndependentAlphaBlendEnable; + } +#else + (void)has_writeable_rt; +#endif + + GENX(BLEND_STATE_pack)(NULL, pipeline->blend_state.map, &blend_state); + if (!device->info.has_llc) + anv_state_clflush(pipeline->blend_state); + + anv_batch_emit(&pipeline->batch, GENX(3DSTATE_BLEND_STATE_POINTERS), bsp) { + bsp.BlendStatePointer = pipeline->blend_state.offset; +#if GEN_GEN >= 8 + bsp.BlendStatePointerValid = true; +#endif + } +}