| #include "rive/renderer/gpu.hpp" | |
| #include "rive/renderer/vulkan/vkutil.hpp" | |
| #include "shaders/constants.glsl" | |
| #include <array> | |
| #include <vulkan/vulkan.h> | |
| // Common layout descriptors shared by various pipelines. | |
| namespace rive::gpu::layout | |
| { | |
| // rasterOrdering mode with a non-input-attachment renderTarget currently | |
| // requires the most attachments in a single pass: all 4 PLS planes plus one | |
| // more resolve target. | |
| constexpr static uint32_t MAX_RENDER_PASS_ATTACHMENTS = PLS_PLANE_COUNT + 1; | |
| constexpr VkVertexInputBindingDescription PATH_INPUT_BINDINGS[] = {{ | |
| .binding = 0, | |
| .stride = sizeof(rive::gpu::PatchVertex), | |
| .inputRate = VK_VERTEX_INPUT_RATE_VERTEX, | |
| }}; | |
| constexpr VkVertexInputAttributeDescription PATH_VERTEX_ATTRIBS[] = { | |
| { | |
| .location = 0, | |
| .binding = 0, | |
| .format = VK_FORMAT_R32G32B32A32_SFLOAT, | |
| .offset = 0, | |
| }, | |
| { | |
| .location = 1, | |
| .binding = 0, | |
| .format = VK_FORMAT_R32G32B32A32_SFLOAT, | |
| .offset = 4 * sizeof(float), | |
| }, | |
| }; | |
| constexpr VkPipelineVertexInputStateCreateInfo PATH_VERTEX_INPUT_STATE = { | |
| .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, | |
| .vertexBindingDescriptionCount = std::size(PATH_INPUT_BINDINGS), | |
| .pVertexBindingDescriptions = PATH_INPUT_BINDINGS, | |
| .vertexAttributeDescriptionCount = std::size(PATH_VERTEX_ATTRIBS), | |
| .pVertexAttributeDescriptions = PATH_VERTEX_ATTRIBS, | |
| }; | |
| constexpr VkVertexInputBindingDescription INTERIOR_TRI_INPUT_BINDINGS[] = {{ | |
| .binding = 0, | |
| .stride = sizeof(rive::gpu::TriangleVertex), | |
| .inputRate = VK_VERTEX_INPUT_RATE_VERTEX, | |
| }}; | |
| constexpr VkVertexInputAttributeDescription INTERIOR_TRI_VERTEX_ATTRIBS[] = { | |
| { | |
| .location = 0, | |
| .binding = 0, | |
| .format = VK_FORMAT_R32G32B32_SFLOAT, | |
| .offset = 0, | |
| }, | |
| }; | |
| constexpr VkPipelineVertexInputStateCreateInfo INTERIOR_TRI_VERTEX_INPUT_STATE = | |
| { | |
| .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, | |
| .vertexBindingDescriptionCount = std::size(INTERIOR_TRI_INPUT_BINDINGS), | |
| .pVertexBindingDescriptions = INTERIOR_TRI_INPUT_BINDINGS, | |
| .vertexAttributeDescriptionCount = | |
| std::size(INTERIOR_TRI_VERTEX_ATTRIBS), | |
| .pVertexAttributeDescriptions = INTERIOR_TRI_VERTEX_ATTRIBS, | |
| }; | |
| // Concatenates the given geometryAttribs with Rive's ImageDrawInstance attribs | |
| // (bound at 'binding'). | |
| template <typename... GeometryAttribs> | |
| constexpr std::array<VkVertexInputAttributeDescription, | |
| sizeof...(GeometryAttribs) + IMAGE_ATTRIB_COUNT> | |
| appendImageDrawInstanceAttribs(uint32_t binding, | |
| GeometryAttribs... geometryAttribs) | |
| { | |
| return {{ | |
| geometryAttribs..., | |
| { | |
| .location = IMAGE_VIEW_MATRIX_ATTRIB_IDX, | |
| .binding = binding, | |
| .format = VK_FORMAT_R32G32B32A32_SFLOAT, | |
| .offset = (IMAGE_VIEW_MATRIX_ATTRIB_IDX - IMAGE_FIRST_ATTRIB_IDX) * | |
| sizeof(uint32_t) * 4, | |
| }, | |
| { | |
| .location = IMAGE_CLIP_RECT_INVERSE_MATRIX_ATTRIB_IDX, | |
| .binding = binding, | |
| .format = VK_FORMAT_R32G32B32A32_SFLOAT, | |
| .offset = (IMAGE_CLIP_RECT_INVERSE_MATRIX_ATTRIB_IDX - | |
| IMAGE_FIRST_ATTRIB_IDX) * | |
| sizeof(uint32_t) * 4, | |
| }, | |
| { | |
| .location = IMAGE_TRANSLATES_ATTRIB_IDX, | |
| .binding = binding, | |
| .format = VK_FORMAT_R32G32B32A32_SFLOAT, | |
| .offset = (IMAGE_TRANSLATES_ATTRIB_IDX - IMAGE_FIRST_ATTRIB_IDX) * | |
| sizeof(uint32_t) * 4, | |
| }, | |
| { | |
| .location = IMAGE_PACKED_ATTRIBS_IDX, | |
| .binding = binding, | |
| .format = VK_FORMAT_R32G32B32A32_UINT, | |
| .offset = (IMAGE_PACKED_ATTRIBS_IDX - IMAGE_FIRST_ATTRIB_IDX) * | |
| sizeof(uint32_t) * 4, | |
| }, | |
| }}; | |
| } | |
| constexpr uint32_t ImageRectGeometryBufferBinding = 0; | |
| constexpr uint32_t ImageRectImageAttribBufferBinding = 1; | |
| constexpr VkVertexInputBindingDescription ImageRectInputBindings[] = { | |
| { | |
| .binding = ImageRectGeometryBufferBinding, | |
| .stride = sizeof(rive::gpu::ImageRectVertex), | |
| .inputRate = VK_VERTEX_INPUT_RATE_VERTEX, | |
| }, | |
| { | |
| .binding = ImageRectImageAttribBufferBinding, | |
| .stride = sizeof(rive::gpu::ImageDrawInstance), | |
| .inputRate = VK_VERTEX_INPUT_RATE_INSTANCE, | |
| }, | |
| }; | |
| constexpr auto ImageRectVertexAttribs = appendImageDrawInstanceAttribs( | |
| ImageRectImageAttribBufferBinding, | |
| VkVertexInputAttributeDescription{ | |
| .location = 0, | |
| .binding = ImageRectGeometryBufferBinding, | |
| .format = VK_FORMAT_R32G32B32A32_SFLOAT, | |
| .offset = 0, | |
| }); | |
| constexpr VkPipelineVertexInputStateCreateInfo IMAGE_RECT_VERTEX_INPUT_STATE = { | |
| .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, | |
| .vertexBindingDescriptionCount = std::size(ImageRectInputBindings), | |
| .pVertexBindingDescriptions = ImageRectInputBindings, | |
| .vertexAttributeDescriptionCount = std::size(ImageRectVertexAttribs), | |
| .pVertexAttributeDescriptions = ImageRectVertexAttribs.data(), | |
| }; | |
| constexpr uint32_t ImageMeshVertexBufferBinding = 0; | |
| constexpr uint32_t ImageMeshUVBufferBinding = 1; | |
| constexpr uint32_t ImageMeshImageAttribBufferBinding = 2; | |
| constexpr VkVertexInputBindingDescription ImageMeshInputBindings[] = { | |
| { | |
| .binding = ImageMeshVertexBufferBinding, | |
| .stride = sizeof(float) * 2, | |
| .inputRate = VK_VERTEX_INPUT_RATE_VERTEX, | |
| }, | |
| { | |
| .binding = ImageMeshUVBufferBinding, | |
| .stride = sizeof(float) * 2, | |
| .inputRate = VK_VERTEX_INPUT_RATE_VERTEX, | |
| }, | |
| { | |
| .binding = ImageMeshImageAttribBufferBinding, | |
| .stride = sizeof(rive::gpu::ImageDrawInstance), | |
| .inputRate = VK_VERTEX_INPUT_RATE_INSTANCE, | |
| }, | |
| }; | |
| constexpr auto ImageMeshVertexAttribs = | |
| appendImageDrawInstanceAttribs(ImageMeshImageAttribBufferBinding, | |
| VkVertexInputAttributeDescription{ | |
| .location = 0, | |
| .binding = ImageMeshVertexBufferBinding, | |
| .format = VK_FORMAT_R32G32_SFLOAT, | |
| .offset = 0, | |
| }, | |
| VkVertexInputAttributeDescription{ | |
| .location = 1, | |
| .binding = ImageMeshUVBufferBinding, | |
| .format = VK_FORMAT_R32G32_SFLOAT, | |
| .offset = 0, | |
| }); | |
| constexpr VkPipelineVertexInputStateCreateInfo IMAGE_MESH_VERTEX_INPUT_STATE = { | |
| .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, | |
| .vertexBindingDescriptionCount = std::size(ImageMeshInputBindings), | |
| .pVertexBindingDescriptions = ImageMeshInputBindings, | |
| .vertexAttributeDescriptionCount = std::size(ImageMeshVertexAttribs), | |
| .pVertexAttributeDescriptions = ImageMeshVertexAttribs.data(), | |
| }; | |
| constexpr VkPipelineVertexInputStateCreateInfo EMPTY_VERTEX_INPUT_STATE = { | |
| .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, | |
| .vertexBindingDescriptionCount = 0, | |
| .vertexAttributeDescriptionCount = 0, | |
| }; | |
| constexpr VkPipelineInputAssemblyStateCreateInfo INPUT_ASSEMBLY_TRIANGLE_STRIP = | |
| { | |
| .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, | |
| .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, | |
| }; | |
| constexpr VkPipelineInputAssemblyStateCreateInfo INPUT_ASSEMBLY_TRIANGLE_LIST = | |
| { | |
| .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, | |
| .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, | |
| }; | |
| constexpr VkPipelineViewportStateCreateInfo SINGLE_VIEWPORT = { | |
| .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, | |
| .viewportCount = 1, | |
| .scissorCount = 1, | |
| }; | |
| constexpr VkPipelineRasterizationStateCreateInfo RASTER_STATE_CULL_BACK_CCW = { | |
| .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, | |
| .polygonMode = VK_POLYGON_MODE_FILL, | |
| .cullMode = VK_CULL_MODE_BACK_BIT, | |
| .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE, | |
| .lineWidth = 1.f, | |
| }; | |
| constexpr VkPipelineRasterizationStateCreateInfo RASTER_STATE_CULL_BACK_CW = { | |
| .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, | |
| .polygonMode = VK_POLYGON_MODE_FILL, | |
| .cullMode = VK_CULL_MODE_BACK_BIT, | |
| .frontFace = VK_FRONT_FACE_CLOCKWISE, | |
| .lineWidth = 1.f, | |
| }; | |
| constexpr VkPipelineRasterizationStateCreateInfo RASTER_STATE_CULL_NONE_CW = { | |
| .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, | |
| .polygonMode = VK_POLYGON_MODE_FILL, | |
| .cullMode = VK_CULL_MODE_NONE, | |
| .frontFace = VK_FRONT_FACE_CLOCKWISE, | |
| .lineWidth = 1.f, | |
| }; | |
| constexpr VkPipelineMultisampleStateCreateInfo MSAA_DISABLED = { | |
| .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, | |
| .rasterizationSamples = VK_SAMPLE_COUNT_1_BIT, | |
| }; | |
| constexpr VkPipelineColorBlendAttachmentState BLEND_DISABLED_VALUES = { | |
| .colorWriteMask = rive::gpu::vkutil::kColorWriteMaskRGBA}; | |
| constexpr VkPipelineColorBlendStateCreateInfo SINGLE_ATTACHMENT_BLEND_DISABLED = | |
| { | |
| .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, | |
| .attachmentCount = 1, | |
| .pAttachments = &BLEND_DISABLED_VALUES, | |
| }; | |
| constexpr VkDynamicState DYNAMIC_VIEWPORT_SCISSOR_VALUES[] = { | |
| VK_DYNAMIC_STATE_VIEWPORT, | |
| VK_DYNAMIC_STATE_SCISSOR, | |
| }; | |
| constexpr VkPipelineDynamicStateCreateInfo DYNAMIC_VIEWPORT_SCISSOR = { | |
| .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, | |
| .dynamicStateCount = std::size(DYNAMIC_VIEWPORT_SCISSOR_VALUES), | |
| .pDynamicStates = DYNAMIC_VIEWPORT_SCISSOR_VALUES, | |
| }; | |
| constexpr VkAttachmentReference SINGLE_ATTACHMENT_SUBPASS_REFERENCE = { | |
| .attachment = 0, | |
| .layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, | |
| }; | |
| constexpr VkSubpassDescription SINGLE_ATTACHMENT_SUBPASS = { | |
| .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, | |
| .colorAttachmentCount = 1, | |
| .pColorAttachments = &SINGLE_ATTACHMENT_SUBPASS_REFERENCE, | |
| }; | |
| } // namespace rive::gpu::layout |