anv: fix index buffer emission
In the following case : vkCmdBindPipeline(compute_pipeline); vkCmdDispatch(...); vkCmdBindPipeline(graphics_pipeline); vkCmdBindIndexBuffer(buffer) vkCmdDraw(...); We're emitting the 3DSTATE_INDEX_BUFFER instruction while the HW is still in GPGPU mode, because we're dealing the pipeline selection to vkCmdDraw(). Found while debugging Age Of Empire 4, HW is hung on 3DSTATE_INDEX_BUFFER instruction. Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Cc: mesa-stable Reviewed-by: Jason Ekstrand <jason.ekstrand@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17153>
This commit is contained in:

committed by
Marge Bot

parent
21ea19d504
commit
4f10eddf77
@@ -2888,11 +2888,9 @@ struct anv_cmd_graphics_state {
|
||||
|
||||
uint32_t primitive_topology;
|
||||
|
||||
struct {
|
||||
struct anv_buffer *index_buffer;
|
||||
uint32_t index_type; /**< 3DSTATE_INDEX_BUFFER.IndexFormat */
|
||||
uint32_t index_offset;
|
||||
} gfx7;
|
||||
};
|
||||
|
||||
enum anv_depth_reg_mode {
|
||||
|
@@ -7425,6 +7425,51 @@ void genX(CmdWaitEvents2)(
|
||||
cmd_buffer_barrier(cmd_buffer, pDependencyInfos, "wait event");
|
||||
}
|
||||
|
||||
static uint32_t vk_to_intel_index_type(VkIndexType type)
|
||||
{
|
||||
switch (type) {
|
||||
case VK_INDEX_TYPE_UINT8_EXT:
|
||||
return INDEX_BYTE;
|
||||
case VK_INDEX_TYPE_UINT16:
|
||||
return INDEX_WORD;
|
||||
case VK_INDEX_TYPE_UINT32:
|
||||
return INDEX_DWORD;
|
||||
default:
|
||||
unreachable("invalid index type");
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t restart_index_for_type(VkIndexType type)
|
||||
{
|
||||
switch (type) {
|
||||
case VK_INDEX_TYPE_UINT8_EXT:
|
||||
return UINT8_MAX;
|
||||
case VK_INDEX_TYPE_UINT16:
|
||||
return UINT16_MAX;
|
||||
case VK_INDEX_TYPE_UINT32:
|
||||
return UINT32_MAX;
|
||||
default:
|
||||
unreachable("invalid index type");
|
||||
}
|
||||
}
|
||||
|
||||
void genX(CmdBindIndexBuffer)(
|
||||
VkCommandBuffer commandBuffer,
|
||||
VkBuffer _buffer,
|
||||
VkDeviceSize offset,
|
||||
VkIndexType indexType)
|
||||
{
|
||||
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
|
||||
ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
|
||||
|
||||
cmd_buffer->state.restart_index = restart_index_for_type(indexType);
|
||||
cmd_buffer->state.gfx.index_buffer = buffer;
|
||||
cmd_buffer->state.gfx.index_type = vk_to_intel_index_type(indexType);
|
||||
cmd_buffer->state.gfx.index_offset = offset;
|
||||
|
||||
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_INDEX_BUFFER;
|
||||
}
|
||||
|
||||
VkResult genX(CmdSetPerformanceOverrideINTEL)(
|
||||
VkCommandBuffer commandBuffer,
|
||||
const VkPerformanceOverrideInfoINTEL* pOverrideInfo)
|
||||
|
@@ -33,54 +33,6 @@
|
||||
#include "genxml/gen_macros.h"
|
||||
#include "genxml/genX_pack.h"
|
||||
|
||||
#if GFX_VERx10 == 70
|
||||
#endif
|
||||
|
||||
static uint32_t vk_to_intel_index_type(VkIndexType type)
|
||||
{
|
||||
switch (type) {
|
||||
case VK_INDEX_TYPE_UINT8_EXT:
|
||||
return INDEX_BYTE;
|
||||
case VK_INDEX_TYPE_UINT16:
|
||||
return INDEX_WORD;
|
||||
case VK_INDEX_TYPE_UINT32:
|
||||
return INDEX_DWORD;
|
||||
default:
|
||||
unreachable("invalid index type");
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t restart_index_for_type(VkIndexType type)
|
||||
{
|
||||
switch (type) {
|
||||
case VK_INDEX_TYPE_UINT8_EXT:
|
||||
return UINT8_MAX;
|
||||
case VK_INDEX_TYPE_UINT16:
|
||||
return UINT16_MAX;
|
||||
case VK_INDEX_TYPE_UINT32:
|
||||
return UINT32_MAX;
|
||||
default:
|
||||
unreachable("invalid index type");
|
||||
}
|
||||
}
|
||||
|
||||
void genX(CmdBindIndexBuffer)(
|
||||
VkCommandBuffer commandBuffer,
|
||||
VkBuffer _buffer,
|
||||
VkDeviceSize offset,
|
||||
VkIndexType indexType)
|
||||
{
|
||||
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
|
||||
ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
|
||||
|
||||
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_INDEX_BUFFER;
|
||||
if (GFX_VERx10 == 75)
|
||||
cmd_buffer->state.restart_index = restart_index_for_type(indexType);
|
||||
cmd_buffer->state.gfx.gfx7.index_buffer = buffer;
|
||||
cmd_buffer->state.gfx.gfx7.index_type = vk_to_intel_index_type(indexType);
|
||||
cmd_buffer->state.gfx.gfx7.index_offset = offset;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
get_depth_format(struct anv_cmd_buffer *cmd_buffer)
|
||||
{
|
||||
@@ -244,12 +196,12 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
|
||||
}
|
||||
}
|
||||
|
||||
if (cmd_buffer->state.gfx.gfx7.index_buffer &&
|
||||
if (cmd_buffer->state.gfx.index_buffer &&
|
||||
cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE |
|
||||
ANV_CMD_DIRTY_INDEX_BUFFER |
|
||||
ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE)) {
|
||||
struct anv_buffer *buffer = cmd_buffer->state.gfx.gfx7.index_buffer;
|
||||
uint32_t offset = cmd_buffer->state.gfx.gfx7.index_offset;
|
||||
struct anv_buffer *buffer = cmd_buffer->state.gfx.index_buffer;
|
||||
uint32_t offset = cmd_buffer->state.gfx.index_offset;
|
||||
|
||||
#if GFX_VERx10 == 75
|
||||
anv_batch_emit(&cmd_buffer->batch, GFX75_3DSTATE_VF, vf) {
|
||||
@@ -262,7 +214,7 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
|
||||
#if GFX_VERx10 != 75
|
||||
ib.CutIndexEnable = d->primitive_restart_enable;
|
||||
#endif
|
||||
ib.IndexFormat = cmd_buffer->state.gfx.gfx7.index_type;
|
||||
ib.IndexFormat = cmd_buffer->state.gfx.index_type;
|
||||
ib.MOCS = anv_mocs(cmd_buffer->device,
|
||||
buffer->address.bo,
|
||||
ISL_SURF_USAGE_INDEX_BUFFER_BIT);
|
||||
|
@@ -592,6 +592,23 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
|
||||
}
|
||||
}
|
||||
|
||||
if (cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_INDEX_BUFFER) {
|
||||
struct anv_buffer *buffer = cmd_buffer->state.gfx.index_buffer;
|
||||
uint32_t offset = cmd_buffer->state.gfx.index_offset;
|
||||
anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_INDEX_BUFFER), ib) {
|
||||
ib.IndexFormat = cmd_buffer->state.gfx.index_type;
|
||||
ib.MOCS = anv_mocs(cmd_buffer->device,
|
||||
buffer->address.bo,
|
||||
ISL_SURF_USAGE_INDEX_BUFFER_BIT);
|
||||
#if GFX_VER >= 12
|
||||
ib.L3BypassDisable = true;
|
||||
#endif
|
||||
ib.BufferStartingAddress = anv_address_add(buffer->address, offset);
|
||||
ib.BufferSize = vk_buffer_range(&buffer->vk, offset,
|
||||
VK_WHOLE_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
#if GFX_VERx10 >= 125
|
||||
if (cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE |
|
||||
ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE)) {
|
||||
@@ -712,58 +729,3 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
|
||||
|
||||
cmd_buffer->state.gfx.dirty = 0;
|
||||
}
|
||||
|
||||
static uint32_t vk_to_intel_index_type(VkIndexType type)
|
||||
{
|
||||
switch (type) {
|
||||
case VK_INDEX_TYPE_UINT8_EXT:
|
||||
return INDEX_BYTE;
|
||||
case VK_INDEX_TYPE_UINT16:
|
||||
return INDEX_WORD;
|
||||
case VK_INDEX_TYPE_UINT32:
|
||||
return INDEX_DWORD;
|
||||
default:
|
||||
unreachable("invalid index type");
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t restart_index_for_type(VkIndexType type)
|
||||
{
|
||||
switch (type) {
|
||||
case VK_INDEX_TYPE_UINT8_EXT:
|
||||
return UINT8_MAX;
|
||||
case VK_INDEX_TYPE_UINT16:
|
||||
return UINT16_MAX;
|
||||
case VK_INDEX_TYPE_UINT32:
|
||||
return UINT32_MAX;
|
||||
default:
|
||||
unreachable("invalid index type");
|
||||
}
|
||||
}
|
||||
|
||||
void genX(CmdBindIndexBuffer)(
|
||||
VkCommandBuffer commandBuffer,
|
||||
VkBuffer _buffer,
|
||||
VkDeviceSize offset,
|
||||
VkIndexType indexType)
|
||||
{
|
||||
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
|
||||
ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
|
||||
|
||||
cmd_buffer->state.restart_index = restart_index_for_type(indexType);
|
||||
|
||||
anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_INDEX_BUFFER), ib) {
|
||||
ib.IndexFormat = vk_to_intel_index_type(indexType);
|
||||
ib.MOCS = anv_mocs(cmd_buffer->device,
|
||||
buffer->address.bo,
|
||||
ISL_SURF_USAGE_INDEX_BUFFER_BIT);
|
||||
#if GFX_VER >= 12
|
||||
ib.L3BypassDisable = true;
|
||||
#endif
|
||||
ib.BufferStartingAddress = anv_address_add(buffer->address, offset);
|
||||
ib.BufferSize = vk_buffer_range(&buffer->vk, offset,
|
||||
VK_WHOLE_SIZE);
|
||||
}
|
||||
|
||||
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_INDEX_BUFFER;
|
||||
}
|
||||
|
Reference in New Issue
Block a user