void getSemaphoreNative (const vk::DeviceInterface& vkd, vk::VkDevice device, vk::VkSemaphore semaphore, vk::VkExternalSemaphoreHandleTypeFlagBitsKHR externalType, NativeHandle& nativeHandle) { if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT_KHR || externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR) { const vk::VkSemaphoreGetFdInfoKHR info = { vk::VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR, DE_NULL, semaphore, externalType }; int fd = -1; VK_CHECK(vkd.getSemaphoreFdKHR(device, &info, &fd)); TCU_CHECK(fd >= 0); nativeHandle = fd; } else if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR || externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR) { const vk::VkSemaphoreGetWin32HandleInfoKHR info = { vk::VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR, DE_NULL, semaphore, externalType }; vk::pt::Win32Handle handle (DE_NULL); VK_CHECK(vkd.getSemaphoreWin32HandleKHR(device, &info, &handle)); switch (externalType) { case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR: nativeHandle.setWin32Handle(NativeHandle::WIN32HANDLETYPE_NT, handle); break; case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR: nativeHandle.setWin32Handle(NativeHandle::WIN32HANDLETYPE_KMT, handle); break; default: DE_FATAL("Unknow external memory handle type"); } } else DE_FATAL("Unknow external semaphore handle type"); }
NativeHandle::NativeHandle (const NativeHandle& other) : m_fd (-1) , m_win32HandleType (WIN32HANDLETYPE_LAST) , m_win32Handle (DE_NULL) { if (other.m_fd >= 0) { #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX) DE_ASSERT(!other.m_win32Handle.internal); m_fd = dup(other.m_fd); TCU_CHECK(m_fd >= 0); #else DE_FATAL("Platform doesn't support file descriptors"); #endif } else if (other.m_win32Handle.internal) { #if (DE_OS == DE_OS_WIN32) m_win32HandleType = other.m_win32HandleType; switch (other.m_win32HandleType) { case WIN32HANDLETYPE_NT: { DE_ASSERT(other.m_fd == -1); const HANDLE process = ::GetCurrentProcess(); ::DuplicateHandle(process, other.m_win32Handle.internal, process, &m_win32Handle.internal, 0, TRUE, DUPLICATE_SAME_ACCESS); break; } case WIN32HANDLETYPE_KMT: { m_win32Handle = other.m_win32Handle; break; } default: DE_FATAL("Unknown win32 handle type"); } #else DE_FATAL("Platform doesn't support win32 handles"); #endif } else DE_FATAL("Native handle can't be duplicated"); }
tcu::UVec3 getShaderGridSize (const ImageType imageType, const tcu::UVec3& imageSize) { switch (imageType) { case IMAGE_TYPE_1D: case IMAGE_TYPE_BUFFER: return tcu::UVec3(imageSize.x(), 1u, 1u); case IMAGE_TYPE_1D_ARRAY: return tcu::UVec3(imageSize.x(), imageSize.z(), 1u); case IMAGE_TYPE_2D: return tcu::UVec3(imageSize.x(), imageSize.y(), 1u); case IMAGE_TYPE_2D_ARRAY: case IMAGE_TYPE_3D: return tcu::UVec3(imageSize.x(), imageSize.y(), imageSize.z()); case IMAGE_TYPE_CUBE: return tcu::UVec3(imageSize.x(), imageSize.y(), 6u); case IMAGE_TYPE_CUBE_ARRAY: return tcu::UVec3(imageSize.x(), imageSize.y(), 6u * imageSize.z()); default: DE_FATAL("Unknown image type"); return tcu::UVec3(1u, 1u, 1u); } }
deUint32 getNumLayers (const ImageType imageType, const tcu::UVec3& imageSize) { switch (imageType) { case IMAGE_TYPE_1D: case IMAGE_TYPE_2D: case IMAGE_TYPE_3D: case IMAGE_TYPE_BUFFER: return 1u; case IMAGE_TYPE_1D_ARRAY: case IMAGE_TYPE_2D_ARRAY: return imageSize.z(); case IMAGE_TYPE_CUBE: return 6u; case IMAGE_TYPE_CUBE_ARRAY: return imageSize.z() * 6u; default: DE_FATAL("Unknown image type"); return 0u; } }
ImageType getImageTypeForSingleLayer (const ImageType imageType) { switch (imageType) { case IMAGE_TYPE_1D: case IMAGE_TYPE_1D_ARRAY: return IMAGE_TYPE_1D; case IMAGE_TYPE_2D: case IMAGE_TYPE_2D_ARRAY: case IMAGE_TYPE_CUBE: case IMAGE_TYPE_CUBE_ARRAY: // A single layer for cube is a 2d face return IMAGE_TYPE_2D; case IMAGE_TYPE_3D: return IMAGE_TYPE_3D; case IMAGE_TYPE_BUFFER: return IMAGE_TYPE_BUFFER; default: DE_FATAL("Internal test error"); return IMAGE_TYPE_LAST; } }
const char* externalMemoryTypeToName (vk::VkExternalMemoryHandleTypeFlagBitsKHR type) { switch (type) { case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR: return "opaque_fd"; case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR: return "opaque_win32"; case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR: return "opaque_win32_kmt"; case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT_KHR: return "d3d11_texture"; case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT_KHR: return "d3d11_texture_kmt"; case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT_KHR: return "d3d12_heap"; case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT_KHR: return "d3d12_resource"; default: DE_FATAL("Unknown external memory type"); return DE_NULL; } }
static inline const char* getWindingShaderName (const Winding winding) { switch (winding) { case WINDING_CCW: return "ccw"; case WINDING_CW: return "cw"; default: DE_FATAL("Unexpected winding type."); return DE_NULL; } }
static inline const char* getShaderLanguageName (const ShaderLanguage language) { switch (language) { case SHADER_LANGUAGE_GLSL: return "glsl"; case SHADER_LANGUAGE_HLSL: return "hlsl"; default: DE_FATAL("Unexpected shader language."); return DE_NULL; } }
static inline const char* getOutputTopologyName (const TessPrimitiveType type, const Winding winding, const bool usePointMode) { if (usePointMode) return "point"; else if (type == TESSPRIMITIVETYPE_TRIANGLES || type == TESSPRIMITIVETYPE_QUADS) return (winding == WINDING_CCW ? "triangle_ccw" : "triangle_cw"); else if (type == TESSPRIMITIVETYPE_ISOLINES) return "line"; DE_FATAL("Unexpected primitive type."); return DE_NULL; }
static inline const char* getPartitioningShaderName (SpacingMode mode) { switch (mode) { case SPACINGMODE_EQUAL: return "integer"; case SPACINGMODE_FRACTIONAL_ODD: return "fractional_odd"; case SPACINGMODE_FRACTIONAL_EVEN: return "fractional_even"; default: DE_FATAL("Unexpected spacing mode."); return DE_NULL; } }
static inline const char* getDomainName (const TessPrimitiveType type) { switch (type) { case TESSPRIMITIVETYPE_TRIANGLES: return "tri"; case TESSPRIMITIVETYPE_QUADS: return "quad"; case TESSPRIMITIVETYPE_ISOLINES: return "isoline"; default: DE_FATAL("Unexpected primitive type."); return DE_NULL; } }
void NativeHandle::reset (void) { if (m_fd >= 0) { #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX) DE_ASSERT(!m_win32Handle.internal); ::close(m_fd); #else DE_FATAL("Platform doesn't support file descriptors"); #endif } if (m_win32Handle.internal) { #if (DE_OS == DE_OS_WIN32) switch (m_win32HandleType) { case WIN32HANDLETYPE_NT: DE_ASSERT(m_fd == -1); ::CloseHandle((HANDLE)m_win32Handle.internal); break; case WIN32HANDLETYPE_KMT: break; default: DE_FATAL("Unknown win32 handle type"); } #else DE_FATAL("Platform doesn't support win32 handles"); #endif } m_fd = -1; m_win32Handle = vk::pt::Win32Handle(DE_NULL); m_win32HandleType = WIN32HANDLETYPE_LAST; }
void importSemaphore (const vk::DeviceInterface& vkd, const vk::VkDevice device, const vk::VkSemaphore semaphore, vk::VkExternalSemaphoreHandleTypeFlagBitsKHR externalType, NativeHandle& handle, vk::VkSemaphoreImportFlagsKHR flags) { if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT_KHR || externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR) { const vk::VkImportSemaphoreFdInfoKHR importInfo = { vk::VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR, DE_NULL, semaphore, flags, externalType, handle.getFd() }; VK_CHECK(vkd.importSemaphoreFdKHR(device, &importInfo)); handle.disown(); } else if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR || externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR) { const vk::VkImportSemaphoreWin32HandleInfoKHR importInfo = { vk::VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR, DE_NULL, semaphore, flags, externalType, handle.getWin32Handle(), DE_NULL }; VK_CHECK(vkd.importSemaphoreWin32HandleKHR(device, &importInfo)); // \note File descriptors and win32 handles behave differently, but this call wil make it seem like they would behave in same way handle.reset(); } else DE_FATAL("Unknown semaphore external handle type"); }
Transference getHandelTypeTransferences (vk::VkExternalFenceHandleTypeFlagBitsKHR type) { switch (type) { case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR: case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR: return TRANSFERENCE_REFERENCE; case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR: return TRANSFERENCE_REFERENCE; case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR: return TRANSFERENCE_COPY; default: DE_FATAL("Unknown external fence type"); return TRANSFERENCE_REFERENCE; } }
static inline const char* getGeometryShaderOutputPrimitiveTypeShaderName (const TessPrimitiveType type, const bool usePointMode) { if (usePointMode) return "points"; switch (type) { case TESSPRIMITIVETYPE_TRIANGLES: case TESSPRIMITIVETYPE_QUADS: return "triangle_strip"; case TESSPRIMITIVETYPE_ISOLINES: return "line_strip"; default: DE_FATAL("Unexpected primitive type."); return DE_NULL; } }
bool isSupportedPermanence (vk::VkExternalFenceHandleTypeFlagBitsKHR type, Permanence permanence) { switch (type) { case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR: case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR: return permanence == PERMANENCE_PERMANENT || permanence == PERMANENCE_TEMPORARY; case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR: return permanence == PERMANENCE_PERMANENT || permanence == PERMANENCE_TEMPORARY; case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR: return permanence == PERMANENCE_TEMPORARY; default: DE_FATAL("Unknown external fence type"); return false; } }
const char* externalFenceTypeToName (vk::VkExternalFenceHandleTypeFlagBitsKHR type) { switch (type) { case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR: return "opaque_fd"; case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR: return "opaque_win32"; case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR: return "opaque_win32_kmt"; case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR: return "sync_fd"; default: DE_FATAL("Unknown external fence type"); return DE_NULL; } }
deUint32 getLayerDimensions (const ImageType imageType) { switch (imageType) { case IMAGE_TYPE_1D: case IMAGE_TYPE_BUFFER: case IMAGE_TYPE_1D_ARRAY: return 1u; case IMAGE_TYPE_2D: case IMAGE_TYPE_2D_ARRAY: case IMAGE_TYPE_CUBE: case IMAGE_TYPE_CUBE_ARRAY: return 2u; case IMAGE_TYPE_3D: return 3u; default: DE_FATAL("Unknown image type"); return 0u; } }
VkResult createSurface (const InstanceInterface& vki, VkInstance instance, Type wsiType, const Display& nativeDisplay, const Window& nativeWindow, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) { // Update this function if you add more WSI implementations DE_STATIC_ASSERT(TYPE_LAST == 7); switch (wsiType) { case TYPE_XLIB: { const XlibDisplayInterface& xlibDisplay = dynamic_cast<const XlibDisplayInterface&>(nativeDisplay); const XlibWindowInterface& xlibWindow = dynamic_cast<const XlibWindowInterface&>(nativeWindow); const VkXlibSurfaceCreateInfoKHR createInfo = { VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR, DE_NULL, (VkXlibSurfaceCreateFlagsKHR)0, xlibDisplay.getNative(), xlibWindow.getNative() }; return vki.createXlibSurfaceKHR(instance, &createInfo, pAllocator, pSurface); } case TYPE_XCB: { const XcbDisplayInterface& xcbDisplay = dynamic_cast<const XcbDisplayInterface&>(nativeDisplay); const XcbWindowInterface& xcbWindow = dynamic_cast<const XcbWindowInterface&>(nativeWindow); const VkXcbSurfaceCreateInfoKHR createInfo = { VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR, DE_NULL, (VkXcbSurfaceCreateFlagsKHR)0, xcbDisplay.getNative(), xcbWindow.getNative() }; return vki.createXcbSurfaceKHR(instance, &createInfo, pAllocator, pSurface); } case TYPE_WAYLAND: { const WaylandDisplayInterface& waylandDisplay = dynamic_cast<const WaylandDisplayInterface&>(nativeDisplay); const WaylandWindowInterface& waylandWindow = dynamic_cast<const WaylandWindowInterface&>(nativeWindow); const VkWaylandSurfaceCreateInfoKHR createInfo = { VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR, DE_NULL, (VkWaylandSurfaceCreateFlagsKHR)0, waylandDisplay.getNative(), waylandWindow.getNative() }; return vki.createWaylandSurfaceKHR(instance, &createInfo, pAllocator, pSurface); } case TYPE_MIR: { const MirDisplayInterface& mirDisplay = dynamic_cast<const MirDisplayInterface&>(nativeDisplay); const MirWindowInterface& mirWindow = dynamic_cast<const MirWindowInterface&>(nativeWindow); const VkMirSurfaceCreateInfoKHR createInfo = { VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR, DE_NULL, (VkXcbSurfaceCreateFlagsKHR)0, mirDisplay.getNative(), mirWindow.getNative() }; return vki.createMirSurfaceKHR(instance, &createInfo, pAllocator, pSurface); } case TYPE_ANDROID: { const AndroidWindowInterface& androidWindow = dynamic_cast<const AndroidWindowInterface&>(nativeWindow); const VkAndroidSurfaceCreateInfoKHR createInfo = { VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR, DE_NULL, (VkAndroidSurfaceCreateFlagsKHR)0, androidWindow.getNative() }; return vki.createAndroidSurfaceKHR(instance, &createInfo, pAllocator, pSurface); } case TYPE_WIN32: { const Win32DisplayInterface& win32Display = dynamic_cast<const Win32DisplayInterface&>(nativeDisplay); const Win32WindowInterface& win32Window = dynamic_cast<const Win32WindowInterface&>(nativeWindow); const VkWin32SurfaceCreateInfoKHR createInfo = { VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR, DE_NULL, (VkWin32SurfaceCreateFlagsKHR)0, win32Display.getNative(), win32Window.getNative() }; return vki.createWin32SurfaceKHR(instance, &createInfo, pAllocator, pSurface); } case TYPE_MACOS: { const MacOSWindowInterface& macOSWindow = dynamic_cast<const MacOSWindowInterface&>(nativeWindow); const VkMacOSSurfaceCreateInfoMVK createInfo = { VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK, DE_NULL, (VkMacOSSurfaceCreateFlagsMVK)0, macOSWindow.getNative() }; return vki.createMacOSSurfaceMVK(instance, &createInfo, pAllocator, pSurface); } default: DE_FATAL("Unknown WSI type"); return VK_ERROR_SURFACE_LOST_KHR; } }
static vk::Move<vk::VkDeviceMemory> importMemory (const vk::DeviceInterface& vkd, vk::VkDevice device, vk::VkBuffer buffer, vk::VkImage image, const vk::VkMemoryRequirements& requirements, vk::VkExternalMemoryHandleTypeFlagBitsKHR externalType, NativeHandle& handle) { const bool isDedicated = !!buffer || !!image; DE_ASSERT(!buffer || !image); if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR) { const vk::VkImportMemoryFdInfoKHR importInfo = { vk::VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR, DE_NULL, externalType, handle.getFd() }; const vk::VkMemoryDedicatedAllocateInfoKHR dedicatedInfo = { vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR, &importInfo, image, buffer, }; const vk::VkMemoryAllocateInfo info = { vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, (isDedicated ? (const void*)&dedicatedInfo : (const void*)&importInfo), requirements.size, chooseMemoryType(requirements.memoryTypeBits) }; vk::Move<vk::VkDeviceMemory> memory (vk::allocateMemory(vkd, device, &info)); handle.disown(); return memory; } else if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR || externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR) { const vk::VkImportMemoryWin32HandleInfoKHR importInfo = { vk::VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR, DE_NULL, externalType, handle.getWin32Handle(), DE_NULL }; const vk::VkMemoryDedicatedAllocateInfoKHR dedicatedInfo = { vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR, &importInfo, image, buffer, }; const vk::VkMemoryAllocateInfo info = { vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, (isDedicated ? (const void*)&dedicatedInfo : (const void*)&importInfo), requirements.size, chooseMemoryType(requirements.memoryTypeBits) }; vk::Move<vk::VkDeviceMemory> memory (vk::allocateMemory(vkd, device, &info)); handle.disown(); return memory; } else { DE_FATAL("Unknown external memory type"); return vk::Move<vk::VkDeviceMemory>(); } }