anv: Emulate texture swizzle in the shader when needed

Now that we have the descriptor buffer mechanism, emulated texture
swizzle can be implemented in a very non-invasive way.  Previous
attempts all tried to extend the push constant based image param
mechanism which was gross.  This could, in theory, be done much faster
with a magic back-end instruction which does indirect MOVs but Vulkan on
IVB is already so slow this isn't going to matter much.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=104355
Cc: "19.1" <mesa-stable@lists.freedesktop.org>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
This commit is contained in:
Jason Ekstrand
2019-05-17 10:04:58 -05:00
parent ea479fdc1d
commit d2aa65eb18
4 changed files with 133 additions and 2 deletions

View File

@@ -103,6 +103,12 @@ anv_descriptor_data_for_type(const struct anv_physical_device *device,
type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC))
data |= ANV_DESCRIPTOR_ADDRESS_RANGE;
/* On Ivy Bridge and Bay Trail, we need swizzles textures in the shader */
if (device->info.gen == 7 && !device->info.is_haswell &&
(type == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE ||
type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER))
data |= ANV_DESCRIPTOR_TEXTURE_SWIZZLE;
return data;
}
@@ -123,6 +129,9 @@ anv_descriptor_data_size(enum anv_descriptor_data data)
if (data & ANV_DESCRIPTOR_ADDRESS_RANGE)
size += sizeof(struct anv_address_range_descriptor);
if (data & ANV_DESCRIPTOR_TEXTURE_SWIZZLE)
size += sizeof(struct anv_texture_swizzle_descriptor);
return size;
}
@@ -1184,6 +1193,26 @@ anv_descriptor_set_write_image_view(struct anv_device *device,
anv_descriptor_set_write_image_param(desc_map, image_param);
}
if (bind_layout->data & ANV_DESCRIPTOR_TEXTURE_SWIZZLE) {
assert(!(bind_layout->data & ANV_DESCRIPTOR_SAMPLED_IMAGE));
assert(image_view);
struct anv_texture_swizzle_descriptor desc_data[3];
memset(desc_data, 0, sizeof(desc_data));
for (unsigned p = 0; p < image_view->n_planes; p++) {
desc_data[p] = (struct anv_texture_swizzle_descriptor) {
.swizzle = {
(uint8_t)image_view->planes[p].isl.swizzle.r,
(uint8_t)image_view->planes[p].isl.swizzle.g,
(uint8_t)image_view->planes[p].isl.swizzle.b,
(uint8_t)image_view->planes[p].isl.swizzle.a,
},
};
}
memcpy(desc_map, desc_data,
MAX2(1, bind_layout->max_plane_count) * sizeof(desc_data[0]));
}
}
void