• Advertisement

mark_braga

Member
  • Content count

    44
  • Joined

  • Last visited

Community Reputation

6 Neutral

3 Followers

About mark_braga

  • Rank
    Member

Personal Information

  • Interests
    Art
    Programming
  1. I am working on a project which needs to share render targets between Vulkan and DirectX12. I have enabled the external memory extension and now allocate the memory for the render targets by adding the VkExportMemoryInfoKHR to the pNext chain of VkMemoryAllocateInfo. Similarly I have added the VkExternalMemoryImageCreateInfo to the pNext chain of VkImageCreateInfo. After calling the get win32 handle function, I get some handle pointer which is not null (I assume it is valid). VkExternalMemoryImageCreateInfoKHR externalImageInfo = {}; if (gExternalMemoryExtensionKHR) { externalImageInfo.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR; externalImageInfo.pNext = NULL; externalImageInfo.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR | VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR | VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR | VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT_KHR | VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT_KHR | VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT_KHR | VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT_KH imageCreateInfo.pNext = &externalImageInfo; } vkCreateImage(...); VkExportMemoryAllocateInfoKHR exportInfo = { VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR }; exportInfo.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR | VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR | VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR | VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT_KHR | VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT_KHR | VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT_KHR | VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT_KHR; memoryAllocateInfo.pNext = &exportInfo; vkAllocateMemory(...); VkMemoryGetWin32HandleInfoKHR info = { VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR, NULL }; info.memory = pTexture->GetMemory(); info.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT_KHR; VkResult res = vkGetMemoryWin32HandleKHR(vulkanDevice, &info, &pTexture->pSharedHandle); ASSERT(VK_SUCCESS == res); Now when I try to call OpenSharedHandle from a D3D12 device, it crashes inside nvwgf2umx.dll with the integer division by zero error. I am now lost and have no idea what the other handle types do. For example: How do we get the D3D12 resource from the VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR handle? I also found some documentation on this link but it doesn't help much. https://javadoc.lwjgl.org/org/lwjgl/vulkan/NVExternalMemoryWin32.html This is all assuming the extension works as expected since it has made it to the KHR
  2. I tried to create a resource on one device and use it on another and it works without specifying any flags or even opening any handles. Any reason why the validation won't complain? This is the overview of what I did and it works just fine even if the render target texture was created on pDevice0 and the render target is cleared on a command list created on pDevice1 initDevice(pDevice0); addRenderTarget(pDevice0, &pRenderTarget); initDevice(pDevice1); // This works without any problems clearRTV(pDevice1->pCmdList, pRenderTarget, WHITE);
  3. Thanks for posting these links. They have given a lot of insight. So just to confirm if I want to create a 2D view of face 3 of a cubemap, will the code look something like this? SRV_DESC desc = {}; desc.dimension = TEXTURE_2D_ARRAY; desc.tex2DArray.firstArraySlice = 3; // Face 3 in the cubemap desc.tex2DArray.arraySize = 1; // Only need one face addSRV(pCubeMapResource, &desc); Thank you
  4. I was wondering if it is possible to use individual faces of cubemap for creating 2D srvs. So the underlying ID3D12Resource will be the cubemap but we can also access it as 6 separate 2d textures in shader code. ID3D12Resource* pCubeMap = createCubeMap(); SRV cubeMapFace1 = {}; cubeMapFace1.dimension = 2D; cubeMapFace1.xxx = 0; // This will be the face index (is this the plane slice field in D3D12_TEX2D_SRV? How does it map to Vulkan since there is no plane slice in VkImageViewCreateInfo) // Plan is to create an srv for only the first face of the cubemap and use it as a normal 2D texture in shader code createSRV(pCubeMap, &cubeMapFace1); Thank you
  5. It seems like nobody really knows what is the correct behavior after window minimizes in Vulkan. I have looked at most of the examples (Sascha Willems, GPUOpen,...) and all of them crash after the window minimize event with the error VK_ERROR_OUT_OF_DATE either with an assertion during acquire image or after calling present. This is because we have to recreate the swap chain. I tried this but then Vulkan expects you to provide a swap chain with extents { 0, 0, 0, 0 }, but now if you try to set the viewport or create new image views with extents { 0, 0, 0, 0 }, Vulkan expects you to provide non-zero values. So now I am confused. Should we just do nothing after a window minimize event? No rendering, update, ...?
  6. Yes. This has broken my understanding of the constant buffer alignment. The behavior seems odd. If you place the numLights after the lights array, everything breaks. cbuffer lightData : register(b0) { // If this part is placed after the lights array, everything breaks /// uint lightCount; uint _pad0; uint _pad1; uint _pad2; /// Light lights[NUM_LIGHTS]; };
  7. I am confused why this code works because the lights array is not 16 bytes aligned. struct Light { float4 position; float radius; float intensity; // How does this work without adding // uint _pad0, _pad1; }; cbuffer lightData : register(b0) { uint lightCount; uint _pad0; uint _pad1; uint _pad2; // Shouldn't the shader be not able to read the second element in the light struct // Because after float intensity, we need 8 more bytes to make it 16 byte aligned? Light lights[NUM_LIGHTS]; } This has erased everything I thought I knew about constant buffer alignment. Any explanation will help clear my head. Thank you
  8. I have always been confused about how std::vector class gets the debugging info. You get a nice list of all the elements in the vector. Whereas, for non-stl vector classes which I have written or used, all you get to see is the first element(begin) and the last element (end) which is just garbage memory. We don't use any STL code in our engine for obvious reasons but sometimes it's nice to view the contents inside the vector Does Visual studio have some special logic to show all elements of the std::vector in the debug view?
  9. I am working on a VR project where we have two devices. One for the renderer belonging to the game engine and the other used to present the textures to the VR screens. We ported both the game engine renderer and the VR renderer to DirectX12 recently. I haven't seen any examples of sharing textures across devices in DirectX12. Microsoft has an example on cross adapter sharing but we are only dealing with one GPU. Can we create a shared heap for two devices like we do for two adapters? Is there a way to do async copy between two devices? If async copy is possible, it would be ideal since we already have designed our engine along the lines of taking the most advantage of async copy and compute. Any guidance on this will really help to reduce the texture transfer overhead. Thank you
  10. So how is the image barrier issued. Is the logic something like this: for (uint32_t i = 0; i < dependencyCount; ++i) { if (pDependencies[i].srcSubpass == currentSubpass) { for (uint32_t att = 0; att < pRenderPass->attachmentCount; ++att) { if (pRenderPass->pAttachments[att]->srcAccessFlag == pDepdendencies[i].srcAccessFlag) { // transition the attachment to pDependencies[i].dstAccess? } } } }
  11. Thanks for the explanation. Here are you talking about the attachment in the subpass or the renderpass? (Is attachment0 relative to the pColorAttachments in the subpass or pAttachments in the renderpass)
  12. I am looking at the SaschaWillems subpass example for getting some insight into subpass depdendencies but its hard to understand whats going on without any comments. Also there is not a lot of documentation on subpass dependencies overall. Looking at the code, I can see that user specifies the src subpass, dst subpass and src state, dst state. But there is no mention of which resource the dependency is on. Is a subpass dependency like a pipeline barrier. If yes, how does it issue the barrier? Is the pipeline barrier issued on all attachments in the subpass with the input src and dst access flags? Any explanation will really clear a lot of doubts on subpass dependencies. Thank you
  13. I need to index into a texture array using indices which are not dynamically uniform. This works fine on NVIDIA chips but you can see the artifacts on AMD due to the wavefront problem. This means, a lot of pixel invocations get the wrong index value. I know you fix this by using NonUniformResourceIndex in hlsl. Is there an equivalent for Vulkan glsl? This is the shader code for reference. As you can see, index is an arbitrary value for each pixel and is not dynamically uniform. I fix this for hlsl by using NonUniformResourceIndex(index) layout(set = 0, binding = 0) uniform sampler textureSampler; layout(set = 0, binding = 1) uniform texture2D albedoMaps[256]; layout(location = 0) out vec4 oColor; void main() { uint index = calculate_arbitrary_texture_index(); vec2 texCoord = calculate_texcoord(); vec4 albedo = texture(sampler2D(albedoMaps[index], textureSampler), texCoord); oColor = albedo; } Thank you
  14. This makes it more confusing What is an example use case of the VOLATILE flag?
  15. Thanks for the info. Since we are on the topic, just curious to know whether it's optimal to use: The DESCRIPTORS_VOLATILE flag, create one big descriptor table and let the driver manage the versioning Separate the tables based on update frequency? The first scenario will have only one SetRootDescriptorTable call from app code. Not sure about driver code. The second scenario will have multiple SetRootDescriptorTable calls depending on the update frequency and the driver has to do no versioning since the app manages it. Thanks
  • Advertisement