优化内存读取
This commit is contained in:
+45
-33
@@ -641,24 +641,31 @@ uint32_t Application::findMemoryType(VkPhysicalDevice physicalDevice, uint32_t t
|
||||
throw std::runtime_error("Failed to find suitable memory type!");
|
||||
}
|
||||
|
||||
Texture Application::loadTexture(std::string path, Texture& tex, bool srgb)
|
||||
void Application::loadTexture(std::string path, Texture& tex, bool srgb)
|
||||
{
|
||||
std::vector<unsigned char> data = readFileUnsignedChar(path, false);
|
||||
std::vector<unsigned char> image;
|
||||
unsigned w, h;
|
||||
unsigned error = lodepng::decode(image, w, h, data, LCT_RGBA, 8);
|
||||
processWithVulkan(image.data(), w, h, w * 4, image.size(), tex, srgb);
|
||||
return tex;
|
||||
//return tex;
|
||||
}
|
||||
|
||||
void Application::loadTexture(std::vector<unsigned char>& image_data, size_t image_size, int w, int h, Texture& tex, bool srgb)
|
||||
{
|
||||
processWithVulkan(image_data.data(), w, h, w * 4, image_size, tex, srgb);
|
||||
//return tex;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
Texture Application::loadTextureExample(std::wstring path, Texture& tex, bool srgb)
|
||||
void Application::loadTextureExample(std::wstring path, Texture& tex, bool srgb)
|
||||
{
|
||||
std::vector<unsigned char> data = readFileUnsignedCharWin32(path, true);
|
||||
std::vector<unsigned char> image;
|
||||
unsigned w, h;
|
||||
unsigned error = lodepng::decode(image, w, h, data, LCT_RGBA, 8);
|
||||
processWithVulkan(image.data(), w, h, w * 4, image.size(), tex, srgb);
|
||||
return tex;
|
||||
//return tex;
|
||||
}
|
||||
|
||||
#endif // _WIN32
|
||||
@@ -762,6 +769,7 @@ void Application::createTexture(VkDevice device, VkPhysicalDevice physicalDevice
|
||||
}
|
||||
|
||||
texture.image_layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
texture.device = device;
|
||||
}
|
||||
|
||||
void Application::processWithVulkan(uint8_t* data, int width, int height, int rowStride, size_t dataSize, Texture& out_texture, bool srgb)
|
||||
@@ -820,38 +828,44 @@ void Application::updateTexture(VkDevice device, VkPhysicalDevice physicalDevice
|
||||
uint8_t* data, int width, int height,
|
||||
int rowStride, size_t dataSize, Texture& texture)
|
||||
{
|
||||
VkBuffer stagingBuffer;
|
||||
VkDeviceMemory stagingBufferMemory;
|
||||
//VkBuffer stagingBuffer;
|
||||
//VkDeviceMemory stagingBufferMemory;
|
||||
|
||||
VkBufferCreateInfo bufferInfo = {};
|
||||
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
||||
bufferInfo.size = dataSize;
|
||||
bufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
|
||||
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
|
||||
if (vkCreateBuffer(device, &bufferInfo, nullptr, &stagingBuffer) != VK_SUCCESS)
|
||||
if (texture.stagingBuffer == nullptr)
|
||||
{
|
||||
throw std::runtime_error("Failed to create staging buffer!");
|
||||
VkBufferCreateInfo bufferInfo = {};
|
||||
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
||||
bufferInfo.size = dataSize;
|
||||
bufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
|
||||
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
|
||||
if (vkCreateBuffer(device, &bufferInfo, nullptr, &texture.stagingBuffer) != VK_SUCCESS)
|
||||
{
|
||||
throw std::runtime_error("Failed to create staging buffer!");
|
||||
}
|
||||
}
|
||||
|
||||
VkMemoryRequirements memRequirements;
|
||||
vkGetBufferMemoryRequirements(device, stagingBuffer, &memRequirements);
|
||||
|
||||
VkMemoryAllocateInfo allocInfo = {};
|
||||
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||
allocInfo.allocationSize = memRequirements.size;
|
||||
allocInfo.memoryTypeIndex = findMemoryType(physicalDevice,
|
||||
memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
|
||||
|
||||
if (vkAllocateMemory(device, &allocInfo, nullptr, &stagingBufferMemory) != VK_SUCCESS)
|
||||
|
||||
if (texture.stagingBufferMemory == nullptr)
|
||||
{
|
||||
throw std::runtime_error("Failed to allocate staging buffer memory!");
|
||||
}
|
||||
VkMemoryRequirements memRequirements;
|
||||
vkGetBufferMemoryRequirements(device, texture.stagingBuffer, &memRequirements);
|
||||
|
||||
vkBindBufferMemory(device, stagingBuffer, stagingBufferMemory, 0);
|
||||
VkMemoryAllocateInfo allocInfo = {};
|
||||
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||
allocInfo.allocationSize = memRequirements.size;
|
||||
allocInfo.memoryTypeIndex = findMemoryType(physicalDevice,
|
||||
memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
|
||||
|
||||
if (vkAllocateMemory(device, &allocInfo, nullptr, &texture.stagingBufferMemory) != VK_SUCCESS)
|
||||
{
|
||||
throw std::runtime_error("Failed to allocate staging buffer memory!");
|
||||
}
|
||||
|
||||
vkBindBufferMemory(device, texture.stagingBuffer, texture.stagingBufferMemory, 0);
|
||||
}
|
||||
|
||||
void* mappedData;
|
||||
vkMapMemory(device, stagingBufferMemory, 0, dataSize, 0, &mappedData);
|
||||
vkMapMemory(device, texture.stagingBufferMemory, 0, dataSize, 0, &mappedData);
|
||||
|
||||
if (rowStride == width * 4)
|
||||
{
|
||||
@@ -871,7 +885,7 @@ void Application::updateTexture(VkDevice device, VkPhysicalDevice physicalDevice
|
||||
}
|
||||
}
|
||||
|
||||
vkUnmapMemory(device, stagingBufferMemory);
|
||||
vkUnmapMemory(device, texture.stagingBufferMemory);
|
||||
|
||||
VkCommandBuffer commandBuffer = beginSingleTimeCommands(device, commandPool);
|
||||
|
||||
@@ -891,7 +905,7 @@ void Application::updateTexture(VkDevice device, VkPhysicalDevice physicalDevice
|
||||
region.imageExtent = { static_cast<uint32_t>(width),
|
||||
static_cast<uint32_t>(height), 1 };
|
||||
|
||||
vkCmdCopyBufferToImage(commandBuffer, stagingBuffer, texture.image,
|
||||
vkCmdCopyBufferToImage(commandBuffer, texture.stagingBuffer, texture.image,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
||||
|
||||
transitionImageLayout(commandBuffer, texture.image,
|
||||
@@ -900,8 +914,6 @@ void Application::updateTexture(VkDevice device, VkPhysicalDevice physicalDevice
|
||||
|
||||
endSingleTimeCommands(device, commandPool, queue, commandBuffer);
|
||||
|
||||
vkDestroyBuffer(device, stagingBuffer, nullptr);
|
||||
vkFreeMemory(device, stagingBufferMemory, nullptr);
|
||||
|
||||
texture.image_layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
struct Texture
|
||||
{
|
||||
std::string name;
|
||||
VkSampler sampler;
|
||||
VkImage image;
|
||||
VkImageLayout image_layout;
|
||||
@@ -15,6 +16,9 @@ struct Texture
|
||||
VkImageView view;
|
||||
uint32_t width, height;
|
||||
uint32_t mip_levels;
|
||||
VkBuffer stagingBuffer = VK_NULL_HANDLE;
|
||||
VkDeviceMemory stagingBufferMemory = VK_NULL_HANDLE;
|
||||
VkDevice device;
|
||||
};
|
||||
|
||||
class Application : public AppBase
|
||||
@@ -74,9 +78,10 @@ protected:
|
||||
|
||||
|
||||
protected:
|
||||
Texture loadTexture(std::string path, Texture& tex, bool srgb);
|
||||
void loadTexture(std::string path, Texture& tex, bool srgb);
|
||||
void loadTexture(std::vector<unsigned char>& image_data, size_t image_size, int w, int h, Texture& tex, bool srgb);
|
||||
#ifdef _WIN32
|
||||
Texture loadTextureExample(std::wstring path, Texture& tex, bool srgb);
|
||||
void loadTextureExample(std::wstring path, Texture& tex, bool srgb);
|
||||
#endif
|
||||
|
||||
uint32_t findMemoryType(VkPhysicalDevice physicalDevice, uint32_t typeFilter,
|
||||
|
||||
+19
-2
@@ -1,5 +1,6 @@
|
||||
#include "FaceApp.h"
|
||||
#include "hardcode_data.h"
|
||||
#include "lodepng.h"
|
||||
#include <sstream>
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
@@ -721,12 +722,18 @@ void FaceApp::initVulkan()
|
||||
{
|
||||
m_texs_ex.resize(kMaxTexture);
|
||||
}
|
||||
|
||||
std::vector<unsigned char> data = readFileUnsignedChar("demo0.png", false);
|
||||
std::vector<unsigned char> image;
|
||||
unsigned w, h;
|
||||
unsigned error = lodepng::decode(image, w, h, data, LCT_RGBA, 8);
|
||||
|
||||
for (int i = 0; i < kMaxTexture; ++i)
|
||||
{
|
||||
loadTexture("demo0.png", m_texs[i], true);
|
||||
loadTexture(image, image.size(), w, h, m_texs[i], true);
|
||||
if (kThick)
|
||||
{
|
||||
loadTexture("demo0_ex.png", m_texs_ex[i], true);
|
||||
loadTexture(image, image.size(), w, h, m_texs_ex[i], true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1142,6 +1149,16 @@ void FaceApp::destroyTexture(VkDevice device, Texture& texture) {
|
||||
vkFreeMemory(device, texture.device_memory, nullptr);
|
||||
texture.device_memory = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
if (texture.stagingBuffer != VK_NULL_HANDLE)
|
||||
{
|
||||
vkDestroyBuffer(device, texture.stagingBuffer, nullptr);
|
||||
}
|
||||
|
||||
if (texture.stagingBufferMemory != VK_NULL_HANDLE)
|
||||
{
|
||||
vkFreeMemory(device, texture.stagingBufferMemory, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void FaceApp::cleanupResources(VkDevice device, VmaAllocator allocator) {
|
||||
|
||||
+14
-13
@@ -49,20 +49,21 @@ int main() {
|
||||
|
||||
InitArg init_arg;
|
||||
Motion motion;
|
||||
motion.type = "action24";
|
||||
for (int i = 0; i < 25; ++i)
|
||||
{
|
||||
if (i < 10)
|
||||
{
|
||||
motion.png_names.push_back("00000" + std::to_string(i) + ".png");
|
||||
}
|
||||
else
|
||||
{
|
||||
motion.png_names.push_back("0000" + std::to_string(i) + ".png");
|
||||
motion.type = "4";
|
||||
motion.png_names.push_back("4.png");
|
||||
//for (int i = 0; i < 25; ++i)
|
||||
//{
|
||||
// if (i < 10)
|
||||
// {
|
||||
// motion.png_names.push_back("00000" + std::to_string(i) + ".png");
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// motion.png_names.push_back("0000" + std::to_string(i) + ".png");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
// }
|
||||
//
|
||||
//}
|
||||
|
||||
#
|
||||
|
||||
|
||||
Reference in New Issue
Block a user