MeshLoader now uses VulkanDevice for creating buffers

This commit is contained in:
saschawillems 2016-07-16 19:14:11 +02:00
parent 3c944c2bd9
commit 8d7450dbf6
6 changed files with 51 additions and 97 deletions

View file

@ -32,6 +32,8 @@
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/matrix_transform.hpp>
#include "vulkandevice.hpp"
#if defined(__ANDROID__) #if defined(__ANDROID__)
#include <android/asset_manager.h> #include <android/asset_manager.h>
#endif #endif
@ -201,8 +203,10 @@ namespace vkMeshLoader
} }
// Simple mesh class for getting all the necessary stuff from models loaded via ASSIMP // Simple mesh class for getting all the necessary stuff from models loaded via ASSIMP
class VulkanMeshLoader { class VulkanMeshLoader
{
private: private:
vk::VulkanDevice *vulkanDevice;
struct Vertex struct Vertex
{ {
@ -234,24 +238,6 @@ private:
std::vector<unsigned int> Indices; std::vector<unsigned int> Indices;
}; };
VkBool32 getMemoryType(VkPhysicalDeviceMemoryProperties deviceMemoryProperties, uint32_t typeBits, VkMemoryPropertyFlags properties)
{
for (uint32_t i = 0; i < 32; i++)
{
if ((typeBits & 1) == 1)
{
if ((deviceMemoryProperties.memoryTypes[i].propertyFlags & properties) == properties)
{
return i;
}
}
typeBits >>= 1;
}
// todo : throw error
return 0;
}
public: public:
#if defined(__ANDROID__) #if defined(__ANDROID__)
AAssetManager* assetManager = nullptr; AAssetManager* assetManager = nullptr;
@ -289,6 +275,12 @@ public:
Assimp::Importer Importer; Assimp::Importer Importer;
const aiScene* pScene; const aiScene* pScene;
VulkanMeshLoader(vk::VulkanDevice *vulkanDevice)
{
assert(vulkanDevice != nullptr);
this->vulkanDevice = vulkanDevice;
}
~VulkanMeshLoader() ~VulkanMeshLoader()
{ {
m_Entries.clear(); m_Entries.clear();
@ -416,7 +408,9 @@ public:
} }
} }
// Clean up vulkan resources used by a mesh /**
* Free up all Vulkan resources used by a mesh
*/
static void freeVulkanResources(VkDevice device, VulkanMeshLoader *mesh) static void freeVulkanResources(VkDevice device, VulkanMeshLoader *mesh)
{ {
vkDestroyBuffer(device, mesh->vertexBuffer.buf, nullptr); vkDestroyBuffer(device, mesh->vertexBuffer.buf, nullptr);
@ -425,34 +419,20 @@ public:
vkFreeMemory(device, mesh->indexBuffer.mem, nullptr); vkFreeMemory(device, mesh->indexBuffer.mem, nullptr);
} }
VkResult createBuffer(
VkDevice device,
VkPhysicalDeviceMemoryProperties deviceMemoryProperties,
VkBufferUsageFlags usageFlags,
VkMemoryPropertyFlags memoryPropertyFlags,
VkDeviceSize size,
VkBuffer *buffer,
VkDeviceMemory *memory)
{
VkMemoryAllocateInfo memAllocInfo = vkTools::initializers::memoryAllocateInfo();
VkMemoryRequirements memReqs;
VkBufferCreateInfo bufferInfo = vkTools::initializers::bufferCreateInfo(usageFlags, size);
VK_CHECK_RESULT(vkCreateBuffer(device, &bufferInfo, nullptr, buffer));
vkGetBufferMemoryRequirements(device, *buffer, &memReqs);
memAllocInfo.allocationSize = memReqs.size;
memAllocInfo.memoryTypeIndex = getMemoryType(deviceMemoryProperties, memReqs.memoryTypeBits, memoryPropertyFlags);
VK_CHECK_RESULT(vkAllocateMemory(device, &memAllocInfo, nullptr, memory));
VK_CHECK_RESULT(vkBindBufferMemory(device, *buffer, *memory, 0));
return VK_SUCCESS;
}
// Create vertex and index buffer with given layout // Create vertex and index buffer with given layout
// Note : Only does staging if a valid command buffer and transfer queue are passed // Note : Only does staging if a valid command buffer and transfer queue are passed
/**
* Create Vulkan buffers for the index and vertex buffer using a vertex layout
*
* @param meshBuffer Pointer to the mesh buffer containing buffer handles and memory
* @param layout Vertex layout for the vertex buffer
* @param createInfo Structure containing information for mesh creation time (center, scaling, etc.)
* @param useStaging If true, buffers are staged to device local memory
* @param copyCmd (Required for staging) Command buffer to put the copy commands into
* @param copyQueue (Required for staging) Queue to put copys into
*/
void createBuffers( void createBuffers(
VkDevice device,
VkPhysicalDeviceMemoryProperties deviceMemoryProperties,
vkMeshLoader::MeshBuffer *meshBuffer, vkMeshLoader::MeshBuffer *meshBuffer,
std::vector<vkMeshLoader::VertexLayout> layout, std::vector<vkMeshLoader::VertexLayout> layout,
vkMeshLoader::MeshCreateInfo *createInfo, vkMeshLoader::MeshCreateInfo *createInfo,
@ -571,38 +551,26 @@ public:
} vertexStaging, indexStaging; } vertexStaging, indexStaging;
// Vertex buffer // Vertex buffer
createBuffer( vulkanDevice->createBuffer(
device,
deviceMemoryProperties,
VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
meshBuffer->vertices.size, meshBuffer->vertices.size,
&vertexStaging.buffer, &vertexStaging.buffer,
&vertexStaging.memory); &vertexStaging.memory,
vertexBuffer.data());
VK_CHECK_RESULT(vkMapMemory(device, vertexStaging.memory, 0, VK_WHOLE_SIZE, 0, &data));
memcpy(data, vertexBuffer.data(), meshBuffer->vertices.size);
vkUnmapMemory(device, vertexStaging.memory);
// Index buffer // Index buffer
createBuffer( vulkanDevice->createBuffer(
device,
deviceMemoryProperties,
VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
meshBuffer->indices.size, meshBuffer->indices.size,
&indexStaging.buffer, &indexStaging.buffer,
&indexStaging.memory); &indexStaging.memory,
indexBuffer.data());
VK_CHECK_RESULT(vkMapMemory(device, indexStaging.memory, 0, VK_WHOLE_SIZE, 0, &data));
memcpy(data, indexBuffer.data(), meshBuffer->indices.size);
vkUnmapMemory(device, indexStaging.memory);
// Create device local target buffers // Create device local target buffers
// Vertex buffer // Vertex buffer
createBuffer( vulkanDevice->createBuffer(
device,
deviceMemoryProperties,
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
meshBuffer->vertices.size, meshBuffer->vertices.size,
@ -610,9 +578,7 @@ public:
&meshBuffer->vertices.mem); &meshBuffer->vertices.mem);
// Index buffer // Index buffer
createBuffer( vulkanDevice->createBuffer(
device,
deviceMemoryProperties,
VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
meshBuffer->indices.size, meshBuffer->indices.size,
@ -651,40 +617,30 @@ public:
VK_CHECK_RESULT(vkQueueSubmit(copyQueue, 1, &submitInfo, VK_NULL_HANDLE)); VK_CHECK_RESULT(vkQueueSubmit(copyQueue, 1, &submitInfo, VK_NULL_HANDLE));
VK_CHECK_RESULT(vkQueueWaitIdle(copyQueue)); VK_CHECK_RESULT(vkQueueWaitIdle(copyQueue));
vkDestroyBuffer(device, vertexStaging.buffer, nullptr); vkDestroyBuffer(vulkanDevice->device, vertexStaging.buffer, nullptr);
vkFreeMemory(device, vertexStaging.memory, nullptr); vkFreeMemory(vulkanDevice->device, vertexStaging.memory, nullptr);
vkDestroyBuffer(device, indexStaging.buffer, nullptr); vkDestroyBuffer(vulkanDevice->device, indexStaging.buffer, nullptr);
vkFreeMemory(device, indexStaging.memory, nullptr); vkFreeMemory(vulkanDevice->device, indexStaging.memory, nullptr);
} }
else else
{ {
// Generate vertex buffer // Generate vertex buffer
createBuffer( vulkanDevice->createBuffer(
device,
deviceMemoryProperties,
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
meshBuffer->vertices.size, meshBuffer->vertices.size,
&meshBuffer->vertices.buf, &meshBuffer->vertices.buf,
&meshBuffer->vertices.mem); &meshBuffer->vertices.mem,
vertexBuffer.data());
VK_CHECK_RESULT(vkMapMemory(device, meshBuffer->vertices.mem, 0, meshBuffer->vertices.size, 0, &data));
memcpy(data, vertexBuffer.data(), meshBuffer->vertices.size);
vkUnmapMemory(device, meshBuffer->vertices.mem);
// Generate index buffer // Generate index buffer
createBuffer( vulkanDevice->createBuffer(
device,
deviceMemoryProperties,
VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
meshBuffer->indices.size, meshBuffer->indices.size,
&meshBuffer->indices.buf, &meshBuffer->indices.buf,
&meshBuffer->indices.mem); &meshBuffer->indices.mem,
indexBuffer.data());
VK_CHECK_RESULT(vkMapMemory(device, meshBuffer->indices.mem, 0, meshBuffer->indices.size, 0, &data));
memcpy(data, indexBuffer.data(), meshBuffer->indices.size);
vkUnmapMemory(device, meshBuffer->indices.mem);
} }
} }
}; };

View file

@ -346,7 +346,7 @@ void VulkanExampleBase::loadMesh(std::string filename, vkMeshLoader::MeshBuffer
void VulkanExampleBase::loadMesh(std::string filename, vkMeshLoader::MeshBuffer * meshBuffer, std::vector<vkMeshLoader::VertexLayout> vertexLayout, vkMeshLoader::MeshCreateInfo *meshCreateInfo) void VulkanExampleBase::loadMesh(std::string filename, vkMeshLoader::MeshBuffer * meshBuffer, std::vector<vkMeshLoader::VertexLayout> vertexLayout, vkMeshLoader::MeshCreateInfo *meshCreateInfo)
{ {
VulkanMeshLoader *mesh = new VulkanMeshLoader(); VulkanMeshLoader *mesh = new VulkanMeshLoader(&vulkanDevice);
#if defined(__ANDROID__) #if defined(__ANDROID__)
mesh->assetManager = androidApp->activity->assetManager; mesh->assetManager = androidApp->activity->assetManager;
@ -358,8 +358,6 @@ void VulkanExampleBase::loadMesh(std::string filename, vkMeshLoader::MeshBuffer
VkCommandBuffer copyCmd = VulkanExampleBase::createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, false); VkCommandBuffer copyCmd = VulkanExampleBase::createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, false);
mesh->createBuffers( mesh->createBuffers(
device,
deviceMemoryProperties,
meshBuffer, meshBuffer,
vertexLayout, vertexLayout,
meshCreateInfo, meshCreateInfo,

View file

@ -585,7 +585,7 @@ public:
// Load a model file as separate meshes into a scene // Load a model file as separate meshes into a scene
void loadModel(std::string filename, Scene *scene) void loadModel(std::string filename, Scene *scene)
{ {
VulkanMeshLoader *meshLoader = new VulkanMeshLoader(); VulkanMeshLoader *meshLoader = new VulkanMeshLoader(&vulkanDevice);
#if defined(__ANDROID__) #if defined(__ANDROID__)
meshLoader->assetManager = androidApp->activity->assetManager; meshLoader->assetManager = androidApp->activity->assetManager;
#endif #endif

View file

@ -175,7 +175,7 @@ public:
// The other example will use the VulkanMesh loader which has some additional functionality for loading meshes // The other example will use the VulkanMesh loader which has some additional functionality for loading meshes
void loadMesh() void loadMesh()
{ {
VulkanMeshLoader *meshLoader = new VulkanMeshLoader(); VulkanMeshLoader *meshLoader = new VulkanMeshLoader(&vulkanDevice);
#if defined(__ANDROID__) #if defined(__ANDROID__)
meshLoader->assetManager = androidApp->activity->assetManager; meshLoader->assetManager = androidApp->activity->assetManager;
#endif #endif

View file

@ -482,7 +482,7 @@ public:
void loadMesh() void loadMesh()
{ {
skinnedMesh = new SkinnedMesh(); skinnedMesh = new SkinnedMesh();
skinnedMesh->meshLoader = new VulkanMeshLoader(); skinnedMesh->meshLoader = new VulkanMeshLoader(&vulkanDevice);
#if defined(__ANDROID__) #if defined(__ANDROID__)
skinnedMesh->meshLoader->assetManager = androidApp->activity->assetManager; skinnedMesh->meshLoader->assetManager = androidApp->activity->assetManager;
#endif #endif

View file

@ -182,10 +182,10 @@ public:
}; };
// Load meshes for demos scene // Load meshes for demos scene
demoMeshes.logos = new VulkanMeshLoader(); demoMeshes.logos = new VulkanMeshLoader(&vulkanDevice);
demoMeshes.background = new VulkanMeshLoader(); demoMeshes.background = new VulkanMeshLoader(&vulkanDevice);
demoMeshes.models = new VulkanMeshLoader(); demoMeshes.models = new VulkanMeshLoader(&vulkanDevice);
demoMeshes.skybox = new VulkanMeshLoader(); demoMeshes.skybox = new VulkanMeshLoader(&vulkanDevice);
#if defined(__ANDROID__) #if defined(__ANDROID__)
demoMeshes.logos->assetManager = androidApp->activity->assetManager; demoMeshes.logos->assetManager = androidApp->activity->assetManager;