|
|
|
@ -87,7 +87,8 @@ static void mat3_to_mat4(const float mat3[9], float mat4[4][4]) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct wlr_vk_descriptor_pool *vulkan_alloc_texture_ds(
|
|
|
|
|
struct wlr_vk_renderer *renderer, VkDescriptorSet *ds) {
|
|
|
|
|
struct wlr_vk_renderer *renderer, VkDescriptorSetLayout ds_layout,
|
|
|
|
|
VkDescriptorSet *ds) {
|
|
|
|
|
VkResult res;
|
|
|
|
|
|
|
|
|
|
bool found = false;
|
|
|
|
@ -139,7 +140,7 @@ struct wlr_vk_descriptor_pool *vulkan_alloc_texture_ds(
|
|
|
|
|
VkDescriptorSetAllocateInfo ds_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
|
|
|
|
|
.descriptorSetCount = 1,
|
|
|
|
|
.pSetLayouts = &renderer->ds_layout,
|
|
|
|
|
.pSetLayouts = &ds_layout,
|
|
|
|
|
.descriptorPool = pool->pool,
|
|
|
|
|
};
|
|
|
|
|
res = vkAllocateDescriptorSets(renderer->dev->dev, &ds_info, ds);
|
|
|
|
@ -168,6 +169,7 @@ static void destroy_render_format_setup(struct wlr_vk_renderer *renderer,
|
|
|
|
|
vkDestroyRenderPass(dev, setup->render_pass, NULL);
|
|
|
|
|
vkDestroyPipeline(dev, setup->tex_identity_pipe, NULL);
|
|
|
|
|
vkDestroyPipeline(dev, setup->tex_srgb_pipe, NULL);
|
|
|
|
|
vkDestroyPipeline(dev, setup->tex_nv12_pipe, NULL);
|
|
|
|
|
vkDestroyPipeline(dev, setup->quad_pipe, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1182,11 +1184,14 @@ static bool vulkan_render_subtexture_with_matrix(struct wlr_renderer *wlr_render
|
|
|
|
|
|
|
|
|
|
VkPipeline pipe;
|
|
|
|
|
// SRGB formats already have the transfer function applied
|
|
|
|
|
if (texture->format->is_srgb) {
|
|
|
|
|
if (texture->format->drm == DRM_FORMAT_NV12) {
|
|
|
|
|
pipe = renderer->current_render_buffer->render_setup->tex_nv12_pipe;
|
|
|
|
|
} else if (texture->format->is_srgb) {
|
|
|
|
|
pipe = renderer->current_render_buffer->render_setup->tex_identity_pipe;
|
|
|
|
|
} else {
|
|
|
|
|
pipe = renderer->current_render_buffer->render_setup->tex_srgb_pipe;
|
|
|
|
|
}
|
|
|
|
|
assert(pipe != VK_NULL_HANDLE);
|
|
|
|
|
if (pipe != renderer->bound_pipe) {
|
|
|
|
|
vkCmdBindPipeline(cb, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
|
|
|
|
|
renderer->bound_pipe = pipe;
|
|
|
|
@ -1403,6 +1408,7 @@ static void vulkan_destroy(struct wlr_renderer *wlr_renderer) {
|
|
|
|
|
vkDestroyPipelineLayout(dev->dev, renderer->pipe_layout, NULL);
|
|
|
|
|
vkDestroyDescriptorSetLayout(dev->dev, renderer->ds_layout, NULL);
|
|
|
|
|
vkDestroySampler(dev->dev, renderer->sampler, NULL);
|
|
|
|
|
vkDestroySamplerYcbcrConversion(dev->dev, renderer->nv12_conversion, NULL);
|
|
|
|
|
vkDestroyCommandPool(dev->dev, renderer->command_pool, NULL);
|
|
|
|
|
|
|
|
|
|
if (renderer->read_pixels_cache.initialized) {
|
|
|
|
@ -1671,6 +1677,47 @@ static const struct wlr_renderer_impl renderer_impl = {
|
|
|
|
|
.texture_from_buffer = vulkan_texture_from_buffer,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static bool init_nv12_sampler(struct wlr_vk_renderer *renderer, VkSampler *sampler) {
|
|
|
|
|
VkResult res;
|
|
|
|
|
|
|
|
|
|
VkSamplerYcbcrConversionCreateInfo conversion_create_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO,
|
|
|
|
|
.format = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
|
|
|
|
|
.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, &renderer->nv12_conversion);
|
|
|
|
|
if (res != VK_SUCCESS) {
|
|
|
|
|
wlr_vk_error("vkCreateSamplerYcbcrConversion", res);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkSamplerYcbcrConversionInfo conversion_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO,
|
|
|
|
|
.conversion = renderer->nv12_conversion,
|
|
|
|
|
};
|
|
|
|
|
VkSamplerCreateInfo sampler_create_info = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
|
|
|
|
|
.pNext = &conversion_info,
|
|
|
|
|
.magFilter = VK_FILTER_LINEAR,
|
|
|
|
|
.minFilter = VK_FILTER_LINEAR,
|
|
|
|
|
.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
|
|
|
|
|
.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
|
|
|
|
|
.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
|
|
|
|
|
.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK,
|
|
|
|
|
};
|
|
|
|
|
res = vkCreateSampler(renderer->dev->dev, &sampler_create_info, NULL, sampler);
|
|
|
|
|
if (res != VK_SUCCESS) {
|
|
|
|
|
wlr_vk_error("vkCreateSampler", res);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Initializes the VkDescriptorSetLayout and VkPipelineLayout needed
|
|
|
|
|
// for the texture rendering pipeline using the given VkSampler.
|
|
|
|
|
static bool init_tex_layouts(struct wlr_vk_renderer *renderer,
|
|
|
|
@ -1889,10 +1936,18 @@ static bool init_static_render_data(struct wlr_vk_renderer *renderer) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (renderer->dev->sampler_ycbcr_conversion && !init_nv12_sampler(renderer, &renderer->nv12_sampler)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!init_tex_layouts(renderer, renderer->sampler,
|
|
|
|
|
&renderer->ds_layout, &renderer->pipe_layout)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if (renderer->dev->sampler_ycbcr_conversion && !init_tex_layouts(renderer, renderer->nv12_sampler,
|
|
|
|
|
&renderer->nv12_ds_layout, &renderer->nv12_pipe_layout)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// load vert module and tex frag module since they are needed to
|
|
|
|
|
// initialize the tex pipeline
|
|
|
|
@ -2033,6 +2088,12 @@ static struct wlr_vk_render_format_setup *find_or_create_render_setup(
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (renderer->dev->sampler_ycbcr_conversion && !init_tex_pipeline(renderer,
|
|
|
|
|
setup->render_pass, renderer->nv12_pipe_layout,
|
|
|
|
|
WLR_VK_TEXTURE_TRANSFORM_SRGB, &setup->tex_nv12_pipe)) {
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkPipelineShaderStageCreateInfo quad_stages[2] = {
|
|
|
|
|
{
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
|
|
|
|