blob: 93303adfb8574b3fff740d99aa5be9a85efa8ebf [file]
#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