mirror of
https://github.com/PancakeTAS/lsfg-vk.git
synced 2025-10-30 07:01:10 +00:00
host image copy
This commit is contained in:
parent
6b21e1f298
commit
bdeae9b8d0
4 changed files with 107 additions and 4 deletions
16
include/utils/upload.hpp
Normal file
16
include/utils/upload.hpp
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef UPLOAD_HPP
|
||||
#define UPLOAD_HPP
|
||||
|
||||
#include "core/image.hpp"
|
||||
#include "device.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace Upload {
|
||||
|
||||
void upload(const Vulkan::Device& device,
|
||||
Vulkan::Core::Image& image, const std::string& path);
|
||||
|
||||
}
|
||||
|
||||
#endif // UPLOAD_HPP
|
||||
|
|
@ -3,10 +3,13 @@
|
|||
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
using namespace Vulkan;
|
||||
|
||||
const std::vector<const char*> requiredExtensions = {
|
||||
"VK_EXT_host_image_copy"
|
||||
};
|
||||
|
||||
Device::Device(const Instance& instance) {
|
||||
// get all physical devices
|
||||
uint32_t deviceCount{};
|
||||
|
|
@ -50,8 +53,13 @@ Device::Device(const Instance& instance) {
|
|||
|
||||
// create logical device
|
||||
const float queuePriority{1.0F}; // highest priority
|
||||
VkPhysicalDeviceHostImageCopyFeaturesEXT hostImageCopyFeatures{
|
||||
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_IMAGE_COPY_FEATURES_EXT,
|
||||
.hostImageCopy = VK_TRUE
|
||||
};
|
||||
VkPhysicalDeviceVulkan13Features features13{
|
||||
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES,
|
||||
.pNext = &hostImageCopyFeatures,
|
||||
.synchronization2 = VK_TRUE
|
||||
};
|
||||
const VkPhysicalDeviceVulkan12Features features12{
|
||||
|
|
@ -70,7 +78,9 @@ Device::Device(const Instance& instance) {
|
|||
.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
|
||||
.pNext = &features12,
|
||||
.queueCreateInfoCount = 1,
|
||||
.pQueueCreateInfos = &computeQueueDesc
|
||||
.pQueueCreateInfos = &computeQueueDesc,
|
||||
.enabledExtensionCount = static_cast<uint32_t>(requiredExtensions.size()),
|
||||
.ppEnabledExtensionNames = requiredExtensions.data()
|
||||
};
|
||||
VkDevice deviceHandle{};
|
||||
res = vkCreateDevice(*physicalDevice, &deviceCreateInfo, nullptr, &deviceHandle);
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include "instance.hpp"
|
||||
#include "shaderchains/downsample.hpp"
|
||||
#include "utils/global.hpp"
|
||||
#include "utils/upload.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
|
@ -23,11 +24,13 @@ int main() {
|
|||
Globals::initializeGlobals(device);
|
||||
|
||||
// create initialization resources
|
||||
const Core::Image inputImage(
|
||||
Core::Image inputImage(
|
||||
device, { 2560, 1411 }, VK_FORMAT_R8G8B8A8_UNORM,
|
||||
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT,
|
||||
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT
|
||||
| VK_IMAGE_USAGE_HOST_TRANSFER_BIT, // (remove in prod)
|
||||
VK_IMAGE_ASPECT_COLOR_BIT
|
||||
);
|
||||
Upload::upload(device, inputImage, "rsc/images/source.dds");
|
||||
|
||||
// create the shaderchains
|
||||
Shaderchains::Downsample downsample(device, descriptorPool, inputImage);
|
||||
|
|
|
|||
74
src/utils/upload.cpp
Normal file
74
src/utils/upload.cpp
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
#include "utils/upload.hpp"
|
||||
#include "utils/exceptions.hpp"
|
||||
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
using namespace Upload;
|
||||
|
||||
void Upload::upload(const Vulkan::Device& device,
|
||||
Vulkan::Core::Image& image, const std::string& path) {
|
||||
auto vkTransitionImageLayoutEXT = reinterpret_cast<PFN_vkTransitionImageLayoutEXT>(
|
||||
vkGetDeviceProcAddr(device.handle(), "vkTransitionImageLayoutEXT"));
|
||||
auto vkCopyMemoryToImageEXT = reinterpret_cast<PFN_vkCopyMemoryToImageEXT>(
|
||||
vkGetDeviceProcAddr(device.handle(), "vkCopyMemoryToImageEXT"));
|
||||
|
||||
const VkHostImageLayoutTransitionInfoEXT transitionInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_HOST_IMAGE_LAYOUT_TRANSITION_INFO_EXT,
|
||||
.image = image.handle(),
|
||||
.oldLayout = image.getLayout(),
|
||||
.newLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.subresourceRange = {
|
||||
.aspectMask = image.getAspectFlags(),
|
||||
.levelCount = 1,
|
||||
.layerCount = 1
|
||||
}
|
||||
};
|
||||
image.setLayout(VK_IMAGE_LAYOUT_GENERAL);
|
||||
auto res = vkTransitionImageLayoutEXT(device.handle(), 1, &transitionInfo);
|
||||
if (res != VK_SUCCESS)
|
||||
throw ls::vulkan_error(res, "Failed to transition image layout for upload");
|
||||
|
||||
// read shader bytecode
|
||||
std::ifstream file(path, std::ios::ate | std::ios::binary);
|
||||
if (!file)
|
||||
throw std::system_error(errno, std::generic_category(), "Failed to open shader file: " + path);
|
||||
|
||||
std::streamsize size = file.tellg();
|
||||
size -= 124 - 4;
|
||||
std::vector<uint8_t> code(static_cast<size_t>(size));
|
||||
|
||||
file.seekg(0, std::ios::beg);
|
||||
if (!file.read(reinterpret_cast<char*>(code.data()), size))
|
||||
throw std::system_error(errno, std::generic_category(), "Failed to read shader file: " + path);
|
||||
|
||||
file.close();
|
||||
|
||||
// copy data to image
|
||||
auto extent = image.getExtent();
|
||||
const VkMemoryToImageCopyEXT copyInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_MEMORY_TO_IMAGE_COPY_EXT,
|
||||
.pHostPointer = code.data(),
|
||||
.imageSubresource = {
|
||||
.aspectMask = image.getAspectFlags(),
|
||||
.layerCount = 1
|
||||
},
|
||||
.imageExtent = {
|
||||
.width = extent.width,
|
||||
.height = extent.height,
|
||||
.depth = 1
|
||||
},
|
||||
};
|
||||
|
||||
const VkCopyMemoryToImageInfoEXT operationInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_COPY_MEMORY_TO_IMAGE_INFO_EXT,
|
||||
.dstImage = image.handle(),
|
||||
.dstImageLayout = image.getLayout(),
|
||||
.regionCount = 1,
|
||||
.pRegions = ©Info,
|
||||
};
|
||||
res = vkCopyMemoryToImageEXT(device.handle(), &operationInfo);
|
||||
if (res != VK_SUCCESS)
|
||||
throw ls::vulkan_error(res, "Failed to copy memory to image");
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue