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"); }
Window::Window (Display& display, int width, int height, ::Visual* visual) : m_display (display) , m_colormap (None) , m_window (None) , m_visible (false) { XSetWindowAttributes swa; ::Display* const dpy = m_display.getXDisplay(); ::Window root = DefaultRootWindow(dpy); unsigned long mask = CWBorderPixel | CWEventMask; // If redirect is enabled, window size can't be guaranteed and it is up to // the window manager to decide whether to honor sizing requests. However, // overriding that causes window to appear as an overlay, which causes // other issues, so this is disabled by default. const bool overrideRedirect = false; if (overrideRedirect) { mask |= CWOverrideRedirect; swa.override_redirect = true; } if (visual == DE_NULL) visual = CopyFromParent; else { XVisualInfo info = XVisualInfo(); bool succ = display.getVisualInfo(XVisualIDFromVisual(visual), info); TCU_CHECK_INTERNAL(succ); root = RootWindow(dpy, info.screen); m_colormap = XCreateColormap(dpy, root, visual, AllocNone); swa.colormap = m_colormap; mask |= CWColormap; } swa.border_pixel = 0; swa.event_mask = ExposureMask|KeyPressMask|KeyReleaseMask|StructureNotifyMask; if (width == glu::RenderConfig::DONT_CARE) width = DEFAULT_WINDOW_WIDTH; if (height == glu::RenderConfig::DONT_CARE) height = DEFAULT_WINDOW_HEIGHT; m_window = XCreateWindow(dpy, root, 0, 0, width, height, 0, CopyFromParent, InputOutput, visual, mask, &swa); TCU_CHECK(m_window); Atom deleteAtom = m_display.getDeleteAtom(); XSetWMProtocols(dpy, m_window, &deleteAtom, 1); }
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"); }
Window::Window (Display& display, int width, int height, ::Visual* visual) : m_display (display) , m_colormap (None) , m_window (None) , m_visible (false) { XSetWindowAttributes swa; ::Display* dpy = m_display.getXDisplay(); ::Window root = DefaultRootWindow(dpy); unsigned long mask = CWBorderPixel | CWEventMask; if (visual == DE_NULL) visual = CopyFromParent; else { XVisualInfo info = XVisualInfo(); bool succ = display.getVisualInfo(XVisualIDFromVisual(visual), info); TCU_CHECK_INTERNAL(succ); root = RootWindow(dpy, info.screen); m_colormap = XCreateColormap(dpy, root, visual, AllocNone); swa.colormap = m_colormap; mask |= CWColormap; } swa.border_pixel = 0; swa.event_mask = ExposureMask|KeyPressMask|KeyReleaseMask|StructureNotifyMask; mask |= CWOverrideRedirect; swa.override_redirect = true; if (width == glu::RenderConfig::DONT_CARE) width = DEFAULT_WINDOW_WIDTH; if (height == glu::RenderConfig::DONT_CARE) height = DEFAULT_WINDOW_HEIGHT; m_window = XCreateWindow(dpy, root, 0, 0, width, height, 0, CopyFromParent, InputOutput, visual, mask, &swa); TCU_CHECK(m_window); Atom deleteAtom = m_display.getDeleteAtom(); XSetWMProtocols(dpy, m_window, &deleteAtom, 1); }
int getSemaphoreFd (const vk::DeviceInterface& vkd, vk::VkDevice device, vk::VkSemaphore semaphore, vk::VkExternalSemaphoreHandleTypeFlagBitsKHR externalType) { 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); return fd; }
int getFenceFd (const vk::DeviceInterface& vkd, vk::VkDevice device, vk::VkFence fence, vk::VkExternalFenceHandleTypeFlagBitsKHR externalType) { const vk::VkFenceGetFdInfoKHR info = { vk::VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR, DE_NULL, fence, externalType }; int fd = -1; VK_CHECK(vkd.getFenceFdKHR(device, &info, &fd)); TCU_CHECK(fd >= 0); return fd; }
int getMemoryFd (const vk::DeviceInterface& vkd, vk::VkDevice device, vk::VkDeviceMemory memory, vk::VkExternalMemoryHandleTypeFlagBitsKHR externalType) { const vk::VkMemoryGetFdInfoKHR info = { vk::VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR, DE_NULL, memory, externalType }; int fd = -1; VK_CHECK(vkd.getMemoryFdKHR(device, &info, &fd)); TCU_CHECK(fd >= 0); return fd; }
void parseTypePath (const char* nameWithPath, const VarType& type, TypeComponentVector& path) { VarTokenizer tokenizer(nameWithPath); if (tokenizer.getToken() == VarTokenizer::TOKEN_IDENTIFIER) tokenizer.advance(); path.clear(); while (tokenizer.getToken() != VarTokenizer::TOKEN_END) { VarType curType = getVarType(type, path); if (tokenizer.getToken() == VarTokenizer::TOKEN_PERIOD) { tokenizer.advance(); TCU_CHECK(tokenizer.getToken() == VarTokenizer::TOKEN_IDENTIFIER); TCU_CHECK_MSG(curType.isStructType(), "Invalid field selector"); // Find member. std::string memberName = tokenizer.getIdentifier(); int ndx = 0; for (; ndx < curType.getStructPtr()->getNumMembers(); ndx++) { if (memberName == curType.getStructPtr()->getMember(ndx).getName()) break; } TCU_CHECK_MSG(ndx < curType.getStructPtr()->getNumMembers(), "Member not found in type"); path.push_back(VarTypeComponent(VarTypeComponent::STRUCT_MEMBER, ndx)); tokenizer.advance(); } else if (tokenizer.getToken() == VarTokenizer::TOKEN_LEFT_BRACKET) { tokenizer.advance(); TCU_CHECK(tokenizer.getToken() == VarTokenizer::TOKEN_NUMBER); int ndx = tokenizer.getNumber(); if (curType.isArrayType()) { TCU_CHECK(de::inBounds(ndx, 0, curType.getArraySize())); path.push_back(VarTypeComponent(VarTypeComponent::ARRAY_ELEMENT, ndx)); } else if (curType.isBasicType() && isDataTypeMatrix(curType.getBasicType())) { TCU_CHECK(de::inBounds(ndx, 0, getDataTypeMatrixNumColumns(curType.getBasicType()))); path.push_back(VarTypeComponent(VarTypeComponent::MATRIX_COLUMN, ndx)); } else if (curType.isBasicType() && isDataTypeVector(curType.getBasicType())) { TCU_CHECK(de::inBounds(ndx, 0, getDataTypeScalarSize(curType.getBasicType()))); path.push_back(VarTypeComponent(VarTypeComponent::VECTOR_COMPONENT, ndx)); } else TCU_FAIL("Invalid subscript"); tokenizer.advance(); TCU_CHECK(tokenizer.getToken() == VarTokenizer::TOKEN_RIGHT_BRACKET); tokenizer.advance(); } else TCU_FAIL("Unexpected token"); } }
std::string parseVariableName (const char* nameWithPath) { VarTokenizer tokenizer(nameWithPath); TCU_CHECK(tokenizer.getToken() == VarTokenizer::TOKEN_IDENTIFIER); return tokenizer.getIdentifier(); }
void ReadPixelsTest::render (tcu::Texture2D& reference) { // Create program const char* vertexSource = "attribute mediump vec2 a_coord;\n" "void main (void)\n" "{\n" "\tgl_Position = vec4(a_coord, 0.0, 1.0);\n" "}\n"; const char* fragmentSource = "void main (void)\n" "{\n" "\tgl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);\n" "}\n"; glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(vertexSource, fragmentSource)); m_testCtx.getLog() << program; TCU_CHECK(program.isOk()); GLU_CHECK_CALL(glUseProgram(program.getProgram())); // Render { const float coords[] = { -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f }; GLuint coordLoc; coordLoc = glGetAttribLocation(program.getProgram(), "a_coord"); GLU_CHECK_MSG("glGetAttribLocation()"); GLU_CHECK_CALL(glEnableVertexAttribArray(coordLoc)); GLU_CHECK_CALL(glVertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, coords)); GLU_CHECK_CALL(glDrawArrays(GL_TRIANGLES, 0, 6)); GLU_CHECK_CALL(glDisableVertexAttribArray(coordLoc)); } // Render reference const int coordX1 = (int)((-0.5f * reference.getWidth() / 2.0f) + reference.getWidth() / 2.0f); const int coordY1 = (int)((-0.5f * reference.getHeight() / 2.0f) + reference.getHeight() / 2.0f); const int coordX2 = (int)(( 0.5f * reference.getWidth() / 2.0f) + reference.getWidth() / 2.0f); const int coordY2 = (int)(( 0.5f * reference.getHeight() / 2.0f) + reference.getHeight() / 2.0f); for (int x = 0; x < reference.getWidth(); x++) { if (x < coordX1 || x > coordX2) continue; for (int y = 0; y < reference.getHeight(); y++) { if (y >= coordY1 && y <= coordY2) reference.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), x, y); } } }
void RenderThread::run (void) { // Init state m_windowState = WINDOWSTATE_NOT_CREATED; m_paused = true; m_finish = false; try { while (!m_finish) { if (m_paused || m_windowState != WINDOWSTATE_READY) { // Block until we are not paused and window is ready. Message msg = m_msgQueue.popBack(); processMessage(msg); continue; } // Process available commands { Message msg; if (m_msgQueue.tryPopBack(msg)) { processMessage(msg); continue; } } DE_ASSERT(m_windowState == WINDOWSTATE_READY); // Process input events. // \todo [2013-05-08 pyry] What if system fills up the input queue before we have window ready? while (m_inputQueue && AInputQueue_hasEvents(m_inputQueue) > 0) { AInputEvent* event; TCU_CHECK(AInputQueue_getEvent(m_inputQueue, &event) >= 0); onInputEvent(event); AInputQueue_finishEvent(m_inputQueue, event, 1); } // Everything set up - safe to render. if (!render()) { DBG_PRINT(("RenderThread::run(): render\n")); break; } } } catch (const std::exception& e) { print("RenderThread: %s\n", e.what()); } // Tell activity to finish. DBG_PRINT(("RenderThread::run(): done, waiting for FINISH\n")); m_activity.finish(); // Thread must keep draining message queue until FINISH message is encountered. try { while (!m_finish) { Message msg = m_msgQueue.popBack(); // Ignore all but SYNC and FINISH messages. if (msg.type == MESSAGE_SYNC || msg.type == MESSAGE_FINISH) processMessage(msg); } } catch (const std::exception& e) { die("RenderThread: %s\n", e.what()); } DBG_PRINT(("RenderThread::run(): exiting...\n")); }