diff --git a/src/modules/graphics/vulkan/Graphics.cpp b/src/modules/graphics/vulkan/Graphics.cpp index e4be8a2da..69662f309 100644 --- a/src/modules/graphics/vulkan/Graphics.cpp +++ b/src/modules/graphics/vulkan/Graphics.cpp @@ -126,6 +126,19 @@ void Graphics::clear(const std::vector& colors, OptionalInt sten attachments.push_back(attachment); } + VkClearAttachment depthStencilAttachment{}; + + if (stencil.hasValue) { + depthStencilAttachment.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT; + depthStencilAttachment.clearValue.depthStencil.stencil = static_cast(stencil.value); + } + if (depth.hasValue) { + depthStencilAttachment.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; + depthStencilAttachment.clearValue.depthStencil.depth = static_cast(depth.value); + } + + attachments.push_back(depthStencilAttachment); + VkClearRect rect{}; rect.layerCount = 1; rect.rect.extent.width = static_cast(currentViewportWidth); @@ -1242,6 +1255,7 @@ void Graphics::createImageViews() { void Graphics::createDefaultRenderPass() { RenderPassConfiguration renderPassConfiguration{}; renderPassConfiguration.colorFormats.push_back(swapChainImageFormat); + renderPassConfiguration.staticData.initialColorImageLayout = VK_IMAGE_LAYOUT_UNDEFINED; renderPassConfiguration.staticData.msaaSamples = msaaSamples; renderPassConfiguration.staticData.depthFormat = findDepthFormat(); renderPassConfiguration.staticData.resolve = true; @@ -1336,11 +1350,11 @@ VkRenderPass Graphics::createRenderPass(RenderPassConfiguration configuration) { VkAttachmentDescription colorDescription{}; colorDescription.format = colorFormat; colorDescription.samples = configuration.staticData.msaaSamples; - colorDescription.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + colorDescription.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; colorDescription.storeOp = VK_ATTACHMENT_STORE_OP_STORE; colorDescription.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; colorDescription.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - colorDescription.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + colorDescription.initialLayout = configuration.staticData.initialColorImageLayout; colorDescription.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; attachments.push_back(colorDescription); } @@ -1387,8 +1401,8 @@ VkRenderPass Graphics::createRenderPass(RenderPassConfiguration configuration) { VkSubpassDependency dependency{}; dependency.srcSubpass = VK_SUBPASS_EXTERNAL; dependency.dstSubpass = 0; - dependency.srcStageMask = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; - dependency.srcAccessMask = 0; + dependency.srcStageMask = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT; + dependency.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; dependency.dstStageMask = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; dependency.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; @@ -1553,12 +1567,10 @@ void Graphics::startDefaultRenderPass() { void Graphics::startRenderPass(const RenderTargets& rts, int pixelw, int pixelh, bool hasSRGBtexture) { auto currentCommandBuffer = commandBuffers.at(currentFrame); - auto width = static_cast(rts.getFirstTarget().texture->getWidth()); - auto height = static_cast(rts.getFirstTarget().texture->getHeight()); - // fixme: hasSRGBtexture // fixme: msaaSamples RenderPassConfiguration renderPassConfiguration{}; + renderPassConfiguration.staticData.initialColorImageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; for (const auto &color : rts.colors) { // fixme: use mipmap and slice. color.mipmap; @@ -1593,13 +1605,13 @@ void Graphics::startRenderPass(const RenderTargets& rts, int pixelw, int pixelh, transitionBackImages.push_back((VkImage) color.texture->getHandle()); } if (rts.depthStencil.texture != nullptr) { - configuration.colorViews.push_back((VkImageView)rts.depthStencil.texture->getRenderTargetHandle()); + configuration.staticData.depthView = (VkImageView)rts.depthStencil.texture->getRenderTargetHandle(); // fixme: layout transition of depth stencil image? } configuration.staticData.renderPass = renderPass; - configuration.staticData.width = static_cast(width); - configuration.staticData.height = static_cast(height); + configuration.staticData.width = static_cast(pixelw); + configuration.staticData.height = static_cast(pixelh); VkFramebuffer framebuffer = getFramebuffer(configuration); VkRenderPassBeginInfo renderPassInfo{}; @@ -1607,15 +1619,15 @@ void Graphics::startRenderPass(const RenderTargets& rts, int pixelw, int pixelh, renderPassInfo.renderPass = renderPass; renderPassInfo.framebuffer = framebuffer; renderPassInfo.renderArea.offset = {0, 0}; - renderPassInfo.renderArea.extent.width = static_cast(width); - renderPassInfo.renderArea.extent.height = static_cast(height); + renderPassInfo.renderArea.extent.width = static_cast(pixelw); + renderPassInfo.renderArea.extent.height = static_cast(pixelh); vkCmdBeginRenderPass(currentCommandBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE); currentRenderPass = renderPass; currentGraphicsPipeline = VK_NULL_HANDLE; - currentViewportWidth = (float)width; - currentViewportHeight = (float)height; + currentViewportWidth = (float)pixelw; + currentViewportHeight = (float)pixelh; currentMsaaSamples = VK_SAMPLE_COUNT_1_BIT; currentNumColorAttachments = static_cast(rts.colors.size()); @@ -2046,9 +2058,6 @@ void Graphics::createDefaultTexture() { } void Graphics::cleanup() { - delete quadIndexBuffer; - quadIndexBuffer = nullptr; - cleanupSwapChain(); for (auto &cleanUpFns : cleanUpFunctions) { diff --git a/src/modules/graphics/vulkan/Graphics.h b/src/modules/graphics/vulkan/Graphics.h index 69971e5fe..234ecf6b6 100644 --- a/src/modules/graphics/vulkan/Graphics.h +++ b/src/modules/graphics/vulkan/Graphics.h @@ -27,6 +27,7 @@ struct RenderPassConfiguration { std::vector colorFormats; struct StaticRenderPassConfiguration { + VkImageLayout initialColorImageLayout = VK_IMAGE_LAYOUT_UNDEFINED; VkSampleCountFlagBits msaaSamples = VK_SAMPLE_COUNT_1_BIT; VkFormat depthFormat = VK_FORMAT_UNDEFINED; bool resolve = false; diff --git a/src/modules/graphics/vulkan/Shader.cpp b/src/modules/graphics/vulkan/Shader.cpp index bd8bc4410..6dcffb2dd 100644 --- a/src/modules/graphics/vulkan/Shader.cpp +++ b/src/modules/graphics/vulkan/Shader.cpp @@ -652,12 +652,12 @@ void Shader::createDescriptorSetLayout() { layoutBinding.binding = val.location; layoutBinding.descriptorType = val.baseType == UNIFORM_SAMPLER ? VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER : VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; layoutBinding.descriptorCount = val.count; - layoutBinding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT; // fixme: can we determine in what shader it got used? + layoutBinding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT; bindings.push_back(layoutBinding); } } - + VkDescriptorSetLayoutBinding uniformBinding{}; uniformBinding.binding = uniformLocation; uniformBinding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; diff --git a/src/modules/graphics/vulkan/Texture.cpp b/src/modules/graphics/vulkan/Texture.cpp index b393bfa79..2c0e11c5b 100644 --- a/src/modules/graphics/vulkan/Texture.cpp +++ b/src/modules/graphics/vulkan/Texture.cpp @@ -50,8 +50,8 @@ bool Texture::loadVolatile() { imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; imageInfo.flags = createFlags; imageInfo.imageType = Vulkan::getImageType(getTextureType()); - imageInfo.extent.width = static_cast(width); - imageInfo.extent.height = static_cast(height); + imageInfo.extent.width = static_cast(pixelWidth); + imageInfo.extent.height = static_cast(pixelHeight); imageInfo.extent.depth = 1; imageInfo.mipLevels = static_cast(getMipmapCount()); imageInfo.arrayLayers = static_cast(layerCount); @@ -164,8 +164,10 @@ void Texture::clear() { VkImageSubresourceRange range{}; range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - range.layerCount = static_cast(layerCount); - range.levelCount = static_cast(getMipmapCount()); + range.baseMipLevel = 0; + range.levelCount = VK_REMAINING_MIP_LEVELS; + range.baseArrayLayer = 0; + range.layerCount = VK_REMAINING_ARRAY_LAYERS; Vulkan::cmdTransitionImageLayout(commandBuffer, textureImage, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, @@ -263,14 +265,14 @@ void Texture::generateMipmapsInternal() { VkImageBlit blit{}; blit.srcOffsets[0] = { 0, 0, 0 }; - blit.srcOffsets[1] = { getWidth(i - 1), getHeight(i - 1), 1 }; + blit.srcOffsets[1] = { getPixelWidth(i - 1), getPixelHeight(i - 1), 1 }; blit.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; blit.srcSubresource.mipLevel = i - 1; blit.srcSubresource.baseArrayLayer = 0; blit.srcSubresource.layerCount = static_cast(layerCount); blit.dstOffsets[0] = { 0, 0, 0 }; - blit.dstOffsets[1] = { getWidth(i), getHeight(i), 1 }; + blit.dstOffsets[1] = { getPixelWidth(i), getPixelHeight(i), 1 }; blit.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; blit.dstSubresource.mipLevel = i; blit.dstSubresource.baseArrayLayer = 0; diff --git a/src/modules/graphics/vulkan/Vulkan.cpp b/src/modules/graphics/vulkan/Vulkan.cpp index aa29ab206..6a7cb2dc4 100644 --- a/src/modules/graphics/vulkan/Vulkan.cpp +++ b/src/modules/graphics/vulkan/Vulkan.cpp @@ -267,34 +267,68 @@ TextureFormat Vulkan::getTextureFormat(PixelFormat format) { 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: - case PIXELFORMAT_DEPTH24_UNORM: - case PIXELFORMAT_DEPTH32_FLOAT: + 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: @@ -309,7 +343,7 @@ TextureFormat Vulkan::getTextureFormat(PixelFormat format) { case PIXELFORMAT_ASTC_10x10: case PIXELFORMAT_ASTC_12x10: case PIXELFORMAT_ASTC_12x12: - throw love::Exception("unimplemented pixel format"); + throw love::Exception("unimplemented pixel format: astc"); default: throw love::Exception("unknown pixel format"); } @@ -325,7 +359,7 @@ std::string Vulkan::getVendorName(uint32_t vendorId) { return "AMD"; case 4318: return "Nvidia"; - case 8086: + case 32902: return "Intel"; case 4203: return "Apple";