Q> 마우스로 컬러픽커 기능을 하는 함수 만들기


대략 알고리즘

1) stagingBuffer, stagingBufferMemory 생성

2) 커멘드 버퍼 할당, 레코딩 시작

3) pipelineBarrier로 swapchainImage의 레이아웃 transpose_bit으로 바꾸기

4) 커멘드 버퍼를 그래픽스 큐에 제출

5) 레코딩 시작

6) swapchain에서 stagingBufferMemory로 카피

7) 커멘드 버퍼를 그래픽스 큐에 제출

8) 커멘드 버퍼 할당 해제

9) staging 맵핑

10) memcpy로 이미지 데이터를 void* data에 가져옴

11) 마우스 포지션을 얻어와서 data에서 해당 위치를 검색하면 끝


졸작으로 만드는 중인데 진짜 너무 어렵다 머리 다 빠질 것 같음 ㅅㅂ..

요즘 VULKAN 글 많이 보이던데 진짜 대단한 사람인것 같다 


void getImageData(VkImage src, VkDeviceSize imageSize) {
// 스테깅 버퍼, 스테깅 버퍼 메모리 생성
// 커맨드 버퍼 할당
// 커맨드 버퍼 비긴 인포
// Image2Buffer
// memcpy

VkBuffer stagingBuffer;
VkDeviceMemory stagingBufferMemory;

VkBufferCreateInfo bufferCreateInfo{};
bufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
bufferCreateInfo.pNext = NULL;
bufferCreateInfo.flags = 0;
bufferCreateInfo.size = imageSize;
// Image에서 값을 받아온다.
bufferCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
bufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;

if (vkCreateBuffer(device, &bufferCreateInfo, nullptr, &stagingBuffer) != VK_SUCCESS) {
throw std::runtime_error("staging Buffer 생성 오류");
}

VkMemoryRequirements memReq;
vkGetBufferMemoryRequirements(device, stagingBuffer, &memReq);

VkPhysicalDeviceMemoryProperties memProp;
vkGetPhysicalDeviceMemoryProperties(physicalDevice, &memProp);

int memoryTypeIdx = -1;
for (int i = 0; i < memProp.memoryTypeCount; i++) {
if (memReq.memoryTypeBits & (1 << i) && memProp.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT == VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) {
memoryTypeIdx = i;
break;
}
}
if (memoryTypeIdx == -1)
throw std::runtime_error("stagingBuffer가 요구하는 메모리 유형을 찾을 수 없음.");

VkMemoryAllocateInfo memAllocInfo{};
memAllocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
memAllocInfo.allocationSize = memReq.size;
memAllocInfo.memoryTypeIndex = memoryTypeIdx;

std::cout << memReq.size << std::endl;

if (vkAllocateMemory(device, &memAllocInfo, nullptr, &stagingBufferMemory) != VK_SUCCESS) {
throw std::runtime_error("stagingBufferMemory생성 오류");
}

vkBindBufferMemory(device, stagingBuffer, stagingBufferMemory, 0);

VkCommandBuffer recordBuffer;

VkCommandBufferAllocateInfo cmdbufAllocInfo{};
cmdbufAllocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
cmdbufAllocInfo.pNext = nullptr;
cmdbufAllocInfo.commandPool = commandPool;
cmdbufAllocInfo.commandBufferCount = 1;
cmdbufAllocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;

if (vkAllocateCommandBuffers(device, &cmdbufAllocInfo, &recordBuffer) != VK_SUCCESS) {
throw std::runtime_error("command buffer 생성 실패.");
}

VkCommandBufferBeginInfo cmdbufBeginInfo{};
cmdbufBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
cmdbufBeginInfo.pNext = nullptr;
cmdbufBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
cmdbufBeginInfo.pInheritanceInfo = nullptr;

vkBeginCommandBuffer(recordBuffer, &cmdbufBeginInfo);

VkImageMemoryBarrier imageMemBarrier{};
imageMemBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
imageMemBarrier.pNext = nullptr;
imageMemBarrier.image = src;
imageMemBarrier.oldLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
imageMemBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
imageMemBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
imageMemBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
imageMemBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
imageMemBarrier.subresourceRange.baseArrayLayer = 0;
imageMemBarrier.subresourceRange.baseMipLevel = 0;
imageMemBarrier.subresourceRange.layerCount = 1;
imageMemBarrier.subresourceRange.levelCount = 1;

vkCmdPipelineBarrier( recordBuffer,
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT,
0,
0, nullptr,
0, nullptr,
1, &imageMemBarrier);

vkEndCommandBuffer(recordBuffer);

VkSubmitInfo submitInfo{};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submitInfo.pNext = nullptr;
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &recordBuffer;
if (vkQueueSubmit(graphicsQueue, 1, &submitInfo, nullptr) != VK_SUCCESS) {
throw std::runtime_error("commandBuffer를 제출하는데 실패.");
}

vkQueueWaitIdle(graphicsQueue);
VkCommandBufferBeginInfo cmdbufBeginInfo{};
cmdbufBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
cmdbufBeginInfo.pNext = nullptr;
cmdbufBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
cmdbufBeginInfo.pInheritanceInfo = nullptr;

vkBeginCommandBuffer(recordBuffer, &cmdbufBeginInfo);

VkBufferImageCopy bufferImageCopy{};

bufferImageCopy.bufferOffset = 0;
bufferImageCopy.bufferRowLength = 0;
bufferImageCopy.bufferImageHeight = 0;
bufferImageCopy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
bufferImageCopy.imageSubresource.mipLevel = 0;
bufferImageCopy.imageSubresource.baseArrayLayer = 0;
bufferImageCopy.imageSubresource.layerCount = 1;
bufferImageCopy.imageOffset = { 0,
0,
0};
bufferImageCopy.imageExtent = { static_cast<unsigned int>(swapChainExtent.width),
static_cast<unsigned int>(swapChainExtent.height),
1 };


vkCmdCopyImageToBuffer(recordBuffer, src, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, stagingBuffer, 1, &bufferImageCopy);

vkEndCommandBuffer(recordBuffer);

VkSubmitInfo submitInfo{};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submitInfo.pNext = nullptr;
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &recordBuffer;
if (vkQueueSubmit(graphicsQueue, 1, &submitInfo, nullptr) != VK_SUCCESS) {
throw std::runtime_error("commandBuffer를 제출하는데 실패.");
}

vkQueueWaitIdle(graphicsQueue);
vkFreeCommandBuffers(device, commandPool, 1, &recordBuffer);

void* data;
vkMapMemory(device, stagingBufferMemory, 0, imageSize, 0, &data);

memcpy(data, stagingBufferMemory, imageSize);
vkUnmapMemory(device, stagingBufferMemory);

vkFreeMemory(device, stagingBufferMemory, nullptr);
vkDestroyBuffer(device, stagingBuffer, nullptr);

std::cout << "픽셀 개수: " << sizeof(data) << std::endl;
}