diff --git a/src/intel/vulkan/anv_batch_chain.c b/src/intel/vulkan/anv_batch_chain.c index eb39ae6e85b..60af0fa3157 100644 --- a/src/intel/vulkan/anv_batch_chain.c +++ b/src/intel/vulkan/anv_batch_chain.c @@ -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( diff --git a/src/intel/vulkan/anv_cmd_buffer.c b/src/intel/vulkan/anv_cmd_buffer.c index 524ad475415..8f9fb72c5b5 100644 --- a/src/intel/vulkan/anv_cmd_buffer.c +++ b/src/intel/vulkan/anv_cmd_buffer.c @@ -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, diff --git a/src/intel/vulkan/anv_descriptor_set.c b/src/intel/vulkan/anv_descriptor_set.c index 5dd7df16903..62202bec0c8 100644 --- a/src/intel/vulkan/anv_descriptor_set.c +++ b/src/intel/vulkan/anv_descriptor_set.c @@ -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 diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index c11595cc53b..abd1d8f9a2b 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -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, diff --git a/src/intel/vulkan/genX_blorp_exec.c b/src/intel/vulkan/genX_blorp_exec.c index 3cf2ae9b768..587dbc46db9 100644 --- a/src/intel/vulkan/genX_blorp_exec.c +++ b/src/intel/vulkan/genX_blorp_exec.c @@ -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; diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c index fa3f1415951..9a8ac921304 100644 --- a/src/intel/vulkan/genX_cmd_buffer.c +++ b/src/intel/vulkan/genX_cmd_buffer.c @@ -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 = {}; diff --git a/src/intel/vulkan/genX_cmd_draw_generated_indirect.h b/src/intel/vulkan/genX_cmd_draw_generated_indirect.h index acd768890f4..943a9700eed 100644 --- a/src/intel/vulkan/genX_cmd_draw_generated_indirect.h +++ b/src/intel/vulkan/genX_cmd_draw_generated_indirect.h @@ -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); diff --git a/src/intel/vulkan/genX_query.c b/src/intel/vulkan/genX_query.c index cb99830a7dd..9047418b58a 100644 --- a/src/intel/vulkan/genX_query.c +++ b/src/intel/vulkan/genX_query.c @@ -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 = diff --git a/src/intel/vulkan/genX_simple_shader.c b/src/intel/vulkan/genX_simple_shader.c index ee87eb6ef48..8d609ed6026 100644 --- a/src/intel/vulkan/genX_simple_shader.c +++ b/src/intel/vulkan/genX_simple_shader.c @@ -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, diff --git a/src/intel/vulkan_hasvk/genX_blorp_exec.c b/src/intel/vulkan_hasvk/genX_blorp_exec.c index 0005e527ac9..2c4c3e4036e 100644 --- a/src/intel/vulkan_hasvk/genX_blorp_exec.c +++ b/src/intel/vulkan_hasvk/genX_blorp_exec.c @@ -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,