2016-06-12 7 views
3

vkCmdBlitImage을 사용하여 밉맵 런타임 (glGenerateMipmap() 기능 구현)을 생성하려고하지만 프로세스를 이해하지 못합니다. 지금까지 내 코드는 다음과 같습니다.Vulkan에서 밉맵 생성

VkImageCreateInfo imageCreateInfo = {}; 
imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 
imageCreateInfo.pNext = nullptr; 
imageCreateInfo.imageType = VK_IMAGE_TYPE_2D; 
imageCreateInfo.format = format; 
imageCreateInfo.mipLevels = mipLevels; 
imageCreateInfo.arrayLayers = 1; 
imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT; 
imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL; 
imageCreateInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT; 
imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 
imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; 
imageCreateInfo.extent = { static_cast<std::uint32_t>(width), static_cast<std::uint32_t>(height), 1 }; 
imageCreateInfo.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; 

err = vkCreateImage(GfxDeviceGlobal::device, &imageCreateInfo, nullptr, &image); 

... 

    for (int i = 1; i < mipLevels; ++i) 
    { 
     const std::int32_t mipWidth = width >> i; 
     const std::int32_t mipHeight = height >> i; 

     VkImageBlit imageBlit = {}; 
     imageBlit.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 
     imageBlit.srcSubresource.baseArrayLayer = 0; 
     imageBlit.srcSubresource.layerCount = 1; 
     imageBlit.srcSubresource.mipLevel = 0; 
     imageBlit.srcOffsets[ 0 ] = { 0, 0, 0 }; 
     imageBlit.srcOffsets[ 1 ] = { width, height, 1 }; 

     imageBlit.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 
     imageBlit.dstSubresource.baseArrayLayer = 0; 
     imageBlit.dstSubresource.layerCount = 1; 
     imageBlit.dstSubresource.mipLevel = i; 
     imageBlit.dstOffsets[ 0 ] = { 0, 0, 0 }; 
     imageBlit.dstOffsets[ 1 ] = { mipWidth, mipHeight, 1 }; 

     vkCmdBlitImage(texCmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 
         image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 
         1, &imageBlit, VK_FILTER_LINEAR); 
    } 

각 밉 레벨에는 고유 한 이미지가 필요합니까? 그것들을 어떻게 초기화해야합니까? 텍스처 데이터에 스테이징 버퍼를 사용할 때 언제 밉맵을 생성해야합니까?

편집 : 제안 된대로 하나의 이미지 만 사용하도록 코드가 수정되었으므로 RenderDoc 텍스처 뷰어에서 올바른 밉 레벨 이미지를 볼 수 있으며 유효성 검사 오류가 발생하지 않습니다.

+1

src와 dst 이미지는 동일 할 수 있습니다. 이 목적을 위해 아마도해야합니다. ; 각 이미지는 최소 1 밉 레벨 ([0]이 기본 "텍스처"임)을가집니다. 'i'는'나는'이상하게 들린다. – krOoze

답변

3

각 밉 레벨에는 고유 한 이미지가 필요합니까?

아니요, 밉 레벨마다 별도의 이미지가 필요하지 않습니다. 텍스처의 이미지를 만들면 VkImageCreateInfo의 mipLevels 만 설정하면됩니다.

어떻게 초기화해야합니까? 텍스처 데이터에 스테이징 버퍼를 사용할 때 언제 밉맵을 생성해야합니까?

이것은 크게 밉을 먹이려는 대상에 따라 다릅니다. 그냥 텍스처 파일 (정적 밉 레벨)에서로드하고 싶습니까, 아니면 런타임에 생성해야합니까?

파일에서로드하려는 경우 blit을 전혀 사용하지 마십시오. 스테이징 버퍼 (이미지가 아님)를 생성하고 텍스처 데이터를로드 한 다음 해당 버퍼에서 이미지로 vkCmdCopyBufferToImage를 수행하십시오.

하지만 좀 더 자세히 설명해주세요. 구현에 따라 중요 할 수있는 이미지 레이아웃 전환이 표시되지 않으며 이미지 작성 정보 (예 : 플래그)에 대한 정보가 없으며 코드가 실제로 작동하는지 여부는 명시하지 않습니다.

blit 소스의 mipLevel이 잘못 될 수 있습니다. 당신은 정말로 mip으로 완전한 mip chain과 copy mip을 가진 소스를 가지고 있습니까?

+0

감사합니다. 질문에 몇 가지 세부 사항을 추가했습니다. 나는 전반적인 과정을 확신 할 수 없었기 때문에 전환을 아직 쓰지 않았다. – SurvivalMachine

+1

@SurvivalMachine 내 굉장한 인터넷 검색 기술을 통해 정확히 무엇을 하려는지 예를 발견했습니다. 이 답변에 피기 백을 달아주세요 : https://skia.googlesource.com/skia.git/+/master/src/gpu/vk/GrVkGpu.cpp#779 – krOoze

관련 문제