|
|
@ -214,8 +214,12 @@ void vulkan_texture_destroy(struct wlr_vk_texture *texture) {
|
|
|
|
wl_list_remove(&texture->link);
|
|
|
|
wl_list_remove(&texture->link);
|
|
|
|
|
|
|
|
|
|
|
|
VkDevice dev = texture->renderer->dev->dev;
|
|
|
|
VkDevice dev = texture->renderer->dev->dev;
|
|
|
|
if (texture->ds && texture->ds_pool) {
|
|
|
|
|
|
|
|
vulkan_free_ds(texture->renderer, texture->ds_pool, texture->ds);
|
|
|
|
struct wlr_vk_texture_view *view, *tmp_view;
|
|
|
|
|
|
|
|
wl_list_for_each_safe(view, tmp_view, &texture->views, link) {
|
|
|
|
|
|
|
|
vulkan_free_ds(texture->renderer, view->ds_pool, view->ds);
|
|
|
|
|
|
|
|
vkDestroyImageView(dev, view->image_view, NULL);
|
|
|
|
|
|
|
|
free(view);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < WLR_DMABUF_MAX_PLANES; i++) {
|
|
|
|
for (size_t i = 0; i < WLR_DMABUF_MAX_PLANES; i++) {
|
|
|
@ -224,7 +228,6 @@ void vulkan_texture_destroy(struct wlr_vk_texture *texture) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
vkDestroyImageView(dev, texture->image_view, NULL);
|
|
|
|
|
|
|
|
vkDestroyImage(dev, texture->image, NULL);
|
|
|
|
vkDestroyImage(dev, texture->image, NULL);
|
|
|
|
|
|
|
|
|
|
|
|
for (unsigned i = 0u; i < texture->mem_count; ++i) {
|
|
|
|
for (unsigned i = 0u; i < texture->mem_count; ++i) {
|
|
|
@ -262,22 +265,29 @@ static struct wlr_vk_texture *vulkan_texture_create(
|
|
|
|
&texture_impl, width, height);
|
|
|
|
&texture_impl, width, height);
|
|
|
|
texture->renderer = renderer;
|
|
|
|
texture->renderer = renderer;
|
|
|
|
wl_list_insert(&renderer->textures, &texture->link);
|
|
|
|
wl_list_insert(&renderer->textures, &texture->link);
|
|
|
|
|
|
|
|
wl_list_init(&texture->views);
|
|
|
|
return texture;
|
|
|
|
return texture;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static bool vulkan_texture_init_view(struct wlr_vk_texture *texture) {
|
|
|
|
struct wlr_vk_texture_view *vulkan_texture_get_or_create_view(struct wlr_vk_texture *texture,
|
|
|
|
VkResult res;
|
|
|
|
const struct wlr_vk_pipeline_layout *pipeline_layout) {
|
|
|
|
VkDevice dev = texture->renderer->dev->dev;
|
|
|
|
struct wlr_vk_texture_view *view;
|
|
|
|
|
|
|
|
wl_list_for_each(view, &texture->views, link) {
|
|
|
|
|
|
|
|
if (view->layout == pipeline_layout) {
|
|
|
|
|
|
|
|
return view;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
struct wlr_vk_pipeline_layout *pipeline_layout = get_or_create_pipeline_layout(
|
|
|
|
view = calloc(1, sizeof(*view));
|
|
|
|
texture->renderer, &(struct wlr_vk_pipeline_layout_key) {
|
|
|
|
if (!view) {
|
|
|
|
.ycbcr_format = texture->format->is_ycbcr ? texture->format : NULL,
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
if (!pipeline_layout) {
|
|
|
|
|
|
|
|
wlr_log(WLR_ERROR, "Failed to create a pipeline layout for a texture");
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
view->layout = pipeline_layout;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
VkResult res;
|
|
|
|
|
|
|
|
VkDevice dev = texture->renderer->dev->dev;
|
|
|
|
|
|
|
|
|
|
|
|
const struct wlr_pixel_format_info *format_info =
|
|
|
|
const struct wlr_pixel_format_info *format_info =
|
|
|
|
drm_get_pixel_format_info(texture->format->drm);
|
|
|
|
drm_get_pixel_format_info(texture->format->drm);
|
|
|
|
if (format_info != NULL) {
|
|
|
|
if (format_info != NULL) {
|
|
|
@ -317,20 +327,22 @@ static bool vulkan_texture_init_view(struct wlr_vk_texture *texture) {
|
|
|
|
view_info.pNext = &ycbcr_conversion_info;
|
|
|
|
view_info.pNext = &ycbcr_conversion_info;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
res = vkCreateImageView(dev, &view_info, NULL, &texture->image_view);
|
|
|
|
res = vkCreateImageView(dev, &view_info, NULL, &view->image_view);
|
|
|
|
if (res != VK_SUCCESS) {
|
|
|
|
if (res != VK_SUCCESS) {
|
|
|
|
|
|
|
|
free(view);
|
|
|
|
wlr_vk_error("vkCreateImageView failed", res);
|
|
|
|
wlr_vk_error("vkCreateImageView failed", res);
|
|
|
|
return false;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
texture->ds_pool = vulkan_alloc_texture_ds(texture->renderer, pipeline_layout->ds, &texture->ds);
|
|
|
|
view->ds_pool = vulkan_alloc_texture_ds(texture->renderer, pipeline_layout->ds, &view->ds);
|
|
|
|
if (!texture->ds_pool) {
|
|
|
|
if (!view->ds_pool) {
|
|
|
|
|
|
|
|
free(view);
|
|
|
|
wlr_log(WLR_ERROR, "failed to allocate descriptor");
|
|
|
|
wlr_log(WLR_ERROR, "failed to allocate descriptor");
|
|
|
|
return false;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VkDescriptorImageInfo ds_img_info = {
|
|
|
|
VkDescriptorImageInfo ds_img_info = {
|
|
|
|
.imageView = texture->image_view,
|
|
|
|
.imageView = view->image_view,
|
|
|
|
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
|
|
|
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
@ -338,13 +350,14 @@ static bool vulkan_texture_init_view(struct wlr_vk_texture *texture) {
|
|
|
|
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
|
|
|
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
|
|
|
.descriptorCount = 1,
|
|
|
|
.descriptorCount = 1,
|
|
|
|
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
|
|
|
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
|
|
|
.dstSet = texture->ds,
|
|
|
|
.dstSet = view->ds,
|
|
|
|
.pImageInfo = &ds_img_info,
|
|
|
|
.pImageInfo = &ds_img_info,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
vkUpdateDescriptorSets(dev, 1, &ds_write, 0, NULL);
|
|
|
|
vkUpdateDescriptorSets(dev, 1, &ds_write, 0, NULL);
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
wl_list_insert(&texture->views, &view->link);
|
|
|
|
|
|
|
|
return view;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static struct wlr_texture *vulkan_texture_from_pixels(
|
|
|
|
static struct wlr_texture *vulkan_texture_from_pixels(
|
|
|
@ -419,10 +432,6 @@ static struct wlr_texture *vulkan_texture_from_pixels(
|
|
|
|
goto error;
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!vulkan_texture_init_view(texture)) {
|
|
|
|
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pixman_region32_t region;
|
|
|
|
pixman_region32_t region;
|
|
|
|
pixman_region32_init_rect(®ion, 0, 0, width, height);
|
|
|
|
pixman_region32_init_rect(®ion, 0, 0, width, height);
|
|
|
|
if (!write_pixels(texture, stride, ®ion, data, VK_IMAGE_LAYOUT_UNDEFINED,
|
|
|
|
if (!write_pixels(texture, stride, ®ion, data, VK_IMAGE_LAYOUT_UNDEFINED,
|
|
|
@ -706,10 +715,6 @@ static struct wlr_vk_texture *vulkan_texture_from_dmabuf(
|
|
|
|
goto error;
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!vulkan_texture_init_view(texture)) {
|
|
|
|
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
texture->dmabuf_imported = true;
|
|
|
|
texture->dmabuf_imported = true;
|
|
|
|
|
|
|
|
|
|
|
|
return texture;
|
|
|
|
return texture;
|
|
|
|