anv_cmd_predicated_ccs_resolve(struct anv_cmd_buffer *cmd_buffer,
const struct anv_image *image,
enum isl_format format,
+ struct isl_swizzle swizzle,
VkImageAspectFlagBits aspect,
uint32_t level, uint32_t array_layer,
enum isl_aux_op resolve_op,
image->planes[plane].aux_usage == ISL_AUX_USAGE_CCS_D)
resolve_op = ISL_AUX_OP_FULL_RESOLVE;
- anv_image_ccs_op(cmd_buffer, image, format, aspect, level,
- array_layer, 1, resolve_op, NULL, true);
+ anv_image_ccs_op(cmd_buffer, image, format, swizzle, aspect,
+ level, array_layer, 1, resolve_op, NULL, true);
}
static void
anv_cmd_predicated_mcs_resolve(struct anv_cmd_buffer *cmd_buffer,
const struct anv_image *image,
enum isl_format format,
+ struct isl_swizzle swizzle,
VkImageAspectFlagBits aspect,
uint32_t array_layer,
enum isl_aux_op resolve_op,
aspect, 0, array_layer,
resolve_op, fast_clear_supported);
- anv_image_mcs_op(cmd_buffer, image, format, aspect,
+ anv_image_mcs_op(cmd_buffer, image, format, swizzle, aspect,
array_layer, 1, resolve_op, NULL, true);
#else
unreachable("MCS resolves are unsupported on Ivybridge and Bay Trail");
* with not having this stall in some cases if we were really careful but
* it's better to play it safe. Full stall the GPU.
*/
- cmd_buffer->state.pending_pipe_bits |= ANV_PIPE_CS_STALL_BIT;
+ cmd_buffer->state.pending_pipe_bits |= ANV_PIPE_END_OF_PIPE_SYNC_BIT;
genX(cmd_buffer_apply_pipe_flushes)(cmd_buffer);
struct gen_mi_builder b;
anv_image_ccs_op(cmd_buffer, image,
image->planes[plane].surface.isl.format,
+ ISL_SWIZZLE_IDENTITY,
aspect, level, base_layer, level_layer_count,
ISL_AUX_OP_AMBIGUATE, NULL, false);
assert(base_level == 0 && level_count == 1);
anv_image_mcs_op(cmd_buffer, image,
image->planes[plane].surface.isl.format,
+ ISL_SWIZZLE_IDENTITY,
aspect, base_layer, layer_count,
ISL_AUX_OP_FAST_CLEAR, NULL, false);
}
if (image->samples == 1) {
anv_cmd_predicated_ccs_resolve(cmd_buffer, image,
image->planes[plane].surface.isl.format,
+ ISL_SWIZZLE_IDENTITY,
aspect, level, array_layer, resolve_op,
final_fast_clear);
} else {
anv_cmd_predicated_mcs_resolve(cmd_buffer, image,
image->planes[plane].surface.isl.format,
+ ISL_SWIZZLE_IDENTITY,
aspect, array_layer, resolve_op,
final_fast_clear);
}
* add extra flushes in the case it knows that the engine is already
* IDLE."
*/
- if (GEN_GEN == 12 && ANV_PIPE_AUX_TABLE_INVALIDATE_BIT)
+ if (GEN_GEN == 12 && (bits & ANV_PIPE_AUX_TABLE_INVALIDATE_BIT))
bits |= ANV_PIPE_NEEDS_END_OF_PIPE_SYNC_BIT;
/* If we're going to do an invalidate and we have a pending end-of-pipe
cmd_buffer_alloc_push_constants(struct anv_cmd_buffer *cmd_buffer)
{
VkShaderStageFlags stages =
- cmd_buffer->state.gfx.base.pipeline->active_stages;
+ cmd_buffer->state.gfx.pipeline->active_stages;
/* In order to avoid thrash, we assume that vertex and fragment stages
* always exist. In the rare case where one is missing *and* the other
static VkResult
emit_binding_table(struct anv_cmd_buffer *cmd_buffer,
struct anv_cmd_pipeline_state *pipe_state,
- gl_shader_stage stage,
+ struct anv_shader_bin *shader,
struct anv_state *bt_state)
{
struct anv_subpass *subpass = cmd_buffer->state.subpass;
uint32_t state_offset;
- struct anv_pipeline *pipeline = pipe_state->pipeline;
-
- struct anv_pipeline_bind_map *map = &pipeline->shaders[stage]->bind_map;
+ struct anv_pipeline_bind_map *map = &shader->bind_map;
if (map->surface_count == 0) {
*bt_state = (struct anv_state) { 0, };
return VK_SUCCESS;
case ANV_DESCRIPTOR_SET_COLOR_ATTACHMENTS:
/* Color attachment binding */
- assert(stage == MESA_SHADER_FRAGMENT);
+ assert(shader->stage == MESA_SHADER_FRAGMENT);
if (binding->index < subpass->color_count) {
const unsigned att =
subpass->color_attachments[binding->index].attachment;
anv_cmd_buffer_alloc_surface_state(cmd_buffer);
struct anv_address constant_data = {
- .bo = pipeline->device->dynamic_state_pool.block_pool.bo,
- .offset = pipeline->shaders[stage]->constant_data.offset,
+ .bo = cmd_buffer->device->dynamic_state_pool.block_pool.bo,
+ .offset = shader->constant_data.offset,
};
- unsigned constant_data_size =
- pipeline->shaders[stage]->constant_data_size;
+ unsigned constant_data_size = shader->constant_data_size;
const enum isl_format format =
anv_isl_format_for_descriptor_type(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
case ANV_DESCRIPTOR_SET_NUM_WORK_GROUPS: {
/* This is always the first binding for compute shaders */
- assert(stage == MESA_SHADER_COMPUTE && s == 0);
+ assert(shader->stage == MESA_SHADER_COMPUTE && s == 0);
struct anv_state surface_state =
anv_cmd_buffer_alloc_surface_state(cmd_buffer);
break;
}
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
- assert(stage == MESA_SHADER_FRAGMENT);
+ assert(shader->stage == MESA_SHADER_FRAGMENT);
if ((desc->image_view->aspect_mask & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV) == 0) {
/* For depth and stencil input attachments, we treat it like any
* old texture that a user may have bound.
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: {
/* Compute the offset within the buffer */
struct anv_push_constants *push =
- &cmd_buffer->state.push_constants[stage];
+ &cmd_buffer->state.push_constants[shader->stage];
uint32_t dynamic_offset =
push->dynamic_offsets[binding->dynamic_offset_index];
static VkResult
emit_samplers(struct anv_cmd_buffer *cmd_buffer,
struct anv_cmd_pipeline_state *pipe_state,
- gl_shader_stage stage,
+ struct anv_shader_bin *shader,
struct anv_state *state)
{
- struct anv_pipeline *pipeline = pipe_state->pipeline;
-
- struct anv_pipeline_bind_map *map = &pipeline->shaders[stage]->bind_map;
+ struct anv_pipeline_bind_map *map = &shader->bind_map;
if (map->sampler_count == 0) {
*state = (struct anv_state) { 0, };
return VK_SUCCESS;
static uint32_t
flush_descriptor_sets(struct anv_cmd_buffer *cmd_buffer,
- struct anv_cmd_pipeline_state *pipe_state)
+ struct anv_cmd_pipeline_state *pipe_state,
+ struct anv_shader_bin **shaders,
+ uint32_t num_shaders)
{
- VkShaderStageFlags dirty = cmd_buffer->state.descriptors_dirty &
- pipe_state->pipeline->active_stages;
+ const VkShaderStageFlags dirty = cmd_buffer->state.descriptors_dirty;
+ VkShaderStageFlags flushed = 0;
VkResult result = VK_SUCCESS;
- anv_foreach_stage(s, dirty) {
- result = emit_samplers(cmd_buffer, pipe_state, s,
- &cmd_buffer->state.samplers[s]);
+ for (uint32_t i = 0; i < num_shaders; i++) {
+ if (!shaders[i])
+ continue;
+
+ gl_shader_stage stage = shaders[i]->stage;
+ VkShaderStageFlags vk_stage = mesa_to_vk_shader_stage(stage);
+ if ((vk_stage & dirty) == 0)
+ continue;
+
+ result = emit_samplers(cmd_buffer, pipe_state, shaders[i],
+ &cmd_buffer->state.samplers[stage]);
if (result != VK_SUCCESS)
break;
- result = emit_binding_table(cmd_buffer, pipe_state, s,
- &cmd_buffer->state.binding_tables[s]);
+ result = emit_binding_table(cmd_buffer, pipe_state, shaders[i],
+ &cmd_buffer->state.binding_tables[stage]);
if (result != VK_SUCCESS)
break;
+
+ flushed |= vk_stage;
}
if (result != VK_SUCCESS) {
genX(cmd_buffer_emit_state_base_address)(cmd_buffer);
/* Re-emit all active binding tables */
- dirty |= pipe_state->pipeline->active_stages;
- anv_foreach_stage(s, dirty) {
- result = emit_samplers(cmd_buffer, pipe_state, s,
- &cmd_buffer->state.samplers[s]);
+ flushed = 0;
+
+ for (uint32_t i = 0; i < num_shaders; i++) {
+ if (!shaders[i])
+ continue;
+
+ gl_shader_stage stage = shaders[i]->stage;
+
+ result = emit_samplers(cmd_buffer, pipe_state, shaders[i],
+ &cmd_buffer->state.samplers[stage]);
if (result != VK_SUCCESS) {
anv_batch_set_error(&cmd_buffer->batch, result);
return 0;
}
- result = emit_binding_table(cmd_buffer, pipe_state, s,
- &cmd_buffer->state.binding_tables[s]);
+ result = emit_binding_table(cmd_buffer, pipe_state, shaders[i],
+ &cmd_buffer->state.binding_tables[stage]);
if (result != VK_SUCCESS) {
anv_batch_set_error(&cmd_buffer->batch, result);
return 0;
}
+
+ flushed |= mesa_to_vk_shader_stage(stage);
}
}
- cmd_buffer->state.descriptors_dirty &= ~dirty;
+ cmd_buffer->state.descriptors_dirty &= ~flushed;
- return dirty;
+ return flushed;
}
static void
}
-/** Returns the size in bytes of the bound buffer relative to range->start
+/** Returns the size in bytes of the bound buffer
+ *
+ * The range is relative to the start of the buffer, not the start of the
+ * range. The returned range may be smaller than
*
- * This may be smaller than range->length * 32.
+ * (range->start + range->length) * 32;
*/
static uint32_t
get_push_range_bound_size(struct anv_cmd_buffer *cmd_buffer,
struct anv_descriptor_set *set =
gfx_state->base.descriptors[range->index];
assert(range->start * 32 < set->desc_mem.alloc_size);
- assert((range->start + range->length) * 32 < set->desc_mem.alloc_size);
- return set->desc_mem.alloc_size - range->start * 32;
+ assert((range->start + range->length) * 32 <= set->desc_mem.alloc_size);
+ return set->desc_mem.alloc_size;
}
case ANV_DESCRIPTOR_SET_PUSH_CONSTANTS:
- return range->length * 32;
+ return (range->start + range->length) * 32;
default: {
assert(range->set < MAX_SETS);
&set->descriptors[range->index];
if (desc->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) {
- if (range->start * 32 > desc->buffer_view->range)
- return 0;
-
- return desc->buffer_view->range - range->start * 32;
+ return desc->buffer_view->range;
} else {
assert(desc->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC);
/* Compute the offset within the buffer */
/* Align the range for consistency */
bound_range = align_u32(bound_range, ANV_UBO_BOUNDS_CHECK_ALIGNMENT);
- if (range->start * 32 > bound_range)
- return 0;
-
- return bound_range - range->start * 32;
+ return bound_range;
}
}
}
unsigned buffer_count)
{
const struct anv_cmd_graphics_state *gfx_state = &cmd_buffer->state.gfx;
- const struct anv_pipeline *pipeline = gfx_state->base.pipeline;
+ const struct anv_graphics_pipeline *pipeline = gfx_state->pipeline;
static const uint32_t push_constant_opcodes[] = {
[MESA_SHADER_VERTEX] = 21,
}
const struct anv_cmd_graphics_state *gfx_state = &cmd_buffer->state.gfx;
- const struct anv_pipeline *pipeline = gfx_state->base.pipeline;
+ const struct anv_graphics_pipeline *pipeline = gfx_state->pipeline;
static const uint32_t push_constant_opcodes[] = {
[MESA_SHADER_VERTEX] = 21,
{
VkShaderStageFlags flushed = 0;
const struct anv_cmd_graphics_state *gfx_state = &cmd_buffer->state.gfx;
- const struct anv_pipeline *pipeline = gfx_state->base.pipeline;
+ const struct anv_graphics_pipeline *pipeline = gfx_state->pipeline;
#if GEN_GEN >= 12
uint32_t nobuffer_stages = 0;
void
genX(cmd_buffer_flush_state)(struct anv_cmd_buffer *cmd_buffer)
{
- struct anv_pipeline *pipeline = cmd_buffer->state.gfx.base.pipeline;
+ struct anv_graphics_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
uint32_t *p;
uint32_t vb_emit = cmd_buffer->state.gfx.vb_dirty & pipeline->vb_used;
assert((pipeline->active_stages & VK_SHADER_STAGE_COMPUTE_BIT) == 0);
- genX(cmd_buffer_config_l3)(cmd_buffer, pipeline->l3_config);
+ genX(cmd_buffer_config_l3)(cmd_buffer, pipeline->base.l3_config);
genX(cmd_buffer_emit_hashing_mode)(cmd_buffer, UINT_MAX, UINT_MAX, 1);
#endif
if (cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_PIPELINE) {
- anv_batch_emit_batch(&cmd_buffer->batch, &pipeline->batch);
+ anv_batch_emit_batch(&cmd_buffer->batch, &pipeline->base.batch);
/* If the pipeline changed, we may need to re-allocate push constant
* space in the URB.
* 3DSTATE_BINDING_TABLE_POINTER_* for the push constants to take effect.
*/
uint32_t dirty = 0;
- if (cmd_buffer->state.descriptors_dirty)
- dirty = flush_descriptor_sets(cmd_buffer, &cmd_buffer->state.gfx.base);
+ if (cmd_buffer->state.descriptors_dirty) {
+ dirty = flush_descriptor_sets(cmd_buffer,
+ &cmd_buffer->state.gfx.base,
+ pipeline->shaders,
+ ARRAY_SIZE(pipeline->shaders));
+ }
if (dirty || cmd_buffer->state.push_constants_dirty) {
/* Because we're pushing UBOs, we have to push whenever either
update_dirty_vbs_for_gen8_vb_flush(struct anv_cmd_buffer *cmd_buffer,
uint32_t access_type)
{
- struct anv_pipeline *pipeline = cmd_buffer->state.gfx.base.pipeline;
+ struct anv_graphics_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
const struct brw_vs_prog_data *vs_prog_data = get_vs_prog_data(pipeline);
uint64_t vb_used = pipeline->vb_used;
uint32_t firstInstance)
{
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
- struct anv_pipeline *pipeline = cmd_buffer->state.gfx.base.pipeline;
+ struct anv_graphics_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
const struct brw_vs_prog_data *vs_prog_data = get_vs_prog_data(pipeline);
if (anv_batch_has_error(&cmd_buffer->batch))
uint32_t firstInstance)
{
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
- struct anv_pipeline *pipeline = cmd_buffer->state.gfx.base.pipeline;
+ struct anv_graphics_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
const struct brw_vs_prog_data *vs_prog_data = get_vs_prog_data(pipeline);
if (anv_batch_has_error(&cmd_buffer->batch))
#if GEN_IS_HASWELL || GEN_GEN >= 8
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
ANV_FROM_HANDLE(anv_buffer, counter_buffer, counterBuffer);
- struct anv_pipeline *pipeline = cmd_buffer->state.gfx.base.pipeline;
+ struct anv_graphics_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
const struct brw_vs_prog_data *vs_prog_data = get_vs_prog_data(pipeline);
/* firstVertex is always zero for this draw function */
{
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
- struct anv_pipeline *pipeline = cmd_buffer->state.gfx.base.pipeline;
+ struct anv_graphics_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
const struct brw_vs_prog_data *vs_prog_data = get_vs_prog_data(pipeline);
if (anv_batch_has_error(&cmd_buffer->batch))
{
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
- struct anv_pipeline *pipeline = cmd_buffer->state.gfx.base.pipeline;
+ struct anv_graphics_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
const struct brw_vs_prog_data *vs_prog_data = get_vs_prog_data(pipeline);
if (anv_batch_has_error(&cmd_buffer->batch))
ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
ANV_FROM_HANDLE(anv_buffer, count_buffer, _countBuffer);
struct anv_cmd_state *cmd_state = &cmd_buffer->state;
- struct anv_pipeline *pipeline = cmd_state->gfx.base.pipeline;
+ struct anv_graphics_pipeline *pipeline = cmd_state->gfx.pipeline;
const struct brw_vs_prog_data *vs_prog_data = get_vs_prog_data(pipeline);
if (anv_batch_has_error(&cmd_buffer->batch))
ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
ANV_FROM_HANDLE(anv_buffer, count_buffer, _countBuffer);
struct anv_cmd_state *cmd_state = &cmd_buffer->state;
- struct anv_pipeline *pipeline = cmd_state->gfx.base.pipeline;
+ struct anv_graphics_pipeline *pipeline = cmd_state->gfx.pipeline;
const struct brw_vs_prog_data *vs_prog_data = get_vs_prog_data(pipeline);
if (anv_batch_has_error(&cmd_buffer->batch))
void
genX(cmd_buffer_flush_compute_state)(struct anv_cmd_buffer *cmd_buffer)
{
- struct anv_pipeline *pipeline = cmd_buffer->state.compute.base.pipeline;
+ struct anv_compute_pipeline *pipeline = cmd_buffer->state.compute.pipeline;
- assert(pipeline->active_stages == VK_SHADER_STAGE_COMPUTE_BIT);
+ assert(pipeline->cs);
- genX(cmd_buffer_config_l3)(cmd_buffer, pipeline->l3_config);
+ genX(cmd_buffer_config_l3)(cmd_buffer, pipeline->base.l3_config);
genX(flush_pipeline_select_gpgpu)(cmd_buffer);
cmd_buffer->state.pending_pipe_bits |= ANV_PIPE_CS_STALL_BIT;
genX(cmd_buffer_apply_pipe_flushes)(cmd_buffer);
- anv_batch_emit_batch(&cmd_buffer->batch, &pipeline->batch);
+ anv_batch_emit_batch(&cmd_buffer->batch, &pipeline->base.batch);
/* The workgroup size of the pipeline affects our push constant layout
* so flag push constants as dirty if we change the pipeline.
if ((cmd_buffer->state.descriptors_dirty & VK_SHADER_STAGE_COMPUTE_BIT) ||
cmd_buffer->state.compute.pipeline_dirty) {
- flush_descriptor_sets(cmd_buffer, &cmd_buffer->state.compute.base);
+ flush_descriptor_sets(cmd_buffer,
+ &cmd_buffer->state.compute.base,
+ &pipeline->cs, 1);
uint32_t iface_desc_data_dw[GENX(INTERFACE_DESCRIPTOR_DATA_length)];
struct GENX(INTERFACE_DESCRIPTOR_DATA) desc = {
uint32_t groupCountZ)
{
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
- struct anv_pipeline *pipeline = cmd_buffer->state.compute.base.pipeline;
+ struct anv_compute_pipeline *pipeline = cmd_buffer->state.compute.pipeline;
const struct brw_cs_prog_data *prog_data = get_cs_prog_data(pipeline);
anv_cmd_buffer_push_base_group_id(cmd_buffer, baseGroupX,
{
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
- struct anv_pipeline *pipeline = cmd_buffer->state.compute.base.pipeline;
+ struct anv_compute_pipeline *pipeline = cmd_buffer->state.compute.pipeline;
const struct brw_cs_prog_data *prog_data = get_cs_prog_data(pipeline);
struct anv_address addr = anv_address_add(buffer->address, offset);
struct anv_batch *batch = &cmd_buffer->batch;
if (iview->image->samples == 1) {
anv_image_ccs_op(cmd_buffer, image,
iview->planes[0].isl.format,
+ iview->planes[0].isl.swizzle,
VK_IMAGE_ASPECT_COLOR_BIT,
0, 0, 1, ISL_AUX_OP_FAST_CLEAR,
&clear_color,
} else {
anv_image_mcs_op(cmd_buffer, image,
iview->planes[0].isl.format,
+ iview->planes[0].isl.swizzle,
VK_IMAGE_ASPECT_COLOR_BIT,
0, 1, ISL_AUX_OP_FAST_CLEAR,
&clear_color,
if (image->samples == 1) {
anv_cmd_predicated_ccs_resolve(cmd_buffer, image,
iview->planes[0].isl.format,
+ iview->planes[0].isl.swizzle,
VK_IMAGE_ASPECT_COLOR_BIT,
iview->planes[0].isl.base_level,
array_layer,
} else {
anv_cmd_predicated_mcs_resolve(cmd_buffer, image,
iview->planes[0].isl.format,
+ iview->planes[0].isl.swizzle,
VK_IMAGE_ASPECT_COLOR_BIT,
base_layer,
ISL_AUX_OP_PARTIAL_RESOLVE,