diff --git a/include/render/vulkan.h b/include/render/vulkan.h index 25111fb6..f25d7cd5 100644 --- a/include/render/vulkan.h +++ b/include/render/vulkan.h @@ -123,7 +123,13 @@ const struct wlr_vk_format_modifier_props *vulkan_format_props_find_modifier( struct wlr_vk_format_props *props, uint64_t mod, bool render); void vulkan_format_props_finish(struct wlr_vk_format_props *props); +struct wlr_vk_pipeline_layout_key { + const struct wlr_vk_format *ycbcr_format; +}; + struct wlr_vk_pipeline_layout { + struct wlr_vk_pipeline_layout_key key; + VkPipelineLayout vk; VkDescriptorSetLayout ds; VkSampler sampler; @@ -133,6 +139,8 @@ struct wlr_vk_pipeline_layout { VkSamplerYcbcrConversion conversion; VkFormat format; } ycbcr; + + struct wl_list link; // struct wlr_vk_renderer.pipeline_layouts }; // Constants used to pick the color transform for the texture drawing @@ -148,8 +156,8 @@ enum wlr_vk_shader_source { }; struct wlr_vk_pipeline_key { + struct wlr_vk_pipeline_layout_key layout; enum wlr_vk_shader_source source; - struct wlr_vk_pipeline_layout *layout; enum wlr_render_blend_mode blend_mode; // only used if source is texture @@ -160,6 +168,7 @@ struct wlr_vk_pipeline { struct wlr_vk_pipeline_key key; VkPipeline vk; + const struct wlr_vk_pipeline_layout *layout; struct wlr_vk_render_format_setup *setup; struct wl_list link; // struct wlr_vk_render_format_setup }; @@ -168,7 +177,7 @@ struct wlr_vk_pipeline { // and therefore also separate pipelines. struct wlr_vk_render_format_setup { struct wl_list link; // wlr_vk_renderer.render_format_setups - VkFormat render_format; // used in renderpass + const struct wlr_vk_format *render_format; // used in renderpass VkRenderPass render_pass; VkPipeline output_pipe; @@ -228,9 +237,7 @@ struct wlr_vk_renderer { VkShaderModule quad_frag_module; VkShaderModule output_module; - struct wlr_vk_pipeline_layout default_pipeline_layout; - size_t ycbcr_pipeline_layouts_len; - struct wlr_vk_pipeline_layout *ycbcr_pipeline_layouts; + struct wl_list pipeline_layouts; // struct wlr_vk_pipeline_layout.link // for blend->output subpass VkPipelineLayout output_pipe_layout; @@ -291,6 +298,9 @@ struct wlr_vk_vert_pcr_data { struct wlr_vk_pipeline *setup_get_or_create_pipeline( struct wlr_vk_render_format_setup *setup, const struct wlr_vk_pipeline_key *key); +struct wlr_vk_pipeline_layout *get_or_create_pipeline_layout( + struct wlr_vk_renderer *renderer, + const struct wlr_vk_pipeline_layout_key *key); // Creates a vulkan renderer for the given device. struct wlr_renderer *vulkan_renderer_create_for_device(struct wlr_vk_device *dev); @@ -344,9 +354,6 @@ struct wlr_vk_format_props *vulkan_format_props_from_drm( struct wlr_vk_device *dev, uint32_t drm_format); struct wlr_vk_renderer *vulkan_get_renderer(struct wlr_renderer *r); -struct wlr_vk_pipeline_layout *vulkan_get_pipeline_layout(struct wlr_vk_renderer *renderer, - const struct wlr_vk_format *format); - struct wlr_vk_command_buffer *vulkan_acquire_command_buffer( struct wlr_vk_renderer *renderer); uint64_t vulkan_end_command_buffer(struct wlr_vk_command_buffer *cb, @@ -368,7 +375,6 @@ struct wlr_vk_texture { VkImage image; VkImageView image_view; const struct wlr_vk_format *format; - struct wlr_vk_pipeline_layout *pipeline_layout; enum wlr_vk_texture_transform transform; VkDescriptorSet ds; struct wlr_vk_descriptor_pool *ds_pool; diff --git a/render/vulkan/pass.c b/render/vulkan/pass.c index 9b060239..419f92e0 100644 --- a/render/vulkan/pass.c +++ b/render/vulkan/pass.c @@ -404,7 +404,6 @@ error: static void render_pass_add_rect(struct wlr_render_pass *wlr_pass, const struct wlr_render_rect_options *options) { struct wlr_vk_render_pass *pass = get_render_pass(wlr_pass); - struct wlr_vk_renderer *renderer = pass->renderer; VkCommandBuffer cb = pass->command_buffer->vk; // Input color values are given in sRGB space, shader expects @@ -436,7 +435,7 @@ static void render_pass_add_rect(struct wlr_render_pass *wlr_pass, pass->render_buffer->render_setup, &(struct wlr_vk_pipeline_key) { .source = WLR_VK_SHADER_SOURCE_SINGLE_COLOR, - .layout = &renderer->default_pipeline_layout, + .layout = { .ycbcr_format = NULL }, }); if (!pipe) { pass->failed = true; @@ -450,9 +449,9 @@ static void render_pass_add_rect(struct wlr_render_pass *wlr_pass, mat3_to_mat4(matrix, vert_pcr_data.mat4); bind_pipeline(pass, pipe->vk); - vkCmdPushConstants(cb, renderer->default_pipeline_layout.vk, + vkCmdPushConstants(cb, pipe->layout->vk, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(vert_pcr_data), &vert_pcr_data); - vkCmdPushConstants(cb, renderer->default_pipeline_layout.vk, + vkCmdPushConstants(cb, pipe->layout->vk, VK_SHADER_STAGE_FRAGMENT_BIT, sizeof(vert_pcr_data), sizeof(float) * 4, linear_color); @@ -546,21 +545,24 @@ static void render_pass_add_texture(struct wlr_render_pass *wlr_pass, render_buffer->render_setup, &(struct wlr_vk_pipeline_key) { .source = WLR_VK_SHADER_SOURCE_TEXTURE, - .layout = texture->pipeline_layout, + .layout = { + .ycbcr_format = texture->format->is_ycbcr ? texture->format : NULL, + }, .texture_transform = texture->transform, }); if (!pipe) { pass->failed = true; + return; } bind_pipeline(pass, pipe->vk); vkCmdBindDescriptorSets(cb, VK_PIPELINE_BIND_POINT_GRAPHICS, - pipe->key.layout->vk, 0, 1, &texture->ds, 0, NULL); + pipe->layout->vk, 0, 1, &texture->ds, 0, NULL); - vkCmdPushConstants(cb, pipe->key.layout->vk, + vkCmdPushConstants(cb, pipe->layout->vk, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(vert_pcr_data), &vert_pcr_data); - vkCmdPushConstants(cb, pipe->key.layout->vk, + vkCmdPushConstants(cb, pipe->layout->vk, VK_SHADER_STAGE_FRAGMENT_BIT, sizeof(vert_pcr_data), sizeof(float), &alpha); diff --git a/render/vulkan/renderer.c b/render/vulkan/renderer.c index 039f6ef7..57334af7 100644 --- a/render/vulkan/renderer.c +++ b/render/vulkan/renderer.c @@ -56,7 +56,8 @@ struct wlr_vk_renderer *vulkan_get_renderer(struct wlr_renderer *wlr_renderer) { } static struct wlr_vk_render_format_setup *find_or_create_render_setup( - struct wlr_vk_renderer *renderer, VkFormat format, bool has_blending_buffer); + struct wlr_vk_renderer *renderer, const struct wlr_vk_format *format, + bool has_blending_buffer); // https://www.w3.org/Graphics/Color/srgb static float color_to_linear(float non_linear) { @@ -793,7 +794,7 @@ static struct wlr_vk_render_buffer *create_render_buffer( bool has_blending_buffer = !fmt->format.is_srgb; buffer->render_setup = find_or_create_render_setup( - renderer, fmt->format.vk, has_blending_buffer); + renderer, &fmt->format, has_blending_buffer); if (!buffer->render_setup) { goto error; } @@ -1409,7 +1410,9 @@ static bool vulkan_render_subtexture_with_matrix(struct wlr_renderer *wlr_render struct wlr_vk_pipeline *pipe = setup_get_or_create_pipeline( renderer->current_render_buffer->render_setup, &(struct wlr_vk_pipeline_key) { - .layout = texture->pipeline_layout, + .layout = { + .ycbcr_format = texture->format->is_ycbcr ? texture->format : NULL, + }, .texture_transform = texture->transform, }); if (!pipe) { @@ -1422,7 +1425,7 @@ static bool vulkan_render_subtexture_with_matrix(struct wlr_renderer *wlr_render } vkCmdBindDescriptorSets(cb, VK_PIPELINE_BIND_POINT_GRAPHICS, - pipe->key.layout->vk, 0, 1, &texture->ds, 0, NULL); + pipe->layout->vk, 0, 1, &texture->ds, 0, NULL); float final_matrix[9]; wlr_matrix_multiply(final_matrix, renderer->projection, matrix); @@ -1435,9 +1438,9 @@ static bool vulkan_render_subtexture_with_matrix(struct wlr_renderer *wlr_render vert_pcr_data.uv_size[0] = box->width / wlr_texture->width; vert_pcr_data.uv_size[1] = box->height / wlr_texture->height; - vkCmdPushConstants(cb, pipe->key.layout->vk, + vkCmdPushConstants(cb, pipe->layout->vk, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(vert_pcr_data), &vert_pcr_data); - vkCmdPushConstants(cb, pipe->key.layout->vk, + vkCmdPushConstants(cb, pipe->layout->vk, VK_SHADER_STAGE_FRAGMENT_BIT, sizeof(vert_pcr_data), sizeof(float), &alpha); vkCmdDraw(cb, 4, 1, 0, 0); @@ -1512,7 +1515,9 @@ static void vulkan_render_quad_with_matrix(struct wlr_renderer *wlr_renderer, renderer->current_render_buffer->render_setup, &(struct wlr_vk_pipeline_key) { .source = WLR_VK_SHADER_SOURCE_SINGLE_COLOR, - .layout = &renderer->default_pipeline_layout, + .layout = { + .ycbcr_format = NULL, + }, }); if (!pipe) { return; @@ -1546,9 +1551,9 @@ static void vulkan_render_quad_with_matrix(struct wlr_renderer *wlr_renderer, linear_color[2] = color_to_linear(color[2]); linear_color[3] = color[3]; // no conversion for alpha - vkCmdPushConstants(cb, renderer->default_pipeline_layout.vk, + vkCmdPushConstants(cb, pipe->layout->vk, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(vert_pcr_data), &vert_pcr_data); - vkCmdPushConstants(cb, renderer->default_pipeline_layout.vk, + vkCmdPushConstants(cb, pipe->layout->vk, VK_SHADER_STAGE_FRAGMENT_BIT, sizeof(vert_pcr_data), sizeof(float) * 4, linear_color); vkCmdDraw(cb, 4, 1, 0, 0); @@ -1578,15 +1583,6 @@ static uint32_t vulkan_preferred_read_format( return dmabuf.format; } -static void finish_pipeline_layout(struct wlr_vk_renderer *renderer, - struct wlr_vk_pipeline_layout *pipeline_layout) { - struct wlr_vk_device *dev = renderer->dev; - vkDestroyPipelineLayout(dev->dev, pipeline_layout->vk, NULL); - vkDestroyDescriptorSetLayout(dev->dev, pipeline_layout->ds, NULL); - vkDestroySampler(dev->dev, pipeline_layout->sampler, NULL); - vkDestroySamplerYcbcrConversion(dev->dev, pipeline_layout->ycbcr.conversion, NULL); -} - static void vulkan_destroy(struct wlr_renderer *wlr_renderer) { struct wlr_vk_renderer *renderer = vulkan_get_renderer(wlr_renderer); struct wlr_vk_device *dev = renderer->dev; @@ -1651,11 +1647,14 @@ static void vulkan_destroy(struct wlr_renderer *wlr_renderer) { vkDestroyShaderModule(dev->dev, renderer->quad_frag_module, NULL); vkDestroyShaderModule(dev->dev, renderer->output_module, NULL); - finish_pipeline_layout(renderer, &renderer->default_pipeline_layout); - for (size_t i = 0; i < renderer->ycbcr_pipeline_layouts_len; i++) { - finish_pipeline_layout(renderer, &renderer->ycbcr_pipeline_layouts[i]); + struct wlr_vk_pipeline_layout *pipeline_layout, *pipeline_layout_tmp; + wl_list_for_each_safe(pipeline_layout, pipeline_layout_tmp, + &renderer->pipeline_layouts, link) { + vkDestroyPipelineLayout(dev->dev, pipeline_layout->vk, NULL); + vkDestroyDescriptorSetLayout(dev->dev, pipeline_layout->ds, NULL); + vkDestroySampler(dev->dev, pipeline_layout->sampler, NULL); + vkDestroySamplerYcbcrConversion(dev->dev, pipeline_layout->ycbcr.conversion, NULL); } - free(renderer->ycbcr_pipeline_layouts); vkDestroySemaphore(dev->dev, renderer->timeline_semaphore, NULL); vkDestroyPipelineLayout(dev->dev, renderer->output_pipe_layout, NULL); @@ -1698,7 +1697,7 @@ static bool vulkan_read_pixels(struct wlr_renderer *wlr_renderer, return false; } VkFormat dst_format = wlr_vk_format->vk; - VkFormat src_format = vk_renderer->current_render_buffer->render_setup->render_format; + VkFormat src_format = vk_renderer->current_render_buffer->render_setup->render_format->vk; VkFormatProperties dst_format_props = {0}, src_format_props = {0}; vkGetPhysicalDeviceFormatProperties(vk_renderer->dev->phdev, dst_format, &dst_format_props); vkGetPhysicalDeviceFormatProperties(vk_renderer->dev->phdev, src_format, &src_format_props); @@ -2094,9 +2093,22 @@ static bool init_blend_to_output_layouts(struct wlr_vk_renderer *renderer, return true; } +static bool pipeline_layout_key_equals( + const struct wlr_vk_pipeline_layout_key *a, + const struct wlr_vk_pipeline_layout_key *b) { + assert(!a->ycbcr_format || a->ycbcr_format->is_ycbcr); + assert(!b->ycbcr_format || b->ycbcr_format->is_ycbcr); + + if (a->ycbcr_format != b->ycbcr_format) { + return false; + } + + return true; +} + static bool pipeline_key_equals(const struct wlr_vk_pipeline_key *a, const struct wlr_vk_pipeline_key *b) { - if (a->layout != b->layout) { + if (!pipeline_layout_key_equals(&a->layout, &b->layout)) { return false; } @@ -2128,15 +2140,22 @@ struct wlr_vk_pipeline *setup_get_or_create_pipeline( } } + struct wlr_vk_renderer *renderer = setup->renderer; + + struct wlr_vk_pipeline_layout *pipeline_layout = get_or_create_pipeline_layout( + renderer, &key->layout); + if (!pipeline_layout) { + return NULL; + } + pipeline = calloc(1, sizeof(*pipeline)); if (!pipeline) { return NULL; } - struct wlr_vk_renderer *renderer = setup->renderer; - pipeline->setup = setup; pipeline->key = *key; + pipeline->layout = pipeline_layout; VkResult res; VkDevice dev = renderer->dev->dev; @@ -2246,7 +2265,7 @@ struct wlr_vk_pipeline *setup_get_or_create_pipeline( VkGraphicsPipelineCreateInfo pinfo = { .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, - .layout = key->layout->vk, + .layout = pipeline_layout->vk, .renderPass = setup->render_pass, .subpass = 0, .stageCount = 2, @@ -2386,31 +2405,51 @@ static bool init_pipeline_layout(struct wlr_vk_renderer *renderer, return true; } -static bool init_ycbcr_pipeline_layout(struct wlr_vk_renderer *renderer, - struct wlr_vk_pipeline_layout *pipeline_layout, - const struct wlr_vk_format *format) { +struct wlr_vk_pipeline_layout *get_or_create_pipeline_layout( + struct wlr_vk_renderer *renderer, + const struct wlr_vk_pipeline_layout_key *key) { + struct wlr_vk_pipeline_layout *pipeline_layout; + wl_list_for_each(pipeline_layout, &renderer->pipeline_layouts, link) { + if (pipeline_layout_key_equals(&pipeline_layout->key, key)) { + return pipeline_layout; + } + } + + pipeline_layout = calloc(1, sizeof(*pipeline_layout)); + if (!pipeline_layout) { + return NULL; + } + + pipeline_layout->key = *key; + VkResult res; - assert(format->is_ycbcr); - pipeline_layout->ycbcr.format = format->vk; + if (key->ycbcr_format) { + VkSamplerYcbcrConversionCreateInfo conversion_create_info = { + .sType = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO, + .format = key->ycbcr_format->vk, + .ycbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601, + .ycbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_NARROW, + .xChromaOffset = VK_CHROMA_LOCATION_MIDPOINT, + .yChromaOffset = VK_CHROMA_LOCATION_MIDPOINT, + .chromaFilter = VK_FILTER_LINEAR, + }; + res = vkCreateSamplerYcbcrConversion(renderer->dev->dev, + &conversion_create_info, NULL, &pipeline_layout->ycbcr.conversion); + if (res != VK_SUCCESS) { + wlr_vk_error("vkCreateSamplerYcbcrConversion", res); + free(pipeline_layout); + return NULL; + } + } - VkSamplerYcbcrConversionCreateInfo conversion_create_info = { - .sType = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO, - .format = format->vk, - .ycbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601, - .ycbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_NARROW, - .xChromaOffset = VK_CHROMA_LOCATION_MIDPOINT, - .yChromaOffset = VK_CHROMA_LOCATION_MIDPOINT, - .chromaFilter = VK_FILTER_LINEAR, - }; - res = vkCreateSamplerYcbcrConversion(renderer->dev->dev, - &conversion_create_info, NULL, &pipeline_layout->ycbcr.conversion); - if (res != VK_SUCCESS) { - wlr_vk_error("vkCreateSamplerYcbcrConversion", res); - return false; + if (!init_pipeline_layout(renderer, pipeline_layout)) { + free(pipeline_layout); + return NULL; } - return init_pipeline_layout(renderer, pipeline_layout); + wl_list_insert(&renderer->pipeline_layouts, &pipeline_layout->link); + return pipeline_layout; } // Creates static render data, such as sampler, layouts and shader modules @@ -2420,41 +2459,6 @@ static bool init_static_render_data(struct wlr_vk_renderer *renderer) { VkResult res; VkDevice dev = renderer->dev->dev; - if (!init_pipeline_layout(renderer, &renderer->default_pipeline_layout)) { - return false; - } - - size_t ycbcr_formats_len = 0; - for (size_t i = 0; i < renderer->dev->format_prop_count; i++) { - struct wlr_vk_format_props *props = &renderer->dev->format_props[i]; - if (renderer->dev->sampler_ycbcr_conversion && props->format.is_ycbcr) { - ycbcr_formats_len++; - } - } - - if (ycbcr_formats_len > 0) { - renderer->ycbcr_pipeline_layouts = - calloc(ycbcr_formats_len, sizeof(*renderer->ycbcr_pipeline_layouts)); - if (renderer->ycbcr_pipeline_layouts == NULL) { - return false; - } - - for (size_t i = 0; i < renderer->dev->format_prop_count; i++) { - const struct wlr_vk_format *format = &renderer->dev->format_props[i].format; - if (!format->is_ycbcr) { - continue; - } - - struct wlr_vk_pipeline_layout *pl = - &renderer->ycbcr_pipeline_layouts[renderer->ycbcr_pipeline_layouts_len]; - if (!init_ycbcr_pipeline_layout(renderer, pl, format)) { - return false; - } - - renderer->ycbcr_pipeline_layouts_len++; - } - } - if (!init_blend_to_output_layouts(renderer, &renderer->output_ds_layout, &renderer->output_pipe_layout)) { return false; @@ -2510,7 +2514,8 @@ static bool init_static_render_data(struct wlr_vk_renderer *renderer) { } static struct wlr_vk_render_format_setup *find_or_create_render_setup( - struct wlr_vk_renderer *renderer, VkFormat format, bool has_blending_buffer) { + struct wlr_vk_renderer *renderer, const struct wlr_vk_format *format, + bool has_blending_buffer) { struct wlr_vk_render_format_setup *setup; wl_list_for_each(setup, &renderer->render_format_setups, link) { if (setup->render_format == format) { @@ -2544,7 +2549,7 @@ static struct wlr_vk_render_format_setup *find_or_create_render_setup( .finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, }, { - .format = format, + .format = format->vk, .samples = VK_SAMPLE_COUNT_1_BIT, .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, .storeOp = VK_ATTACHMENT_STORE_OP_STORE, @@ -2649,7 +2654,7 @@ static struct wlr_vk_render_format_setup *find_or_create_render_setup( } } else { VkAttachmentDescription attachment = { - .format = format, + .format = format->vk, .samples = VK_SAMPLE_COUNT_1_BIT, .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, .storeOp = VK_ATTACHMENT_STORE_OP_STORE, @@ -2718,7 +2723,7 @@ static struct wlr_vk_render_format_setup *find_or_create_render_setup( if (!setup_get_or_create_pipeline(setup, &(struct wlr_vk_pipeline_key){ .source = WLR_VK_SHADER_SOURCE_SINGLE_COLOR, - .layout = &renderer->default_pipeline_layout, + .layout = { .ycbcr_format = NULL }, })) { goto error; } @@ -2726,7 +2731,7 @@ static struct wlr_vk_render_format_setup *find_or_create_render_setup( if (!setup_get_or_create_pipeline(setup, &(struct wlr_vk_pipeline_key){ .source = WLR_VK_SHADER_SOURCE_TEXTURE, .texture_transform = WLR_VK_TEXTURE_TRANSFORM_IDENTITY, - .layout = &renderer->default_pipeline_layout, + .layout = {.ycbcr_format = NULL }, })) { goto error; } @@ -2734,18 +2739,24 @@ static struct wlr_vk_render_format_setup *find_or_create_render_setup( if (!setup_get_or_create_pipeline(setup, &(struct wlr_vk_pipeline_key){ .source = WLR_VK_SHADER_SOURCE_TEXTURE, .texture_transform = WLR_VK_TEXTURE_TRANSFORM_SRGB, - .layout = &renderer->default_pipeline_layout, + .layout = {.ycbcr_format = NULL }, })) { goto error; } - for (size_t i = 0; i < renderer->ycbcr_pipeline_layouts_len; i++) { - if (!setup_get_or_create_pipeline(setup, &(struct wlr_vk_pipeline_key){ - .source = WLR_VK_SHADER_SOURCE_TEXTURE, - .texture_transform = WLR_VK_TEXTURE_TRANSFORM_SRGB, - .layout = &renderer->ycbcr_pipeline_layouts[i], - })) { - goto error; + for (size_t i = 0; i < renderer->dev->format_prop_count; i++) { + const struct wlr_vk_format *format = &renderer->dev->format_props[i].format; + const struct wlr_vk_pipeline_layout_key layout = { + .ycbcr_format = format, + }; + + if (format->is_ycbcr) { + if (!setup_get_or_create_pipeline(setup, &(struct wlr_vk_pipeline_key){ + .texture_transform = WLR_VK_TEXTURE_TRANSFORM_SRGB, + .layout = layout + })) { + goto error; + } } } @@ -2774,6 +2785,7 @@ struct wlr_renderer *vulkan_renderer_create_for_device(struct wlr_vk_device *dev wl_list_init(&renderer->output_descriptor_pools); wl_list_init(&renderer->render_format_setups); wl_list_init(&renderer->render_buffers); + wl_list_init(&renderer->pipeline_layouts); if (!init_static_render_data(renderer)) { goto error; @@ -2858,26 +2870,6 @@ struct wlr_renderer *wlr_vk_renderer_create_with_drm_fd(int drm_fd) { return vulkan_renderer_create_for_device(dev); } -struct wlr_vk_pipeline_layout *vulkan_get_pipeline_layout(struct wlr_vk_renderer *renderer, - const struct wlr_vk_format *format) { - if (!format->is_ycbcr) { - return &renderer->default_pipeline_layout; - } - - for (size_t i = 0; i < renderer->ycbcr_pipeline_layouts_len; i++) { - struct wlr_vk_pipeline_layout *pl = &renderer->ycbcr_pipeline_layouts[i]; - if (pl->ycbcr.format == format->vk) { - return pl; - } - } - - char *name = drmGetFormatName(format->drm); - wlr_log(WLR_ERROR, "No pipeline layout found for format %s (0x%08"PRIX32")", - name, format->drm); - free(name); - return NULL; -} - VkInstance wlr_vk_renderer_get_instance(struct wlr_renderer *renderer) { struct wlr_vk_renderer *vk_renderer = vulkan_get_renderer(renderer); return vk_renderer->dev->instance->instance; @@ -2902,6 +2894,6 @@ void wlr_vk_renderer_get_current_image_attribs(struct wlr_renderer *renderer, struct wlr_vk_image_attribs *attribs) { struct wlr_vk_renderer *vk_renderer = vulkan_get_renderer(renderer); attribs->image = vk_renderer->current_render_buffer->image; - attribs->format = vk_renderer->current_render_buffer->render_setup->render_format; + attribs->format = vk_renderer->current_render_buffer->render_setup->render_format->vk; attribs->layout = VK_IMAGE_LAYOUT_UNDEFINED; } diff --git a/render/vulkan/texture.c b/render/vulkan/texture.c index c1a4b7bb..f6252c2b 100644 --- a/render/vulkan/texture.c +++ b/render/vulkan/texture.c @@ -269,6 +269,15 @@ static bool vulkan_texture_init_view(struct wlr_vk_texture *texture) { VkResult res; VkDevice dev = texture->renderer->dev->dev; + 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"); + return NULL; + } + const struct wlr_pixel_format_info *format_info = drm_get_pixel_format_info(texture->format->drm); if (format_info != NULL) { @@ -300,10 +309,10 @@ static bool vulkan_texture_init_view(struct wlr_vk_texture *texture) { VkSamplerYcbcrConversionInfo ycbcr_conversion_info; if (texture->format->is_ycbcr) { - assert(texture->pipeline_layout->ycbcr.conversion != VK_NULL_HANDLE); + assert(pipeline_layout->ycbcr.conversion != VK_NULL_HANDLE); ycbcr_conversion_info = (VkSamplerYcbcrConversionInfo){ .sType = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO, - .conversion = texture->pipeline_layout->ycbcr.conversion, + .conversion = pipeline_layout->ycbcr.conversion, }; view_info.pNext = &ycbcr_conversion_info; } @@ -314,7 +323,7 @@ static bool vulkan_texture_init_view(struct wlr_vk_texture *texture) { return false; } - texture->ds_pool = vulkan_alloc_texture_ds(texture->renderer, texture->pipeline_layout->ds, &texture->ds); + texture->ds_pool = vulkan_alloc_texture_ds(texture->renderer, pipeline_layout->ds, &texture->ds); if (!texture->ds_pool) { wlr_log(WLR_ERROR, "failed to allocate descriptor"); return false; @@ -360,7 +369,6 @@ static struct wlr_texture *vulkan_texture_from_pixels( } texture->format = &fmt->format; - texture->pipeline_layout = &renderer->default_pipeline_layout; VkImageCreateInfo img_info = { .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, @@ -692,11 +700,6 @@ static struct wlr_vk_texture *vulkan_texture_from_dmabuf( texture->transform = !texture->format->is_ycbcr && texture->format->is_srgb ? WLR_VK_TEXTURE_TRANSFORM_IDENTITY : WLR_VK_TEXTURE_TRANSFORM_SRGB; - texture->pipeline_layout = vulkan_get_pipeline_layout(renderer, texture->format); - if (texture->pipeline_layout == NULL) { - goto error; - } - texture->image = vulkan_import_dmabuf(renderer, attribs, texture->memories, &texture->mem_count, false); if (!texture->image) {