내 질문은 두 부분으로 구성되어 있습니다 :VULKAN : 데이터 일관성
- /볼 수있는 메모리를 사용할 수있는 차이점은 무엇입니까?
이 튜토리얼 (https://vulkan-tutorial.com)에서 Vulkan을 배우면서 현재 유니폼 데이터 (단순 모델/뷰/프로젝션 행렬)를 장치 로컬 메모리에 업로드하는 다른 방법을 찾고 있습니다. 행렬은 버텍스 쉐이더에서 사용됩니다.
이 튜토리얼에서는 매트릭스가 업데이트되어 스테이징 버퍼 (
vkMapMemory
등)에 복사 된 다음 명령 버퍼를 작성하고vkCmdCopy
을 녹음하고 제출하여 버퍼를 파괴하여 최종 장치 로컬 버퍼로 복사합니다. 나는 드로잉을 위해 명령 버퍼 내에서 마지막 단계를 시도한다.튜토리얼 방식으로 유창한 애니메이션을 만들 수 있지만 실험에서이 기능이 빠져 있습니다. 나는 2 개의 bufferBarriers를 설치하여 복사가 완료되었다는 것을 확인했지만 (문제가있는 것 같지만) 도움이되지 않았다. 리소스가 제대로 만들어지고 바인딩됩니다. 정상적으로 작동합니다.
vkcpp
(https://github.com/KhronosGroup/Vulkan-Hpp)를 사용namespace Tools { struct UniformBufferObject { glm::mat4 model; glm::mat4 view; glm::mat4 proj; }; }; vk::Buffer uniformStagingBuffer; vk::DeviceMemory uniformStagingMemory; //dataBuffer also contains the vertex and index data, is device local vk::Buffer dataBuffer; vk::DeviceMemory dataBufferMemory; vk::vector<vk::DeviceSize> dataBufferOffsets; std::vector<vk::CommandBuffer> cmdBuffers;
임과
//update uniform buffer and copy it to the staging buffer //(called every frame) Tools::UniformBufferObject ubo; //set the matrices void* data; data = device.mapMemory(uniformStagingMemory, 0, sizeof(ubo), (vk::MemoryMapFlagBits) 0); memcpy(data, &ubo, sizeof(ubo)); device.unmapMemory(uniformStagingMemory); //once: create a command buffer for each framebuffer of the swapchain //queueFamily struct members set properly //1st barrier: make transfer from host memory to staging buffer available/visible vk::BufferMemoryBarrier bufMemBarrierStaging; bufMemBarrierStaging.srcAccessMask = vk::AccessFlagBits::eHostWrite; bufMemBarrierStaging.dstAccessMask = vk::AccessFlagBits::eTransferRead; bufMemBarrierStaging.buffer = uniformStagingBuffer; bufMemBarrierStaging.offset = 0; bufMemBarrierStaging.size = sizeof(Tools::UniformBufferObject); //2nd barrier: make transfer from staging buffer to device local buffer available/visible vk::BufferMemoryBarrier bufMemBarrier; bufMemBarrier.srcAccessMask = vk::AccessFlagBits::eTransferWrite; bufMemBarrier.dstAccessMask = vk::AccessFlagBits::eUniformRead | vk::AccessFlagBits::eShaderRead; bufMemBarrier.buffer = dataBuffer; bufMemBarrier.offset = dataBufferOffsets[2]; bufMemBarrier.size = sizeof(Tools::UniformBufferObject); for(size_t i = 0; i < cmdBuffers.size(); i++) { //begin command buffer cmdBuffers[i].pipelineBarrier( vk::PipelineStageFlagBits::eHost, //srcPipelineStage vk::PipelineStageFlagBits::eTransfer, //dstPipelineStage (vk::DependencyFlagBits) 0, nullptr, //memBarrier bufMemBarrierStaging, nullptr //imgBarrier ); vk::BufferCopy copyRegion; //filled appropriate cmdBuffers[i].copyBuffer(uniformStagingBuffer, dataBuffer, copyRegion); cmdBuffers[i].pipelineBarrier( vk::PipelineStageFlagBits::eTransfer, //srcPipelineStage vk::PipelineStageFlagBits::eVertexShader, //dstPipelineStage (vk::DependencyFlagBits) 0, nullptr, //memBarrier bufMemBarrier, nullptr //imgBarrier ); //renderpass stuff and drawing etc. }
.
이 유동적이지 않은 애니메이션의 데이터 일관성이 누락 된 이유는 무엇입니까? 그리고이를 달성하기 위해 실수를 했습니까?
미리 감사드립니다.
편집 : 파트 2의 문제는 syncronisation이 누락되었습니다. 스테이징 버퍼는 이전에 프레임을 렌더링하는 동안 읽히기 전에 부분적으로 업데이트되었습니다. (사용 가능/보이는 메모리의 차이점을 명확히 해 주셔서 감사합니다).
"사용할 수있는 메모리와 보이지 않는 메모리의 차이점은 무엇입니까?" "사용 가능하다는 것의 의미가 명확하지 않습니다. "* 그리고 버퍼를 파괴 *"왜 버퍼를 파괴하겠습니까? 그게 정확히 무슨 뜻이야? –
처음에는 첫 번째 메모리 장벽이 필요하지 않습니다. 메모리 장벽 HOST_WRITE_BIT/HOST_STAGE는 명령 버퍼의 제출에 의해 암시 적으로 수행됩니다. –
@ NicolBolas 첫 번째 질문은 메모리 의존성에 대한 절의 6.4 절을 참조합니다. 나는 어떤 차이도 볼 수 없었다. Destory a buffer는, 나는'vkFreeCommandBuffers'를 호출합니다. 튜토리얼의 코드이므로, 가장 쉬운 방법은 선택하는 것이지 좋은 방법은 아닙니다. – camelCase