.depth_bias = {
.bias = 0.0f,
.clamp = 0.0f,
- .slope_scaled = 0.0f,
+ .slope = 0.0f,
},
.blend_constants = { 0.0f, 0.0f, 0.0f, 0.0f },
.depth_bounds = {
static void
anv_cmd_state_init(struct anv_cmd_state *state)
{
- memset(&state->state_vf, 0, sizeof(state->state_vf));
memset(&state->descriptors, 0, sizeof(state->descriptors));
memset(&state->push_constants, 0, sizeof(state->push_constants));
state->descriptors_dirty = 0;
state->push_constants_dirty = 0;
state->pipeline = NULL;
+ state->restart_index = UINT32_MAX;
state->dynamic = default_dynamic_state;
state->gen7.index_buffer = NULL;
static VkResult
anv_cmd_buffer_ensure_push_constants_size(struct anv_cmd_buffer *cmd_buffer,
- VkShaderStage stage, uint32_t size)
+ gl_shader_stage stage, uint32_t size)
{
struct anv_push_constants **ptr = &cmd_buffer->state.push_constants[stage];
if (*ptr == NULL) {
- *ptr = anv_device_alloc(cmd_buffer->device, size, 8,
- VK_SYSTEM_ALLOC_TYPE_INTERNAL);
+ *ptr = anv_alloc(&cmd_buffer->pool->alloc, size, 8,
+ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (*ptr == NULL)
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
- (*ptr)->size = size;
} else if ((*ptr)->size < size) {
- void *new_data = anv_device_alloc(cmd_buffer->device, size, 8,
- VK_SYSTEM_ALLOC_TYPE_INTERNAL);
- if (new_data == NULL)
+ *ptr = anv_realloc(&cmd_buffer->pool->alloc, *ptr, size, 8,
+ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+ if (*ptr == NULL)
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
-
- memcpy(new_data, *ptr, (*ptr)->size);
- anv_device_free(cmd_buffer->device, *ptr);
-
- *ptr = new_data;
- (*ptr)->size = size;
}
+ (*ptr)->size = size;
return VK_SUCCESS;
}
(offsetof(struct anv_push_constants, field) + \
sizeof(cmd_buffer->state.push_constants[0]->field)))
-VkResult anv_CreateCommandBuffer(
- VkDevice _device,
- const VkCmdBufferCreateInfo* pCreateInfo,
- VkCmdBuffer* pCmdBuffer)
+static VkResult anv_create_cmd_buffer(
+ struct anv_device * device,
+ struct anv_cmd_pool * pool,
+ VkCommandBufferLevel level,
+ VkCommandBuffer* pCommandBuffer)
{
- ANV_FROM_HANDLE(anv_device, device, _device);
- ANV_FROM_HANDLE(anv_cmd_pool, pool, pCreateInfo->cmdPool);
struct anv_cmd_buffer *cmd_buffer;
VkResult result;
- cmd_buffer = anv_device_alloc(device, sizeof(*cmd_buffer), 8,
- VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+ cmd_buffer = anv_alloc(&pool->alloc, sizeof(*cmd_buffer), 8,
+ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (cmd_buffer == NULL)
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
cmd_buffer->_loader_data.loaderMagic = ICD_LOADER_MAGIC;
cmd_buffer->device = device;
+ cmd_buffer->pool = pool;
result = anv_cmd_buffer_init_batch_bo_chain(cmd_buffer);
if (result != VK_SUCCESS)
anv_state_stream_init(&cmd_buffer->dynamic_state_stream,
&device->dynamic_state_block_pool);
- cmd_buffer->level = pCreateInfo->level;
- cmd_buffer->opt_flags = 0;
+ cmd_buffer->level = level;
+ cmd_buffer->usage_flags = 0;
anv_cmd_state_init(&cmd_buffer->state);
list_inithead(&cmd_buffer->pool_link);
}
- *pCmdBuffer = anv_cmd_buffer_to_handle(cmd_buffer);
+ *pCommandBuffer = anv_cmd_buffer_to_handle(cmd_buffer);
return VK_SUCCESS;
- fail: anv_device_free(device, cmd_buffer);
+ fail:
+ anv_free(&cmd_buffer->pool->alloc, cmd_buffer);
return result;
}
-void anv_DestroyCommandBuffer(
+VkResult anv_AllocateCommandBuffers(
VkDevice _device,
- VkCmdBuffer _cmd_buffer)
+ const VkCommandBufferAllocateInfo* pAllocateInfo,
+ VkCommandBuffer* pCommandBuffers)
{
ANV_FROM_HANDLE(anv_device, device, _device);
- ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, _cmd_buffer);
+ ANV_FROM_HANDLE(anv_cmd_pool, pool, pAllocateInfo->commandPool);
+
+ VkResult result = VK_SUCCESS;
+ uint32_t i;
+
+ for (i = 0; i < pAllocateInfo->bufferCount; i++) {
+ result = anv_create_cmd_buffer(device, pool, pAllocateInfo->level,
+ &pCommandBuffers[i]);
+ if (result != VK_SUCCESS)
+ break;
+ }
+ if (result != VK_SUCCESS)
+ anv_FreeCommandBuffers(_device, pAllocateInfo->commandPool,
+ i, pCommandBuffers);
+
+ return result;
+}
+
+static void
+anv_cmd_buffer_destroy(struct anv_cmd_buffer *cmd_buffer)
+{
list_del(&cmd_buffer->pool_link);
anv_cmd_buffer_fini_batch_bo_chain(cmd_buffer);
anv_state_stream_finish(&cmd_buffer->surface_state_stream);
anv_state_stream_finish(&cmd_buffer->dynamic_state_stream);
- anv_device_free(device, cmd_buffer);
+
+ anv_free(&cmd_buffer->pool->alloc, cmd_buffer);
+}
+
+void anv_FreeCommandBuffers(
+ VkDevice device,
+ VkCommandPool commandPool,
+ uint32_t commandBufferCount,
+ const VkCommandBuffer* pCommandBuffers)
+{
+ for (uint32_t i = 0; i < commandBufferCount; i++) {
+ ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, pCommandBuffers[i]);
+
+ anv_cmd_buffer_destroy(cmd_buffer);
+ }
}
VkResult anv_ResetCommandBuffer(
- VkCmdBuffer cmdBuffer,
- VkCmdBufferResetFlags flags)
+ VkCommandBuffer commandBuffer,
+ VkCommandBufferResetFlags flags)
{
- ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+ ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
anv_cmd_buffer_reset_batch_bo_chain(cmd_buffer);
{
switch (cmd_buffer->device->info.gen) {
case 7:
- return gen7_cmd_buffer_emit_state_base_address(cmd_buffer);
+ if (cmd_buffer->device->info.is_haswell)
+ return gen7_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);
default:
unreachable("unsupported gen\n");
}
}
VkResult anv_BeginCommandBuffer(
- VkCmdBuffer cmdBuffer,
- const VkCmdBufferBeginInfo* pBeginInfo)
+ VkCommandBuffer commandBuffer,
+ const VkCommandBufferBeginInfo* pBeginInfo)
{
- ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+ ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
anv_cmd_buffer_reset_batch_bo_chain(cmd_buffer);
- cmd_buffer->opt_flags = pBeginInfo->flags;
+ cmd_buffer->usage_flags = pBeginInfo->flags;
- if (cmd_buffer->level == VK_CMD_BUFFER_LEVEL_SECONDARY) {
+ if (cmd_buffer->level == VK_COMMAND_BUFFER_LEVEL_SECONDARY) {
cmd_buffer->state.framebuffer =
anv_framebuffer_from_handle(pBeginInfo->framebuffer);
cmd_buffer->state.pass =
}
VkResult anv_EndCommandBuffer(
- VkCmdBuffer cmdBuffer)
+ VkCommandBuffer commandBuffer)
{
- ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+ ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
struct anv_device *device = cmd_buffer->device;
anv_cmd_buffer_end_batch_buffer(cmd_buffer);
- if (cmd_buffer->level == VK_CMD_BUFFER_LEVEL_PRIMARY) {
+ if (cmd_buffer->level == VK_COMMAND_BUFFER_LEVEL_PRIMARY) {
/* The algorithm used to compute the validate list is not threadsafe as
* it uses the bo->index field. We have to lock the device around it.
* Fortunately, the chances for contention here are probably very low.
}
void anv_CmdBindPipeline(
- VkCmdBuffer cmdBuffer,
+ VkCommandBuffer commandBuffer,
VkPipelineBindPoint pipelineBindPoint,
VkPipeline _pipeline)
{
- ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+ ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
ANV_FROM_HANDLE(anv_pipeline, pipeline, _pipeline);
switch (pipelineBindPoint) {
}
void anv_CmdSetViewport(
- VkCmdBuffer cmdBuffer,
+ VkCommandBuffer commandBuffer,
uint32_t viewportCount,
const VkViewport* pViewports)
{
- ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+ ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
cmd_buffer->state.dynamic.viewport.count = viewportCount;
memcpy(cmd_buffer->state.dynamic.viewport.viewports,
}
void anv_CmdSetScissor(
- VkCmdBuffer cmdBuffer,
+ VkCommandBuffer commandBuffer,
uint32_t scissorCount,
const VkRect2D* pScissors)
{
- ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+ ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
cmd_buffer->state.dynamic.scissor.count = scissorCount;
memcpy(cmd_buffer->state.dynamic.scissor.scissors,
}
void anv_CmdSetLineWidth(
- VkCmdBuffer cmdBuffer,
+ VkCommandBuffer commandBuffer,
float lineWidth)
{
- ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+ 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;
}
void anv_CmdSetDepthBias(
- VkCmdBuffer cmdBuffer,
- float depthBias,
+ VkCommandBuffer commandBuffer,
+ float depthBiasConstantFactor,
float depthBiasClamp,
- float slopeScaledDepthBias)
+ float depthBiasSlopeFactor)
{
- ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+ ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
- cmd_buffer->state.dynamic.depth_bias.bias = depthBias;
+ cmd_buffer->state.dynamic.depth_bias.bias = depthBiasConstantFactor;
cmd_buffer->state.dynamic.depth_bias.clamp = depthBiasClamp;
- cmd_buffer->state.dynamic.depth_bias.slope_scaled = slopeScaledDepthBias;
+ cmd_buffer->state.dynamic.depth_bias.slope = depthBiasSlopeFactor;
cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS;
}
void anv_CmdSetBlendConstants(
- VkCmdBuffer cmdBuffer,
- const float blendConst[4])
+ VkCommandBuffer commandBuffer,
+ const float blendConstants[4])
{
- ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+ ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
memcpy(cmd_buffer->state.dynamic.blend_constants,
- blendConst, sizeof(float) * 4);
+ blendConstants, sizeof(float) * 4);
cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS;
}
void anv_CmdSetDepthBounds(
- VkCmdBuffer cmdBuffer,
+ VkCommandBuffer commandBuffer,
float minDepthBounds,
float maxDepthBounds)
{
- ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+ 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;
}
void anv_CmdSetStencilCompareMask(
- VkCmdBuffer cmdBuffer,
+ VkCommandBuffer commandBuffer,
VkStencilFaceFlags faceMask,
- uint32_t stencilCompareMask)
+ uint32_t compareMask)
{
- ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+ ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
- cmd_buffer->state.dynamic.stencil_compare_mask.front = stencilCompareMask;
+ cmd_buffer->state.dynamic.stencil_compare_mask.front = compareMask;
if (faceMask & VK_STENCIL_FACE_BACK_BIT)
- cmd_buffer->state.dynamic.stencil_compare_mask.back = stencilCompareMask;
+ cmd_buffer->state.dynamic.stencil_compare_mask.back = compareMask;
cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK;
}
void anv_CmdSetStencilWriteMask(
- VkCmdBuffer cmdBuffer,
+ VkCommandBuffer commandBuffer,
VkStencilFaceFlags faceMask,
- uint32_t stencilWriteMask)
+ uint32_t writeMask)
{
- ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+ ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
- cmd_buffer->state.dynamic.stencil_write_mask.front = stencilWriteMask;
+ cmd_buffer->state.dynamic.stencil_write_mask.front = writeMask;
if (faceMask & VK_STENCIL_FACE_BACK_BIT)
- cmd_buffer->state.dynamic.stencil_write_mask.back = stencilWriteMask;
+ cmd_buffer->state.dynamic.stencil_write_mask.back = writeMask;
cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK;
}
void anv_CmdSetStencilReference(
- VkCmdBuffer cmdBuffer,
+ VkCommandBuffer commandBuffer,
VkStencilFaceFlags faceMask,
- uint32_t stencilReference)
+ uint32_t reference)
{
- ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+ ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
- cmd_buffer->state.dynamic.stencil_reference.front = stencilReference;
+ cmd_buffer->state.dynamic.stencil_reference.front = reference;
if (faceMask & VK_STENCIL_FACE_BACK_BIT)
- cmd_buffer->state.dynamic.stencil_reference.back = stencilReference;
+ cmd_buffer->state.dynamic.stencil_reference.back = reference;
cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE;
}
void anv_CmdBindDescriptorSets(
- VkCmdBuffer cmdBuffer,
+ VkCommandBuffer commandBuffer,
VkPipelineBindPoint pipelineBindPoint,
VkPipelineLayout _layout,
uint32_t firstSet,
- uint32_t setCount,
+ uint32_t descriptorSetCount,
const VkDescriptorSet* pDescriptorSets,
uint32_t dynamicOffsetCount,
const uint32_t* pDynamicOffsets)
{
- ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+ 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 + setCount < MAX_SETS);
+ assert(firstSet + descriptorSetCount < MAX_SETS);
uint32_t dynamic_slot = 0;
- for (uint32_t i = 0; i < setCount; i++) {
+ for (uint32_t i = 0; i < descriptorSetCount; i++) {
ANV_FROM_HANDLE(anv_descriptor_set, set, pDescriptorSets[i]);
set_layout = layout->set[firstSet + i].layout;
}
if (set_layout->dynamic_offset_count > 0) {
- VkShaderStage s;
- for_each_bit(s, set_layout->shader_stages) {
+ anv_foreach_stage(s, set_layout->shader_stages) {
anv_cmd_buffer_ensure_push_constant_field(cmd_buffer, s, dynamic);
struct anv_push_constants *push =
}
void anv_CmdBindVertexBuffers(
- VkCmdBuffer cmdBuffer,
+ VkCommandBuffer commandBuffer,
uint32_t startBinding,
uint32_t bindingCount,
const VkBuffer* pBuffers,
const VkDeviceSize* pOffsets)
{
- ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+ ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
struct anv_vertex_binding *vb = cmd_buffer->state.vertex_bindings;
/* We have to defer setting up vertex buffer since we need the buffer
const uint32_t dword = cmd_buffer->device->info.gen < 8 ? 1 : 8;
- anv_reloc_list_add(&cmd_buffer->surface_relocs, cmd_buffer->device,
+ anv_reloc_list_add(&cmd_buffer->surface_relocs, &cmd_buffer->pool->alloc,
state.offset + dword * 4, bo, offset);
}
static void
fill_descriptor_buffer_surface_state(struct anv_device *device, void *state,
- VkShaderStage stage, VkDescriptorType type,
+ gl_shader_stage stage,
+ VkDescriptorType type,
uint32_t offset, uint32_t range)
{
VkFormat format;
- uint32_t stride;
-
switch (type) {
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
- if (anv_is_scalar_shader_stage(device->instance->physicalDevice.compiler,
- stage)) {
- stride = 4;
- } else {
- stride = 16;
- }
format = VK_FORMAT_R32G32B32A32_SFLOAT;
break;
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
- stride = 1;
format = VK_FORMAT_UNDEFINED;
break;
anv_fill_buffer_surface_state(device, state,
anv_format_for_vk_format(format),
- offset, range, stride);
+ offset, range, 1);
}
VkResult
anv_cmd_buffer_emit_binding_table(struct anv_cmd_buffer *cmd_buffer,
- VkShaderStage stage, struct anv_state *bt_state)
+ gl_shader_stage stage,
+ struct anv_state *bt_state)
{
struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
struct anv_subpass *subpass = cmd_buffer->state.subpass;
struct anv_pipeline_layout *layout;
uint32_t color_count, bias, state_offset;
- if (stage == VK_SHADER_STAGE_COMPUTE)
+ if (stage == MESA_SHADER_COMPUTE)
layout = cmd_buffer->state.compute_pipeline->layout;
else
layout = cmd_buffer->state.pipeline->layout;
- if (stage == VK_SHADER_STAGE_FRAGMENT) {
+ if (stage == MESA_SHADER_FRAGMENT) {
bias = MAX_RTS;
color_count = subpass->color_count;
} else {
}
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];
surface_state.map,
stage, desc->type,
bo_offset, desc->range);
+
+ if (!cmd_buffer->device->info.has_llc)
+ anv_state_clflush(surface_state);
+
break;
}
bo_offset = desc->image_view->offset;
break;
- case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
+ case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: {
+ surface_state = desc->image_view->storage_surface_state;
+ 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_UNIFORM_TEXEL_BUFFER:
+ surface_state = desc->buffer_view->surface_state;
+ bo = desc->buffer_view->bo;
+ bo_offset = desc->buffer_view->offset;
+ break;
+
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
assert(!"Unsupported descriptor type");
break;
+
+ default:
+ assert(!"Invalid descriptor type");
+ continue;
}
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;
}
VkResult
anv_cmd_buffer_emit_samplers(struct anv_cmd_buffer *cmd_buffer,
- VkShaderStage stage, struct anv_state *state)
+ gl_shader_stage stage, struct anv_state *state)
{
struct anv_pipeline_layout *layout;
uint32_t sampler_count;
- if (stage == VK_SHADER_STAGE_COMPUTE)
+ if (stage == MESA_SHADER_COMPUTE)
layout = cmd_buffer->state.compute_pipeline->layout;
else
layout = cmd_buffer->state.pipeline->layout;
sampler->state, sizeof(sampler->state));
}
- return VK_SUCCESS;
-}
-
-static VkResult
-flush_descriptor_set(struct anv_cmd_buffer *cmd_buffer, VkShaderStage stage)
-{
- struct anv_state surfaces = { 0, }, samplers = { 0, };
- VkResult result;
-
- result = anv_cmd_buffer_emit_samplers(cmd_buffer, stage, &samplers);
- if (result != VK_SUCCESS)
- return result;
- result = anv_cmd_buffer_emit_binding_table(cmd_buffer, stage, &surfaces);
- if (result != VK_SUCCESS)
- return result;
-
- static const uint32_t sampler_state_opcodes[] = {
- [VK_SHADER_STAGE_VERTEX] = 43,
- [VK_SHADER_STAGE_TESS_CONTROL] = 44, /* HS */
- [VK_SHADER_STAGE_TESS_EVALUATION] = 45, /* DS */
- [VK_SHADER_STAGE_GEOMETRY] = 46,
- [VK_SHADER_STAGE_FRAGMENT] = 47,
- [VK_SHADER_STAGE_COMPUTE] = 0,
- };
-
- static const uint32_t binding_table_opcodes[] = {
- [VK_SHADER_STAGE_VERTEX] = 38,
- [VK_SHADER_STAGE_TESS_CONTROL] = 39,
- [VK_SHADER_STAGE_TESS_EVALUATION] = 40,
- [VK_SHADER_STAGE_GEOMETRY] = 41,
- [VK_SHADER_STAGE_FRAGMENT] = 42,
- [VK_SHADER_STAGE_COMPUTE] = 0,
- };
-
- if (samplers.alloc_size > 0) {
- anv_batch_emit(&cmd_buffer->batch,
- GEN7_3DSTATE_SAMPLER_STATE_POINTERS_VS,
- ._3DCommandSubOpcode = sampler_state_opcodes[stage],
- .PointertoVSSamplerState = samplers.offset);
- }
-
- if (surfaces.alloc_size > 0) {
- anv_batch_emit(&cmd_buffer->batch,
- GEN7_3DSTATE_BINDING_TABLE_POINTERS_VS,
- ._3DCommandSubOpcode = binding_table_opcodes[stage],
- .PointertoVSBindingTable = surfaces.offset);
- }
+ if (!cmd_buffer->device->info.has_llc)
+ anv_state_clflush(*state);
return VK_SUCCESS;
}
-void
-anv_flush_descriptor_sets(struct anv_cmd_buffer *cmd_buffer)
-{
- VkShaderStage s;
- VkShaderStageFlags dirty = cmd_buffer->state.descriptors_dirty &
- cmd_buffer->state.pipeline->active_stages;
-
- VkResult result = VK_SUCCESS;
- for_each_bit(s, dirty) {
- result = flush_descriptor_set(cmd_buffer, s);
- if (result != VK_SUCCESS)
- break;
- }
-
- if (result != VK_SUCCESS) {
- assert(result == VK_ERROR_OUT_OF_DEVICE_MEMORY);
-
- result = anv_cmd_buffer_new_binding_table_block(cmd_buffer);
- assert(result == VK_SUCCESS);
-
- /* Re-emit state base addresses so we get the new surface state base
- * address before we start emitting binding tables etc.
- */
- anv_cmd_buffer_emit_state_base_address(cmd_buffer);
-
- /* Re-emit all active binding tables */
- for_each_bit(s, cmd_buffer->state.pipeline->active_stages) {
- result = flush_descriptor_set(cmd_buffer, s);
-
- /* It had better succeed this time */
- assert(result == VK_SUCCESS);
- }
- }
-
- cmd_buffer->state.descriptors_dirty &= ~cmd_buffer->state.pipeline->active_stages;
-}
-
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;
case 8:
gen8_cmd_buffer_begin_subpass(cmd_buffer, subpass);
break;
+ case 9:
+ gen9_cmd_buffer_begin_subpass(cmd_buffer, subpass);
+ break;
default:
unreachable("unsupported gen\n");
}
}
-static void
-emit_viewport_state(struct anv_cmd_buffer *cmd_buffer,
- uint32_t count, const VkViewport *viewports)
-{
- struct anv_state sf_clip_state =
- anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, count * 64, 64);
- struct anv_state cc_state =
- anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, count * 8, 32);
-
- for (uint32_t i = 0; i < count; i++) {
- const VkViewport *vp = &viewports[i];
-
- /* The gen7 state struct has just the matrix and guardband fields, the
- * gen8 struct adds the min/max viewport fields. */
- struct GEN8_SF_CLIP_VIEWPORT sf_clip_viewport = {
- .ViewportMatrixElementm00 = vp->width / 2,
- .ViewportMatrixElementm11 = vp->height / 2,
- .ViewportMatrixElementm22 = (vp->maxDepth - vp->minDepth) / 2,
- .ViewportMatrixElementm30 = vp->originX + vp->width / 2,
- .ViewportMatrixElementm31 = vp->originY + vp->height / 2,
- .ViewportMatrixElementm32 = (vp->maxDepth + vp->minDepth) / 2,
- .XMinClipGuardband = -1.0f,
- .XMaxClipGuardband = 1.0f,
- .YMinClipGuardband = -1.0f,
- .YMaxClipGuardband = 1.0f,
- .XMinViewPort = vp->originX,
- .XMaxViewPort = vp->originX + vp->width - 1,
- .YMinViewPort = vp->originY,
- .YMaxViewPort = vp->originY + vp->height - 1,
- };
-
- struct GEN7_CC_VIEWPORT cc_viewport = {
- .MinimumDepth = vp->minDepth,
- .MaximumDepth = vp->maxDepth
- };
-
- GEN8_SF_CLIP_VIEWPORT_pack(NULL, sf_clip_state.map + i * 64,
- &sf_clip_viewport);
- GEN7_CC_VIEWPORT_pack(NULL, cc_state.map + i * 32, &cc_viewport);
- }
-
- anv_batch_emit(&cmd_buffer->batch,
- GEN8_3DSTATE_VIEWPORT_STATE_POINTERS_CC,
- .CCViewportPointer = cc_state.offset);
- anv_batch_emit(&cmd_buffer->batch,
- GEN8_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP,
- .SFClipViewportPointer = sf_clip_state.offset);
-}
-
-void
-anv_cmd_buffer_emit_viewport(struct anv_cmd_buffer *cmd_buffer)
-{
- if (cmd_buffer->state.dynamic.viewport.count > 0) {
- emit_viewport_state(cmd_buffer, cmd_buffer->state.dynamic.viewport.count,
- cmd_buffer->state.dynamic.viewport.viewports);
- } else {
- /* If viewport count is 0, this is taken to mean "use the default" */
- emit_viewport_state(cmd_buffer, 1,
- &(VkViewport) {
- .originX = 0.0f,
- .originY = 0.0f,
- .width = cmd_buffer->state.framebuffer->width,
- .height = cmd_buffer->state.framebuffer->height,
- .minDepth = 0.0f,
- .maxDepth = 1.0f,
- });
- }
-}
-
-static inline int64_t
-clamp_int64(int64_t x, int64_t min, int64_t max)
-{
- if (x < min)
- return min;
- else if (x < max)
- return x;
- else
- return max;
-}
-
-static void
-emit_scissor_state(struct anv_cmd_buffer *cmd_buffer,
- uint32_t count, const VkRect2D *scissors)
-{
- struct anv_state scissor_state =
- anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, count * 32, 32);
-
- for (uint32_t i = 0; i < count; i++) {
- const VkRect2D *s = &scissors[i];
-
- /* Since xmax and ymax are inclusive, we have to have xmax < xmin or
- * ymax < ymin for empty clips. In case clip x, y, width height are all
- * 0, the clamps below produce 0 for xmin, ymin, xmax, ymax, which isn't
- * what we want. Just special case empty clips and produce a canonical
- * empty clip. */
- static const struct GEN7_SCISSOR_RECT empty_scissor = {
- .ScissorRectangleYMin = 1,
- .ScissorRectangleXMin = 1,
- .ScissorRectangleYMax = 0,
- .ScissorRectangleXMax = 0
- };
-
- const int max = 0xffff;
- struct GEN7_SCISSOR_RECT scissor = {
- /* Do this math using int64_t so overflow gets clamped correctly. */
- .ScissorRectangleYMin = clamp_int64(s->offset.y, 0, max),
- .ScissorRectangleXMin = clamp_int64(s->offset.x, 0, max),
- .ScissorRectangleYMax = clamp_int64((uint64_t) s->offset.y + s->extent.height - 1, 0, max),
- .ScissorRectangleXMax = clamp_int64((uint64_t) s->offset.x + s->extent.width - 1, 0, max)
- };
-
- if (s->extent.width <= 0 || s->extent.height <= 0) {
- GEN7_SCISSOR_RECT_pack(NULL, scissor_state.map + i * 32,
- &empty_scissor);
- } else {
- GEN7_SCISSOR_RECT_pack(NULL, scissor_state.map + i * 32, &scissor);
- }
- }
-
- anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_SCISSOR_STATE_POINTERS,
- .ScissorRectPointer = scissor_state.offset);
-}
-
-void
-anv_cmd_buffer_emit_scissor(struct anv_cmd_buffer *cmd_buffer)
-{
- if (cmd_buffer->state.dynamic.scissor.count > 0) {
- emit_scissor_state(cmd_buffer, cmd_buffer->state.dynamic.scissor.count,
- cmd_buffer->state.dynamic.scissor.scissors);
- } else {
- /* Emit a default scissor based on the currently bound framebuffer */
- emit_scissor_state(cmd_buffer, 1,
- &(VkRect2D) {
- .offset = { .x = 0, .y = 0, },
- .extent = {
- .width = cmd_buffer->state.framebuffer->width,
- .height = cmd_buffer->state.framebuffer->height,
- },
- });
- }
-}
-
void anv_CmdSetEvent(
- VkCmdBuffer cmdBuffer,
+ VkCommandBuffer commandBuffer,
VkEvent event,
VkPipelineStageFlags stageMask)
{
}
void anv_CmdResetEvent(
- VkCmdBuffer cmdBuffer,
+ VkCommandBuffer commandBuffer,
VkEvent event,
VkPipelineStageFlags stageMask)
{
}
void anv_CmdWaitEvents(
- VkCmdBuffer cmdBuffer,
+ VkCommandBuffer commandBuffer,
uint32_t eventCount,
const VkEvent* pEvents,
VkPipelineStageFlags srcStageMask,
struct anv_state
anv_cmd_buffer_push_constants(struct anv_cmd_buffer *cmd_buffer,
- VkShaderStage stage)
+ gl_shader_stage stage)
{
struct anv_push_constants *data =
cmd_buffer->state.push_constants[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;
+ struct anv_state state =
+ anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
+ total_push_constants_size,
+ 32 /* bottom 5 bits MBZ */);
+
+ /* 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;
}
void anv_CmdPushConstants(
- VkCmdBuffer cmdBuffer,
+ VkCommandBuffer commandBuffer,
VkPipelineLayout layout,
VkShaderStageFlags stageFlags,
- uint32_t start,
- uint32_t length,
- const void* values)
+ uint32_t offset,
+ uint32_t size,
+ const void* pValues)
{
- ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
- VkShaderStage stage;
+ ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
- for_each_bit(stage, stageFlags) {
+ anv_foreach_stage(stage, stageFlags) {
anv_cmd_buffer_ensure_push_constant_field(cmd_buffer, stage, client_data);
- memcpy(cmd_buffer->state.push_constants[stage]->client_data + start,
- values, length);
+ memcpy(cmd_buffer->state.push_constants[stage]->client_data + offset,
+ pValues, size);
}
cmd_buffer->state.push_constants_dirty |= stageFlags;
}
void anv_CmdExecuteCommands(
- VkCmdBuffer cmdBuffer,
- uint32_t cmdBuffersCount,
- const VkCmdBuffer* pCmdBuffers)
+ VkCommandBuffer commandBuffer,
+ uint32_t commandBuffersCount,
+ const VkCommandBuffer* pCmdBuffers)
{
- ANV_FROM_HANDLE(anv_cmd_buffer, primary, cmdBuffer);
+ ANV_FROM_HANDLE(anv_cmd_buffer, primary, commandBuffer);
- assert(primary->level == VK_CMD_BUFFER_LEVEL_PRIMARY);
+ assert(primary->level == VK_COMMAND_BUFFER_LEVEL_PRIMARY);
anv_assert(primary->state.subpass == &primary->state.pass->subpasses[0]);
- for (uint32_t i = 0; i < cmdBuffersCount; i++) {
+ for (uint32_t i = 0; i < commandBuffersCount; i++) {
ANV_FROM_HANDLE(anv_cmd_buffer, secondary, pCmdBuffers[i]);
- assert(secondary->level == VK_CMD_BUFFER_LEVEL_SECONDARY);
+ assert(secondary->level == VK_COMMAND_BUFFER_LEVEL_SECONDARY);
anv_cmd_buffer_add_secondary(primary, secondary);
}
VkResult anv_CreateCommandPool(
VkDevice _device,
- const VkCmdPoolCreateInfo* pCreateInfo,
- VkCmdPool* pCmdPool)
+ const VkCommandPoolCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkCommandPool* pCmdPool)
{
ANV_FROM_HANDLE(anv_device, device, _device);
struct anv_cmd_pool *pool;
- pool = anv_device_alloc(device, sizeof(*pool), 8,
- VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+ pool = anv_alloc2(&device->alloc, pAllocator, sizeof(*pool), 8,
+ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (pool == NULL)
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+ if (pAllocator)
+ pool->alloc = *pAllocator;
+ else
+ pool->alloc = device->alloc;
+
list_inithead(&pool->cmd_buffers);
*pCmdPool = anv_cmd_pool_to_handle(pool);
void anv_DestroyCommandPool(
VkDevice _device,
- VkCmdPool cmdPool)
+ VkCommandPool commandPool,
+ const VkAllocationCallbacks* pAllocator)
{
ANV_FROM_HANDLE(anv_device, device, _device);
- ANV_FROM_HANDLE(anv_cmd_pool, pool, cmdPool);
+ ANV_FROM_HANDLE(anv_cmd_pool, pool, commandPool);
- anv_ResetCommandPool(_device, cmdPool, 0);
+ anv_ResetCommandPool(_device, commandPool, 0);
- anv_device_free(device, pool);
+ anv_free2(&device->alloc, pAllocator, pool);
}
VkResult anv_ResetCommandPool(
VkDevice device,
- VkCmdPool cmdPool,
- VkCmdPoolResetFlags flags)
+ VkCommandPool commandPool,
+ VkCommandPoolResetFlags flags)
{
- ANV_FROM_HANDLE(anv_cmd_pool, pool, cmdPool);
+ ANV_FROM_HANDLE(anv_cmd_pool, pool, commandPool);
list_for_each_entry_safe(struct anv_cmd_buffer, cmd_buffer,
&pool->cmd_buffers, pool_link) {
- anv_DestroyCommandBuffer(device, anv_cmd_buffer_to_handle(cmd_buffer));
+ anv_cmd_buffer_destroy(cmd_buffer);
}
return VK_SUCCESS;