#include "vk_conversion.h"
#include "backend/vulkan/vk_api.h"
namespace vk {
namespace {
VkImageUsageFlags image_usage_bit_to_vk(ImageUsage flag) {
switch (flag) {
case ImageUsage::ColorAttachment:
return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
case ImageUsage::DepthAttachment:
return VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
case ImageUsage::StencilAttachment:
return VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
case ImageUsage::Sampled:
return VK_IMAGE_USAGE_SAMPLED_BIT;
case ImageUsage::Storage:
return VK_IMAGE_USAGE_STORAGE_BIT;
case ImageUsage::TransferSrc:
return VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
case ImageUsage::TransferDst:
return VK_IMAGE_USAGE_TRANSFER_DST_BIT;
case ImageUsage::InputAttachment:
return VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
default:
return 0;
}
}
} // anonymous namespace
VkImageAspectFlags image_aspect_bit_to_vk(ImageAspect flag) {
switch (flag) {
case ImageAspect::Color:
return VK_IMAGE_ASPECT_COLOR_BIT;
case ImageAspect::Depth:
return VK_IMAGE_ASPECT_DEPTH_BIT;
case ImageAspect::Stencil:
return VK_IMAGE_ASPECT_STENCIL_BIT;
default:
return 0;
}
}
VkFormat image_format_to_vk(ImageFormat format) {
switch (format) {
case ImageFormat::UNDEFINED:
return VK_FORMAT_UNDEFINED;
case ImageFormat::R8_UNORM:
return VK_FORMAT_R8_UNORM;
case ImageFormat::RGBA8_UNORM:
return VK_FORMAT_R8G8B8A8_UNORM;
case ImageFormat::RGBA8_SRGB:
return VK_FORMAT_R8G8B8A8_SRGB;
case ImageFormat::BGRA8_UNORM:
return VK_FORMAT_B8G8R8A8_UNORM;
case ImageFormat::ASTC6X6_SRGB:
return VK_FORMAT_ASTC_6x6_SRGB_BLOCK;
case ImageFormat::ASTC6X6_UNORM:
return VK_FORMAT_ASTC_6x6_UNORM_BLOCK;
case ImageFormat::BC7_SRGB:
return VK_FORMAT_BC7_SRGB_BLOCK;
case ImageFormat::BC7_UNORM:
return VK_FORMAT_BC7_UNORM_BLOCK;
case ImageFormat::D32_FLOAT:
return VK_FORMAT_D32_SFLOAT;
case ImageFormat::RGBA16_FLOAT:
return VK_FORMAT_R16G16B16A16_SFLOAT;
case ImageFormat::RGBA32_FLOAT:
return VK_FORMAT_R32G32B32A32_SFLOAT;
case ImageFormat::R32_FLOAT:
return VK_FORMAT_R32_SFLOAT;
case ImageFormat::R32_UINT:
return VK_FORMAT_R32_UINT;
case ImageFormat::R16_FLOAT:
return VK_FORMAT_R16_SFLOAT;
case ImageFormat::R10G10B10A2_UNORM:
return VK_FORMAT_A2B10G10R10_UNORM_PACK32;
case ImageFormat::RG16_FLOAT:
return VK_FORMAT_R16G16_SFLOAT;
case ImageFormat::RG32_FLOAT:
return VK_FORMAT_R32G32_SFLOAT;
case ImageFormat::RGB32_FLOAT:
return VK_FORMAT_R32G32B32_SFLOAT;
default:
return VK_FORMAT_UNDEFINED;
}
}
ImageFormat image_format_from_vk(VkFormat format) {
switch (format) {
case VK_FORMAT_UNDEFINED:
return ImageFormat::UNDEFINED;
case VK_FORMAT_R8_UNORM:
return ImageFormat::R8_UNORM;
case VK_FORMAT_R8G8B8A8_UNORM:
return ImageFormat::RGBA8_UNORM;
case VK_FORMAT_R8G8B8A8_SRGB:
return ImageFormat::RGBA8_SRGB;
case VK_FORMAT_B8G8R8A8_UNORM:
return ImageFormat::BGRA8_UNORM;
case VK_FORMAT_ASTC_6x6_SRGB_BLOCK:
return ImageFormat::ASTC6X6_SRGB;
case VK_FORMAT_ASTC_6x6_UNORM_BLOCK:
return ImageFormat::ASTC6X6_UNORM;
case VK_FORMAT_BC7_SRGB_BLOCK:
return ImageFormat::BC7_SRGB;
case VK_FORMAT_BC7_UNORM_BLOCK:
return ImageFormat::BC7_UNORM;
case VK_FORMAT_D32_SFLOAT:
return ImageFormat::D32_FLOAT;
case VK_FORMAT_R16G16B16A16_SFLOAT:
return ImageFormat::RGBA16_FLOAT;
case VK_FORMAT_R32G32B32A32_SFLOAT:
return ImageFormat::RGBA32_FLOAT;
case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
return ImageFormat::R10G10B10A2_UNORM;
case VK_FORMAT_R16G16_SFLOAT:
return ImageFormat::RG16_FLOAT;
case VK_FORMAT_R32_UINT:
return ImageFormat::R32_UINT;
default:
return ImageFormat::UNDEFINED;
}
}
VkImageViewType image_view_type_to_vk(TextureViewDimension type) {
switch (type) {
case TextureViewDimension::TEXTURE_2D:
return VK_IMAGE_VIEW_TYPE_2D;
case TextureViewDimension::TEXTURE_2D_ARRAY:
return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
case TextureViewDimension::TEXTURE_CUBE:
return VK_IMAGE_VIEW_TYPE_CUBE;
case TextureViewDimension::TEXTURE_3D:
return VK_IMAGE_VIEW_TYPE_3D;
}
return VK_IMAGE_VIEW_TYPE_2D;
}
VkComponentSwizzle component_swizzle_to_vk(ComponentSwizzle swizzle) {
switch (swizzle) {
case ComponentSwizzle::Identity:
return VK_COMPONENT_SWIZZLE_IDENTITY;
case ComponentSwizzle::R:
return VK_COMPONENT_SWIZZLE_R;
case ComponentSwizzle::G:
return VK_COMPONENT_SWIZZLE_G;
case ComponentSwizzle::B:
return VK_COMPONENT_SWIZZLE_B;
case ComponentSwizzle::A:
return VK_COMPONENT_SWIZZLE_A;
case ComponentSwizzle::Zero:
return VK_COMPONENT_SWIZZLE_ZERO;
case ComponentSwizzle::One:
return VK_COMPONENT_SWIZZLE_ONE;
}
return VK_COMPONENT_SWIZZLE_IDENTITY;
}
VkImageUsageFlags image_usage_to_vk(Device &device, ImageDesc const &desc) {
VkImageUsageFlags flags = 0;
u32 bits = static_cast<u32>(desc.usage);
for (int i = 0; i < 8; ++i) {
if (bits & (1u << i)) {
flags |= image_usage_bit_to_vk(static_cast<ImageUsage>(1u << i));
}
}
VkFormatProperties props{};
vkGetPhysicalDeviceFormatProperties(device.physical, image_format_to_vk(desc.format), &props);
if (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) {
flags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
}
if (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) {
flags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
}
return flags;
}
VkImageAspectFlags image_aspect_to_vk(ImageAspect aspect) {
VkImageAspectFlags flags = 0;
u32 bits = static_cast<u32>(aspect);
if (bits & static_cast<u32>(ImageAspect::Color)) {
flags |= VK_IMAGE_ASPECT_COLOR_BIT;
}
if (bits & static_cast<u32>(ImageAspect::Depth)) {
flags |= VK_IMAGE_ASPECT_DEPTH_BIT;
}
if (bits & static_cast<u32>(ImageAspect::Stencil)) {
flags |= VK_IMAGE_ASPECT_STENCIL_BIT;
}
return flags;
}
VkSamplerAddressMode sampler_address_to_vk(SamplerAddressMode mode) {
switch (mode) {
case SamplerAddressMode::WRAP:
return VK_SAMPLER_ADDRESS_MODE_REPEAT;
case SamplerAddressMode::MIRROR:
return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
case SamplerAddressMode::CLAMP:
return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
case SamplerAddressMode::BORDER:
return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
default:
return VK_SAMPLER_ADDRESS_MODE_REPEAT;
}
}
VkFilter sampler_filter_to_vk(SamplerFilter filter) {
switch (filter) {
case SamplerFilter::POINT:
return VK_FILTER_NEAREST;
case SamplerFilter::LINEAR:
case SamplerFilter::ANISOTROPIC:
return VK_FILTER_LINEAR;
default:
return VK_FILTER_NEAREST;
}
}
VkCompareOp sampler_comparison_to_vk(SamplerComparisonFunc func) {
switch (func) {
case SamplerComparisonFunc::NEVER:
return VK_COMPARE_OP_NEVER;
case SamplerComparisonFunc::LESS:
return VK_COMPARE_OP_LESS;
case SamplerComparisonFunc::EQUAL:
return VK_COMPARE_OP_EQUAL;
case SamplerComparisonFunc::LESS_EQUAL:
return VK_COMPARE_OP_LESS_OR_EQUAL;
case SamplerComparisonFunc::GREATER:
return VK_COMPARE_OP_GREATER;
case SamplerComparisonFunc::NOT_EQUAL:
return VK_COMPARE_OP_NOT_EQUAL;
case SamplerComparisonFunc::GREATER_EQUAL:
return VK_COMPARE_OP_GREATER_OR_EQUAL;
case SamplerComparisonFunc::ALWAYS:
return VK_COMPARE_OP_ALWAYS;
default:
return VK_COMPARE_OP_ALWAYS;
}
}
VkPrimitiveTopology pipeline_topology_to_vk(rhi::PipelineTopology topology) {
switch (topology) {
case rhi::PipelineTopology::TRIANGLES:
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
case rhi::PipelineTopology::LINES:
return VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
case rhi::PipelineTopology::POINTS:
return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
default:
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
}
}
VkPolygonMode pipeline_fill_mode_to_vk(rhi::PipelineFillMode fill_mode) {
switch (fill_mode) {
case rhi::PipelineFillMode::SOLID:
return VK_POLYGON_MODE_FILL;
case rhi::PipelineFillMode::WIREFRAME:
return VK_POLYGON_MODE_LINE;
default:
return VK_POLYGON_MODE_FILL;
}
}
VkCullModeFlags pipeline_cull_mode_to_vk(rhi::PipelineCullMode cull_mode) {
switch (cull_mode) {
case rhi::PipelineCullMode::NONE:
return VK_CULL_MODE_NONE;
case rhi::PipelineCullMode::FRONT:
return VK_CULL_MODE_FRONT_BIT;
case rhi::PipelineCullMode::BACK:
return VK_CULL_MODE_BACK_BIT;
default:
return VK_CULL_MODE_BACK_BIT;
}
}
VkFrontFace triangle_winding_to_vk(rhi::PipelineTriangleWindingOrder winding) {
switch (winding) {
case rhi::PipelineTriangleWindingOrder::CW:
return VK_FRONT_FACE_CLOCKWISE;
case rhi::PipelineTriangleWindingOrder::CCW:
return VK_FRONT_FACE_COUNTER_CLOCKWISE;
default:
return VK_FRONT_FACE_CLOCKWISE;
}
}
VkCompareOp pipeline_compare_op_to_vk(rhi::PipelineCompareOp compare_op) {
switch (compare_op) {
case rhi::PipelineCompareOp::NEVER:
return VK_COMPARE_OP_NEVER;
case rhi::PipelineCompareOp::LESS:
return VK_COMPARE_OP_LESS;
case rhi::PipelineCompareOp::EQUAL:
return VK_COMPARE_OP_EQUAL;
case rhi::PipelineCompareOp::LESS_EQUAL:
return VK_COMPARE_OP_LESS_OR_EQUAL;
case rhi::PipelineCompareOp::GREATER:
return VK_COMPARE_OP_GREATER;
case rhi::PipelineCompareOp::NOT_EQUAL:
return VK_COMPARE_OP_NOT_EQUAL;
case rhi::PipelineCompareOp::GREATER_EQUAL:
return VK_COMPARE_OP_GREATER_OR_EQUAL;
case rhi::PipelineCompareOp::ALWAYS:
return VK_COMPARE_OP_ALWAYS;
default:
return VK_COMPARE_OP_LESS;
}
}
VkShaderStageFlags shader_stage_to_vk(rhi::ShaderStage stages) {
if ((stages & rhi::ShaderStage::ALL) == rhi::ShaderStage::ALL) {
return VK_SHADER_STAGE_ALL;
}
VkShaderStageFlags flags = 0;
if ((stages & rhi::ShaderStage::VERTEX) == rhi::ShaderStage::VERTEX) {
flags |= VK_SHADER_STAGE_VERTEX_BIT;
}
if ((stages & rhi::ShaderStage::FRAGMENT) == rhi::ShaderStage::FRAGMENT) {
flags |= VK_SHADER_STAGE_FRAGMENT_BIT;
}
if ((stages & rhi::ShaderStage::COMPUTE) == rhi::ShaderStage::COMPUTE) {
flags |= VK_SHADER_STAGE_COMPUTE_BIT;
}
if ((stages & rhi::ShaderStage::MESH) == rhi::ShaderStage::MESH) {
flags |= VK_SHADER_STAGE_MESH_BIT_EXT;
}
if ((stages & rhi::ShaderStage::TASK) == rhi::ShaderStage::TASK) {
flags |= VK_SHADER_STAGE_TASK_BIT_EXT;
}
if ((stages & rhi::ShaderStage::GEOMETRY) == rhi::ShaderStage::GEOMETRY) {
flags |= VK_SHADER_STAGE_GEOMETRY_BIT;
}
if ((stages & rhi::ShaderStage::RAYGEN) == rhi::ShaderStage::RAYGEN) {
flags |= VK_SHADER_STAGE_RAYGEN_BIT_KHR;
}
if ((stages & rhi::ShaderStage::CLOSEST_HIT) == rhi::ShaderStage::CLOSEST_HIT) {
flags |= VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR;
}
if ((stages & rhi::ShaderStage::ANY_HIT) == rhi::ShaderStage::ANY_HIT) {
flags |= VK_SHADER_STAGE_ANY_HIT_BIT_KHR;
}
if ((stages & rhi::ShaderStage::MISS) == rhi::ShaderStage::MISS) {
flags |= VK_SHADER_STAGE_MISS_BIT_KHR;
}
if ((stages & rhi::ShaderStage::INTERSECTION) == rhi::ShaderStage::INTERSECTION) {
flags |= VK_SHADER_STAGE_INTERSECTION_BIT_KHR;
}
if ((stages & rhi::ShaderStage::CALLABLE) == rhi::ShaderStage::CALLABLE) {
flags |= VK_SHADER_STAGE_CALLABLE_BIT_KHR;
}
return flags;
}
enum VkBlendFactor pipeline_blend_factor_to_vk(rhi::PipelineBlendFactor factor) {
switch (factor) {
case rhi::PipelineBlendFactor::ZERO:
return VK_BLEND_FACTOR_ZERO;
case rhi::PipelineBlendFactor::ONE:
return VK_BLEND_FACTOR_ONE;
case rhi::PipelineBlendFactor::SRC_ALPHA:
return VK_BLEND_FACTOR_SRC_ALPHA;
case rhi::PipelineBlendFactor::ONE_MINUS_SRC_ALPHA:
return VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
case rhi::PipelineBlendFactor::DST_ALPHA:
return VK_BLEND_FACTOR_DST_ALPHA;
case rhi::PipelineBlendFactor::ONE_MINUS_DST_ALPHA:
return VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA;
case rhi::PipelineBlendFactor::SRC_COLOR:
return VK_BLEND_FACTOR_SRC_COLOR;
case rhi::PipelineBlendFactor::ONE_MINUS_SRC_COLOR:
return VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR;
case rhi::PipelineBlendFactor::DST_COLOR:
return VK_BLEND_FACTOR_DST_COLOR;
case rhi::PipelineBlendFactor::ONE_MINUS_DST_COLOR:
return VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR;
case rhi::PipelineBlendFactor::SRC_ALPHA_SATURATE:
return VK_BLEND_FACTOR_SRC_ALPHA_SATURATE;
default:
return VK_BLEND_FACTOR_ONE;
}
}
enum VkBlendOp pipeline_blend_op_to_vk(rhi::PipelineBlendOp op) {
switch (op) {
case rhi::PipelineBlendOp::ADD:
return VK_BLEND_OP_ADD;
case rhi::PipelineBlendOp::SUBTRACT:
return VK_BLEND_OP_SUBTRACT;
case rhi::PipelineBlendOp::REVERSE_SUBTRACT:
return VK_BLEND_OP_REVERSE_SUBTRACT;
case rhi::PipelineBlendOp::MIN:
return VK_BLEND_OP_MIN;
case rhi::PipelineBlendOp::MAX:
return VK_BLEND_OP_MAX;
default:
return VK_BLEND_OP_ADD;
}
}
VkSampleCountFlagBits sample_count_to_vk(rhi::SampleCount samples) {
switch (samples) {
case rhi::SampleCount::Sample1:
return VK_SAMPLE_COUNT_1_BIT;
case rhi::SampleCount::Sample2:
return VK_SAMPLE_COUNT_2_BIT;
case rhi::SampleCount::Sample4:
return VK_SAMPLE_COUNT_4_BIT;
case rhi::SampleCount::Sample8:
return VK_SAMPLE_COUNT_8_BIT;
case rhi::SampleCount::Sample16:
return VK_SAMPLE_COUNT_16_BIT;
case rhi::SampleCount::Sample32:
return VK_SAMPLE_COUNT_32_BIT;
case rhi::SampleCount::Sample64:
return VK_SAMPLE_COUNT_64_BIT;
}
return VK_SAMPLE_COUNT_1_BIT;
}
VkCommandPoolCreateFlags to_vk_cmd_pool_flags(CmdPoolUsage flags) {
VkCommandPoolCreateFlags vk_flags = 0;
if (Any(flags, CmdPoolUsage::Transient)) {
vk_flags |= VK_COMMAND_POOL_CREATE_TRANSIENT_BIT;
}
if (Any(flags, CmdPoolUsage::ResetCommandBuffer)) {
vk_flags |= VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
}
if (Any(flags, CmdPoolUsage::Protected)) {
vk_flags |= VK_COMMAND_POOL_CREATE_PROTECTED_BIT;
}
return vk_flags;
}
VkCommandBufferLevel to_vk_cmd_buffer_level(CmdBufferLevel level) {
switch (level) {
case CmdBufferLevel::Primary:
return VK_COMMAND_BUFFER_LEVEL_PRIMARY;
case CmdBufferLevel::Secondary:
return VK_COMMAND_BUFFER_LEVEL_SECONDARY;
default:
return VK_COMMAND_BUFFER_LEVEL_PRIMARY;
}
}
VkCommandBufferUsageFlags to_vk_cmd_buffer_usage_flags(CmdBufferUsage flags) {
VkCommandBufferUsageFlags vk_flags = 0;
if (Any(flags, CmdBufferUsage::OneTimeSubmit)) {
vk_flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
}
if (Any(flags, CmdBufferUsage::RenderPassContinue)) {
vk_flags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
}
if (Any(flags, CmdBufferUsage::SimultaneousUse)) {
vk_flags |= VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
}
return vk_flags;
}
VkPipelineStageFlags2 pipeline_stage_flags_to_vk(PipelineStages stages) {
return static_cast<VkPipelineStageFlags2>(stages);
}
static bool is_depth_aspect(ImageAspect aspect) {
return Any(aspect, ImageAspect::Depth) || Any(aspect, ImageAspect::Stencil);
}
StateSync image_state_to_vk(ResourceState state, ImageAspect aspect) {
const bool depth = is_depth_aspect(aspect);
switch (state) {
case ResourceState::Idle:
return {};
case ResourceState::ColorDraw:
return {
VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
};
case ResourceState::ColorFetch:
return {
VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
};
case ResourceState::DepthDraw:
return {
VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT,
VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
};
case ResourceState::DepthFetch:
return {
VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT,
VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
};
case ResourceState::TextureSample:
return {
VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT,
VK_ACCESS_2_SHADER_READ_BIT,
depth ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
};
case ResourceState::TextureSampleNonFragment:
return {
VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
VK_ACCESS_2_SHADER_READ_BIT,
depth ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
};
case ResourceState::StorageRead:
return {VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, VK_ACCESS_2_SHADER_STORAGE_READ_BIT, VK_IMAGE_LAYOUT_GENERAL};
case ResourceState::StorageReadWrite:
return {
VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
VK_ACCESS_2_SHADER_READ_BIT | VK_ACCESS_2_SHADER_WRITE_BIT,
VK_IMAGE_LAYOUT_GENERAL
};
case ResourceState::TransferFrom:
return {VK_PIPELINE_STAGE_2_TRANSFER_BIT, VK_ACCESS_2_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL};
case ResourceState::TransferTo:
return {VK_PIPELINE_STAGE_2_TRANSFER_BIT, VK_ACCESS_2_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL};
case ResourceState::Display:
return {VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT, VK_ACCESS_2_NONE, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR};
case ResourceState::AccelBuild:
return {
VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_KHR,
VK_ACCESS_2_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_2_ACCELERATION_STRUCTURE_WRITE_BIT_KHR,
VK_IMAGE_LAYOUT_GENERAL
};
case ResourceState::AccelTrace:
return {VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, VK_ACCESS_2_SHADER_READ_BIT, VK_IMAGE_LAYOUT_GENERAL};
default:
return {VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, VK_ACCESS_2_SHADER_READ_BIT, VK_IMAGE_LAYOUT_GENERAL};
}
}
StateSync buffer_state_to_vk(ResourceState state) {
switch (state) {
case ResourceState::Idle:
return {};
case ResourceState::StorageRead:
return {
VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT |
VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
VK_ACCESS_2_SHADER_STORAGE_READ_BIT,
VK_IMAGE_LAYOUT_UNDEFINED
};
case ResourceState::StorageReadWrite:
return {
VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
VK_ACCESS_2_SHADER_READ_BIT | VK_ACCESS_2_SHADER_WRITE_BIT,
VK_IMAGE_LAYOUT_UNDEFINED
};
case ResourceState::VertexFetch:
return {
VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT,
VK_ACCESS_2_VERTEX_ATTRIBUTE_READ_BIT,
VK_IMAGE_LAYOUT_UNDEFINED
};
case ResourceState::IndexFetch:
return {VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT, VK_ACCESS_2_INDEX_READ_BIT, VK_IMAGE_LAYOUT_UNDEFINED};
case ResourceState::IndirectFetch:
return {
VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT, VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT, VK_IMAGE_LAYOUT_UNDEFINED
};
case ResourceState::UniformRead:
return {
VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT |
VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
VK_ACCESS_2_UNIFORM_READ_BIT,
VK_IMAGE_LAYOUT_UNDEFINED
};
case ResourceState::TransferFrom:
return {VK_PIPELINE_STAGE_2_TRANSFER_BIT, VK_ACCESS_2_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_UNDEFINED};
case ResourceState::TransferTo:
return {
VK_PIPELINE_STAGE_2_TRANSFER_BIT | VK_PIPELINE_STAGE_2_CLEAR_BIT,
VK_ACCESS_2_TRANSFER_WRITE_BIT,
VK_IMAGE_LAYOUT_UNDEFINED
};
case ResourceState::TextureSample:
case ResourceState::TextureSampleNonFragment:
return {
VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT |
VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
VK_ACCESS_2_SHADER_READ_BIT,
VK_IMAGE_LAYOUT_UNDEFINED
};
case ResourceState::AccelBuild:
return {
VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_KHR,
VK_ACCESS_2_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_2_ACCELERATION_STRUCTURE_WRITE_BIT_KHR,
VK_IMAGE_LAYOUT_UNDEFINED
};
case ResourceState::AccelTrace:
return {
VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_KHR,
VK_ACCESS_2_ACCELERATION_STRUCTURE_READ_BIT_KHR,
VK_IMAGE_LAYOUT_UNDEFINED
};
case ResourceState::HostRead:
return {VK_PIPELINE_STAGE_2_HOST_BIT, VK_ACCESS_2_HOST_READ_BIT, VK_IMAGE_LAYOUT_UNDEFINED};
default:
return {};
}
}
} // namespace vk