mirror of
https://github.com/love2d/love.git
synced 2026-08-12 08:30:56 +02:00
first draft of vulkan texture impl
This commit is contained in:
@@ -46,8 +46,8 @@ public:
|
||||
bool loadVolatile() override;
|
||||
void unloadVolatile() override;
|
||||
|
||||
void copyFromBuffer(love::graphics::Buffer *source, size_t sourceoffset, int sourcewidth, size_t size, int slice, int mipmap, const Rect &rect) override;
|
||||
void copyToBuffer(love::graphics::Buffer *dest, int slice, int mipmap, const Rect &rect, size_t destoffset, int destwidth, size_t size) override;
|
||||
void copyFromBuffer(love::graphics::Buffer* source, size_t sourceoffset, int sourcewidth, size_t size, int slice, int mipmap, const Rect& rect) override;
|
||||
void copyToBuffer(love::graphics::Buffer* dest, int slice, int mipmap, const Rect& rect, size_t destoffset, int destwidth, size_t size) override;
|
||||
|
||||
void setSamplerState(const SamplerState &s) override;
|
||||
|
||||
@@ -59,7 +59,6 @@ public:
|
||||
inline GLuint getFBO() const { return fbo; }
|
||||
|
||||
private:
|
||||
|
||||
void createTexture();
|
||||
|
||||
void uploadByteData(PixelFormat pixelformat, const void *data, size_t size, int level, int slice, const Rect &r) override;
|
||||
|
||||
@@ -94,7 +94,7 @@ namespace love {
|
||||
|
||||
void Graphics::startRecordingGraphicsCommands() {
|
||||
vkWaitForFences(device, 1, &inFlightFences[currentFrame], VK_TRUE, UINT64_MAX);
|
||||
|
||||
|
||||
while (true) {
|
||||
VkResult result = vkAcquireNextImageKHR(device, swapChain, UINT64_MAX, imageAvailableSemaphores[currentFrame], VK_NULL_HANDLE, &imageIndex);
|
||||
if (result == VK_ERROR_OUT_OF_DATE_KHR) {
|
||||
@@ -211,7 +211,7 @@ namespace love {
|
||||
recreateSwapChain();
|
||||
}
|
||||
|
||||
bool Graphics::setMode(void* context, int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil, int msaa) {
|
||||
bool Graphics::setMode(void* context, int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil, int msaa) {
|
||||
std::cout << "setMode ";
|
||||
|
||||
initCapabilities();
|
||||
@@ -232,9 +232,6 @@ namespace love {
|
||||
|
||||
void Graphics::initCapabilities() {
|
||||
std::cout << "initCapabilities ";
|
||||
|
||||
VkPhysicalDeviceProperties properties;
|
||||
vkGetPhysicalDeviceProperties(physicalDevice, &properties);
|
||||
|
||||
// todo
|
||||
capabilities.features[FEATURE_MULTI_RENDER_TARGET_FORMATS] = false;
|
||||
@@ -256,6 +253,9 @@ namespace love {
|
||||
capabilities.features[FEATURE_COPY_RENDER_TARGET_TO_BUFFER] = false;
|
||||
static_assert(FEATURE_MAX_ENUM == 17, "Graphics::initCapabilities must be updated when adding a new graphics feature!");
|
||||
|
||||
VkPhysicalDeviceProperties properties;
|
||||
vkGetPhysicalDeviceProperties(physicalDevice, &properties);
|
||||
|
||||
capabilities.limits[LIMIT_POINT_SIZE] = properties.limits.pointSizeRange[1];
|
||||
capabilities.limits[LIMIT_TEXTURE_SIZE] = properties.limits.maxImageDimension2D;
|
||||
capabilities.limits[LIMIT_TEXTURE_LAYERS] = properties.limits.maxImageArrayLayers;
|
||||
@@ -283,27 +283,59 @@ namespace love {
|
||||
std::cout << "unSetMode ";
|
||||
}
|
||||
|
||||
void Graphics::draw(const DrawIndexedCommand& cmd) {
|
||||
void Graphics::draw(const DrawIndexedCommand& cmd) {
|
||||
std::cout << "drawIndexed ";
|
||||
|
||||
std::vector<VkBuffer> buffers;
|
||||
std::vector<VkDeviceSize> offsets;
|
||||
buffers.push_back((VkBuffer)cmd.buffers->info[0].buffer->getHandle());
|
||||
offsets.push_back((VkDeviceSize) 0);
|
||||
offsets.push_back((VkDeviceSize)0);
|
||||
|
||||
vkCmdBindDescriptorSets(commandBuffers.at(imageIndex), VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSets.at(currentFrame), 0, nullptr);
|
||||
vkCmdBindVertexBuffers(commandBuffers.at(imageIndex), 0, 1, buffers.data(), offsets.data());
|
||||
vkCmdBindIndexBuffer(commandBuffers.at(imageIndex), (VkBuffer) cmd.indexBuffer->getHandle(), 0, VK_INDEX_TYPE_UINT16);
|
||||
vkCmdBindIndexBuffer(commandBuffers.at(imageIndex), (VkBuffer)cmd.indexBuffer->getHandle(), 0, VK_INDEX_TYPE_UINT16);
|
||||
vkCmdDrawIndexed(commandBuffers.at(imageIndex), static_cast<uint32_t>(cmd.indexCount), 1, 0, 0, 0);
|
||||
}
|
||||
|
||||
graphics::StreamBuffer* Graphics::newStreamBuffer(BufferUsage type, size_t size) {
|
||||
graphics::StreamBuffer* Graphics::newStreamBuffer(BufferUsage type, size_t size) {
|
||||
std::cout << "newStreamBuffer ";
|
||||
return new StreamBuffer(vmaAllocator, type, size);
|
||||
}
|
||||
|
||||
// END IMPLEMENTATION OVERRIDDEN FUNCTIONS
|
||||
|
||||
VkCommandBuffer Graphics::beginSingleTimeCommands() {
|
||||
VkCommandBufferAllocateInfo allocInfo{};
|
||||
allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
||||
allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
||||
allocInfo.commandPool = commandPool;
|
||||
allocInfo.commandBufferCount = 1;
|
||||
|
||||
VkCommandBuffer commandBuffer;
|
||||
vkAllocateCommandBuffers(device, &allocInfo, &commandBuffer);
|
||||
|
||||
VkCommandBufferBeginInfo beginInfo{};
|
||||
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
||||
|
||||
vkBeginCommandBuffer(commandBuffer, &beginInfo);
|
||||
|
||||
return commandBuffer;
|
||||
}
|
||||
|
||||
void Graphics::endSingleTimeCommands(VkCommandBuffer commandBuffer) {
|
||||
vkEndCommandBuffer(commandBuffer);
|
||||
|
||||
VkSubmitInfo submitInfo{};
|
||||
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||
submitInfo.commandBufferCount = 1;
|
||||
submitInfo.pCommandBuffers = &commandBuffer;
|
||||
|
||||
vkQueueSubmit(graphicsQueue, 1, &submitInfo, VK_NULL_HANDLE);
|
||||
vkQueueWaitIdle(graphicsQueue);
|
||||
vkFreeCommandBuffers(device, commandPool, 1, &commandBuffer);
|
||||
}
|
||||
|
||||
void Graphics::prepareDraw(uint32_t currentImage) {
|
||||
auto& buffer = uniformBuffers.at(currentImage);
|
||||
|
||||
@@ -471,6 +503,10 @@ namespace love {
|
||||
}
|
||||
}
|
||||
|
||||
if (!deviceFeatures.samplerAnisotropy) {
|
||||
score = 0;
|
||||
}
|
||||
|
||||
return score;
|
||||
}
|
||||
|
||||
@@ -523,6 +559,7 @@ namespace love {
|
||||
}
|
||||
|
||||
VkPhysicalDeviceFeatures deviceFeatures{};
|
||||
deviceFeatures.samplerAnisotropy = VK_TRUE;
|
||||
|
||||
VkDeviceCreateInfo createInfo{};
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
||||
|
||||
@@ -37,8 +37,14 @@ namespace love {
|
||||
return physicalDevice;
|
||||
}
|
||||
|
||||
const VmaAllocator getVmaAllocator() const {
|
||||
return vmaAllocator;
|
||||
}
|
||||
|
||||
// implementation for virtual functions
|
||||
Texture* newTexture(const Texture::Settings& settings, const Texture::Slices* data = nullptr) override { std::cout << "newTexture "; return new Texture(this, settings, data); }
|
||||
love::graphics::Texture* newTexture(const love::graphics::Texture::Settings& settings, const love::graphics::Texture::Slices* data = nullptr) override {
|
||||
return new Texture(this, settings, data);
|
||||
}
|
||||
love::graphics::Buffer* newBuffer(const love::graphics::Buffer::Settings& settings, const std::vector<love::graphics::Buffer::DataDeclaration>& format, const void* data, size_t size, size_t arraylength) override;
|
||||
void clear(OptionalColorD color, OptionalInt stencil, OptionalDouble depth) override { std::cout << "clear1 "; }
|
||||
void clear(const std::vector<OptionalColorD>& colors, OptionalInt stencil, OptionalDouble depth) override { std::cout << "clear2 "; }
|
||||
@@ -70,6 +76,9 @@ namespace love {
|
||||
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 "; }
|
||||
|
||||
VkCommandBuffer beginSingleTimeCommands();
|
||||
void endSingleTimeCommands(VkCommandBuffer);
|
||||
|
||||
protected:
|
||||
graphics::ShaderStage* newShaderStageInternal(ShaderStageType stage, const std::string& cachekey, const std::string& source, bool gles) override {
|
||||
std::cout << "newShaderStageInternal ";
|
||||
|
||||
@@ -1,15 +1,219 @@
|
||||
#include "Texture.h"
|
||||
#include "Graphics.h"
|
||||
|
||||
// make vulkan::Graphics functions available
|
||||
#define vgfx ((Graphics*)gfx)
|
||||
|
||||
namespace love {
|
||||
namespace graphics {
|
||||
namespace vulkan {
|
||||
Texture::Texture(love::graphics::Graphics* gfx, const Settings& settings, const Slices* data)
|
||||
: love::graphics::Texture(gfx, settings, data) {
|
||||
: love::graphics::Texture(gfx, settings, data), slices(settings.type), gfx(gfx) {
|
||||
allocator = vgfx->getVmaAllocator();
|
||||
device = vgfx->getDevice();
|
||||
|
||||
if (data != nullptr) {
|
||||
slices = *data;
|
||||
}
|
||||
loadVolatile();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void Texture::createTextureImageView() {
|
||||
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.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
viewInfo.subresourceRange.baseMipLevel = 0;
|
||||
viewInfo.subresourceRange.levelCount = 1;
|
||||
viewInfo.subresourceRange.baseArrayLayer = 0;
|
||||
viewInfo.subresourceRange.layerCount = 1;
|
||||
|
||||
if (vkCreateImageView(device, &viewInfo, nullptr, &textureImageView) != VK_SUCCESS) {
|
||||
throw love::Exception("could not create texture image view");
|
||||
}
|
||||
}
|
||||
|
||||
void Texture::createTextureSampler() {
|
||||
auto physicalDevice = vgfx->getPhysicalDevice();
|
||||
VkPhysicalDeviceProperties properties{};
|
||||
vkGetPhysicalDeviceProperties(physicalDevice, &properties);
|
||||
|
||||
VkSamplerCreateInfo samplerInfo{};
|
||||
samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
||||
samplerInfo.magFilter = VK_FILTER_LINEAR;
|
||||
samplerInfo.minFilter = VK_FILTER_LINEAR;
|
||||
samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
samplerInfo.anisotropyEnable = VK_TRUE;
|
||||
samplerInfo.maxAnisotropy = properties.limits.maxSamplerAnisotropy;
|
||||
samplerInfo.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK;
|
||||
samplerInfo.unnormalizedCoordinates = VK_FALSE;
|
||||
samplerInfo.compareEnable = VK_FALSE;
|
||||
samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS;
|
||||
samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
|
||||
samplerInfo.mipLodBias = 0.0f;
|
||||
samplerInfo.minLod = 0.0f;
|
||||
samplerInfo.maxLod = 0.0f;
|
||||
|
||||
if (vkCreateSampler(device, &samplerInfo, nullptr, &textureSampler) != VK_SUCCESS) {
|
||||
throw love::Exception("failed to create texture sampler");
|
||||
}
|
||||
}
|
||||
|
||||
void Texture::transitionImageLayout(VkImage image, VkFormat format, VkImageLayout oldLayout, VkImageLayout newLayout) {
|
||||
auto commandBuffer = vgfx->beginSingleTimeCommands();
|
||||
|
||||
VkPipelineStageFlags sourceStage;
|
||||
VkPipelineStageFlags destinationStage;
|
||||
|
||||
VkImageMemoryBarrier barrier{};
|
||||
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
||||
barrier.oldLayout = oldLayout;
|
||||
barrier.newLayout = newLayout;
|
||||
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
barrier.image = image;
|
||||
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
barrier.subresourceRange.baseMipLevel = 0;
|
||||
barrier.subresourceRange.levelCount = 1;
|
||||
barrier.subresourceRange.baseArrayLayer = 0;
|
||||
barrier.subresourceRange.layerCount = 1;
|
||||
|
||||
if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) {
|
||||
barrier.srcAccessMask = 0;
|
||||
barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
|
||||
sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
|
||||
destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
} else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
|
||||
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
||||
|
||||
sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
||||
}
|
||||
else {
|
||||
throw love::Exception("unsupported lay transition");
|
||||
}
|
||||
|
||||
vkCmdPipelineBarrier(
|
||||
commandBuffer,
|
||||
sourceStage, destinationStage,
|
||||
0,
|
||||
0, nullptr,
|
||||
0, nullptr,
|
||||
1, &barrier
|
||||
);
|
||||
|
||||
vgfx->endSingleTimeCommands(commandBuffer);
|
||||
}
|
||||
|
||||
void Texture::copyBufferToImage(VkBuffer buffer, VkImage image, uint32_t width, uint32_t height) {
|
||||
auto commandBuffer = vgfx->beginSingleTimeCommands();
|
||||
|
||||
VkBufferImageCopy region{};
|
||||
region.bufferOffset = 0;
|
||||
region.bufferRowLength = 0;
|
||||
region.bufferImageHeight = 0;
|
||||
|
||||
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
region.imageSubresource.mipLevel = 0;
|
||||
region.imageSubresource.baseArrayLayer = 0;
|
||||
region.imageSubresource.layerCount = 1;
|
||||
|
||||
region.imageOffset = { 0, 0, 0 };
|
||||
region.imageExtent = {
|
||||
width,
|
||||
height, 1
|
||||
};
|
||||
|
||||
vkCmdCopyBufferToImage(
|
||||
commandBuffer,
|
||||
buffer,
|
||||
image,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
1,
|
||||
®ion
|
||||
);
|
||||
|
||||
vgfx->endSingleTimeCommands(commandBuffer);
|
||||
}
|
||||
|
||||
void Texture::uploadByteData(PixelFormat pixelformat, const void* data, size_t size, int level, int slice, const Rect& r) {
|
||||
std::cout << "Texture::uploadByteData ";
|
||||
VkBuffer stagingBuffer;
|
||||
VmaAllocation vmaAllocation;
|
||||
|
||||
VkBufferCreateInfo bufferCreateInfo{};
|
||||
bufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
||||
bufferCreateInfo.size = size;
|
||||
bufferCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
|
||||
|
||||
VmaAllocationCreateInfo allocCreateInfo = {};
|
||||
allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
|
||||
allocCreateInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT;
|
||||
|
||||
VmaAllocationInfo allocInfo;
|
||||
vmaCreateBuffer(allocator, &bufferCreateInfo, &allocCreateInfo, &stagingBuffer, &vmaAllocation, &allocInfo);
|
||||
|
||||
memcpy(allocInfo.pMappedData, data, size);
|
||||
|
||||
VkImageCreateInfo imageInfo{};
|
||||
imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||
imageInfo.imageType = VK_IMAGE_TYPE_2D;
|
||||
imageInfo.extent.width = static_cast<uint32_t>(r.w);
|
||||
imageInfo.extent.height = static_cast<uint32_t>(r.h);
|
||||
imageInfo.extent.depth = 1;
|
||||
imageInfo.mipLevels = 1;
|
||||
imageInfo.arrayLayers = 1;
|
||||
imageInfo.format = VK_FORMAT_R8G8B8A8_SRGB;
|
||||
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;
|
||||
imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
imageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
|
||||
VmaAllocationCreateInfo imageAllocationCreateInfo{};
|
||||
|
||||
if (vmaCreateImage(allocator, &imageInfo, &imageAllocationCreateInfo, &textureImage, &textureImageAllocation, nullptr) != VK_SUCCESS) {
|
||||
throw love::Exception("failed to create image");
|
||||
}
|
||||
|
||||
transitionImageLayout(textureImage, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
copyBufferToImage(stagingBuffer, textureImage, static_cast<uint32_t>(r.w), static_cast<uint32_t>(r.h));
|
||||
transitionImageLayout(textureImage, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
|
||||
vmaDestroyBuffer(allocator, stagingBuffer, vmaAllocation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,25 @@
|
||||
#ifndef LOVE_GRAPHICS_VULKAN_TEXTURE_H
|
||||
#define LOVE_GRAPHICS_VULKAN_TEXTURE_H
|
||||
|
||||
#include "graphics/Texture.h"
|
||||
#include "graphics/Volatile.h"
|
||||
|
||||
#include "vk_mem_alloc.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
||||
namespace love {
|
||||
namespace graphics {
|
||||
namespace vulkan {
|
||||
class Texture : public graphics::Texture {
|
||||
class Texture : public graphics::Texture, public graphics::Volatile {
|
||||
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 "; };
|
||||
@@ -22,7 +34,24 @@ namespace love {
|
||||
|
||||
int getMSAA() const override { std::cout << "Texture::getMSAA "; return 0; };
|
||||
ptrdiff_t getHandle() const override { std::cout << "Texture::getHandle "; return (ptrdiff_t)0; }
|
||||
|
||||
private:
|
||||
void transitionImageLayout(VkImage, VkFormat, VkImageLayout oldLayout, VkImageLayout newLayout);
|
||||
void copyBufferToImage(VkBuffer, VkImage, uint32_t width, uint32_t height);
|
||||
void createTextureImageView();
|
||||
void createTextureSampler();
|
||||
|
||||
graphics::Graphics* gfx;
|
||||
VkDevice device;
|
||||
Slices slices;
|
||||
VmaAllocator allocator;
|
||||
VkImage textureImage;
|
||||
VmaAllocation textureImageAllocation;
|
||||
VkImageView textureImageView;
|
||||
VkSampler textureSampler;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user