Changeset eea05dd in opengl-game for vulkan-game.cpp
- Timestamp:
- Jul 26, 2019, 5:23:30 AM (5 years ago)
- Branches:
- feature/imgui-sdl, master, points-test
- Children:
- 88ebdc8
- Parents:
- c7fb883
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
vulkan-game.cpp
rc7fb883 reea05dd 16 16 #include <glm/glm.hpp> 17 17 #include <glm/gtc/matrix_transform.hpp> 18 19 #define STB_IMAGE_IMPLEMENTATION 20 #include "stb_image.h" 18 21 19 22 #include <iostream> … … 189 192 vector<VkSemaphore> renderFinishedSemaphores; 190 193 vector<VkFence> inFlightFences; 194 195 VkImage textureImage; 196 VkDeviceMemory textureImageMemory; 191 197 192 198 size_t currentFrame = 0; … … 223 229 createFramebuffers(); 224 230 createCommandPool(); 231 createTextureImage(); 225 232 createVertexBuffer(); 226 233 createIndexBuffer(); … … 919 926 } 920 927 928 void createTextureImage() { 929 int texWidth, texHeight, texChannels; 930 931 stbi_uc* pixels = stbi_load("textures/texture.jpg", &texWidth, &texHeight, &texChannels, STBI_rgb_alpha); 932 VkDeviceSize imageSize = texWidth * texHeight * 4; 933 934 if (!pixels) { 935 throw runtime_error("failed to load texture image!"); 936 } 937 938 VkBuffer stagingBuffer; 939 VkDeviceMemory stagingBufferMemory; 940 941 createBuffer(imageSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, 942 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, 943 stagingBuffer, stagingBufferMemory); 944 945 void* data; 946 947 vkMapMemory(device, stagingBufferMemory, 0, imageSize, 0, &data); 948 memcpy(data, pixels, static_cast<size_t>(imageSize)); 949 vkUnmapMemory(device, stagingBufferMemory); 950 951 stbi_image_free(pixels); 952 953 createImage(texWidth, texHeight, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TILING_OPTIMAL, 954 VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, 955 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, textureImage, textureImageMemory); 956 957 transitionImageLayout(textureImage, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); 958 copyBufferToImage(stagingBuffer, textureImage, static_cast<uint32_t>(texWidth), static_cast<uint32_t>(texHeight)); 959 transitionImageLayout(textureImage, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); 960 961 vkDestroyBuffer(device, stagingBuffer, nullptr); 962 vkDestroyMemory(device, stagingBufferMemory, nullptr); 963 } 964 965 void createImage(uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling, 966 VkImageUsageFlags usage, VkMemoryPropertyFlags properties, VkImage& image, VkDeviceMemory& imageMemory) { 967 VkImageCreateInfo imageInfo = {}; 968 imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 969 imageInfo.imageType = VK_IMAGE_TYPE_2D; 970 imageInfo.extent.width = width; 971 imageInfo.extent.height = height; 972 imageInfo.extent.depth = 1; 973 imageInfo.mipLevels = 1; 974 imageInfo.arrayLayers = 1; 975 imageInfo.format = format; 976 imageInfo.tiling = tiling; 977 imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; 978 imageInfo.usage = usage; 979 imageInfo.samples = VK_SAMPLE_COUNT_1_BIT; 980 imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 981 982 if (vkCreateImage(device, &imageInfo, nullptr, &image) != VK_SUCCESS) { 983 throw runtime_error("failed to create image!"); 984 } 985 986 VkMemoryRequirements memRequirements; 987 vkGetImageMemoryRequirements(device, image, &memRequirements); 988 989 VkMemoryAllocateInfo allocInfo; 990 allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 991 allocInfo.allocationSize = memRequirements.size; 992 allocInfo.memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits, properties); 993 994 if (vkAllocateMemory(device, &allocInfo, nullptr, &imageMemory) != VK_SUCCESS) { 995 throw runtime_error("failed to allocate image memory!"); 996 } 997 998 vkBindImageMemory(device, image, imageMemory, 0); 999 } 1000 1001 void transitionImageLayout(VkImage image, VkFormat format, VkImageLayout oldLayout, VkImageLayout newLayout) { 1002 VkCommandBuffer commandBuffer = beginSingleTimeCommands(); 1003 1004 VkImageMemoryBarrier barrier = {}; 1005 barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; 1006 barrier.oldLayout = oldLayout; 1007 barrier.newLayout = newLayout; 1008 barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 1009 barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 1010 barrier.image = image; 1011 barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 1012 barrier.subresourceRange.baseMipLevel = 0; 1013 barrier.subresourceRange.levelCount = 1; 1014 barrier.subresourceRange.baseArrayLayer = 0; 1015 barrier.subresourceRange.layerCount = 1; 1016 1017 VkPipelineStageFlags sourceFlags; 1018 VkPipelineStageFlags destinationFlags; 1019 1020 if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) { 1021 barrier.srcAccessMask = 0; 1022 barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; 1023 1024 sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; 1025 destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT; 1026 } else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) { 1027 barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; 1028 barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; 1029 1030 sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT; 1031 destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; 1032 } else { 1033 throw invalid_argument("unsupported layout transition!"); 1034 } 1035 1036 vkCmdPipelineBarrier( 1037 commandBuffer, 1038 sourceFlags, destinationFlags, 1039 0, 1040 0, nullptr, 1041 0, nullptr, 1042 1, &barrier 1043 ); 1044 1045 endSingleTimeCommands(commandBuffer); 1046 } 1047 1048 void copyBufferToImage(VkBuffer buffer, VkImage image, uint32_t width, uint32_t height) { 1049 VkCommandBuffer commandBuffer = beginSingleTimeCommands(); 1050 1051 VkBufferImageCopy region = {}; 1052 region.bufferOffset = 0; 1053 region.bufferRowLength = 0; 1054 region.bufferImageHeight = 0; 1055 1056 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 1057 region.imageSubresource.mipLevel = 0; 1058 region.imageSubresource.baseArrayLayer = 0; 1059 region.imageSubresource.layerCount = 1; 1060 1061 region.imageOffset = { 0, 0, 0 }; 1062 region.imageExtent = { width, height, 1 }; 1063 1064 vkCmdCopyBufferToImage( 1065 commandBuffer, 1066 buffer, 1067 image, 1068 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1069 1, 1070 ®ion 1071 ); 1072 1073 endSingleTimeCommands(commandBuffer); 1074 } 1075 921 1076 void createVertexBuffer() { 922 1077 VkDeviceSize bufferSize = sizeof(vertices[0]) * vertices.size(); … … 993 1148 994 1149 void copyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size) { 1150 VkCommandBuffer commandBuffer = beginSingleTimeCommands(); 1151 1152 VkBufferCopy copyRegion = {}; 1153 copyRegion.size = size; 1154 vkCmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, 1, ©Region); 1155 1156 endSingleTimeCommands(commandBuffer); 1157 } 1158 1159 VkCommandBuffer beginSingleTimeCommands() { 995 1160 VkCommandBufferAllocateInfo allocInfo = {}; 996 1161 allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; … … 1008 1173 vkBeginCommandBuffer(commandBuffer, &beginInfo); 1009 1174 1010 VkBufferCopy copyRegion = {}; 1011 copyRegion.srcOffset = 0; 1012 copyRegion.dstOffset = 0; 1013 copyRegion.size = size; 1014 1015 vkCmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, 1, ©Region); 1016 1175 return commandBuffer; 1176 } 1177 1178 void endSingleTimeCommands(VkCommandBuffer commandBuffer) { 1017 1179 vkEndCommandBuffer(commandBuffer); 1018 1180 … … 1296 1458 cleanupSwapChain(); 1297 1459 1460 vkDestroyImage(device, textureImage, nullptr); 1461 vkDestroyMemory(device, textureImageMemory, nullptr); 1462 1298 1463 vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr); 1299 1464
Note:
See TracChangeset
for help on using the changeset viewer.