Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  gskvulkanycbcr.c

  Sprache: C
 

#include "config.h"

#include "gskvulkanycbcrprivate.h"

#include "gskgpucacheprivate.h"
#include "gskgpucachedprivate.h"

struct _GskVulkanYcbcr
{
  GskGpuCached parent;

  int ref_count;

  GskVulkanYcbcrInfo info;

  VkSamplerYcbcrConversion vk_conversion;
  VkSampler vk_sampler;
  VkDescriptorSetLayout vk_descriptor_set_layout;
  VkPipelineLayout vk_pipeline_layouts[2];
};

static guint
gsk_vulkan_ycbcr_info_hash (gconstpointer info_)
{
  const GskVulkanYcbcrInfo *info = info_;

  return ((info->vk_components.r << 29) |
          (info->vk_components.g << 26) |
          (info->vk_components.b << 23) |
          (info->vk_components.a << 20) |
          (info->vk_ycbcr_model << 17) |
          (info->vk_ycbcr_range << 16)) ^
         info->vk_features ^
         info->vk_format;
}

static gboolean
gsk_vulkan_ycbcr_info_equal (gconstpointer info1_,
                             gconstpointer info2_)
{
  const GskVulkanYcbcrInfo *info1 = info1_;
  const GskVulkanYcbcrInfo *info2 = info2_;

  return info1->vk_format == info2->vk_format &&
         info1->vk_features == info2->vk_features &&
         info1->vk_components.r == info2->vk_components.r && 
         info1->vk_components.g == info2->vk_components.g && 
         info1->vk_components.b == info2->vk_components.b && 
         info1->vk_components.a == info2->vk_components.a && 
         info1->vk_ycbcr_model == info2->vk_ycbcr_model &&
         info1->vk_ycbcr_range == info2->vk_ycbcr_range;
}

static void
gsk_vulkan_ycbcr_finalize (GskGpuCached *cached)
{
  GskGpuCachePrivate *priv = gsk_gpu_cache_get_private (cached->cache);
  GskVulkanYcbcr *self = (GskVulkanYcbcr *) cached;
  GskGpuCache *cache = cached->cache;
  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);

  g_hash_table_remove (priv->ycbcr_cache, &self->info);

  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);
}

static gboolean
gsk_vulkan_ycbcr_should_collect (GskGpuCached *cached,
                                 gint64        cache_timeout,
                                 gint64        timestamp)
{
  GskVulkanYcbcr *self = (GskVulkanYcbcr *) cached;

  if (self->ref_count > 0)
    return FALSE;

  return gsk_gpu_cached_is_old (cached, cache_timeout, timestamp);
}

static const GskGpuCachedClass GSK_VULKAN_YCBCR_CLASS =
{
  sizeof (GskVulkanYcbcr),
  "Vulkan Ycbcr",
  FALSE,
  gsk_gpu_cached_print_no_stats,
  gsk_vulkan_ycbcr_finalize,
  gsk_vulkan_ycbcr_should_collect
};

void
gsk_vulkan_ycbcr_init_cache (GskGpuCache *cache)
{
  GskGpuCachePrivate *priv = gsk_gpu_cache_get_private (cache);

  priv->ycbcr_cache = g_hash_table_new (gsk_vulkan_ycbcr_info_hash, gsk_vulkan_ycbcr_info_equal);
}

void
gsk_vulkan_ycbcr_finish_cache (GskGpuCache *cache)
{
  GskGpuCachePrivate *priv = gsk_gpu_cache_get_private (cache);

  g_assert (g_hash_table_size (priv->ycbcr_cache) == 0);
  g_hash_table_unref (priv->ycbcr_cache);
}

gboolean
gsk_vulkan_ycbcr_is_supported (VkFormatFeatureFlags vk_features)
{
  /* If neither VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT nor VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT is set,
   * the application must not define a sampler YCBCR conversion using this format as a source.
   */

  if (!(vk_features & (VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT | VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT)))
    return FALSE;

  return TRUE;
}

static VkChromaLocation
gsk_vulkan_ycbcr_get_best_vk_chroma (VkFormatFeatureFlags vk_features)
{
  if (vk_features & VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT)
    {
      return VK_CHROMA_LOCATION_COSITED_EVEN;
    }
  else if (vk_features & VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT)
    {
      return VK_CHROMA_LOCATION_MIDPOINT;
    }
  else
    {
      /* Checked via gsk_vulkan_ycbcr_is_supported () */
      g_return_val_if_reached (VK_CHROMA_LOCATION_COSITED_EVEN);
    }
}

GskVulkanYcbcr *
gsk_vulkan_ycbcr_get (GskVulkanDevice          *device,
                      const GskVulkanYcbcrInfo *info)
{
  GskGpuCache *cache = gsk_gpu_device_get_cache (GSK_GPU_DEVICE (device));
  GskGpuCachePrivate *priv = gsk_gpu_cache_get_private (cache);
  VkDevice vk_device = gsk_vulkan_device_get_vk_device (device);
  VkDescriptorSetLayout vk_image_set_layout;
  VkChromaLocation vk_chroma;
  GskVulkanYcbcr *self;

  self = g_hash_table_lookup (priv->ycbcr_cache, info);
  if (self)
    return self;

  /* We expect calling code to check this */
  g_assert (gsk_vulkan_ycbcr_is_supported (info->vk_features));

  self = gsk_gpu_cached_new (cache, &GSK_VULKAN_YCBCR_CLASS);

  self->info = *info;

  vk_chroma = gsk_vulkan_ycbcr_get_best_vk_chroma (info->vk_features);
  GSK_VK_CHECK (vkCreateSamplerYcbcrConversion, vk_device,
                                                &(VkSamplerYcbcrConversionCreateInfo) {
                                                    .sType = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO,
                                                    .format = self->info.vk_format,
                                                    .ycbcrModel = self->info.vk_ycbcr_model,
                                                    .ycbcrRange = self->info.vk_ycbcr_range,
                                                    .components = self->info.vk_components,
                                                    .xChromaOffset = vk_chroma,
                                                    .yChromaOffset = vk_chroma,
                                                    .chromaFilter = info->vk_features & VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT 
                                                                  ? VK_FILTER_LINEAR : VK_FILTER_NEAREST,
                                                    .forceExplicitReconstruction = VK_FALSE
                                                },
                                                NULL,
                                                &self->vk_conversion);

  GSK_VK_CHECK (vkCreateSampler, vk_device,
                                 &(VkSamplerCreateInfo) {
                                     .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
                                     .magFilter = gsk_vulkan_ycbcr_is_filterable (self) ? VK_FILTER_LINEAR : VK_FILTER_NEAREST,
                                     .minFilter = gsk_vulkan_ycbcr_is_filterable (self) ? VK_FILTER_LINEAR : VK_FILTER_NEAREST,
                                     .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 = 3,
                                                         .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
                                                         .pImmutableSamplers = (VkSampler[3]) {
                                                             self->vk_sampler,
                                                             self->vk_sampler,
                                                             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);

  g_hash_table_insert (priv->ycbcr_cache, &self->info, self);

  return self;
}

GskVulkanYcbcr *
gsk_vulkan_ycbcr_ref (GskVulkanYcbcr *self)
{
  self->ref_count++;

  return self;
}

void
gsk_vulkan_ycbcr_unref (GskVulkanYcbcr *self)
{
  self->ref_count--;

  gsk_gpu_cached_use ((GskGpuCached *) self);
}

gboolean
gsk_vulkan_ycbcr_is_filterable (GskVulkanYcbcr *self)
{
  /* VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT specifies that
   * the format can have different chroma, min, and mag filters.
   */

  if (self->info.vk_features & VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT)
    return TRUE;

  /* VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT specifies that an application
   * can define a sampler YCBCR conversion using this format as a source with chromaFilter set to VK_FILTER_LINEAR.
   */

  if (self->info.vk_features & VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT)
    return TRUE;

  return FALSE;
}

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];
}

Messung V0.5 in Prozent
C=98 H=96 G=96

¤ Dauer der Verarbeitung: 0.11 Sekunden  (vorverarbeitet am  2026-07-02) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik