mirror of
https://github.com/love2d/love.git
synced 2026-08-14 10:13:46 +02:00
use default texture when rendering primitives
This commit is contained in:
@@ -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));
|
||||
}
|
||||
)";
|
||||
|
||||
|
||||
@@ -4,12 +4,14 @@
|
||||
#include "window/Window.h"
|
||||
#include "common/Exception.h"
|
||||
#include "Shader.h"
|
||||
#include "graphics/Texture.h"
|
||||
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
#include <set>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <array>
|
||||
|
||||
|
||||
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<VkDescriptorSetLayoutBinding, 2> 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<uint32_t>(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<uint32_t>(MAX_FRAMES_IN_FLIGHT);
|
||||
std::array<VkDescriptorPoolSize, 2> poolSizes{};
|
||||
poolSizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||
poolSizes[0].descriptorCount = static_cast<uint32_t>(MAX_FRAMES_IN_FLIGHT);
|
||||
poolSizes[1].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
poolSizes[1].descriptorCount = static_cast<uint32_t>(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<uint32_t>(poolSizes.size());
|
||||
poolInfo.pPoolSizes = poolSizes.data();
|
||||
poolInfo.maxSets = static_cast<uint32_t>(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<VkWriteDescriptorSet, 2> 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<uint32_t>(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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user