2016-03-14 20 views
15

私は過去数週間Vulkanと作業していましたが、私はAMDカードでしか起こっていない問題に遭遇しました。特にAMD 7970M。私は問題なくGTX 700と900シリーズカードでプロジェクトを実行しました。私はWindowsでLinux(Steam OS)を使ってNvidiaカードを動かすことさえしました。この問題は、AMDカードでのみ表示され、私のプロジェクトでのみ表示されます。 Sascha Willemsのすべてのサンプルとプロジェクトは問題ありません。Vulkanが深さをクリアできない

今、私はテクスチャ付きのRaptorモデルを描き、それを所定の位置に回転させています。これをテクスチャにレンダリングし、そのテクスチャを全画面三角形に適用します。基本的なオフスクリーンレンダリング。しかし、深さは私の7970Mでは正しくクリアされていないようです。代わりに、私は深さのようなこの奇妙なアーチファクトが適切に消去されていない取得:もちろん

Bad Raptor

私はRenderDocでこれに掘りしようとした深さは完全に間違っています。ラプターとフルスクリーントライアングルその上に描かれたの両方がちょうど混乱している:

Bad Depth

Bad Tri Depth

私はサシャ・ウィレムスからオフスクリーンの例に私のコードを比較してみたと私はほとんどやっているん表示されますすべて同じように。私は深みを生み出した方法で何かが間違っているかもしれないと思ったが、私が見たすべての例と比較してうまくいくように思える。ここで

は、私は奥行き画像とビューを作成していますどこのいくつかのデバッグビューは、次のとおりです。

image info image view info

ここでは全体の方法です:誰でも詳細を望んでいる場合

 bool VKRenderTarget::setupFramebuffer(VKRenderer* renderer) 
      { 
       VkDevice device = renderer->GetVKDevice(); 
       VkCommandBuffer setupCommand; 

       m_colorFormat = renderer->GetPreferredImageFormat(); 
       m_depthFormat = renderer->GetPreferredDepthFormat(); 

       renderer->CreateSetupCommandBuffer(); 

       setupCommand = renderer->GetSetupCommandBuffer(); 

       VkResult err; 

       //Color attachment 
       VkImageCreateInfo imageInfo = {}; 
       imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 
       imageInfo.pNext = nullptr; 
       imageInfo.format = m_colorFormat; 
       imageInfo.imageType = VK_IMAGE_TYPE_2D; 
       imageInfo.extent.width = m_width; 
       imageInfo.extent.height = m_height; 
       imageInfo.mipLevels = 1; 
       imageInfo.arrayLayers = 1; 
       imageInfo.samples = VK_SAMPLE_COUNT_1_BIT; 
       imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL; 
       imageInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 
       imageInfo.flags = 0; 

       VkMemoryAllocateInfo memAllocInfo = {}; 
       memAllocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 

       VkMemoryRequirements memReqs; 

       err = vkCreateImage(device, &imageInfo, nullptr, &m_color.image); 
       assert(!err); 
       if (err != VK_SUCCESS) 
       { 
#ifdef _DEBUG 
        Core::DebugPrintF("VKRenderTarget::VPrepare(): Error creating color image!\n"); 
#endif 
        return false; 
       } 

       vkGetImageMemoryRequirements(device, m_color.image, &memReqs); 
       memAllocInfo.allocationSize = memReqs.size; 
       renderer->MemoryTypeFromProperties(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &memAllocInfo.memoryTypeIndex); 

       err = vkAllocateMemory(device, &memAllocInfo, nullptr, &m_color.memory); 
       assert(!err); 
       if (err != VK_SUCCESS) 
       { 
#ifdef _DEBUG 
        Core::DebugPrintF("VKRenderTarget::VPrepare(): Error allocating color image memory!\n"); 
#endif 
        return false; 
       } 

       err = vkBindImageMemory(device, m_color.image, m_color.memory, 0); 
       if (err != VK_SUCCESS) 
       { 
#ifdef _DEBUG 
        Core::DebugPrintF("VKRenderTarget::VPrepare(): Error binding color image memory!\n"); 
#endif 
        return false; 
       } 

       renderer->SetImageLayout(setupCommand, m_color.image, VK_IMAGE_ASPECT_COLOR_BIT, 
        VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); 

       VkImageViewCreateInfo viewInfo = {}; 
       viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 
       viewInfo.pNext = nullptr; 
       viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; 
       viewInfo.format = m_colorFormat; 
       viewInfo.flags = 0; 
       viewInfo.subresourceRange = {}; 
       viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 
       viewInfo.subresourceRange.baseMipLevel = 0; 
       viewInfo.subresourceRange.levelCount = 1; 
       viewInfo.subresourceRange.baseArrayLayer = 0; 
       viewInfo.subresourceRange.layerCount = 1; 
       viewInfo.image = m_color.image; 

       err = vkCreateImageView(device, &viewInfo, nullptr, &m_color.view); 
       if (err != VK_SUCCESS) 
       { 
#ifdef _DEBUG 
        Core::DebugPrintF("VKRenderTarget::VPrepare(): Error creating color image view!\n"); 
#endif 
        return false; 
       } 

       //We can reuse the same info structs to build the depth image 
       imageInfo.format = m_depthFormat; 
       imageInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; 

       err = vkCreateImage(device, &imageInfo, nullptr, &(m_depth.image)); 

       assert(!err); 
       if (err != VK_SUCCESS) 
       { 
#ifdef _DEBUG 
        Core::DebugPrintF("VKRenderTarget::VPrepare(): Error creating depth image!\n"); 
#endif 
        return false; 
       } 

       viewInfo.format = m_depthFormat; 
       viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; 

       vkGetImageMemoryRequirements(device, m_depth.image, &memReqs); 
       memAllocInfo.allocationSize = memReqs.size; 
       renderer->MemoryTypeFromProperties(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &memAllocInfo.memoryTypeIndex); 

       err = vkAllocateMemory(device, &memAllocInfo, nullptr, &m_depth.memory); 
       assert(!err); 
       if (err != VK_SUCCESS) 
       { 
#ifdef _DEBUG 
        Core::DebugPrintF("VKRenderTarget::VPrepare(): Error allocating depth image memory!\n"); 
#endif 
        return false; 
       } 

       err = vkBindImageMemory(device, m_depth.image, m_depth.memory, 0); 
       if (err != VK_SUCCESS) 
       { 
#ifdef _DEBUG 
        Core::DebugPrintF("VKRenderTarget::VPrepare(): Error binding depth image memory!\n"); 
#endif 
        return false; 
       } 

       renderer->SetImageLayout(setupCommand, m_depth.image, 
        VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 
        VK_IMAGE_LAYOUT_UNDEFINED, 
        VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); 

       viewInfo.image = m_depth.image; 

       err = vkCreateImageView(device, &viewInfo, nullptr, &m_depth.view); 
       if (err != VK_SUCCESS) 
       { 
#ifdef _DEBUG 
        Core::DebugPrintF("VKRenderTarget::VPrepare(): Error creating depth image view!\n"); 
#endif 
        return false; 
       } 

       renderer->FlushSetupCommandBuffer(); 

       //Finally create internal framebuffer 
       VkImageView attachments[2]; 
       attachments[0] = m_color.view; 
       attachments[1] = m_depth.view; 

       VkFramebufferCreateInfo framebufferInfo = {}; 
       framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; 
       framebufferInfo.pNext = nullptr; 
       framebufferInfo.flags = 0; 
       framebufferInfo.renderPass = *((VKRenderPass*)m_renderPass)->GetVkRenderPass(); 
       framebufferInfo.attachmentCount = 2; 
       framebufferInfo.pAttachments = attachments; 
       framebufferInfo.width = m_width; 
       framebufferInfo.height = m_height; 
       framebufferInfo.layers = 1; 

       err = vkCreateFramebuffer(device, &framebufferInfo, nullptr, &m_framebuffer); 
       if (err != VK_SUCCESS) 
       { 
#ifdef _DEBUG 
        Core::DebugPrintF("VKRenderTarget::VPrepare(): Error creating framebuffer!\n"); 
#endif 
        return false; 
       } 

       return true; 
      } 

は、コードは自由に聞いてください。私はそれを提供します。このプロジェクトにはたくさんのコードがありますので、誰もがこのプロジェクト全体を歩き回らないようにしたいと思います。もしあなたが望むのであれば、すべてのコードはhttp://github.com/thirddegree/HatchitGraphics/tree/dev

で見つけることができます。もう少し詳しく調べてみてください。 RenderDocは、各フレームがラプタの切り抜きのみレンダリングし、フレームの残りの部分はクリアしないことを示しています。これはドライバーの問題ですか?

編集:もう少し詳しい情報。私は、何も描画しないと、レンダリングパスを開始して終了し、フルスクリーンの三角形を描画しなくても、画面がクリアされることがわかりました。しかし、私が三角形だけを描くと、深度は間違っています(私はオフスクリーンから何かをblitしたり、何らかのテクスチャを適用しなくても)。

編集:より具体的には、色はクリアされますが、奥行きはありません。私が何かを描かなければ、深みは黒くなります。すべて0です。なぜフルスクリーンの三角形が奇妙な奥行きの静寂を引き起こすのかわからない。

答えて

9

これは私が私のバルカン例はAMDのハードウェア上で動作得るために始めたときに私に起こった正確に何である:

enter image description here

彼らのGPUは(ほとんどが例えばNVIDIAによって無視されます)正しい画像遷移に大きく依存していますあなたのスクリーンショットに表示されている破損は、事前に存在する障壁がないことの結果であると私は考えています。

プレ・バリア(here参照)は、カラー・アタッチメントのイメージ・レイアウトを、スワップ・チェーンに提示するためのプレゼンテーション・フォーマットに変換します。

これは、添付ファイルが表示される前に完了していることを確認するために、カラー添付ファイルへのレンダリングが終了した後に行う必要があります。

この例は、私の例のdraw routineにあります。

次のフレームのレンダリング時に、カラーアタッチメントのイメージフォーマットを変換し直して、再度レンダリングできるようにする必要があります。

それを合計するには、次の

  • VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMALVK_IMAGE_LAYOUT_PRESENT_SRC_KHRから自分の色のアタッチメント遷移に(別名 "ポスト存在")

  • をあなたの画像をレンダリングする前に、あなたが

  • トランジションをレンダリングしていますあなたのカラーアタッチメントイメージはVK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMALからVK_IMAGE_LAYOUT_PRESENT_SRC_KHRになり、スワップチェーンに表示されます

+0

深度と色の両方の添付ファイルに対してこれを行う必要がありますか? – Honeybunch

+1

カラーアタッチメントは十分でなければなりません。現在の障壁にもかかわらず、破損が見られる場合は、店舗と添付ファイルの読み込み操作が正しいかどうかを確認してください。 –

+0

この件について遅れて申し訳ありません。私は私のロードとストア操作が正しいと確信しています。私は現在の障壁の前後に問題があるとは確信していません。私はあなたのサンプルで設定した方法と非常によく似た方法でエンジンに実装しました。画像には何の影響もありませんでした。実際、私はこれを書いている間に問題を修正したと思うし、画像の移行コマンドを送信するのを忘れてしまった。 – Honeybunch

5

Saschaのおかげで、新しい1.0.5 LunarG SDKが登場しました。私は問題を解決できました。固定の変更(とカップル他のささい)でコミットここで見つけることができます:https://github.com/thirddegree/HatchitGraphics/commit/515d0303f45a8e9c00f67a74c824530ea37b687a

それはいくつかの組み合わせだった:

私がのフレームバッファの添付ファイルを奥行き画像を設定するために必要な私はsubresourceRangebaseArrayLayerをspecifiyするのを忘れほとんどすべての画像メモリバリアについてVK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BITだけではなく、VK_IMAGE_ASPECT_DEPTH_BIT

にswapchain。バージョン1.0.5まではこれでエラーは発生しませんでした。

同様のバグを追跡してテクスチャの生成に影響する1.0.5までポップアップしなかった別のエラーは、テクスチャのデバイスメモリをホストメモリにマッピングする前に、それをVK_IMAGE_LAYOUT_UNDEFINEDVK_IMAGE_LAYOUT_GENERALに送信するには、そのコマンドを送信し、メモリをマップしてから、それをGENERALからVK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMALに移行します(そのコマンドも送信することを忘れないでください)。繰り返しますが、これはサンプルしたいテクスチャだけですが、ここでの道徳は実際にはイメージ遷移を送信すると思います。

関連する問題