/* * Copyright (c) 2017, NVIDIA CORPORATION. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and/or associated documentation files (the * "Materials"), to deal in the Materials without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Materials, and to * permit persons to whom the Materials are furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * unaltered in all copies or substantial portions of the Materials. * Any additions, deletions, or changes to the original source files * must be clearly indicated in accompanying documentation. * * If only executable code is distributed, then the accompanying * documentation must state that "this software is based in part on the * work of the Khronos Group." * * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. */ #include #include #include #include #include #include #include #include "dummy/patchentrypoints.h" #define DUMMY_VENDOR_COUNT 3 #define NUM_GLDISPATCH_CALLS 2 static const char *GENERATED_FUNCTION_NAME = "glDummyTestGLVND"; enum { CALL_INDEX_STATIC, CALL_INDEX_GENERATED, CALL_INDEX_STATIC_PATCH, CALL_INDEX_GENERATED_PATCH, CALL_INDEX_COUNT }; typedef void (* pfn_glVertex3fv) (const GLfloat *v); typedef struct DummyVendorLibRec { pfn_glVertex3fv vertexProc; pfn_glVertex3fv testProc; __GLgetProcAddressCallback getProcCallback; __GLdispatchThreadState threadState; __GLdispatchTable *dispatch; int vendorID; const __GLdispatchPatchCallbacks *patchCallbacksPtr; __GLdispatchPatchCallbacks patchCallbacks; int callCounts[CALL_INDEX_COUNT]; } DummyVendorLib; static void InitDummyVendors(void); static void CleanupDummyVendors(void); static void *ForceMultiThreadedProc(void *param); static GLboolean TestDispatch(int vendorIndex, GLboolean testStatic, GLboolean testGenerated); static void *common_getProcAddressCallback(const char *procName, void *param, int vendorIndex); static GLboolean common_InitiatePatch(int type, int stubSize, DispatchPatchLookupStubOffset lookupStubOffset, int vendorIndex); static void *dummy0_getProcAddressCallback(const char *procName, void *param); static void dummy0_glVertex3fv(const GLfloat *v); static void dummy0_glDummyTestProc(const GLfloat *v); static GLboolean dummy0_InitiatePatch(int type, int stubSize, DispatchPatchLookupStubOffset lookupStubOffset); static void *dummy1_getProcAddressCallback(const char *procName, void *param); static void dummy1_glVertex3fv(const GLfloat *v); static void dummy1_glDummyTestProc(const GLfloat *v); static GLboolean dummy1_InitiatePatch(int type, int stubSize, DispatchPatchLookupStubOffset lookupStubOffset); static void *dummy2_getProcAddressCallback(const char *procName, void *param); static void dummy2_glVertex3fv(const GLfloat *v); static void dummy2_glDummyTestProc(const GLfloat *v); static DummyVendorLib dummyVendors[DUMMY_VENDOR_COUNT] = { { dummy0_glVertex3fv, dummy0_glDummyTestProc, dummy0_getProcAddressCallback }, { dummy1_glVertex3fv, dummy1_glDummyTestProc, dummy1_getProcAddressCallback }, { dummy2_glVertex3fv, dummy2_glDummyTestProc, dummy2_getProcAddressCallback }, }; static pfn_glVertex3fv ptr_glVertex3fv; static pfn_glVertex3fv ptr_glDummyTestProc; static GLboolean enableStaticTest = GL_FALSE; static GLboolean enableGeneratedTest = GL_FALSE; static GLboolean enablePatching = GL_FALSE; static GLboolean forceMultiThreaded = GL_FALSE; int main(int argc, char **argv) { int i; while (1) { int opt = getopt(argc, argv, "sgpt"); if (opt == -1) { break; } switch (opt) { case 's': enableStaticTest = GL_TRUE; break; case 'g': enableGeneratedTest = GL_TRUE; break; case 'p': enablePatching = GL_TRUE; break; case 't': forceMultiThreaded = GL_TRUE; break; default: return 1; } }; __glDispatchInit(); InitDummyVendors(); if (forceMultiThreaded) { pthread_t thr; printf("Forcing libGLdispatch into multi-threaded mode.\n"); __glDispatchCheckMultithreaded(); pthread_create(&thr, NULL, ForceMultiThreadedProc, NULL); pthread_join(thr, NULL); } ptr_glVertex3fv = (pfn_glVertex3fv) __glDispatchGetProcAddress("glVertex3fv"); if (ptr_glVertex3fv == NULL) { printf("Can't find dispatch function for glVertex3fv\n"); } if (enableGeneratedTest) { ptr_glDummyTestProc = (pfn_glVertex3fv) __glDispatchGetProcAddress(GENERATED_FUNCTION_NAME); if (ptr_glDummyTestProc == NULL) { printf("Can't find dispatch function for %s\n", GENERATED_FUNCTION_NAME); } } for (i=0; ivertexProc; } else if (strcmp(procName, GENERATED_FUNCTION_NAME) == 0) { return dummyVendor->testProc; } else { return NULL; } } static void *dummy0_getProcAddressCallback(const char *procName, void *param) { return common_getProcAddressCallback(procName, param, 0); } static void *dummy1_getProcAddressCallback(const char *procName, void *param) { return common_getProcAddressCallback(procName, param, 1); } static void *dummy2_getProcAddressCallback(const char *procName, void *param) { return common_getProcAddressCallback(procName, param, 2); } static void dummy0_glVertex3fv(const GLfloat *v) { dummyVendors[0].callCounts[CALL_INDEX_STATIC]++; } static void dummy1_glVertex3fv(const GLfloat *v) { dummyVendors[1].callCounts[CALL_INDEX_STATIC]++; } static void dummy2_glVertex3fv(const GLfloat *v) { dummyVendors[2].callCounts[CALL_INDEX_STATIC]++; } static void dummy0_glDummyTestProc(const GLfloat *v) { dummyVendors[0].callCounts[CALL_INDEX_GENERATED]++; } static void dummy1_glDummyTestProc(const GLfloat *v) { dummyVendors[1].callCounts[CALL_INDEX_GENERATED]++; } static void dummy2_glDummyTestProc(const GLfloat *v) { dummyVendors[2].callCounts[CALL_INDEX_GENERATED]++; } static GLboolean common_InitiatePatch(int type, int stubSize, DispatchPatchLookupStubOffset lookupStubOffset, int vendorIndex) { if (!dummyPatchFunction(type, stubSize, lookupStubOffset, "Vertex3fv", &dummyVendors[vendorIndex].callCounts[CALL_INDEX_STATIC_PATCH])) { return GL_FALSE; } if (enableGeneratedTest) { if (!dummyPatchFunction(type, stubSize, lookupStubOffset, GENERATED_FUNCTION_NAME, &dummyVendors[vendorIndex].callCounts[CALL_INDEX_GENERATED_PATCH])) { return GL_FALSE; } } return GL_TRUE; } static GLboolean dummy0_InitiatePatch(int type, int stubSize, DispatchPatchLookupStubOffset lookupStubOffset) { return common_InitiatePatch(type, stubSize, lookupStubOffset, 0); } static GLboolean dummy1_InitiatePatch(int type, int stubSize, DispatchPatchLookupStubOffset lookupStubOffset) { return common_InitiatePatch(type, stubSize, lookupStubOffset, 1); }