anv: move SBE emission to dynamic path

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Tapani Pälli <tapani.palli@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36665>
This commit is contained in:
Lionel Landwerlin 2025-03-28 13:56:18 +02:00 committed by Marge Bot
parent 33abaf2d0e
commit c8305dfe0e
4 changed files with 241 additions and 157 deletions

View file

@ -558,8 +558,6 @@ anv_cmd_buffer_flush_pipeline_hw_state(struct anv_cmd_buffer *cmd_buffer,
if (cmd_buffer->device->info->ver >= 11)
diff_fix_state(VF_SGVS_2, final.vf_sgvs_2);
diff_fix_state(VF_COMPONENT_PACKING, final.vf_component_packing);
diff_fix_state(SBE, final.sbe);
diff_fix_state(SBE_SWIZ, final.sbe_swiz);
diff_fix_state(VS, final.vs);
diff_fix_state(HS, final.hs);
diff_fix_state(DS, final.ds);
@ -581,7 +579,6 @@ anv_cmd_buffer_flush_pipeline_hw_state(struct anv_cmd_buffer *cmd_buffer,
diff_fix_state(MESH_SHADER, final.mesh_shader);
diff_fix_state(MESH_DISTRIB, final.mesh_distrib);
diff_fix_state(CLIP_MESH, final.clip_mesh);
diff_fix_state(SBE_MESH, final.sbe_mesh);
} else {
assert_empty(final.task_control);
assert_empty(final.task_shader);
@ -590,7 +587,6 @@ anv_cmd_buffer_flush_pipeline_hw_state(struct anv_cmd_buffer *cmd_buffer,
assert_empty(final.mesh_shader);
assert_empty(final.mesh_distrib);
assert_empty(final.clip_mesh);
assert_empty(final.sbe_mesh);
}
/* States that can vary in length */
@ -765,8 +761,6 @@ void anv_CmdBindPipeline(
cmd_buffer->state.gfx.fs_source_hash = new_pipeline->fs_source_hash;
cmd_buffer->state.gfx.instance_multiplier = new_pipeline->instance_multiplier;
cmd_buffer->state.gfx.primitive_id_index = new_pipeline->primitive_id_index;
cmd_buffer->state.gfx.first_vue_slot = new_pipeline->first_vue_slot;
anv_cmd_buffer_flush_pipeline_hw_state(cmd_buffer, old_pipeline, new_pipeline);
break;

View file

@ -1791,6 +1791,37 @@ struct anv_gfx_dynamic_state {
} elem[MAX_SCISSORS];
} scissor;
/* 3DSTATE_SBE */
struct {
bool AttributeSwizzleEnable;
uint32_t PointSpriteTextureCoordinateEnable;
uint32_t PointSpriteTextureCoordinateOrigin;
uint32_t NumberofSFOutputAttributes;
uint32_t ConstantInterpolationEnable;
uint32_t VertexURBEntryReadOffset;
uint32_t VertexURBEntryReadLength;
bool VertexAttributesBypass;
uint32_t PrimitiveIDOverrideAttributeSelect;
bool PrimitiveIDOverrideComponentX;
bool PrimitiveIDOverrideComponentY;
bool PrimitiveIDOverrideComponentZ;
bool PrimitiveIDOverrideComponentW;
} sbe;
struct {
uint32_t PerVertexURBEntryOutputReadOffset;
uint32_t PerVertexURBEntryOutputReadLength;
uint32_t PerPrimitiveURBEntryOutputReadOffset;
uint32_t PerPrimitiveURBEntryOutputReadLength;
} sbe_mesh;
/* 3DSTATE_SBE_SWIZ */
struct {
struct {
uint32_t SourceAttribute;
} Attribute[16];
} sbe_swiz;
/* 3DSTATE_SF */
struct {
uint32_t DerefBlockSize;
@ -1933,6 +1964,17 @@ struct anv_gfx_dynamic_state {
bool pma_fix;
/**
* Attribute index of gl_PrimitiveID in the fragment shader relative to the
* first read attribute.
*/
uint32_t primitive_id_index;
/**
* First attribute read by SBE in the VUE.
*/
uint32_t first_vue_slot;
/**
* DEPTH and STENCIL attachment write state for Wa_18019816803.
*/
@ -4130,8 +4172,6 @@ struct anv_cmd_graphics_state {
bool kill_pixel;
bool uses_xfb;
uint32_t primitive_id_index;
uint32_t first_vue_slot;
/* Render pass information */
VkRenderingFlags rendering_flags;
@ -5094,11 +5134,6 @@ struct anv_graphics_pipeline {
uint32_t view_mask;
uint32_t instance_multiplier;
/* First VUE slot read by SBE */
uint32_t first_vue_slot;
/* Attribute index of the PrimitiveID in the delivered attributes */
uint32_t primitive_id_index;
bool kill_pixel;
bool uses_xfb;
@ -5146,8 +5181,6 @@ struct anv_graphics_pipeline {
struct anv_gfx_state_ptr vf_sgvs_instancing;
struct anv_gfx_state_ptr vf_instancing;
struct anv_gfx_state_ptr vf_component_packing;
struct anv_gfx_state_ptr sbe;
struct anv_gfx_state_ptr sbe_swiz;
struct anv_gfx_state_ptr so_decl_list;
struct anv_gfx_state_ptr vs;
struct anv_gfx_state_ptr hs;
@ -5165,7 +5198,6 @@ struct anv_graphics_pipeline {
struct anv_gfx_state_ptr mesh_control_protected;
struct anv_gfx_state_ptr mesh_shader;
struct anv_gfx_state_ptr mesh_distrib;
struct anv_gfx_state_ptr sbe_mesh;
} final;
/* Pre packed CS instructions & structures that need to be merged later

View file

@ -38,6 +38,31 @@
#include "genX_mi_builder.h"
#define anv_gfx_emit(_gfx, _bit, _field, cmd, name) \
for (struct cmd name = { __anv_cmd_header(cmd) }, *_dst = &name; \
__builtin_expect(_dst != NULL, 1); \
({ assert(ARRAY_SIZE((_gfx)->_field) >= __anv_cmd_length(cmd)); \
uint32_t __packed[__anv_cmd_length(cmd)]; \
__anv_cmd_pack(cmd)(NULL, __packed, &name); \
if (memcmp(__packed, (_gfx)->_field, \
4 * __anv_cmd_length(cmd))) { \
memcpy((_gfx)->_field, __packed, \
4 * __anv_cmd_length(cmd)); \
BITSET_SET((_gfx)->dirty, ANV_GFX_STATE_##_bit); \
} \
_dst = NULL; \
}))
#define anv_batch_emit_gfx_state(batch, _packed, cmd) \
({ \
assert((_packed)[0] != 0); \
void *_dst = anv_batch_emit_dwords(batch, __anv_cmd_length(cmd)); \
if (_dst != NULL) { \
memcpy(_dst, _packed, 4 * __anv_cmd_length(cmd)); \
VG(VALGRIND_CHECK_MEM_IS_DEFINED(_dst, __anv_cmd_length(cmd) * 4)); \
} \
})
static const uint32_t vk_to_intel_blend[] = {
[VK_BLEND_FACTOR_ZERO] = BLENDFACTOR_ZERO,
[VK_BLEND_FACTOR_ONE] = BLENDFACTOR_ONE,
@ -847,8 +872,8 @@ update_fs_msaa_flags(struct anv_gfx_dynamic_state *hw_state,
.coarse_pixel = !vk_fragment_shading_rate_is_disabled(&dyn->fsr),
.alpha_to_coverage = dyn->ms.alpha_to_coverage_enable,
.provoking_vertex_last = dyn->rs.provoking_vertex == VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT,
.first_vue_slot = gfx->first_vue_slot,
.primitive_id_index = gfx->primitive_id_index,
.first_vue_slot = hw_state->first_vue_slot,
.primitive_id_index = hw_state->primitive_id_index,
.per_primitive_remapping = mesh_prog_data &&
mesh_prog_data->map.wa_18019110168_active,
});
@ -856,6 +881,129 @@ update_fs_msaa_flags(struct anv_gfx_dynamic_state *hw_state,
SET(FS_MSAA_FLAGS, fs_msaa_flags, fs_msaa_flags);
}
static bool
sbe_primitive_id_override(const struct anv_cmd_graphics_state *gfx)
{
const struct brw_wm_prog_data *wm_prog_data = get_gfx_wm_prog_data(gfx);
if (!wm_prog_data)
return false;
if (anv_gfx_has_stage(gfx, MESA_SHADER_MESH)) {
const struct brw_mesh_prog_data *mesh_prog_data =
get_gfx_mesh_prog_data(gfx);
const struct brw_mue_map *mue = &mesh_prog_data->map;
return (wm_prog_data->inputs & VARYING_BIT_PRIMITIVE_ID) &&
mue->per_primitive_offsets[VARYING_SLOT_PRIMITIVE_ID] == -1;
}
const struct intel_vue_map *vue_map = get_gfx_last_vue_map(gfx);
return (wm_prog_data->inputs & VARYING_BIT_PRIMITIVE_ID) &&
(vue_map->slots_valid & VARYING_BIT_PRIMITIVE_ID) == 0;
}
ALWAYS_INLINE static void
update_sbe(struct anv_gfx_dynamic_state *hw_state,
const struct anv_cmd_graphics_state *gfx,
const struct anv_device *device)
{
const struct brw_wm_prog_data *wm_prog_data = get_gfx_wm_prog_data(gfx);
if (wm_prog_data == NULL)
return;
const struct brw_mesh_prog_data *mesh_prog_data =
get_gfx_mesh_prog_data(gfx);
const struct intel_vue_map *vue_map = get_gfx_last_vue_map(gfx);
uint32_t vertex_read_offset, vertex_read_length, vertex_varyings, flat_inputs;
brw_compute_sbe_per_vertex_urb_read(
vue_map, mesh_prog_data != NULL,
mesh_prog_data ? mesh_prog_data->map.wa_18019110168_active : false,
wm_prog_data,
&vertex_read_offset, &vertex_read_length, &vertex_varyings,
&hw_state->primitive_id_index, &flat_inputs);
hw_state->first_vue_slot = vertex_read_offset * 2;
/* As far as we can test, 3DSTATE_SBE & 3DSTATE_SBE_SWIZ has no effect when
* the pipeline is using Mesh. We still fill the instruction for now, but
* in the future we might want to completely avoid its emission.
*/
SET(SBE, sbe.AttributeSwizzleEnable, mesh_prog_data == NULL);
SET(SBE, sbe.PointSpriteTextureCoordinateOrigin, UPPERLEFT);
SET(SBE, sbe.NumberofSFOutputAttributes, vertex_varyings);
SET(SBE, sbe.ConstantInterpolationEnable, flat_inputs);
SET(SBE, sbe.VertexAttributesBypass, wm_prog_data->vertex_attributes_bypass);
if (mesh_prog_data == NULL) {
for (uint8_t idx = 0; idx < wm_prog_data->urb_setup_attribs_count; idx++) {
gl_varying_slot attr = wm_prog_data->urb_setup_attribs[idx];
int input_index = wm_prog_data->urb_setup[attr];
assert(0 <= input_index);
if (attr == VARYING_SLOT_PNTC) {
SET(SBE, sbe.PointSpriteTextureCoordinateEnable, 1 << input_index);
continue;
}
const int slot = vue_map->varying_to_slot[attr];
if (slot == -1)
continue;
/* We have to subtract two slots to account for the URB entry output
* read offset in the VS and GS stages.
*/
const int source_attr = slot - 2 * vertex_read_offset;
assert(source_attr >= 0 && source_attr < 32);
/* The hardware can only do overrides on 16 overrides at a time, and
* the other up to 16 have to be lined up so that the input index =
* the output index. We'll need to do some tweaking to make sure
* that's the case.
*/
if (input_index < 16) {
SET(SBE_SWIZ,
sbe_swiz.Attribute[input_index].SourceAttribute,
source_attr);
} else {
assert(source_attr == input_index);
}
}
SET(SBE, sbe.VertexURBEntryReadOffset, vertex_read_offset);
SET(SBE, sbe.VertexURBEntryReadLength, vertex_read_length);
}
/* Ask the hardware to supply PrimitiveID if the fragment shader reads it
* but a previous stage didn't write one.
*/
const bool prim_id_override = sbe_primitive_id_override(gfx);
SET(SBE, sbe.PrimitiveIDOverrideAttributeSelect,
prim_id_override ? wm_prog_data->urb_setup[VARYING_SLOT_PRIMITIVE_ID] : 0);
SET(SBE, sbe.PrimitiveIDOverrideComponentX, prim_id_override);
SET(SBE, sbe.PrimitiveIDOverrideComponentY, prim_id_override);
SET(SBE, sbe.PrimitiveIDOverrideComponentZ, prim_id_override);
SET(SBE, sbe.PrimitiveIDOverrideComponentW, prim_id_override);
#if GFX_VERx10 >= 125
if (mesh_prog_data) {
SET(SBE_MESH, sbe_mesh.PerVertexURBEntryOutputReadOffset, vertex_read_offset);
SET(SBE_MESH, sbe_mesh.PerVertexURBEntryOutputReadLength, vertex_read_length);
uint32_t prim_read_offset, prim_read_length;
brw_compute_sbe_per_primitive_urb_read(wm_prog_data->per_primitive_inputs,
wm_prog_data->num_per_primitive_inputs,
&mesh_prog_data->map,
&prim_read_offset,
&prim_read_length);
SET(SBE_MESH, sbe_mesh.PerPrimitiveURBEntryOutputReadOffset, prim_read_offset);
SET(SBE_MESH, sbe_mesh.PerPrimitiveURBEntryOutputReadLength, prim_read_length);
}
#endif
}
ALWAYS_INLINE static void
update_ps(struct anv_gfx_dynamic_state *hw_state,
const struct anv_device *device,
@ -1988,6 +2136,11 @@ cmd_buffer_flush_gfx_runtime_state(struct anv_gfx_dynamic_state *hw_state,
VkCommandBufferLevel cmd_buffer_level)
{
UNUSED bool fs_msaa_changed = false;
/* Do this before update_fs_msaa_flags() for primitive_id_index */
if (gfx->dirty & ANV_CMD_DIRTY_ALL_SHADERS(device))
update_sbe(hw_state, gfx, device);
if ((gfx->dirty & ANV_CMD_DIRTY_PS) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_MS_ALPHA_TO_COVERAGE_ENABLE) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_MS_RASTERIZATION_SAMPLES) ||
@ -2527,12 +2680,6 @@ cmd_buffer_gfx_state_emission(struct anv_cmd_buffer *cmd_buffer)
}
}
if (BITSET_TEST(hw_state->dirty, ANV_GFX_STATE_SBE))
anv_batch_emit_pipeline_state(&cmd_buffer->batch, pipeline, final.sbe);
if (BITSET_TEST(hw_state->dirty, ANV_GFX_STATE_SBE_SWIZ))
anv_batch_emit_pipeline_state(&cmd_buffer->batch, pipeline, final.sbe_swiz);
if (BITSET_TEST(hw_state->dirty, ANV_GFX_STATE_SO_DECL_LIST)) {
/* Wa_16011773973:
* If SOL is enabled and SO_DECL state has to be programmed,
@ -2562,6 +2709,7 @@ cmd_buffer_gfx_state_emission(struct anv_cmd_buffer *cmd_buffer)
#endif
}
#if GFX_VERx10 >= 125
if (device->vk.enabled_extensions.EXT_mesh_shader) {
if (BITSET_TEST(hw_state->dirty, ANV_GFX_STATE_MESH_CONTROL)) {
anv_batch_emit_pipeline_state_protected(&cmd_buffer->batch, pipeline,
@ -2585,12 +2733,20 @@ cmd_buffer_gfx_state_emission(struct anv_cmd_buffer *cmd_buffer)
if (BITSET_TEST(hw_state->dirty, ANV_GFX_STATE_TASK_REDISTRIB))
anv_batch_emit_pipeline_state(&cmd_buffer->batch, pipeline, final.task_redistrib);
if (BITSET_TEST(hw_state->dirty, ANV_GFX_STATE_SBE_MESH))
anv_batch_emit_pipeline_state(&cmd_buffer->batch, pipeline, final.sbe_mesh);
if (BITSET_TEST(hw_state->dirty, ANV_GFX_STATE_SBE_MESH)) {
anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_SBE_MESH), sbe_mesh) {
SET(sbe_mesh, sbe_mesh, PerVertexURBEntryOutputReadOffset);
SET(sbe_mesh, sbe_mesh, PerVertexURBEntryOutputReadLength);
SET(sbe_mesh, sbe_mesh, PerPrimitiveURBEntryOutputReadOffset);
SET(sbe_mesh, sbe_mesh, PerPrimitiveURBEntryOutputReadLength);
}
}
if (BITSET_TEST(hw_state->dirty, ANV_GFX_STATE_CLIP_MESH))
anv_batch_emit_pipeline_state(&cmd_buffer->batch, pipeline, final.clip_mesh);
} else {
} else
#endif
{
assert(!BITSET_TEST(hw_state->dirty, ANV_GFX_STATE_MESH_CONTROL) &&
!BITSET_TEST(hw_state->dirty, ANV_GFX_STATE_MESH_SHADER) &&
!BITSET_TEST(hw_state->dirty, ANV_GFX_STATE_MESH_DISTRIB) &&
@ -2603,6 +2759,38 @@ cmd_buffer_gfx_state_emission(struct anv_cmd_buffer *cmd_buffer)
/* Now the potentially dynamic instructions */
if (BITSET_TEST(hw_state->dirty, ANV_GFX_STATE_SBE)) {
anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_SBE), sbe) {
for (unsigned i = 0; i < 32; i++)
sbe.AttributeActiveComponentFormat[i] = ACF_XYZW;
sbe.ForceVertexURBEntryReadOffset = true;
sbe.ForceVertexURBEntryReadLength = true;
SET(sbe, sbe, AttributeSwizzleEnable);
SET(sbe, sbe, PointSpriteTextureCoordinateEnable);
SET(sbe, sbe, PointSpriteTextureCoordinateOrigin);
SET(sbe, sbe, NumberofSFOutputAttributes);
SET(sbe, sbe, ConstantInterpolationEnable);
SET(sbe, sbe, VertexURBEntryReadOffset);
SET(sbe, sbe, VertexURBEntryReadLength);
#if GFX_VER >= 20
SET(sbe, sbe, VertexAttributesBypass);
#endif
SET(sbe, sbe, PrimitiveIDOverrideAttributeSelect);
SET(sbe, sbe, PrimitiveIDOverrideComponentX);
SET(sbe, sbe, PrimitiveIDOverrideComponentY);
SET(sbe, sbe, PrimitiveIDOverrideComponentZ);
SET(sbe, sbe, PrimitiveIDOverrideComponentW);
}
}
if (BITSET_TEST(hw_state->dirty, ANV_GFX_STATE_SBE_SWIZ)) {
anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_SBE_SWIZ), sbe_swiz) {
for (unsigned i = 0; i < 16; i++)
SET(sbe_swiz, sbe_swiz, Attribute[i].SourceAttribute);
}
}
if (BITSET_TEST(hw_state->dirty, ANV_GFX_STATE_PS)) {
DEBUG_SHADER_HASH(MESA_SHADER_FRAGMENT);
anv_batch_emit_merge_protected(&cmd_buffer->batch, GENX(3DSTATE_PS),

View file

@ -469,135 +469,6 @@ sbe_primitive_id_override(struct anv_graphics_pipeline *pipeline)
(fs_input_map->slots_valid & VARYING_BIT_PRIMITIVE_ID) == 0;
}
static void
emit_3dstate_sbe(struct anv_graphics_pipeline *pipeline)
{
const struct brw_wm_prog_data *wm_prog_data = get_pipeline_wm_prog_data(pipeline);
const struct brw_mesh_prog_data *mesh_prog_data =
get_pipeline_mesh_prog_data(pipeline);
UNUSED const struct anv_device *device = pipeline->base.base.device;
if (!anv_pipeline_has_stage(pipeline, MESA_SHADER_FRAGMENT)) {
anv_pipeline_emit(pipeline, final.sbe, GENX(3DSTATE_SBE), sbe);
anv_pipeline_emit(pipeline, final.sbe_swiz, GENX(3DSTATE_SBE_SWIZ), sbe);
#if GFX_VERx10 >= 125
if (device->vk.enabled_extensions.EXT_mesh_shader)
anv_pipeline_emit(pipeline, final.sbe_mesh, GENX(3DSTATE_SBE_MESH), sbe);
#endif
return;
}
const struct intel_vue_map *vue_map =
anv_pipeline_is_mesh(pipeline) ?
&get_pipeline_mesh_prog_data(pipeline)->map.vue_map :
&anv_pipeline_get_last_vue_prog_data(pipeline)->vue_map;
anv_pipeline_emit(pipeline, final.sbe, GENX(3DSTATE_SBE), sbe) {
anv_pipeline_emit(pipeline, final.sbe_swiz, GENX(3DSTATE_SBE_SWIZ), swiz) {
int max_source_attr = 0;
uint32_t vertex_read_offset, vertex_read_length, vertex_varyings, flat_inputs;
brw_compute_sbe_per_vertex_urb_read(
vue_map, mesh_prog_data != NULL,
mesh_prog_data ? mesh_prog_data->map.wa_18019110168_active : false,
wm_prog_data,
&vertex_read_offset, &vertex_read_length, &vertex_varyings,
&pipeline->primitive_id_index,
&flat_inputs);
pipeline->first_vue_slot = vertex_read_offset * 2;
sbe.AttributeSwizzleEnable = anv_pipeline_is_primitive(pipeline);
sbe.PointSpriteTextureCoordinateOrigin = UPPERLEFT;
sbe.ConstantInterpolationEnable = flat_inputs;
sbe.NumberofSFOutputAttributes = vertex_varyings;
#if GFX_VERx10 >= 200
sbe.VertexAttributesBypass = wm_prog_data->vertex_attributes_bypass;
#endif
for (unsigned i = 0; i < 32; i++)
sbe.AttributeActiveComponentFormat[i] = ACF_XYZW;
/* As far as we can test, some of the fields in 3DSTATE_SBE & all of
* 3DSTATE_SBE_SWIZ has no effect when the pipeline is using Mesh so
* don't bother filling those fields.
*/
if (anv_pipeline_is_primitive(pipeline)) {
for (uint8_t idx = 0; idx < wm_prog_data->urb_setup_attribs_count; idx++) {
gl_varying_slot attr = wm_prog_data->urb_setup_attribs[idx];
int input_index = wm_prog_data->urb_setup[attr];
assert(0 <= input_index);
if (attr == VARYING_SLOT_PNTC) {
sbe.PointSpriteTextureCoordinateEnable = 1 << input_index;
continue;
}
const int slot = vue_map->varying_to_slot[attr];
if (slot == -1)
continue;
/* We have to subtract two slots to account for the URB entry
* output read offset in the VS and GS stages.
*/
const int source_attr = slot - 2 * vertex_read_offset;
assert(source_attr >= 0 && source_attr < 32);
max_source_attr = MAX2(max_source_attr, source_attr);
/* The hardware can only do overrides on 16 overrides at a time,
* and the other up to 16 have to be lined up so that the input
* index = the output index. We'll need to do some tweaking to
* make sure that's the case.
*/
if (input_index < 16)
swiz.Attribute[input_index].SourceAttribute = source_attr;
else
assert(source_attr == input_index);
}
sbe.VertexURBEntryReadOffset = vertex_read_offset;
sbe.VertexURBEntryReadLength = vertex_read_length;
sbe.ForceVertexURBEntryReadOffset = true;
sbe.ForceVertexURBEntryReadLength = true;
}
/* Ask the hardware to supply PrimitiveID if the fragment shader reads
* it but a previous stage didn't write one.
*/
if (sbe_primitive_id_override(pipeline)) {
sbe.PrimitiveIDOverrideAttributeSelect =
wm_prog_data->urb_setup[VARYING_SLOT_PRIMITIVE_ID];
sbe.PrimitiveIDOverrideComponentX = true;
sbe.PrimitiveIDOverrideComponentY = true;
sbe.PrimitiveIDOverrideComponentZ = true;
sbe.PrimitiveIDOverrideComponentW = true;
}
#if GFX_VERx10 >= 125
if (device->vk.enabled_extensions.EXT_mesh_shader) {
anv_pipeline_emit(pipeline, final.sbe_mesh,
GENX(3DSTATE_SBE_MESH), sbe_mesh) {
if (mesh_prog_data == NULL)
continue;
sbe_mesh.PerVertexURBEntryOutputReadOffset = vertex_read_offset;
sbe_mesh.PerVertexURBEntryOutputReadLength = vertex_read_length;
uint32_t prim_read_offset, prim_read_length;
brw_compute_sbe_per_primitive_urb_read(wm_prog_data->per_primitive_inputs,
wm_prog_data->num_per_primitive_inputs,
&mesh_prog_data->map,
&prim_read_offset,
&prim_read_length);
sbe_mesh.PerPrimitiveURBEntryOutputReadOffset = prim_read_offset;
sbe_mesh.PerPrimitiveURBEntryOutputReadLength = prim_read_length;
}
}
#endif
}
}
}
static void
emit_3dstate_clip(struct anv_graphics_pipeline *pipeline,
const struct vk_input_assembly_state *ia,
@ -1766,7 +1637,6 @@ genX(graphics_pipeline_emit)(struct anv_graphics_pipeline *pipeline,
#endif
}
emit_3dstate_sbe(pipeline);
emit_3dstate_wm(pipeline, state->ia, state->rs,
state->ms, state->cb, state->rp);
emit_3dstate_ps(pipeline, state->ms, state->cb);