diff --git a/src/modules/graphics/vulkan/Buffer.cpp b/src/modules/graphics/vulkan/Buffer.cpp index 4ba184595..c724e8f21 100644 --- a/src/modules/graphics/vulkan/Buffer.cpp +++ b/src/modules/graphics/vulkan/Buffer.cpp @@ -58,7 +58,7 @@ bool Buffer::loadVolatile() if (result != VK_SUCCESS) throw love::Exception("failed to create buffer"); - if (usageFlags & BUFFERUSAGE_TEXEL) + if (usageFlags & BUFFERUSAGEFLAG_TEXEL) { VkBufferViewCreateInfo bufferViewInfo{}; bufferViewInfo.buffer = buffer; diff --git a/src/modules/graphics/vulkan/Graphics.cpp b/src/modules/graphics/vulkan/Graphics.cpp index 53ff8c506..f4a24694d 100644 --- a/src/modules/graphics/vulkan/Graphics.cpp +++ b/src/modules/graphics/vulkan/Graphics.cpp @@ -184,7 +184,7 @@ void Graphics::clear(const std::vector &colors, OptionalInt sten 1, &rect); } -void Graphics::discard(const std::vector& colorbuffers, bool depthstencil) +void Graphics::discard(const std::vector &colorbuffers, bool depthstencil) { if (renderPassState.active) endRenderPass(); @@ -228,7 +228,7 @@ void Graphics::discard(const std::vector& colorbuffers, bool depthstencil) startRenderPass(); } -void Graphics::submitGpuCommands(bool present, void* screenshotCallbackData) +void Graphics::submitGpuCommands(bool present, void *screenshotCallbackData) { flushBatchedDraws(); @@ -409,7 +409,7 @@ void Graphics::present(void *screenshotCallbackdata) deprecations.draw(this); - submitGpuCommands(true); + submitGpuCommands(true, screenshotCallbackdata); VkPresentInfoKHR presentInfo{}; presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; @@ -538,7 +538,7 @@ void Graphics::initCapabilities() capabilities.features[FEATURE_GLSL3] = true; capabilities.features[FEATURE_GLSL4] = true; capabilities.features[FEATURE_INSTANCING] = true; - capabilities.features[FEATURE_TEXEL_BUFFER] = false; + capabilities.features[FEATURE_TEXEL_BUFFER] = true; capabilities.features[FEATURE_INDEX_BUFFER_32BIT] = true; capabilities.features[FEATURE_COPY_BUFFER] = true; capabilities.features[FEATURE_COPY_BUFFER_TO_TEXTURE] = true; @@ -554,13 +554,13 @@ void Graphics::initCapabilities() capabilities.limits[LIMIT_TEXTURE_LAYERS] = properties.limits.maxImageArrayLayers; capabilities.limits[LIMIT_VOLUME_TEXTURE_SIZE] = properties.limits.maxImageDimension3D; capabilities.limits[LIMIT_CUBE_TEXTURE_SIZE] = properties.limits.maxImageDimensionCube; - capabilities.limits[LIMIT_TEXEL_BUFFER_SIZE] = properties.limits.maxTexelBufferElements; // ? - capabilities.limits[LIMIT_SHADER_STORAGE_BUFFER_SIZE] = properties.limits.maxStorageBufferRange; // ? - capabilities.limits[LIMIT_THREADGROUPS_X] = properties.limits.maxComputeWorkGroupSize[0]; // this is correct? + capabilities.limits[LIMIT_TEXEL_BUFFER_SIZE] = properties.limits.maxTexelBufferElements; + capabilities.limits[LIMIT_SHADER_STORAGE_BUFFER_SIZE] = properties.limits.maxStorageBufferRange; + capabilities.limits[LIMIT_THREADGROUPS_X] = properties.limits.maxComputeWorkGroupSize[0]; capabilities.limits[LIMIT_THREADGROUPS_Y] = properties.limits.maxComputeWorkGroupSize[1]; capabilities.limits[LIMIT_THREADGROUPS_Z] = properties.limits.maxComputeWorkGroupSize[2]; capabilities.limits[LIMIT_RENDER_TARGETS] = properties.limits.maxColorAttachments; - capabilities.limits[LIMIT_TEXTURE_MSAA] = 1; // todo + capabilities.limits[LIMIT_TEXTURE_MSAA] = static_cast(getMsaaCount(64)); capabilities.limits[LIMIT_ANISOTROPY] = properties.limits.maxSamplerAnisotropy; static_assert(LIMIT_MAX_ENUM == 13, "Graphics::initCapabilities must be updated when adding a new system limit!"); @@ -892,6 +892,75 @@ PixelFormat Graphics::getSizedFormat(PixelFormat format, bool rendertarget, bool bool Graphics::isPixelFormatSupported(PixelFormat format, uint32 usage, bool sRGB) { + (void)sRGB; // fixme: sRGB + + auto vulkanFormat = Vulkan::getTextureFormat(format); + + VkFormatProperties formatProperties; + vkGetPhysicalDeviceFormatProperties(physicalDevice, vulkanFormat.internalFormat, &formatProperties); + + VkFormatFeatureFlags featureFlags; + VkImageTiling tiling; + VkImageUsageFlags usageFlags = 0; + + if (usage & PIXELFORMATUSAGEFLAGS_LINEAR) + { + tiling = VK_IMAGE_TILING_LINEAR; + featureFlags = formatProperties.linearTilingFeatures; + } + else + { + tiling = VK_IMAGE_TILING_OPTIMAL; + featureFlags = formatProperties.optimalTilingFeatures; + } + + if (!featureFlags) + return false; + + if (usage & PIXELFORMATUSAGEFLAGS_SAMPLE) + { + usageFlags |= VK_IMAGE_USAGE_SAMPLED_BIT; + if (!(featureFlags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) + return false; + } + + if (usage & PIXELFORMATUSAGEFLAGS_RENDERTARGET) + { + if (isPixelFormatDepth(format) || isPixelFormatDepthStencil(format)) + { + usageFlags |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + if (!(featureFlags & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) + return false; + } + else + { + usageFlags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + if (!(featureFlags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)) + return false; + } + } + + if (usage & PIXELFORMATUSAGEFLAGS_BLEND) + if (!(featureFlags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT)) + return false; + + if (usage & PIXELFORMATUSAGEFLAGS_COMPUTEWRITE) + { + usageFlags |= VK_IMAGE_USAGE_STORAGE_BIT; + if (!(featureFlags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT)) + return false; + } + + if (usage & PIXELFORMATUSAGEFLAGS_MSAA) + { + VkImageFormatProperties properties; + + vkGetPhysicalDeviceImageFormatProperties(physicalDevice, vulkanFormat.internalFormat, VK_IMAGE_TYPE_2D, tiling, usageFlags, 0, &properties); + + if (static_cast(properties.sampleCounts) == 1) + return false; + } + return true; } @@ -1175,7 +1244,7 @@ static void checkOptionalInstanceExtensions(OptionalInstanceExtensions &ext) vkEnumerateInstanceExtensionProperties(nullptr, &count, extensions.data()); - for (const auto& extension : extensions) + for (const auto &extension : extensions) { #ifdef VK_KHR_get_physical_device_properties2 if (strcmp(extension.extensionName, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME) == 0) @@ -1404,7 +1473,7 @@ static void findOptionalDeviceExtensions(VkPhysicalDevice physicalDevice, Option std::vector availableExtensions(extensionCount); vkEnumerateDeviceExtensionProperties(physicalDevice, nullptr, &extensionCount, availableExtensions.data()); - for (const auto& extension : availableExtensions) + for (const auto &extension : availableExtensions) { #ifdef VK_EXT_extended_dynamic_state if (strcmp(extension.extensionName, VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME) == 0) @@ -1720,7 +1789,7 @@ void Graphics::createSwapChain() VkSurfaceFormatKHR Graphics::chooseSwapSurfaceFormat(const std::vector &availableFormats) { - for (const auto& availableFormat : availableFormats) + for (const auto &availableFormat : availableFormats) // fixme: what if this format and colorspace is not available? if (availableFormat.format == VK_FORMAT_B8G8R8A8_UNORM && availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) return availableFormat; @@ -1735,7 +1804,8 @@ VkPresentModeKHR Graphics::chooseSwapPresentMode(const std::vector(pixelHeight); imageInfo.extent.depth = static_cast(depth); imageInfo.arrayLayers = static_cast(layerCount); - imageInfo.mipLevels = static_cast(getMipmapCount()); + imageInfo.mipLevels = static_cast(mipmapCount); imageInfo.format = vulkanFormat.internalFormat; - imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL; + if (isPixelFormatCompressed(format)) + imageInfo.tiling = VK_IMAGE_TILING_LINEAR; + else + imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL; imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; imageInfo.usage = usageFlags; imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; @@ -100,26 +106,26 @@ bool Texture::loadVolatile() if (hasdata) for (int mip = 0; mip < getMipmapCount(); mip++) { - // fixme: deal with compressed images. - int sliceCount; if (texType == TEXTURE_CUBE) sliceCount = 6; else sliceCount = slices.getSliceCount(); + for (int slice = 0; slice < sliceCount; slice++) { - auto *id = slices.get(slice, mip); + auto* id = slices.get(slice, mip); if (id != nullptr) uploadImageData(id, mip, slice, 0, 0); } } else clear(); + createTextureImageView(); textureSampler = vgfx->getCachedSampler(samplerState); - if (slices.getMipmapCount() <= 1 && getMipmapsMode() != MIPMAPS_NONE) + if (mipmapCount > 1 && getMipmapsMode() != MIPMAPS_NONE) generateMipmaps(); if (renderTarget) @@ -436,12 +442,15 @@ void Texture::uploadByteData(PixelFormat pixelformat, const void *data, size_t s region.bufferRowLength = 0; region.bufferImageHeight = 0; + uint32_t baseLayer; + if (getTextureType() == TEXTURE_VOLUME) + baseLayer = 0; + else + baseLayer = slice; + region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; region.imageSubresource.mipLevel = level; - if (getTextureType() == TEXTURE_VOLUME) - region.imageSubresource.baseArrayLayer = 0; - else - region.imageSubresource.baseArrayLayer = slice; + region.imageSubresource.baseArrayLayer = baseLayer; region.imageSubresource.layerCount = 1; region.imageOffset = { r.x, r.y, 0 }; @@ -455,13 +464,11 @@ void Texture::uploadByteData(PixelFormat pixelformat, const void *data, size_t s auto commandBuffer = vgfx->getCommandBufferForDataTransfer(); - if (imageLayout != VK_IMAGE_LAYOUT_GENERAL) { Vulkan::cmdTransitionImageLayout(commandBuffer, textureImage, - VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - level, 1, slice, 1); - + imageLayout, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + level, 1, baseLayer, 1); vkCmdCopyBufferToImage( commandBuffer, @@ -473,8 +480,8 @@ void Texture::uploadByteData(PixelFormat pixelformat, const void *data, size_t s ); Vulkan::cmdTransitionImageLayout(commandBuffer, textureImage, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - level, 1, slice, 1); + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, imageLayout, + level, 1, baseLayer, 1); } else vkCmdCopyBufferToImage( @@ -542,11 +549,11 @@ void Texture::copyToBuffer(graphics::Buffer *dest, int slice, int mipmap, const if (imageLayout != VK_IMAGE_LAYOUT_GENERAL) { - Vulkan::cmdTransitionImageLayout(commandBuffer, textureImage, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); + Vulkan::cmdTransitionImageLayout(commandBuffer, textureImage, imageLayout, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); vkCmdCopyImageToBuffer(commandBuffer, textureImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, (VkBuffer) dest->getHandle(), 1, ®ion); - Vulkan::cmdTransitionImageLayout(commandBuffer, textureImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + Vulkan::cmdTransitionImageLayout(commandBuffer, textureImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, imageLayout); } else vkCmdCopyImageToBuffer(commandBuffer, textureImage, VK_IMAGE_LAYOUT_GENERAL, (VkBuffer)dest->getHandle(), 1, ®ion); diff --git a/src/modules/graphics/vulkan/Vulkan.cpp b/src/modules/graphics/vulkan/Vulkan.cpp index d080fdcb4..abc3f2312 100644 --- a/src/modules/graphics/vulkan/Vulkan.cpp +++ b/src/modules/graphics/vulkan/Vulkan.cpp @@ -127,238 +127,305 @@ TextureFormat Vulkan::getTextureFormat(PixelFormat format) switch (format) { - case PIXELFORMAT_UNKNOWN: - throw love::Exception("unknown pixel format"); - case PIXELFORMAT_NORMAL: - textureFormat.internalFormat = VK_FORMAT_R8G8B8A8_SRGB; - textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_FLOAT; - break; - case PIXELFORMAT_HDR: - throw love::Exception("unimplemented pixel format: hdr"); - case PIXELFORMAT_R8_UNORM: - textureFormat.internalFormat = VK_FORMAT_R8_UNORM; - textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_FLOAT; - 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; - textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_FLOAT; - break; - case PIXELFORMAT_R16_FLOAT: - textureFormat.internalFormat = VK_FORMAT_R16_SFLOAT; - textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_FLOAT; - 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; - textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_FLOAT; - 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; - textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_FLOAT; - 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; - textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_FLOAT; - break; - case PIXELFORMAT_RG16_UNORM: - textureFormat.internalFormat = VK_FORMAT_R16G16_UNORM; - textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_FLOAT; - break; - case PIXELFORMAT_RG16_FLOAT: - textureFormat.internalFormat = VK_FORMAT_R16G16_SFLOAT; - textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_FLOAT; - 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; - textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_FLOAT; - 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; - textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_FLOAT; - break; - case PIXELFORMAT_RGBA8_UNORM_sRGB: - textureFormat.internalFormat = VK_FORMAT_R8G8B8A8_SRGB; - textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_FLOAT; - break; - case PIXELFORMAT_BGRA8_UNORM: - textureFormat.internalFormat = VK_FORMAT_B8G8R8A8_UNORM; - textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_FLOAT; - break; - case PIXELFORMAT_BGRA8_UNORM_sRGB: - textureFormat.internalFormat = VK_FORMAT_B8G8R8A8_SRGB; - textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_FLOAT; - 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; - textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_FLOAT; - break; - case PIXELFORMAT_RGBA16_FLOAT: - textureFormat.internalFormat = VK_FORMAT_R16G16B16A16_SFLOAT; - textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_FLOAT; - 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; - textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_FLOAT; - 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] - 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] - throw love::Exception("unimplemented pixel format (rgba4, rgb5a1, rgb565, 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; - textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_FLOAT; - break; - case PIXELFORMAT_DEPTH32_FLOAT_STENCIL8: - textureFormat.internalFormat = VK_FORMAT_D32_SFLOAT_S8_UINT; - textureFormat.internalFormatRepresentation = FORMATREPRESENTATION_FLOAT; // ? - break; - case PIXELFORMAT_DXT1_UNORM: - case PIXELFORMAT_DXT3_UNORM: - case PIXELFORMAT_DXT5_UNORM: - throw love::Exception("unimplemented: dxt"); - 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: - case PIXELFORMAT_PVR1_RGB4_UNORM: - case PIXELFORMAT_PVR1_RGBA2_UNORM: - case PIXELFORMAT_PVR1_RGBA4_UNORM: - throw love::Exception("unimplemented pixel format: pvr1"); - case PIXELFORMAT_ETC1_UNORM: - case PIXELFORMAT_ETC2_RGB_UNORM: - case PIXELFORMAT_ETC2_RGBA_UNORM: - case PIXELFORMAT_ETC2_RGBA1_UNORM: - throw love::Exception("unimplemented pixel format: etc"); - case PIXELFORMAT_EAC_R_UNORM: - case PIXELFORMAT_EAC_R_SNORM: - case PIXELFORMAT_EAC_RG_UNORM: - case PIXELFORMAT_EAC_RG_SNORM: - throw love::Exception("unimplemented pixel format: eac"); - 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: astc"); - default: - throw love::Exception("unknown pixel 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; diff --git a/src/modules/graphics/vulkan/Vulkan.h b/src/modules/graphics/vulkan/Vulkan.h index a75925310..10e1d6c65 100644 --- a/src/modules/graphics/vulkan/Vulkan.h +++ b/src/modules/graphics/vulkan/Vulkan.h @@ -20,7 +20,7 @@ enum InternalFormatRepresentation struct TextureFormat { - InternalFormatRepresentation internalFormatRepresentation; + InternalFormatRepresentation internalFormatRepresentation = FORMATREPRESENTATION_FLOAT; VkFormat internalFormat = VK_FORMAT_UNDEFINED; VkComponentSwizzle swizzleR = VK_COMPONENT_SWIZZLE_IDENTITY; @@ -63,7 +63,7 @@ public: static void cmdTransitionImageLayout( VkCommandBuffer, VkImage, VkImageLayout oldLayout, VkImageLayout newLayout, - uint32_t baseLevel = 0, uint32_t levelCount = 1, uint32_t baseLayer = 0, uint32_t layerCount = 1); + uint32_t baseLevel = 0, uint32_t levelCount = VK_REMAINING_MIP_LEVELS, uint32_t baseLayer = 0, uint32_t layerCount = VK_REMAINING_ARRAY_LAYERS); }; } // vulkan