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;
|
uint32_t primitive_topology;
|
||||||
|
|
||||||
struct {
|
struct anv_buffer *index_buffer;
|
||||||
struct anv_buffer *index_buffer;
|
uint32_t index_type; /**< 3DSTATE_INDEX_BUFFER.IndexFormat */
|
||||||
uint32_t index_type; /**< 3DSTATE_INDEX_BUFFER.IndexFormat */
|
uint32_t index_offset;
|
||||||
uint32_t index_offset;
|
|
||||||
} gfx7;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum anv_depth_reg_mode {
|
enum anv_depth_reg_mode {
|
||||||
|
@@ -7425,6 +7425,51 @@ void genX(CmdWaitEvents2)(
|
|||||||
cmd_buffer_barrier(cmd_buffer, pDependencyInfos, "wait event");
|
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)(
|
VkResult genX(CmdSetPerformanceOverrideINTEL)(
|
||||||
VkCommandBuffer commandBuffer,
|
VkCommandBuffer commandBuffer,
|
||||||
const VkPerformanceOverrideInfoINTEL* pOverrideInfo)
|
const VkPerformanceOverrideInfoINTEL* pOverrideInfo)
|
||||||
|
@@ -33,54 +33,6 @@
|
|||||||
#include "genxml/gen_macros.h"
|
#include "genxml/gen_macros.h"
|
||||||
#include "genxml/genX_pack.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
|
static uint32_t
|
||||||
get_depth_format(struct anv_cmd_buffer *cmd_buffer)
|
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 |
|
cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE |
|
||||||
ANV_CMD_DIRTY_INDEX_BUFFER |
|
ANV_CMD_DIRTY_INDEX_BUFFER |
|
||||||
ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE)) {
|
ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE)) {
|
||||||
struct anv_buffer *buffer = cmd_buffer->state.gfx.gfx7.index_buffer;
|
struct anv_buffer *buffer = cmd_buffer->state.gfx.index_buffer;
|
||||||
uint32_t offset = cmd_buffer->state.gfx.gfx7.index_offset;
|
uint32_t offset = cmd_buffer->state.gfx.index_offset;
|
||||||
|
|
||||||
#if GFX_VERx10 == 75
|
#if GFX_VERx10 == 75
|
||||||
anv_batch_emit(&cmd_buffer->batch, GFX75_3DSTATE_VF, vf) {
|
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
|
#if GFX_VERx10 != 75
|
||||||
ib.CutIndexEnable = d->primitive_restart_enable;
|
ib.CutIndexEnable = d->primitive_restart_enable;
|
||||||
#endif
|
#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,
|
ib.MOCS = anv_mocs(cmd_buffer->device,
|
||||||
buffer->address.bo,
|
buffer->address.bo,
|
||||||
ISL_SURF_USAGE_INDEX_BUFFER_BIT);
|
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 GFX_VERx10 >= 125
|
||||||
if (cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE |
|
if (cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE |
|
||||||
ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE)) {
|
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;
|
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