diff --git a/src/modules/graphics/vulkan/Buffer.cpp b/src/modules/graphics/vulkan/Buffer.cpp index 578e97cc6..48e2f004b 100644 --- a/src/modules/graphics/vulkan/Buffer.cpp +++ b/src/modules/graphics/vulkan/Buffer.cpp @@ -4,71 +4,59 @@ namespace love { namespace graphics { namespace vulkan { - static uint32_t findMemoryType(VkPhysicalDevice physicalDevice, uint32_t typeFtiler, VkMemoryPropertyFlags properties) { - VkPhysicalDeviceMemoryProperties memProperties; - vkGetPhysicalDeviceMemoryProperties(physicalDevice, &memProperties); - - for (uint32_t i = 0; i < memProperties.memoryTypeCount; i++) { - if ((typeFtiler & (1 << i)) && (memProperties.memoryTypes[i].propertyFlags & properties) == properties) { - return i; - } + static VkBufferUsageFlags getUsageBit(BufferUsage mode) { + switch (mode) { + case BUFFERUSAGE_VERTEX: return VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; + case BUFFERUSAGE_INDEX: return VK_BUFFER_USAGE_INDEX_BUFFER_BIT; + case BUFFERUSAGE_UNIFORM: return VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; + default: + throw love::Exception("unsupported BufferUsage mode"); } - - throw love::Exception("failed to find suitable memory type"); } - Buffer::Buffer(love::graphics::Graphics* gfx, const Settings& settings, const std::vector& format, const void* data, size_t size, size_t arraylength) - : love::graphics::Buffer(gfx, settings, format, size, arrayLength) { - auto vgfx = (Graphics*)gfx; - device = vgfx->getDevice(); - auto physicalDevice = vgfx->getPhysicalDevice(); + static VkBufferUsageFlags getVulkanUsageFlags(BufferUsageFlags flags) { + VkBufferUsageFlags vkFlags = 0; + for (int i = 0; i < BUFFERUSAGE_MAX_ENUM; i++) { + BufferUsageFlags flag = static_cast(1u << i); + if (flags & flag) { + vkFlags |= getUsageBit((BufferUsage)i); + } + } + return vkFlags; + } + + Buffer::Buffer(VmaAllocator allocator, love::graphics::Graphics* gfx, const Settings& settings, const std::vector& format, const void* data, size_t size, size_t arraylength) + : love::graphics::Buffer(gfx, settings, format, size, arraylength) { VkBufferCreateInfo bufferInfo{}; bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; - bufferInfo.size = getSize(); - bufferInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; // todo: only vertex buffers are allowed for now + bufferInfo.size = size; + bufferInfo.usage = getVulkanUsageFlags(settings.usageFlags); bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - if (vkCreateBuffer(device, &bufferInfo, nullptr, &buffer) != VK_SUCCESS) { - throw love::Exception("failed to create buffer"); - } + VmaAllocationCreateInfo allocCreateInfo = {}; + allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO; + allocCreateInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT; - VkMemoryRequirements memRequirements; - vkGetBufferMemoryRequirements(device, buffer, &memRequirements); - - VkMemoryAllocateInfo allocInfo{}; - allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; - allocInfo.allocationSize = memRequirements.size; - allocInfo.memoryTypeIndex = findMemoryType(physicalDevice, memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); - - if (vkAllocateMemory(device, &allocInfo, nullptr, &bufferMemory) != VK_SUCCESS) { - throw love::Exception("failed to allocate vertex buffer memory"); - } - - vkBindBufferMemory(device, buffer, bufferMemory, 0); - - vkMapMemory(device, bufferMemory, 0, getSize(), 0, &mappedMemory); - memcpy(mappedMemory, data, size); - vkUnmapMemory(device, bufferMemory); + vmaCreateBuffer(allocator, &bufferInfo, &allocCreateInfo, &buffer, &allocation, &allocInfo); } Buffer::~Buffer() { - vkDestroyBuffer(device, buffer, nullptr); - vkFreeMemory(device, bufferMemory, nullptr); + // fixme } void* Buffer::map(MapType map, size_t offset, size_t size) { - vkMapMemory(device, bufferMemory, offset, size, 0, &mappedMemory); - return mappedMemory; + char* data = (char*)allocInfo.pMappedData; + return (void*) (data + offset); } bool Buffer::fill(size_t offset, size_t size, const void *data) { - memcpy(mappedMemory, data, size); + void* dst = (void*)((char*)allocInfo.pMappedData + offset); + memcpy(dst, data, size); return true; } void Buffer::unmap(size_t usedoffset, size_t usedsize) { - vkUnmapMemory(device, bufferMemory); } void Buffer::copyTo(love::graphics::Buffer* dest, size_t sourceoffset, size_t destoffset, size_t size) { diff --git a/src/modules/graphics/vulkan/Buffer.h b/src/modules/graphics/vulkan/Buffer.h index e2ccd161a..d9abe1038 100644 --- a/src/modules/graphics/vulkan/Buffer.h +++ b/src/modules/graphics/vulkan/Buffer.h @@ -1,5 +1,6 @@ #include "graphics/Buffer.h" #include +#include "vk_mem_alloc.h" namespace love { @@ -7,7 +8,7 @@ namespace love { namespace vulkan { class Buffer : public love::graphics::Buffer { public: - Buffer(love::graphics::Graphics* gfx, const Settings& settings, const std::vector& format, const void* data, size_t size, size_t arraylength); + Buffer(VmaAllocator allocator, love::graphics::Graphics* gfx, const Settings& settings, const std::vector& format, const void* data, size_t size, size_t arraylength); virtual ~Buffer(); void* map(MapType map, size_t offset, size_t size) override; @@ -18,18 +19,15 @@ namespace love { return (ptrdiff_t) buffer; // todo ? } ptrdiff_t getTexelBufferHandle() const override { + throw love::Exception("unimplemented Buffer::getTexelBufferHandle"); return (ptrdiff_t) nullptr; // todo ? } private: - VkDevice device; - VkPhysicalDevice physicalDevice; - // todo use a staging buffer for improved performance VkBuffer buffer; - VkDeviceMemory bufferMemory; - - void* mappedMemory; + VmaAllocation allocation; + VmaAllocationInfo allocInfo; }; } } diff --git a/src/modules/graphics/vulkan/Graphics.cpp b/src/modules/graphics/vulkan/Graphics.cpp index 273d4e497..5c301fade 100644 --- a/src/modules/graphics/vulkan/Graphics.cpp +++ b/src/modules/graphics/vulkan/Graphics.cpp @@ -62,7 +62,7 @@ namespace love { love::graphics::Buffer* Graphics::newBuffer(const love::graphics::Buffer::Settings& settings, const std::vector& format, const void* data, size_t size, size_t arraylength) { std::cout << "newBuffer "; - return nullptr; + return new Buffer(vmaAllocator, this, settings, format, data, size, arraylength); } void Graphics::startRecordingGraphicsCommands() { @@ -211,6 +211,7 @@ namespace love { createCommandBuffers(); createUniformBuffers(); createDefaultTexture(); + createQuadIndexBuffer(); createDescriptorPool(); createSyncObjects(); startRecordingGraphicsCommands(); @@ -308,8 +309,14 @@ namespace love { createVulkanVertexFormat(*cmd.attributes, useConstantColorBuffer, configuration); for (uint32_t i = 0; i < 2; i++) { - buffers.push_back((VkBuffer)cmd.buffers->info[i].buffer->getHandle()); - offsets.push_back((VkDeviceSize)cmd.buffers->info[i].offset); + if (cmd.buffers->useBits & (1u << i)) { + buffers.push_back((VkBuffer)cmd.buffers->info[i].buffer->getHandle()); + offsets.push_back((VkDeviceSize)cmd.buffers->info[i].offset); + } + else { + buffers.push_back(VK_NULL_HANDLE); + offsets.push_back(0); + } } if (useConstantColorBuffer) { @@ -332,6 +339,61 @@ namespace love { vkCmdDrawIndexed(commandBuffers.at(imageIndex), static_cast(cmd.indexCount), 1, 0, 0, 0); } + void Graphics::drawQuads(int start, int count, const VertexAttributes& attributes, const BufferBindings& buffers, graphics::Texture* texture) { + std::cout << "drawQuads "; + + const int MAX_VERTICES_PER_DRAW = LOVE_UINT16_MAX; + const int MAX_QUADS_PER_DRAW = MAX_VERTICES_PER_DRAW / 4; + + std::vector bufferVector; + std::vector offsets; + + bool useConstantColorBuffer; + GraphicsPipelineConfiguration configuration; + createVulkanVertexFormat(attributes, useConstantColorBuffer, configuration); + + for (uint32_t i = 0; i < 2; i++) { + if (buffers.useBits & (1u << i)) { + bufferVector.push_back((VkBuffer)buffers.info[i].buffer->getHandle()); + offsets.push_back((VkDeviceSize)buffers.info[i].offset); + } + else { + if (useConstantColorBuffer) { + bufferVector.push_back(VK_NULL_HANDLE); + offsets.push_back(0); + } + } + } + + if (useConstantColorBuffer) { + bufferVector.push_back((VkBuffer)batchedDrawBuffers[currentFrame].constantColorBuffer->getHandle()); + offsets.push_back((VkDeviceSize)0); + } + + if (texture == nullptr) { + setTexture(standardTexture); + } + else { + setTexture(texture); + } + + ensureGraphicsPipelineConfiguration(configuration); + + vkCmdBindDescriptorSets(commandBuffers.at(imageIndex), VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, getDescriptorSet(currentFrame), 0, nullptr); + vkCmdBindIndexBuffer(commandBuffers.at(imageIndex), (VkBuffer)quadIndexBuffer->getHandle(), 0, getVulkanIndexBufferType(INDEX_UINT16)); + vkCmdBindVertexBuffers(commandBuffers.at(imageIndex), 0, bufferVector.size(), bufferVector.data(), offsets.data()); + vkCmdDrawIndexed(commandBuffers.at(imageIndex), static_cast(count * 6), 1, 0, 0, 0); + + int baseVertex = start * 4; + + for (int quadindex = 0; quadindex < count; quadindex += MAX_QUADS_PER_DRAW) { + int quadcount = std::min(MAX_QUADS_PER_DRAW, count - quadindex); + + // vkCmdDrawIndexed(commandBuffers.at(imageIndex), static_cast(quadcount * 6), 1, 0, baseVertex, 0); + baseVertex += quadcount * 4; + } + } + graphics::StreamBuffer* Graphics::newStreamBuffer(BufferUsage type, size_t size) { std::cout << "newStreamBuffer "; return new StreamBuffer(vmaAllocator, type, size); @@ -652,11 +714,16 @@ namespace love { VkPhysicalDeviceFeatures deviceFeatures{}; deviceFeatures.samplerAnisotropy = VK_TRUE; + VkPhysicalDeviceFeatures2 deviceFeatures2{}; + deviceFeatures2.features.robustBufferAccess = VK_TRUE; + deviceFeatures2.pNext = nullptr; + VkDeviceCreateInfo createInfo{}; createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; createInfo.queueCreateInfoCount = static_cast(queueCreateInfos.size()); createInfo.pQueueCreateInfos = queueCreateInfos.data(); createInfo.pEnabledFeatures = &deviceFeatures; + createInfo.pNext = &deviceFeatures2; createInfo.enabledExtensionCount = static_cast(deviceExtensions.size()); createInfo.ppEnabledExtensionNames = deviceExtensions.data(); @@ -1033,7 +1100,7 @@ namespace love { bool usesColor = false; - for (uint32_t i = 0; i < 32; i++) { // change to loop like in opengl implementation ? + for (uint32_t i = 0; i < VertexAttributes::MAX; i++) { // change to loop like in opengl implementation ? uint32 bit = 1u << i; if (allBits & bit) { if (i == ATTRIB_COLOR) { @@ -1293,6 +1360,17 @@ namespace love { standardTexture = newTexture(settings); } + void Graphics::createQuadIndexBuffer() { + if (quadIndexBuffer != nullptr) + return; + + size_t size = sizeof(uint16) * getIndexCount(TRIANGLEINDEX_QUADS, LOVE_UINT16_MAX); + quadIndexBuffer = static_cast(newStreamBuffer(BUFFERUSAGE_INDEX, size)); + auto map = quadIndexBuffer->map(size); + fillIndices(TRIANGLEINDEX_QUADS, 0, LOVE_UINT16_MAX, (uint16*)map.data); + quadIndexBuffer->unmap(size); + } + bool operator==(const Graphics::GraphicsPipelineConfiguration& first, const Graphics::GraphicsPipelineConfiguration& other) { if (first.vertexInputAttributeDescriptions.size() != other.vertexInputAttributeDescriptions.size()) { return false; diff --git a/src/modules/graphics/vulkan/Graphics.h b/src/modules/graphics/vulkan/Graphics.h index bdf48bf60..cb848171a 100644 --- a/src/modules/graphics/vulkan/Graphics.h +++ b/src/modules/graphics/vulkan/Graphics.h @@ -72,7 +72,7 @@ namespace love { RendererInfo getRendererInfo() const override { std::cout << "getRendererInfo "; return {}; } void draw(const DrawCommand& cmd) override { std::cout << "draw "; } void draw(const DrawIndexedCommand& cmd) override; - void drawQuads(int start, int count, const VertexAttributes& attributes, const BufferBindings& buffers, graphics::Texture* texture) override { std::cout << "drawQuads "; } + void drawQuads(int start, int count, const VertexAttributes& attributes, const BufferBindings& buffers, graphics::Texture* texture) override; GraphicsReadback* newReadbackInternal(ReadbackMethod method, love::graphics::Buffer* buffer, size_t offset, size_t size, data::ByteData* dest, size_t destoffset) override { return nullptr; }; GraphicsReadback* newReadbackInternal(ReadbackMethod method, love::graphics::Texture* texture, int slice, int mipmap, const Rect& rect, image::ImageData* dest, int destx, int desty) { return nullptr; } @@ -87,6 +87,8 @@ namespace love { friend static bool operator==(const GraphicsPipelineConfiguration& first, const GraphicsPipelineConfiguration& other); }; + void setShader(Shader*); + protected: graphics::ShaderStage* newShaderStageInternal(ShaderStageType stage, const std::string& cachekey, const std::string& source, bool gles) override { std::cout << "newShaderStageInternal "; @@ -134,6 +136,8 @@ namespace love { void createVulkanVertexFormat(VertexAttributes vertexAttributes, bool& useConstantVertexColor, GraphicsPipelineConfiguration& configuration); + StreamBuffer* quadIndexBuffer = nullptr; + // vulkan specific member functions and variables struct QueueFamilyIndices { @@ -178,6 +182,7 @@ namespace love { void createCommandBuffers(); void createSyncObjects(); void createDefaultTexture(); + void createQuadIndexBuffer(); void cleanup(); void cleanupSwapChain(); void recreateSwapChain(); diff --git a/src/modules/graphics/vulkan/Texture.cpp b/src/modules/graphics/vulkan/Texture.cpp index 64bc3dd8d..354f84231 100644 --- a/src/modules/graphics/vulkan/Texture.cpp +++ b/src/modules/graphics/vulkan/Texture.cpp @@ -1,5 +1,6 @@ #include "Texture.h" #include "Graphics.h" +#include "Vulkan.h" // make vulkan::Graphics functions available #define vgfx ((Graphics*)gfx) @@ -16,13 +17,13 @@ namespace love { auto sliceData = data->get(0, 0); auto size = sliceData->getSize(); auto dataPtr = sliceData->getData(); - Rect rect; + Rect rect{}; rect.x = 0; rect.y = 0; rect.w = sliceData->getWidth(); rect.h = sliceData->getHeight(); - uploadByteData(PIXELFORMAT_RGBA8_UNORM, dataPtr, size, 0, 0, rect); + uploadByteData(format, dataPtr, size, 0, 0, rect); } else { uint8 defaultPixel[] = { 255, 255, 255, 255 }; @@ -40,16 +41,22 @@ namespace love { } void Texture::createTextureImageView() { + auto vulkanFormat = Vulkan::getTextureFormat(format); + VkImageViewCreateInfo viewInfo{}; viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; viewInfo.image = textureImage; viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; - viewInfo.format = VK_FORMAT_R8G8B8A8_SRGB; + viewInfo.format = vulkanFormat.internalFormat; viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; viewInfo.subresourceRange.baseMipLevel = 0; viewInfo.subresourceRange.levelCount = 1; viewInfo.subresourceRange.baseArrayLayer = 0; viewInfo.subresourceRange.layerCount = 1; + viewInfo.components.r = vulkanFormat.swizzleR; + viewInfo.components.g = vulkanFormat.swizzleG; + viewInfo.components.b = vulkanFormat.swizzleB; + viewInfo.components.a = vulkanFormat.swizzleA; if (vkCreateImageView(device, &viewInfo, nullptr, &textureImageView) != VK_SUCCESS) { throw love::Exception("could not create texture image view"); @@ -181,6 +188,8 @@ namespace love { memcpy(allocInfo.pMappedData, data, size); + auto vulkanFormat = Vulkan::getTextureFormat(format); + VkImageCreateInfo imageInfo{}; imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; imageInfo.imageType = VK_IMAGE_TYPE_2D; @@ -189,7 +198,7 @@ namespace love { imageInfo.extent.depth = 1; imageInfo.mipLevels = 1; imageInfo.arrayLayers = 1; - imageInfo.format = VK_FORMAT_R8G8B8A8_SRGB; + imageInfo.format = vulkanFormat.internalFormat; imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL; imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; imageInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; diff --git a/src/modules/graphics/vulkan/Vulkan.cpp b/src/modules/graphics/vulkan/Vulkan.cpp index 83763a563..9d812b583 100644 --- a/src/modules/graphics/vulkan/Vulkan.cpp +++ b/src/modules/graphics/vulkan/Vulkan.cpp @@ -83,6 +83,172 @@ namespace love { 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; + break; + case PIXELFORMAT_R8_UINT: + textureFormat.internalFormat = VK_FORMAT_R8_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; + break; + case PIXELFORMAT_R16_UINT: + textureFormat.internalFormat = VK_FORMAT_R16_UINT; + break; + case PIXELFORMAT_R32_FLOAT: + textureFormat.internalFormat = VK_FORMAT_R32_SFLOAT; + break; + case PIXELFORMAT_R32_INT: + textureFormat.internalFormat = VK_FORMAT_R32_SINT; + break; + case PIXELFORMAT_R32_UINT: + textureFormat.internalFormat = VK_FORMAT_R32_UINT; + break; + case PIXELFORMAT_RG8_UNORM: + textureFormat.internalFormat = VK_FORMAT_R8G8_UNORM; + break; + case PIXELFORMAT_RG8_INT: + textureFormat.internalFormat = VK_FORMAT_R8G8_SINT; + break; + case PIXELFORMAT_RG8_UINT: + textureFormat.internalFormat = VK_FORMAT_R8G8_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; + break; + case PIXELFORMAT_RG16_UINT: + textureFormat.internalFormat = VK_FORMAT_R16G16_UINT; + break; + case PIXELFORMAT_RG32_FLOAT: + textureFormat.internalFormat = VK_FORMAT_R32G32_SFLOAT; + break; + case PIXELFORMAT_RG32_INT: + textureFormat.internalFormat = VK_FORMAT_R32G32_SINT; + break; + case PIXELFORMAT_RG32_UINT: + textureFormat.internalFormat = VK_FORMAT_R32G32_UINT; + break; + case PIXELFORMAT_RGBA8_UNORM: + case PIXELFORMAT_RGBA8_UNORM_sRGB: // fixme ? + textureFormat.internalFormat = VK_FORMAT_R8G8B8A8_UNORM; + break; + case PIXELFORMAT_BGRA8_UNORM: + case PIXELFORMAT_BGRA8_UNORM_sRGB: // fixme ? + textureFormat.internalFormat = VK_FORMAT_B8G8R8A8_UNORM; + break; + case PIXELFORMAT_RGBA8_INT: + textureFormat.internalFormat = VK_FORMAT_R8G8B8A8_SINT; + break; + case PIXELFORMAT_RGBA8_UINT: + textureFormat.internalFormat = VK_FORMAT_R8G8B8A8_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; + break; + case PIXELFORMAT_RGBA16_UINT: + textureFormat.internalFormat = VK_FORMAT_R16G16B16A16_UINT; + break; + case PIXELFORMAT_RGBA32_FLOAT: + textureFormat.internalFormat = VK_FORMAT_R32G32B32A32_SFLOAT; + break; + case PIXELFORMAT_RGBA32_INT: + textureFormat.internalFormat = VK_FORMAT_R32G32B32A32_SINT; + break; + case PIXELFORMAT_RGBA32_UINT: + textureFormat.internalFormat = VK_FORMAT_R32G32B32A32_UINT; + break; + case PIXELFORMAT_RGBA4_UNORM: // LSB->MSB: [a: b: g: r] + case PIXELFORMAT_RGB5A1_UNORM: // LSB->MSB: [a: b: g: r] + case PIXELFORMAT_RGB565_UNORM: // LSB->MSB: [b: g: r] + case PIXELFORMAT_RGB10A2_UNORM: // LSB->MSB: [r: g: b: a] + case PIXELFORMAT_RG11B10_FLOAT: // LSB->MSB: [r: g: b] + case PIXELFORMAT_STENCIL8: + case PIXELFORMAT_DEPTH16_UNORM: + case PIXELFORMAT_DEPTH24_UNORM: + case PIXELFORMAT_DEPTH32_FLOAT: + case PIXELFORMAT_DEPTH24_UNORM_STENCIL8: + case PIXELFORMAT_DEPTH32_FLOAT_STENCIL8: + case PIXELFORMAT_DXT1_UNORM: + case PIXELFORMAT_DXT3_UNORM: + case PIXELFORMAT_DXT5_UNORM: + case PIXELFORMAT_BC4_UNORM: + case PIXELFORMAT_BC4_SNORM: + case PIXELFORMAT_BC5_UNORM: + case PIXELFORMAT_BC5_SNORM: + case PIXELFORMAT_BC6H_UFLOAT: + case PIXELFORMAT_BC6H_FLOAT: + case PIXELFORMAT_BC7_UNORM: + case PIXELFORMAT_PVR1_RGB2_UNORM: + case PIXELFORMAT_PVR1_RGB4_UNORM: + case PIXELFORMAT_PVR1_RGBA2_UNORM: + case PIXELFORMAT_PVR1_RGBA4_UNORM: + case PIXELFORMAT_ETC1_UNORM: + case PIXELFORMAT_ETC2_RGB_UNORM: + case PIXELFORMAT_ETC2_RGBA_UNORM: + case PIXELFORMAT_ETC2_RGBA1_UNORM: + case PIXELFORMAT_EAC_R_UNORM: + case PIXELFORMAT_EAC_R_SNORM: + case PIXELFORMAT_EAC_RG_UNORM: + case PIXELFORMAT_EAC_RG_SNORM: + case PIXELFORMAT_ASTC_4x4: + case PIXELFORMAT_ASTC_5x4: + case PIXELFORMAT_ASTC_5x5: + case PIXELFORMAT_ASTC_6x5: + case PIXELFORMAT_ASTC_6x6: + case PIXELFORMAT_ASTC_8x5: + case PIXELFORMAT_ASTC_8x6: + case PIXELFORMAT_ASTC_8x8: + case PIXELFORMAT_ASTC_10x5: + case PIXELFORMAT_ASTC_10x6: + case PIXELFORMAT_ASTC_10x8: + case PIXELFORMAT_ASTC_10x10: + case PIXELFORMAT_ASTC_12x10: + case PIXELFORMAT_ASTC_12x12: + throw love::Exception("unimplemented pixel format"); + } + + return textureFormat; + } } } } diff --git a/src/modules/graphics/vulkan/Vulkan.h b/src/modules/graphics/vulkan/Vulkan.h index 8dcb1de9c..714a296b3 100644 --- a/src/modules/graphics/vulkan/Vulkan.h +++ b/src/modules/graphics/vulkan/Vulkan.h @@ -1,15 +1,25 @@ #ifndef LOVE_GRAPHICS_VULKAN_VULKAN_H #define LOVE_GRAPHICS_VULKAN_VULKAN_H -#include "Vulkan.h" -#include "Graphics.h" +#include "graphics/Graphics.h" +#include "vulkan/vulkan.h" namespace love { namespace graphics { namespace vulkan { + struct TextureFormat { + VkFormat internalFormat = VK_FORMAT_UNDEFINED; + + VkComponentSwizzle swizzleR = VK_COMPONENT_SWIZZLE_IDENTITY; + VkComponentSwizzle swizzleG = VK_COMPONENT_SWIZZLE_IDENTITY; + VkComponentSwizzle swizzleB = VK_COMPONENT_SWIZZLE_IDENTITY; + VkComponentSwizzle swizzleA = VK_COMPONENT_SWIZZLE_IDENTITY; + }; + class Vulkan { public: static VkFormat getVulkanVertexFormat(DataFormat format); + static TextureFormat getTextureFormat(PixelFormat); }; } }