genxml: Make BLEND_STATE command support variable length array.

We need to emit BLEND_STATE, which size is 1 + 2 * nr_draw_buffers
dwords (on gen8+), but the BLEND_STATE struct length is always 17. By
marking it size 1, which is actually the size of the struct minus the
BLEND_STATE_ENTRY's, we can emit a BLEND_STATE of variable number of
entries.

For gen6 and gen7 we set length to 0, since it only contains
BLEND_STATE_ENTRY's, and no other data.

With this change, we also change the code for blorp and anv to emit only
the needed BLEND_STATE_ENTRY's, instead of always emitting 16 dwords on
gen6-7 and 17 dwords on gen8+.

v2:
   - Use designated initializers on blorp and remove 0 from
   initialization (Jason)
   - Default entries to disabled on Vulkan (Jason)
   - Rebase code.

Signed-off-by: Rafael Antognolli <rafael.antognolli@intel.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
This commit is contained in:
Rafael Antognolli 2017-03-30 11:33:05 -07:00 committed by Kenneth Graunke
parent 4ace73b1f6
commit 9670124e31
7 changed files with 74 additions and 48 deletions

View file

@ -858,20 +858,35 @@ static uint32_t
blorp_emit_blend_state(struct blorp_batch *batch, blorp_emit_blend_state(struct blorp_batch *batch,
const struct blorp_params *params) const struct blorp_params *params)
{ {
uint32_t offset; struct GENX(BLEND_STATE) blend;
blorp_emit_dynamic(batch, GENX(BLEND_STATE), blend, 64, &offset) { memset(&blend, 0, sizeof(blend));
for (unsigned i = 0; i < params->num_draw_buffers; ++i) {
blend.Entry[i].PreBlendColorClampEnable = true;
blend.Entry[i].PostBlendColorClampEnable = true;
blend.Entry[i].ColorClampRange = COLORCLAMP_RTFORMAT;
blend.Entry[i].WriteDisableRed = params->color_write_disable[0]; uint32_t offset;
blend.Entry[i].WriteDisableGreen = params->color_write_disable[1]; int size = GENX(BLEND_STATE_length) * 4;
blend.Entry[i].WriteDisableBlue = params->color_write_disable[2]; size += GENX(BLEND_STATE_ENTRY_length) * 4 * params->num_draw_buffers;
blend.Entry[i].WriteDisableAlpha = params->color_write_disable[3]; uint32_t *state = blorp_alloc_dynamic_state(batch, size, 64, &offset);
} uint32_t *pos = state;
GENX(BLEND_STATE_pack)(NULL, pos, &blend);
pos += GENX(BLEND_STATE_length);
for (unsigned i = 0; i < params->num_draw_buffers; ++i) {
struct GENX(BLEND_STATE_ENTRY) entry = {
.PreBlendColorClampEnable = true,
.PostBlendColorClampEnable = true,
.ColorClampRange = COLORCLAMP_RTFORMAT,
.WriteDisableRed = params->color_write_disable[0],
.WriteDisableGreen = params->color_write_disable[1],
.WriteDisableBlue = params->color_write_disable[2],
.WriteDisableAlpha = params->color_write_disable[3],
};
GENX(BLEND_STATE_ENTRY_pack)(NULL, pos, &entry);
pos += GENX(BLEND_STATE_ENTRY_length);
} }
blorp_flush_range(batch, state, size);
#if GEN_GEN >= 7 #if GEN_GEN >= 7
blorp_emit(batch, GENX(3DSTATE_BLEND_STATE_POINTERS), sp) { blorp_emit(batch, GENX(3DSTATE_BLEND_STATE_POINTERS), sp) {
sp.BlendStatePointer = offset; sp.BlendStatePointer = offset;

View file

@ -452,8 +452,8 @@
<field name="Post-Blend Color Clamp Enable" start="32" end="32" type="bool"/> <field name="Post-Blend Color Clamp Enable" start="32" end="32" type="bool"/>
</struct> </struct>
<struct name="BLEND_STATE" length="16"> <struct name="BLEND_STATE" length="0">
<group count="8" start="0" size="64"> <group count="0" start="0" size="64">
<field name="Entry" start="0" end="63" type="BLEND_STATE_ENTRY"/> <field name="Entry" start="0" end="63" type="BLEND_STATE_ENTRY"/>
</group> </group>
</struct> </struct>

View file

@ -507,8 +507,8 @@
<field name="Post-Blend Color Clamp Enable" start="32" end="32" type="bool"/> <field name="Post-Blend Color Clamp Enable" start="32" end="32" type="bool"/>
</struct> </struct>
<struct name="BLEND_STATE" length="16"> <struct name="BLEND_STATE" length="0">
<group count="8" start="0" size="64"> <group count="0" start="0" size="64">
<field name="Entry" start="0" end="63" type="BLEND_STATE_ENTRY"/> <field name="Entry" start="0" end="63" type="BLEND_STATE_ENTRY"/>
</group> </group>
</struct> </struct>

View file

@ -517,8 +517,8 @@
<field name="Post-Blend Color Clamp Enable" start="32" end="32" type="bool"/> <field name="Post-Blend Color Clamp Enable" start="32" end="32" type="bool"/>
</struct> </struct>
<struct name="BLEND_STATE" length="16"> <struct name="BLEND_STATE" length="0">
<group count="8" start="0" size="64"> <group count="0" start="0" size="64">
<field name="Entry" start="0" end="63" type="BLEND_STATE_ENTRY"/> <field name="Entry" start="0" end="63" type="BLEND_STATE_ENTRY"/>
</group> </group>
</struct> </struct>

View file

@ -546,7 +546,7 @@
<field name="Write Disable Blue" start="0" end="0" type="bool"/> <field name="Write Disable Blue" start="0" end="0" type="bool"/>
</struct> </struct>
<struct name="BLEND_STATE" length="17"> <struct name="BLEND_STATE" length="1">
<field name="Alpha To Coverage Enable" start="31" end="31" type="bool"/> <field name="Alpha To Coverage Enable" start="31" end="31" type="bool"/>
<field name="Independent Alpha Blend Enable" start="30" end="30" type="bool"/> <field name="Independent Alpha Blend Enable" start="30" end="30" type="bool"/>
<field name="Alpha To One Enable" start="29" end="29" type="bool"/> <field name="Alpha To One Enable" start="29" end="29" type="bool"/>
@ -556,7 +556,7 @@
<field name="Color Dither Enable" start="23" end="23" type="bool"/> <field name="Color Dither Enable" start="23" end="23" type="bool"/>
<field name="X Dither Offset" start="21" end="22" type="uint"/> <field name="X Dither Offset" start="21" end="22" type="uint"/>
<field name="Y Dither Offset" start="19" end="20" type="uint"/> <field name="Y Dither Offset" start="19" end="20" type="uint"/>
<group count="8" start="32" size="64"> <group count="0" start="32" size="64">
<field name="Entry" start="0" end="63" type="BLEND_STATE_ENTRY"/> <field name="Entry" start="0" end="63" type="BLEND_STATE_ENTRY"/>
</group> </group>
</struct> </struct>

View file

@ -555,7 +555,7 @@
<field name="Write Disable Blue" start="0" end="0" type="bool"/> <field name="Write Disable Blue" start="0" end="0" type="bool"/>
</struct> </struct>
<struct name="BLEND_STATE" length="17"> <struct name="BLEND_STATE" length="1">
<field name="Alpha To Coverage Enable" start="31" end="31" type="bool"/> <field name="Alpha To Coverage Enable" start="31" end="31" type="bool"/>
<field name="Independent Alpha Blend Enable" start="30" end="30" type="bool"/> <field name="Independent Alpha Blend Enable" start="30" end="30" type="bool"/>
<field name="Alpha To One Enable" start="29" end="29" type="bool"/> <field name="Alpha To One Enable" start="29" end="29" type="bool"/>
@ -565,7 +565,7 @@
<field name="Color Dither Enable" start="23" end="23" type="bool"/> <field name="Color Dither Enable" start="23" end="23" type="bool"/>
<field name="X Dither Offset" start="21" end="22" type="uint"/> <field name="X Dither Offset" start="21" end="22" type="uint"/>
<field name="Y Dither Offset" start="19" end="20" type="uint"/> <field name="Y Dither Offset" start="19" end="20" type="uint"/>
<group count="8" start="32" size="64"> <group count="0" start="32" size="64">
<field name="Entry" start="0" end="63" type="BLEND_STATE_ENTRY"/> <field name="Entry" start="0" end="63" type="BLEND_STATE_ENTRY"/>
</group> </group>
</struct> </struct>

View file

@ -862,28 +862,14 @@ emit_cb_state(struct anv_pipeline *pipeline,
{ {
struct anv_device *device = pipeline->device; 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 = { struct GENX(BLEND_STATE) blend_state = {
#if GEN_GEN >= 8 #if GEN_GEN >= 8
.AlphaToCoverageEnable = ms_info && ms_info->alphaToCoverageEnable, .AlphaToCoverageEnable = ms_info && ms_info->alphaToCoverageEnable,
.AlphaToOneEnable = ms_info && ms_info->alphaToOneEnable, .AlphaToOneEnable = ms_info && ms_info->alphaToOneEnable,
#else
/* Make sure it gets zeroed */
.Entry = { { 0, }, },
#endif #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;
}
uint32_t surface_count = 0; uint32_t surface_count = 0;
struct anv_pipeline_bind_map *map; struct anv_pipeline_bind_map *map;
if (anv_pipeline_has_stage(pipeline, MESA_SHADER_FRAGMENT)) { if (anv_pipeline_has_stage(pipeline, MESA_SHADER_FRAGMENT)) {
@ -891,7 +877,17 @@ emit_cb_state(struct anv_pipeline *pipeline,
surface_count = map->surface_count; surface_count = map->surface_count;
} }
const uint32_t num_dwords = GENX(BLEND_STATE_length) +
GENX(BLEND_STATE_ENTRY_length) * surface_count;
pipeline->blend_state =
anv_state_pool_alloc(&device->dynamic_state_pool, num_dwords * 4, 64);
bool has_writeable_rt = false; bool has_writeable_rt = false;
uint32_t *state_pos = pipeline->blend_state.map;
state_pos += GENX(BLEND_STATE_length);
#if GEN_GEN >= 8
struct GENX(BLEND_STATE_ENTRY) bs0 = { 0 };
#endif
for (unsigned i = 0; i < surface_count; i++) { for (unsigned i = 0; i < surface_count; i++) {
struct anv_pipeline_binding *binding = &map->surface_to_descriptor[i]; struct anv_pipeline_binding *binding = &map->surface_to_descriptor[i];
@ -902,14 +898,24 @@ emit_cb_state(struct anv_pipeline *pipeline,
/* We can have at most 8 attachments */ /* We can have at most 8 attachments */
assert(i < 8); assert(i < 8);
if (info == NULL || binding->index >= info->attachmentCount) if (info == NULL || binding->index >= info->attachmentCount) {
/* Default everything to disabled */
struct GENX(BLEND_STATE_ENTRY) entry = {
.WriteDisableAlpha = true,
.WriteDisableRed = true,
.WriteDisableGreen = true,
.WriteDisableBlue = true,
};
GENX(BLEND_STATE_ENTRY_pack)(NULL, state_pos, &entry);
state_pos += GENX(BLEND_STATE_ENTRY_length);
continue; continue;
}
assert(binding->binding == 0); assert(binding->binding == 0);
const VkPipelineColorBlendAttachmentState *a = const VkPipelineColorBlendAttachmentState *a =
&info->pAttachments[binding->index]; &info->pAttachments[binding->index];
blend_state.Entry[i] = (struct GENX(BLEND_STATE_ENTRY)) { struct GENX(BLEND_STATE_ENTRY) entry = {
#if GEN_GEN < 8 #if GEN_GEN < 8
.AlphaToCoverageEnable = ms_info && ms_info->alphaToCoverageEnable, .AlphaToCoverageEnable = ms_info && ms_info->alphaToCoverageEnable,
.AlphaToOneEnable = ms_info && ms_info->alphaToOneEnable, .AlphaToOneEnable = ms_info && ms_info->alphaToOneEnable,
@ -938,7 +944,7 @@ emit_cb_state(struct anv_pipeline *pipeline,
#if GEN_GEN >= 8 #if GEN_GEN >= 8
blend_state.IndependentAlphaBlendEnable = true; blend_state.IndependentAlphaBlendEnable = true;
#else #else
blend_state.Entry[i].IndependentAlphaBlendEnable = true; entry.IndependentAlphaBlendEnable = true;
#endif #endif
} }
@ -953,26 +959,31 @@ emit_cb_state(struct anv_pipeline *pipeline,
*/ */
if (a->colorBlendOp == VK_BLEND_OP_MIN || if (a->colorBlendOp == VK_BLEND_OP_MIN ||
a->colorBlendOp == VK_BLEND_OP_MAX) { a->colorBlendOp == VK_BLEND_OP_MAX) {
blend_state.Entry[i].SourceBlendFactor = BLENDFACTOR_ONE; entry.SourceBlendFactor = BLENDFACTOR_ONE;
blend_state.Entry[i].DestinationBlendFactor = BLENDFACTOR_ONE; entry.DestinationBlendFactor = BLENDFACTOR_ONE;
} }
if (a->alphaBlendOp == VK_BLEND_OP_MIN || if (a->alphaBlendOp == VK_BLEND_OP_MIN ||
a->alphaBlendOp == VK_BLEND_OP_MAX) { a->alphaBlendOp == VK_BLEND_OP_MAX) {
blend_state.Entry[i].SourceAlphaBlendFactor = BLENDFACTOR_ONE; entry.SourceAlphaBlendFactor = BLENDFACTOR_ONE;
blend_state.Entry[i].DestinationAlphaBlendFactor = BLENDFACTOR_ONE; entry.DestinationAlphaBlendFactor = BLENDFACTOR_ONE;
} }
GENX(BLEND_STATE_ENTRY_pack)(NULL, state_pos, &entry);
state_pos += GENX(BLEND_STATE_ENTRY_length);
#if GEN_GEN >= 8
if (i == 0)
bs0 = entry;
#endif
} }
#if GEN_GEN >= 8 #if GEN_GEN >= 8
struct GENX(BLEND_STATE_ENTRY) *bs0 = &blend_state.Entry[0];
anv_batch_emit(&pipeline->batch, GENX(3DSTATE_PS_BLEND), blend) { anv_batch_emit(&pipeline->batch, GENX(3DSTATE_PS_BLEND), blend) {
blend.AlphaToCoverageEnable = blend_state.AlphaToCoverageEnable; blend.AlphaToCoverageEnable = blend_state.AlphaToCoverageEnable;
blend.HasWriteableRT = has_writeable_rt; blend.HasWriteableRT = has_writeable_rt;
blend.ColorBufferBlendEnable = bs0->ColorBufferBlendEnable; blend.ColorBufferBlendEnable = bs0.ColorBufferBlendEnable;
blend.SourceAlphaBlendFactor = bs0->SourceAlphaBlendFactor; blend.SourceAlphaBlendFactor = bs0.SourceAlphaBlendFactor;
blend.DestinationAlphaBlendFactor = bs0->DestinationAlphaBlendFactor; blend.DestinationAlphaBlendFactor = bs0.DestinationAlphaBlendFactor;
blend.SourceBlendFactor = bs0->SourceBlendFactor; blend.SourceBlendFactor = bs0.SourceBlendFactor;
blend.DestinationBlendFactor = bs0->DestinationBlendFactor; blend.DestinationBlendFactor = bs0.DestinationBlendFactor;
blend.AlphaTestEnable = false; blend.AlphaTestEnable = false;
blend.IndependentAlphaBlendEnable = blend.IndependentAlphaBlendEnable =
blend_state.IndependentAlphaBlendEnable; blend_state.IndependentAlphaBlendEnable;