From c16c07780f34fab2d91c97adbe440b8859e91e05 Mon Sep 17 00:00:00 2001 From: niki Date: Sun, 8 May 2022 22:44:32 +0200 Subject: [PATCH] use default texture when rendering primitives --- src/modules/graphics/Shader.cpp | 4 +- src/modules/graphics/vulkan/Graphics.cpp | 111 +++++++++++++++-------- src/modules/graphics/vulkan/Graphics.h | 4 +- src/modules/graphics/vulkan/Texture.cpp | 44 ++++----- src/modules/graphics/vulkan/Texture.h | 11 +-- 5 files changed, 101 insertions(+), 73 deletions(-) diff --git a/src/modules/graphics/Shader.cpp b/src/modules/graphics/Shader.cpp index 375a985f1..dcb058450 100644 --- a/src/modules/graphics/Shader.cpp +++ b/src/modules/graphics/Shader.cpp @@ -460,8 +460,10 @@ layout(location = 0) in vec4 fragColor; layout(location = 0) out vec4 outColor; +layout(binding = 1) uniform sampler2D texSampler; + void main() { - outColor = fragColor; + outColor = fragColor * texture(texSampler, vec2(0, 0)); } )"; diff --git a/src/modules/graphics/vulkan/Graphics.cpp b/src/modules/graphics/vulkan/Graphics.cpp index 13f184360..831d2029b 100644 --- a/src/modules/graphics/vulkan/Graphics.cpp +++ b/src/modules/graphics/vulkan/Graphics.cpp @@ -4,12 +4,14 @@ #include "window/Window.h" #include "common/Exception.h" #include "Shader.h" +#include "graphics/Texture.h" #include #include #include #include #include +#include namespace love { @@ -59,30 +61,8 @@ namespace love { void Graphics::initVulkan() { if (!init) { init = true; - createVulkanInstance(); - createSurface(); - pickPhysicalDevice(); - createLogicalDevice(); - initVMA(); - createSwapChain(); - createImageViews(); - createRenderPass(); - createDefaultShaders(); - createDescriptorSetLayout(); - createGraphicsPipeline(); - createFramebuffers(); - createCommandPool(); - createCommandBuffers(); - createUniformBuffers(); - createDescriptorPool(); - createDescriptorSets(); - createSyncObjects(); - startRecordingGraphicsCommands(); - } - } - Graphics::~Graphics() { - cleanup(); + } } // START OVERRIDEN FUNCTIONS @@ -214,7 +194,27 @@ namespace love { bool Graphics::setMode(void* context, int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil, int msaa) { std::cout << "setMode "; + createVulkanInstance(); + createSurface(); + pickPhysicalDevice(); + createLogicalDevice(); + initVMA(); initCapabilities(); + createSwapChain(); + createImageViews(); + createRenderPass(); + createDefaultShaders(); + createDescriptorSetLayout(); + createGraphicsPipeline(); + createFramebuffers(); + createCommandPool(); + createCommandBuffers(); + createUniformBuffers(); + createDefaultTexture(); + createDescriptorPool(); + createDescriptorSets(); + createSyncObjects(); + startRecordingGraphicsCommands(); created = true; @@ -279,6 +279,7 @@ namespace love { void Graphics::unSetMode() { created = false; + cleanup(); std::cout << "unSetMode "; } @@ -469,6 +470,9 @@ namespace love { return requiredExtensions.empty(); } + // if the score is nonzero then the device is suitable. + // A higher rating means generally better performance + // if the score is 0 the device is unsuitable int Graphics::rateDeviceSuitability(VkPhysicalDevice device) { VkPhysicalDeviceProperties deviceProperties; VkPhysicalDeviceFeatures deviceFeatures; @@ -835,10 +839,18 @@ namespace love { uboLayoutBinding.descriptorCount = 1; uboLayoutBinding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; + VkDescriptorSetLayoutBinding samplerLayoutBinding{}; + samplerLayoutBinding.binding = 1; + samplerLayoutBinding.descriptorCount = 1; + samplerLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + samplerLayoutBinding.pImmutableSamplers = nullptr; + samplerLayoutBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; + + std::array bindings = { uboLayoutBinding, samplerLayoutBinding }; VkDescriptorSetLayoutCreateInfo layoutInfo{}; layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; - layoutInfo.bindingCount = 1; - layoutInfo.pBindings = &uboLayoutBinding; + layoutInfo.bindingCount = static_cast(bindings.size()); + layoutInfo.pBindings = bindings.data(); if (vkCreateDescriptorSetLayout(device, &layoutInfo, nullptr, &descriptorSetLayout) != VK_SUCCESS) { throw love::Exception("failed to create descriptor set layout"); @@ -854,14 +866,16 @@ namespace love { } void Graphics::createDescriptorPool() { - VkDescriptorPoolSize poolSize{}; - poolSize.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - poolSize.descriptorCount = static_cast(MAX_FRAMES_IN_FLIGHT); + std::array poolSizes{}; + poolSizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + poolSizes[0].descriptorCount = static_cast(MAX_FRAMES_IN_FLIGHT); + poolSizes[1].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + poolSizes[1].descriptorCount = static_cast(MAX_FRAMES_IN_FLIGHT); VkDescriptorPoolCreateInfo poolInfo{}; poolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; - poolInfo.poolSizeCount = 1; - poolInfo.pPoolSizes = &poolSize; + poolInfo.poolSizeCount = static_cast(poolSizes.size()); + poolInfo.pPoolSizes = poolSizes.data(); poolInfo.maxSets = static_cast(MAX_FRAMES_IN_FLIGHT); if (vkCreateDescriptorPool(device, &poolInfo, nullptr, &descriptorPool) != VK_SUCCESS) { @@ -888,16 +902,30 @@ namespace love { bufferInfo.offset = 0; bufferInfo.range = sizeof(Shader::UniformBufferObject); - VkWriteDescriptorSet descriptorWrite{}; - descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - descriptorWrite.dstSet = descriptorSets[i]; - descriptorWrite.dstBinding = 0; - descriptorWrite.dstArrayElement = 0; - descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - descriptorWrite.descriptorCount = 1; - descriptorWrite.pBufferInfo = &bufferInfo; + VkDescriptorImageInfo imageInfo{}; + imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + Texture* vkTexture = (Texture*)standardTexture; + imageInfo.imageView = vkTexture->getImageView(); + imageInfo.sampler = vkTexture->getSampler(); - vkUpdateDescriptorSets(device, 1, &descriptorWrite, 0, nullptr); + std::array descriptorWrite{}; + descriptorWrite[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + descriptorWrite[0].dstSet = descriptorSets[i]; + descriptorWrite[0].dstBinding = 0; + descriptorWrite[0].dstArrayElement = 0; + descriptorWrite[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + descriptorWrite[0].descriptorCount = 1; + descriptorWrite[0].pBufferInfo = &bufferInfo; + + descriptorWrite[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + descriptorWrite[1].dstSet = descriptorSets[i]; + descriptorWrite[1].dstBinding = 1; + descriptorWrite[1].dstArrayElement = 0; + descriptorWrite[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + descriptorWrite[1].descriptorCount = 1; + descriptorWrite[1].pImageInfo = &imageInfo; + + vkUpdateDescriptorSets(device, static_cast(descriptorWrite.size()), descriptorWrite.data(), 0, nullptr); } } @@ -1090,6 +1118,11 @@ namespace love { } } + void Graphics::createDefaultTexture() { + Texture::Settings settings; + standardTexture = newTexture(settings); + } + void Graphics::cleanup() { vkDeviceWaitIdle(device); diff --git a/src/modules/graphics/vulkan/Graphics.h b/src/modules/graphics/vulkan/Graphics.h index 82904e835..4b552fbf2 100644 --- a/src/modules/graphics/vulkan/Graphics.h +++ b/src/modules/graphics/vulkan/Graphics.h @@ -25,7 +25,7 @@ namespace love { void initVulkan(); - virtual ~Graphics(); + virtual ~Graphics() = default; const char* getName() const override; @@ -139,6 +139,7 @@ namespace love { void createCommandPool(); void createCommandBuffers(); void createSyncObjects(); + void createDefaultTexture(); void cleanup(); void cleanupSwapChain(); void recreateSwapChain(); @@ -178,6 +179,7 @@ namespace love { uint32_t imageIndex; bool framebufferResized = false; VmaAllocator vmaAllocator; + graphics::Texture* standardTexture; }; } } diff --git a/src/modules/graphics/vulkan/Texture.cpp b/src/modules/graphics/vulkan/Texture.cpp index acc87fc9e..cbbf02d2f 100644 --- a/src/modules/graphics/vulkan/Texture.cpp +++ b/src/modules/graphics/vulkan/Texture.cpp @@ -8,38 +8,32 @@ namespace love { namespace graphics { namespace vulkan { Texture::Texture(love::graphics::Graphics* gfx, const Settings& settings, const Slices* data) - : love::graphics::Texture(gfx, settings, data), slices(settings.type), gfx(gfx) { + : love::graphics::Texture(gfx, settings, data), gfx(gfx) { allocator = vgfx->getVmaAllocator(); device = vgfx->getDevice(); - if (data != nullptr) { - slices = *data; + if (data) { + auto sliceData = data->get(0, 0); + auto size = sliceData->getSize(); + auto dataPtr = sliceData->getData(); + Rect rect; + rect.x = 0; + rect.y = 0; + rect.w = sliceData->getWidth(); + rect.h = sliceData->getHeight(); + + uploadByteData(PIXELFORMAT_BGRA8_UNORM, dataPtr, size, 0, 0, rect); } - loadVolatile(); + else { + uint8 defaultPixel[] = { 255, 255, 255, 255 }; + Rect rect = { 0, 0, 1, 1 }; + uploadByteData(PIXELFORMAT_BGRA8_UNORM, defaultPixel, sizeof(defaultPixel), 0, 0, rect); + } + createTextureImageView(); + createTextureSampler(); } Texture::~Texture() { - unloadVolatile(); - } - - bool Texture::loadVolatile() { - auto data = slices.get(0, 0); - auto size = data->getSize(); - auto dataPtr = data->getData(); - Rect rect; - rect.x = 0; - rect.y = 0; - rect.w = data->getWidth(); - rect.h = data->getHeight(); - - uploadByteData(PIXELFORMAT_BGRA8_UNORM, dataPtr, size, 0, 0, rect); - createTextureImageView(); - createTextureSampler(); - - return true; - } - - void Texture::unloadVolatile() { // vkDestroySampler(device, textureSampler, nullptr); // vkDestroyImageView(device, textureImageView, nullptr); // vmaDestroyImage(allocator, textureImage, nullptr); diff --git a/src/modules/graphics/vulkan/Texture.h b/src/modules/graphics/vulkan/Texture.h index 611b800fd..625bb29cd 100644 --- a/src/modules/graphics/vulkan/Texture.h +++ b/src/modules/graphics/vulkan/Texture.h @@ -12,15 +12,11 @@ namespace love { namespace graphics { namespace vulkan { - class Texture : public graphics::Texture, public graphics::Volatile { + class Texture : public graphics::Texture { public: Texture(love::graphics::Graphics* gfx, const Settings& settings, const Slices* data); ~Texture(); - bool loadVolatile() override; - - void unloadVolatile() override; - void copyFromBuffer(graphics::Buffer* source, size_t sourceoffset, int sourcewidth, size_t size, int slice, int mipmap, const Rect& rect) override { std::cout << "Texture::copyFromBuffer "; }; void copyToBuffer(graphics::Buffer* dest, int slice, int mipmap, const Rect& rect, size_t destoffset, int destwidth, size_t size) override { std::cout << "Texture::copyToBuffer "; }; @@ -33,7 +29,9 @@ namespace love { void readbackImageData(love::image::ImageData* imagedata, int slice, int mipmap, const Rect& rect) override { std::cout << "Texture::readbackImageData "; }; int getMSAA() const override { std::cout << "Texture::getMSAA "; return 0; }; - ptrdiff_t getHandle() const override { std::cout << "Texture::getHandle "; return (ptrdiff_t)0; } + ptrdiff_t getHandle() const override { std::cout << "Texture::getHandle "; return (ptrdiff_t)textureImage; } + VkImageView getImageView() const { return textureImageView; } + VkSampler getSampler() const { return textureSampler; } private: void transitionImageLayout(VkImage, VkFormat, VkImageLayout oldLayout, VkImageLayout newLayout); @@ -43,7 +41,6 @@ namespace love { graphics::Graphics* gfx; VkDevice device; - Slices slices; VmaAllocator allocator; VkImage textureImage; VmaAllocation textureImageAllocation;