Render scene mesh by mesh, add debug names for buffers, pipelines, etc. add some debug markers
This commit is contained in:
parent
8acda2c1d0
commit
b6ce7bcfef
1 changed files with 229 additions and 179 deletions
|
|
@ -23,16 +23,9 @@
|
||||||
#define VERTEX_BUFFER_BIND_ID 0
|
#define VERTEX_BUFFER_BIND_ID 0
|
||||||
#define ENABLE_VALIDATION false
|
#define ENABLE_VALIDATION false
|
||||||
|
|
||||||
// Vertex layout used in this example
|
|
||||||
struct Vertex {
|
|
||||||
glm::vec3 pos;
|
|
||||||
glm::vec3 normal;
|
|
||||||
glm::vec2 uv;
|
|
||||||
glm::vec3 color;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Setup and functions for the VK_EXT_debug_marker_extension
|
// Setup and functions for the VK_EXT_debug_marker_extension
|
||||||
// Extension spec can be found at https://github.com/KhronosGroup/Vulkan-Docs/blob/1.0-VK_EXT_debug_marker/doc/specs/vulkan/appendices/VK_EXT_debug_marker.txt
|
// Extension spec can be found at https://github.com/KhronosGroup/Vulkan-Docs/blob/1.0-VK_EXT_debug_marker/doc/specs/vulkan/appendices/VK_EXT_debug_marker.txt
|
||||||
|
// Note that the extension will only be present if run from an offline debugging application
|
||||||
namespace DebugReportExt
|
namespace DebugReportExt
|
||||||
{
|
{
|
||||||
bool active = false;
|
bool active = false;
|
||||||
|
|
@ -91,7 +84,7 @@ namespace DebugReportExt
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert a new debug marker into the command buffer
|
// Insert a new debug marker into the command buffer
|
||||||
void insertDebugMarker(VkCommandBuffer cmdbuffer, const char* pMarkerName, glm::vec4 color)
|
void insertDebugMarker(VkCommandBuffer cmdbuffer, std::string markerName, glm::vec4 color)
|
||||||
{
|
{
|
||||||
// Check for valid function (may not be present if not runnin in a debugging application)
|
// Check for valid function (may not be present if not runnin in a debugging application)
|
||||||
if (pfnCmdDebugMarkerInsert)
|
if (pfnCmdDebugMarkerInsert)
|
||||||
|
|
@ -99,7 +92,7 @@ namespace DebugReportExt
|
||||||
VkDebugMarkerMarkerInfoEXT markerInfo = {};
|
VkDebugMarkerMarkerInfoEXT markerInfo = {};
|
||||||
markerInfo.sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT;
|
markerInfo.sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT;
|
||||||
memcpy(markerInfo.color, &color[0], sizeof(float) * 4);
|
memcpy(markerInfo.color, &color[0], sizeof(float) * 4);
|
||||||
markerInfo.pMarkerName = pMarkerName;
|
markerInfo.pMarkerName = markerName.c_str();
|
||||||
pfnCmdDebugMarkerInsert(cmdbuffer, &markerInfo);
|
pfnCmdDebugMarkerInsert(cmdbuffer, &markerInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -115,10 +108,18 @@ namespace DebugReportExt
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Vertex layout used in this example
|
||||||
|
struct Vertex {
|
||||||
|
glm::vec3 pos;
|
||||||
|
glm::vec3 normal;
|
||||||
|
glm::vec2 uv;
|
||||||
|
glm::vec3 color;
|
||||||
|
};
|
||||||
|
|
||||||
class VulkanExample : public VulkanExampleBase
|
class VulkanExample : public VulkanExampleBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool wireframe = true;
|
bool wireframe = false;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
vkTools::VulkanTexture colorMap;
|
vkTools::VulkanTexture colorMap;
|
||||||
|
|
@ -134,17 +135,25 @@ public:
|
||||||
// necessary to represent a mesh for rendering purposes
|
// necessary to represent a mesh for rendering purposes
|
||||||
// This is for demonstration and learning purposes,
|
// This is for demonstration and learning purposes,
|
||||||
// the other examples use a mesh loader class for easy access
|
// the other examples use a mesh loader class for easy access
|
||||||
struct Mesh {
|
struct Scene {
|
||||||
struct {
|
struct {
|
||||||
VkBuffer buf;
|
VkBuffer buf;
|
||||||
VkDeviceMemory mem;
|
VkDeviceMemory mem;
|
||||||
} vertices;
|
} vertices;
|
||||||
struct {
|
struct {
|
||||||
int count;
|
|
||||||
VkBuffer buf;
|
VkBuffer buf;
|
||||||
VkDeviceMemory mem;
|
VkDeviceMemory mem;
|
||||||
} indices;
|
} indices;
|
||||||
} mesh;
|
|
||||||
|
// Store mesh offsets for vertex and indexbuffers
|
||||||
|
struct Mesh
|
||||||
|
{
|
||||||
|
uint32_t indexStart;
|
||||||
|
uint32_t indexCount;
|
||||||
|
std::string name;
|
||||||
|
};
|
||||||
|
std::vector<Mesh> meshes;
|
||||||
|
} scene;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
vkTools::UniformData vsScene;
|
vkTools::UniformData vsScene;
|
||||||
|
|
@ -186,16 +195,182 @@ public:
|
||||||
vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr);
|
vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr);
|
||||||
|
|
||||||
// Destroy and free mesh resources
|
// Destroy and free mesh resources
|
||||||
vkDestroyBuffer(device, mesh.vertices.buf, nullptr);
|
vkDestroyBuffer(device, scene.vertices.buf, nullptr);
|
||||||
vkFreeMemory(device, mesh.vertices.mem, nullptr);
|
vkFreeMemory(device, scene.vertices.mem, nullptr);
|
||||||
vkDestroyBuffer(device, mesh.indices.buf, nullptr);
|
vkDestroyBuffer(device, scene.indices.buf, nullptr);
|
||||||
vkFreeMemory(device, mesh.indices.mem, nullptr);
|
vkFreeMemory(device, scene.indices.mem, nullptr);
|
||||||
|
|
||||||
textureLoader->destroyTexture(textures.colorMap);
|
textureLoader->destroyTexture(textures.colorMap);
|
||||||
|
|
||||||
vkTools::destroyUniformData(device, &uniformData.vsScene);
|
vkTools::destroyUniformData(device, &uniformData.vsScene);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load the scene from a model file
|
||||||
|
void loadScene(std::string filename)
|
||||||
|
{
|
||||||
|
VulkanMeshLoader *meshLoader = new VulkanMeshLoader();
|
||||||
|
#if defined(__ANDROID__)
|
||||||
|
meshLoader->assetManager = androidApp->activity->assetManager;
|
||||||
|
#endif
|
||||||
|
meshLoader->LoadMesh(filename);
|
||||||
|
|
||||||
|
scene.meshes.resize(meshLoader->m_Entries.size());
|
||||||
|
|
||||||
|
// Generate vertex buffer
|
||||||
|
float scale = 1.0f;
|
||||||
|
std::vector<Vertex> vertexBuffer;
|
||||||
|
// Iterate through all meshes in the file
|
||||||
|
// and extract the vertex information used in this demo
|
||||||
|
for (uint32_t m = 0; m < meshLoader->m_Entries.size(); m++)
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; i < meshLoader->m_Entries[m].Vertices.size(); i++)
|
||||||
|
{
|
||||||
|
Vertex vertex;
|
||||||
|
|
||||||
|
vertex.pos = meshLoader->m_Entries[m].Vertices[i].m_pos * scale;
|
||||||
|
vertex.normal = meshLoader->m_Entries[m].Vertices[i].m_normal;
|
||||||
|
vertex.uv = meshLoader->m_Entries[m].Vertices[i].m_tex;
|
||||||
|
vertex.color = meshLoader->m_Entries[m].Vertices[i].m_color;
|
||||||
|
|
||||||
|
vertexBuffer.push_back(vertex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uint32_t vertexBufferSize = vertexBuffer.size() * sizeof(Vertex);
|
||||||
|
|
||||||
|
// Generate index buffer from loaded mesh file
|
||||||
|
std::vector<uint32_t> indexBuffer;
|
||||||
|
for (uint32_t m = 0; m < meshLoader->m_Entries.size(); m++)
|
||||||
|
{
|
||||||
|
uint32_t indexBase = indexBuffer.size();
|
||||||
|
for (uint32_t i = 0; i < meshLoader->m_Entries[m].Indices.size(); i++)
|
||||||
|
{
|
||||||
|
indexBuffer.push_back(meshLoader->m_Entries[m].Indices[i] + indexBase);
|
||||||
|
}
|
||||||
|
scene.meshes[m].indexStart = indexBase;
|
||||||
|
scene.meshes[m].indexCount = meshLoader->m_Entries[m].Indices.size();
|
||||||
|
}
|
||||||
|
uint32_t indexBufferSize = indexBuffer.size() * sizeof(uint32_t);
|
||||||
|
|
||||||
|
// Static mesh should always be device local
|
||||||
|
|
||||||
|
bool useStaging = true;
|
||||||
|
|
||||||
|
if (useStaging)
|
||||||
|
{
|
||||||
|
struct {
|
||||||
|
VkBuffer buffer;
|
||||||
|
VkDeviceMemory memory;
|
||||||
|
} vertexStaging, indexStaging;
|
||||||
|
|
||||||
|
// Create staging buffers
|
||||||
|
// Vertex data
|
||||||
|
createBuffer(
|
||||||
|
VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
|
||||||
|
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
|
||||||
|
vertexBufferSize,
|
||||||
|
vertexBuffer.data(),
|
||||||
|
&vertexStaging.buffer,
|
||||||
|
&vertexStaging.memory);
|
||||||
|
// Index data
|
||||||
|
createBuffer(
|
||||||
|
VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
|
||||||
|
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
|
||||||
|
indexBufferSize,
|
||||||
|
indexBuffer.data(),
|
||||||
|
&indexStaging.buffer,
|
||||||
|
&indexStaging.memory);
|
||||||
|
|
||||||
|
// Create device local buffers
|
||||||
|
// Vertex buffer
|
||||||
|
createBuffer(
|
||||||
|
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
||||||
|
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||||
|
vertexBufferSize,
|
||||||
|
nullptr,
|
||||||
|
&scene.vertices.buf,
|
||||||
|
&scene.vertices.mem);
|
||||||
|
// Index buffer
|
||||||
|
createBuffer(
|
||||||
|
VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
||||||
|
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||||
|
indexBufferSize,
|
||||||
|
nullptr,
|
||||||
|
&scene.indices.buf,
|
||||||
|
&scene.indices.mem);
|
||||||
|
|
||||||
|
// Copy from staging buffers
|
||||||
|
VkCommandBuffer copyCmd = VulkanExampleBase::createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, true);
|
||||||
|
|
||||||
|
VkBufferCopy copyRegion = {};
|
||||||
|
|
||||||
|
copyRegion.size = vertexBufferSize;
|
||||||
|
vkCmdCopyBuffer(
|
||||||
|
copyCmd,
|
||||||
|
vertexStaging.buffer,
|
||||||
|
scene.vertices.buf,
|
||||||
|
1,
|
||||||
|
©Region);
|
||||||
|
|
||||||
|
copyRegion.size = indexBufferSize;
|
||||||
|
vkCmdCopyBuffer(
|
||||||
|
copyCmd,
|
||||||
|
indexStaging.buffer,
|
||||||
|
scene.indices.buf,
|
||||||
|
1,
|
||||||
|
©Region);
|
||||||
|
|
||||||
|
VulkanExampleBase::flushCommandBuffer(copyCmd, queue, true);
|
||||||
|
|
||||||
|
vkDestroyBuffer(device, vertexStaging.buffer, nullptr);
|
||||||
|
vkFreeMemory(device, vertexStaging.memory, nullptr);
|
||||||
|
vkDestroyBuffer(device, indexStaging.buffer, nullptr);
|
||||||
|
vkFreeMemory(device, indexStaging.memory, nullptr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Vertex buffer
|
||||||
|
createBuffer(
|
||||||
|
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
|
||||||
|
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
|
||||||
|
vertexBufferSize,
|
||||||
|
vertexBuffer.data(),
|
||||||
|
&scene.vertices.buf,
|
||||||
|
&scene.vertices.mem);
|
||||||
|
// Index buffer
|
||||||
|
createBuffer(
|
||||||
|
VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
|
||||||
|
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
|
||||||
|
indexBufferSize,
|
||||||
|
indexBuffer.data(),
|
||||||
|
&scene.indices.buf,
|
||||||
|
&scene.indices.mem);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete(meshLoader);
|
||||||
|
|
||||||
|
// Name the meshes
|
||||||
|
// ASSIMP does not load mesh names from the COLLADA file used in this example
|
||||||
|
// so we need to set them manually
|
||||||
|
// These names are used in command buffer creation for setting debug markers
|
||||||
|
std::vector<std::string> names = { "hill", "rocks", "cave", "tree", "mushroom stems", "blue mushroom caps", "red mushroom caps", "grass blades", "chest box", "chest fittings" };
|
||||||
|
for (size_t i = 0; i < names.size(); i++)
|
||||||
|
{
|
||||||
|
scene.meshes[i].name = names[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name the buffers for debugging
|
||||||
|
DebugReportExt::setObjectName(device, (uint64_t)scene.vertices.buf, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, "Scene vertex buffer");
|
||||||
|
DebugReportExt::setObjectName(device, (uint64_t)scene.indices.buf, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, "Scene index buffer");
|
||||||
|
}
|
||||||
|
|
||||||
|
void loadTextures()
|
||||||
|
{
|
||||||
|
textureLoader->loadTexture(
|
||||||
|
getAssetPath() + "models/voyager/voyager.ktx",
|
||||||
|
VK_FORMAT_BC3_UNORM_BLOCK,
|
||||||
|
&textures.colorMap);
|
||||||
|
}
|
||||||
|
|
||||||
void reBuildCommandBuffers()
|
void reBuildCommandBuffers()
|
||||||
{
|
{
|
||||||
if (!checkCommandBuffers())
|
if (!checkCommandBuffers())
|
||||||
|
|
@ -247,27 +422,41 @@ public:
|
||||||
|
|
||||||
// Solid rendering
|
// Solid rendering
|
||||||
|
|
||||||
// Insert debug marker
|
// Start a new debug marker region
|
||||||
DebugReportExt::insertDebugMarker(drawCmdBuffers[i], "Solid draw", glm::vec4(0.0f, 1.0f, 0.0f, 0.0f));
|
DebugReportExt::beginDebugMarkerRegion(drawCmdBuffers[i], "Solid draw", glm::vec4(1.0f, 0.0f, 0.0f, 0.0f));
|
||||||
|
|
||||||
vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.solid);
|
vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.solid);
|
||||||
vkCmdBindVertexBuffers(drawCmdBuffers[i], VERTEX_BUFFER_BIND_ID, 1, &mesh.vertices.buf, offsets);
|
vkCmdBindVertexBuffers(drawCmdBuffers[i], VERTEX_BUFFER_BIND_ID, 1, &scene.vertices.buf, offsets);
|
||||||
vkCmdBindIndexBuffer(drawCmdBuffers[i], mesh.indices.buf, 0, VK_INDEX_TYPE_UINT32);
|
vkCmdBindIndexBuffer(drawCmdBuffers[i], scene.indices.buf, 0, VK_INDEX_TYPE_UINT32);
|
||||||
vkCmdDrawIndexed(drawCmdBuffers[i], mesh.indices.count, 1, 0, 0, 0);
|
for (auto mesh : scene.meshes)
|
||||||
|
{
|
||||||
|
// Add debug marker for mesh name
|
||||||
|
DebugReportExt::insertDebugMarker(drawCmdBuffers[i], "Draw \"" + mesh.name + "\"", glm::vec4(0.0f));
|
||||||
|
vkCmdDrawIndexed(drawCmdBuffers[i], mesh.indexCount, 1, mesh.indexStart, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
DebugReportExt::endDebugMarkerRegion(drawCmdBuffers[i]);
|
||||||
|
|
||||||
// Wireframe rendering
|
// Wireframe rendering
|
||||||
if (wireframe)
|
if (wireframe)
|
||||||
{
|
{
|
||||||
// Insert debug marker
|
// Insert debug marker
|
||||||
DebugReportExt::insertDebugMarker(drawCmdBuffers[i], "Wireframe draw", glm::vec4(0.0f, 1.0f, 0.0f, 0.0f));
|
DebugReportExt::beginDebugMarkerRegion(drawCmdBuffers[i], "Wireframe draw", glm::vec4(1.0f, 0.0f, 0.0f, 0.0f));
|
||||||
|
|
||||||
scissor.offset.x = width / 2;
|
scissor.offset.x = width / 2;
|
||||||
vkCmdSetScissor(drawCmdBuffers[i], 0, 1, &scissor);
|
vkCmdSetScissor(drawCmdBuffers[i], 0, 1, &scissor);
|
||||||
|
|
||||||
vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.wireframe);
|
vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.wireframe);
|
||||||
vkCmdBindVertexBuffers(drawCmdBuffers[i], VERTEX_BUFFER_BIND_ID, 1, &mesh.vertices.buf, offsets);
|
vkCmdBindVertexBuffers(drawCmdBuffers[i], VERTEX_BUFFER_BIND_ID, 1, &scene.vertices.buf, offsets);
|
||||||
vkCmdBindIndexBuffer(drawCmdBuffers[i], mesh.indices.buf, 0, VK_INDEX_TYPE_UINT32);
|
vkCmdBindIndexBuffer(drawCmdBuffers[i], scene.indices.buf, 0, VK_INDEX_TYPE_UINT32);
|
||||||
vkCmdDrawIndexed(drawCmdBuffers[i], mesh.indices.count, 1, 0, 0, 0);
|
for (auto mesh : scene.meshes)
|
||||||
|
{
|
||||||
|
// Add debug marker for mesh name
|
||||||
|
DebugReportExt::insertDebugMarker(drawCmdBuffers[i], "Draw \"" + mesh.name + "\"", glm::vec4(0.0f));
|
||||||
|
vkCmdDrawIndexed(drawCmdBuffers[i], mesh.indexCount, 1, mesh.indexStart, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
DebugReportExt::endDebugMarkerRegion(drawCmdBuffers[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
vkCmdEndRenderPass(drawCmdBuffers[i]);
|
vkCmdEndRenderPass(drawCmdBuffers[i]);
|
||||||
|
|
@ -279,156 +468,6 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load a mesh based on data read via assimp
|
|
||||||
// The other example will use the VulkanMesh loader which has some additional functionality for loading meshes
|
|
||||||
void loadMesh()
|
|
||||||
{
|
|
||||||
VulkanMeshLoader *meshLoader = new VulkanMeshLoader();
|
|
||||||
#if defined(__ANDROID__)
|
|
||||||
meshLoader->assetManager = androidApp->activity->assetManager;
|
|
||||||
#endif
|
|
||||||
meshLoader->LoadMesh(getAssetPath() + "models/treasure.dae");
|
|
||||||
|
|
||||||
// Generate vertex buffer
|
|
||||||
float scale = 1.0f;
|
|
||||||
std::vector<Vertex> vertexBuffer;
|
|
||||||
// Iterate through all meshes in the file
|
|
||||||
// and extract the vertex information used in this demo
|
|
||||||
for (uint32_t m = 0; m < meshLoader->m_Entries.size(); m++)
|
|
||||||
{
|
|
||||||
for (uint32_t i = 0; i < meshLoader->m_Entries[m].Vertices.size(); i++)
|
|
||||||
{
|
|
||||||
Vertex vertex;
|
|
||||||
|
|
||||||
vertex.pos = meshLoader->m_Entries[m].Vertices[i].m_pos * scale;
|
|
||||||
vertex.normal = meshLoader->m_Entries[m].Vertices[i].m_normal;
|
|
||||||
vertex.uv = meshLoader->m_Entries[m].Vertices[i].m_tex;
|
|
||||||
vertex.color = meshLoader->m_Entries[m].Vertices[i].m_color;
|
|
||||||
|
|
||||||
vertexBuffer.push_back(vertex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
uint32_t vertexBufferSize = vertexBuffer.size() * sizeof(Vertex);
|
|
||||||
|
|
||||||
// Generate index buffer from loaded mesh file
|
|
||||||
std::vector<uint32_t> indexBuffer;
|
|
||||||
for (uint32_t m = 0; m < meshLoader->m_Entries.size(); m++)
|
|
||||||
{
|
|
||||||
uint32_t indexBase = indexBuffer.size();
|
|
||||||
for (uint32_t i = 0; i < meshLoader->m_Entries[m].Indices.size(); i++)
|
|
||||||
{
|
|
||||||
indexBuffer.push_back(meshLoader->m_Entries[m].Indices[i] + indexBase);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
uint32_t indexBufferSize = indexBuffer.size() * sizeof(uint32_t);
|
|
||||||
mesh.indices.count = indexBuffer.size();
|
|
||||||
|
|
||||||
// Static mesh should always be device local
|
|
||||||
|
|
||||||
bool useStaging = true;
|
|
||||||
|
|
||||||
if (useStaging)
|
|
||||||
{
|
|
||||||
struct {
|
|
||||||
VkBuffer buffer;
|
|
||||||
VkDeviceMemory memory;
|
|
||||||
} vertexStaging, indexStaging;
|
|
||||||
|
|
||||||
// Create staging buffers
|
|
||||||
// Vertex data
|
|
||||||
createBuffer(
|
|
||||||
VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
|
|
||||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
|
|
||||||
vertexBufferSize,
|
|
||||||
vertexBuffer.data(),
|
|
||||||
&vertexStaging.buffer,
|
|
||||||
&vertexStaging.memory);
|
|
||||||
// Index data
|
|
||||||
createBuffer(
|
|
||||||
VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
|
|
||||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
|
|
||||||
indexBufferSize,
|
|
||||||
indexBuffer.data(),
|
|
||||||
&indexStaging.buffer,
|
|
||||||
&indexStaging.memory);
|
|
||||||
|
|
||||||
// Create device local buffers
|
|
||||||
// Vertex buffer
|
|
||||||
createBuffer(
|
|
||||||
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
|
||||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
|
||||||
vertexBufferSize,
|
|
||||||
nullptr,
|
|
||||||
&mesh.vertices.buf,
|
|
||||||
&mesh.vertices.mem);
|
|
||||||
// Index buffer
|
|
||||||
createBuffer(
|
|
||||||
VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
|
||||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
|
||||||
indexBufferSize,
|
|
||||||
nullptr,
|
|
||||||
&mesh.indices.buf,
|
|
||||||
&mesh.indices.mem);
|
|
||||||
|
|
||||||
// Copy from staging buffers
|
|
||||||
VkCommandBuffer copyCmd = VulkanExampleBase::createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, true);
|
|
||||||
|
|
||||||
VkBufferCopy copyRegion = {};
|
|
||||||
|
|
||||||
copyRegion.size = vertexBufferSize;
|
|
||||||
vkCmdCopyBuffer(
|
|
||||||
copyCmd,
|
|
||||||
vertexStaging.buffer,
|
|
||||||
mesh.vertices.buf,
|
|
||||||
1,
|
|
||||||
©Region);
|
|
||||||
|
|
||||||
copyRegion.size = indexBufferSize;
|
|
||||||
vkCmdCopyBuffer(
|
|
||||||
copyCmd,
|
|
||||||
indexStaging.buffer,
|
|
||||||
mesh.indices.buf,
|
|
||||||
1,
|
|
||||||
©Region);
|
|
||||||
|
|
||||||
VulkanExampleBase::flushCommandBuffer(copyCmd, queue, true);
|
|
||||||
|
|
||||||
vkDestroyBuffer(device, vertexStaging.buffer, nullptr);
|
|
||||||
vkFreeMemory(device, vertexStaging.memory, nullptr);
|
|
||||||
vkDestroyBuffer(device, indexStaging.buffer, nullptr);
|
|
||||||
vkFreeMemory(device, indexStaging.memory, nullptr);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Vertex buffer
|
|
||||||
createBuffer(
|
|
||||||
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
|
|
||||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
|
|
||||||
vertexBufferSize,
|
|
||||||
vertexBuffer.data(),
|
|
||||||
&mesh.vertices.buf,
|
|
||||||
&mesh.vertices.mem);
|
|
||||||
// Index buffer
|
|
||||||
createBuffer(
|
|
||||||
VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
|
|
||||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
|
|
||||||
indexBufferSize,
|
|
||||||
indexBuffer.data(),
|
|
||||||
&mesh.indices.buf,
|
|
||||||
&mesh.indices.mem);
|
|
||||||
}
|
|
||||||
|
|
||||||
delete(meshLoader);
|
|
||||||
}
|
|
||||||
|
|
||||||
void loadTextures()
|
|
||||||
{
|
|
||||||
textureLoader->loadTexture(
|
|
||||||
getAssetPath() + "models/voyager/voyager.ktx",
|
|
||||||
VK_FORMAT_BC3_UNORM_BLOCK,
|
|
||||||
&textures.colorMap);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setupVertexDescriptions()
|
void setupVertexDescriptions()
|
||||||
{
|
{
|
||||||
// Binding description
|
// Binding description
|
||||||
|
|
@ -618,6 +657,10 @@ public:
|
||||||
shaderStages[0] = loadShader(getAssetPath() + "shaders/debugmarker/mesh.vert.spv", VK_SHADER_STAGE_VERTEX_BIT);
|
shaderStages[0] = loadShader(getAssetPath() + "shaders/debugmarker/mesh.vert.spv", VK_SHADER_STAGE_VERTEX_BIT);
|
||||||
shaderStages[1] = loadShader(getAssetPath() + "shaders/debugmarker/mesh.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT);
|
shaderStages[1] = loadShader(getAssetPath() + "shaders/debugmarker/mesh.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||||
|
|
||||||
|
// Name shader moduels for debugging
|
||||||
|
DebugReportExt::setObjectName(device, (uint64_t)shaderModules[0], VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT, "Mesh rendering vertex shader");
|
||||||
|
DebugReportExt::setObjectName(device, (uint64_t)shaderModules[1], VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT, "Mesh rendering fragment shader");
|
||||||
|
|
||||||
VkGraphicsPipelineCreateInfo pipelineCreateInfo =
|
VkGraphicsPipelineCreateInfo pipelineCreateInfo =
|
||||||
vkTools::initializers::pipelineCreateInfo(
|
vkTools::initializers::pipelineCreateInfo(
|
||||||
pipelineLayout,
|
pipelineLayout,
|
||||||
|
|
@ -642,6 +685,10 @@ public:
|
||||||
rasterizationState.lineWidth = 1.0f;
|
rasterizationState.lineWidth = 1.0f;
|
||||||
|
|
||||||
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.wireframe));
|
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.wireframe));
|
||||||
|
|
||||||
|
// Name pipelines for debugging
|
||||||
|
DebugReportExt::setObjectName(device, (uint64_t)pipelines.solid, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, "Solid rendering pipeline");
|
||||||
|
DebugReportExt::setObjectName(device, (uint64_t)pipelines.wireframe, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, "Wireframe rendering pipeline");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepare and initialize uniform buffer containing shader uniforms
|
// Prepare and initialize uniform buffer containing shader uniforms
|
||||||
|
|
@ -657,6 +704,9 @@ public:
|
||||||
&uniformData.vsScene.memory,
|
&uniformData.vsScene.memory,
|
||||||
&uniformData.vsScene.descriptor);
|
&uniformData.vsScene.descriptor);
|
||||||
|
|
||||||
|
// Name uniform buffer for debugging
|
||||||
|
DebugReportExt::setObjectName(device, (uint64_t)uniformData.vsScene.buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, "Scene uniform buffer block");
|
||||||
|
|
||||||
updateUniformBuffers();
|
updateUniformBuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -690,9 +740,9 @@ public:
|
||||||
void prepare()
|
void prepare()
|
||||||
{
|
{
|
||||||
VulkanExampleBase::prepare();
|
VulkanExampleBase::prepare();
|
||||||
DebugReportExt::setupDebugMarkers(VulkanExampleBase::device);
|
DebugReportExt::setupDebugMarkers(device);
|
||||||
loadTextures();
|
loadTextures();
|
||||||
loadMesh();
|
loadScene(getAssetPath() + "models/treasure.dae");
|
||||||
setupVertexDescriptions();
|
setupVertexDescriptions();
|
||||||
prepareUniformBuffers();
|
prepareUniformBuffers();
|
||||||
setupDescriptorSetLayout();
|
setupDescriptorSetLayout();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue