Eine aufbereitete Darstellung der Quelle

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

Benutzer

Quelle  gskvulkanframe.c

  Sprache: C
 

#include "config.h"

#include "gskvulkanframeprivate.h"

#include "gskgpuopprivate.h"
#include "gskgpuutilsprivate.h"
#include "gskvulkanbufferprivate.h"
#include "gskvulkandeviceprivate.h"
#include "gskvulkanimageprivate.h"

#include "gdk/gdkdmabuftextureprivate.h"
#include "gdk/gdkglcontextprivate.h"
#include "gdk/gdkgltextureprivate.h"

#ifdef GDK_WINDOWING_WIN32
#include "gdk/win32/gdkd3d12textureprivate.h"
#endif

#define GDK_ARRAY_NAME gsk_semaphores
#define GDK_ARRAY_TYPE_NAME GskSemaphores
#define GDK_ARRAY_ELEMENT_TYPE VkSemaphore
#define GDK_ARRAY_PREALLOC 16
#define GDK_ARRAY_NO_MEMSET 1
#include "gdk/gdkarrayimpl.c"

#define GDK_ARRAY_NAME gsk_semaphore_values
#define GDK_ARRAY_TYPE_NAME GskSemaphoreValues
#define GDK_ARRAY_ELEMENT_TYPE uint64_t
#define GDK_ARRAY_PREALLOC 16
#define GDK_ARRAY_NO_MEMSET 1
#include "gdk/gdkarrayimpl.c"

#define GDK_ARRAY_NAME gsk_pipeline_stages
#define GDK_ARRAY_TYPE_NAME GskPipelineStages
#define GDK_ARRAY_ELEMENT_TYPE VkPipelineStageFlags
#define GDK_ARRAY_PREALLOC 16
#define GDK_ARRAY_NO_MEMSET 1
#include "gdk/gdkarrayimpl.c"

struct _GskVulkanSemaphores
{
  GskSemaphores wait_semaphores;
  GskSemaphoreValues wait_semaphore_values;
  GskPipelineStages wait_stages;
  GskSemaphores signal_semaphores;
};

typedef struct _GskVulkanFramePrivate GskVulkanFramePrivate;

struct _GskVulkanFramePrivate
{
  VkSemaphore vk_acquire_semaphore;
  VkFence vk_fence;
  VkCommandBuffer vk_command_buffer;

  gsize pool_n_sets;
  gsize pool_n_images;
  gsize pool_n_buffers;
};

G_DEFINE_TYPE_WITH_PRIVATE (GskVulkanFrame, gsk_vulkan_frame, GSK_TYPE_GPU_FRAME)

static gboolean
gsk_vulkan_frame_is_busy (GskGpuFrame *frame)
{
  GskVulkanFrame *self = GSK_VULKAN_FRAME (frame);
  GskVulkanFramePrivate *priv = gsk_vulkan_frame_get_instance_private (self);
  VkDevice device;
  VkResult res;

  device = gsk_vulkan_device_get_vk_device (GSK_VULKAN_DEVICE (gsk_gpu_frame_get_device (frame)));

  res = vkGetFenceStatus (device, priv->vk_fence);
  if (res == VK_NOT_READY)
    return TRUE;

  gsk_vulkan_handle_result (res, "vkGetFenceStatus");
  return res;
}

static void
gsk_vulkan_frame_wait (GskGpuFrame *frame)
{
  GskVulkanFrame *self = GSK_VULKAN_FRAME (frame);
  GskVulkanFramePrivate *priv = gsk_vulkan_frame_get_instance_private (self);
  VkDevice vk_device;

  vk_device = gsk_vulkan_device_get_vk_device (GSK_VULKAN_DEVICE (gsk_gpu_frame_get_device (frame)));

  GSK_VK_CHECK (vkWaitForFences, vk_device,
                                 1,
                                 &priv->vk_fence,
                                 VK_FALSE,
                                 INT64_MAX);
}

static void
gsk_vulkan_frame_setup (GskGpuFrame *frame)
{
  GskVulkanFrame *self = GSK_VULKAN_FRAME (frame);
  GskVulkanFramePrivate *priv = gsk_vulkan_frame_get_instance_private (self);
  GskVulkanDevice *device;
  VkDevice vk_device;
  VkCommandPool vk_command_pool;

  device = GSK_VULKAN_DEVICE (gsk_gpu_frame_get_device (frame));
  vk_device = gsk_vulkan_device_get_vk_device (device);
  vk_command_pool = gsk_vulkan_device_get_vk_command_pool (device);

  GSK_VK_CHECK (vkAllocateCommandBuffers, vk_device,
                                          &(VkCommandBufferAllocateInfo) {
                                              .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
                                              .commandPool = vk_command_pool,
                                              .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
                                              .commandBufferCount = 1,
                                          },
                                          &priv->vk_command_buffer);

  GDK_VK_CHECK (vkCreateSemaphore, vk_device,
                                   &(VkSemaphoreCreateInfo) {
                                       .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
                                   },
                                   NULL,
                                   &priv->vk_acquire_semaphore);

  GSK_VK_CHECK (vkCreateFence, vk_device,
                               &(VkFenceCreateInfo) {
                                   .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
                               },
                               NULL,
                               &priv->vk_fence);
}

static void
gsk_vulkan_frame_cleanup (GskGpuFrame *frame)
{
  GskVulkanFrame *self = GSK_VULKAN_FRAME (frame);
  GskVulkanFramePrivate *priv = gsk_vulkan_frame_get_instance_private (self);
  GskVulkanDevice *device;
  VkDevice vk_device;

  device = GSK_VULKAN_DEVICE (gsk_gpu_frame_get_device (frame));
  vk_device = gsk_vulkan_device_get_vk_device (device);

  GSK_VK_CHECK (vkWaitForFences, vk_device,
                                 1,
                                 &priv->vk_fence,
                                 VK_TRUE,
                                 INT64_MAX);

  GSK_VK_CHECK (vkResetFences, vk_device,
                               1,
                               &priv->vk_fence);

  GSK_VK_CHECK (vkResetCommandBuffer, priv->vk_command_buffer,
                                      0);

  GSK_GPU_FRAME_CLASS (gsk_vulkan_frame_parent_class)->cleanup (frame);
}

static void
gsk_vulkan_frame_begin (GskGpuFrame           *frame,
                        GdkDrawContext        *context,
                        GdkMemoryDepth         depth,
                        const cairo_region_t  *region,
                        const graphene_rect_t *opaque)
{
  GskVulkanFrame *self = GSK_VULKAN_FRAME (frame);
  GskVulkanFramePrivate *priv = gsk_vulkan_frame_get_instance_private (self);

  gdk_draw_context_begin_frame_full (context,
                                     /* We pass a pointer here for 32bit architectures */
                                     &priv->vk_acquire_semaphore,
                                     depth,
                                     region,
                                     opaque);
}

static GskGpuImage *
gsk_vulkan_frame_upload_texture (GskGpuFrame  *frame,
                                 gboolean      with_mipmap,
                                 GdkTexture   *texture)
{
#ifdef HAVE_DMABUF
  if (GDK_IS_GL_TEXTURE (texture))
    {
      GdkGLTexture *gltexture = GDK_GL_TEXTURE (texture);
      GdkDisplay *display;
      GdkGLContext *glcontext;
      GdkDmabuf dmabuf;

      display = gsk_gpu_device_get_display (gsk_gpu_frame_get_device (frame));
      glcontext = gdk_display_get_gl_context (display);
      if (glcontext && gdk_gl_context_is_shared (glcontext, gdk_gl_texture_get_context (gltexture)))
        {
          gdk_gl_context_make_current (glcontext);

          if (gdk_gl_context_export_dmabuf (gdk_gl_texture_get_context (gltexture),
                                            gdk_gl_texture_get_id (gltexture),
                                            &dmabuf))
            {
              GskGpuImage *image;

              image = gsk_vulkan_image_new_for_dmabuf (GSK_VULKAN_DEVICE (gsk_gpu_frame_get_device (frame)),
                                                       gdk_texture_get_width (texture),
                                                       gdk_texture_get_height (texture),
                                                       &dmabuf,
                                                       gdk_memory_format_alpha (gdk_texture_get_format (texture)) == GDK_MEMORY_ALPHA_PREMULTIPLIED,
                                                       GSK_GPU_CONVERSION_NONE);

              /* Vulkan import dups the fds, so we can close these */
              gdk_dmabuf_close_fds (&dmabuf);

              if (image)
                {
                  gsk_gpu_image_toggle_ref_texture (image, texture);
                  return image;
                }
            }
        }
    }

  if (GDK_IS_DMABUF_TEXTURE (texture))
    {
      GskGpuImage *image;

      image = gsk_vulkan_image_new_for_dmabuf (GSK_VULKAN_DEVICE (gsk_gpu_frame_get_device (frame)),
                                               gdk_texture_get_width (texture),
                                               gdk_texture_get_height (texture),
                                               gdk_dmabuf_texture_get_dmabuf (GDK_DMABUF_TEXTURE (texture)),
                                               gdk_memory_format_alpha (gdk_texture_get_format (texture)) == GDK_MEMORY_ALPHA_PREMULTIPLIED,
                                               gsk_gpu_color_state_get_conversion (gdk_texture_get_color_state (texture)));
      if (image)
        {
          gsk_gpu_image_toggle_ref_texture (image, texture);
          return image;
        }
    }
#endif
#ifdef GDK_WINDOWING_WIN32
  if (GDK_IS_D3D12_TEXTURE (texture))
    {
      GdkD3D12Texture *d3d_texture = GDK_D3D12_TEXTURE (texture);
      GskGpuImage *image;

      image = gsk_vulkan_image_new_for_d3d12resource (GSK_VULKAN_DEVICE (gsk_gpu_frame_get_device (frame)),
                                                      gdk_d3d12_texture_get_resource (d3d_texture),
                                                      gdk_d3d12_texture_get_resource_handle (d3d_texture),
                                                      gdk_d3d12_texture_get_fence (d3d_texture),
                                                      gdk_d3d12_texture_get_fence_handle (d3d_texture),
                                                      gdk_d3d12_texture_get_fence_wait (d3d_texture),
                                                      gdk_memory_format_alpha (gdk_texture_get_format (texture)) != GDK_MEMORY_ALPHA_STRAIGHT);
      if (image)
        {
          gsk_gpu_image_toggle_ref_texture (image, texture);
          return image;
        }
    }
#endif

  return GSK_GPU_FRAME_CLASS (gsk_vulkan_frame_parent_class)->upload_texture (frame, with_mipmap, texture);
}

static GskGpuBuffer *
gsk_vulkan_frame_create_vertex_buffer (GskGpuFrame *frame,
                                       gsize        size)
{
  return gsk_vulkan_buffer_new_vertex (GSK_VULKAN_DEVICE (gsk_gpu_frame_get_device (frame)), size);
}

static GskGpuBuffer *
gsk_vulkan_frame_create_globals_buffer (GskGpuFrame *frame,
                                        gsize        size)
{
  return NULL;
}

static GskGpuBuffer *
gsk_vulkan_frame_create_storage_buffer (GskGpuFrame *frame,
                                        gsize        size)
{
  return gsk_vulkan_buffer_new_storage (GSK_VULKAN_DEVICE (gsk_gpu_frame_get_device (frame)), size);
}

static void
gsk_vulkan_frame_write_texture_vertex_data (GskGpuFrame    *self,
                                            guchar         *data,
                                            GskGpuImage   **images,
                                            GskGpuSampler  *samplers,
                                            gsize           n_images)
{
}

static void
gsk_vulkan_frame_submit_ops (GskVulkanFrame        *frame,
                             GskVulkanCommandState *state,
                             GskGpuOp              *op)
{
  while (op)
    {
      op = gsk_gpu_op_vk_command (op, GSK_GPU_FRAME (frame), state);
    }
}

static void
gsk_vulkan_frame_submit (GskGpuFrame       *frame,
                         GskRenderPassType  pass_type,
                         GskGpuBuffer      *vertex_buffer,
                         GskGpuBuffer      *globals_buffer,
                         GskGpuOp          *op)
{
  GskVulkanFrame *self = GSK_VULKAN_FRAME (frame);
  GskVulkanFramePrivate *priv = gsk_vulkan_frame_get_instance_private (self);
  GskVulkanDevice *device;
  GskVulkanSemaphores semaphores;
  GskVulkanCommandState state = { 0, };

  device = GSK_VULKAN_DEVICE (gsk_gpu_frame_get_device (frame));

  GSK_VK_CHECK (vkBeginCommandBuffer, priv->vk_command_buffer,
                                      &(VkCommandBufferBeginInfo) {
                                          .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
                                          .flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
                                      });

  if (vertex_buffer)
    vkCmdBindVertexBuffers (priv->vk_command_buffer,
                            0,
                            1,
                            (VkBuffer[1]) {
                                gsk_vulkan_buffer_get_vk_buffer (GSK_VULKAN_BUFFER (vertex_buffer))
                            },
                            (VkDeviceSize[1]) { 0 });

  gsk_semaphores_init (&semaphores.wait_semaphores);
  gsk_semaphore_values_init (&semaphores.wait_semaphore_values);
  gsk_pipeline_stages_init (&semaphores.wait_stages);
  gsk_semaphores_init (&semaphores.signal_semaphores);

  if (pass_type == GSK_RENDER_PASS_PRESENT)
    {
      GdkVulkanContext *context = GDK_VULKAN_CONTEXT (gsk_gpu_frame_get_context (frame));
      gsk_vulkan_semaphores_add_wait (&semaphores,
                                      priv->vk_acquire_semaphore,
                                      0,
                                      VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
      gsk_vulkan_semaphores_add_signal (&semaphores,
                                        gdk_vulkan_context_get_present_semaphore (context));
    }

  state.vk_command_buffer = priv->vk_command_buffer;
  state.vk_render_pass = VK_NULL_HANDLE;
  state.vk_format = VK_FORMAT_UNDEFINED;
  state.blend = GSK_GPU_BLEND_OVER; /* should we have a BLEND_NONE? */
  state.semaphores = &semaphores;

  GSK_VULKAN_FRAME_GET_CLASS (self)->submit_ops (self, &state, op);

  GSK_VK_CHECK (vkEndCommandBuffer, priv->vk_command_buffer);

  GSK_VK_CHECK (vkQueueSubmit, gsk_vulkan_device_get_vk_queue (device),
                               1,
                               &(VkSubmitInfo) {
                                  .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
                                  .commandBufferCount = 1,
                                  .pCommandBuffers = &priv->vk_command_buffer,
                                  .pWaitSemaphores = gsk_semaphores_get_data (&semaphores.wait_semaphores),
                                  .pWaitDstStageMask = gsk_pipeline_stages_get_data (&semaphores.wait_stages),
                                  .waitSemaphoreCount = gsk_semaphores_get_size (&semaphores.wait_semaphores),
                                  .pSignalSemaphores = gsk_semaphores_get_data (&semaphores.signal_semaphores),
                                  .signalSemaphoreCount = gsk_semaphores_get_size (&semaphores.signal_semaphores),
                                  .pNext = gsk_vulkan_device_has_feature (device, GDK_VULKAN_FEATURE_TIMELINE_SEMAPHORE) ? &(VkTimelineSemaphoreSubmitInfo) {
                                       .sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO,
                                       .waitSemaphoreValueCount = gsk_semaphore_values_get_size (&semaphores.wait_semaphore_values),
                                       .pWaitSemaphoreValues = gsk_semaphore_values_get_data (&semaphores.wait_semaphore_values),
                                  } : NULL,
                               },
                               priv->vk_fence);

  gsk_semaphores_clear (&semaphores.wait_semaphores);
  gsk_semaphore_values_clear (&semaphores.wait_semaphore_values);
  gsk_pipeline_stages_clear (&semaphores.wait_stages);
  gsk_semaphores_clear (&semaphores.signal_semaphores);
}

static void
gsk_vulkan_frame_finalize (GObject *object)
{
  GskVulkanFrame *self = GSK_VULKAN_FRAME (object);
  GskVulkanFramePrivate *priv = gsk_vulkan_frame_get_instance_private (self);
  GskVulkanDevice *device;
  VkDevice vk_device;
  VkCommandPool vk_command_pool;

  device = GSK_VULKAN_DEVICE (gsk_gpu_frame_get_device (GSK_GPU_FRAME (self)));
  vk_device = gsk_vulkan_device_get_vk_device (device);
  vk_command_pool = gsk_vulkan_device_get_vk_command_pool (device);

  vkFreeCommandBuffers (vk_device,
                        vk_command_pool,
                        1, &priv->vk_command_buffer);
  vkDestroySemaphore (vk_device,
                      priv->vk_acquire_semaphore,
                      NULL);
  vkDestroyFence (vk_device,
                  priv->vk_fence,
                  NULL);

  G_OBJECT_CLASS (gsk_vulkan_frame_parent_class)->finalize (object);
}

static void
gsk_vulkan_frame_class_init (GskVulkanFrameClass *klass)
{
  GskGpuFrameClass *gpu_frame_class = GSK_GPU_FRAME_CLASS (klass);
  GObjectClass *object_class = G_OBJECT_CLASS (klass);

  klass->submit_ops = gsk_vulkan_frame_submit_ops;

  gpu_frame_class->is_busy = gsk_vulkan_frame_is_busy;
  gpu_frame_class->wait = gsk_vulkan_frame_wait;
  gpu_frame_class->setup = gsk_vulkan_frame_setup;
  gpu_frame_class->cleanup = gsk_vulkan_frame_cleanup;
  gpu_frame_class->begin = gsk_vulkan_frame_begin;
  gpu_frame_class->upload_texture = gsk_vulkan_frame_upload_texture;
  gpu_frame_class->create_vertex_buffer = gsk_vulkan_frame_create_vertex_buffer;
  gpu_frame_class->create_globals_buffer = gsk_vulkan_frame_create_globals_buffer;
  gpu_frame_class->create_storage_buffer = gsk_vulkan_frame_create_storage_buffer;
  gpu_frame_class->write_texture_vertex_data = gsk_vulkan_frame_write_texture_vertex_data;
  gpu_frame_class->submit = gsk_vulkan_frame_submit;

  object_class->finalize = gsk_vulkan_frame_finalize;
}

static void
gsk_vulkan_frame_init (GskVulkanFrame *self)
{
  GskVulkanFramePrivate *priv = gsk_vulkan_frame_get_instance_private (self);

  priv->pool_n_sets = 4;
  priv->pool_n_images = 8;
  priv->pool_n_buffers = 8;
}

void
gsk_vulkan_semaphores_add_wait (GskVulkanSemaphores  *self,
                                VkSemaphore           semaphore,
                                uint64_t              semaphore_wait,
                                VkPipelineStageFlags  stage)
{
  gsk_semaphores_append (&self->wait_semaphores, semaphore);
  gsk_semaphore_values_append (&self->wait_semaphore_values, semaphore_wait);
  gsk_pipeline_stages_append (&self->wait_stages, stage);
}

void
gsk_vulkan_semaphores_add_signal (GskVulkanSemaphores  *self,
                                  VkSemaphore           semaphore)
{
  gsk_semaphores_append (&self->signal_semaphores, semaphore);
}


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

¤ Dauer der Verarbeitung: 0.10 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