X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fintel%2Fvulkan%2Fanv_cmd_buffer.c;h=8ef71b0ed9cfc387c33c0ffb87d76059f32df9f6;hb=ca4e465f7d018f8702ddb5332bf1c892b1808366;hp=3b59af8f6f48c0a2db7c4ded13d1c13f5e417fa7;hpb=a848e693efc8e2a1d355dc1076409968b374153f;p=mesa.git diff --git a/src/intel/vulkan/anv_cmd_buffer.c b/src/intel/vulkan/anv_cmd_buffer.c index 3b59af8f6f4..8ef71b0ed9c 100644 --- a/src/intel/vulkan/anv_cmd_buffer.c +++ b/src/intel/vulkan/anv_cmd_buffer.c @@ -113,49 +113,60 @@ anv_dynamic_state_copy(struct anv_dynamic_state *dest, } static void -anv_cmd_state_reset(struct anv_cmd_buffer *cmd_buffer) +anv_cmd_state_init(struct anv_cmd_buffer *cmd_buffer) { struct anv_cmd_state *state = &cmd_buffer->state; - cmd_buffer->batch.status = VK_SUCCESS; + memset(state, 0, sizeof(*state)); - memset(&state->descriptors, 0, sizeof(state->descriptors)); - for (uint32_t i = 0; i < MESA_SHADER_STAGES; i++) { - if (state->push_constants[i] != NULL) { - vk_free(&cmd_buffer->pool->alloc, state->push_constants[i]); - state->push_constants[i] = NULL; - } - } - memset(state->binding_tables, 0, sizeof(state->binding_tables)); - memset(state->samplers, 0, sizeof(state->samplers)); - - /* 0 isn't a valid config. This ensures that we always configure L3$. */ - cmd_buffer->state.current_l3_config = 0; - - state->dirty = 0; - state->vb_dirty = 0; - state->pending_pipe_bits = 0; - state->descriptors_dirty = 0; - state->push_constants_dirty = 0; - state->pipeline = NULL; - state->framebuffer = NULL; - state->pass = NULL; - state->subpass = NULL; - state->push_constant_stages = 0; + state->current_pipeline = UINT32_MAX; state->restart_index = UINT32_MAX; - state->dynamic = default_dynamic_state; - state->need_query_wa = true; - state->pma_fix_enabled = false; - state->hiz_enabled = false; - - if (state->attachments != NULL) { - vk_free(&cmd_buffer->pool->alloc, state->attachments); - state->attachments = NULL; - } + state->gfx.dynamic = default_dynamic_state; +} - state->gen7.index_buffer = NULL; +static void +anv_cmd_pipeline_state_finish(struct anv_cmd_buffer *cmd_buffer, + struct anv_cmd_pipeline_state *pipe_state) +{ + for (uint32_t i = 0; i < ARRAY_SIZE(pipe_state->push_descriptors); i++) + vk_free(&cmd_buffer->pool->alloc, pipe_state->push_descriptors[i]); } +static void +anv_cmd_state_finish(struct anv_cmd_buffer *cmd_buffer) +{ + struct anv_cmd_state *state = &cmd_buffer->state; + + anv_cmd_pipeline_state_finish(cmd_buffer, &state->gfx.base); + anv_cmd_pipeline_state_finish(cmd_buffer, &state->compute.base); + + for (uint32_t i = 0; i < MESA_SHADER_STAGES; i++) + vk_free(&cmd_buffer->pool->alloc, state->push_constants[i]); + + vk_free(&cmd_buffer->pool->alloc, state->attachments); +} + +static void +anv_cmd_state_reset(struct anv_cmd_buffer *cmd_buffer) +{ + anv_cmd_state_finish(cmd_buffer); + anv_cmd_state_init(cmd_buffer); +} + +/** + * This function updates the size of the push constant buffer we need to emit. + * This is called in various parts of the driver to ensure that different + * pieces of push constant data get emitted as needed. However, it is important + * that we never shrink the size of the buffer. For example, a compute shader + * dispatch will always call this for the base group id, which has an + * offset in the push constant buffer that is smaller than the offset for + * storage image data. If the compute shader has storage images, we will call + * this again with a larger size during binding table emission. However, + * if we dispatch the compute shader again without dirtying our descriptors, + * we would still call this function with a smaller size for the base group + * id, and not for the images, which would incorrectly shrink the size of the + * push constant data we emit with that dispatch, making us drop the image data. + */ VkResult anv_cmd_buffer_ensure_push_constants_size(struct anv_cmd_buffer *cmd_buffer, gl_shader_stage stage, uint32_t size) @@ -169,6 +180,7 @@ anv_cmd_buffer_ensure_push_constants_size(struct anv_cmd_buffer *cmd_buffer, anv_batch_set_error(&cmd_buffer->batch, VK_ERROR_OUT_OF_HOST_MEMORY); return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); } + (*ptr)->size = size; } else if ((*ptr)->size < size) { *ptr = vk_realloc(&cmd_buffer->pool->alloc, *ptr, size, 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); @@ -176,8 +188,8 @@ anv_cmd_buffer_ensure_push_constants_size(struct anv_cmd_buffer *cmd_buffer, anv_batch_set_error(&cmd_buffer->batch, VK_ERROR_OUT_OF_HOST_MEMORY); return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); } + (*ptr)->size = size; } - (*ptr)->size = size; return VK_SUCCESS; } @@ -198,14 +210,10 @@ static VkResult anv_create_cmd_buffer( cmd_buffer->batch.status = VK_SUCCESS; - for (uint32_t i = 0; i < MESA_SHADER_STAGES; i++) { - cmd_buffer->state.push_constants[i] = NULL; - } cmd_buffer->_loader_data.loaderMagic = ICD_LOADER_MAGIC; cmd_buffer->device = device; cmd_buffer->pool = pool; cmd_buffer->level = level; - cmd_buffer->state.attachments = NULL; result = anv_cmd_buffer_init_batch_bo_chain(cmd_buffer); if (result != VK_SUCCESS) @@ -216,8 +224,7 @@ static VkResult anv_create_cmd_buffer( anv_state_stream_init(&cmd_buffer->dynamic_state_stream, &device->dynamic_state_pool, 16384); - memset(&cmd_buffer->state.push_descriptor, 0, - sizeof(cmd_buffer->state.push_descriptor)); + anv_cmd_state_init(cmd_buffer); if (pool) { list_addtail(&cmd_buffer->pool_link, &pool->cmd_buffers); @@ -276,7 +283,8 @@ anv_cmd_buffer_destroy(struct anv_cmd_buffer *cmd_buffer) anv_state_stream_finish(&cmd_buffer->surface_state_stream); anv_state_stream_finish(&cmd_buffer->dynamic_state_stream); - vk_free(&cmd_buffer->pool->alloc, cmd_buffer->state.attachments); + anv_cmd_state_finish(cmd_buffer); + vk_free(&cmd_buffer->pool->alloc, cmd_buffer); } @@ -300,7 +308,6 @@ VkResult anv_cmd_buffer_reset(struct anv_cmd_buffer *cmd_buffer) { cmd_buffer->usage_flags = 0; - cmd_buffer->state.current_pipeline = UINT32_MAX; anv_cmd_buffer_reset_batch_bo_chain(cmd_buffer); anv_cmd_state_reset(cmd_buffer); @@ -322,24 +329,52 @@ VkResult anv_ResetCommandBuffer( return anv_cmd_buffer_reset(cmd_buffer); } +#define anv_genX_call(devinfo, func, ...) \ + switch ((devinfo)->gen) { \ + case 7: \ + if ((devinfo)->is_haswell) { \ + gen75_##func(__VA_ARGS__); \ + } else { \ + gen7_##func(__VA_ARGS__); \ + } \ + break; \ + case 8: \ + gen8_##func(__VA_ARGS__); \ + break; \ + case 9: \ + gen9_##func(__VA_ARGS__); \ + break; \ + case 10: \ + gen10_##func(__VA_ARGS__); \ + break; \ + case 11: \ + gen11_##func(__VA_ARGS__); \ + break; \ + default: \ + assert(!"Unknown hardware generation"); \ + } + void anv_cmd_buffer_emit_state_base_address(struct anv_cmd_buffer *cmd_buffer) { - switch (cmd_buffer->device->info.gen) { - case 7: - if (cmd_buffer->device->info.is_haswell) - return gen75_cmd_buffer_emit_state_base_address(cmd_buffer); - else - return gen7_cmd_buffer_emit_state_base_address(cmd_buffer); - case 8: - return gen8_cmd_buffer_emit_state_base_address(cmd_buffer); - case 9: - return gen9_cmd_buffer_emit_state_base_address(cmd_buffer); - case 10: - return gen10_cmd_buffer_emit_state_base_address(cmd_buffer); - default: - unreachable("unsupported gen\n"); - } + anv_genX_call(&cmd_buffer->device->info, + cmd_buffer_emit_state_base_address, + cmd_buffer); +} + +void +anv_cmd_buffer_mark_image_written(struct anv_cmd_buffer *cmd_buffer, + const struct anv_image *image, + VkImageAspectFlagBits aspect, + enum isl_aux_usage aux_usage, + uint32_t level, + uint32_t base_layer, + uint32_t layer_count) +{ + anv_genX_call(&cmd_buffer->device->info, + cmd_buffer_mark_image_written, + cmd_buffer, image, aspect, aux_usage, + level, base_layer, layer_count); } void anv_CmdBindPipeline( @@ -352,22 +387,22 @@ void anv_CmdBindPipeline( switch (pipelineBindPoint) { case VK_PIPELINE_BIND_POINT_COMPUTE: - cmd_buffer->state.compute_pipeline = pipeline; - cmd_buffer->state.compute_dirty |= ANV_CMD_DIRTY_PIPELINE; + cmd_buffer->state.compute.base.pipeline = pipeline; + cmd_buffer->state.compute.pipeline_dirty = true; cmd_buffer->state.push_constants_dirty |= VK_SHADER_STAGE_COMPUTE_BIT; cmd_buffer->state.descriptors_dirty |= VK_SHADER_STAGE_COMPUTE_BIT; break; case VK_PIPELINE_BIND_POINT_GRAPHICS: - cmd_buffer->state.pipeline = pipeline; - cmd_buffer->state.vb_dirty |= pipeline->vb_used; - cmd_buffer->state.dirty |= ANV_CMD_DIRTY_PIPELINE; + cmd_buffer->state.gfx.base.pipeline = pipeline; + cmd_buffer->state.gfx.vb_dirty |= pipeline->vb_used; + cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_PIPELINE; cmd_buffer->state.push_constants_dirty |= pipeline->active_stages; cmd_buffer->state.descriptors_dirty |= pipeline->active_stages; /* Apply the dynamic state from the pipeline */ - cmd_buffer->state.dirty |= pipeline->dynamic_state_mask; - anv_dynamic_state_copy(&cmd_buffer->state.dynamic, + cmd_buffer->state.gfx.dirty |= pipeline->dynamic_state_mask; + anv_dynamic_state_copy(&cmd_buffer->state.gfx.dynamic, &pipeline->dynamic_state, pipeline->dynamic_state_mask); break; @@ -387,13 +422,13 @@ void anv_CmdSetViewport( ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); const uint32_t total_count = firstViewport + viewportCount; - if (cmd_buffer->state.dynamic.viewport.count < total_count) - cmd_buffer->state.dynamic.viewport.count = total_count; + if (cmd_buffer->state.gfx.dynamic.viewport.count < total_count) + cmd_buffer->state.gfx.dynamic.viewport.count = total_count; - memcpy(cmd_buffer->state.dynamic.viewport.viewports + firstViewport, + memcpy(cmd_buffer->state.gfx.dynamic.viewport.viewports + firstViewport, pViewports, viewportCount * sizeof(*pViewports)); - cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_VIEWPORT; + cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_VIEWPORT; } void anv_CmdSetScissor( @@ -405,13 +440,13 @@ void anv_CmdSetScissor( ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); const uint32_t total_count = firstScissor + scissorCount; - if (cmd_buffer->state.dynamic.scissor.count < total_count) - cmd_buffer->state.dynamic.scissor.count = total_count; + if (cmd_buffer->state.gfx.dynamic.scissor.count < total_count) + cmd_buffer->state.gfx.dynamic.scissor.count = total_count; - memcpy(cmd_buffer->state.dynamic.scissor.scissors + firstScissor, + memcpy(cmd_buffer->state.gfx.dynamic.scissor.scissors + firstScissor, pScissors, scissorCount * sizeof(*pScissors)); - cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_SCISSOR; + cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_SCISSOR; } void anv_CmdSetLineWidth( @@ -420,8 +455,8 @@ void anv_CmdSetLineWidth( { ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); - cmd_buffer->state.dynamic.line_width = lineWidth; - cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH; + cmd_buffer->state.gfx.dynamic.line_width = lineWidth; + cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH; } void anv_CmdSetDepthBias( @@ -432,11 +467,11 @@ void anv_CmdSetDepthBias( { ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); - cmd_buffer->state.dynamic.depth_bias.bias = depthBiasConstantFactor; - cmd_buffer->state.dynamic.depth_bias.clamp = depthBiasClamp; - cmd_buffer->state.dynamic.depth_bias.slope = depthBiasSlopeFactor; + cmd_buffer->state.gfx.dynamic.depth_bias.bias = depthBiasConstantFactor; + cmd_buffer->state.gfx.dynamic.depth_bias.clamp = depthBiasClamp; + cmd_buffer->state.gfx.dynamic.depth_bias.slope = depthBiasSlopeFactor; - cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS; + cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS; } void anv_CmdSetBlendConstants( @@ -445,10 +480,10 @@ void anv_CmdSetBlendConstants( { ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); - memcpy(cmd_buffer->state.dynamic.blend_constants, + memcpy(cmd_buffer->state.gfx.dynamic.blend_constants, blendConstants, sizeof(float) * 4); - cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS; + cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS; } void anv_CmdSetDepthBounds( @@ -458,10 +493,10 @@ void anv_CmdSetDepthBounds( { ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); - cmd_buffer->state.dynamic.depth_bounds.min = minDepthBounds; - cmd_buffer->state.dynamic.depth_bounds.max = maxDepthBounds; + cmd_buffer->state.gfx.dynamic.depth_bounds.min = minDepthBounds; + cmd_buffer->state.gfx.dynamic.depth_bounds.max = maxDepthBounds; - cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS; + cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS; } void anv_CmdSetStencilCompareMask( @@ -472,11 +507,11 @@ void anv_CmdSetStencilCompareMask( ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); if (faceMask & VK_STENCIL_FACE_FRONT_BIT) - cmd_buffer->state.dynamic.stencil_compare_mask.front = compareMask; + cmd_buffer->state.gfx.dynamic.stencil_compare_mask.front = compareMask; if (faceMask & VK_STENCIL_FACE_BACK_BIT) - cmd_buffer->state.dynamic.stencil_compare_mask.back = compareMask; + cmd_buffer->state.gfx.dynamic.stencil_compare_mask.back = compareMask; - cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK; + cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK; } void anv_CmdSetStencilWriteMask( @@ -487,11 +522,11 @@ void anv_CmdSetStencilWriteMask( ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); if (faceMask & VK_STENCIL_FACE_FRONT_BIT) - cmd_buffer->state.dynamic.stencil_write_mask.front = writeMask; + cmd_buffer->state.gfx.dynamic.stencil_write_mask.front = writeMask; if (faceMask & VK_STENCIL_FACE_BACK_BIT) - cmd_buffer->state.dynamic.stencil_write_mask.back = writeMask; + cmd_buffer->state.gfx.dynamic.stencil_write_mask.back = writeMask; - cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK; + cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK; } void anv_CmdSetStencilReference( @@ -502,11 +537,67 @@ void anv_CmdSetStencilReference( ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); if (faceMask & VK_STENCIL_FACE_FRONT_BIT) - cmd_buffer->state.dynamic.stencil_reference.front = reference; + cmd_buffer->state.gfx.dynamic.stencil_reference.front = reference; if (faceMask & VK_STENCIL_FACE_BACK_BIT) - cmd_buffer->state.dynamic.stencil_reference.back = reference; + cmd_buffer->state.gfx.dynamic.stencil_reference.back = reference; + + cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE; +} + +static void +anv_cmd_buffer_bind_descriptor_set(struct anv_cmd_buffer *cmd_buffer, + VkPipelineBindPoint bind_point, + struct anv_pipeline_layout *layout, + uint32_t set_index, + struct anv_descriptor_set *set, + uint32_t *dynamic_offset_count, + const uint32_t **dynamic_offsets) +{ + struct anv_descriptor_set_layout *set_layout = + layout->set[set_index].layout; + + struct anv_cmd_pipeline_state *pipe_state; + if (bind_point == VK_PIPELINE_BIND_POINT_COMPUTE) { + pipe_state = &cmd_buffer->state.compute.base; + } else { + assert(bind_point == VK_PIPELINE_BIND_POINT_GRAPHICS); + pipe_state = &cmd_buffer->state.gfx.base; + } + pipe_state->descriptors[set_index] = set; + + if (dynamic_offsets) { + if (set_layout->dynamic_offset_count > 0) { + uint32_t dynamic_offset_start = + layout->set[set_index].dynamic_offset_start; + + /* Assert that everything is in range */ + assert(set_layout->dynamic_offset_count <= *dynamic_offset_count); + assert(dynamic_offset_start + set_layout->dynamic_offset_count <= + ARRAY_SIZE(pipe_state->dynamic_offsets)); + + typed_memcpy(&pipe_state->dynamic_offsets[dynamic_offset_start], + *dynamic_offsets, set_layout->dynamic_offset_count); - cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE; + *dynamic_offsets += set_layout->dynamic_offset_count; + *dynamic_offset_count -= set_layout->dynamic_offset_count; + } + } + + if (bind_point == VK_PIPELINE_BIND_POINT_COMPUTE) { + cmd_buffer->state.descriptors_dirty |= VK_SHADER_STAGE_COMPUTE_BIT; + } else { + assert(bind_point == VK_PIPELINE_BIND_POINT_GRAPHICS); + cmd_buffer->state.descriptors_dirty |= + set_layout->shader_stages & VK_SHADER_STAGE_ALL_GRAPHICS; + } + + /* Pipeline layout objects are required to live at least while any command + * buffers that use them are in recording state. We need to grab a reference + * to the pipeline layout being bound here so we can compute correct dynamic + * offsets for VK_DESCRIPTOR_TYPE_*_DYNAMIC in dynamic_offset_for_binding() + * when we record draw commands that come after this. + */ + pipe_state->layout = layout; } void anv_CmdBindDescriptorSets( @@ -521,35 +612,15 @@ void anv_CmdBindDescriptorSets( { ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); ANV_FROM_HANDLE(anv_pipeline_layout, layout, _layout); - struct anv_descriptor_set_layout *set_layout; - assert(firstSet + descriptorSetCount < MAX_SETS); + assert(firstSet + descriptorSetCount <= MAX_SETS); - uint32_t dynamic_slot = 0; for (uint32_t i = 0; i < descriptorSetCount; i++) { ANV_FROM_HANDLE(anv_descriptor_set, set, pDescriptorSets[i]); - set_layout = layout->set[firstSet + i].layout; - - cmd_buffer->state.descriptors[firstSet + i] = set; - - if (set_layout->dynamic_offset_count > 0) { - uint32_t dynamic_offset_start = - layout->set[firstSet + i].dynamic_offset_start; - - /* Assert that everything is in range */ - assert(dynamic_offset_start + set_layout->dynamic_offset_count <= - ARRAY_SIZE(cmd_buffer->state.dynamic_offsets)); - assert(dynamic_slot + set_layout->dynamic_offset_count <= - dynamicOffsetCount); - - typed_memcpy(&cmd_buffer->state.dynamic_offsets[dynamic_offset_start], - &pDynamicOffsets[dynamic_slot], - set_layout->dynamic_offset_count); - - dynamic_slot += set_layout->dynamic_offset_count; - } - - cmd_buffer->state.descriptors_dirty |= set_layout->shader_stages; + anv_cmd_buffer_bind_descriptor_set(cmd_buffer, pipelineBindPoint, + layout, firstSet + i, set, + &dynamicOffsetCount, + &pDynamicOffsets); } } @@ -570,7 +641,7 @@ void anv_CmdBindVertexBuffers( for (uint32_t i = 0; i < bindingCount; i++) { vb[firstBinding + i].buffer = anv_buffer_from_handle(pBuffers[i]); vb[firstBinding + i].offset = pOffsets[i]; - cmd_buffer->state.vb_dirty |= 1 << (firstBinding + i); + cmd_buffer->state.gfx.vb_dirty |= 1 << (firstBinding + i); } } @@ -628,18 +699,46 @@ anv_cmd_buffer_merge_dynamic(struct anv_cmd_buffer *cmd_buffer, return state; } +static uint32_t +anv_push_constant_value(struct anv_push_constants *data, uint32_t param) +{ + if (BRW_PARAM_IS_BUILTIN(param)) { + switch (param) { + case BRW_PARAM_BUILTIN_ZERO: + return 0; + case BRW_PARAM_BUILTIN_BASE_WORK_GROUP_ID_X: + return data->base_work_group_id[0]; + case BRW_PARAM_BUILTIN_BASE_WORK_GROUP_ID_Y: + return data->base_work_group_id[1]; + case BRW_PARAM_BUILTIN_BASE_WORK_GROUP_ID_Z: + return data->base_work_group_id[2]; + default: + unreachable("Invalid param builtin"); + } + } else { + uint32_t offset = ANV_PARAM_PUSH_OFFSET(param); + assert(offset % sizeof(uint32_t) == 0); + if (offset < data->size) + return *(uint32_t *)((uint8_t *)data + offset); + else + return 0; + } +} + struct anv_state anv_cmd_buffer_push_constants(struct anv_cmd_buffer *cmd_buffer, gl_shader_stage stage) { + struct anv_pipeline *pipeline = cmd_buffer->state.gfx.base.pipeline; + /* If we don't have this stage, bail. */ - if (!anv_pipeline_has_stage(cmd_buffer->state.pipeline, stage)) + if (!anv_pipeline_has_stage(pipeline, stage)) return (struct anv_state) { .offset = 0 }; struct anv_push_constants *data = cmd_buffer->state.push_constants[stage]; const struct brw_stage_prog_data *prog_data = - cmd_buffer->state.pipeline->shaders[stage]->prog_data; + pipeline->shaders[stage]->prog_data; /* If we don't actually have any push constants, bail. */ if (data == NULL || prog_data == NULL || prog_data->nr_params == 0) @@ -652,10 +751,8 @@ anv_cmd_buffer_push_constants(struct anv_cmd_buffer *cmd_buffer, /* Walk through the param array and fill the buffer with data */ uint32_t *u32_map = state.map; - for (unsigned i = 0; i < prog_data->nr_params; i++) { - uint32_t offset = (uintptr_t)prog_data->param[i]; - u32_map[i] = *(uint32_t *)((uint8_t *)data + offset); - } + for (unsigned i = 0; i < prog_data->nr_params; i++) + u32_map[i] = anv_push_constant_value(data, prog_data->param[i]); anv_state_flush(cmd_buffer->device, state); @@ -667,7 +764,7 @@ anv_cmd_buffer_cs_push_constants(struct anv_cmd_buffer *cmd_buffer) { struct anv_push_constants *data = cmd_buffer->state.push_constants[MESA_SHADER_COMPUTE]; - struct anv_pipeline *pipeline = cmd_buffer->state.compute_pipeline; + struct anv_pipeline *pipeline = cmd_buffer->state.compute.base.pipeline; const struct brw_cs_prog_data *cs_prog_data = get_cs_prog_data(pipeline); const struct brw_stage_prog_data *prog_data = &cs_prog_data->base; @@ -688,14 +785,11 @@ anv_cmd_buffer_cs_push_constants(struct anv_cmd_buffer *cmd_buffer) uint32_t *u32_map = state.map; if (cs_prog_data->push.cross_thread.size > 0) { - assert(cs_prog_data->thread_local_id_index < 0 || - cs_prog_data->thread_local_id_index >= - cs_prog_data->push.cross_thread.dwords); for (unsigned i = 0; i < cs_prog_data->push.cross_thread.dwords; i++) { - uint32_t offset = (uintptr_t)prog_data->param[i]; - u32_map[i] = *(uint32_t *)((uint8_t *)data + offset); + assert(prog_data->param[i] != BRW_PARAM_BUILTIN_SUBGROUP_ID); + u32_map[i] = anv_push_constant_value(data, prog_data->param[i]); } } @@ -706,11 +800,11 @@ anv_cmd_buffer_cs_push_constants(struct anv_cmd_buffer *cmd_buffer) cs_prog_data->push.cross_thread.regs); unsigned src = cs_prog_data->push.cross_thread.dwords; for ( ; src < prog_data->nr_params; src++, dst++) { - if (src != cs_prog_data->thread_local_id_index) { - uint32_t offset = (uintptr_t)prog_data->param[src]; - u32_map[dst] = *(uint32_t *)((uint8_t *)data + offset); + if (prog_data->param[src] == BRW_PARAM_BUILTIN_SUBGROUP_ID) { + u32_map[dst] = t; } else { - u32_map[dst] = t * cs_prog_data->simd_size; + u32_map[dst] = + anv_push_constant_value(data, prog_data->param[src]); } } } @@ -805,10 +899,10 @@ VkResult anv_ResetCommandPool( return VK_SUCCESS; } -void anv_TrimCommandPoolKHR( +void anv_TrimCommandPool( VkDevice device, VkCommandPool commandPool, - VkCommandPoolTrimFlagsKHR flags) + VkCommandPoolTrimFlags flags) { /* Nothing for us to do here. Our pools stay pretty tidy. */ } @@ -822,11 +916,11 @@ anv_cmd_buffer_get_depth_stencil_view(const struct anv_cmd_buffer *cmd_buffer) const struct anv_subpass *subpass = cmd_buffer->state.subpass; const struct anv_framebuffer *fb = cmd_buffer->state.framebuffer; - if (subpass->depth_stencil_attachment.attachment == VK_ATTACHMENT_UNUSED) + if (subpass->depth_stencil_attachment == NULL) return NULL; const struct anv_image_view *iview = - fb->attachments[subpass->depth_stencil_attachment.attachment]; + fb->attachments[subpass->depth_stencil_attachment->attachment]; assert(iview->aspect_mask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)); @@ -834,6 +928,35 @@ anv_cmd_buffer_get_depth_stencil_view(const struct anv_cmd_buffer *cmd_buffer) return iview; } +static struct anv_push_descriptor_set * +anv_cmd_buffer_get_push_descriptor_set(struct anv_cmd_buffer *cmd_buffer, + VkPipelineBindPoint bind_point, + uint32_t set) +{ + struct anv_cmd_pipeline_state *pipe_state; + if (bind_point == VK_PIPELINE_BIND_POINT_COMPUTE) { + pipe_state = &cmd_buffer->state.compute.base; + } else { + assert(bind_point == VK_PIPELINE_BIND_POINT_GRAPHICS); + pipe_state = &cmd_buffer->state.gfx.base; + } + + struct anv_push_descriptor_set **push_set = + &pipe_state->push_descriptors[set]; + + if (*push_set == NULL) { + *push_set = vk_alloc(&cmd_buffer->pool->alloc, + sizeof(struct anv_push_descriptor_set), 8, + VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (*push_set == NULL) { + anv_batch_set_error(&cmd_buffer->batch, VK_ERROR_OUT_OF_HOST_MEMORY); + return NULL; + } + } + + return *push_set; +} + void anv_CmdPushDescriptorSetKHR( VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, @@ -845,18 +968,22 @@ void anv_CmdPushDescriptorSetKHR( ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); ANV_FROM_HANDLE(anv_pipeline_layout, layout, _layout); - assert(pipelineBindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS || - pipelineBindPoint == VK_PIPELINE_BIND_POINT_COMPUTE); assert(_set < MAX_SETS); - const struct anv_descriptor_set_layout *set_layout = - layout->set[_set].layout; - struct anv_descriptor_set *set = &cmd_buffer->state.push_descriptor.set; + struct anv_descriptor_set_layout *set_layout = layout->set[_set].layout; + + struct anv_push_descriptor_set *push_set = + anv_cmd_buffer_get_push_descriptor_set(cmd_buffer, + pipelineBindPoint, _set); + if (!push_set) + return; + + struct anv_descriptor_set *set = &push_set->set; set->layout = set_layout; set->size = anv_descriptor_set_layout_size(set_layout); set->buffer_count = set_layout->buffer_count; - set->buffer_views = cmd_buffer->state.push_descriptor.buffer_views; + set->buffer_views = push_set->buffer_views; /* Go through the user supplied descriptors. */ for (uint32_t i = 0; i < descriptorWriteCount; i++) { @@ -917,13 +1044,13 @@ void anv_CmdPushDescriptorSetKHR( } } - cmd_buffer->state.descriptors[_set] = set; - cmd_buffer->state.descriptors_dirty |= set_layout->shader_stages; + anv_cmd_buffer_bind_descriptor_set(cmd_buffer, pipelineBindPoint, + layout, _set, set, NULL, NULL); } void anv_CmdPushDescriptorSetWithTemplateKHR( VkCommandBuffer commandBuffer, - VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate, + VkDescriptorUpdateTemplate descriptorUpdateTemplate, VkPipelineLayout _layout, uint32_t _set, const void* pData) @@ -935,14 +1062,20 @@ void anv_CmdPushDescriptorSetWithTemplateKHR( assert(_set < MAX_PUSH_DESCRIPTORS); - const struct anv_descriptor_set_layout *set_layout = - layout->set[_set].layout; - struct anv_descriptor_set *set = &cmd_buffer->state.push_descriptor.set; + struct anv_descriptor_set_layout *set_layout = layout->set[_set].layout; + + struct anv_push_descriptor_set *push_set = + anv_cmd_buffer_get_push_descriptor_set(cmd_buffer, + template->bind_point, _set); + if (!push_set) + return; + + struct anv_descriptor_set *set = &push_set->set; set->layout = set_layout; set->size = anv_descriptor_set_layout_size(set_layout); set->buffer_count = set_layout->buffer_count; - set->buffer_views = cmd_buffer->state.push_descriptor.buffer_views; + set->buffer_views = push_set->buffer_views; anv_descriptor_set_write_template(set, cmd_buffer->device, @@ -950,6 +1083,13 @@ void anv_CmdPushDescriptorSetWithTemplateKHR( template, pData); - cmd_buffer->state.descriptors[_set] = set; - cmd_buffer->state.descriptors_dirty |= set_layout->shader_stages; + anv_cmd_buffer_bind_descriptor_set(cmd_buffer, template->bind_point, + layout, _set, set, NULL, NULL); +} + +void anv_CmdSetDeviceMask( + VkCommandBuffer commandBuffer, + uint32_t deviceMask) +{ + /* No-op */ }