#include "config.h" #include "gskvulkanpushconstantsprivate.h" #include "gskroundedrectprivate.h" #include "gsktransform.h" typedef struct _GskVulkanPushConstantsWire GskVulkanPushConstantsWire; struct _GskVulkanPushConstantsWire { struct { float mvp[16]; float clip[12]; } common; }; void gsk_vulkan_push_constants_init (GskVulkanPushConstants *constants, const graphene_matrix_t *mvp, const graphene_rect_t *viewport) { graphene_matrix_init_from_matrix (&constants->mvp, mvp); gsk_vulkan_clip_init_empty (&constants->clip, viewport); } void gsk_vulkan_push_constants_init_copy (GskVulkanPushConstants *self, const GskVulkanPushConstants *src) { *self = *src; } gboolean gsk_vulkan_push_constants_transform (GskVulkanPushConstants *self, const GskVulkanPushConstants *src, GskTransform *transform, const graphene_rect_t *viewport) { graphene_matrix_t matrix; if (!gsk_vulkan_clip_transform (&self->clip, &src->clip, transform, viewport)) return FALSE; gsk_transform_to_matrix (transform, &matrix); graphene_matrix_multiply (&matrix, &src->mvp, &self->mvp); return TRUE; } gboolean gsk_vulkan_push_constants_intersect_rect (GskVulkanPushConstants *self, const GskVulkanPushConstants *src, const graphene_rect_t *rect) { if (!gsk_vulkan_clip_intersect_rect (&self->clip, &src->clip, rect)) return FALSE; graphene_matrix_init_from_matrix (&self->mvp, &src->mvp); return TRUE; } gboolean gsk_vulkan_push_constants_intersect_rounded (GskVulkanPushConstants *self, const GskVulkanPushConstants *src, const GskRoundedRect *rect) { if (!gsk_vulkan_clip_intersect_rounded_rect (&self->clip, &src->clip, rect)) return FALSE; graphene_matrix_init_from_matrix (&self->mvp, &src->mvp); return TRUE; } static void gsk_vulkan_push_constants_wire_init (GskVulkanPushConstantsWire *wire, const GskVulkanPushConstants *self) { graphene_matrix_to_float (&self->mvp, wire->common.mvp); gsk_rounded_rect_to_float (&self->clip.rect, wire->common.clip); } void gsk_vulkan_push_constants_push (const GskVulkanPushConstants *self, VkCommandBuffer command_buffer, VkPipelineLayout pipeline_layout) { GskVulkanPushConstantsWire wire; gsk_vulkan_push_constants_wire_init (&wire, self); vkCmdPushConstants (command_buffer, pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, G_STRUCT_OFFSET (GskVulkanPushConstantsWire, common), sizeof (wire.common), &wire.common); } uint32_t gsk_vulkan_push_constants_get_range_count (void) { return 1; } const VkPushConstantRange * gsk_vulkan_push_constants_get_ranges (void) { static const VkPushConstantRange ranges[1] = { { .stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, .offset = G_STRUCT_OFFSET (GskVulkanPushConstantsWire, common), .size = sizeof (((GskVulkanPushConstantsWire *) 0)->common) } }; return ranges; }