anv/meta2d: Add support for blitting from W-tiled sources on gen7

Reviewed-by: Nanley Chery <nanley.g.chery@intel.com>
Reviewed-by: Chad Versace <chad.versace@intel.com>
This commit is contained in:
Jason Ekstrand
2016-03-28 16:52:56 -07:00
parent b0a5ca5cfc
commit 819d0e1a7c

View File

@@ -173,6 +173,10 @@ create_iview(struct anv_cmd_buffer *cmd_buffer,
struct blit2d_src_temps {
VkImage image;
struct anv_image_view iview;
struct anv_buffer buffer;
struct anv_buffer_view bview;
VkDescriptorPool desc_pool;
VkDescriptorSet set;
};
@@ -187,56 +191,130 @@ blit2d_bind_src(struct anv_cmd_buffer *cmd_buffer,
struct anv_device *device = cmd_buffer->device;
VkDevice vk_device = anv_device_to_handle(cmd_buffer->device);
create_iview(cmd_buffer, src, rect, VK_IMAGE_USAGE_SAMPLED_BIT,
&tmp->image, &tmp->iview);
if (src_type == BLIT2D_SRC_TYPE_NORMAL) {
create_iview(cmd_buffer, src, rect, VK_IMAGE_USAGE_SAMPLED_BIT,
&tmp->image, &tmp->iview);
anv_CreateDescriptorPool(vk_device,
&(const VkDescriptorPoolCreateInfo) {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
.pNext = NULL,
.flags = 0,
.maxSets = 1,
.poolSizeCount = 1,
.pPoolSizes = (VkDescriptorPoolSize[]) {
{
.type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
.descriptorCount = 1
},
}
}, &cmd_buffer->pool->alloc, &tmp->desc_pool);
anv_AllocateDescriptorSets(vk_device,
&(VkDescriptorSetAllocateInfo) {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
.descriptorPool = tmp->desc_pool,
.descriptorSetCount = 1,
.pSetLayouts = &device->meta_state.blit2d.img_ds_layout
}, &tmp->set);
anv_UpdateDescriptorSets(vk_device,
1, /* writeCount */
(VkWriteDescriptorSet[]) {
{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.dstSet = tmp->set,
.dstBinding = 0,
.dstArrayElement = 0,
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
.pImageInfo = (VkDescriptorImageInfo[]) {
anv_CreateDescriptorPool(vk_device,
&(const VkDescriptorPoolCreateInfo) {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
.pNext = NULL,
.flags = 0,
.maxSets = 1,
.poolSizeCount = 1,
.pPoolSizes = (VkDescriptorPoolSize[]) {
{
.sampler = NULL,
.imageView = anv_image_view_to_handle(&tmp->iview),
.imageLayout = VK_IMAGE_LAYOUT_GENERAL,
.type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
.descriptorCount = 1
},
}
}
}, 0, NULL);
}, &cmd_buffer->pool->alloc, &tmp->desc_pool);
anv_CmdBindDescriptorSets(anv_cmd_buffer_to_handle(cmd_buffer),
VK_PIPELINE_BIND_POINT_GRAPHICS,
device->meta_state.blit2d.img_p_layout, 0, 1,
&tmp->set, 0, NULL);
anv_AllocateDescriptorSets(vk_device,
&(VkDescriptorSetAllocateInfo) {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
.descriptorPool = tmp->desc_pool,
.descriptorSetCount = 1,
.pSetLayouts = &device->meta_state.blit2d.img_ds_layout
}, &tmp->set);
anv_UpdateDescriptorSets(vk_device,
1, /* writeCount */
(VkWriteDescriptorSet[]) {
{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.dstSet = tmp->set,
.dstBinding = 0,
.dstArrayElement = 0,
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
.pImageInfo = (VkDescriptorImageInfo[]) {
{
.sampler = NULL,
.imageView = anv_image_view_to_handle(&tmp->iview),
.imageLayout = VK_IMAGE_LAYOUT_GENERAL,
},
}
}
}, 0, NULL);
anv_CmdBindDescriptorSets(anv_cmd_buffer_to_handle(cmd_buffer),
VK_PIPELINE_BIND_POINT_GRAPHICS,
device->meta_state.blit2d.img_p_layout, 0, 1,
&tmp->set, 0, NULL);
} else {
assert(src_type == BLIT2D_SRC_TYPE_W_DETILE);
assert(src->tiling == ISL_TILING_W);
assert(src->bs == 1);
uint32_t tile_offset = 0;
isl_tiling_get_intratile_offset_el(&cmd_buffer->device->isl_dev,
ISL_TILING_W, 1, src->pitch,
rect->src_x, rect->src_y,
&tile_offset,
&rect->src_x, &rect->src_y);
tmp->buffer = (struct anv_buffer) {
.device = device,
.size = align_u32(rect->src_y + rect->height, 64) * src->pitch,
.usage = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT,
.bo = src->bo,
.offset = src->base_offset + tile_offset,
};
anv_buffer_view_init(&tmp->bview, device,
&(VkBufferViewCreateInfo) {
.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,
.buffer = anv_buffer_to_handle(&tmp->buffer),
.format = VK_FORMAT_R8_UINT,
.offset = 0,
.range = VK_WHOLE_SIZE,
}, cmd_buffer);
anv_CreateDescriptorPool(vk_device,
&(const VkDescriptorPoolCreateInfo) {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
.pNext = NULL,
.flags = 0,
.maxSets = 1,
.poolSizeCount = 1,
.pPoolSizes = (VkDescriptorPoolSize[]) {
{
.type = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
.descriptorCount = 1
},
}
}, &cmd_buffer->pool->alloc, &tmp->desc_pool);
anv_AllocateDescriptorSets(vk_device,
&(VkDescriptorSetAllocateInfo) {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
.descriptorPool = tmp->desc_pool,
.descriptorSetCount = 1,
.pSetLayouts = &device->meta_state.blit2d.buf_ds_layout
}, &tmp->set);
anv_UpdateDescriptorSets(vk_device,
1, /* writeCount */
(VkWriteDescriptorSet[]) {
{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.dstSet = tmp->set,
.dstBinding = 0,
.dstArrayElement = 0,
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
.pTexelBufferView = (VkBufferView[]) {
anv_buffer_view_to_handle(&tmp->bview),
},
}
}, 0, NULL);
anv_CmdBindDescriptorSets(anv_cmd_buffer_to_handle(cmd_buffer),
VK_PIPELINE_BIND_POINT_GRAPHICS,
device->meta_state.blit2d.buf_p_layout, 0, 1,
&tmp->set, 0, NULL);
}
}
static void
@@ -246,8 +324,10 @@ blit2d_unbind_src(struct anv_cmd_buffer *cmd_buffer,
{
anv_DestroyDescriptorPool(anv_device_to_handle(cmd_buffer->device),
tmp->desc_pool, &cmd_buffer->pool->alloc);
anv_DestroyImage(anv_device_to_handle(cmd_buffer->device),
tmp->image, &cmd_buffer->pool->alloc);
if (src_type == BLIT2D_SRC_TYPE_NORMAL) {
anv_DestroyImage(anv_device_to_handle(cmd_buffer->device),
tmp->image, &cmd_buffer->pool->alloc);
}
}
void
@@ -478,6 +558,80 @@ typedef nir_ssa_def* (*texel_fetch_build_func)(struct nir_builder *,
struct anv_device *,
nir_ssa_def *, nir_ssa_def *);
static nir_ssa_def *
nir_copy_bits(struct nir_builder *b, nir_ssa_def *dst, unsigned dst_offset,
nir_ssa_def *src, unsigned src_offset, unsigned num_bits)
{
unsigned src_mask = (~1u >> (32 - num_bits)) << src_offset;
nir_ssa_def *masked = nir_iand(b, src, nir_imm_int(b, src_mask));
nir_ssa_def *shifted;
if (dst_offset > src_offset) {
shifted = nir_ishl(b, masked, nir_imm_int(b, dst_offset - src_offset));
} else if (dst_offset < src_offset) {
shifted = nir_ushr(b, masked, nir_imm_int(b, src_offset - dst_offset));
} else {
assert(dst_offset == src_offset);
shifted = masked;
}
return nir_ior(b, dst, shifted);
}
static nir_ssa_def *
build_nir_w_tiled_fetch(struct nir_builder *b, struct anv_device *device,
nir_ssa_def *tex_pos, nir_ssa_def *tex_pitch)
{
nir_ssa_def *x = nir_channel(b, tex_pos, 0);
nir_ssa_def *y = nir_channel(b, tex_pos, 1);
/* First, compute the block-aligned offset */
nir_ssa_def *x_major = nir_ushr(b, x, nir_imm_int(b, 6));
nir_ssa_def *y_major = nir_ushr(b, y, nir_imm_int(b, 6));
nir_ssa_def *offset =
nir_iadd(b, nir_imul(b, y_major,
nir_imul(b, tex_pitch, nir_imm_int(b, 64))),
nir_imul(b, x_major, nir_imm_int(b, 4096)));
/* Compute the bottom 12 bits of the offset */
offset = nir_copy_bits(b, offset, 0, x, 0, 1);
offset = nir_copy_bits(b, offset, 1, y, 0, 1);
offset = nir_copy_bits(b, offset, 2, x, 1, 1);
offset = nir_copy_bits(b, offset, 3, y, 1, 1);
offset = nir_copy_bits(b, offset, 4, x, 2, 1);
offset = nir_copy_bits(b, offset, 5, y, 2, 4);
offset = nir_copy_bits(b, offset, 9, x, 3, 3);
if (device->isl_dev.has_bit6_swizzling) {
offset = nir_ixor(b, offset,
nir_ushr(b, nir_iand(b, offset, nir_imm_int(b, 0x0200)),
nir_imm_int(b, 3)));
}
const struct glsl_type *sampler_type =
glsl_sampler_type(GLSL_SAMPLER_DIM_BUF, false, false, GLSL_TYPE_FLOAT);
nir_variable *sampler = nir_variable_create(b->shader, nir_var_uniform,
sampler_type, "s_tex");
sampler->data.descriptor_set = 0;
sampler->data.binding = 0;
nir_tex_instr *tex = nir_tex_instr_create(b->shader, 1);
tex->sampler_dim = GLSL_SAMPLER_DIM_BUF;
tex->op = nir_texop_txf;
tex->src[0].src_type = nir_tex_src_coord;
tex->src[0].src = nir_src_for_ssa(offset);
tex->dest_type = nir_type_float; /* TODO */
tex->is_array = false;
tex->coord_components = 1;
tex->texture = nir_deref_var_create(tex, sampler);
tex->sampler = NULL;
nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, "tex");
nir_builder_instr_insert(b, &tex->instr);
return &tex->dest.ssa;
}
static nir_ssa_def *
build_nir_texel_fetch(struct nir_builder *b, struct anv_device *device,
nir_ssa_def *tex_pos, nir_ssa_def *tex_pitch)
@@ -595,9 +749,10 @@ blit2d_init_pipeline(struct anv_device *device,
src_func = build_nir_texel_fetch;
break;
case BLIT2D_SRC_TYPE_W_DETILE:
/* Not yet supported */
src_func = build_nir_w_tiled_fetch;
break;
default:
return VK_SUCCESS;
unreachable("Invalid blit2d source type");
}
struct anv_shader_module fs = { .nir = NULL };