123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955 |
- #include "Vulkan.h"
- #include <sstream>
- namespace love
- {
- namespace graphics
- {
- namespace vulkan
- {
- static uint32_t numShaderSwitches;
- static int vsync = 1;
- void Vulkan::shaderSwitch()
- {
- numShaderSwitches++;
- }
- uint32_t Vulkan::getNumShaderSwitches()
- {
- return numShaderSwitches;
- }
- void Vulkan::resetShaderSwitches()
- {
- numShaderSwitches = 0;
- }
- void Vulkan::setVsync(int value)
- {
- vsync = value;
- }
- int Vulkan::getVsync()
- {
- return vsync;
- }
- VkFormat Vulkan::getVulkanVertexFormat(DataFormat format)
- {
- switch (format)
- {
- case DATAFORMAT_FLOAT:
- return VK_FORMAT_R32_SFLOAT;
- case DATAFORMAT_FLOAT_VEC2:
- return VK_FORMAT_R32G32_SFLOAT;
- case DATAFORMAT_FLOAT_VEC3:
- return VK_FORMAT_R32G32B32_SFLOAT;
- case DATAFORMAT_FLOAT_VEC4:
- return VK_FORMAT_R32G32B32A32_SFLOAT;
- case DATAFORMAT_FLOAT_MAT2X2:
- case DATAFORMAT_FLOAT_MAT2X3:
- case DATAFORMAT_FLOAT_MAT2X4:
- case DATAFORMAT_FLOAT_MAT3X2:
- case DATAFORMAT_FLOAT_MAT3X3:
- case DATAFORMAT_FLOAT_MAT3X4:
- case DATAFORMAT_FLOAT_MAT4X2:
- case DATAFORMAT_FLOAT_MAT4X3:
- case DATAFORMAT_FLOAT_MAT4X4:
- throw love::Exception("unimplemented data format (matnxm)");
- case DATAFORMAT_INT32:
- return VK_FORMAT_R32_SINT;
- case DATAFORMAT_INT32_VEC2:
- return VK_FORMAT_R32G32_SINT;
- case DATAFORMAT_INT32_VEC3:
- return VK_FORMAT_R32G32B32_SINT;
- case DATAFORMAT_INT32_VEC4:
- return VK_FORMAT_R32G32B32A32_SINT;
- case DATAFORMAT_UINT32:
- return VK_FORMAT_R32_UINT;
- case DATAFORMAT_UINT32_VEC2:
- return VK_FORMAT_R32G32_UINT;
- case DATAFORMAT_UINT32_VEC3:
- return VK_FORMAT_R32G32B32_UINT;
- case DATAFORMAT_UINT32_VEC4:
- return VK_FORMAT_R32G32B32A32_UINT;
- case DATAFORMAT_SNORM8_VEC4:
- return VK_FORMAT_R8G8B8A8_SNORM;
- case DATAFORMAT_UNORM8_VEC4:
- return VK_FORMAT_R8G8B8A8_UNORM;
- case DATAFORMAT_INT8_VEC4:
- return VK_FORMAT_R8G8B8A8_SINT;
- case DATAFORMAT_UINT8_VEC4:
- return VK_FORMAT_R8G8B8A8_UINT;
- case DATAFORMAT_SNORM16_VEC2:
- return VK_FORMAT_R16G16_SNORM;
- case DATAFORMAT_SNORM16_VEC4:
- return VK_FORMAT_R16G16B16A16_SNORM;
- case DATAFORMAT_UNORM16_VEC2:
- return VK_FORMAT_R16G16_UNORM;
- case DATAFORMAT_UNORM16_VEC4:
- return VK_FORMAT_R16G16B16A16_UNORM;
- case DATAFORMAT_INT16_VEC2:
- return VK_FORMAT_R16G16_SINT;
- case DATAFORMAT_INT16_VEC4:
- return VK_FORMAT_R16G16B16A16_SINT;
- case DATAFORMAT_UINT16:
- return VK_FORMAT_R16_UINT;
- case DATAFORMAT_UINT16_VEC2:
- return VK_FORMAT_R16G16_UINT;
- case DATAFORMAT_UINT16_VEC4:
- return VK_FORMAT_R16G16B16A16_UINT;
- case DATAFORMAT_BOOL:
- case DATAFORMAT_BOOL_VEC2:
- case DATAFORMAT_BOOL_VEC3:
- case DATAFORMAT_BOOL_VEC4:
- throw love::Exception("unimplemented data format (bool)");
- default:
- throw love::Exception("unknown data format");
- }
- }
- TextureFormat Vulkan::getTextureFormat(PixelFormat format)
- {
- TextureFormat textureFormat{};
- switch (format)
- {
- case PIXELFORMAT_UNKNOWN:
- throw love::Exception("unknown pixel format");
- case PIXELFORMAT_NORMAL:
- textureFormat.internalFormat = VK_FORMAT_R8G8B8A8_SRGB;
- break;
- case PIXELFORMAT_HDR:
- throw love::Exception("unimplemented pixel format: hdr");
- case PIXELFORMAT_R8_UNORM:
- textureFormat.internalFormat = VK_FORMAT_R8_UNORM;
- break;
- case PIXELFORMAT_R8_INT:
- textureFormat.internalFormat = VK_FORMAT_R8_SINT;
- textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_SINT;
- break;
- case PIXELFORMAT_R8_UINT:
- textureFormat.internalFormat = VK_FORMAT_R8_UINT;
- textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_UINT;
- break;
- case PIXELFORMAT_R16_UNORM:
- textureFormat.internalFormat = VK_FORMAT_R16_UNORM;
- break;
- case PIXELFORMAT_R16_FLOAT:
- textureFormat.internalFormat = VK_FORMAT_R16_SFLOAT;
- break;
- case PIXELFORMAT_R16_INT:
- textureFormat.internalFormat = VK_FORMAT_R16_SINT;
- textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_SINT;
- break;
- case PIXELFORMAT_R16_UINT:
- textureFormat.internalFormat = VK_FORMAT_R16_UINT;
- textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_UINT;
- break;
- case PIXELFORMAT_R32_FLOAT:
- textureFormat.internalFormat = VK_FORMAT_R32_SFLOAT;
- break;
- case PIXELFORMAT_R32_INT:
- textureFormat.internalFormat = VK_FORMAT_R32_SINT;
- textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_SINT;
- break;
- case PIXELFORMAT_R32_UINT:
- textureFormat.internalFormat = VK_FORMAT_R32_UINT;
- textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_UINT;
- break;
- case PIXELFORMAT_RG8_UNORM:
- textureFormat.internalFormat = VK_FORMAT_R8G8_UNORM;
- break;
- case PIXELFORMAT_RG8_INT:
- textureFormat.internalFormat = VK_FORMAT_R8G8_SINT;
- textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_SINT;
- break;
- case PIXELFORMAT_RG8_UINT:
- textureFormat.internalFormat = VK_FORMAT_R8G8_UINT;
- textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_UINT;
- break;
- case PIXELFORMAT_LA8_UNORM: // Same as RG8: but accessed as (L: L: L: A)
- textureFormat.internalFormat = VK_FORMAT_R8G8_UNORM;
- textureFormat.swizzleR = VK_COMPONENT_SWIZZLE_R;
- textureFormat.swizzleG = VK_COMPONENT_SWIZZLE_R;
- textureFormat.swizzleB = VK_COMPONENT_SWIZZLE_R;
- textureFormat.swizzleA = VK_COMPONENT_SWIZZLE_G;
- break;
- case PIXELFORMAT_RG16_UNORM:
- textureFormat.internalFormat = VK_FORMAT_R16G16_UNORM;
- break;
- case PIXELFORMAT_RG16_FLOAT:
- textureFormat.internalFormat = VK_FORMAT_R16G16_SFLOAT;
- break;
- case PIXELFORMAT_RG16_INT:
- textureFormat.internalFormat = VK_FORMAT_R16G16_SINT;
- textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_SINT;
- break;
- case PIXELFORMAT_RG16_UINT:
- textureFormat.internalFormat = VK_FORMAT_R16G16_UINT;
- textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_UINT;
- break;
- case PIXELFORMAT_RG32_FLOAT:
- textureFormat.internalFormat = VK_FORMAT_R32G32_SFLOAT;
- break;
- case PIXELFORMAT_RG32_INT:
- textureFormat.internalFormat = VK_FORMAT_R32G32_SINT;
- textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_SINT;
- break;
- case PIXELFORMAT_RG32_UINT:
- textureFormat.internalFormat = VK_FORMAT_R32G32_UINT;
- textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_UINT;
- break;
- case PIXELFORMAT_RGBA8_UNORM:
- textureFormat.internalFormat = VK_FORMAT_R8G8B8A8_UNORM;
- break;
- case PIXELFORMAT_RGBA8_UNORM_sRGB:
- textureFormat.internalFormat = VK_FORMAT_R8G8B8A8_SRGB;
- break;
- case PIXELFORMAT_BGRA8_UNORM:
- textureFormat.internalFormat = VK_FORMAT_B8G8R8A8_UNORM;
- break;
- case PIXELFORMAT_BGRA8_UNORM_sRGB:
- textureFormat.internalFormat = VK_FORMAT_B8G8R8A8_SRGB;
- break;
- case PIXELFORMAT_RGBA8_INT:
- textureFormat.internalFormat = VK_FORMAT_R8G8B8A8_SINT;
- textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_SINT;
- break;
- case PIXELFORMAT_RGBA8_UINT:
- textureFormat.internalFormat = VK_FORMAT_R8G8B8A8_UINT;
- textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_UINT;
- break;
- case PIXELFORMAT_RGBA16_UNORM:
- textureFormat.internalFormat = VK_FORMAT_R16G16B16A16_UNORM;
- break;
- case PIXELFORMAT_RGBA16_FLOAT:
- textureFormat.internalFormat = VK_FORMAT_R16G16B16A16_SFLOAT;
- break;
- case PIXELFORMAT_RGBA16_INT:
- textureFormat.internalFormat = VK_FORMAT_R16G16B16A16_SINT;
- textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_SINT;
- break;
- case PIXELFORMAT_RGBA16_UINT:
- textureFormat.internalFormat = VK_FORMAT_R16G16B16A16_UINT;
- textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_UINT;
- break;
- case PIXELFORMAT_RGBA32_FLOAT:
- textureFormat.internalFormat = VK_FORMAT_R32G32B32A32_SFLOAT;
- break;
- case PIXELFORMAT_RGBA32_INT:
- textureFormat.internalFormat = VK_FORMAT_R32G32B32A32_SINT;
- textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_SINT;
- break;
- case PIXELFORMAT_RGBA32_UINT:
- textureFormat.internalFormat = VK_FORMAT_R32G32B32A32_UINT;
- textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_UINT;
- break;
- case PIXELFORMAT_RGBA4_UNORM: // LSB->MSB: [a: b: g: r]
- textureFormat.internalFormat = VK_FORMAT_R4G4B4A4_UNORM_PACK16;
- break;
- case PIXELFORMAT_RGB5A1_UNORM: // LSB->MSB: [a: b: g: r]
- textureFormat.internalFormat = VK_FORMAT_R5G5B5A1_UNORM_PACK16;
- break;
- case PIXELFORMAT_RGB565_UNORM: // LSB->MSB: [b: g: r]
- textureFormat.internalFormat = VK_FORMAT_R5G6B5_UNORM_PACK16;
- break;
- case PIXELFORMAT_RGB10A2_UNORM: // LSB->MSB: [r: g: b: a]
- case PIXELFORMAT_RG11B10_FLOAT: // LSB->MSB: [r: g: b]
- throw love::Exception("unimplemented pixel format (rgb10a2, rg11b10)");
- case PIXELFORMAT_STENCIL8:
- textureFormat.internalFormat = VK_FORMAT_S8_UINT;
- textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_UINT;
- break;
- case PIXELFORMAT_DEPTH16_UNORM:
- textureFormat.internalFormat = VK_FORMAT_D16_UNORM;
- textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_UINT;
- break;
- case PIXELFORMAT_DEPTH24_UNORM:
- case PIXELFORMAT_DEPTH24_UNORM_STENCIL8:
- textureFormat.internalFormat = VK_FORMAT_D24_UNORM_S8_UINT;
- textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_UINT;
- break;
- case PIXELFORMAT_DEPTH32_FLOAT:
- textureFormat.internalFormat = VK_FORMAT_D32_SFLOAT;
- break;
- case PIXELFORMAT_DEPTH32_FLOAT_STENCIL8:
- textureFormat.internalFormat = VK_FORMAT_D32_SFLOAT_S8_UINT;
- break;
- case PIXELFORMAT_DXT1_UNORM:
- textureFormat.internalFormat = VK_FORMAT_BC1_RGBA_UNORM_BLOCK;
- break;
- case PIXELFORMAT_DXT3_UNORM:
- textureFormat.internalFormat = VK_FORMAT_BC2_UNORM_BLOCK;
- break;
- case PIXELFORMAT_DXT5_UNORM:
- textureFormat.internalFormat = VK_FORMAT_BC3_UNORM_BLOCK;
- break;
- case PIXELFORMAT_BC4_UNORM:
- textureFormat.internalFormat = VK_FORMAT_BC4_UNORM_BLOCK;
- break;
- case PIXELFORMAT_BC4_SNORM:
- textureFormat.internalFormat = VK_FORMAT_BC4_SNORM_BLOCK;
- break;
- case PIXELFORMAT_BC5_UNORM:
- textureFormat.internalFormat = VK_FORMAT_BC5_UNORM_BLOCK;
- break;
- case PIXELFORMAT_BC5_SNORM:
- textureFormat.internalFormat = VK_FORMAT_BC5_SNORM_BLOCK;
- break;
- case PIXELFORMAT_BC6H_UFLOAT:
- textureFormat.internalFormat = VK_FORMAT_BC6H_UFLOAT_BLOCK;
- break;
- case PIXELFORMAT_BC6H_FLOAT:
- textureFormat.internalFormat = VK_FORMAT_BC6H_SFLOAT_BLOCK;
- break;
- case PIXELFORMAT_BC7_UNORM:
- textureFormat.internalFormat = VK_FORMAT_BC7_UNORM_BLOCK;
- break;
- case PIXELFORMAT_PVR1_RGB2_UNORM:
- textureFormat.internalFormat = VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG;
- break;
- case PIXELFORMAT_PVR1_RGB4_UNORM:
- textureFormat.internalFormat = VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG;
- break;
- case PIXELFORMAT_PVR1_RGBA2_UNORM:
- textureFormat.internalFormat = VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG;
- break;
- case PIXELFORMAT_PVR1_RGBA4_UNORM:
- textureFormat.internalFormat = VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG;
- break;
- case PIXELFORMAT_ETC1_UNORM:
- throw love::Exception("unimplemented pixel format: etc1");
- case PIXELFORMAT_ETC2_RGB_UNORM:
- textureFormat.internalFormat = VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK;
- break;
- case PIXELFORMAT_ETC2_RGBA_UNORM:
- textureFormat.internalFormat = VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK;
- break;
- case PIXELFORMAT_ETC2_RGBA1_UNORM:
- textureFormat.internalFormat = VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK;
- break;
- case PIXELFORMAT_EAC_R_UNORM:
- textureFormat.internalFormat = VK_FORMAT_EAC_R11_UNORM_BLOCK;
- break;
- case PIXELFORMAT_EAC_R_SNORM:
- textureFormat.internalFormat = VK_FORMAT_EAC_R11_SNORM_BLOCK;
- break;
- case PIXELFORMAT_EAC_RG_UNORM:
- textureFormat.internalFormat = VK_FORMAT_EAC_R11G11_UNORM_BLOCK;
- break;
- case PIXELFORMAT_EAC_RG_SNORM:
- textureFormat.internalFormat = VK_FORMAT_EAC_R11G11_SNORM_BLOCK;
- break;
- case PIXELFORMAT_ASTC_4x4:
- #ifdef VK_EXT_texture_compression_astc_hdr
- textureFormat.internalFormat = VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK_EXT;
- #endif
- break;
- case PIXELFORMAT_ASTC_5x4:
- #ifdef VK_EXT_texture_compression_astc_hdr
- textureFormat.internalFormat = VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK_EXT;
- #endif
- break;
- case PIXELFORMAT_ASTC_5x5:
- #ifdef VK_EXT_texture_compression_astc_hdr
- textureFormat.internalFormat = VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK_EXT;
- #endif
- break;
- case PIXELFORMAT_ASTC_6x5:
- #ifdef VK_EXT_texture_compression_astc_hdr
- textureFormat.internalFormat = VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK_EXT;
- #endif
- break;
- case PIXELFORMAT_ASTC_6x6:
- #ifdef VK_EXT_texture_compression_astc_hdr
- textureFormat.internalFormat = VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK_EXT;
- #endif
- break;
- case PIXELFORMAT_ASTC_8x5:
- #ifdef VK_EXT_texture_compression_astc_hdr
- textureFormat.internalFormat = VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK_EXT;
- #endif
- break;
- case PIXELFORMAT_ASTC_8x6:
- #ifdef VK_EXT_texture_compression_astc_hdr
- textureFormat.internalFormat = VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK_EXT;
- #endif
- break;
- case PIXELFORMAT_ASTC_8x8:
- #ifdef VK_EXT_texture_compression_astc_hdr
- textureFormat.internalFormat = VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK_EXT;
- #endif
- break;
- case PIXELFORMAT_ASTC_10x5:
- #ifdef VK_EXT_texture_compression_astc_hdr
- textureFormat.internalFormat = VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK_EXT;
- #endif
- break;
- case PIXELFORMAT_ASTC_10x6:
- #ifdef VK_EXT_texture_compression_astc_hdr
- textureFormat.internalFormat = VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK_EXT;
- #endif
- break;
- case PIXELFORMAT_ASTC_10x8:
- #ifdef VK_EXT_texture_compression_astc_hdr
- textureFormat.internalFormat = VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK_EXT;
- #endif
- break;
- case PIXELFORMAT_ASTC_10x10:
- #ifdef VK_EXT_texture_compression_astc_hdr
- textureFormat.internalFormat = VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK_EXT;
- #endif
- break;
- case PIXELFORMAT_ASTC_12x10:
- #ifdef VK_EXT_texture_compression_astc_hdr
- textureFormat.internalFormat = VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK_EXT;
- #endif
- break;
- case PIXELFORMAT_ASTC_12x12:
- #ifdef VK_EXT_texture_compression_astc_hdr
- textureFormat.internalFormat = VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK_EXT;
- #endif
- break;
- default:
- throw love::Exception("unknown pixel format");
- }
- return textureFormat;
- }
- // values taken from https://pcisig.com/membership/member-companies
- // as specified at https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VkPhysicalDeviceProperties.html
- std::string Vulkan::getVendorName(uint32_t vendorId)
- {
- switch (vendorId)
- {
- case 4130:
- return "AMD";
- case 4318:
- return "Nvidia";
- case 32902:
- return "Intel";
- case 4203:
- return "Apple";
- case 5140:
- return "Microsoft";
- case 5045:
- return "ARM";
- case 20803:
- return "Qualcomm";
- case 5348:
- return "Broadcom";
- default:
- return "unknown";
- }
- }
- std::string Vulkan::getVulkanApiVersion(uint32_t version)
- {
- std::stringstream ss;
- ss << VK_API_VERSION_MAJOR(version)
- << "." << VK_API_VERSION_MINOR(version)
- << "." << VK_API_VERSION_PATCH(version);
- return ss.str();
- }
- VkPrimitiveTopology Vulkan::getPrimitiveTypeTopology(graphics::PrimitiveType primitiveType)
- {
- switch (primitiveType)
- {
- case PRIMITIVE_POINTS:
- return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
- case PRIMITIVE_TRIANGLES:
- return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
- case PRIMITIVE_TRIANGLE_FAN:
- return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN;
- case PRIMITIVE_TRIANGLE_STRIP:
- return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
- default:
- throw love::Exception("unknown primitive type");
- }
- }
- VkBlendFactor Vulkan::getBlendFactor(BlendFactor blendFactor)
- {
- switch (blendFactor)
- {
- case BLENDFACTOR_ZERO:
- return VK_BLEND_FACTOR_ZERO;
- case BLENDFACTOR_ONE:
- return VK_BLEND_FACTOR_ONE;
- case BLENDFACTOR_SRC_COLOR:
- return VK_BLEND_FACTOR_SRC_COLOR;
- case BLENDFACTOR_ONE_MINUS_SRC_COLOR:
- return VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR;
- case BLENDFACTOR_SRC_ALPHA:
- return VK_BLEND_FACTOR_SRC_ALPHA;
- case BLENDFACTOR_ONE_MINUS_SRC_ALPHA:
- return VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
- case BLENDFACTOR_DST_COLOR:
- return VK_BLEND_FACTOR_DST_COLOR;
- case BLENDFACTOR_ONE_MINUS_DST_COLOR:
- return VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR;
- case BLENDFACTOR_DST_ALPHA:
- return VK_BLEND_FACTOR_DST_ALPHA;
- case BLENDFACTOR_ONE_MINUS_DST_ALPHA:
- return VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA;
- case BLENDFACTOR_SRC_ALPHA_SATURATED:
- return VK_BLEND_FACTOR_SRC_ALPHA_SATURATE;
- default:
- throw love::Exception("unknown blend factor");
- }
- }
- VkBlendOp Vulkan::getBlendOp(BlendOperation op)
- {
- switch (op)
- {
- case BLENDOP_ADD:
- return VK_BLEND_OP_ADD;
- case BLENDOP_MAX:
- return VK_BLEND_OP_MAX;
- case BLENDOP_MIN:
- return VK_BLEND_OP_MIN;
- case BLENDOP_SUBTRACT:
- return VK_BLEND_OP_SUBTRACT;
- case BLENDOP_REVERSE_SUBTRACT:
- return VK_BLEND_OP_REVERSE_SUBTRACT;
- default:
- throw love::Exception("unknown blend operation");
- }
- }
- VkBool32 Vulkan::getBool(bool b)
- {
- if (b)
- return VK_TRUE;
- else
- return VK_FALSE;
- }
- VkColorComponentFlags Vulkan::getColorMask(ColorChannelMask mask)
- {
- VkColorComponentFlags flags = 0;
- if (mask.r)
- flags |= VK_COLOR_COMPONENT_R_BIT;
- if (mask.g)
- flags |= VK_COLOR_COMPONENT_G_BIT;
- if (mask.b)
- flags |= VK_COLOR_COMPONENT_B_BIT;
- if (mask.a)
- flags |= VK_COLOR_COMPONENT_A_BIT;
- return flags;
- }
- VkFrontFace Vulkan::getFrontFace(Winding winding)
- {
- switch (winding)
- {
- case WINDING_CW:
- return VK_FRONT_FACE_CLOCKWISE;
- case WINDING_CCW:
- return VK_FRONT_FACE_COUNTER_CLOCKWISE;
- default:
- throw love::Exception("unknown winding");
- }
- }
- VkCullModeFlags Vulkan::getCullMode(CullMode cullmode)
- {
- switch (cullmode)
- {
- case CULL_BACK:
- return VK_CULL_MODE_BACK_BIT;
- case CULL_FRONT:
- return VK_CULL_MODE_FRONT_BIT;
- case CULL_NONE:
- return VK_CULL_MODE_NONE;
- default:
- throw love::Exception("unknown cull mode");
- }
- }
- VkImageType Vulkan::getImageType(TextureType textureType)
- {
- switch (textureType)
- {
- case TEXTURE_2D:
- case TEXTURE_2D_ARRAY:
- case TEXTURE_CUBE:
- return VK_IMAGE_TYPE_2D;
- case TEXTURE_VOLUME:
- return VK_IMAGE_TYPE_3D;
- default:
- throw love::Exception("unknown texture type");
- }
- }
- VkImageViewType Vulkan::getImageViewType(TextureType textureType)
- {
- switch (textureType)
- {
- case TEXTURE_2D:
- return VK_IMAGE_VIEW_TYPE_2D;
- case TEXTURE_2D_ARRAY:
- return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
- case TEXTURE_CUBE:
- return VK_IMAGE_VIEW_TYPE_CUBE;
- case TEXTURE_VOLUME:
- return VK_IMAGE_VIEW_TYPE_3D;
- default:
- throw love::Exception("unknown texture type");
- }
- }
- VkPolygonMode Vulkan::getPolygonMode(bool wireframe)
- {
- if (wireframe)
- return VK_POLYGON_MODE_LINE;
- else
- return VK_POLYGON_MODE_FILL;
- }
- VkFilter Vulkan::getFilter(SamplerState::FilterMode mode)
- {
- switch (mode)
- {
- case SamplerState::FILTER_LINEAR:
- return VK_FILTER_LINEAR;
- case SamplerState::FILTER_NEAREST:
- return VK_FILTER_NEAREST;
- default:
- throw love::Exception("unkonwn filter mode");
- }
- }
- VkSamplerAddressMode Vulkan::getWrapMode(SamplerState::WrapMode mode)
- {
- switch (mode)
- {
- //fixme: not accounting for different clamps (how does that work in vulkan?)
- case SamplerState::WRAP_CLAMP:
- case SamplerState::WRAP_CLAMP_ZERO:
- case SamplerState::WRAP_CLAMP_ONE:
- return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
- case SamplerState::WRAP_REPEAT:
- return VK_SAMPLER_ADDRESS_MODE_REPEAT;
- case SamplerState::WRAP_MIRRORED_REPEAT:
- return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
- default:
- throw love::Exception("unknown wrap mode");
- }
- }
- VkCompareOp Vulkan::getCompareOp(CompareMode mode)
- {
- switch (mode)
- {
- case COMPARE_LESS:
- return VK_COMPARE_OP_LESS;
- case COMPARE_LEQUAL:
- return VK_COMPARE_OP_LESS_OR_EQUAL;
- case COMPARE_EQUAL:
- return VK_COMPARE_OP_EQUAL;
- case COMPARE_GEQUAL:
- return VK_COMPARE_OP_GREATER_OR_EQUAL;
- case COMPARE_GREATER:
- return VK_COMPARE_OP_GREATER;
- case COMPARE_NOTEQUAL:
- return VK_COMPARE_OP_NOT_EQUAL;
- case COMPARE_ALWAYS:
- return VK_COMPARE_OP_ALWAYS;
- case COMPARE_NEVER:
- return VK_COMPARE_OP_NEVER;
- default:
- throw love::Exception("unknown compare mode");
- }
- }
- VkSamplerMipmapMode Vulkan::getMipMapMode(SamplerState::MipmapFilterMode mode)
- {
- switch (mode)
- {
- case SamplerState::MIPMAP_FILTER_NEAREST:
- return VK_SAMPLER_MIPMAP_MODE_NEAREST;
- case SamplerState::MIPMAP_FILTER_NONE:
- case SamplerState::MIPMAP_FILTER_LINEAR:
- default:
- return VK_SAMPLER_MIPMAP_MODE_LINEAR;
- }
- }
- VkDescriptorType Vulkan::getDescriptorType(graphics::Shader::UniformType type)
- {
- switch (type)
- {
- case graphics::Shader::UniformType::UNIFORM_FLOAT:
- case graphics::Shader::UniformType::UNIFORM_MATRIX:
- case graphics::Shader::UniformType::UNIFORM_INT:
- case graphics::Shader::UniformType::UNIFORM_UINT:
- case graphics::Shader::UniformType::UNIFORM_BOOL:
- return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
- case graphics::Shader::UniformType::UNIFORM_SAMPLER:
- return VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
- case graphics::Shader::UniformType::UNIFORM_STORAGETEXTURE:
- return VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
- case graphics::Shader::UniformType::UNIFORM_TEXELBUFFER:
- return VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
- case graphics::Shader::UniformType::UNIFORM_STORAGEBUFFER:
- return VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
- default:
- throw love::Exception("unkonwn uniform type");
- }
- }
- VkStencilOp Vulkan::getStencilOp(StencilAction action)
- {
- switch (action)
- {
- case STENCIL_KEEP:
- return VK_STENCIL_OP_KEEP;
- case STENCIL_ZERO:
- return VK_STENCIL_OP_ZERO;
- case STENCIL_REPLACE:
- return VK_STENCIL_OP_REPLACE;
- case STENCIL_INCREMENT:
- return VK_STENCIL_OP_INCREMENT_AND_CLAMP;
- case STENCIL_DECREMENT:
- return VK_STENCIL_OP_DECREMENT_AND_CLAMP;
- case STENCIL_INCREMENT_WRAP:
- return VK_STENCIL_OP_INCREMENT_AND_WRAP;
- case STENCIL_DECREMENT_WRAP:
- return VK_STENCIL_OP_DECREMENT_AND_WRAP;
- case STENCIL_INVERT:
- return VK_STENCIL_OP_INVERT;
- default:
- throw love::Exception("unknown stencil action");
- }
- }
- VkIndexType Vulkan::getVulkanIndexBufferType(IndexDataType type)
- {
- switch (type)
- {
- case INDEX_UINT16: return VK_INDEX_TYPE_UINT16;
- case INDEX_UINT32: return VK_INDEX_TYPE_UINT32;
- default:
- throw love::Exception("unknown Index Data type");
- }
- }
- void Vulkan::cmdTransitionImageLayout(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout,
- uint32_t baseLevel, uint32_t levelCount, uint32_t baseLayer, uint32_t layerCount)
- {
- VkImageMemoryBarrier barrier{};
- barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
- barrier.oldLayout = oldLayout;
- barrier.newLayout = newLayout;
- barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
- barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
- barrier.image = image;
- barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
- barrier.subresourceRange.baseMipLevel = baseLevel;
- barrier.subresourceRange.levelCount = levelCount;
- barrier.subresourceRange.baseArrayLayer = baseLayer;
- barrier.subresourceRange.layerCount = layerCount;
- VkPipelineStageFlags sourceStage;
- VkPipelineStageFlags destinationStage;
- if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
- {
- barrier.srcAccessMask = 0;
- barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
- sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
- destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
- }
- else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
- {
- barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
- barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
- sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
- destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
- }
- else if (oldLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
- {
- barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
- barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
- sourceStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
- destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
- }
- else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
- {
- barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
- barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
- sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
- destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
- }
- else if (oldLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL)
- {
- barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
- barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
- sourceStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
- destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
- }
- else if (oldLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
- {
- barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
- barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
- sourceStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
- destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
- }
- else if (oldLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)
- {
- barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
- barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
- sourceStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
- destinationStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
- }
- else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)
- {
- barrier.srcAccessMask = 0;
- barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
- sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
- destinationStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
- }
- else if (oldLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR)
- {
- barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
- barrier.dstAccessMask = 0;
- sourceStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
- destinationStage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
- }
- // we use general for images that are both sampled and compute write
- else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_GENERAL)
- {
- barrier.srcAccessMask = 0;
- barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_TRANSFER_READ_BIT;
- sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
- destinationStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT;
- }
- else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED &&
- (newLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL || newLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL))
- {
- barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
- barrier.srcAccessMask = 0;
- barrier.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
- sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
- destinationStage = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
- }
- else if ((oldLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL || oldLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL) &&
- newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
- {
- barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
- barrier.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
- barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
- sourceStage = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
- destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
- }
- else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL &&
- (newLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL || newLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL))
- {
- barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
- barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
- barrier.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
- sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
- destinationStage = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
- }
- else if (oldLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL)
- {
- barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
- barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
- sourceStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
- destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
- }
- else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR)
- {
- barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
- barrier.dstAccessMask = 0;
-
- sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
- destinationStage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
- }
- else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
- {
- barrier.srcAccessMask = 0;
- barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
- sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
- destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
- }
- else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL)
- {
- barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
- barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
- sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
- destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
- }
- else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
- {
- barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
- barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
- sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
- destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
- }
- else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_UNDEFINED)
- {
- barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
- barrier.dstAccessMask = 0;
- sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
- destinationStage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
- }
- else
- throw std::invalid_argument("unsupported layout transition!");
- vkCmdPipelineBarrier(
- commandBuffer,
- sourceStage, destinationStage,
- 0,
- 0, nullptr,
- 0, nullptr,
- 1, &barrier
- );
- }
- } // vulkan
- } // graphics
- } // love
|