state->pipeline = NULL;
state->restart_index = UINT32_MAX;
state->dynamic = default_dynamic_state;
+ state->need_query_wa = true;
state->gen7.index_buffer = NULL;
}
cmd_buffer->usage_flags = pBeginInfo->flags;
- if (cmd_buffer->level == VK_COMMAND_BUFFER_LEVEL_SECONDARY) {
+ assert(cmd_buffer->level == VK_COMMAND_BUFFER_LEVEL_SECONDARY ||
+ !(cmd_buffer->usage_flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT));
+
+ if (cmd_buffer->usage_flags &
+ VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT) {
cmd_buffer->state.framebuffer =
anv_framebuffer_from_handle(pBeginInfo->framebuffer);
cmd_buffer->state.pass =
void anv_CmdSetViewport(
VkCommandBuffer commandBuffer,
+ uint32_t firstViewport,
uint32_t viewportCount,
const VkViewport* pViewports)
{
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
cmd_buffer->state.dynamic.viewport.count = viewportCount;
- memcpy(cmd_buffer->state.dynamic.viewport.viewports,
+ memcpy(cmd_buffer->state.dynamic.viewport.viewports + firstViewport,
pViewports, viewportCount * sizeof(*pViewports));
cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_VIEWPORT;
void anv_CmdSetScissor(
VkCommandBuffer commandBuffer,
+ uint32_t firstScissor,
uint32_t scissorCount,
const VkRect2D* pScissors)
{
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
cmd_buffer->state.dynamic.scissor.count = scissorCount;
- memcpy(cmd_buffer->state.dynamic.scissor.scissors,
+ memcpy(cmd_buffer->state.dynamic.scissor.scissors + firstScissor,
pScissors, scissorCount * sizeof(*pScissors));
cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_SCISSOR;
unsigned array_size = set_layout->binding[b].array_size;
for (unsigned j = 0; j < array_size; j++) {
+ uint32_t range = 0;
+ if (desc->buffer_view)
+ range = desc->buffer_view->range;
push->dynamic[d].offset = *(offsets++);
- push->dynamic[d].range = (desc++)->range;
+ push->dynamic[d].range = range;
+ desc++;
d++;
}
}
void anv_CmdBindVertexBuffers(
VkCommandBuffer commandBuffer,
- uint32_t startBinding,
+ uint32_t firstBinding,
uint32_t bindingCount,
const VkBuffer* pBuffers,
const VkDeviceSize* pOffsets)
/* We have to defer setting up vertex buffer since we need the buffer
* stride from the pipeline. */
- assert(startBinding + bindingCount < MAX_VBS);
+ assert(firstBinding + bindingCount < MAX_VBS);
for (uint32_t i = 0; i < bindingCount; i++) {
- vb[startBinding + i].buffer = anv_buffer_from_handle(pBuffers[i]);
- vb[startBinding + i].offset = pOffsets[i];
- cmd_buffer->state.vb_dirty |= 1 << (startBinding + 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);
}
}
state.offset + dword * 4, bo, offset);
}
-static void
-fill_descriptor_buffer_surface_state(struct anv_device *device, void *state,
- gl_shader_stage stage,
- VkDescriptorType type,
- uint32_t offset, uint32_t range)
+const struct anv_format *
+anv_format_for_descriptor_type(VkDescriptorType type)
{
- VkFormat format;
- uint32_t stride;
-
switch (type) {
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
- if (device->instance->physicalDevice.compiler->scalar_stage[stage]) {
- stride = 4;
- } else {
- stride = 16;
- }
- format = VK_FORMAT_R32G32B32A32_SFLOAT;
- break;
+ return anv_format_for_vk_format(VK_FORMAT_R32G32B32A32_SFLOAT);
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
- stride = 1;
- format = VK_FORMAT_UNDEFINED;
- break;
+ return anv_format_for_vk_format(VK_FORMAT_UNDEFINED);
default:
unreachable("Invalid descriptor type");
}
-
- anv_fill_buffer_surface_state(device, state,
- anv_format_for_vk_format(format),
- offset, range, stride);
}
VkResult
struct anv_pipeline_layout *layout;
uint32_t color_count, bias, state_offset;
- if (stage == MESA_SHADER_COMPUTE)
- layout = cmd_buffer->state.compute_pipeline->layout;
- else
+ switch (stage) {
+ case MESA_SHADER_FRAGMENT:
layout = cmd_buffer->state.pipeline->layout;
-
- if (stage == MESA_SHADER_FRAGMENT) {
bias = MAX_RTS;
color_count = subpass->color_count;
- } else {
+ break;
+ case MESA_SHADER_COMPUTE:
+ layout = cmd_buffer->state.compute_pipeline->layout;
+ bias = 1;
+ color_count = 0;
+ break;
+ default:
+ layout = cmd_buffer->state.pipeline->layout;
bias = 0;
color_count = 0;
+ break;
}
/* This is a little awkward: layout can be NULL but we still have to
* targets. */
uint32_t surface_count = layout ? layout->stage[stage].surface_count : 0;
- if (color_count + surface_count == 0)
+ if (color_count + surface_count == 0) {
+ *bt_state = (struct anv_state) { 0, };
return VK_SUCCESS;
+ }
*bt_state = anv_cmd_buffer_alloc_binding_table(cmd_buffer,
bias + surface_count,
const struct anv_image_view *iview =
fb->attachments[subpass->color_attachments[a]];
+ assert(iview->color_rt_surface_state.alloc_size);
bt_map[a] = iview->color_rt_surface_state.offset + state_offset;
add_surface_state_reloc(cmd_buffer, iview->color_rt_surface_state,
iview->bo, iview->offset);
}
+ if (stage == MESA_SHADER_COMPUTE &&
+ cmd_buffer->state.compute_pipeline->cs_prog_data.uses_num_work_groups) {
+ struct anv_bo *bo = cmd_buffer->state.num_workgroups_bo;
+ uint32_t bo_offset = cmd_buffer->state.num_workgroups_offset;
+
+ struct anv_state surface_state;
+ surface_state =
+ anv_cmd_buffer_alloc_surface_state(cmd_buffer);
+
+ const struct anv_format *format =
+ anv_format_for_descriptor_type(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
+ anv_fill_buffer_surface_state(cmd_buffer->device, surface_state.map,
+ format->surface_format, bo_offset, 12, 1);
+
+ if (!cmd_buffer->device->info.has_llc)
+ anv_state_clflush(surface_state);
+
+ bt_map[0] = surface_state.offset + state_offset;
+ add_surface_state_reloc(cmd_buffer, surface_state, bo, bo_offset);
+ }
+
if (layout == NULL)
- return VK_SUCCESS;
+ goto out;
+ if (layout->stage[stage].image_count > 0) {
+ VkResult result =
+ anv_cmd_buffer_ensure_push_constant_field(cmd_buffer, stage, images);
+ if (result != VK_SUCCESS)
+ return result;
+
+ cmd_buffer->state.push_constants_dirty |= 1 << stage;
+ }
+
+ uint32_t image = 0;
for (uint32_t s = 0; s < layout->stage[stage].surface_count; s++) {
struct anv_pipeline_binding *binding =
&layout->stage[stage].surface_to_descriptor[s];
/* Nothing for us to do here */
continue;
- case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
- case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
- case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
- case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: {
- bo = desc->buffer->bo;
- bo_offset = desc->buffer->offset + desc->offset;
-
- surface_state =
- anv_cmd_buffer_alloc_surface_state(cmd_buffer);
-
- fill_descriptor_buffer_surface_state(cmd_buffer->device,
- surface_state.map,
- stage, desc->type,
- bo_offset, desc->range);
- break;
- }
-
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
surface_state = desc->image_view->nonrt_surface_state;
+ assert(surface_state.alloc_size);
+ bo = desc->image_view->bo;
+ bo_offset = desc->image_view->offset;
+ break;
+
+ case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: {
+ surface_state = desc->image_view->storage_surface_state;
+ assert(surface_state.alloc_size);
bo = desc->image_view->bo;
bo_offset = desc->image_view->offset;
+
+ struct brw_image_param *image_param =
+ &cmd_buffer->state.push_constants[stage]->images[image++];
+
+ anv_image_view_fill_image_param(cmd_buffer->device, desc->image_view,
+ image_param);
+ image_param->surface_idx = bias + s;
break;
+ }
- case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
+ case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
+ case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
+ case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
+ case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
+ surface_state = desc->buffer_view->surface_state;
+ assert(surface_state.alloc_size);
+ bo = desc->buffer_view->bo;
+ bo_offset = desc->buffer_view->offset;
+ break;
+
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
- assert(!"Unsupported descriptor type");
+ surface_state = desc->buffer_view->storage_surface_state;
+ assert(surface_state.alloc_size);
+ bo = desc->buffer_view->bo;
+ bo_offset = desc->buffer_view->offset;
+
+ struct brw_image_param *image_param =
+ &cmd_buffer->state.push_constants[stage]->images[image++];
+
+ anv_buffer_view_fill_image_param(cmd_buffer->device, desc->buffer_view,
+ image_param);
+ image_param->surface_idx = bias + s;
break;
default:
bt_map[bias + s] = surface_state.offset + state_offset;
add_surface_state_reloc(cmd_buffer, surface_state, bo, bo_offset);
}
+ assert(image == layout->stage[stage].image_count);
+
+ out:
+ if (!cmd_buffer->device->info.has_llc)
+ anv_state_clflush(*bt_state);
return VK_SUCCESS;
}
layout = cmd_buffer->state.pipeline->layout;
sampler_count = layout ? layout->stage[stage].sampler_count : 0;
- if (sampler_count == 0)
+ if (sampler_count == 0) {
+ *state = (struct anv_state) { 0, };
return VK_SUCCESS;
+ }
uint32_t size = sampler_count * 16;
*state = anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, size, 32);
sampler->state, sizeof(sampler->state));
}
+ if (!cmd_buffer->device->info.has_llc)
+ anv_state_clflush(*state);
+
return VK_SUCCESS;
}
struct anv_state
anv_cmd_buffer_emit_dynamic(struct anv_cmd_buffer *cmd_buffer,
- uint32_t *a, uint32_t dwords, uint32_t alignment)
+ const void *data, uint32_t size, uint32_t alignment)
{
struct anv_state state;
- state = anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
- dwords * 4, alignment);
- memcpy(state.map, a, dwords * 4);
+ state = anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, size, alignment);
+ memcpy(state.map, data, size);
- VG(VALGRIND_CHECK_MEM_IS_DEFINED(state.map, dwords * 4));
+ if (!cmd_buffer->device->info.has_llc)
+ anv_state_clflush(state);
+
+ VG(VALGRIND_CHECK_MEM_IS_DEFINED(state.map, size));
return state;
}
for (uint32_t i = 0; i < dwords; i++)
p[i] = a[i] | b[i];
+ if (!cmd_buffer->device->info.has_llc)
+ anv_state_clflush(state);
+
VG(VALGRIND_CHECK_MEM_IS_DEFINED(p, dwords * 4));
return state;
}
}
-void anv_CmdSetEvent(
- VkCommandBuffer commandBuffer,
- VkEvent event,
- VkPipelineStageFlags stageMask)
-{
- stub();
-}
-
-void anv_CmdResetEvent(
- VkCommandBuffer commandBuffer,
- VkEvent event,
- VkPipelineStageFlags stageMask)
-{
- stub();
-}
-
-void anv_CmdWaitEvents(
- VkCommandBuffer commandBuffer,
- uint32_t eventCount,
- const VkEvent* pEvents,
- VkPipelineStageFlags srcStageMask,
- VkPipelineStageFlags destStageMask,
- uint32_t memBarrierCount,
- const void* const* ppMemBarriers)
-{
- stub();
-}
-
struct anv_state
anv_cmd_buffer_push_constants(struct anv_cmd_buffer *cmd_buffer,
gl_shader_stage stage)
u32_map[i] = *(uint32_t *)((uint8_t *)data + offset);
}
+ if (!cmd_buffer->device->info.has_llc)
+ anv_state_clflush(state);
+
+ return state;
+}
+
+struct anv_state
+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;
+ const struct brw_cs_prog_data *cs_prog_data = &pipeline->cs_prog_data;
+ const struct brw_stage_prog_data *prog_data = &cs_prog_data->base;
+
+ const unsigned local_id_dwords = cs_prog_data->local_invocation_id_regs * 8;
+ const unsigned push_constant_data_size =
+ (local_id_dwords + prog_data->nr_params) * 4;
+ const unsigned reg_aligned_constant_size = ALIGN(push_constant_data_size, 32);
+ const unsigned param_aligned_count =
+ reg_aligned_constant_size / sizeof(uint32_t);
+
+ /* If we don't actually have any push constants, bail. */
+ if (reg_aligned_constant_size == 0)
+ return (struct anv_state) { .offset = 0 };
+
+ const unsigned threads = pipeline->cs_thread_width_max;
+ const unsigned total_push_constants_size =
+ reg_aligned_constant_size * threads;
+ const unsigned push_constant_alignment =
+ cmd_buffer->device->info.gen < 8 ? 32 : 64;
+ const unsigned aligned_total_push_constants_size =
+ ALIGN(total_push_constants_size, push_constant_alignment);
+ struct anv_state state =
+ anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
+ aligned_total_push_constants_size,
+ push_constant_alignment);
+
+ /* Walk through the param array and fill the buffer with data */
+ uint32_t *u32_map = state.map;
+
+ brw_cs_fill_local_id_payload(cs_prog_data, u32_map, threads,
+ reg_aligned_constant_size);
+
+ /* Setup uniform data for the first thread */
+ for (unsigned i = 0; i < prog_data->nr_params; i++) {
+ uint32_t offset = (uintptr_t)prog_data->param[i];
+ u32_map[local_id_dwords + i] = *(uint32_t *)((uint8_t *)data + offset);
+ }
+
+ /* Copy uniform data from the first thread to every other thread */
+ const size_t uniform_data_size = prog_data->nr_params * sizeof(uint32_t);
+ for (unsigned t = 1; t < threads; t++) {
+ memcpy(&u32_map[t * param_aligned_count + local_id_dwords],
+ &u32_map[local_id_dwords],
+ uniform_data_size);
+ }
+
+ if (!cmd_buffer->device->info.has_llc)
+ anv_state_clflush(state);
+
return state;
}
const struct anv_image_view *iview =
fb->attachments[subpass->depth_stencil_attachment];
- assert(anv_format_is_depth_or_stencil(iview->format));
+ assert(iview->aspect_mask & (VK_IMAGE_ASPECT_DEPTH_BIT |
+ VK_IMAGE_ASPECT_STENCIL_BIT));
return iview;
}