Added code for tutorial 05 - Staging Resources

This commit is contained in:
plapins
2016-06-06 14:08:17 +02:00
parent 1ee571a0fb
commit 2c06d5d63f
13 changed files with 1174 additions and 1 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB

View File

@@ -127,4 +127,10 @@ add_executable( "04" "Vertex_Attributes"
${ALL_BASIC_AND_ADVANCED_SHARED_FILES} ${ALL_BASIC_AND_ADVANCED_SHARED_FILES}
Tutorial04/Tutorial04.h Tutorial04/Tutorial04.h
Tutorial04/main.cpp Tutorial04/main.cpp
Tutorial04/Tutorial04.cpp ) Tutorial04/Tutorial04.cpp )
add_executable( "05" "Staging_Resources"
${ALL_BASIC_AND_ADVANCED_SHARED_FILES}
Tutorial05/Tutorial05.h
Tutorial05/main.cpp
Tutorial05/Tutorial05.cpp )

View File

@@ -157,4 +157,7 @@ VK_DEVICE_LEVEL_FUNCTION( vkFreeMemory )
VK_DEVICE_LEVEL_FUNCTION( vkDestroyBuffer ) VK_DEVICE_LEVEL_FUNCTION( vkDestroyBuffer )
VK_DEVICE_LEVEL_FUNCTION( vkDestroyFence ) VK_DEVICE_LEVEL_FUNCTION( vkDestroyFence )
// Tutorial 05
VK_DEVICE_LEVEL_FUNCTION( vkCmdCopyBuffer )
#undef VK_DEVICE_LEVEL_FUNCTION #undef VK_DEVICE_LEVEL_FUNCTION

Binary file not shown.

View File

@@ -0,0 +1,36 @@
shader.frag
Warning, version 430 is not yet complete; most version-specific features are present, but some are missing.
Linked fragment stage:
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 13
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 9 11
ExecutionMode 4 OriginLowerLeft
Source GLSL 430
Name 4 "main"
Name 9 "o_Color"
Name 11 "v_Color"
Decorate 9(o_Color) Location 0
Decorate 11(v_Color) Location 0
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
7: TypeVector 6(float) 4
8: TypePointer Output 7(fvec4)
9(o_Color): 8(ptr) Variable Output
10: TypePointer Input 7(fvec4)
11(v_Color): 10(ptr) Variable Input
4(main): 2 Function None 3
5: Label
12: 7(fvec4) Load 11(v_Color)
Store 9(o_Color) 12
Return
FunctionEnd

View File

@@ -0,0 +1,19 @@
// Copyright 2016 Intel Corporation All Rights Reserved
//
// Intel makes no representations about the suitability of this software for any purpose.
// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES,
// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES,
// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY
// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
// Intel does not assume any responsibility for any errors which may appear in this software
// nor any responsibility to update it.
#version 430
layout(location = 0) in vec4 v_Color;
layout(location = 0) out vec4 o_Color;
void main() {
o_Color = v_Color;
}

View File

@@ -0,0 +1,21 @@
// Copyright 2016 Intel Corporation All Rights Reserved
//
// Intel makes no representations about the suitability of this software for any purpose.
// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES,
// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES,
// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY
// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
// Intel does not assume any responsibility for any errors which may appear in this software
// nor any responsibility to update it.
#version 430
layout(location = 0) in vec4 i_Position;
layout(location = 1) in vec4 i_Color;
layout(location = 0) out vec4 v_Color;
void main() {
gl_Position = i_Position;
v_Color = i_Color;
}

Binary file not shown.

View File

@@ -0,0 +1,59 @@
shader.vert
Warning, version 430 is not yet complete; most version-specific features are present, but some are missing.
Linked vertex stage:
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 24
Capability Shader
Capability ClipDistance
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Vertex 4 "main" 13 17 21 22
Source GLSL 430
Name 4 "main"
Name 11 "gl_PerVertex"
MemberName 11(gl_PerVertex) 0 "gl_Position"
MemberName 11(gl_PerVertex) 1 "gl_PointSize"
MemberName 11(gl_PerVertex) 2 "gl_ClipDistance"
Name 13 ""
Name 17 "i_Position"
Name 21 "v_Color"
Name 22 "i_Color"
MemberDecorate 11(gl_PerVertex) 0 BuiltIn Position
MemberDecorate 11(gl_PerVertex) 1 BuiltIn PointSize
MemberDecorate 11(gl_PerVertex) 2 BuiltIn ClipDistance
Decorate 11(gl_PerVertex) Block
Decorate 17(i_Position) Location 0
Decorate 21(v_Color) Location 0
Decorate 22(i_Color) Location 1
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
7: TypeVector 6(float) 4
8: TypeInt 32 0
9: 8(int) Constant 1
10: TypeArray 6(float) 9
11(gl_PerVertex): TypeStruct 7(fvec4) 6(float) 10
12: TypePointer Output 11(gl_PerVertex)
13: 12(ptr) Variable Output
14: TypeInt 32 1
15: 14(int) Constant 0
16: TypePointer Input 7(fvec4)
17(i_Position): 16(ptr) Variable Input
19: TypePointer Output 7(fvec4)
21(v_Color): 19(ptr) Variable Output
22(i_Color): 16(ptr) Variable Input
4(main): 2 Function None 3
5: Label
18: 7(fvec4) Load 17(i_Position)
20: 19(ptr) AccessChain 13 15
Store 20 18
23: 7(fvec4) Load 22(i_Color)
Store 21(v_Color) 23
Return
FunctionEnd

View File

@@ -0,0 +1,834 @@
// Copyright 2016 Intel Corporation All Rights Reserved
//
// Intel makes no representations about the suitability of this software for any purpose.
// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES,
// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES,
// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY
// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
// Intel does not assume any responsibility for any errors which may appear in this software
// nor any responsibility to update it.
#include "Tutorial05.h"
#include "VulkanFunctions.h"
namespace ApiWithoutSecrets {
Tutorial05::Tutorial05() :
Vulkan() {
}
bool Tutorial05::CreateRenderPass() {
VkAttachmentDescription attachment_descriptions[] = {
{
0, // VkAttachmentDescriptionFlags flags
GetSwapChain().Format, // VkFormat format
VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp
VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp
VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp
VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout
}
};
VkAttachmentReference color_attachment_references[] = {
{
0, // uint32_t attachment
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout
}
};
VkSubpassDescription subpass_descriptions[] = {
{
0, // VkSubpassDescriptionFlags flags
VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint
0, // uint32_t inputAttachmentCount
nullptr, // const VkAttachmentReference *pInputAttachments
1, // uint32_t colorAttachmentCount
color_attachment_references, // const VkAttachmentReference *pColorAttachments
nullptr, // const VkAttachmentReference *pResolveAttachments
nullptr, // const VkAttachmentReference *pDepthStencilAttachment
0, // uint32_t preserveAttachmentCount
nullptr // const uint32_t* pPreserveAttachments
}
};
VkRenderPassCreateInfo render_pass_create_info = {
VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType
nullptr, // const void *pNext
0, // VkRenderPassCreateFlags flags
1, // uint32_t attachmentCount
attachment_descriptions, // const VkAttachmentDescription *pAttachments
1, // uint32_t subpassCount
subpass_descriptions, // const VkSubpassDescription *pSubpasses
0, // uint32_t dependencyCount
nullptr // const VkSubpassDependency *pDependencies
};
if( vkCreateRenderPass( GetDevice(), &render_pass_create_info, nullptr, &Vulkan.RenderPass ) != VK_SUCCESS ) {
std::cout << "Could not create render pass!" << std::endl;
return false;
}
return true;
}
Tools::AutoDeleter<VkShaderModule, PFN_vkDestroyShaderModule> Tutorial05::CreateShaderModule( const char* filename ) {
const std::vector<char> code = Tools::GetBinaryFileContents( filename );
if( code.size() == 0 ) {
return Tools::AutoDeleter<VkShaderModule, PFN_vkDestroyShaderModule>();
}
VkShaderModuleCreateInfo shader_module_create_info = {
VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, // VkStructureType sType
nullptr, // const void *pNext
0, // VkShaderModuleCreateFlags flags
code.size(), // size_t codeSize
reinterpret_cast<const uint32_t*>(&code[0]) // const uint32_t *pCode
};
VkShaderModule shader_module;
if( vkCreateShaderModule( GetDevice(), &shader_module_create_info, nullptr, &shader_module ) != VK_SUCCESS ) {
std::cout << "Could not create shader module from a \"" << filename << "\" file!" << std::endl;
return Tools::AutoDeleter<VkShaderModule, PFN_vkDestroyShaderModule>();
}
return Tools::AutoDeleter<VkShaderModule, PFN_vkDestroyShaderModule>( shader_module, vkDestroyShaderModule, GetDevice() );
}
Tools::AutoDeleter<VkPipelineLayout, PFN_vkDestroyPipelineLayout> Tutorial05::CreatePipelineLayout() {
VkPipelineLayoutCreateInfo layout_create_info = {
VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType
nullptr, // const void *pNext
0, // VkPipelineLayoutCreateFlags flags
0, // uint32_t setLayoutCount
nullptr, // const VkDescriptorSetLayout *pSetLayouts
0, // uint32_t pushConstantRangeCount
nullptr // const VkPushConstantRange *pPushConstantRanges
};
VkPipelineLayout pipeline_layout;
if( vkCreatePipelineLayout( GetDevice(), &layout_create_info, nullptr, &pipeline_layout ) != VK_SUCCESS ) {
std::cout << "Could not create pipeline layout!" << std::endl;
return Tools::AutoDeleter<VkPipelineLayout, PFN_vkDestroyPipelineLayout>();
}
return Tools::AutoDeleter<VkPipelineLayout, PFN_vkDestroyPipelineLayout>( pipeline_layout, vkDestroyPipelineLayout, GetDevice() );
}
bool Tutorial05::CreatePipeline() {
Tools::AutoDeleter<VkShaderModule, PFN_vkDestroyShaderModule> vertex_shader_module = CreateShaderModule( "Data05/vert.spv" );
Tools::AutoDeleter<VkShaderModule, PFN_vkDestroyShaderModule> fragment_shader_module = CreateShaderModule( "Data05/frag.spv" );
if( !vertex_shader_module || !fragment_shader_module ) {
return false;
}
std::vector<VkPipelineShaderStageCreateInfo> shader_stage_create_infos = {
// Vertex shader
{
VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType
nullptr, // const void *pNext
0, // VkPipelineShaderStageCreateFlags flags
VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage
vertex_shader_module.Get(), // VkShaderModule module
"main", // const char *pName
nullptr // const VkSpecializationInfo *pSpecializationInfo
},
// Fragment shader
{
VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType
nullptr, // const void *pNext
0, // VkPipelineShaderStageCreateFlags flags
VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage
fragment_shader_module.Get(), // VkShaderModule module
"main", // const char *pName
nullptr // const VkSpecializationInfo *pSpecializationInfo
}
};
VkVertexInputBindingDescription vertex_binding_description = {
0, // uint32_t binding
sizeof(VertexData), // uint32_t stride
VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputRate inputRate
};
VkVertexInputAttributeDescription vertex_attribute_descriptions[] = {
{
0, // uint32_t location
vertex_binding_description.binding, // uint32_t binding
VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format
0 // uint32_t offset
},
{
1, // uint32_t location
vertex_binding_description.binding, // uint32_t binding
VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format
4 * sizeof(float) // uint32_t offset
}
};
VkPipelineVertexInputStateCreateInfo vertex_input_state_create_info = {
VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType
nullptr, // const void *pNext
0, // VkPipelineVertexInputStateCreateFlags flags;
1, // uint32_t vertexBindingDescriptionCount
&vertex_binding_description, // const VkVertexInputBindingDescription *pVertexBindingDescriptions
2, // uint32_t vertexAttributeDescriptionCount
vertex_attribute_descriptions // const VkVertexInputAttributeDescription *pVertexAttributeDescriptions
};
VkPipelineInputAssemblyStateCreateInfo input_assembly_state_create_info = {
VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType
nullptr, // const void *pNext
0, // VkPipelineInputAssemblyStateCreateFlags flags
VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, // VkPrimitiveTopology topology
VK_FALSE // VkBool32 primitiveRestartEnable
};
VkPipelineViewportStateCreateInfo viewport_state_create_info = {
VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType
nullptr, // const void *pNext
0, // VkPipelineViewportStateCreateFlags flags
1, // uint32_t viewportCount
nullptr, // const VkViewport *pViewports
1, // uint32_t scissorCount
nullptr // const VkRect2D *pScissors
};
VkPipelineRasterizationStateCreateInfo rasterization_state_create_info = {
VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType
nullptr, // const void *pNext
0, // VkPipelineRasterizationStateCreateFlags flags
VK_FALSE, // VkBool32 depthClampEnable
VK_FALSE, // VkBool32 rasterizerDiscardEnable
VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode
VK_CULL_MODE_BACK_BIT, // VkCullModeFlags cullMode
VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace
VK_FALSE, // VkBool32 depthBiasEnable
0.0f, // float depthBiasConstantFactor
0.0f, // float depthBiasClamp
0.0f, // float depthBiasSlopeFactor
1.0f // float lineWidth
};
VkPipelineMultisampleStateCreateInfo multisample_state_create_info = {
VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType
nullptr, // const void *pNext
0, // VkPipelineMultisampleStateCreateFlags flags
VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples
VK_FALSE, // VkBool32 sampleShadingEnable
1.0f, // float minSampleShading
nullptr, // const VkSampleMask *pSampleMask
VK_FALSE, // VkBool32 alphaToCoverageEnable
VK_FALSE // VkBool32 alphaToOneEnable
};
VkPipelineColorBlendAttachmentState color_blend_attachment_state = {
VK_FALSE, // VkBool32 blendEnable
VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor
VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor
VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp
VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor
VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor
VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp
VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | // VkColorComponentFlags colorWriteMask
VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
};
VkPipelineColorBlendStateCreateInfo color_blend_state_create_info = {
VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType
nullptr, // const void *pNext
0, // VkPipelineColorBlendStateCreateFlags flags
VK_FALSE, // VkBool32 logicOpEnable
VK_LOGIC_OP_COPY, // VkLogicOp logicOp
1, // uint32_t attachmentCount
&color_blend_attachment_state, // const VkPipelineColorBlendAttachmentState *pAttachments
{ 0.0f, 0.0f, 0.0f, 0.0f } // float blendConstants[4]
};
VkDynamicState dynamic_states[] = {
VK_DYNAMIC_STATE_VIEWPORT,
VK_DYNAMIC_STATE_SCISSOR,
};
VkPipelineDynamicStateCreateInfo dynamic_state_create_info = {
VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType sType
nullptr, // const void *pNext
0, // VkPipelineDynamicStateCreateFlags flags
2, // uint32_t dynamicStateCount
dynamic_states // const VkDynamicState *pDynamicStates
};
Tools::AutoDeleter<VkPipelineLayout, PFN_vkDestroyPipelineLayout> pipeline_layout = CreatePipelineLayout();
if( !pipeline_layout ) {
return false;
}
VkGraphicsPipelineCreateInfo pipeline_create_info = {
VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType
nullptr, // const void *pNext
0, // VkPipelineCreateFlags flags
static_cast<uint32_t>(shader_stage_create_infos.size()), // uint32_t stageCount
&shader_stage_create_infos[0], // const VkPipelineShaderStageCreateInfo *pStages
&vertex_input_state_create_info, // const VkPipelineVertexInputStateCreateInfo *pVertexInputState;
&input_assembly_state_create_info, // const VkPipelineInputAssemblyStateCreateInfo *pInputAssemblyState
nullptr, // const VkPipelineTessellationStateCreateInfo *pTessellationState
&viewport_state_create_info, // const VkPipelineViewportStateCreateInfo *pViewportState
&rasterization_state_create_info, // const VkPipelineRasterizationStateCreateInfo *pRasterizationState
&multisample_state_create_info, // const VkPipelineMultisampleStateCreateInfo *pMultisampleState
nullptr, // const VkPipelineDepthStencilStateCreateInfo *pDepthStencilState
&color_blend_state_create_info, // const VkPipelineColorBlendStateCreateInfo *pColorBlendState
&dynamic_state_create_info, // const VkPipelineDynamicStateCreateInfo *pDynamicState
pipeline_layout.Get(), // VkPipelineLayout layout
Vulkan.RenderPass, // VkRenderPass renderPass
0, // uint32_t subpass
VK_NULL_HANDLE, // VkPipeline basePipelineHandle
-1 // int32_t basePipelineIndex
};
if( vkCreateGraphicsPipelines( GetDevice(), VK_NULL_HANDLE, 1, &pipeline_create_info, nullptr, &Vulkan.GraphicsPipeline ) != VK_SUCCESS ) {
std::cout << "Could not create graphics pipeline!" << std::endl;
return false;
}
return true;
}
bool Tutorial05::CreateRenderingResources() {
if( !CreateCommandBuffers() ) {
return false;
}
if( !CreateSemaphores() ) {
return false;
}
if( !CreateFences() ) {
return false;
}
return true;
}
bool Tutorial05::CreateCommandBuffers() {
if( !CreateCommandPool( GetGraphicsQueue().FamilyIndex, &Vulkan.CommandPool ) ) {
std::cout << "Could not create command pool!" << std::endl;
return false;
}
for( size_t i = 0; i < Vulkan.RenderingResources.size(); ++i ) {
if( !AllocateCommandBuffers( Vulkan.CommandPool, 1, &Vulkan.RenderingResources[i].CommandBuffer ) ) {
std::cout << "Could not allocate command buffer!" << std::endl;
return false;
}
}
return true;
}
bool Tutorial05::CreateCommandPool( uint32_t queue_family_index, VkCommandPool *pool ) {
VkCommandPoolCreateInfo cmd_pool_create_info = {
VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType
nullptr, // const void *pNext
VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT | // VkCommandPoolCreateFlags flags
VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,
queue_family_index // uint32_t queueFamilyIndex
};
if( vkCreateCommandPool( GetDevice(), &cmd_pool_create_info, nullptr, pool ) != VK_SUCCESS ) {
return false;
}
return true;
}
bool Tutorial05::AllocateCommandBuffers( VkCommandPool pool, uint32_t count, VkCommandBuffer *command_buffers ) {
VkCommandBufferAllocateInfo command_buffer_allocate_info = {
VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType
nullptr, // const void *pNext
pool, // VkCommandPool commandPool
VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level
count // uint32_t bufferCount
};
if( vkAllocateCommandBuffers( GetDevice(), &command_buffer_allocate_info, command_buffers ) != VK_SUCCESS ) {
return false;
}
return true;
}
bool Tutorial05::CreateSemaphores() {
VkSemaphoreCreateInfo semaphore_create_info = {
VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, // VkStructureType sType
nullptr, // const void* pNext
0 // VkSemaphoreCreateFlags flags
};
for( size_t i = 0; i < Vulkan.RenderingResources.size(); ++i ) {
if( (vkCreateSemaphore( GetDevice(), &semaphore_create_info, nullptr, &Vulkan.RenderingResources[i].ImageAvailableSemaphore ) != VK_SUCCESS) ||
(vkCreateSemaphore( GetDevice(), &semaphore_create_info, nullptr, &Vulkan.RenderingResources[i].FinishedRenderingSemaphore ) != VK_SUCCESS) ) {
std::cout << "Could not create semaphores!" << std::endl;
return false;
}
}
return true;
}
bool Tutorial05::CreateFences() {
VkFenceCreateInfo fence_create_info = {
VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType
nullptr, // const void *pNext
VK_FENCE_CREATE_SIGNALED_BIT // VkFenceCreateFlags flags
};
for( size_t i = 0; i < Vulkan.RenderingResources.size(); ++i ) {
if( vkCreateFence( GetDevice(), &fence_create_info, nullptr, &Vulkan.RenderingResources[i].Fence ) != VK_SUCCESS ) {
std::cout << "Could not create a fence!" << std::endl;
return false;
}
}
return true;
}
bool Tutorial05::CreateVertexBuffer() {
const std::vector<float>& vertex_data = GetVertexData();
Vulkan.VertexBuffer.Size = static_cast<uint32_t>(vertex_data.size() * sizeof(vertex_data[0]));
if( !CreateBuffer( VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, Vulkan.VertexBuffer ) ) {
std::cout << "Could not create vertex buffer!" << std::endl;
}
return true;
}
bool Tutorial05::CreateStagingBuffer() {
Vulkan.StagingBuffer.Size = 4000;
if( !CreateBuffer( VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, Vulkan.StagingBuffer ) ) {
std::cout << "Could not staging buffer!" << std::endl;
}
return true;
}
bool Tutorial05::CreateBuffer( VkBufferUsageFlags usage, VkMemoryPropertyFlagBits memoryProperty, BufferParameters &buffer ) {
VkBufferCreateInfo buffer_create_info = {
VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType
nullptr, // const void *pNext
0, // VkBufferCreateFlags flags
buffer.Size, // VkDeviceSize size
usage, // VkBufferUsageFlags usage
VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
0, // uint32_t queueFamilyIndexCount
nullptr // const uint32_t *pQueueFamilyIndices
};
if( vkCreateBuffer( GetDevice(), &buffer_create_info, nullptr, &buffer.Handle ) != VK_SUCCESS ) {
std::cout << "Could not create buffer!" << std::endl;
return false;
}
if( !AllocateBufferMemory( buffer.Handle, memoryProperty, &buffer.Memory ) ) {
std::cout << "Could not allocate memory for a buffer!" << std::endl;
return false;
}
if( vkBindBufferMemory( GetDevice(), buffer.Handle, buffer.Memory, 0 ) != VK_SUCCESS ) {
std::cout << "Could not bind memory to a buffer!" << std::endl;
return false;
}
return true;
}
bool Tutorial05::AllocateBufferMemory( VkBuffer buffer, VkMemoryPropertyFlagBits property, VkDeviceMemory *memory ) {
VkMemoryRequirements buffer_memory_requirements;
vkGetBufferMemoryRequirements( GetDevice(), Vulkan.VertexBuffer.Handle, &buffer_memory_requirements );
VkPhysicalDeviceMemoryProperties memory_properties;
vkGetPhysicalDeviceMemoryProperties( GetPhysicalDevice(), &memory_properties );
for( uint32_t i = 0; i < memory_properties.memoryTypeCount; ++i ) {
if( (buffer_memory_requirements.memoryTypeBits & (1 << i)) &&
(memory_properties.memoryTypes[i].propertyFlags & property) ) {
VkMemoryAllocateInfo memory_allocate_info = {
VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // VkStructureType sType
nullptr, // const void *pNext
buffer_memory_requirements.size, // VkDeviceSize allocationSize
i // uint32_t memoryTypeIndex
};
if( vkAllocateMemory( GetDevice(), &memory_allocate_info, nullptr, memory ) == VK_SUCCESS ) {
return true;
}
}
}
return false;
}
const std::vector<float>& Tutorial05::GetVertexData() const {
static const std::vector<float> vertex_data = {
-0.7f, -0.7f, 0.0f, 1.0f,
1.0f, 0.0f, 0.0f, 0.0f,
//
-0.7f, 0.7f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 0.0f,
//
0.7f, -0.7f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 0.0f,
//
0.7f, 0.7f, 0.0f, 1.0f,
0.3f, 0.3f, 0.3f, 0.0f
};
return vertex_data;
}
bool Tutorial05::CopyVertexData() {
// Prepare data in staging buffer
const std::vector<float>& vertex_data = GetVertexData();
void *staging_buffer_memory_pointer;
if( vkMapMemory( GetDevice(), Vulkan.StagingBuffer.Memory, 0, Vulkan.VertexBuffer.Size, 0, &staging_buffer_memory_pointer) != VK_SUCCESS ) {
std::cout << "Could not map memory and upload data to a staging buffer!" << std::endl;
return false;
}
memcpy( staging_buffer_memory_pointer, &vertex_data[0], Vulkan.VertexBuffer.Size );
VkMappedMemoryRange flush_range = {
VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType
nullptr, // const void *pNext
Vulkan.StagingBuffer.Memory, // VkDeviceMemory memory
0, // VkDeviceSize offset
Vulkan.VertexBuffer.Size // VkDeviceSize size
};
vkFlushMappedMemoryRanges( GetDevice(), 1, &flush_range );
vkUnmapMemory( GetDevice(), Vulkan.StagingBuffer.Memory );
// Prepare command buffer to copy data from staging buffer to a vertex buffer
VkCommandBufferBeginInfo command_buffer_begin_info = {
VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType
nullptr, // const void *pNext
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags
nullptr // const VkCommandBufferInheritanceInfo *pInheritanceInfo
};
VkCommandBuffer command_buffer = Vulkan.RenderingResources[0].CommandBuffer;
vkBeginCommandBuffer( command_buffer, &command_buffer_begin_info);
VkBufferCopy buffer_copy_info = {
0, // VkDeviceSize srcOffset
0, // VkDeviceSize dstOffset
Vulkan.VertexBuffer.Size // VkDeviceSize size
};
vkCmdCopyBuffer(command_buffer, Vulkan.StagingBuffer.Handle, Vulkan.VertexBuffer.Handle, 1, &buffer_copy_info);
VkBufferMemoryBarrier buffer_memory_barrier = {
VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
nullptr, // const void *pNext
VK_ACCESS_MEMORY_WRITE_BIT, // VkAccessFlags srcAccessMask
VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, // VkAccessFlags dstAccessMask
VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex
VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex
Vulkan.VertexBuffer.Handle, // VkBuffer buffer
0, // VkDeviceSize offset
VK_WHOLE_SIZE // VkDeviceSize size
};
vkCmdPipelineBarrier( command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 0, 0, nullptr, 1, &buffer_memory_barrier, 0, nullptr );
vkEndCommandBuffer( command_buffer );
// Submit command buffer and copy data from staging buffer to a vertex buffer
VkSubmitInfo submit_info = {
VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType
nullptr, // const void *pNext
0, // uint32_t waitSemaphoreCount
nullptr, // const VkSemaphore *pWaitSemaphores
nullptr, // const VkPipelineStageFlags *pWaitDstStageMask;
1, // uint32_t commandBufferCount
&command_buffer, // const VkCommandBuffer *pCommandBuffers
0, // uint32_t signalSemaphoreCount
nullptr // const VkSemaphore *pSignalSemaphores
};
if( vkQueueSubmit( GetGraphicsQueue().Handle, 1, &submit_info, VK_NULL_HANDLE ) != VK_SUCCESS ) {
return false;
}
vkDeviceWaitIdle( GetDevice() );
return true;
}
bool Tutorial05::PrepareFrame( VkCommandBuffer command_buffer, const ImageParameters &image_parameters, VkFramebuffer &framebuffer ) {
if( !CreateFramebuffer( framebuffer, image_parameters.ImageView ) ) {
return false;
}
VkCommandBufferBeginInfo command_buffer_begin_info = {
VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType
nullptr, // const void *pNext
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags
nullptr // const VkCommandBufferInheritanceInfo *pInheritanceInfo
};
vkBeginCommandBuffer( command_buffer, &command_buffer_begin_info );
VkImageSubresourceRange image_subresource_range = {
VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask
0, // uint32_t baseMipLevel
1, // uint32_t levelCount
0, // uint32_t baseArrayLayer
1 // uint32_t layerCount
};
uint32_t present_queue_family_index = (GetPresentQueue().Handle != GetGraphicsQueue().Handle) ? GetPresentQueue().FamilyIndex : VK_QUEUE_FAMILY_IGNORED;
uint32_t graphics_queue_family_index = (GetPresentQueue().Handle != GetGraphicsQueue().Handle) ? GetGraphicsQueue().FamilyIndex : VK_QUEUE_FAMILY_IGNORED;
VkImageMemoryBarrier barrier_from_present_to_draw = {
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
nullptr, // const void *pNext
VK_ACCESS_MEMORY_READ_BIT, // VkAccessFlags srcAccessMask
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, // VkImageLayout oldLayout
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout
present_queue_family_index, // uint32_t srcQueueFamilyIndex
graphics_queue_family_index, // uint32_t dstQueueFamilyIndex
image_parameters.Handle, // VkImage image
image_subresource_range // VkImageSubresourceRange subresourceRange
};
vkCmdPipelineBarrier( command_buffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, nullptr, 0, nullptr, 1, &barrier_from_present_to_draw );
VkClearValue clear_value = {
{ 1.0f, 0.8f, 0.4f, 0.0f }, // VkClearColorValue color
};
VkRenderPassBeginInfo render_pass_begin_info = {
VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType
nullptr, // const void *pNext
Vulkan.RenderPass, // VkRenderPass renderPass
framebuffer, // VkFramebuffer framebuffer
{ // VkRect2D renderArea
{ // VkOffset2D offset
0, // int32_t x
0 // int32_t y
},
GetSwapChain().Extent, // VkExtent2D extent;
},
1, // uint32_t clearValueCount
&clear_value // const VkClearValue *pClearValues
};
vkCmdBeginRenderPass( command_buffer, &render_pass_begin_info, VK_SUBPASS_CONTENTS_INLINE );
vkCmdBindPipeline( command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, Vulkan.GraphicsPipeline );
VkViewport viewport = {
0.0f, // float x
0.0f, // float y
static_cast<float>(GetSwapChain().Extent.width), // float width
static_cast<float>(GetSwapChain().Extent.height), // float height
0.0f, // float minDepth
1.0f // float maxDepth
};
VkRect2D scissor = {
{ // VkOffset2D offset
0, // int32_t x
0 // int32_t y
},
{ // VkExtent2D extent
GetSwapChain().Extent.width, // uint32_t width
GetSwapChain().Extent.height // uint32_t height
}
};
vkCmdSetViewport( command_buffer, 0, 1, &viewport );
vkCmdSetScissor( command_buffer, 0, 1, &scissor );
VkDeviceSize offset = 0;
vkCmdBindVertexBuffers( command_buffer, 0, 1, &Vulkan.VertexBuffer.Handle, &offset );
vkCmdDraw( command_buffer, 4, 1, 0, 0 );
vkCmdEndRenderPass( command_buffer );
VkImageMemoryBarrier barrier_from_draw_to_present = {
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
nullptr, // const void *pNext
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask
VK_ACCESS_MEMORY_READ_BIT, // VkAccessFlags dstAccessMask
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, // VkImageLayout newLayout
graphics_queue_family_index, // uint32_t srcQueueFamilyIndex
present_queue_family_index, // uint32_t dstQueueFamilyIndex
image_parameters.Handle, // VkImage image
image_subresource_range // VkImageSubresourceRange subresourceRange
};
vkCmdPipelineBarrier( command_buffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, nullptr, 0, nullptr, 1, &barrier_from_draw_to_present );
if( vkEndCommandBuffer( command_buffer ) != VK_SUCCESS ) {
std::cout << "Could not record command buffer!" << std::endl;
return false;
}
return true;
}
bool Tutorial05::CreateFramebuffer( VkFramebuffer &framebuffer, VkImageView image_view ) {
if( framebuffer != VK_NULL_HANDLE ) {
vkDestroyFramebuffer( GetDevice(), framebuffer, nullptr );
}
VkFramebufferCreateInfo framebuffer_create_info = {
VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType
nullptr, // const void *pNext
0, // VkFramebufferCreateFlags flags
Vulkan.RenderPass, // VkRenderPass renderPass
1, // uint32_t attachmentCount
&image_view, // const VkImageView *pAttachments
GetSwapChain().Extent.width, // uint32_t width
GetSwapChain().Extent.height, // uint32_t height
1 // uint32_t layers
};
if( vkCreateFramebuffer( GetDevice(), &framebuffer_create_info, nullptr, &framebuffer ) != VK_SUCCESS ) {
std::cout << "Could not create a framebuffer!" << std::endl;
return false;
}
return true;
}
bool Tutorial05::ChildOnWindowSizeChanged() {
return true;
}
bool Tutorial05::Draw() {
static size_t resource_index = 0;
RenderingResourcesData &current_rendering_resource = Vulkan.RenderingResources[resource_index];
VkSwapchainKHR swap_chain = GetSwapChain().Handle;
uint32_t image_index;
resource_index = (resource_index + 1) % VulkanTutorial05Parameters::ResourcesCount;
if( vkWaitForFences( GetDevice(), 1, &current_rendering_resource.Fence, VK_FALSE, 1000000000 ) != VK_SUCCESS ) {
std::cout << "Waiting for fence takes too long!" << std::endl;
return false;
}
vkResetFences( GetDevice(), 1, &current_rendering_resource.Fence );
VkResult result = vkAcquireNextImageKHR( GetDevice(), swap_chain, UINT64_MAX, current_rendering_resource.ImageAvailableSemaphore, VK_NULL_HANDLE, &image_index );
switch( result ) {
case VK_SUCCESS:
case VK_SUBOPTIMAL_KHR:
break;
case VK_ERROR_OUT_OF_DATE_KHR:
return OnWindowSizeChanged();
default:
std::cout << "Problem occurred during swap chain image acquisition!" << std::endl;
return false;
}
if( !PrepareFrame( current_rendering_resource.CommandBuffer, GetSwapChain( ).Images[image_index], current_rendering_resource.Framebuffer ) ) {
return false;
}
VkPipelineStageFlags wait_dst_stage_mask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
VkSubmitInfo submit_info = {
VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType
nullptr, // const void *pNext
1, // uint32_t waitSemaphoreCount
&current_rendering_resource.ImageAvailableSemaphore, // const VkSemaphore *pWaitSemaphores
&wait_dst_stage_mask, // const VkPipelineStageFlags *pWaitDstStageMask;
1, // uint32_t commandBufferCount
&current_rendering_resource.CommandBuffer, // const VkCommandBuffer *pCommandBuffers
1, // uint32_t signalSemaphoreCount
&current_rendering_resource.FinishedRenderingSemaphore // const VkSemaphore *pSignalSemaphores
};
if( vkQueueSubmit( GetGraphicsQueue().Handle, 1, &submit_info, current_rendering_resource.Fence ) != VK_SUCCESS ) {
return false;
}
VkPresentInfoKHR present_info = {
VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, // VkStructureType sType
nullptr, // const void *pNext
1, // uint32_t waitSemaphoreCount
&current_rendering_resource.FinishedRenderingSemaphore, // const VkSemaphore *pWaitSemaphores
1, // uint32_t swapchainCount
&swap_chain, // const VkSwapchainKHR *pSwapchains
&image_index, // const uint32_t *pImageIndices
nullptr // VkResult *pResults
};
result = vkQueuePresentKHR( GetPresentQueue().Handle, &present_info );
switch( result ) {
case VK_SUCCESS:
break;
case VK_ERROR_OUT_OF_DATE_KHR:
case VK_SUBOPTIMAL_KHR:
return OnWindowSizeChanged();
default:
std::cout << "Problem occurred during image presentation!" << std::endl;
return false;
}
return true;
}
void Tutorial05::ChildClear() {
}
Tutorial05::~Tutorial05() {
if( GetDevice() != VK_NULL_HANDLE ) {
vkDeviceWaitIdle( GetDevice() );
for( size_t i = 0; i < Vulkan.RenderingResources.size(); ++i ) {
if( Vulkan.RenderingResources[i].Framebuffer != VK_NULL_HANDLE ) {
vkDestroyFramebuffer( GetDevice(), Vulkan.RenderingResources[i].Framebuffer, nullptr );
}
if( Vulkan.RenderingResources[i].CommandBuffer != VK_NULL_HANDLE ) {
vkFreeCommandBuffers( GetDevice(), Vulkan.CommandPool, 1, &Vulkan.RenderingResources[i].CommandBuffer );
}
if( Vulkan.RenderingResources[i].ImageAvailableSemaphore != VK_NULL_HANDLE ) {
vkDestroySemaphore( GetDevice(), Vulkan.RenderingResources[i].ImageAvailableSemaphore, nullptr );
}
if( Vulkan.RenderingResources[i].FinishedRenderingSemaphore != VK_NULL_HANDLE ) {
vkDestroySemaphore( GetDevice(), Vulkan.RenderingResources[i].FinishedRenderingSemaphore, nullptr );
}
if( Vulkan.RenderingResources[i].Fence != VK_NULL_HANDLE ) {
vkDestroyFence( GetDevice(), Vulkan.RenderingResources[i].Fence, nullptr );
}
}
if( Vulkan.CommandPool != VK_NULL_HANDLE ) {
vkDestroyCommandPool( GetDevice(), Vulkan.CommandPool, nullptr );
Vulkan.CommandPool = VK_NULL_HANDLE;
}
DestroyBuffer( Vulkan.VertexBuffer );
DestroyBuffer( Vulkan.StagingBuffer );
if( Vulkan.GraphicsPipeline != VK_NULL_HANDLE ) {
vkDestroyPipeline( GetDevice(), Vulkan.GraphicsPipeline, nullptr );
Vulkan.GraphicsPipeline = VK_NULL_HANDLE;
}
if( Vulkan.RenderPass != VK_NULL_HANDLE ) {
vkDestroyRenderPass( GetDevice(), Vulkan.RenderPass, nullptr );
Vulkan.RenderPass = VK_NULL_HANDLE;
}
}
}
void Tutorial05::DestroyBuffer( BufferParameters& buffer ) {
if( buffer.Handle != VK_NULL_HANDLE ) {
vkDestroyBuffer( GetDevice(), buffer.Handle, nullptr );
buffer.Handle = VK_NULL_HANDLE;
}
if( buffer.Memory != VK_NULL_HANDLE ) {
vkFreeMemory( GetDevice(), buffer.Memory, nullptr );
buffer.Memory = VK_NULL_HANDLE;
}
}
} // namespace ApiWithoutSecrets

View File

@@ -0,0 +1,133 @@
// Copyright 2016 Intel Corporation All Rights Reserved
//
// Intel makes no representations about the suitability of this software for any purpose.
// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES,
// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES,
// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY
// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
// Intel does not assume any responsibility for any errors which may appear in this software
// nor any responsibility to update it.
#if !defined(TUTORIAL_05_HEADER)
#define TUTORIAL_05_HEADER
#include "VulkanCommon.h"
#include "Tools.h"
namespace ApiWithoutSecrets {
// ************************************************************ //
// BufferParameters //
// //
// Vulkan Buffer's parameters container class //
// ************************************************************ //
struct BufferParameters {
VkBuffer Handle;
VkDeviceMemory Memory;
uint32_t Size;
BufferParameters() :
Handle( VK_NULL_HANDLE ),
Memory( VK_NULL_HANDLE ),
Size( 0 ) {
}
};
// ************************************************************ //
// VertexData //
// //
// Struct describing data type and format of vertex attributes //
// ************************************************************ //
struct VertexData {
float x, y, z, w;
float r, g, b, a;
};
// ************************************************************ //
// RenderingResourcesData //
// //
// Struct containing data used during rendering process //
// ************************************************************ //
struct RenderingResourcesData {
VkFramebuffer Framebuffer;
VkCommandBuffer CommandBuffer;
VkSemaphore ImageAvailableSemaphore;
VkSemaphore FinishedRenderingSemaphore;
VkFence Fence;
RenderingResourcesData() :
Framebuffer( VK_NULL_HANDLE ),
CommandBuffer( VK_NULL_HANDLE ),
ImageAvailableSemaphore( VK_NULL_HANDLE ),
FinishedRenderingSemaphore( VK_NULL_HANDLE ),
Fence( VK_NULL_HANDLE ) {
}
};
// ************************************************************ //
// VulkanTutorial04Parameters //
// //
// Vulkan specific parameters //
// ************************************************************ //
struct VulkanTutorial05Parameters {
VkRenderPass RenderPass;
VkPipeline GraphicsPipeline;
BufferParameters VertexBuffer;
BufferParameters StagingBuffer;
VkCommandPool CommandPool;
std::vector<RenderingResourcesData> RenderingResources;
static const size_t ResourcesCount = 3;
VulkanTutorial05Parameters() :
RenderPass( VK_NULL_HANDLE ),
GraphicsPipeline( VK_NULL_HANDLE ),
VertexBuffer(),
CommandPool( VK_NULL_HANDLE ),
RenderingResources( ResourcesCount ) {
}
};
// ************************************************************ //
// Tutorial04 //
// //
// Class for presenting Vulkan usage topics //
// ************************************************************ //
class Tutorial05 : public VulkanCommon {
public:
Tutorial05();
~Tutorial05();
bool CreateRenderPass();
bool CreatePipeline();
bool CreateRenderingResources();
bool CreateVertexBuffer();
bool CreateStagingBuffer();
bool CopyVertexData();
bool Draw() override;
private:
VulkanTutorial05Parameters Vulkan;
Tools::AutoDeleter<VkShaderModule, PFN_vkDestroyShaderModule> CreateShaderModule( const char* filename );
Tools::AutoDeleter<VkPipelineLayout, PFN_vkDestroyPipelineLayout> CreatePipelineLayout();
bool CreateCommandPool( uint32_t queue_family_index, VkCommandPool *pool );
bool AllocateCommandBuffers( VkCommandPool pool, uint32_t count, VkCommandBuffer *command_buffers );
bool CreateCommandBuffers();
bool CreateSemaphores();
bool CreateFences();
bool CreateBuffer( VkBufferUsageFlags usage, VkMemoryPropertyFlagBits memoryProperty, BufferParameters &buffer );
bool AllocateBufferMemory( VkBuffer buffer, VkMemoryPropertyFlagBits property, VkDeviceMemory *memory );
const std::vector<float>& GetVertexData() const;
bool PrepareFrame( VkCommandBuffer command_buffer, const ImageParameters &image_parameters, VkFramebuffer &framebuffer );
bool CreateFramebuffer( VkFramebuffer &framebuffer, VkImageView image_view );
void DestroyBuffer( BufferParameters& buffer );
void ChildClear() override;
bool ChildOnWindowSizeChanged() override;
};
} // namespace ApiWithoutSecrets
#endif // TUTORIAL_03_HEADER

View File

@@ -0,0 +1,53 @@
// Copyright 2016 Intel Corporation All Rights Reserved
//
// Intel makes no representations about the suitability of this software for any purpose.
// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES,
// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES,
// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY
// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
// Intel does not assume any responsibility for any errors which may appear in this software
// nor any responsibility to update it.
#include "Tutorial05.h"
int main( int argc, char **argv ) {
ApiWithoutSecrets::OS::Window window;
ApiWithoutSecrets::Tutorial05 tutorial05;
// Window creation
if( !window.Create( "05 - Staging Resources" ) ) {
return -1;
}
// Vulkan preparations and initialization
if( !tutorial05.PrepareVulkan( window.GetParameters() ) ) {
return -1;
}
// Tutorial 04
if( !tutorial05.CreateRenderPass() ) {
return -1;
}
if( !tutorial05.CreatePipeline() ) {
return -1;
}
if( !tutorial05.CreateRenderingResources() ) {
return -1;
}
if( !tutorial05.CreateVertexBuffer() ) {
return -1;
}
if( !tutorial05.CreateStagingBuffer() ) {
return -1;
}
if( !tutorial05.CopyVertexData() ) {
return -1;
}
// Rendering loop
if( !window.RenderingLoop( tutorial05 ) ) {
return -1;
}
return 0;
}

View File

@@ -49,3 +49,12 @@ Here I present render pass, framebuffer and pipeline objects which are necessary
#### Buffers, images and fences #### Buffers, images and fences
This tutorial shows how to set up vertex attributes and bind buffer with vertex data. Here we also create images, memory objects and fences. This tutorial shows how to set up vertex attributes and bind buffer with vertex data. Here we also create images, memory objects and fences.
<hr>
### [05 - Staging Resources](./Project/Tutorial05/)
<img src="./Document/Images/05 - Staging Resources.png" height="96px" align="right">
#### Copying data between buffers
In this example staging resources are presented. They are used as an intermediate resources for copying data between CPU and GPU. This way, resources involved in rendering can be bound only to a device local (very fast) memory.