mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-08 06:58:05 +02:00
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 <jason@jlekstrand.net>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Cc: "12.0" <mesa-stable@lists.freedesktop.org>
(cherry picked from commit a2e7b2e653)
This commit is contained in:
parent
cb9a2a4b85
commit
f194c84b37
3 changed files with 136 additions and 190 deletions
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue