anv: deal with state stream allocation failures
In case we run out of space, all the parts of the driver that rely on this should deal with failure. The helpers will set the batch in error state so that it cannot be submitted by the application. 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/25955>
This commit is contained in:
committed by
Marge Bot
parent
ed83d1415c
commit
b30428416a
@@ -721,19 +721,47 @@ anv_cmd_buffer_alloc_binding_table(struct anv_cmd_buffer *cmd_buffer,
|
||||
}
|
||||
|
||||
struct anv_state
|
||||
anv_cmd_buffer_alloc_surface_state(struct anv_cmd_buffer *cmd_buffer)
|
||||
anv_cmd_buffer_alloc_surface_states(struct anv_cmd_buffer *cmd_buffer,
|
||||
uint32_t count)
|
||||
{
|
||||
if (count == 0)
|
||||
return ANV_STATE_NULL;
|
||||
struct isl_device *isl_dev = &cmd_buffer->device->isl_dev;
|
||||
return anv_state_stream_alloc(&cmd_buffer->surface_state_stream,
|
||||
isl_dev->ss.size, isl_dev->ss.align);
|
||||
struct anv_state state =
|
||||
anv_state_stream_alloc(&cmd_buffer->surface_state_stream,
|
||||
count * isl_dev->ss.size,
|
||||
isl_dev->ss.align);
|
||||
if (state.map == NULL)
|
||||
anv_batch_set_error(&cmd_buffer->batch, VK_ERROR_OUT_OF_DEVICE_MEMORY);
|
||||
return state;
|
||||
}
|
||||
|
||||
struct anv_state
|
||||
anv_cmd_buffer_alloc_dynamic_state(struct anv_cmd_buffer *cmd_buffer,
|
||||
uint32_t size, uint32_t alignment)
|
||||
{
|
||||
return anv_state_stream_alloc(&cmd_buffer->dynamic_state_stream,
|
||||
size, alignment);
|
||||
if (size == 0)
|
||||
return ANV_STATE_NULL;
|
||||
struct anv_state state =
|
||||
anv_state_stream_alloc(&cmd_buffer->dynamic_state_stream,
|
||||
size, alignment);
|
||||
if (state.map == NULL)
|
||||
anv_batch_set_error(&cmd_buffer->batch, VK_ERROR_OUT_OF_DEVICE_MEMORY);
|
||||
return state;
|
||||
}
|
||||
|
||||
struct anv_state
|
||||
anv_cmd_buffer_alloc_general_state(struct anv_cmd_buffer *cmd_buffer,
|
||||
uint32_t size, uint32_t alignment)
|
||||
{
|
||||
if (size == 0)
|
||||
return ANV_STATE_NULL;
|
||||
struct anv_state state =
|
||||
anv_state_stream_alloc(&cmd_buffer->general_state_stream,
|
||||
size, alignment);
|
||||
if (state.map == NULL)
|
||||
anv_batch_set_error(&cmd_buffer->batch, VK_ERROR_OUT_OF_DEVICE_MEMORY);
|
||||
return state;
|
||||
}
|
||||
|
||||
/** Allocate space associated with a command buffer
|
||||
@@ -753,6 +781,12 @@ anv_cmd_buffer_alloc_space(struct anv_cmd_buffer *cmd_buffer,
|
||||
struct anv_state state =
|
||||
anv_state_stream_alloc(&cmd_buffer->dynamic_state_stream,
|
||||
size, alignment);
|
||||
if (state.map == NULL) {
|
||||
anv_batch_set_error(&cmd_buffer->batch, VK_ERROR_OUT_OF_DEVICE_MEMORY);
|
||||
return (struct anv_cmd_alloc) {
|
||||
.address = ANV_NULL_ADDRESS,
|
||||
};
|
||||
}
|
||||
|
||||
return (struct anv_cmd_alloc) {
|
||||
.address = anv_state_pool_state_address(
|
||||
|
||||
@@ -1063,6 +1063,8 @@ anv_cmd_buffer_cs_push_constants(struct anv_cmd_buffer *cmd_buffer)
|
||||
aligned_total_push_constants_size,
|
||||
push_constant_alignment);
|
||||
}
|
||||
if (state.map == NULL)
|
||||
return state;
|
||||
|
||||
void *dst = state.map;
|
||||
const void *src = (char *)data + (range->start * 32);
|
||||
@@ -1164,7 +1166,8 @@ void anv_CmdPushDescriptorSetKHR(
|
||||
struct anv_push_descriptor_set *push_set =
|
||||
&anv_cmd_buffer_get_pipe_state(cmd_buffer,
|
||||
pipelineBindPoint)->push_descriptor;
|
||||
anv_push_descriptor_set_init(cmd_buffer, push_set, set_layout);
|
||||
if (!anv_push_descriptor_set_init(cmd_buffer, push_set, set_layout))
|
||||
return;
|
||||
|
||||
anv_descriptor_set_write(cmd_buffer->device, &push_set->set,
|
||||
descriptorWriteCount, pDescriptorWrites);
|
||||
@@ -1194,7 +1197,8 @@ void anv_CmdPushDescriptorSetWithTemplateKHR(
|
||||
struct anv_push_descriptor_set *push_set =
|
||||
&anv_cmd_buffer_get_pipe_state(cmd_buffer,
|
||||
template->bind_point)->push_descriptor;
|
||||
anv_push_descriptor_set_init(cmd_buffer, push_set, set_layout);
|
||||
if (!anv_push_descriptor_set_init(cmd_buffer, push_set, set_layout))
|
||||
return;
|
||||
|
||||
anv_descriptor_set_write_template(cmd_buffer->device, &push_set->set,
|
||||
template,
|
||||
|
||||
@@ -1345,6 +1345,11 @@ anv_descriptor_set_create(struct anv_device *device,
|
||||
|
||||
if (!pool->host_only) {
|
||||
set->desc_surface_state = anv_descriptor_pool_alloc_state(pool);
|
||||
if (set->desc_surface_state.map == NULL) {
|
||||
anv_descriptor_pool_free_set(pool, set);
|
||||
return vk_error(pool, VK_ERROR_OUT_OF_DEVICE_MEMORY);
|
||||
}
|
||||
|
||||
anv_fill_buffer_surface_state(device, set->desc_surface_state.map,
|
||||
format, ISL_SWIZZLE_IDENTITY,
|
||||
ISL_SURF_USAGE_CONSTANT_BUFFER_BIT,
|
||||
@@ -1533,7 +1538,7 @@ VkResult anv_FreeDescriptorSets(
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
anv_push_descriptor_set_init(struct anv_cmd_buffer *cmd_buffer,
|
||||
struct anv_push_descriptor_set *push_set,
|
||||
struct anv_descriptor_set_layout *layout)
|
||||
@@ -1580,6 +1585,9 @@ anv_push_descriptor_set_init(struct anv_cmd_buffer *cmd_buffer,
|
||||
anv_state_stream_alloc(push_stream,
|
||||
anv_descriptor_set_layout_descriptor_buffer_size(layout, 0),
|
||||
ANV_UBO_ALIGNMENT);
|
||||
if (desc_mem.map == NULL)
|
||||
return false;
|
||||
|
||||
if (set->desc_mem.alloc_size) {
|
||||
/* TODO: Do we really need to copy all the time? */
|
||||
memcpy(desc_mem.map, set->desc_mem.map,
|
||||
@@ -1593,6 +1601,8 @@ anv_push_descriptor_set_init(struct anv_cmd_buffer *cmd_buffer,
|
||||
set->desc_offset = anv_address_physical(set->desc_addr) -
|
||||
push_base_address;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -637,6 +637,7 @@ struct anv_state_table {
|
||||
int fd;
|
||||
struct anv_free_entry *map;
|
||||
uint32_t size;
|
||||
uint64_t max_size;
|
||||
struct anv_block_state state;
|
||||
struct u_vector cleanups;
|
||||
};
|
||||
@@ -2478,7 +2479,7 @@ uint32_t
|
||||
anv_descriptor_set_layout_descriptor_buffer_size(const struct anv_descriptor_set_layout *set_layout,
|
||||
uint32_t var_desc_count);
|
||||
|
||||
void
|
||||
bool
|
||||
anv_push_descriptor_set_init(struct anv_cmd_buffer *cmd_buffer,
|
||||
struct anv_push_descriptor_set *push_set,
|
||||
struct anv_descriptor_set_layout *layout);
|
||||
@@ -3776,10 +3777,14 @@ struct anv_state
|
||||
anv_cmd_buffer_alloc_binding_table(struct anv_cmd_buffer *cmd_buffer,
|
||||
uint32_t entries, uint32_t *state_offset);
|
||||
struct anv_state
|
||||
anv_cmd_buffer_alloc_surface_state(struct anv_cmd_buffer *cmd_buffer);
|
||||
anv_cmd_buffer_alloc_surface_states(struct anv_cmd_buffer *cmd_buffer,
|
||||
uint32_t count);
|
||||
struct anv_state
|
||||
anv_cmd_buffer_alloc_dynamic_state(struct anv_cmd_buffer *cmd_buffer,
|
||||
uint32_t size, uint32_t alignment);
|
||||
struct anv_state
|
||||
anv_cmd_buffer_alloc_general_state(struct anv_cmd_buffer *cmd_buffer,
|
||||
uint32_t size, uint32_t alignment);
|
||||
|
||||
void
|
||||
anv_cmd_buffer_chain_command_buffers(struct anv_cmd_buffer **cmd_buffers,
|
||||
|
||||
@@ -139,8 +139,7 @@ blorp_alloc_general_state(struct blorp_batch *batch,
|
||||
struct anv_cmd_buffer *cmd_buffer = batch->driver_batch;
|
||||
|
||||
struct anv_state state =
|
||||
anv_state_stream_alloc(&cmd_buffer->general_state_stream, size,
|
||||
alignment);
|
||||
anv_cmd_buffer_alloc_general_state(cmd_buffer, size, alignment);
|
||||
|
||||
*offset = state.offset;
|
||||
return state.map;
|
||||
@@ -168,7 +167,9 @@ blorp_alloc_binding_table(struct blorp_batch *batch, unsigned num_entries,
|
||||
|
||||
for (unsigned i = 0; i < num_entries; i++) {
|
||||
struct anv_state surface_state =
|
||||
anv_cmd_buffer_alloc_surface_state(cmd_buffer);
|
||||
anv_cmd_buffer_alloc_surface_states(cmd_buffer, 1);
|
||||
if (surface_state.map == NULL)
|
||||
return false;
|
||||
|
||||
bt_map[i] = surface_state.offset + state_offset;
|
||||
surface_offsets[i] = surface_state.offset;
|
||||
|
||||
@@ -1264,12 +1264,9 @@ anv_cmd_buffer_init_attachments(struct anv_cmd_buffer *cmd_buffer,
|
||||
const struct isl_device *isl_dev = &cmd_buffer->device->isl_dev;
|
||||
const uint32_t ss_stride = align(isl_dev->ss.size, isl_dev->ss.align);
|
||||
gfx->att_states =
|
||||
anv_state_stream_alloc(&cmd_buffer->surface_state_stream,
|
||||
num_states * ss_stride, isl_dev->ss.align);
|
||||
if (gfx->att_states.map == NULL) {
|
||||
return anv_batch_set_error(&cmd_buffer->batch,
|
||||
VK_ERROR_OUT_OF_DEVICE_MEMORY);
|
||||
}
|
||||
anv_cmd_buffer_alloc_surface_states(cmd_buffer, num_states);
|
||||
if (gfx->att_states.map == NULL)
|
||||
return VK_ERROR_OUT_OF_DEVICE_MEMORY;
|
||||
|
||||
struct anv_state next_state = gfx->att_states;
|
||||
next_state.alloc_size = isl_dev->ss.size;
|
||||
@@ -1874,7 +1871,11 @@ emit_dynamic_buffer_binding_table_entry(struct anv_cmd_buffer *cmd_buffer,
|
||||
struct anv_address address =
|
||||
anv_address_add(desc->buffer->address, offset);
|
||||
|
||||
struct anv_state surface_state = anv_cmd_buffer_alloc_surface_state(cmd_buffer);
|
||||
struct anv_state surface_state =
|
||||
anv_cmd_buffer_alloc_surface_states(cmd_buffer, 1);
|
||||
if (surface_state.map == NULL)
|
||||
return ANV_STATE_NULL;
|
||||
|
||||
enum isl_format format =
|
||||
anv_isl_format_for_descriptor_type(cmd_buffer->device,
|
||||
desc->type);
|
||||
@@ -1987,7 +1988,6 @@ emit_indirect_descriptor_binding_table_entry(struct anv_cmd_buffer *cmd_buffer,
|
||||
unreachable("Invalid descriptor type");
|
||||
}
|
||||
|
||||
assert(surface_state.map);
|
||||
return surface_state.offset;
|
||||
}
|
||||
|
||||
@@ -2086,7 +2086,9 @@ emit_binding_table(struct anv_cmd_buffer *cmd_buffer,
|
||||
assert(shader->stage == MESA_SHADER_COMPUTE && s == 0);
|
||||
|
||||
struct anv_state surface_state =
|
||||
anv_cmd_buffer_alloc_surface_state(cmd_buffer);
|
||||
anv_cmd_buffer_alloc_surface_states(cmd_buffer, 1);
|
||||
if (surface_state.map == NULL)
|
||||
return VK_ERROR_OUT_OF_DEVICE_MEMORY;
|
||||
|
||||
const enum isl_format format =
|
||||
anv_isl_format_for_descriptor_type(cmd_buffer->device,
|
||||
@@ -2329,7 +2331,9 @@ flush_push_descriptor_set(struct anv_cmd_buffer *cmd_buffer,
|
||||
|
||||
if (bview != NULL) {
|
||||
bview->general.state =
|
||||
anv_cmd_buffer_alloc_surface_state(cmd_buffer);
|
||||
anv_cmd_buffer_alloc_surface_states(cmd_buffer, 1);
|
||||
if (bview->general.state.map == NULL)
|
||||
return;
|
||||
anv_descriptor_write_surface_state(cmd_buffer->device, desc,
|
||||
bview->general.state);
|
||||
}
|
||||
@@ -2341,7 +2345,10 @@ flush_push_descriptor_set(struct anv_cmd_buffer *cmd_buffer,
|
||||
anv_isl_format_for_descriptor_type(cmd_buffer->device,
|
||||
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
||||
|
||||
set->desc_surface_state = anv_cmd_buffer_alloc_surface_state(cmd_buffer);
|
||||
set->desc_surface_state =
|
||||
anv_cmd_buffer_alloc_surface_states(cmd_buffer, 1);
|
||||
if (set->desc_surface_state.map == NULL)
|
||||
return;
|
||||
anv_fill_buffer_surface_state(cmd_buffer->device,
|
||||
set->desc_surface_state.map,
|
||||
format, ISL_SWIZZLE_IDENTITY,
|
||||
@@ -5926,8 +5933,8 @@ genX(cmd_buffer_dispatch_kernel)(struct anv_cmd_buffer *cmd_buffer,
|
||||
indirect_data_size += kernel->bin->bind_map.kernel_args_size;
|
||||
indirect_data_size = ALIGN(indirect_data_size, 64);
|
||||
struct anv_state indirect_data =
|
||||
anv_state_stream_alloc(&cmd_buffer->general_state_stream,
|
||||
indirect_data_size, 64);
|
||||
anv_cmd_buffer_alloc_general_state(cmd_buffer,
|
||||
indirect_data_size, 64);
|
||||
memset(indirect_data.map, 0, indirect_data.alloc_size);
|
||||
|
||||
struct brw_kernel_sysvals sysvals = {};
|
||||
|
||||
@@ -61,6 +61,8 @@ genX(cmd_buffer_emit_generate_draws)(struct anv_cmd_buffer *cmd_buffer,
|
||||
struct anv_state push_data_state =
|
||||
genX(simple_shader_alloc_push)(simple_state,
|
||||
sizeof(struct anv_generated_indirect_params));
|
||||
if (push_data_state.map == NULL)
|
||||
return ANV_STATE_NULL;
|
||||
|
||||
struct anv_graphics_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
|
||||
const struct brw_vs_prog_data *vs_prog_data = get_vs_prog_data(pipeline);
|
||||
@@ -323,6 +325,8 @@ genX(cmd_buffer_emit_indirect_generated_draws_inplace)(struct anv_cmd_buffer *cm
|
||||
indexed,
|
||||
0 /* ring_count */);
|
||||
struct anv_generated_indirect_params *params = params_state.map;
|
||||
if (params == NULL)
|
||||
return;
|
||||
|
||||
anv_batch_advance(&cmd_buffer->batch, draw_cmd_size);
|
||||
|
||||
|
||||
@@ -1731,6 +1731,9 @@ copy_query_results_with_shader(struct anv_cmd_buffer *cmd_buffer,
|
||||
struct anv_state push_data_state =
|
||||
genX(simple_shader_alloc_push)(&state,
|
||||
sizeof(struct anv_query_copy_params));
|
||||
if (push_data_state.map == NULL)
|
||||
return;
|
||||
|
||||
struct anv_query_copy_params *params = push_data_state.map;
|
||||
|
||||
uint32_t copy_flags =
|
||||
|
||||
@@ -216,6 +216,9 @@ genX(emit_simpler_shader_init_fragment)(struct anv_simple_shader *state)
|
||||
struct anv_state cc_state =
|
||||
anv_state_stream_alloc(state->dynamic_state_stream,
|
||||
4 * GENX(CC_VIEWPORT_length), 32);
|
||||
if (cc_state.map == NULL)
|
||||
return;
|
||||
|
||||
struct GENX(CC_VIEWPORT) cc_viewport = {
|
||||
.MinimumDepth = 0.0f,
|
||||
.MaximumDepth = 1.0f,
|
||||
@@ -380,16 +383,23 @@ genX(emit_simple_shader_init)(struct anv_simple_shader *state)
|
||||
struct anv_state
|
||||
genX(simple_shader_alloc_push)(struct anv_simple_shader *state, uint32_t size)
|
||||
{
|
||||
struct anv_state s;
|
||||
|
||||
if (state->kernel->stage == MESA_SHADER_FRAGMENT) {
|
||||
return anv_state_stream_alloc(state->dynamic_state_stream,
|
||||
size, ANV_UBO_ALIGNMENT);
|
||||
s = anv_state_stream_alloc(state->dynamic_state_stream,
|
||||
size, ANV_UBO_ALIGNMENT);
|
||||
} else {
|
||||
#if GFX_VERx10 >= 125
|
||||
return anv_state_stream_alloc(state->general_state_stream, align(size, 64), 64);
|
||||
s = anv_state_stream_alloc(state->general_state_stream, align(size, 64), 64);
|
||||
#else
|
||||
return anv_state_stream_alloc(state->dynamic_state_stream, size, 64);
|
||||
s = anv_state_stream_alloc(state->dynamic_state_stream, size, 64);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (s.map == NULL)
|
||||
anv_batch_set_error(state->batch, VK_ERROR_OUT_OF_DEVICE_MEMORY);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/** Get the address of allocated push constant data by
|
||||
@@ -433,6 +443,8 @@ genX(emit_simple_shader_dispatch)(struct anv_simple_shader *state,
|
||||
struct anv_state vs_data_state =
|
||||
anv_state_stream_alloc(state->dynamic_state_stream,
|
||||
9 * sizeof(uint32_t), 32);
|
||||
if (vs_data_state.map == NULL)
|
||||
return;
|
||||
|
||||
float x0 = 0.0f, x1 = MIN2(num_threads, 8192);
|
||||
float y0 = 0.0f, y1 = DIV_ROUND_UP(num_threads, 8192);
|
||||
@@ -602,6 +614,9 @@ genX(emit_simple_shader_dispatch)(struct anv_simple_shader *state,
|
||||
struct anv_state iface_desc_state =
|
||||
anv_state_stream_alloc(state->dynamic_state_stream,
|
||||
GENX(INTERFACE_DESCRIPTOR_DATA_length) * 4, 64);
|
||||
if (iface_desc_state.map == NULL)
|
||||
return;
|
||||
|
||||
struct GENX(INTERFACE_DESCRIPTOR_DATA) iface_desc = {
|
||||
.KernelStartPointer = state->kernel->kernel.offset +
|
||||
brw_cs_prog_data_prog_offset(prog_data,
|
||||
|
||||
@@ -165,7 +165,7 @@ blorp_alloc_general_state(struct blorp_batch *batch,
|
||||
return state.map;
|
||||
}
|
||||
|
||||
static void
|
||||
static bool
|
||||
blorp_alloc_binding_table(struct blorp_batch *batch, unsigned num_entries,
|
||||
unsigned state_size, unsigned state_alignment,
|
||||
uint32_t *bt_offset,
|
||||
|
||||
Reference in New Issue
Block a user