diff options
author | Alexander Orzechowski <alex@ozal.ski> | 2023-06-16 20:10:01 -0400 |
---|---|---|
committer | Alexander Orzechowski <alex@ozal.ski> | 2023-06-17 21:21:35 -0400 |
commit | 3ee0f52e09d422b497434f724b9c2e1606c02bea (patch) | |
tree | b905940fb8650f8d0fa1a748416f51c56ef8a4d7 /render/vulkan | |
parent | 7c5a3afd607210263e1199ad8f3d05c154a76356 (diff) |
render/vulkan: Dynamically create texture views
Now that we are dynamically creating pipeline layouts, we need separate
texture views for each pipeline layout we choose to use with a texture.
Diffstat (limited to 'render/vulkan')
-rw-r--r-- | render/vulkan/pass.c | 9 | ||||
-rw-r--r-- | render/vulkan/renderer.c | 8 | ||||
-rw-r--r-- | render/vulkan/texture.c | 61 |
3 files changed, 48 insertions, 30 deletions
diff --git a/render/vulkan/pass.c b/render/vulkan/pass.c index 419f92e0..acc2a5ae 100644 --- a/render/vulkan/pass.c +++ b/render/vulkan/pass.c @@ -555,10 +555,17 @@ static void render_pass_add_texture(struct wlr_render_pass *wlr_pass, return; } + struct wlr_vk_texture_view *view = + vulkan_texture_get_or_create_view(texture, pipe->layout); + if (!view) { + pass->failed = true; + return; + } + bind_pipeline(pass, pipe->vk); vkCmdBindDescriptorSets(cb, VK_PIPELINE_BIND_POINT_GRAPHICS, - pipe->layout->vk, 0, 1, &texture->ds, 0, NULL); + pipe->layout->vk, 0, 1, &view->ds, 0, NULL); vkCmdPushConstants(cb, pipe->layout->vk, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(vert_pcr_data), &vert_pcr_data); diff --git a/render/vulkan/renderer.c b/render/vulkan/renderer.c index 8917f540..205f40ad 100644 --- a/render/vulkan/renderer.c +++ b/render/vulkan/renderer.c @@ -1419,13 +1419,19 @@ static bool vulkan_render_subtexture_with_matrix(struct wlr_renderer *wlr_render return false; } + struct wlr_vk_texture_view *view = + vulkan_texture_get_or_create_view(texture, pipe->layout); + if (!view) { + return false; + } + if (pipe->vk != renderer->bound_pipe) { vkCmdBindPipeline(cb, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe->vk); renderer->bound_pipe = pipe->vk; } vkCmdBindDescriptorSets(cb, VK_PIPELINE_BIND_POINT_GRAPHICS, - pipe->layout->vk, 0, 1, &texture->ds, 0, NULL); + pipe->layout->vk, 0, 1, &view->ds, 0, NULL); float final_matrix[9]; wlr_matrix_multiply(final_matrix, renderer->projection, matrix); diff --git a/render/vulkan/texture.c b/render/vulkan/texture.c index f6252c2b..15e6f601 100644 --- a/render/vulkan/texture.c +++ b/render/vulkan/texture.c @@ -214,8 +214,12 @@ void vulkan_texture_destroy(struct wlr_vk_texture *texture) { wl_list_remove(&texture->link); 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++) { @@ -224,7 +228,6 @@ void vulkan_texture_destroy(struct wlr_vk_texture *texture) { } } - vkDestroyImageView(dev, texture->image_view, NULL); vkDestroyImage(dev, texture->image, NULL); 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->renderer = renderer; wl_list_insert(&renderer->textures, &texture->link); + wl_list_init(&texture->views); return texture; } -static bool vulkan_texture_init_view(struct wlr_vk_texture *texture) { - VkResult res; - VkDevice dev = texture->renderer->dev->dev; +struct wlr_vk_texture_view *vulkan_texture_get_or_create_view(struct wlr_vk_texture *texture, + const struct wlr_vk_pipeline_layout *pipeline_layout) { + 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( - texture->renderer, &(struct wlr_vk_pipeline_layout_key) { - .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"); + view = calloc(1, sizeof(*view)); + if (!view) { return NULL; } + view->layout = pipeline_layout; + + VkResult res; + VkDevice dev = texture->renderer->dev->dev; + const struct wlr_pixel_format_info *format_info = drm_get_pixel_format_info(texture->format->drm); 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; } - res = vkCreateImageView(dev, &view_info, NULL, &texture->image_view); + res = vkCreateImageView(dev, &view_info, NULL, &view->image_view); if (res != VK_SUCCESS) { + free(view); wlr_vk_error("vkCreateImageView failed", res); - return false; + return NULL; } - texture->ds_pool = vulkan_alloc_texture_ds(texture->renderer, pipeline_layout->ds, &texture->ds); - if (!texture->ds_pool) { + view->ds_pool = vulkan_alloc_texture_ds(texture->renderer, pipeline_layout->ds, &view->ds); + if (!view->ds_pool) { + free(view); wlr_log(WLR_ERROR, "failed to allocate descriptor"); - return false; + return NULL; } VkDescriptorImageInfo ds_img_info = { - .imageView = texture->image_view, + .imageView = view->image_view, .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, .descriptorCount = 1, .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - .dstSet = texture->ds, + .dstSet = view->ds, .pImageInfo = &ds_img_info, }; 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( @@ -419,10 +432,6 @@ static struct wlr_texture *vulkan_texture_from_pixels( goto error; } - if (!vulkan_texture_init_view(texture)) { - goto error; - } - pixman_region32_t region; pixman_region32_init_rect(®ion, 0, 0, width, height); 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; } - if (!vulkan_texture_init_view(texture)) { - goto error; - } - texture->dmabuf_imported = true; return texture; |