Ho lavorato con Vulkan per le ultime due settimane e ho incontrato un problema che si è verificato solo sulle schede AMD. In particolare l'AMD 7970M. Ho eseguito il mio progetto sulle schede GTX 700 e 900 senza alcun problema. Ho persino eseguito Windows e Linux (Steam OS) con schede Nvidia senza intoppi. Il problema si presenta solo sulle schede AMD e solo con il mio progetto; tutti i campioni e i progetti da Sascha Willems non eseguono alcun problema.Vulkan non riesce a cancellare la profondità
In questo momento sto disegnando un modello di Raptor con texture e girandolo sul posto. Lo renderò a una texture e quindi applicherei quella texture a un triangolo a schermo intero; rendering offscreen di base. Tuttavia, la profondità non sembra essere corretta correttamente sul mio 7970M. Invece ho questa artifacting strano come la profondità non viene cancellata correttamente:
Naturalmente ho provato a scavare in questo con RenderDoc e la profondità è totalmente sbagliato. Sia il Raptor e il Triangolo a tutto schermo la sua disegnato su sono solo un pasticcio:
ho provato a confronto il mio codice all'esempio Offscreen da Sascha Willems e appaio fatevi fare quasi tutto allo stesso modo. Ho pensato che forse qualcosa sarebbe stato sbagliato nel modo in cui ho creato la mia profondità, ma mi sembra soddisfacente rispetto a tutti gli esempi che ho visto.
Ecco alcuni punti di vista di debug di cui sto creando l'immagine di profondità e la vista:
Ecco l'intero metodo:
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;
}
se qualcuno vuole maggiori informazioni sul codice non esitate a chiedere e lo fornirò. Ci sono molte linee di codice per questo progetto, quindi non voglio che tutti debbano attraversare tutto. Se vuoi che tutto il codice possa essere trovato su http://github.com/thirddegree/HatchitGraphics/tree/dev
Modifica: Dopo un po 'di più, ho scoperto che anche il colore non si cancella bene. RenderDoc mostra che ogni frame esegue solo il ritaglio del raptor e non cancella il resto del frame. È un problema con il guidatore?
Modifica: altre informazioni. Ho scoperto che se disegno NULLA, inizio e termina un passaggio di rendering senza nemmeno disegnare il mio triangolo a schermo intero, lo schermo si cancellerà. Comunque, se disegno solo il triangolo, la profondità è sbagliata (anche se non spacco nulla da fuori schermo o non applico alcun tipo di texture).
Modifica: più specificatamente il colore si cancellerà ma la profondità no. Se non disegno nulla, la profondità rimarrà nera; tutti gli 0 Perché il triangolo a schermo intero causa la strana staticità della profondità non sono sicuro.
Questo dovrebbe essere fatto per gli allegati di profondità e colore? – Honeybunch
L'allegato a colori dovrebbe essere sufficiente. Se vedi ancora la corruzione, anche con le barriere presenti controlla anche se il tuo negozio e le operazioni di carico per gli allegati sono corretti. –
Ci scusiamo per la risposta tardiva su questo. Sono sicuro che le mie operazioni di caricamento e di archiviazione sono corrette. Non sono convinto che le barriere pre e post presenti siano il problema. Li ho implementati nel mio motore in modo molto simile a come li hai impostati nei tuoi esempi e non ha avuto alcun effetto sull'immagine. In effetti penso di aver corretto il problema mentre scrivevo questo e ho dimenticato di inviare un comando di transizione dell'immagine. – Honeybunch