mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-09 10:20:07 +00:00
gpu: Completely revamp YCbCr handling
There is now a GskGpuYcbcr struct that maintains all the Vulkan machinery related to YCbCrConversions. It's a GskGpuCached, so it will make itself go away when it is no longer used, ie a video stopped playing.
This commit is contained in:
parent
762b981dfe
commit
67b9fb43d0
@ -96,7 +96,9 @@ gsk_gpu_shader_op_vk_command_n (GskGpuOp *op,
|
||||
n_ops += next_shader->n_ops;
|
||||
}
|
||||
|
||||
vk_pipeline_layout = gsk_vulkan_device_get_default_vk_pipeline_layout (GSK_VULKAN_DEVICE (gsk_gpu_frame_get_device (frame)));
|
||||
vk_pipeline_layout = gsk_vulkan_device_get_vk_pipeline_layout (GSK_VULKAN_DEVICE (gsk_gpu_frame_get_device (frame)),
|
||||
shader_op_class->n_textures > 0 ? gsk_vulkan_image_get_ycbcr (GSK_VULKAN_IMAGE (self->images[0])) : NULL,
|
||||
shader_op_class->n_textures > 1 ? gsk_vulkan_image_get_ycbcr (GSK_VULKAN_IMAGE (self->images[1])) : NULL);
|
||||
|
||||
for (i = 0; i < shader_op_class->n_textures; i++)
|
||||
{
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "gskgpushaderopprivate.h"
|
||||
#include "gskvulkanbufferprivate.h"
|
||||
#include "gskvulkanimageprivate.h"
|
||||
#include "gskvulkanycbcrprivate.h"
|
||||
|
||||
#include "gdk/gdkdisplayprivate.h"
|
||||
#include "gdk/gdkvulkancontextprivate.h"
|
||||
@ -19,7 +20,7 @@ struct _GskVulkanDevice
|
||||
GskVulkanAllocator *external_allocator;
|
||||
GdkVulkanFeatures features;
|
||||
|
||||
GHashTable *conversion_cache;
|
||||
GHashTable *ycbcr_cache;
|
||||
GHashTable *render_pass_cache;
|
||||
GHashTable *pipeline_cache;
|
||||
|
||||
@ -70,24 +71,6 @@ struct _RenderPassCacheKey
|
||||
VkRenderPass render_pass;
|
||||
};
|
||||
|
||||
static guint
|
||||
conversion_cache_entry_hash (gconstpointer data)
|
||||
{
|
||||
const ConversionCacheEntry *key = data;
|
||||
|
||||
return key->vk_format;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
conversion_cache_entry_equal (gconstpointer a,
|
||||
gconstpointer b)
|
||||
{
|
||||
const ConversionCacheEntry *keya = a;
|
||||
const ConversionCacheEntry *keyb = b;
|
||||
|
||||
return keya->vk_format == keyb->vk_format;
|
||||
}
|
||||
|
||||
static guint
|
||||
pipeline_cache_key_hash (gconstpointer data)
|
||||
{
|
||||
@ -141,8 +124,7 @@ render_pass_cache_key_equal (gconstpointer a,
|
||||
}
|
||||
|
||||
static VkDescriptorSetLayout
|
||||
gsk_vulkan_device_create_vk_image_set_layout (GskVulkanDevice *self,
|
||||
VkSampler immutable_sampler)
|
||||
gsk_vulkan_device_create_vk_image_set_layout (GskVulkanDevice *self)
|
||||
{
|
||||
VkDevice vk_device;
|
||||
VkDescriptorSetLayout result;
|
||||
@ -160,9 +142,6 @@ gsk_vulkan_device_create_vk_image_set_layout (GskVulkanDevice *self,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||
.descriptorCount = 1,
|
||||
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
.pImmutableSamplers = immutable_sampler == VK_NULL_HANDLE ? NULL : (VkSampler[1]) {
|
||||
immutable_sampler,
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
@ -172,7 +151,7 @@ gsk_vulkan_device_create_vk_image_set_layout (GskVulkanDevice *self,
|
||||
return result;
|
||||
}
|
||||
|
||||
static VkPipelineLayout
|
||||
VkPipelineLayout
|
||||
gsk_vulkan_device_create_vk_pipeline_layout (GskVulkanDevice *self,
|
||||
VkDescriptorSetLayout image1_layout,
|
||||
VkDescriptorSetLayout image2_layout)
|
||||
@ -302,6 +281,9 @@ gsk_vulkan_device_finalize (GObject *object)
|
||||
|
||||
g_object_steal_data (G_OBJECT (display), "-gsk-vulkan-device");
|
||||
|
||||
g_assert (g_hash_table_size (self->ycbcr_cache) == 0);
|
||||
g_hash_table_unref (self->ycbcr_cache);
|
||||
|
||||
g_hash_table_iter_init (&iter, self->pipeline_cache);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
{
|
||||
@ -312,16 +294,6 @@ gsk_vulkan_device_finalize (GObject *object)
|
||||
}
|
||||
g_hash_table_unref (self->pipeline_cache);
|
||||
|
||||
g_hash_table_iter_init (&iter, self->conversion_cache);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
{
|
||||
ConversionCacheEntry *entry = key;
|
||||
vkDestroySamplerYcbcrConversion (vk_device, entry->vk_conversion, NULL);
|
||||
vkDestroySampler (vk_device, entry->vk_sampler, NULL);
|
||||
g_free (key);
|
||||
}
|
||||
g_hash_table_unref (self->conversion_cache);
|
||||
|
||||
g_hash_table_iter_init (&iter, self->render_pass_cache);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
{
|
||||
@ -380,7 +352,7 @@ gsk_vulkan_device_class_init (GskVulkanDeviceClass *klass)
|
||||
static void
|
||||
gsk_vulkan_device_init (GskVulkanDevice *self)
|
||||
{
|
||||
self->conversion_cache = g_hash_table_new (conversion_cache_entry_hash, conversion_cache_entry_equal);
|
||||
self->ycbcr_cache = g_hash_table_new (g_direct_hash, g_direct_equal);
|
||||
self->render_pass_cache = g_hash_table_new (render_pass_cache_key_hash, render_pass_cache_key_equal);
|
||||
self->pipeline_cache = g_hash_table_new (pipeline_cache_key_hash, pipeline_cache_key_equal);
|
||||
}
|
||||
@ -416,7 +388,7 @@ gsk_vulkan_device_create_vk_objects (GskVulkanDevice *self)
|
||||
NULL,
|
||||
&self->vk_descriptor_pool);
|
||||
|
||||
self->vk_image_set_layout = gsk_vulkan_device_create_vk_image_set_layout (self, NULL);
|
||||
self->vk_image_set_layout = gsk_vulkan_device_create_vk_image_set_layout (self);
|
||||
|
||||
self->default_vk_pipeline_layout = gsk_vulkan_device_create_vk_pipeline_layout (self,
|
||||
self->vk_image_set_layout,
|
||||
@ -507,6 +479,30 @@ gsk_vulkan_device_get_default_vk_pipeline_layout (GskVulkanDevice *self)
|
||||
return self->default_vk_pipeline_layout;
|
||||
}
|
||||
|
||||
VkPipelineLayout
|
||||
gsk_vulkan_device_get_vk_pipeline_layout (GskVulkanDevice *self,
|
||||
GskVulkanYcbcr *ycbcr0,
|
||||
GskVulkanYcbcr *ycbcr1)
|
||||
{
|
||||
if (ycbcr0 == VK_NULL_HANDLE)
|
||||
{
|
||||
if (ycbcr1 == VK_NULL_HANDLE)
|
||||
return self->default_vk_pipeline_layout;
|
||||
else
|
||||
return gsk_vulkan_ycbcr_get_vk_pipeline_layout (ycbcr1, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ycbcr1 == VK_NULL_HANDLE)
|
||||
return gsk_vulkan_ycbcr_get_vk_pipeline_layout (ycbcr0, 0);
|
||||
else
|
||||
{
|
||||
/* FIXME: someone write a test plz */
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VkCommandPool
|
||||
gsk_vulkan_device_get_vk_command_pool (GskVulkanDevice *self)
|
||||
{
|
||||
@ -609,64 +605,26 @@ gsk_vulkan_device_get_vk_sampler (GskVulkanDevice *self,
|
||||
return self->vk_samplers[sampler];
|
||||
}
|
||||
|
||||
VkSamplerYcbcrConversion
|
||||
gsk_vulkan_device_get_vk_conversion (GskVulkanDevice *self,
|
||||
VkFormat vk_format,
|
||||
VkSampler *out_sampler)
|
||||
GskVulkanYcbcr *
|
||||
gsk_vulkan_device_get_ycbcr (GskVulkanDevice *self,
|
||||
VkFormat vk_format)
|
||||
{
|
||||
ConversionCacheEntry lookup;
|
||||
ConversionCacheEntry *entry;
|
||||
GdkDisplay *display;
|
||||
GskVulkanYcbcr *ycbcr;
|
||||
|
||||
lookup = (ConversionCacheEntry) {
|
||||
.vk_format = vk_format,
|
||||
};
|
||||
entry = g_hash_table_lookup (self->conversion_cache, &lookup);
|
||||
if (entry)
|
||||
{
|
||||
if (out_sampler)
|
||||
*out_sampler = entry->vk_sampler;
|
||||
ycbcr = g_hash_table_lookup (self->ycbcr_cache, GSIZE_TO_POINTER(vk_format));
|
||||
if (ycbcr)
|
||||
return ycbcr;
|
||||
|
||||
return entry->vk_conversion;
|
||||
}
|
||||
ycbcr = gsk_vulkan_ycbcr_new (self, vk_format);
|
||||
g_hash_table_insert (self->ycbcr_cache, GSIZE_TO_POINTER(vk_format), ycbcr);
|
||||
return ycbcr;
|
||||
}
|
||||
|
||||
display = gsk_gpu_device_get_display (GSK_GPU_DEVICE (self));
|
||||
|
||||
entry = g_memdup (&lookup, sizeof (ConversionCacheEntry));
|
||||
|
||||
GSK_VK_CHECK (vkCreateSamplerYcbcrConversion, display->vk_device,
|
||||
&(VkSamplerYcbcrConversionCreateInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO,
|
||||
.format = vk_format,
|
||||
.ycbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601,
|
||||
.ycbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_NARROW,
|
||||
.components = (VkComponentMapping) {
|
||||
VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||
VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||
VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||
VK_COMPONENT_SWIZZLE_IDENTITY
|
||||
},
|
||||
.xChromaOffset = VK_CHROMA_LOCATION_COSITED_EVEN,
|
||||
.yChromaOffset = VK_CHROMA_LOCATION_COSITED_EVEN,
|
||||
.chromaFilter = VK_FILTER_LINEAR,
|
||||
.forceExplicitReconstruction = VK_FALSE
|
||||
},
|
||||
NULL,
|
||||
&entry->vk_conversion);
|
||||
|
||||
entry->vk_sampler = gsk_vulkan_device_create_sampler (self,
|
||||
entry->vk_conversion,
|
||||
VK_FILTER_LINEAR,
|
||||
VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
|
||||
VK_SAMPLER_MIPMAP_MODE_NEAREST,
|
||||
0.0f);
|
||||
|
||||
g_hash_table_insert (self->conversion_cache, entry, entry);
|
||||
|
||||
if (out_sampler)
|
||||
*out_sampler = entry->vk_sampler;
|
||||
|
||||
return entry->vk_conversion;
|
||||
void
|
||||
gsk_vulkan_device_remove_ycbcr (GskVulkanDevice *self,
|
||||
VkFormat vk_format)
|
||||
{
|
||||
g_hash_table_remove (self->ycbcr_cache, GSIZE_TO_POINTER(vk_format));
|
||||
}
|
||||
|
||||
VkRenderPass
|
||||
|
@ -11,6 +11,9 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/* forward declaration */
|
||||
typedef struct _GskVulkanYcbcr GskVulkanYcbcr;
|
||||
|
||||
#define GSK_TYPE_VULKAN_DEVICE (gsk_vulkan_device_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE(GskVulkanDevice, gsk_vulkan_device, GSK, VULKAN_DEVICE, GskGpuDevice)
|
||||
@ -28,14 +31,21 @@ uint32_t gsk_vulkan_device_get_vk_queue_family_index (GskVulk
|
||||
VkCommandPool gsk_vulkan_device_get_vk_command_pool (GskVulkanDevice *self) G_GNUC_PURE;
|
||||
VkDescriptorPool gsk_vulkan_device_get_vk_descriptor_pool (GskVulkanDevice *self) G_GNUC_PURE;
|
||||
VkDescriptorSetLayout gsk_vulkan_device_get_vk_image_set_layout (GskVulkanDevice *self) G_GNUC_PURE;
|
||||
VkPipelineLayout gsk_vulkan_device_create_vk_pipeline_layout (GskVulkanDevice *self,
|
||||
VkDescriptorSetLayout image1_layout,
|
||||
VkDescriptorSetLayout image2_layout);
|
||||
VkPipelineLayout gsk_vulkan_device_get_default_vk_pipeline_layout (GskVulkanDevice *self) G_GNUC_PURE;
|
||||
VkPipelineLayout gsk_vulkan_device_get_vk_pipeline_layout (GskVulkanDevice *self,
|
||||
GskVulkanYcbcr *ycbcr0,
|
||||
GskVulkanYcbcr *ycbcr1);
|
||||
VkSampler gsk_vulkan_device_get_vk_sampler (GskVulkanDevice *self,
|
||||
GskGpuSampler sampler) G_GNUC_PURE;
|
||||
|
||||
VkSamplerYcbcrConversion
|
||||
gsk_vulkan_device_get_vk_conversion (GskVulkanDevice *self,
|
||||
VkFormat vk_format,
|
||||
VkSampler *out_sampler);
|
||||
GskVulkanYcbcr * gsk_vulkan_device_get_ycbcr (GskVulkanDevice *self,
|
||||
VkFormat vk_format);
|
||||
void gsk_vulkan_device_remove_ycbcr (GskVulkanDevice *self,
|
||||
VkFormat vk_format);
|
||||
|
||||
VkRenderPass gsk_vulkan_device_get_vk_render_pass (GskVulkanDevice *self,
|
||||
VkFormat format,
|
||||
VkImageLayout from_layout,
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "gskvulkanbufferprivate.h"
|
||||
#include "gskvulkanframeprivate.h"
|
||||
#include "gskvulkanmemoryprivate.h"
|
||||
#include "gskvulkanycbcrprivate.h"
|
||||
|
||||
#include "gdk/gdkdisplayprivate.h"
|
||||
#include "gdk/gdkdmabuftextureprivate.h"
|
||||
@ -31,7 +32,7 @@ struct _GskVulkanImage
|
||||
VkImageView vk_image_view;
|
||||
VkFramebuffer vk_framebuffer;
|
||||
VkImageView vk_framebuffer_image_view;
|
||||
VkSampler vk_sampler;
|
||||
GskVulkanYcbcr *ycbcr;
|
||||
VkSemaphore vk_semaphore;
|
||||
VkDescriptorSet vk_descriptor_sets[GSK_GPU_SAMPLER_N_SAMPLERS];
|
||||
|
||||
@ -1115,7 +1116,11 @@ gsk_vulkan_image_new_for_dmabuf (GskVulkanDevice *device,
|
||||
#endif
|
||||
|
||||
if (is_yuv)
|
||||
vk_conversion = gsk_vulkan_device_get_vk_conversion (device, vk_format, &self->vk_sampler);
|
||||
{
|
||||
self->ycbcr = gsk_vulkan_device_get_ycbcr (device, vk_format);
|
||||
gsk_vulkan_ycbcr_ref (self->ycbcr);
|
||||
vk_conversion = gsk_vulkan_ycbcr_get_vk_conversion (self->ycbcr);
|
||||
}
|
||||
else
|
||||
vk_conversion = VK_NULL_HANDLE;
|
||||
|
||||
@ -1290,6 +1295,8 @@ gsk_vulkan_image_finalize (GObject *object)
|
||||
vk_device = gsk_vulkan_device_get_vk_device (self->device);
|
||||
vk_descriptor_pool = gsk_vulkan_device_get_vk_descriptor_pool (self->device);
|
||||
|
||||
g_clear_pointer (&self->ycbcr, gsk_vulkan_ycbcr_unref);
|
||||
|
||||
for (i = 0; i < GSK_GPU_SAMPLER_N_SAMPLERS; i++)
|
||||
{
|
||||
if (self->vk_descriptor_sets[i])
|
||||
@ -1395,12 +1402,6 @@ gsk_vulkan_image_get_vk_framebuffer (GskVulkanImage *self,
|
||||
return self->vk_framebuffer;
|
||||
}
|
||||
|
||||
VkSampler
|
||||
gsk_vulkan_image_get_vk_sampler (GskVulkanImage *self)
|
||||
{
|
||||
return self->vk_sampler;
|
||||
}
|
||||
|
||||
VkDescriptorSet
|
||||
gsk_vulkan_image_get_vk_descriptor_set (GskVulkanImage *self,
|
||||
GskGpuSampler sampler)
|
||||
@ -1415,7 +1416,8 @@ gsk_vulkan_image_get_vk_descriptor_set (GskVulkanImage *self,
|
||||
.descriptorPool = gsk_vulkan_device_get_vk_descriptor_pool (self->device),
|
||||
.descriptorSetCount = 1,
|
||||
.pSetLayouts = (VkDescriptorSetLayout[1]) {
|
||||
gsk_vulkan_device_get_vk_image_set_layout (self->device),
|
||||
self->ycbcr ? gsk_vulkan_ycbcr_get_vk_descriptor_set_layout (self->ycbcr)
|
||||
: gsk_vulkan_device_get_vk_image_set_layout (self->device),
|
||||
},
|
||||
},
|
||||
&self->vk_descriptor_sets[sampler]);
|
||||
@ -1430,7 +1432,8 @@ gsk_vulkan_image_get_vk_descriptor_set (GskVulkanImage *self,
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||
.pImageInfo = &(VkDescriptorImageInfo) {
|
||||
.sampler = gsk_vulkan_device_get_vk_sampler (self->device, sampler),
|
||||
.sampler = self->ycbcr ? gsk_vulkan_ycbcr_get_vk_sampler (self->ycbcr)
|
||||
: gsk_vulkan_device_get_vk_sampler (self->device, sampler),
|
||||
.imageView = self->vk_image_view,
|
||||
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
|
||||
},
|
||||
@ -1442,6 +1445,12 @@ gsk_vulkan_image_get_vk_descriptor_set (GskVulkanImage *self,
|
||||
return self->vk_descriptor_sets[sampler];
|
||||
}
|
||||
|
||||
GskVulkanYcbcr *
|
||||
gsk_vulkan_image_get_ycbcr (GskVulkanImage *self)
|
||||
{
|
||||
return self->ycbcr;
|
||||
}
|
||||
|
||||
VkImage
|
||||
gsk_vulkan_image_get_vk_image (GskVulkanImage *self)
|
||||
{
|
||||
|
@ -50,7 +50,7 @@ GdkTexture * gsk_vulkan_image_to_dmabuf_texture (GskVulk
|
||||
guchar * gsk_vulkan_image_get_data (GskVulkanImage *self,
|
||||
gsize *out_stride);
|
||||
|
||||
VkSampler gsk_vulkan_image_get_vk_sampler (GskVulkanImage *self);
|
||||
GskVulkanYcbcr * gsk_vulkan_image_get_ycbcr (GskVulkanImage *self);
|
||||
VkDescriptorSet gsk_vulkan_image_get_vk_descriptor_set (GskVulkanImage *self,
|
||||
GskGpuSampler sampler);
|
||||
VkPipelineStageFlags gsk_vulkan_image_get_vk_pipeline_stage (GskVulkanImage *self);
|
||||
|
203
gsk/gpu/gskvulkanycbcr.c
Normal file
203
gsk/gpu/gskvulkanycbcr.c
Normal file
@ -0,0 +1,203 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "gskvulkanycbcrprivate.h"
|
||||
|
||||
#include "gskgpucacheprivate.h"
|
||||
|
||||
struct _GskVulkanYcbcr
|
||||
{
|
||||
GskGpuCached parent;
|
||||
|
||||
int ref_count;
|
||||
|
||||
VkFormat vk_format;
|
||||
VkSamplerYcbcrConversion vk_conversion;
|
||||
VkSampler vk_sampler;
|
||||
VkDescriptorSetLayout vk_descriptor_set_layout;
|
||||
VkPipelineLayout vk_pipeline_layouts[2];
|
||||
};
|
||||
|
||||
static void
|
||||
gsk_vulkan_ycbcr_free (GskGpuCache *cache,
|
||||
GskGpuCached *cached)
|
||||
{
|
||||
GskVulkanYcbcr *self = (GskVulkanYcbcr *) cached;
|
||||
GskVulkanDevice *device;
|
||||
VkDevice vk_device;
|
||||
|
||||
device = GSK_VULKAN_DEVICE (gsk_gpu_cache_get_device (cache));
|
||||
vk_device = gsk_vulkan_device_get_vk_device (device);
|
||||
|
||||
g_assert (self->ref_count == 0);
|
||||
|
||||
gsk_vulkan_device_remove_ycbcr (device, self->vk_format);
|
||||
|
||||
vkDestroySampler (vk_device, self->vk_sampler, NULL);
|
||||
vkDestroySamplerYcbcrConversion (vk_device, self->vk_conversion, NULL);
|
||||
vkDestroyDescriptorSetLayout (vk_device, self->vk_descriptor_set_layout, NULL);
|
||||
vkDestroyPipelineLayout (vk_device, self->vk_pipeline_layouts[0], NULL);
|
||||
vkDestroyPipelineLayout (vk_device, self->vk_pipeline_layouts[1], NULL);
|
||||
|
||||
g_free (self);
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
gsk_gpu_cached_is_old (GskGpuCache *self,
|
||||
GskGpuCached *cached,
|
||||
gint64 cache_timeout,
|
||||
gint64 timestamp)
|
||||
{
|
||||
if (cache_timeout < 0)
|
||||
return -1;
|
||||
else
|
||||
return timestamp - cached->timestamp > cache_timeout;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_vulkan_ycbcr_should_collect (GskGpuCache *cache,
|
||||
GskGpuCached *cached,
|
||||
gint64 cache_timeout,
|
||||
gint64 timestamp)
|
||||
{
|
||||
GskVulkanYcbcr *self = (GskVulkanYcbcr *) cached;
|
||||
|
||||
if (self->ref_count > 0)
|
||||
return FALSE;
|
||||
|
||||
return gsk_gpu_cached_is_old (cache, cached, cache_timeout, timestamp);
|
||||
}
|
||||
|
||||
static const GskGpuCachedClass GSK_VULKAN_YCBCR_CLASS =
|
||||
{
|
||||
sizeof (GskVulkanYcbcr),
|
||||
"Vulkan Ycbcr",
|
||||
gsk_vulkan_ycbcr_free,
|
||||
gsk_vulkan_ycbcr_should_collect
|
||||
};
|
||||
|
||||
GskVulkanYcbcr *
|
||||
gsk_vulkan_ycbcr_new (GskVulkanDevice *device,
|
||||
VkFormat vk_format)
|
||||
{
|
||||
GskGpuCache *cache = gsk_gpu_device_get_cache (GSK_GPU_DEVICE (device));
|
||||
VkDevice vk_device = gsk_vulkan_device_get_vk_device (device);
|
||||
VkDescriptorSetLayout vk_image_set_layout;
|
||||
GskVulkanYcbcr *self;
|
||||
|
||||
self = gsk_gpu_cached_new (cache, &GSK_VULKAN_YCBCR_CLASS);
|
||||
|
||||
self->vk_format = vk_format;
|
||||
|
||||
GSK_VK_CHECK (vkCreateSamplerYcbcrConversion, vk_device,
|
||||
&(VkSamplerYcbcrConversionCreateInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO,
|
||||
.format = vk_format,
|
||||
.ycbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601,
|
||||
.ycbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_NARROW,
|
||||
.components = (VkComponentMapping) {
|
||||
VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||
VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||
VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||
VK_COMPONENT_SWIZZLE_IDENTITY
|
||||
},
|
||||
.xChromaOffset = VK_CHROMA_LOCATION_COSITED_EVEN,
|
||||
.yChromaOffset = VK_CHROMA_LOCATION_COSITED_EVEN,
|
||||
.chromaFilter = VK_FILTER_LINEAR,
|
||||
.forceExplicitReconstruction = VK_FALSE
|
||||
},
|
||||
NULL,
|
||||
&self->vk_conversion);
|
||||
|
||||
GSK_VK_CHECK (vkCreateSampler, vk_device,
|
||||
&(VkSamplerCreateInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
|
||||
.magFilter = VK_FILTER_LINEAR,
|
||||
.minFilter = VK_FILTER_LINEAR,
|
||||
.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST,
|
||||
.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_TRANSPARENT_BLACK,
|
||||
.unnormalizedCoordinates = VK_FALSE,
|
||||
.maxAnisotropy = 1.0,
|
||||
.minLod = 0.0,
|
||||
.maxLod = 0.0f,
|
||||
.pNext = &(VkSamplerYcbcrConversionInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO,
|
||||
.conversion = self->vk_conversion
|
||||
}
|
||||
},
|
||||
NULL,
|
||||
&self->vk_sampler);
|
||||
|
||||
GSK_VK_CHECK (vkCreateDescriptorSetLayout, vk_device,
|
||||
&(VkDescriptorSetLayoutCreateInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
|
||||
.bindingCount = 1,
|
||||
.flags = 0,
|
||||
.pBindings = (VkDescriptorSetLayoutBinding[1]) {
|
||||
{
|
||||
.binding = 0,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||
.descriptorCount = 1,
|
||||
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
.pImmutableSamplers = (VkSampler[1]) {
|
||||
self->vk_sampler,
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
NULL,
|
||||
&self->vk_descriptor_set_layout);
|
||||
|
||||
vk_image_set_layout = gsk_vulkan_device_get_vk_image_set_layout (device);
|
||||
self->vk_pipeline_layouts[0] = gsk_vulkan_device_create_vk_pipeline_layout (device,
|
||||
self->vk_descriptor_set_layout,
|
||||
vk_image_set_layout);
|
||||
self->vk_pipeline_layouts[1] = gsk_vulkan_device_create_vk_pipeline_layout (device,
|
||||
vk_image_set_layout,
|
||||
self->vk_descriptor_set_layout);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
GskVulkanYcbcr *
|
||||
gsk_vulkan_ycbcr_ref (GskVulkanYcbcr *self)
|
||||
{
|
||||
self->ref_count++;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_vulkan_ycbcr_unref (GskVulkanYcbcr *self)
|
||||
{
|
||||
self->ref_count--;
|
||||
}
|
||||
|
||||
VkSamplerYcbcrConversion
|
||||
gsk_vulkan_ycbcr_get_vk_conversion (GskVulkanYcbcr *self)
|
||||
{
|
||||
return self->vk_conversion;
|
||||
}
|
||||
|
||||
VkSampler
|
||||
gsk_vulkan_ycbcr_get_vk_sampler (GskVulkanYcbcr *self)
|
||||
{
|
||||
return self->vk_sampler;
|
||||
}
|
||||
|
||||
VkDescriptorSetLayout
|
||||
gsk_vulkan_ycbcr_get_vk_descriptor_set_layout (GskVulkanYcbcr *self)
|
||||
{
|
||||
return self->vk_descriptor_set_layout;
|
||||
}
|
||||
|
||||
VkPipelineLayout
|
||||
gsk_vulkan_ycbcr_get_vk_pipeline_layout (GskVulkanYcbcr *self,
|
||||
gsize id)
|
||||
{
|
||||
g_assert (id < 2);
|
||||
|
||||
return self->vk_pipeline_layouts[id];
|
||||
}
|
23
gsk/gpu/gskvulkanycbcrprivate.h
Normal file
23
gsk/gpu/gskvulkanycbcrprivate.h
Normal file
@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include "gskvulkandeviceprivate.h"
|
||||
|
||||
#include "gdk/gdkvulkancontextprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GskVulkanYcbcr * gsk_vulkan_ycbcr_new (GskVulkanDevice *self,
|
||||
VkFormat vk_format);
|
||||
|
||||
GskVulkanYcbcr * gsk_vulkan_ycbcr_ref (GskVulkanYcbcr *self);
|
||||
void gsk_vulkan_ycbcr_unref (GskVulkanYcbcr *self);
|
||||
|
||||
VkSamplerYcbcrConversion
|
||||
gsk_vulkan_ycbcr_get_vk_conversion (GskVulkanYcbcr *self);
|
||||
VkSampler gsk_vulkan_ycbcr_get_vk_sampler (GskVulkanYcbcr *self);
|
||||
VkDescriptorSetLayout gsk_vulkan_ycbcr_get_vk_descriptor_set_layout (GskVulkanYcbcr *self);
|
||||
VkPipelineLayout gsk_vulkan_ycbcr_get_vk_pipeline_layout (GskVulkanYcbcr *self,
|
||||
gsize id);
|
||||
|
||||
|
||||
G_END_DECLS
|
@ -163,6 +163,7 @@ if have_vulkan
|
||||
'gpu/gskvulkanframe.c',
|
||||
'gpu/gskvulkanimage.c',
|
||||
'gpu/gskvulkanmemory.c',
|
||||
'gpu/gskvulkanycbcr.c',
|
||||
])
|
||||
endif # have_vulkan
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user