diff options
author | Jonathan Gray <jsg@cvs.openbsd.org> | 2015-11-22 02:46:45 +0000 |
---|---|---|
committer | Jonathan Gray <jsg@cvs.openbsd.org> | 2015-11-22 02:46:45 +0000 |
commit | 0784c49c0f8fcc8b3abd4c9286d9fd8bc089dd7d (patch) | |
tree | a6394e3e264a0f80b57f4ce0f5d9526aa543d4b0 /lib/mesa/src/gallium/state_trackers/wgl | |
parent | d91d0007eecf589ea5699e34aa4d748fce2c57b2 (diff) |
import Mesa 11.0.6
Diffstat (limited to 'lib/mesa/src/gallium/state_trackers/wgl')
29 files changed, 7026 insertions, 0 deletions
diff --git a/lib/mesa/src/gallium/state_trackers/wgl/Makefile.sources b/lib/mesa/src/gallium/state_trackers/wgl/Makefile.sources new file mode 100644 index 000000000..1e00caf97 --- /dev/null +++ b/lib/mesa/src/gallium/state_trackers/wgl/Makefile.sources @@ -0,0 +1,16 @@ +C_SOURCES := \ + stw_context.c \ + stw_device.c \ + stw_ext_context.c \ + stw_ext_extensionsstring.c \ + stw_ext_pbuffer.c \ + stw_ext_pixelformat.c \ + stw_ext_swapinterval.c \ + stw_framebuffer.c \ + stw_getprocaddress.c \ + stw_nopfuncs.c \ + stw_nopfuncs.h \ + stw_pixelformat.c \ + stw_st.c \ + stw_tls.c \ + stw_wgl.c diff --git a/lib/mesa/src/gallium/state_trackers/wgl/SConscript b/lib/mesa/src/gallium/state_trackers/wgl/SConscript new file mode 100644 index 000000000..6c604a0f2 --- /dev/null +++ b/lib/mesa/src/gallium/state_trackers/wgl/SConscript @@ -0,0 +1,26 @@ +import os + +Import('*') + +env = env.Clone() + +env.Append(CPPPATH = [ + '#src/mapi', + '#src/mesa', + '.', +]) + +env.AppendUnique(CPPDEFINES = [ + '_GDI32_', # prevent wgl* being declared __declspec(dllimport) + 'BUILD_GL32', # declare gl* as __declspec(dllexport) in Mesa headers + 'WIN32_LEAN_AND_MEAN', # http://msdn2.microsoft.com/en-us/library/6dwk3a1z.aspx +]) +if not env['gles']: + # prevent _glapi_* from being declared __declspec(dllimport) + env.Append(CPPDEFINES = ['_GLAPI_NO_EXPORTS']) + +wgl = env.ConvenienceLibrary( + target ='wgl', + source = env.ParseSourceList('Makefile.sources', 'C_SOURCES'), +) +Export('wgl') diff --git a/lib/mesa/src/gallium/state_trackers/wgl/opengl32.def b/lib/mesa/src/gallium/state_trackers/wgl/opengl32.def new file mode 100644 index 000000000..c35c23b55 --- /dev/null +++ b/lib/mesa/src/gallium/state_trackers/wgl/opengl32.def @@ -0,0 +1,388 @@ +EXPORTS +; GlmfBeginGlsBlock +; GlmfCloseMetaFile +; GlmfEndGlsBlock +; GlmfEndPlayback +; GlmfInitPlayback +; GlmfPlayGlsRecord + glAccum + glAlphaFunc + glAreTexturesResident + glArrayElement + glBegin + glBindTexture + glBitmap + glBlendFunc + glCallList + glCallLists + glClear + glClearAccum + glClearColor + glClearDepth + glClearIndex + glClearStencil + glClipPlane + glColor3b + glColor3bv + glColor3d + glColor3dv + glColor3f + glColor3fv + glColor3i + glColor3iv + glColor3s + glColor3sv + glColor3ub + glColor3ubv + glColor3ui + glColor3uiv + glColor3us + glColor3usv + glColor4b + glColor4bv + glColor4d + glColor4dv + glColor4f + glColor4fv + glColor4i + glColor4iv + glColor4s + glColor4sv + glColor4ub + glColor4ubv + glColor4ui + glColor4uiv + glColor4us + glColor4usv + glColorMask + glColorMaterial + glColorPointer + glCopyPixels + glCopyTexImage1D + glCopyTexImage2D + glCopyTexSubImage1D + glCopyTexSubImage2D + glCullFace +; glDebugEntry + glDeleteLists + glDeleteTextures + glDepthFunc + glDepthMask + glDepthRange + glDisable + glDisableClientState + glDrawArrays + glDrawBuffer + glDrawElements + glDrawPixels + glEdgeFlag + glEdgeFlagPointer + glEdgeFlagv + glEnable + glEnableClientState + glEnd + glEndList + glEvalCoord1d + glEvalCoord1dv + glEvalCoord1f + glEvalCoord1fv + glEvalCoord2d + glEvalCoord2dv + glEvalCoord2f + glEvalCoord2fv + glEvalMesh1 + glEvalMesh2 + glEvalPoint1 + glEvalPoint2 + glFeedbackBuffer + glFinish + glFlush + glFogf + glFogfv + glFogi + glFogiv + glFrontFace + glFrustum + glGenLists + glGenTextures + glGetBooleanv + glGetClipPlane + glGetDoublev + glGetError + glGetFloatv + glGetIntegerv + glGetLightfv + glGetLightiv + glGetMapdv + glGetMapfv + glGetMapiv + glGetMaterialfv + glGetMaterialiv + glGetPixelMapfv + glGetPixelMapuiv + glGetPixelMapusv + glGetPointerv + glGetPolygonStipple + glGetString + glGetTexEnvfv + glGetTexEnviv + glGetTexGendv + glGetTexGenfv + glGetTexGeniv + glGetTexImage + glGetTexLevelParameterfv + glGetTexLevelParameteriv + glGetTexParameterfv + glGetTexParameteriv + glHint + glIndexMask + glIndexPointer + glIndexd + glIndexdv + glIndexf + glIndexfv + glIndexi + glIndexiv + glIndexs + glIndexsv + glIndexub + glIndexubv + glInitNames + glInterleavedArrays + glIsEnabled + glIsList + glIsTexture + glLightModelf + glLightModelfv + glLightModeli + glLightModeliv + glLightf + glLightfv + glLighti + glLightiv + glLineStipple + glLineWidth + glListBase + glLoadIdentity + glLoadMatrixd + glLoadMatrixf + glLoadName + glLogicOp + glMap1d + glMap1f + glMap2d + glMap2f + glMapGrid1d + glMapGrid1f + glMapGrid2d + glMapGrid2f + glMaterialf + glMaterialfv + glMateriali + glMaterialiv + glMatrixMode + glMultMatrixd + glMultMatrixf + glNewList + glNormal3b + glNormal3bv + glNormal3d + glNormal3dv + glNormal3f + glNormal3fv + glNormal3i + glNormal3iv + glNormal3s + glNormal3sv + glNormalPointer + glOrtho + glPassThrough + glPixelMapfv + glPixelMapuiv + glPixelMapusv + glPixelStoref + glPixelStorei + glPixelTransferf + glPixelTransferi + glPixelZoom + glPointSize + glPolygonMode + glPolygonOffset + glPolygonStipple + glPopAttrib + glPopClientAttrib + glPopMatrix + glPopName + glPrioritizeTextures + glPushAttrib + glPushClientAttrib + glPushMatrix + glPushName + glRasterPos2d + glRasterPos2dv + glRasterPos2f + glRasterPos2fv + glRasterPos2i + glRasterPos2iv + glRasterPos2s + glRasterPos2sv + glRasterPos3d + glRasterPos3dv + glRasterPos3f + glRasterPos3fv + glRasterPos3i + glRasterPos3iv + glRasterPos3s + glRasterPos3sv + glRasterPos4d + glRasterPos4dv + glRasterPos4f + glRasterPos4fv + glRasterPos4i + glRasterPos4iv + glRasterPos4s + glRasterPos4sv + glReadBuffer + glReadPixels + glRectd + glRectdv + glRectf + glRectfv + glRecti + glRectiv + glRects + glRectsv + glRenderMode + glRotated + glRotatef + glScaled + glScalef + glScissor + glSelectBuffer + glShadeModel + glStencilFunc + glStencilMask + glStencilOp + glTexCoord1d + glTexCoord1dv + glTexCoord1f + glTexCoord1fv + glTexCoord1i + glTexCoord1iv + glTexCoord1s + glTexCoord1sv + glTexCoord2d + glTexCoord2dv + glTexCoord2f + glTexCoord2fv + glTexCoord2i + glTexCoord2iv + glTexCoord2s + glTexCoord2sv + glTexCoord3d + glTexCoord3dv + glTexCoord3f + glTexCoord3fv + glTexCoord3i + glTexCoord3iv + glTexCoord3s + glTexCoord3sv + glTexCoord4d + glTexCoord4dv + glTexCoord4f + glTexCoord4fv + glTexCoord4i + glTexCoord4iv + glTexCoord4s + glTexCoord4sv + glTexCoordPointer + glTexEnvf + glTexEnvfv + glTexEnvi + glTexEnviv + glTexGend + glTexGendv + glTexGenf + glTexGenfv + glTexGeni + glTexGeniv + glTexImage1D + glTexImage2D + glTexParameterf + glTexParameterfv + glTexParameteri + glTexParameteriv + glTexSubImage1D + glTexSubImage2D + glTranslated + glTranslatef + glVertex2d + glVertex2dv + glVertex2f + glVertex2fv + glVertex2i + glVertex2iv + glVertex2s + glVertex2sv + glVertex3d + glVertex3dv + glVertex3f + glVertex3fv + glVertex3i + glVertex3iv + glVertex3s + glVertex3sv + glVertex4d + glVertex4dv + glVertex4f + glVertex4fv + glVertex4i + glVertex4iv + glVertex4s + glVertex4sv + glVertexPointer + glViewport + wglChoosePixelFormat + wglCopyContext + wglCreateContext + wglCreateLayerContext + wglDeleteContext + wglDescribeLayerPlane + wglDescribePixelFormat + wglGetCurrentContext + wglGetCurrentDC +; wglGetDefaultProcAddress + wglGetLayerPaletteEntries + wglGetPixelFormat + wglGetProcAddress + wglMakeCurrent + wglRealizeLayerPalette + wglSetLayerPaletteEntries + wglSetPixelFormat + wglShareLists + wglSwapBuffers + wglSwapLayerBuffers + wglSwapMultipleBuffers + wglUseFontBitmapsA + wglUseFontBitmapsW + wglUseFontOutlinesA + wglUseFontOutlinesW + DrvCopyContext + DrvCreateContext + DrvCreateLayerContext + DrvDeleteContext + DrvDescribeLayerPlane + DrvDescribePixelFormat + DrvGetLayerPaletteEntries + DrvGetProcAddress + DrvPresentBuffers + DrvRealizeLayerPalette + DrvReleaseContext + DrvSetCallbackProcs + DrvSetContext + DrvSetLayerPaletteEntries + DrvSetPixelFormat + DrvShareLists + DrvSwapBuffers + DrvSwapLayerBuffers + DrvValidateVersion diff --git a/lib/mesa/src/gallium/state_trackers/wgl/opengl32.mingw.def b/lib/mesa/src/gallium/state_trackers/wgl/opengl32.mingw.def new file mode 100644 index 000000000..0bceee069 --- /dev/null +++ b/lib/mesa/src/gallium/state_trackers/wgl/opengl32.mingw.def @@ -0,0 +1,388 @@ +EXPORTS +; GlmfBeginGlsBlock = GlmfBeginGlsBlock@4 +; GlmfCloseMetaFile = GlmfCloseMetaFile@4 +; GlmfEndGlsBlock = GlmfEndGlsBlock@4 +; GlmfEndPlayback = GlmfEndPlayback@4 +; GlmfInitPlayback = GlmfInitPlayback@12 +; GlmfPlayGlsRecord = GlmfPlayGlsRecord@16 + glAccum = glAccum@8 + glAlphaFunc = glAlphaFunc@8 + glAreTexturesResident = glAreTexturesResident@12 + glArrayElement = glArrayElement@4 + glBegin = glBegin@4 + glBindTexture = glBindTexture@8 + glBitmap = glBitmap@28 + glBlendFunc = glBlendFunc@8 + glCallList = glCallList@4 + glCallLists = glCallLists@12 + glClear = glClear@4 + glClearAccum = glClearAccum@16 + glClearColor = glClearColor@16 + glClearDepth = glClearDepth@8 + glClearIndex = glClearIndex@4 + glClearStencil = glClearStencil@4 + glClipPlane = glClipPlane@8 + glColor3b = glColor3b@12 + glColor3bv = glColor3bv@4 + glColor3d = glColor3d@24 + glColor3dv = glColor3dv@4 + glColor3f = glColor3f@12 + glColor3fv = glColor3fv@4 + glColor3i = glColor3i@12 + glColor3iv = glColor3iv@4 + glColor3s = glColor3s@12 + glColor3sv = glColor3sv@4 + glColor3ub = glColor3ub@12 + glColor3ubv = glColor3ubv@4 + glColor3ui = glColor3ui@12 + glColor3uiv = glColor3uiv@4 + glColor3us = glColor3us@12 + glColor3usv = glColor3usv@4 + glColor4b = glColor4b@16 + glColor4bv = glColor4bv@4 + glColor4d = glColor4d@32 + glColor4dv = glColor4dv@4 + glColor4f = glColor4f@16 + glColor4fv = glColor4fv@4 + glColor4i = glColor4i@16 + glColor4iv = glColor4iv@4 + glColor4s = glColor4s@16 + glColor4sv = glColor4sv@4 + glColor4ub = glColor4ub@16 + glColor4ubv = glColor4ubv@4 + glColor4ui = glColor4ui@16 + glColor4uiv = glColor4uiv@4 + glColor4us = glColor4us@16 + glColor4usv = glColor4usv@4 + glColorMask = glColorMask@16 + glColorMaterial = glColorMaterial@8 + glColorPointer = glColorPointer@16 + glCopyPixels = glCopyPixels@20 + glCopyTexImage1D = glCopyTexImage1D@28 + glCopyTexImage2D = glCopyTexImage2D@32 + glCopyTexSubImage1D = glCopyTexSubImage1D@24 + glCopyTexSubImage2D = glCopyTexSubImage2D@32 + glCullFace = glCullFace@4 +; glDebugEntry = glDebugEntry@8 + glDeleteLists = glDeleteLists@8 + glDeleteTextures = glDeleteTextures@8 + glDepthFunc = glDepthFunc@4 + glDepthMask = glDepthMask@4 + glDepthRange = glDepthRange@16 + glDisable = glDisable@4 + glDisableClientState = glDisableClientState@4 + glDrawArrays = glDrawArrays@12 + glDrawBuffer = glDrawBuffer@4 + glDrawElements = glDrawElements@16 + glDrawPixels = glDrawPixels@20 + glEdgeFlag = glEdgeFlag@4 + glEdgeFlagPointer = glEdgeFlagPointer@8 + glEdgeFlagv = glEdgeFlagv@4 + glEnable = glEnable@4 + glEnableClientState = glEnableClientState@4 + glEnd = glEnd@0 + glEndList = glEndList@0 + glEvalCoord1d = glEvalCoord1d@8 + glEvalCoord1dv = glEvalCoord1dv@4 + glEvalCoord1f = glEvalCoord1f@4 + glEvalCoord1fv = glEvalCoord1fv@4 + glEvalCoord2d = glEvalCoord2d@16 + glEvalCoord2dv = glEvalCoord2dv@4 + glEvalCoord2f = glEvalCoord2f@8 + glEvalCoord2fv = glEvalCoord2fv@4 + glEvalMesh1 = glEvalMesh1@12 + glEvalMesh2 = glEvalMesh2@20 + glEvalPoint1 = glEvalPoint1@4 + glEvalPoint2 = glEvalPoint2@8 + glFeedbackBuffer = glFeedbackBuffer@12 + glFinish = glFinish@0 + glFlush = glFlush@0 + glFogf = glFogf@8 + glFogfv = glFogfv@8 + glFogi = glFogi@8 + glFogiv = glFogiv@8 + glFrontFace = glFrontFace@4 + glFrustum = glFrustum@48 + glGenLists = glGenLists@4 + glGenTextures = glGenTextures@8 + glGetBooleanv = glGetBooleanv@8 + glGetClipPlane = glGetClipPlane@8 + glGetDoublev = glGetDoublev@8 + glGetError = glGetError@0 + glGetFloatv = glGetFloatv@8 + glGetIntegerv = glGetIntegerv@8 + glGetLightfv = glGetLightfv@12 + glGetLightiv = glGetLightiv@12 + glGetMapdv = glGetMapdv@12 + glGetMapfv = glGetMapfv@12 + glGetMapiv = glGetMapiv@12 + glGetMaterialfv = glGetMaterialfv@12 + glGetMaterialiv = glGetMaterialiv@12 + glGetPixelMapfv = glGetPixelMapfv@8 + glGetPixelMapuiv = glGetPixelMapuiv@8 + glGetPixelMapusv = glGetPixelMapusv@8 + glGetPointerv = glGetPointerv@8 + glGetPolygonStipple = glGetPolygonStipple@4 + glGetString = glGetString@4 + glGetTexEnvfv = glGetTexEnvfv@12 + glGetTexEnviv = glGetTexEnviv@12 + glGetTexGendv = glGetTexGendv@12 + glGetTexGenfv = glGetTexGenfv@12 + glGetTexGeniv = glGetTexGeniv@12 + glGetTexImage = glGetTexImage@20 + glGetTexLevelParameterfv = glGetTexLevelParameterfv@16 + glGetTexLevelParameteriv = glGetTexLevelParameteriv@16 + glGetTexParameterfv = glGetTexParameterfv@12 + glGetTexParameteriv = glGetTexParameteriv@12 + glHint = glHint@8 + glIndexMask = glIndexMask@4 + glIndexPointer = glIndexPointer@12 + glIndexd = glIndexd@8 + glIndexdv = glIndexdv@4 + glIndexf = glIndexf@4 + glIndexfv = glIndexfv@4 + glIndexi = glIndexi@4 + glIndexiv = glIndexiv@4 + glIndexs = glIndexs@4 + glIndexsv = glIndexsv@4 + glIndexub = glIndexub@4 + glIndexubv = glIndexubv@4 + glInitNames = glInitNames@0 + glInterleavedArrays = glInterleavedArrays@12 + glIsEnabled = glIsEnabled@4 + glIsList = glIsList@4 + glIsTexture = glIsTexture@4 + glLightModelf = glLightModelf@8 + glLightModelfv = glLightModelfv@8 + glLightModeli = glLightModeli@8 + glLightModeliv = glLightModeliv@8 + glLightf = glLightf@12 + glLightfv = glLightfv@12 + glLighti = glLighti@12 + glLightiv = glLightiv@12 + glLineStipple = glLineStipple@8 + glLineWidth = glLineWidth@4 + glListBase = glListBase@4 + glLoadIdentity = glLoadIdentity@0 + glLoadMatrixd = glLoadMatrixd@4 + glLoadMatrixf = glLoadMatrixf@4 + glLoadName = glLoadName@4 + glLogicOp = glLogicOp@4 + glMap1d = glMap1d@32 + glMap1f = glMap1f@24 + glMap2d = glMap2d@56 + glMap2f = glMap2f@40 + glMapGrid1d = glMapGrid1d@20 + glMapGrid1f = glMapGrid1f@12 + glMapGrid2d = glMapGrid2d@40 + glMapGrid2f = glMapGrid2f@24 + glMaterialf = glMaterialf@12 + glMaterialfv = glMaterialfv@12 + glMateriali = glMateriali@12 + glMaterialiv = glMaterialiv@12 + glMatrixMode = glMatrixMode@4 + glMultMatrixd = glMultMatrixd@4 + glMultMatrixf = glMultMatrixf@4 + glNewList = glNewList@8 + glNormal3b = glNormal3b@12 + glNormal3bv = glNormal3bv@4 + glNormal3d = glNormal3d@24 + glNormal3dv = glNormal3dv@4 + glNormal3f = glNormal3f@12 + glNormal3fv = glNormal3fv@4 + glNormal3i = glNormal3i@12 + glNormal3iv = glNormal3iv@4 + glNormal3s = glNormal3s@12 + glNormal3sv = glNormal3sv@4 + glNormalPointer = glNormalPointer@12 + glOrtho = glOrtho@48 + glPassThrough = glPassThrough@4 + glPixelMapfv = glPixelMapfv@12 + glPixelMapuiv = glPixelMapuiv@12 + glPixelMapusv = glPixelMapusv@12 + glPixelStoref = glPixelStoref@8 + glPixelStorei = glPixelStorei@8 + glPixelTransferf = glPixelTransferf@8 + glPixelTransferi = glPixelTransferi@8 + glPixelZoom = glPixelZoom@8 + glPointSize = glPointSize@4 + glPolygonMode = glPolygonMode@8 + glPolygonOffset = glPolygonOffset@8 + glPolygonStipple = glPolygonStipple@4 + glPopAttrib = glPopAttrib@0 + glPopClientAttrib = glPopClientAttrib@0 + glPopMatrix = glPopMatrix@0 + glPopName = glPopName@0 + glPrioritizeTextures = glPrioritizeTextures@12 + glPushAttrib = glPushAttrib@4 + glPushClientAttrib = glPushClientAttrib@4 + glPushMatrix = glPushMatrix@0 + glPushName = glPushName@4 + glRasterPos2d = glRasterPos2d@16 + glRasterPos2dv = glRasterPos2dv@4 + glRasterPos2f = glRasterPos2f@8 + glRasterPos2fv = glRasterPos2fv@4 + glRasterPos2i = glRasterPos2i@8 + glRasterPos2iv = glRasterPos2iv@4 + glRasterPos2s = glRasterPos2s@8 + glRasterPos2sv = glRasterPos2sv@4 + glRasterPos3d = glRasterPos3d@24 + glRasterPos3dv = glRasterPos3dv@4 + glRasterPos3f = glRasterPos3f@12 + glRasterPos3fv = glRasterPos3fv@4 + glRasterPos3i = glRasterPos3i@12 + glRasterPos3iv = glRasterPos3iv@4 + glRasterPos3s = glRasterPos3s@12 + glRasterPos3sv = glRasterPos3sv@4 + glRasterPos4d = glRasterPos4d@32 + glRasterPos4dv = glRasterPos4dv@4 + glRasterPos4f = glRasterPos4f@16 + glRasterPos4fv = glRasterPos4fv@4 + glRasterPos4i = glRasterPos4i@16 + glRasterPos4iv = glRasterPos4iv@4 + glRasterPos4s = glRasterPos4s@16 + glRasterPos4sv = glRasterPos4sv@4 + glReadBuffer = glReadBuffer@4 + glReadPixels = glReadPixels@28 + glRectd = glRectd@32 + glRectdv = glRectdv@8 + glRectf = glRectf@16 + glRectfv = glRectfv@8 + glRecti = glRecti@16 + glRectiv = glRectiv@8 + glRects = glRects@16 + glRectsv = glRectsv@8 + glRenderMode = glRenderMode@4 + glRotated = glRotated@32 + glRotatef = glRotatef@16 + glScaled = glScaled@24 + glScalef = glScalef@12 + glScissor = glScissor@16 + glSelectBuffer = glSelectBuffer@8 + glShadeModel = glShadeModel@4 + glStencilFunc = glStencilFunc@12 + glStencilMask = glStencilMask@4 + glStencilOp = glStencilOp@12 + glTexCoord1d = glTexCoord1d@8 + glTexCoord1dv = glTexCoord1dv@4 + glTexCoord1f = glTexCoord1f@4 + glTexCoord1fv = glTexCoord1fv@4 + glTexCoord1i = glTexCoord1i@4 + glTexCoord1iv = glTexCoord1iv@4 + glTexCoord1s = glTexCoord1s@4 + glTexCoord1sv = glTexCoord1sv@4 + glTexCoord2d = glTexCoord2d@16 + glTexCoord2dv = glTexCoord2dv@4 + glTexCoord2f = glTexCoord2f@8 + glTexCoord2fv = glTexCoord2fv@4 + glTexCoord2i = glTexCoord2i@8 + glTexCoord2iv = glTexCoord2iv@4 + glTexCoord2s = glTexCoord2s@8 + glTexCoord2sv = glTexCoord2sv@4 + glTexCoord3d = glTexCoord3d@24 + glTexCoord3dv = glTexCoord3dv@4 + glTexCoord3f = glTexCoord3f@12 + glTexCoord3fv = glTexCoord3fv@4 + glTexCoord3i = glTexCoord3i@12 + glTexCoord3iv = glTexCoord3iv@4 + glTexCoord3s = glTexCoord3s@12 + glTexCoord3sv = glTexCoord3sv@4 + glTexCoord4d = glTexCoord4d@32 + glTexCoord4dv = glTexCoord4dv@4 + glTexCoord4f = glTexCoord4f@16 + glTexCoord4fv = glTexCoord4fv@4 + glTexCoord4i = glTexCoord4i@16 + glTexCoord4iv = glTexCoord4iv@4 + glTexCoord4s = glTexCoord4s@16 + glTexCoord4sv = glTexCoord4sv@4 + glTexCoordPointer = glTexCoordPointer@16 + glTexEnvf = glTexEnvf@12 + glTexEnvfv = glTexEnvfv@12 + glTexEnvi = glTexEnvi@12 + glTexEnviv = glTexEnviv@12 + glTexGend = glTexGend@16 + glTexGendv = glTexGendv@12 + glTexGenf = glTexGenf@12 + glTexGenfv = glTexGenfv@12 + glTexGeni = glTexGeni@12 + glTexGeniv = glTexGeniv@12 + glTexImage1D = glTexImage1D@32 + glTexImage2D = glTexImage2D@36 + glTexParameterf = glTexParameterf@12 + glTexParameterfv = glTexParameterfv@12 + glTexParameteri = glTexParameteri@12 + glTexParameteriv = glTexParameteriv@12 + glTexSubImage1D = glTexSubImage1D@28 + glTexSubImage2D = glTexSubImage2D@36 + glTranslated = glTranslated@24 + glTranslatef = glTranslatef@12 + glVertex2d = glVertex2d@16 + glVertex2dv = glVertex2dv@4 + glVertex2f = glVertex2f@8 + glVertex2fv = glVertex2fv@4 + glVertex2i = glVertex2i@8 + glVertex2iv = glVertex2iv@4 + glVertex2s = glVertex2s@8 + glVertex2sv = glVertex2sv@4 + glVertex3d = glVertex3d@24 + glVertex3dv = glVertex3dv@4 + glVertex3f = glVertex3f@12 + glVertex3fv = glVertex3fv@4 + glVertex3i = glVertex3i@12 + glVertex3iv = glVertex3iv@4 + glVertex3s = glVertex3s@12 + glVertex3sv = glVertex3sv@4 + glVertex4d = glVertex4d@32 + glVertex4dv = glVertex4dv@4 + glVertex4f = glVertex4f@16 + glVertex4fv = glVertex4fv@4 + glVertex4i = glVertex4i@16 + glVertex4iv = glVertex4iv@4 + glVertex4s = glVertex4s@16 + glVertex4sv = glVertex4sv@4 + glVertexPointer = glVertexPointer@16 + glViewport = glViewport@16 + wglChoosePixelFormat = wglChoosePixelFormat@8 + wglCopyContext = wglCopyContext@12 + wglCreateContext = wglCreateContext@4 + wglCreateLayerContext = wglCreateLayerContext@8 + wglDeleteContext = wglDeleteContext@4 + wglDescribeLayerPlane = wglDescribeLayerPlane@20 + wglDescribePixelFormat = wglDescribePixelFormat@16 + wglGetCurrentContext = wglGetCurrentContext@0 + wglGetCurrentDC = wglGetCurrentDC@0 +; wglGetDefaultProcAddress = wglGetDefaultProcAddress@4 + wglGetLayerPaletteEntries = wglGetLayerPaletteEntries@20 + wglGetPixelFormat = wglGetPixelFormat@4 + wglGetProcAddress = wglGetProcAddress@4 + wglMakeCurrent = wglMakeCurrent@8 + wglRealizeLayerPalette = wglRealizeLayerPalette@12 + wglSetLayerPaletteEntries = wglSetLayerPaletteEntries@20 + wglSetPixelFormat = wglSetPixelFormat@12 + wglShareLists = wglShareLists@8 + wglSwapBuffers = wglSwapBuffers@4 + wglSwapLayerBuffers = wglSwapLayerBuffers@8 + wglSwapMultipleBuffers = wglSwapMultipleBuffers@8 + wglUseFontBitmapsA = wglUseFontBitmapsA@16 + wglUseFontBitmapsW = wglUseFontBitmapsW@16 + wglUseFontOutlinesA = wglUseFontOutlinesA@32 + wglUseFontOutlinesW = wglUseFontOutlinesW@32 + DrvCopyContext = DrvCopyContext@12 + DrvCreateContext = DrvCreateContext@4 + DrvCreateLayerContext = DrvCreateLayerContext@8 + DrvDeleteContext = DrvDeleteContext@4 + DrvDescribeLayerPlane = DrvDescribeLayerPlane@20 + DrvDescribePixelFormat = DrvDescribePixelFormat@16 + DrvGetLayerPaletteEntries = DrvGetLayerPaletteEntries@20 + DrvGetProcAddress = DrvGetProcAddress@4 + DrvPresentBuffers = DrvPresentBuffers@8 + DrvRealizeLayerPalette = DrvRealizeLayerPalette@12 + DrvReleaseContext = DrvReleaseContext@4 + DrvSetCallbackProcs = DrvSetCallbackProcs@8 + DrvSetContext = DrvSetContext@12 + DrvSetLayerPaletteEntries = DrvSetLayerPaletteEntries@20 + DrvSetPixelFormat = DrvSetPixelFormat@8 + DrvShareLists = DrvShareLists@8 + DrvSwapBuffers = DrvSwapBuffers@4 + DrvSwapLayerBuffers = DrvSwapLayerBuffers@8 + DrvValidateVersion = DrvValidateVersion@4 diff --git a/lib/mesa/src/gallium/state_trackers/wgl/stw_context.c b/lib/mesa/src/gallium/state_trackers/wgl/stw_context.c new file mode 100644 index 000000000..3e99cc44d --- /dev/null +++ b/lib/mesa/src/gallium/state_trackers/wgl/stw_context.c @@ -0,0 +1,859 @@ +/************************************************************************** + * + * Copyright 2008 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS 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 + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include <windows.h> + +#define WGL_WGLEXT_PROTOTYPES + +#include <GL/gl.h> +#include <GL/wglext.h> + +#include "pipe/p_compiler.h" +#include "pipe/p_context.h" +#include "pipe/p_state.h" +#include "util/u_memory.h" +#include "util/u_atomic.h" +#include "state_tracker/st_api.h" +#include "hud/hud_context.h" + +#include "stw_icd.h" +#include "stw_device.h" +#include "stw_winsys.h" +#include "stw_framebuffer.h" +#include "stw_pixelformat.h" +#include "stw_context.h" +#include "stw_tls.h" + + +struct stw_context * +stw_current_context(void) +{ + struct st_context_iface *st; + + st = (stw_dev) ? stw_dev->stapi->get_current(stw_dev->stapi) : NULL; + + return (struct stw_context *) ((st) ? st->st_manager_private : NULL); +} + +BOOL APIENTRY +DrvCopyContext( + DHGLRC dhrcSource, + DHGLRC dhrcDest, + UINT fuMask ) +{ + struct stw_context *src; + struct stw_context *dst; + BOOL ret = FALSE; + + if (!stw_dev) + return FALSE; + + pipe_mutex_lock( stw_dev->ctx_mutex ); + + src = stw_lookup_context_locked( dhrcSource ); + dst = stw_lookup_context_locked( dhrcDest ); + + if (src && dst) { + /* FIXME */ + assert(0); + (void) src; + (void) dst; + (void) fuMask; + } + + pipe_mutex_unlock( stw_dev->ctx_mutex ); + + return ret; +} + +BOOL APIENTRY +DrvShareLists( + DHGLRC dhglrc1, + DHGLRC dhglrc2 ) +{ + struct stw_context *ctx1; + struct stw_context *ctx2; + BOOL ret = FALSE; + + if (!stw_dev) + return FALSE; + + pipe_mutex_lock( stw_dev->ctx_mutex ); + + ctx1 = stw_lookup_context_locked( dhglrc1 ); + ctx2 = stw_lookup_context_locked( dhglrc2 ); + + if (ctx1 && ctx2 && ctx2->st->share) + ret = ctx2->st->share(ctx2->st, ctx1->st); + + pipe_mutex_unlock( stw_dev->ctx_mutex ); + + return ret; +} + +DHGLRC APIENTRY +DrvCreateContext( + HDC hdc ) +{ + return DrvCreateLayerContext( hdc, 0 ); +} + +DHGLRC APIENTRY +DrvCreateLayerContext( + HDC hdc, + INT iLayerPlane ) +{ + return stw_create_context_attribs(hdc, iLayerPlane, 0, 1, 0, 0, + WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, + 0); +} + + +/** + * Called via DrvCreateContext(), DrvCreateLayerContext() and + * wglCreateContextAttribsARB() to actually create a rendering context. + * \param handle the desired DHGLRC handle to use for the context, or zero + * if a new handle should be allocated. + * \return the handle for the new context or zero if there was a problem. + */ +DHGLRC +stw_create_context_attribs(HDC hdc, INT iLayerPlane, DHGLRC hShareContext, + int majorVersion, int minorVersion, + int contextFlags, int profileMask, + DHGLRC handle) +{ + int iPixelFormat; + struct stw_framebuffer *fb; + const struct stw_pixelformat_info *pfi; + struct st_context_attribs attribs; + struct stw_context *ctx = NULL; + struct stw_context *shareCtx = NULL; + enum st_context_error ctx_err = 0; + + if (!stw_dev) + return 0; + + if (iLayerPlane != 0) + return 0; + + iPixelFormat = GetPixelFormat(hdc); + if(!iPixelFormat) + return 0; + + /* + * GDI only knows about displayable pixel formats, so determine the pixel + * format from the framebuffer. + * + * TODO: Remove the GetPixelFormat() above, and stop relying on GDI. + */ + fb = stw_framebuffer_from_hdc( hdc ); + if (fb) { + assert(iPixelFormat == fb->iDisplayablePixelFormat); + iPixelFormat = fb->iPixelFormat; + stw_framebuffer_release(fb); + } + + pfi = stw_pixelformat_get_info( iPixelFormat ); + + if (hShareContext != 0) { + pipe_mutex_lock( stw_dev->ctx_mutex ); + shareCtx = stw_lookup_context_locked( hShareContext ); + pipe_mutex_unlock( stw_dev->ctx_mutex ); + } + + ctx = CALLOC_STRUCT( stw_context ); + if (ctx == NULL) + goto no_ctx; + + ctx->hdc = hdc; + ctx->iPixelFormat = iPixelFormat; + + memset(&attribs, 0, sizeof(attribs)); + attribs.visual = pfi->stvis; + attribs.major = majorVersion; + attribs.minor = minorVersion; + if (contextFlags & WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB) + attribs.flags |= ST_CONTEXT_FLAG_FORWARD_COMPATIBLE; + if (contextFlags & WGL_CONTEXT_DEBUG_BIT_ARB) + attribs.flags |= ST_CONTEXT_FLAG_DEBUG; + + switch (profileMask) { + case WGL_CONTEXT_CORE_PROFILE_BIT_ARB: + /* There are no profiles before OpenGL 3.2. The + * WGL_ARB_create_context_profile spec says: + * + * "If the requested OpenGL version is less than 3.2, + * WGL_CONTEXT_PROFILE_MASK_ARB is ignored and the functionality + * of the context is determined solely by the requested version." + */ + if (majorVersion > 3 || (majorVersion == 3 && minorVersion >= 2)) { + attribs.profile = ST_PROFILE_OPENGL_CORE; + break; + } + /* fall-through */ + case WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB: + /* + * The spec also says: + * + * "If version 3.1 is requested, the context returned may implement + * any of the following versions: + * + * * Version 3.1. The GL_ARB_compatibility extension may or may not + * be implemented, as determined by the implementation. + * * The core profile of version 3.2 or greater." + * + * But Mesa doesn't support GL_ARB_compatibility, while most prevalent + * Windows OpenGL implementations do, and unfortunately many Windows + * applications don't check whether they receive or not a context with + * GL_ARB_compatibility, so returning a core profile here does more harm + * than good. + */ + attribs.profile = ST_PROFILE_DEFAULT; + break; + case WGL_CONTEXT_ES_PROFILE_BIT_EXT: + if (majorVersion >= 2) { + attribs.profile = ST_PROFILE_OPENGL_ES2; + } else { + attribs.profile = ST_PROFILE_OPENGL_ES1; + } + break; + default: + assert(0); + goto no_st_ctx; + } + + ctx->st = stw_dev->stapi->create_context(stw_dev->stapi, + stw_dev->smapi, &attribs, &ctx_err, shareCtx ? shareCtx->st : NULL); + if (ctx->st == NULL) + goto no_st_ctx; + + ctx->st->st_manager_private = (void *) ctx; + + if (ctx->st->cso_context) { + ctx->hud = hud_create(ctx->st->pipe, ctx->st->cso_context); + } + + pipe_mutex_lock( stw_dev->ctx_mutex ); + if (handle) { + /* We're replacing the context data for this handle. See the + * wglCreateContextAttribsARB() function. + */ + struct stw_context *old_ctx = + stw_lookup_context_locked((unsigned) handle); + if (old_ctx) { + /* free the old context data associated with this handle */ + if (old_ctx->hud) { + hud_destroy(old_ctx->hud); + } + ctx->st->destroy(old_ctx->st); + FREE(old_ctx); + } + + /* replace table entry */ + handle_table_set(stw_dev->ctx_table, (unsigned) handle, ctx); + } + else { + /* create new table entry */ + handle = (DHGLRC) handle_table_add(stw_dev->ctx_table, ctx); + } + + ctx->dhglrc = handle; + + pipe_mutex_unlock( stw_dev->ctx_mutex ); + if (!ctx->dhglrc) + goto no_hglrc; + + return ctx->dhglrc; + +no_hglrc: + if (ctx->hud) { + hud_destroy(ctx->hud); + } + ctx->st->destroy(ctx->st); +no_st_ctx: + FREE(ctx); +no_ctx: + return 0; +} + +BOOL APIENTRY +DrvDeleteContext( + DHGLRC dhglrc ) +{ + struct stw_context *ctx ; + BOOL ret = FALSE; + + if (!stw_dev) + return FALSE; + + pipe_mutex_lock( stw_dev->ctx_mutex ); + ctx = stw_lookup_context_locked(dhglrc); + handle_table_remove(stw_dev->ctx_table, dhglrc); + pipe_mutex_unlock( stw_dev->ctx_mutex ); + + if (ctx) { + struct stw_context *curctx = stw_current_context(); + + /* Unbind current if deleting current context. */ + if (curctx == ctx) + stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL); + + if (ctx->hud) { + hud_destroy(ctx->hud); + } + + ctx->st->destroy(ctx->st); + FREE(ctx); + + ret = TRUE; + } + + return ret; +} + +BOOL APIENTRY +DrvReleaseContext( + DHGLRC dhglrc ) +{ + struct stw_context *ctx; + + if (!stw_dev) + return FALSE; + + pipe_mutex_lock( stw_dev->ctx_mutex ); + ctx = stw_lookup_context_locked( dhglrc ); + pipe_mutex_unlock( stw_dev->ctx_mutex ); + + if (!ctx) + return FALSE; + + /* The expectation is that ctx is the same context which is + * current for this thread. We should check that and return False + * if not the case. + */ + if (ctx != stw_current_context()) + return FALSE; + + if (stw_make_current( NULL, 0 ) == FALSE) + return FALSE; + + return TRUE; +} + + +DHGLRC +stw_get_current_context( void ) +{ + struct stw_context *ctx; + + ctx = stw_current_context(); + if(!ctx) + return 0; + + return ctx->dhglrc; +} + +HDC +stw_get_current_dc( void ) +{ + struct stw_context *ctx; + + ctx = stw_current_context(); + if(!ctx) + return NULL; + + return ctx->hdc; +} + +BOOL +stw_make_current( + HDC hdc, + DHGLRC dhglrc ) +{ + struct stw_context *curctx = NULL; + struct stw_context *ctx = NULL; + struct stw_framebuffer *fb = NULL; + BOOL ret = FALSE; + + if (!stw_dev) + return FALSE; + + curctx = stw_current_context(); + if (curctx != NULL) { + if (curctx->dhglrc == dhglrc) { + if (curctx->hdc == hdc) { + /* Return if already current. */ + return TRUE; + } + } else { + curctx->st->flush(curctx->st, ST_FLUSH_FRONT, NULL); + } + } + + if (dhglrc) { + pipe_mutex_lock( stw_dev->ctx_mutex ); + ctx = stw_lookup_context_locked( dhglrc ); + pipe_mutex_unlock( stw_dev->ctx_mutex ); + if (!ctx) { + goto fail; + } + + fb = stw_framebuffer_from_hdc( hdc ); + if (fb) { + stw_framebuffer_update(fb); + } + else { + /* Applications should call SetPixelFormat before creating a context, + * but not all do, and the opengl32 runtime seems to use a default pixel + * format in some cases, so we must create a framebuffer for those here + */ + int iPixelFormat = GetPixelFormat(hdc); + if (iPixelFormat) + fb = stw_framebuffer_create( hdc, iPixelFormat ); + if (!fb) + goto fail; + } + + if (fb->iPixelFormat != ctx->iPixelFormat) { + SetLastError(ERROR_INVALID_PIXEL_FORMAT); + goto fail; + } + + /* Bind the new framebuffer */ + ctx->hdc = hdc; + + ret = stw_dev->stapi->make_current(stw_dev->stapi, ctx->st, + fb->stfb, fb->stfb); + stw_framebuffer_reference(&ctx->current_framebuffer, fb); + } else { + ret = stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL); + } + +fail: + + if (fb) { + stw_framebuffer_release(fb); + } + + /* On failure, make the thread's current rendering context not current + * before returning */ + if (!ret) { + stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL); + ctx = NULL; + } + + /* Unreference the previous framebuffer if any. It must be done after + * make_current, as it can be referenced inside. + */ + if (curctx && curctx != ctx) { + stw_framebuffer_reference(&curctx->current_framebuffer, NULL); + } + + return ret; +} + +/** + * Flush the current context if it is bound to the framebuffer. + */ +void +stw_flush_current_locked( struct stw_framebuffer *fb ) +{ + struct stw_context *ctx = stw_current_context(); + + if (ctx && ctx->current_framebuffer == fb) { + ctx->st->flush(ctx->st, ST_FLUSH_FRONT, NULL); + } +} + +/** + * Notify the current context that the framebuffer has become invalid. + */ +void +stw_notify_current_locked( struct stw_framebuffer *fb ) +{ + p_atomic_inc(&fb->stfb->stamp); +} + +/** + * Although WGL allows different dispatch entrypoints per context + */ +static const GLCLTPROCTABLE cpt = +{ + OPENGL_VERSION_110_ENTRIES, + { + &glNewList, + &glEndList, + &glCallList, + &glCallLists, + &glDeleteLists, + &glGenLists, + &glListBase, + &glBegin, + &glBitmap, + &glColor3b, + &glColor3bv, + &glColor3d, + &glColor3dv, + &glColor3f, + &glColor3fv, + &glColor3i, + &glColor3iv, + &glColor3s, + &glColor3sv, + &glColor3ub, + &glColor3ubv, + &glColor3ui, + &glColor3uiv, + &glColor3us, + &glColor3usv, + &glColor4b, + &glColor4bv, + &glColor4d, + &glColor4dv, + &glColor4f, + &glColor4fv, + &glColor4i, + &glColor4iv, + &glColor4s, + &glColor4sv, + &glColor4ub, + &glColor4ubv, + &glColor4ui, + &glColor4uiv, + &glColor4us, + &glColor4usv, + &glEdgeFlag, + &glEdgeFlagv, + &glEnd, + &glIndexd, + &glIndexdv, + &glIndexf, + &glIndexfv, + &glIndexi, + &glIndexiv, + &glIndexs, + &glIndexsv, + &glNormal3b, + &glNormal3bv, + &glNormal3d, + &glNormal3dv, + &glNormal3f, + &glNormal3fv, + &glNormal3i, + &glNormal3iv, + &glNormal3s, + &glNormal3sv, + &glRasterPos2d, + &glRasterPos2dv, + &glRasterPos2f, + &glRasterPos2fv, + &glRasterPos2i, + &glRasterPos2iv, + &glRasterPos2s, + &glRasterPos2sv, + &glRasterPos3d, + &glRasterPos3dv, + &glRasterPos3f, + &glRasterPos3fv, + &glRasterPos3i, + &glRasterPos3iv, + &glRasterPos3s, + &glRasterPos3sv, + &glRasterPos4d, + &glRasterPos4dv, + &glRasterPos4f, + &glRasterPos4fv, + &glRasterPos4i, + &glRasterPos4iv, + &glRasterPos4s, + &glRasterPos4sv, + &glRectd, + &glRectdv, + &glRectf, + &glRectfv, + &glRecti, + &glRectiv, + &glRects, + &glRectsv, + &glTexCoord1d, + &glTexCoord1dv, + &glTexCoord1f, + &glTexCoord1fv, + &glTexCoord1i, + &glTexCoord1iv, + &glTexCoord1s, + &glTexCoord1sv, + &glTexCoord2d, + &glTexCoord2dv, + &glTexCoord2f, + &glTexCoord2fv, + &glTexCoord2i, + &glTexCoord2iv, + &glTexCoord2s, + &glTexCoord2sv, + &glTexCoord3d, + &glTexCoord3dv, + &glTexCoord3f, + &glTexCoord3fv, + &glTexCoord3i, + &glTexCoord3iv, + &glTexCoord3s, + &glTexCoord3sv, + &glTexCoord4d, + &glTexCoord4dv, + &glTexCoord4f, + &glTexCoord4fv, + &glTexCoord4i, + &glTexCoord4iv, + &glTexCoord4s, + &glTexCoord4sv, + &glVertex2d, + &glVertex2dv, + &glVertex2f, + &glVertex2fv, + &glVertex2i, + &glVertex2iv, + &glVertex2s, + &glVertex2sv, + &glVertex3d, + &glVertex3dv, + &glVertex3f, + &glVertex3fv, + &glVertex3i, + &glVertex3iv, + &glVertex3s, + &glVertex3sv, + &glVertex4d, + &glVertex4dv, + &glVertex4f, + &glVertex4fv, + &glVertex4i, + &glVertex4iv, + &glVertex4s, + &glVertex4sv, + &glClipPlane, + &glColorMaterial, + &glCullFace, + &glFogf, + &glFogfv, + &glFogi, + &glFogiv, + &glFrontFace, + &glHint, + &glLightf, + &glLightfv, + &glLighti, + &glLightiv, + &glLightModelf, + &glLightModelfv, + &glLightModeli, + &glLightModeliv, + &glLineStipple, + &glLineWidth, + &glMaterialf, + &glMaterialfv, + &glMateriali, + &glMaterialiv, + &glPointSize, + &glPolygonMode, + &glPolygonStipple, + &glScissor, + &glShadeModel, + &glTexParameterf, + &glTexParameterfv, + &glTexParameteri, + &glTexParameteriv, + &glTexImage1D, + &glTexImage2D, + &glTexEnvf, + &glTexEnvfv, + &glTexEnvi, + &glTexEnviv, + &glTexGend, + &glTexGendv, + &glTexGenf, + &glTexGenfv, + &glTexGeni, + &glTexGeniv, + &glFeedbackBuffer, + &glSelectBuffer, + &glRenderMode, + &glInitNames, + &glLoadName, + &glPassThrough, + &glPopName, + &glPushName, + &glDrawBuffer, + &glClear, + &glClearAccum, + &glClearIndex, + &glClearColor, + &glClearStencil, + &glClearDepth, + &glStencilMask, + &glColorMask, + &glDepthMask, + &glIndexMask, + &glAccum, + &glDisable, + &glEnable, + &glFinish, + &glFlush, + &glPopAttrib, + &glPushAttrib, + &glMap1d, + &glMap1f, + &glMap2d, + &glMap2f, + &glMapGrid1d, + &glMapGrid1f, + &glMapGrid2d, + &glMapGrid2f, + &glEvalCoord1d, + &glEvalCoord1dv, + &glEvalCoord1f, + &glEvalCoord1fv, + &glEvalCoord2d, + &glEvalCoord2dv, + &glEvalCoord2f, + &glEvalCoord2fv, + &glEvalMesh1, + &glEvalPoint1, + &glEvalMesh2, + &glEvalPoint2, + &glAlphaFunc, + &glBlendFunc, + &glLogicOp, + &glStencilFunc, + &glStencilOp, + &glDepthFunc, + &glPixelZoom, + &glPixelTransferf, + &glPixelTransferi, + &glPixelStoref, + &glPixelStorei, + &glPixelMapfv, + &glPixelMapuiv, + &glPixelMapusv, + &glReadBuffer, + &glCopyPixels, + &glReadPixels, + &glDrawPixels, + &glGetBooleanv, + &glGetClipPlane, + &glGetDoublev, + &glGetError, + &glGetFloatv, + &glGetIntegerv, + &glGetLightfv, + &glGetLightiv, + &glGetMapdv, + &glGetMapfv, + &glGetMapiv, + &glGetMaterialfv, + &glGetMaterialiv, + &glGetPixelMapfv, + &glGetPixelMapuiv, + &glGetPixelMapusv, + &glGetPolygonStipple, + &glGetString, + &glGetTexEnvfv, + &glGetTexEnviv, + &glGetTexGendv, + &glGetTexGenfv, + &glGetTexGeniv, + &glGetTexImage, + &glGetTexParameterfv, + &glGetTexParameteriv, + &glGetTexLevelParameterfv, + &glGetTexLevelParameteriv, + &glIsEnabled, + &glIsList, + &glDepthRange, + &glFrustum, + &glLoadIdentity, + &glLoadMatrixf, + &glLoadMatrixd, + &glMatrixMode, + &glMultMatrixf, + &glMultMatrixd, + &glOrtho, + &glPopMatrix, + &glPushMatrix, + &glRotated, + &glRotatef, + &glScaled, + &glScalef, + &glTranslated, + &glTranslatef, + &glViewport, + &glArrayElement, + &glBindTexture, + &glColorPointer, + &glDisableClientState, + &glDrawArrays, + &glDrawElements, + &glEdgeFlagPointer, + &glEnableClientState, + &glIndexPointer, + &glIndexub, + &glIndexubv, + &glInterleavedArrays, + &glNormalPointer, + &glPolygonOffset, + &glTexCoordPointer, + &glVertexPointer, + &glAreTexturesResident, + &glCopyTexImage1D, + &glCopyTexImage2D, + &glCopyTexSubImage1D, + &glCopyTexSubImage2D, + &glDeleteTextures, + &glGenTextures, + &glGetPointerv, + &glIsTexture, + &glPrioritizeTextures, + &glTexSubImage1D, + &glTexSubImage2D, + &glPopClientAttrib, + &glPushClientAttrib + } +}; + +PGLCLTPROCTABLE APIENTRY +DrvSetContext( + HDC hdc, + DHGLRC dhglrc, + PFN_SETPROCTABLE pfnSetProcTable ) +{ + PGLCLTPROCTABLE r = (PGLCLTPROCTABLE)&cpt; + + if (!stw_make_current( hdc, dhglrc )) + r = NULL; + + return r; +} diff --git a/lib/mesa/src/gallium/state_trackers/wgl/stw_context.h b/lib/mesa/src/gallium/state_trackers/wgl/stw_context.h new file mode 100644 index 000000000..c66c166de --- /dev/null +++ b/lib/mesa/src/gallium/state_trackers/wgl/stw_context.h @@ -0,0 +1,66 @@ +/************************************************************************** + * + * Copyright 2008 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS 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 + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef STW_CONTEXT_H +#define STW_CONTEXT_H + +#include <windows.h> + +struct hud_context; +struct stw_framebuffer; +struct st_context_iface; + +struct stw_context +{ + struct st_context_iface *st; + DHGLRC dhglrc; + int iPixelFormat; + HDC hdc; + + struct stw_framebuffer *current_framebuffer; + + struct hud_context *hud; +}; + +DHGLRC stw_create_context_attribs(HDC hdc, INT iLayerPlane, + DHGLRC hShareContext, + int majorVersion, int minorVersion, + int contextFlags, int profileMask, + DHGLRC handle); + +DHGLRC stw_get_current_context( void ); + +struct stw_context *stw_current_context(void); + +HDC stw_get_current_dc( void ); + +BOOL stw_make_current( HDC hdc, DHGLRC dhglrc ); + +void stw_flush_current_locked( struct stw_framebuffer *fb ); +void stw_notify_current_locked( struct stw_framebuffer *fb ); + +#endif /* STW_CONTEXT_H */ diff --git a/lib/mesa/src/gallium/state_trackers/wgl/stw_device.c b/lib/mesa/src/gallium/state_trackers/wgl/stw_device.c new file mode 100644 index 000000000..25b6341ec --- /dev/null +++ b/lib/mesa/src/gallium/state_trackers/wgl/stw_device.c @@ -0,0 +1,226 @@ +/************************************************************************** + * + * Copyright 2008 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS 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 + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include <windows.h> + +#include "glapi/glapi.h" +#include "util/u_debug.h" +#include "util/u_math.h" +#include "util/u_memory.h" +#include "pipe/p_screen.h" + +#include "stw_device.h" +#include "stw_winsys.h" +#include "stw_pixelformat.h" +#include "stw_icd.h" +#include "stw_tls.h" +#include "stw_framebuffer.h" +#include "stw_st.h" + + +struct stw_device *stw_dev = NULL; + +static int +stw_get_param(struct st_manager *smapi, + enum st_manager_param param) +{ + switch (param) { + case ST_MANAGER_BROKEN_INVALIDATE: + /* + * Force framebuffer validation on glViewport. + * + * Certain applications, like Rhinoceros 4, uses glReadPixels + * exclusively (never uses SwapBuffers), so framebuffers never get + * resized unless we check on glViewport. + */ + return 1; + default: + return 0; + } +} + +boolean +stw_init(const struct stw_winsys *stw_winsys) +{ + static struct stw_device stw_dev_storage; + struct pipe_screen *screen; + + debug_disable_error_message_boxes(); + + debug_printf("%s\n", __FUNCTION__); + + assert(!stw_dev); + + stw_tls_init(); + + stw_dev = &stw_dev_storage; + memset(stw_dev, 0, sizeof(*stw_dev)); + +#ifdef DEBUG + stw_dev->memdbg_no = debug_memory_begin(); +#endif + + stw_dev->stw_winsys = stw_winsys; + + stw_dev->stapi = stw_st_create_api(); + stw_dev->smapi = CALLOC_STRUCT(st_manager); + if (!stw_dev->stapi || !stw_dev->smapi) + goto error1; + + screen = stw_winsys->create_screen(); + if(!screen) + goto error1; + + if(stw_winsys->get_adapter_luid) + stw_winsys->get_adapter_luid(screen, &stw_dev->AdapterLuid); + + stw_dev->smapi->screen = screen; + stw_dev->smapi->get_param = stw_get_param; + stw_dev->screen = screen; + + stw_dev->max_2d_levels = + screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS); + stw_dev->max_2d_length = 1 << (stw_dev->max_2d_levels - 1); + + pipe_mutex_init( stw_dev->ctx_mutex ); + pipe_mutex_init( stw_dev->fb_mutex ); + + stw_dev->ctx_table = handle_table_create(); + if (!stw_dev->ctx_table) { + goto error1; + } + + stw_pixelformat_init(); + + return TRUE; + +error1: + FREE(stw_dev->smapi); + if (stw_dev->stapi) + stw_dev->stapi->destroy(stw_dev->stapi); + + stw_dev = NULL; + return FALSE; +} + + +boolean +stw_init_thread(void) +{ + return stw_tls_init_thread(); +} + + +void +stw_cleanup_thread(void) +{ + stw_tls_cleanup_thread(); +} + + +void +stw_cleanup(void) +{ + DHGLRC dhglrc; + + debug_printf("%s\n", __FUNCTION__); + + if (!stw_dev) + return; + + /* + * Abort cleanup if there are still active contexts. In some situations + * this DLL may be unloaded before the DLL that is using GL contexts is. + */ + pipe_mutex_lock( stw_dev->ctx_mutex ); + dhglrc = handle_table_get_first_handle(stw_dev->ctx_table); + pipe_mutex_unlock( stw_dev->ctx_mutex ); + if (dhglrc) { + debug_printf("%s: contexts still active -- cleanup aborted\n", __FUNCTION__); + stw_dev = NULL; + return; + } + + handle_table_destroy(stw_dev->ctx_table); + + stw_framebuffer_cleanup(); + + pipe_mutex_destroy( stw_dev->fb_mutex ); + pipe_mutex_destroy( stw_dev->ctx_mutex ); + + FREE(stw_dev->smapi); + stw_dev->stapi->destroy(stw_dev->stapi); + + stw_dev->screen->destroy(stw_dev->screen); + + /* glapi is statically linked: we can call the local destroy function. */ +#ifdef _GLAPI_NO_EXPORTS + _glapi_destroy_multithread(); +#endif + +#ifdef DEBUG + debug_memory_end(stw_dev->memdbg_no); +#endif + + stw_tls_cleanup(); + + stw_dev = NULL; +} + + +void APIENTRY +DrvSetCallbackProcs( + INT nProcs, + PROC *pProcs ) +{ + size_t size; + + if (stw_dev == NULL) + return; + + size = MIN2(nProcs * sizeof *pProcs, sizeof stw_dev->callbacks); + memcpy(&stw_dev->callbacks, pProcs, size); + + return; +} + + +BOOL APIENTRY +DrvValidateVersion( + ULONG ulVersion ) +{ + /* ulVersion is the version reported by the KMD: + * - via D3DKMTQueryAdapterInfo(KMTQAITYPE_UMOPENGLINFO) on WDDM, + * - or ExtEscape on XPDM and can be used to ensure the KMD and OpenGL ICD + * versions match. + * + * We should get the expected version number from the winsys, but for now + * ignore it. + */ + (void)ulVersion; + return TRUE; +} diff --git a/lib/mesa/src/gallium/state_trackers/wgl/stw_device.h b/lib/mesa/src/gallium/state_trackers/wgl/stw_device.h new file mode 100644 index 000000000..e35a4b940 --- /dev/null +++ b/lib/mesa/src/gallium/state_trackers/wgl/stw_device.h @@ -0,0 +1,92 @@ +/************************************************************************** + * + * Copyright 2008 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS 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 + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef STW_DEVICE_H_ +#define STW_DEVICE_H_ + + +#include "pipe/p_compiler.h" +#include "os/os_thread.h" +#include "util/u_handle_table.h" +#include "stw_icd.h" +#include "stw_pixelformat.h" + + +#define STW_MAX_PIXELFORMATS 256 + + +struct pipe_screen; +struct st_api; +struct st_manager; +struct stw_framebuffer; + +struct stw_device +{ + const struct stw_winsys *stw_winsys; + + struct pipe_screen *screen; + + /* Cache some PIPE_CAP_* */ + unsigned max_2d_levels; + unsigned max_2d_length; + + struct st_api *stapi; + struct st_manager *smapi; + + LUID AdapterLuid; + + struct stw_pixelformat_info pixelformats[STW_MAX_PIXELFORMATS]; + unsigned pixelformat_count; + unsigned pixelformat_extended_count; + + GLCALLBACKTABLE callbacks; + + pipe_mutex ctx_mutex; + struct handle_table *ctx_table; + + pipe_mutex fb_mutex; + struct stw_framebuffer *fb_head; + +#ifdef DEBUG + unsigned long memdbg_no; +#endif +}; + + +extern struct stw_device *stw_dev; + + +static inline struct stw_context * +stw_lookup_context_locked( DHGLRC dhglrc ) +{ + if (dhglrc == 0 || stw_dev == NULL) + return NULL; + return (struct stw_context *) handle_table_get(stw_dev->ctx_table, dhglrc); +} + + +#endif /* STW_DEVICE_H_ */ diff --git a/lib/mesa/src/gallium/state_trackers/wgl/stw_ext_context.c b/lib/mesa/src/gallium/state_trackers/wgl/stw_ext_context.c new file mode 100644 index 000000000..6af206273 --- /dev/null +++ b/lib/mesa/src/gallium/state_trackers/wgl/stw_ext_context.c @@ -0,0 +1,195 @@ +/* + * Mesa 3-D graphics library + * + * Copyright (C) 2011 Morgan Armand <morgan.devel@gmail.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS 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 SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include <stdio.h> +#include <windows.h> + +#define WGL_WGLEXT_PROTOTYPES + +#include <GL/gl.h> +#include <GL/wglext.h> + +#include "stw_icd.h" +#include "stw_context.h" +#include "stw_device.h" +#include "stw_ext_context.h" + + +wglCreateContext_t wglCreateContext_func = 0; +wglDeleteContext_t wglDeleteContext_func = 0; + + +/** + * The implementation of this function is tricky. The OPENGL32.DLL library + * remaps the context IDs returned by our stw_create_context_attribs() + * function to different values returned to the caller of wglCreateContext(). + * That is, DHGLRC (driver) handles are not equivalent to HGLRC (public) + * handles. + * + * So we need to generate a new HGLRC ID here. We do that by calling + * the regular wglCreateContext() function. Then, we replace the newly- + * created stw_context with a new stw_context that reflects the arguments + * to this function. + */ +HGLRC WINAPI +wglCreateContextAttribsARB(HDC hDC, HGLRC hShareContext, const int *attribList) +{ + HGLRC context; + + int majorVersion = 1, minorVersion = 0, layerPlane = 0; + int contextFlags = 0x0; + int profileMask = WGL_CONTEXT_CORE_PROFILE_BIT_ARB; + int i; + BOOL done = FALSE; + const int contextFlagsAll = (WGL_CONTEXT_DEBUG_BIT_ARB | + WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB); + + /* parse attrib_list */ + if (attribList) { + for (i = 0; !done && attribList[i]; i++) { + switch (attribList[i]) { + case WGL_CONTEXT_MAJOR_VERSION_ARB: + majorVersion = attribList[++i]; + break; + case WGL_CONTEXT_MINOR_VERSION_ARB: + minorVersion = attribList[++i]; + break; + case WGL_CONTEXT_LAYER_PLANE_ARB: + layerPlane = attribList[++i]; + break; + case WGL_CONTEXT_FLAGS_ARB: + contextFlags = attribList[++i]; + break; + case WGL_CONTEXT_PROFILE_MASK_ARB: + profileMask = attribList[++i]; + break; + case 0: + /* end of list */ + done = TRUE; + break; + default: + /* bad attribute */ + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + } + } + } + + /* check contextFlags */ + if (contextFlags & ~contextFlagsAll) { + SetLastError(ERROR_INVALID_PARAMETER); + return NULL; + } + + /* check profileMask */ + if (profileMask != WGL_CONTEXT_CORE_PROFILE_BIT_ARB && + profileMask != WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB && + profileMask != WGL_CONTEXT_ES_PROFILE_BIT_EXT) { + SetLastError(ERROR_INVALID_PROFILE_ARB); + return NULL; + } + + /* check version (generate ERROR_INVALID_VERSION_ARB if bad) */ + if (majorVersion <= 0 || + minorVersion < 0 || + (profileMask != WGL_CONTEXT_ES_PROFILE_BIT_EXT && + ((majorVersion == 1 && minorVersion > 5) || + (majorVersion == 2 && minorVersion > 1) || + (majorVersion == 3 && minorVersion > 3) || + (majorVersion == 4 && minorVersion > 5) || + majorVersion > 4)) || + (profileMask == WGL_CONTEXT_ES_PROFILE_BIT_EXT && + ((majorVersion == 1 && minorVersion > 1) || + (majorVersion == 2 && minorVersion > 0) || + (majorVersion == 3 && minorVersion > 1) || + majorVersion > 3))) { + SetLastError(ERROR_INVALID_VERSION_ARB); + return NULL; + } + + if ((contextFlags & WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB) && + majorVersion < 3) { + SetLastError(ERROR_INVALID_VERSION_ARB); + return 0; + } + + /* Get pointer to OPENGL32.DLL's wglCreate/DeleteContext() functions */ + if (!wglCreateContext_func || !wglDeleteContext_func) { + /* Get the OPENGL32.DLL library */ + HMODULE opengl_lib = GetModuleHandleA("opengl32.dll"); + if (!opengl_lib) { + _debug_printf("wgl: GetModuleHandleA(\"opengl32.dll\") failed\n"); + return 0; + } + + /* Get pointer to wglCreateContext() function */ + wglCreateContext_func = (wglCreateContext_t) + GetProcAddress(opengl_lib, "wglCreateContext"); + if (!wglCreateContext_func) { + _debug_printf("wgl: failed to get wglCreateContext()\n"); + return 0; + } + + /* Get pointer to wglDeleteContext() function */ + wglDeleteContext_func = (wglDeleteContext_t) + GetProcAddress(opengl_lib, "wglDeleteContext"); + if (!wglDeleteContext_func) { + _debug_printf("wgl: failed to get wglDeleteContext()\n"); + return 0; + } + } + + /* Call wglCreateContext to get a valid context ID */ + context = wglCreateContext_func(hDC); + + if (context) { + /* Now replace the context we just created with a new one that reflects + * the attributes passed to this function. + */ + DHGLRC dhglrc, c, share_dhglrc = 0; + + /* Convert public HGLRC to driver DHGLRC */ + if (stw_dev && stw_dev->callbacks.wglCbGetDhglrc) { + dhglrc = stw_dev->callbacks.wglCbGetDhglrc(context); + if (hShareContext) + share_dhglrc = stw_dev->callbacks.wglCbGetDhglrc(hShareContext); + } + else { + /* not using ICD */ + dhglrc = (DHGLRC) context; + share_dhglrc = (DHGLRC) hShareContext; + } + + c = stw_create_context_attribs(hDC, layerPlane, share_dhglrc, + majorVersion, minorVersion, + contextFlags, profileMask, + dhglrc); + if (!c) { + wglDeleteContext_func(context); + context = 0; + } + } + + return context; +} diff --git a/lib/mesa/src/gallium/state_trackers/wgl/stw_ext_context.h b/lib/mesa/src/gallium/state_trackers/wgl/stw_ext_context.h new file mode 100644 index 000000000..9cb12b498 --- /dev/null +++ b/lib/mesa/src/gallium/state_trackers/wgl/stw_ext_context.h @@ -0,0 +1,36 @@ +/* + * Mesa 3-D graphics library + * + * Copyright (C) 2011 Morgan Armand <morgan.devel@gmail.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS 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 SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include <windows.h> +#include <GL/gl.h> + + +typedef HGLRC (WINAPI *wglCreateContext_t)(HDC hdc); +typedef BOOL (WINAPI *wglDeleteContext_t)(HGLRC hglrc); + +extern wglCreateContext_t wglCreateContext_func; +extern wglDeleteContext_t wglDeleteContext_func; + diff --git a/lib/mesa/src/gallium/state_trackers/wgl/stw_ext_extensionsstring.c b/lib/mesa/src/gallium/state_trackers/wgl/stw_ext_extensionsstring.c new file mode 100644 index 000000000..a8c085a13 --- /dev/null +++ b/lib/mesa/src/gallium/state_trackers/wgl/stw_ext_extensionsstring.c @@ -0,0 +1,66 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * Copyright 2008 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS 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 + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include <windows.h> + +#define WGL_WGLEXT_PROTOTYPES + +#include <GL/gl.h> +#include <GL/wglext.h> + + +static const char *stw_extension_string = + "WGL_ARB_create_context " + "WGL_ARB_create_context_profile " + "WGL_ARB_extensions_string " + "WGL_ARB_multisample " + "WGL_ARB_pbuffer " + "WGL_ARB_pixel_format " + "WGL_EXT_create_context_es_profile " + "WGL_EXT_create_context_es2_profile " +/* "WGL_EXT_swap_interval " */ + "WGL_EXT_extensions_string"; + + +WINGDIAPI const char * APIENTRY +wglGetExtensionsStringARB( + HDC hdc ) +{ + if (!hdc) { + return NULL; + } + + return stw_extension_string; +} + + +WINGDIAPI const char * APIENTRY +wglGetExtensionsStringEXT( void ) +{ + return stw_extension_string; +} diff --git a/lib/mesa/src/gallium/state_trackers/wgl/stw_ext_pbuffer.c b/lib/mesa/src/gallium/state_trackers/wgl/stw_ext_pbuffer.c new file mode 100644 index 000000000..0bd60c064 --- /dev/null +++ b/lib/mesa/src/gallium/state_trackers/wgl/stw_ext_pbuffer.c @@ -0,0 +1,318 @@ +/************************************************************************** + * + * Copyright 2010 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS 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 + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include <windows.h> + +#define WGL_WGLEXT_PROTOTYPES + +#include <GL/gl.h> +#include <GL/wglext.h> + +#include "pipe/p_defines.h" +#include "pipe/p_screen.h" + +#include "stw_device.h" +#include "stw_pixelformat.h" +#include "stw_framebuffer.h" + + +#define LARGE_WINDOW_SIZE 60000 + + +static LRESULT CALLBACK +WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + MINMAXINFO *pMMI; + switch (uMsg) { + case WM_GETMINMAXINFO: + // Allow to create a window bigger than the desktop + pMMI = (MINMAXINFO *)lParam; + pMMI->ptMaxSize.x = LARGE_WINDOW_SIZE; + pMMI->ptMaxSize.y = LARGE_WINDOW_SIZE; + pMMI->ptMaxTrackSize.x = LARGE_WINDOW_SIZE; + pMMI->ptMaxTrackSize.y = LARGE_WINDOW_SIZE; + break; + default: + break; + } + + return DefWindowProc(hWnd, uMsg, wParam, lParam); +} + + +HPBUFFERARB WINAPI +wglCreatePbufferARB(HDC hCurrentDC, + int iPixelFormat, + int iWidth, + int iHeight, + const int *piAttribList) +{ + static boolean first = TRUE; + const int *piAttrib; + int useLargest = 0; + const struct stw_pixelformat_info *info; + struct stw_framebuffer *fb; + DWORD dwExStyle; + DWORD dwStyle; + RECT rect; + HWND hWnd; + HDC hDC; + int iDisplayablePixelFormat; + PIXELFORMATDESCRIPTOR pfd; + BOOL bRet; + + info = stw_pixelformat_get_info(iPixelFormat - 1); + if (!info) { + SetLastError(ERROR_INVALID_PIXEL_FORMAT); + return 0; + } + + if (iWidth <= 0 || iHeight <= 0) { + SetLastError(ERROR_INVALID_DATA); + return 0; + } + + for (piAttrib = piAttribList; *piAttrib; piAttrib++) { + switch (*piAttrib) { + case WGL_PBUFFER_LARGEST_ARB: + piAttrib++; + useLargest = *piAttrib; + break; + default: + SetLastError(ERROR_INVALID_DATA); + return 0; + } + } + + if (iWidth > stw_dev->max_2d_length) { + if (useLargest) { + iWidth = stw_dev->max_2d_length; + } else { + SetLastError(ERROR_NO_SYSTEM_RESOURCES); + return 0; + } + } + + if (iHeight > stw_dev->max_2d_length) { + if (useLargest) { + iHeight = stw_dev->max_2d_length; + } else { + SetLastError(ERROR_NO_SYSTEM_RESOURCES); + return 0; + } + } + + /* + * Implement pbuffers through invisible windows + */ + + if (first) { + WNDCLASS wc; + memset(&wc, 0, sizeof wc); + wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); + wc.lpfnWndProc = WndProc; + wc.lpszClassName = "wglpbuffer"; + wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; + RegisterClass(&wc); + first = FALSE; + } + + dwExStyle = 0; + dwStyle = WS_CLIPSIBLINGS | WS_CLIPCHILDREN; + + if (0) { + /* + * Don't hide the window -- useful for debugging what the application is + * drawing + */ + + dwStyle |= WS_VISIBLE | WS_OVERLAPPEDWINDOW; + } else { + dwStyle |= WS_POPUPWINDOW; + } + + rect.left = 0; + rect.top = 0; + rect.right = rect.left + iWidth; + rect.bottom = rect.top + iHeight; + + /* + * The CreateWindowEx parameters are the total (outside) dimensions of the + * window, which can vary with Windows version and user settings. Use + * AdjustWindowRect to get the required total area for the given client area. + * + * AdjustWindowRectEx does not accept WS_OVERLAPPED style (which is defined + * as 0), which means we need to use some other style instead, e.g., + * WS_OVERLAPPEDWINDOW or WS_POPUPWINDOW as above. + */ + + AdjustWindowRectEx(&rect, dwStyle, FALSE, dwExStyle); + + hWnd = CreateWindowEx(dwExStyle, + "wglpbuffer", /* wc.lpszClassName */ + NULL, + dwStyle, + CW_USEDEFAULT, /* x */ + CW_USEDEFAULT, /* y */ + rect.right - rect.left, /* width */ + rect.bottom - rect.top, /* height */ + NULL, + NULL, + NULL, + NULL); + if (!hWnd) { + return 0; + } + +#ifdef DEBUG + /* + * Verify the client area size matches the specified size. + */ + + GetClientRect(hWnd, &rect); + assert(rect.left == 0); + assert(rect.top == 0); + assert(rect.right - rect.left == iWidth); + assert(rect.bottom - rect.top == iHeight); +#endif + + hDC = GetDC(hWnd); + if (!hDC) { + return 0; + } + + /* + * We can't pass non-displayable pixel formats to GDI, which is why we + * create the framebuffer object before calling SetPixelFormat(). + */ + fb = stw_framebuffer_create(hDC, iPixelFormat); + if (!fb) { + SetLastError(ERROR_NO_SYSTEM_RESOURCES); + return NULL; + } + + fb->bPbuffer = TRUE; + iDisplayablePixelFormat = fb->iDisplayablePixelFormat; + + stw_framebuffer_release(fb); + + /* + * We need to set a displayable pixel format on the hidden window DC + * so that wglCreateContext and wglMakeCurrent are not overruled by GDI. + */ + bRet = SetPixelFormat(hDC, iDisplayablePixelFormat, &pfd); + assert(bRet); + + return (HPBUFFERARB)fb; +} + + +HDC WINAPI +wglGetPbufferDCARB(HPBUFFERARB hPbuffer) +{ + struct stw_framebuffer *fb; + HDC hDC; + + if (!hPbuffer) { + SetLastError(ERROR_INVALID_HANDLE); + return NULL; + } + + fb = (struct stw_framebuffer *)hPbuffer; + + hDC = GetDC(fb->hWnd); + + return hDC; +} + + +int WINAPI +wglReleasePbufferDCARB(HPBUFFERARB hPbuffer, + HDC hDC) +{ + struct stw_framebuffer *fb; + + if (!hPbuffer) { + SetLastError(ERROR_INVALID_HANDLE); + return 0; + } + + fb = (struct stw_framebuffer *)hPbuffer; + + return ReleaseDC(fb->hWnd, hDC); +} + + +BOOL WINAPI +wglDestroyPbufferARB(HPBUFFERARB hPbuffer) +{ + struct stw_framebuffer *fb; + + if (!hPbuffer) { + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + + fb = (struct stw_framebuffer *)hPbuffer; + + /* This will destroy all our data */ + return DestroyWindow(fb->hWnd); +} + + +BOOL WINAPI +wglQueryPbufferARB(HPBUFFERARB hPbuffer, + int iAttribute, + int *piValue) +{ + struct stw_framebuffer *fb; + + if (!hPbuffer) { + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + + fb = (struct stw_framebuffer *)hPbuffer; + + switch (iAttribute) { + case WGL_PBUFFER_WIDTH_ARB: + *piValue = fb->width; + return TRUE; + case WGL_PBUFFER_HEIGHT_ARB: + *piValue = fb->height; + return TRUE; + case WGL_PBUFFER_LOST_ARB: + /* We assume that no content is ever lost due to display mode change */ + *piValue = FALSE; + return TRUE; + default: + SetLastError(ERROR_INVALID_DATA); + return FALSE; + } +} diff --git a/lib/mesa/src/gallium/state_trackers/wgl/stw_ext_pixelformat.c b/lib/mesa/src/gallium/state_trackers/wgl/stw_ext_pixelformat.c new file mode 100644 index 000000000..e38086e86 --- /dev/null +++ b/lib/mesa/src/gallium/state_trackers/wgl/stw_ext_pixelformat.c @@ -0,0 +1,511 @@ +/************************************************************************** + * + * Copyright 2008 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS 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 + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * @file + * + * WGL_ARB_pixel_format extension implementation. + * + * @sa http://www.opengl.org/registry/specs/ARB/wgl_pixel_format.txt + */ + + +#include <windows.h> + +#define WGL_WGLEXT_PROTOTYPES + +#include <GL/gl.h> +#include <GL/wglext.h> + +#include "pipe/p_compiler.h" +#include "util/u_format.h" +#include "util/u_memory.h" +#include "stw_device.h" +#include "stw_pixelformat.h" + + +static boolean +stw_query_attrib( + int iPixelFormat, + int iLayerPlane, + int attrib, + int *pvalue ) +{ + uint count; + const struct stw_pixelformat_info *pfi; + + count = stw_pixelformat_get_extended_count(); + + if (attrib == WGL_NUMBER_PIXEL_FORMATS_ARB) { + *pvalue = (int) count; + return TRUE; + } + + pfi = stw_pixelformat_get_info( iPixelFormat ); + if (!pfi) { + return FALSE; + } + + switch (attrib) { + case WGL_DRAW_TO_WINDOW_ARB: + *pvalue = pfi->pfd.dwFlags & PFD_DRAW_TO_WINDOW ? TRUE : FALSE; + return TRUE; + + case WGL_DRAW_TO_BITMAP_ARB: + *pvalue = pfi->pfd.dwFlags & PFD_DRAW_TO_BITMAP ? TRUE : FALSE; + return TRUE; + + case WGL_NEED_PALETTE_ARB: + *pvalue = pfi->pfd.dwFlags & PFD_NEED_PALETTE ? TRUE : FALSE; + return TRUE; + + case WGL_NEED_SYSTEM_PALETTE_ARB: + *pvalue = pfi->pfd.dwFlags & PFD_NEED_SYSTEM_PALETTE ? TRUE : FALSE; + return TRUE; + + case WGL_SWAP_METHOD_ARB: + if (pfi->pfd.dwFlags & PFD_SWAP_COPY) + *pvalue = WGL_SWAP_COPY_ARB; + else if (pfi->pfd.dwFlags & PFD_SWAP_EXCHANGE) + *pvalue = WGL_SWAP_EXCHANGE_EXT; + else + *pvalue = WGL_SWAP_UNDEFINED_ARB; + return TRUE; + + case WGL_SWAP_LAYER_BUFFERS_ARB: + *pvalue = FALSE; + return TRUE; + + case WGL_NUMBER_OVERLAYS_ARB: + *pvalue = 0; + return TRUE; + + case WGL_NUMBER_UNDERLAYS_ARB: + *pvalue = 0; + return TRUE; + } + + if (iLayerPlane != 0) + return FALSE; + + switch (attrib) { + case WGL_ACCELERATION_ARB: + *pvalue = WGL_FULL_ACCELERATION_ARB; + break; + + case WGL_TRANSPARENT_ARB: + *pvalue = FALSE; + break; + + case WGL_TRANSPARENT_RED_VALUE_ARB: + case WGL_TRANSPARENT_GREEN_VALUE_ARB: + case WGL_TRANSPARENT_BLUE_VALUE_ARB: + case WGL_TRANSPARENT_ALPHA_VALUE_ARB: + case WGL_TRANSPARENT_INDEX_VALUE_ARB: + break; + + case WGL_SHARE_DEPTH_ARB: + case WGL_SHARE_STENCIL_ARB: + case WGL_SHARE_ACCUM_ARB: + *pvalue = TRUE; + break; + + case WGL_SUPPORT_GDI_ARB: + *pvalue = pfi->pfd.dwFlags & PFD_SUPPORT_GDI ? TRUE : FALSE; + break; + + case WGL_SUPPORT_OPENGL_ARB: + *pvalue = pfi->pfd.dwFlags & PFD_SUPPORT_OPENGL ? TRUE : FALSE; + break; + + case WGL_DOUBLE_BUFFER_ARB: + *pvalue = pfi->pfd.dwFlags & PFD_DOUBLEBUFFER ? TRUE : FALSE; + break; + + case WGL_STEREO_ARB: + *pvalue = pfi->pfd.dwFlags & PFD_STEREO ? TRUE : FALSE; + break; + + case WGL_PIXEL_TYPE_ARB: + switch (pfi->pfd.iPixelType) { + case PFD_TYPE_RGBA: + if (util_format_is_float(pfi->stvis.color_format)) { + *pvalue = WGL_TYPE_RGBA_FLOAT_ARB; + } + else { + *pvalue = WGL_TYPE_RGBA_ARB; + } + break; + case PFD_TYPE_COLORINDEX: + *pvalue = WGL_TYPE_COLORINDEX_ARB; + break; + default: + return FALSE; + } + break; + + case WGL_COLOR_BITS_ARB: + *pvalue = pfi->pfd.cColorBits; + break; + + case WGL_RED_BITS_ARB: + *pvalue = pfi->pfd.cRedBits; + break; + + case WGL_RED_SHIFT_ARB: + *pvalue = pfi->pfd.cRedShift; + break; + + case WGL_GREEN_BITS_ARB: + *pvalue = pfi->pfd.cGreenBits; + break; + + case WGL_GREEN_SHIFT_ARB: + *pvalue = pfi->pfd.cGreenShift; + break; + + case WGL_BLUE_BITS_ARB: + *pvalue = pfi->pfd.cBlueBits; + break; + + case WGL_BLUE_SHIFT_ARB: + *pvalue = pfi->pfd.cBlueShift; + break; + + case WGL_ALPHA_BITS_ARB: + *pvalue = pfi->pfd.cAlphaBits; + break; + + case WGL_ALPHA_SHIFT_ARB: + *pvalue = pfi->pfd.cAlphaShift; + break; + + case WGL_ACCUM_BITS_ARB: + *pvalue = pfi->pfd.cAccumBits; + break; + + case WGL_ACCUM_RED_BITS_ARB: + *pvalue = pfi->pfd.cAccumRedBits; + break; + + case WGL_ACCUM_GREEN_BITS_ARB: + *pvalue = pfi->pfd.cAccumGreenBits; + break; + + case WGL_ACCUM_BLUE_BITS_ARB: + *pvalue = pfi->pfd.cAccumBlueBits; + break; + + case WGL_ACCUM_ALPHA_BITS_ARB: + *pvalue = pfi->pfd.cAccumAlphaBits; + break; + + case WGL_DEPTH_BITS_ARB: + *pvalue = pfi->pfd.cDepthBits; + break; + + case WGL_STENCIL_BITS_ARB: + *pvalue = pfi->pfd.cStencilBits; + break; + + case WGL_AUX_BUFFERS_ARB: + *pvalue = pfi->pfd.cAuxBuffers; + break; + + case WGL_SAMPLE_BUFFERS_ARB: + *pvalue = (pfi->stvis.samples > 1); + break; + + case WGL_SAMPLES_ARB: + *pvalue = pfi->stvis.samples; + break; + + + /* WGL_ARB_pbuffer */ + + case WGL_MAX_PBUFFER_WIDTH_ARB: + case WGL_MAX_PBUFFER_HEIGHT_ARB: + *pvalue = stw_dev->max_2d_length; + break; + + case WGL_MAX_PBUFFER_PIXELS_ARB: + *pvalue = stw_dev->max_2d_length * stw_dev->max_2d_length; + break; + + case WGL_DRAW_TO_PBUFFER_ARB: + *pvalue = 1; + break; + + + default: + return FALSE; + } + + return TRUE; +} + +struct attrib_match_info +{ + int attribute; + int weight; + BOOL exact; +}; + +static const struct attrib_match_info attrib_match[] = { + + /* WGL_ARB_pixel_format */ + { WGL_DRAW_TO_WINDOW_ARB, 0, TRUE }, + { WGL_DRAW_TO_BITMAP_ARB, 0, TRUE }, + { WGL_ACCELERATION_ARB, 0, TRUE }, + { WGL_NEED_PALETTE_ARB, 0, TRUE }, + { WGL_NEED_SYSTEM_PALETTE_ARB, 0, TRUE }, + { WGL_SWAP_LAYER_BUFFERS_ARB, 0, TRUE }, + { WGL_SWAP_METHOD_ARB, 0, TRUE }, + { WGL_NUMBER_OVERLAYS_ARB, 4, FALSE }, + { WGL_NUMBER_UNDERLAYS_ARB, 4, FALSE }, + /*{ WGL_SHARE_DEPTH_ARB, 0, TRUE },*/ /* no overlays -- ignore */ + /*{ WGL_SHARE_STENCIL_ARB, 0, TRUE },*/ /* no overlays -- ignore */ + /*{ WGL_SHARE_ACCUM_ARB, 0, TRUE },*/ /* no overlays -- ignore */ + { WGL_SUPPORT_GDI_ARB, 0, TRUE }, + { WGL_SUPPORT_OPENGL_ARB, 0, TRUE }, + { WGL_DOUBLE_BUFFER_ARB, 0, TRUE }, + { WGL_STEREO_ARB, 0, TRUE }, + { WGL_PIXEL_TYPE_ARB, 0, TRUE }, + { WGL_COLOR_BITS_ARB, 1, FALSE }, + { WGL_RED_BITS_ARB, 1, FALSE }, + { WGL_GREEN_BITS_ARB, 1, FALSE }, + { WGL_BLUE_BITS_ARB, 1, FALSE }, + { WGL_ALPHA_BITS_ARB, 1, FALSE }, + { WGL_ACCUM_BITS_ARB, 1, FALSE }, + { WGL_ACCUM_RED_BITS_ARB, 1, FALSE }, + { WGL_ACCUM_GREEN_BITS_ARB, 1, FALSE }, + { WGL_ACCUM_BLUE_BITS_ARB, 1, FALSE }, + { WGL_ACCUM_ALPHA_BITS_ARB, 1, FALSE }, + { WGL_DEPTH_BITS_ARB, 1, FALSE }, + { WGL_STENCIL_BITS_ARB, 1, FALSE }, + { WGL_AUX_BUFFERS_ARB, 2, FALSE }, + + /* WGL_ARB_multisample */ + { WGL_SAMPLE_BUFFERS_ARB, 2, FALSE }, + { WGL_SAMPLES_ARB, 2, FALSE } +}; + +struct stw_pixelformat_score +{ + int points; + uint index; +}; + +static BOOL +score_pixelformats( + struct stw_pixelformat_score *scores, + uint count, + int attribute, + int expected_value ) +{ + uint i; + const struct attrib_match_info *ami = NULL; + uint index; + + /* Find out if a given attribute should be considered for score calculation. + */ + for (i = 0; i < sizeof( attrib_match ) / sizeof( attrib_match[0] ); i++) { + if (attrib_match[i].attribute == attribute) { + ami = &attrib_match[i]; + break; + } + } + if (ami == NULL) + return TRUE; + + /* Iterate all pixelformats, query the requested attribute and calculate + * score points. + */ + for (index = 0; index < count; index++) { + int actual_value; + + if (!stw_query_attrib( index + 1, 0, attribute, &actual_value )) + return FALSE; + + if (ami->exact) { + /* For an exact match criteria, if the actual and expected values differ, + * the score is set to 0 points, effectively removing the pixelformat + * from a list of matching pixelformats. + */ + if (actual_value != expected_value) + scores[index].points = 0; + } + else { + /* For a minimum match criteria, if the actual value is smaller than the expected + * value, the pixelformat is rejected (score set to 0). However, if the actual + * value is bigger, the pixelformat is given a penalty to favour pixelformats that + * more closely match the expected values. + */ + if (actual_value < expected_value) + scores[index].points = 0; + else if (actual_value > expected_value) + scores[index].points -= (actual_value - expected_value) * ami->weight; + } + } + + return TRUE; +} + +WINGDIAPI BOOL APIENTRY +wglChoosePixelFormatARB( + HDC hdc, + const int *piAttribIList, + const FLOAT *pfAttribFList, + UINT nMaxFormats, + int *piFormats, + UINT *nNumFormats ) +{ + uint count; + struct stw_pixelformat_score *scores; + uint i; + + *nNumFormats = 0; + + /* Allocate and initialize pixelformat score table -- better matches + * have higher scores. Start with a high score and take out penalty + * points for a mismatch when the match does not have to be exact. + * Set a score to 0 if there is a mismatch for an exact match criteria. + */ + count = stw_pixelformat_get_extended_count(); + scores = (struct stw_pixelformat_score *) MALLOC( count * sizeof( struct stw_pixelformat_score ) ); + if (scores == NULL) + return FALSE; + for (i = 0; i < count; i++) { + scores[i].points = 0x7fffffff; + scores[i].index = i; + } + + /* Given the attribute list calculate a score for each pixelformat. + */ + if (piAttribIList != NULL) { + while (*piAttribIList != 0) { + if (!score_pixelformats( scores, count, piAttribIList[0], piAttribIList[1] )) { + FREE( scores ); + return FALSE; + } + piAttribIList += 2; + } + } + if (pfAttribFList != NULL) { + while (*pfAttribFList != 0) { + if (!score_pixelformats( scores, count, (int) pfAttribFList[0], (int) pfAttribFList[1] )) { + FREE( scores ); + return FALSE; + } + pfAttribFList += 2; + } + } + + /* Bubble-sort the resulting scores. Pixelformats with higher scores go first. + * TODO: Find out if there are any patent issues with it. + */ + if (count > 1) { + uint n = count; + boolean swapped; + + do { + swapped = FALSE; + for (i = 1; i < n; i++) { + if (scores[i - 1].points < scores[i].points) { + struct stw_pixelformat_score score = scores[i - 1]; + + scores[i - 1] = scores[i]; + scores[i] = score; + swapped = TRUE; + } + } + n--; + } + while (swapped); + } + + /* Return a list of pixelformats that are the best match. + * Reject pixelformats with non-positive scores. + */ + for (i = 0; i < count; i++) { + if (scores[i].points > 0) { + piFormats[*nNumFormats] = scores[i].index + 1; + (*nNumFormats)++; + if (*nNumFormats >= nMaxFormats) { + break; + } + } + } + + FREE( scores ); + return TRUE; +} + +WINGDIAPI BOOL APIENTRY +wglGetPixelFormatAttribfvARB( + HDC hdc, + int iPixelFormat, + int iLayerPlane, + UINT nAttributes, + const int *piAttributes, + FLOAT *pfValues ) +{ + UINT i; + + (void) hdc; + + for (i = 0; i < nAttributes; i++) { + int value; + + if (!stw_query_attrib( iPixelFormat, iLayerPlane, piAttributes[i], &value )) + return FALSE; + pfValues[i] = (FLOAT) value; + } + + return TRUE; +} + +WINGDIAPI BOOL APIENTRY +wglGetPixelFormatAttribivARB( + HDC hdc, + int iPixelFormat, + int iLayerPlane, + UINT nAttributes, + const int *piAttributes, + int *piValues ) +{ + UINT i; + + (void) hdc; + + for (i = 0; i < nAttributes; i++) { + if (!stw_query_attrib( iPixelFormat, iLayerPlane, piAttributes[i], &piValues[i] )) + return FALSE; + } + + return TRUE; +} diff --git a/lib/mesa/src/gallium/state_trackers/wgl/stw_ext_swapinterval.c b/lib/mesa/src/gallium/state_trackers/wgl/stw_ext_swapinterval.c new file mode 100644 index 000000000..b960913cc --- /dev/null +++ b/lib/mesa/src/gallium/state_trackers/wgl/stw_ext_swapinterval.c @@ -0,0 +1,57 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * Copyright 2008 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS 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 + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include <windows.h> + +#define WGL_WGLEXT_PROTOTYPES + +#include <GL/gl.h> +#include <GL/wglext.h> +#include "util/u_debug.h" + +/* A dummy implementation of this extension. + * + * Required as some applications retrieve and call these functions + * regardless of the fact that we don't advertise the extension and + * further more the results of wglGetProcAddress are NULL. + */ +WINGDIAPI BOOL APIENTRY +wglSwapIntervalEXT(int interval) +{ + (void) interval; + debug_printf("%s: %d\n", __FUNCTION__, interval); + return TRUE; +} + +WINGDIAPI int APIENTRY +wglGetSwapIntervalEXT(void) +{ + return 0; +} + + diff --git a/lib/mesa/src/gallium/state_trackers/wgl/stw_framebuffer.c b/lib/mesa/src/gallium/state_trackers/wgl/stw_framebuffer.c new file mode 100644 index 000000000..7b34fcbb5 --- /dev/null +++ b/lib/mesa/src/gallium/state_trackers/wgl/stw_framebuffer.c @@ -0,0 +1,627 @@ +/************************************************************************** + * + * Copyright 2008-2009 Vmware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS 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 + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include <windows.h> + +#include "pipe/p_screen.h" +#include "util/u_memory.h" +#include "hud/hud_context.h" +#include "state_tracker/st_api.h" + +#include "stw_icd.h" +#include "stw_framebuffer.h" +#include "stw_device.h" +#include "stw_winsys.h" +#include "stw_tls.h" +#include "stw_context.h" +#include "stw_st.h" + + +/** + * Search the framebuffer with the matching HWND while holding the + * stw_dev::fb_mutex global lock. + */ +static inline struct stw_framebuffer * +stw_framebuffer_from_hwnd_locked( + HWND hwnd ) +{ + struct stw_framebuffer *fb; + + for (fb = stw_dev->fb_head; fb != NULL; fb = fb->next) + if (fb->hWnd == hwnd) { + pipe_mutex_lock(fb->mutex); + break; + } + + return fb; +} + + +/** + * Destroy this framebuffer. Both stw_dev::fb_mutex and stw_framebuffer::mutex + * must be held, by this order. If there are still references to the + * framebuffer, nothing will happen. + */ +static void +stw_framebuffer_destroy_locked(struct stw_framebuffer *fb) +{ + struct stw_framebuffer **link; + + /* check the reference count */ + fb->refcnt--; + if (fb->refcnt) { + pipe_mutex_unlock( fb->mutex ); + return; + } + + link = &stw_dev->fb_head; + while (*link != fb) + link = &(*link)->next; + assert(*link); + *link = fb->next; + fb->next = NULL; + + if (fb->shared_surface) + stw_dev->stw_winsys->shared_surface_close(stw_dev->screen, + fb->shared_surface); + + stw_st_destroy_framebuffer_locked(fb->stfb); + + pipe_mutex_unlock( fb->mutex ); + + pipe_mutex_destroy( fb->mutex ); + + FREE( fb ); +} + + +void +stw_framebuffer_release(struct stw_framebuffer *fb) +{ + assert(fb); + pipe_mutex_unlock( fb->mutex ); +} + + +static void +stw_framebuffer_get_size(struct stw_framebuffer *fb) +{ + LONG width, height; + RECT client_rect; + RECT window_rect; + POINT client_pos; + + /* + * Sanity checking. + */ + + assert(fb->hWnd); + assert(fb->width && fb->height); + assert(fb->client_rect.right == fb->client_rect.left + fb->width); + assert(fb->client_rect.bottom == fb->client_rect.top + fb->height); + + /* + * Get the client area size. + */ + + if (!GetClientRect(fb->hWnd, &client_rect)) { + return; + } + + assert(client_rect.left == 0); + assert(client_rect.top == 0); + width = client_rect.right - client_rect.left; + height = client_rect.bottom - client_rect.top; + + fb->minimized = width == 0 || height == 0; + + if (width <= 0 || height <= 0) { + /* + * When the window is minimized GetClientRect will return zeros. Simply + * preserve the current window size, until the window is restored or + * maximized again. + */ + + return; + } + + if (width != fb->width || height != fb->height) { + fb->must_resize = TRUE; + fb->width = width; + fb->height = height; + } + + client_pos.x = 0; + client_pos.y = 0; + if (ClientToScreen(fb->hWnd, &client_pos) && + GetWindowRect(fb->hWnd, &window_rect)) { + fb->client_rect.left = client_pos.x - window_rect.left; + fb->client_rect.top = client_pos.y - window_rect.top; + } + + fb->client_rect.right = fb->client_rect.left + fb->width; + fb->client_rect.bottom = fb->client_rect.top + fb->height; + +#if 0 + debug_printf("\n"); + debug_printf("%s: hwnd = %p\n", __FUNCTION__, fb->hWnd); + debug_printf("%s: client_position = (%li, %li)\n", + __FUNCTION__, client_pos.x, client_pos.y); + debug_printf("%s: window_rect = (%li, %li) - (%li, %li)\n", + __FUNCTION__, + window_rect.left, window_rect.top, + window_rect.right, window_rect.bottom); + debug_printf("%s: client_rect = (%li, %li) - (%li, %li)\n", + __FUNCTION__, + fb->client_rect.left, fb->client_rect.top, + fb->client_rect.right, fb->client_rect.bottom); +#endif +} + + +/** + * @sa http://msdn.microsoft.com/en-us/library/ms644975(VS.85).aspx + * @sa http://msdn.microsoft.com/en-us/library/ms644960(VS.85).aspx + */ +LRESULT CALLBACK +stw_call_window_proc(int nCode, WPARAM wParam, LPARAM lParam) +{ + struct stw_tls_data *tls_data; + PCWPSTRUCT pParams = (PCWPSTRUCT)lParam; + struct stw_framebuffer *fb; + + tls_data = stw_tls_get_data(); + if (!tls_data) + return 0; + + if (nCode < 0 || !stw_dev) + return CallNextHookEx(tls_data->hCallWndProcHook, nCode, wParam, lParam); + + if (pParams->message == WM_WINDOWPOSCHANGED) { + /* We handle WM_WINDOWPOSCHANGED instead of WM_SIZE because according to + * http://blogs.msdn.com/oldnewthing/archive/2008/01/15/7113860.aspx + * WM_SIZE is generated from WM_WINDOWPOSCHANGED by DefWindowProc so it + * can be masked out by the application. + */ + LPWINDOWPOS lpWindowPos = (LPWINDOWPOS)pParams->lParam; + if ((lpWindowPos->flags & SWP_SHOWWINDOW) || + !(lpWindowPos->flags & SWP_NOMOVE) || + !(lpWindowPos->flags & SWP_NOSIZE)) { + fb = stw_framebuffer_from_hwnd( pParams->hwnd ); + if (fb) { + /* Size in WINDOWPOS includes the window frame, so get the size + * of the client area via GetClientRect. + */ + stw_framebuffer_get_size(fb); + stw_framebuffer_release(fb); + } + } + } + else if (pParams->message == WM_DESTROY) { + pipe_mutex_lock( stw_dev->fb_mutex ); + fb = stw_framebuffer_from_hwnd_locked( pParams->hwnd ); + if (fb) + stw_framebuffer_destroy_locked(fb); + pipe_mutex_unlock( stw_dev->fb_mutex ); + } + + return CallNextHookEx(tls_data->hCallWndProcHook, nCode, wParam, lParam); +} + + +struct stw_framebuffer * +stw_framebuffer_create(HDC hdc, int iPixelFormat) +{ + HWND hWnd; + struct stw_framebuffer *fb; + const struct stw_pixelformat_info *pfi; + + /* We only support drawing to a window. */ + hWnd = WindowFromDC( hdc ); + if (!hWnd) + return NULL; + + fb = CALLOC_STRUCT( stw_framebuffer ); + if (fb == NULL) + return NULL; + + fb->hWnd = hWnd; + fb->iPixelFormat = iPixelFormat; + + /* + * We often need a displayable pixel format to make GDI happy. Set it + * here (always 1, i.e., out first pixel format) where appropriate. + */ + fb->iDisplayablePixelFormat = iPixelFormat <= stw_dev->pixelformat_count + ? iPixelFormat : 1; + + fb->pfi = pfi = stw_pixelformat_get_info( iPixelFormat ); + fb->stfb = stw_st_create_framebuffer( fb ); + if (!fb->stfb) { + FREE( fb ); + return NULL; + } + + fb->refcnt = 1; + + /* + * Windows can be sometimes have zero width and or height, but we ensure + * a non-zero framebuffer size at all times. + */ + + fb->must_resize = TRUE; + fb->width = 1; + fb->height = 1; + fb->client_rect.left = 0; + fb->client_rect.top = 0; + fb->client_rect.right = fb->client_rect.left + fb->width; + fb->client_rect.bottom = fb->client_rect.top + fb->height; + + stw_framebuffer_get_size(fb); + + pipe_mutex_init( fb->mutex ); + + /* This is the only case where we lock the stw_framebuffer::mutex before + * stw_dev::fb_mutex, since no other thread can know about this framebuffer + * and we must prevent any other thread from destroying it before we return. + */ + pipe_mutex_lock( fb->mutex ); + + pipe_mutex_lock( stw_dev->fb_mutex ); + fb->next = stw_dev->fb_head; + stw_dev->fb_head = fb; + pipe_mutex_unlock( stw_dev->fb_mutex ); + + return fb; +} + + +/** + * Have ptr reference fb. The referenced framebuffer should be locked. + */ +void +stw_framebuffer_reference(struct stw_framebuffer **ptr, + struct stw_framebuffer *fb) +{ + struct stw_framebuffer *old_fb = *ptr; + + if (old_fb == fb) + return; + + if (fb) + fb->refcnt++; + if (old_fb) { + pipe_mutex_lock(stw_dev->fb_mutex); + + pipe_mutex_lock(old_fb->mutex); + stw_framebuffer_destroy_locked(old_fb); + + pipe_mutex_unlock(stw_dev->fb_mutex); + } + + *ptr = fb; +} + + +/** + * Update the framebuffer's size if necessary. + */ +void +stw_framebuffer_update(struct stw_framebuffer *fb) +{ + assert(fb->stfb); + assert(fb->height); + assert(fb->width); + + /* XXX: It would be nice to avoid checking the size again -- in theory + * stw_call_window_proc would have cought the resize and stored the right + * size already, but unfortunately threads created before the DllMain is + * called don't get a DLL_THREAD_ATTACH notification, and there is no way + * to know of their existing without using the not very portable PSAPI. + */ + stw_framebuffer_get_size(fb); +} + + +void +stw_framebuffer_cleanup(void) +{ + struct stw_framebuffer *fb; + struct stw_framebuffer *next; + + if (!stw_dev) + return; + + pipe_mutex_lock( stw_dev->fb_mutex ); + + fb = stw_dev->fb_head; + while (fb) { + next = fb->next; + + pipe_mutex_lock(fb->mutex); + stw_framebuffer_destroy_locked(fb); + + fb = next; + } + stw_dev->fb_head = NULL; + + pipe_mutex_unlock( stw_dev->fb_mutex ); +} + + +/** + * Given an hdc, return the corresponding stw_framebuffer. + */ +static inline struct stw_framebuffer * +stw_framebuffer_from_hdc_locked( + HDC hdc ) +{ + HWND hwnd; + + hwnd = WindowFromDC(hdc); + if (!hwnd) { + return NULL; + } + + return stw_framebuffer_from_hwnd_locked(hwnd); +} + + +/** + * Given an hdc, return the corresponding stw_framebuffer. + */ +struct stw_framebuffer * +stw_framebuffer_from_hdc(HDC hdc) +{ + struct stw_framebuffer *fb; + + if (!stw_dev) + return NULL; + + pipe_mutex_lock( stw_dev->fb_mutex ); + fb = stw_framebuffer_from_hdc_locked(hdc); + pipe_mutex_unlock( stw_dev->fb_mutex ); + + return fb; +} + + +/** + * Given an hdc, return the corresponding stw_framebuffer. + */ +struct stw_framebuffer * +stw_framebuffer_from_hwnd(HWND hwnd) +{ + struct stw_framebuffer *fb; + + pipe_mutex_lock( stw_dev->fb_mutex ); + fb = stw_framebuffer_from_hwnd_locked(hwnd); + pipe_mutex_unlock( stw_dev->fb_mutex ); + + return fb; +} + + +BOOL APIENTRY +DrvSetPixelFormat(HDC hdc, LONG iPixelFormat) +{ + uint count; + uint index; + struct stw_framebuffer *fb; + + if (!stw_dev) + return FALSE; + + index = (uint) iPixelFormat - 1; + count = stw_pixelformat_get_count(); + if (index >= count) + return FALSE; + + fb = stw_framebuffer_from_hdc_locked(hdc); + if (fb) { + /* + * SetPixelFormat must be called only once. However ignore + * pbuffers, for which the framebuffer object is created first. + */ + boolean bPbuffer = fb->bPbuffer; + + stw_framebuffer_release( fb ); + + return bPbuffer; + } + + fb = stw_framebuffer_create(hdc, iPixelFormat); + if (!fb) { + return FALSE; + } + + stw_framebuffer_release( fb ); + + /* Some applications mistakenly use the undocumented wglSetPixelFormat + * function instead of SetPixelFormat, so we call SetPixelFormat here to + * avoid opengl32.dll's wglCreateContext to fail */ + if (GetPixelFormat(hdc) == 0) { + BOOL bRet = SetPixelFormat(hdc, iPixelFormat, NULL); + assert(bRet); + } + + return TRUE; +} + + +int +stw_pixelformat_get(HDC hdc) +{ + int iPixelFormat = 0; + struct stw_framebuffer *fb; + + fb = stw_framebuffer_from_hdc(hdc); + if (fb) { + iPixelFormat = fb->iPixelFormat; + stw_framebuffer_release(fb); + } + + return iPixelFormat; +} + + +BOOL APIENTRY +DrvPresentBuffers(HDC hdc, PGLPRESENTBUFFERSDATA data) +{ + struct stw_framebuffer *fb; + struct pipe_screen *screen; + struct pipe_resource *res; + + if (!stw_dev) + return FALSE; + + fb = stw_framebuffer_from_hdc( hdc ); + if (fb == NULL) + return FALSE; + + screen = stw_dev->screen; + + res = (struct pipe_resource *)data->pPrivateData; + + if (data->hSharedSurface != fb->hSharedSurface) { + if (fb->shared_surface) { + stw_dev->stw_winsys->shared_surface_close(screen, fb->shared_surface); + fb->shared_surface = NULL; + } + + fb->hSharedSurface = data->hSharedSurface; + + if (data->hSharedSurface && + stw_dev->stw_winsys->shared_surface_open) { + fb->shared_surface = + stw_dev->stw_winsys->shared_surface_open(screen, + fb->hSharedSurface); + } + } + + if (!fb->minimized) { + if (fb->shared_surface) { + stw_dev->stw_winsys->compose(screen, + res, + fb->shared_surface, + &fb->client_rect, + data->PresentHistoryToken); + } + else { + stw_dev->stw_winsys->present( screen, res, hdc ); + } + } + + stw_framebuffer_update(fb); + stw_notify_current_locked(fb); + + stw_framebuffer_release(fb); + + return TRUE; +} + + +/** + * Queue a composition. + * + * It will drop the lock on success. + */ +BOOL +stw_framebuffer_present_locked(HDC hdc, + struct stw_framebuffer *fb, + struct pipe_resource *res) +{ + if (stw_dev->callbacks.wglCbPresentBuffers && + stw_dev->stw_winsys->compose) { + GLCBPRESENTBUFFERSDATA data; + + memset(&data, 0, sizeof data); + data.magic1 = 2; + data.magic2 = 0; + data.AdapterLuid = stw_dev->AdapterLuid; + data.rect = fb->client_rect; + data.pPrivateData = (void *)res; + + stw_notify_current_locked(fb); + stw_framebuffer_release(fb); + + return stw_dev->callbacks.wglCbPresentBuffers(hdc, &data); + } + else { + struct pipe_screen *screen = stw_dev->screen; + + stw_dev->stw_winsys->present( screen, res, hdc ); + + stw_framebuffer_update(fb); + stw_notify_current_locked(fb); + stw_framebuffer_release(fb); + + return TRUE; + } +} + + +BOOL APIENTRY +DrvSwapBuffers(HDC hdc) +{ + struct stw_context *ctx; + struct stw_framebuffer *fb; + + if (!stw_dev) + return FALSE; + + fb = stw_framebuffer_from_hdc( hdc ); + if (fb == NULL) + return FALSE; + + if (!(fb->pfi->pfd.dwFlags & PFD_DOUBLEBUFFER)) { + stw_framebuffer_release(fb); + return TRUE; + } + + /* Display the HUD */ + ctx = stw_current_context(); + if (ctx && ctx->hud) { + struct pipe_resource *back = + stw_get_framebuffer_resource(fb->stfb, ST_ATTACHMENT_BACK_LEFT); + hud_draw(ctx->hud, back); + } + + stw_flush_current_locked(fb); + + return stw_st_swap_framebuffer_locked(hdc, fb->stfb); +} + + +BOOL APIENTRY +DrvSwapLayerBuffers(HDC hdc, UINT fuPlanes) +{ + if (fuPlanes & WGL_SWAP_MAIN_PLANE) + return DrvSwapBuffers(hdc); + + return FALSE; +} diff --git a/lib/mesa/src/gallium/state_trackers/wgl/stw_framebuffer.h b/lib/mesa/src/gallium/state_trackers/wgl/stw_framebuffer.h new file mode 100644 index 000000000..28962c8cb --- /dev/null +++ b/lib/mesa/src/gallium/state_trackers/wgl/stw_framebuffer.h @@ -0,0 +1,172 @@ +/************************************************************************** + * + * Copyright 2008 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS 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 + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef STW_FRAMEBUFFER_H +#define STW_FRAMEBUFFER_H + +#include <windows.h> + +#include "os/os_thread.h" + +struct pipe_resource; +struct st_framebuffer_iface; +struct stw_pixelformat_info; + +/** + * Windows framebuffer. + */ +struct stw_framebuffer +{ + /** + * This mutex has two purposes: + * - protect the access to the mutable data members below + * - prevent the framebuffer from being deleted while being accessed. + * + * It is OK to lock this mutex while holding the stw_device::fb_mutex lock, + * but the opposite must never happen. + */ + pipe_mutex mutex; + + /* + * Immutable members. + * + * Note that even access to immutable members implies acquiring the mutex + * above, to prevent the framebuffer from being destroyed. + */ + + HWND hWnd; + + int iPixelFormat; + const struct stw_pixelformat_info *pfi; + + /* A pixel format that can be used by GDI */ + int iDisplayablePixelFormat; + boolean bPbuffer; + + struct st_framebuffer_iface *stfb; + + /* + * Mutable members. + */ + + unsigned refcnt; + + + /* FIXME: Make this work for multiple contexts bound to the same framebuffer */ + boolean must_resize; + + boolean minimized; /**< Is the window currently minimized? */ + + unsigned width; + unsigned height; + + /** + * Client area rectangle, relative to the window upper-left corner. + * + * @sa GLCBPRESENTBUFFERSDATA::rect. + */ + RECT client_rect; + + HANDLE hSharedSurface; + struct stw_shared_surface *shared_surface; + + /** + * This is protected by stw_device::fb_mutex, not the mutex above. + * + * Deletions must be done by first acquiring stw_device::fb_mutex, and then + * acquiring the stw_framebuffer::mutex of the framebuffer to be deleted. + * This ensures that nobody else is reading/writing to the. + * + * It is not necessary to acquire the mutex above to navigate the linked list + * given that deletions are done with stw_device::fb_mutex held, so no other + * thread can delete. + */ + struct stw_framebuffer *next; +}; + + +/** + * Create a new framebuffer object which will correspond to the given HDC. + * + * This function will acquire stw_framebuffer::mutex. stw_framebuffer_release + * must be called when done + */ +struct stw_framebuffer * +stw_framebuffer_create( + HDC hdc, + int iPixelFormat ); + +void +stw_framebuffer_reference( + struct stw_framebuffer **ptr, + struct stw_framebuffer *fb); + +/** + * Search a framebuffer with a matching HWND. + * + * This function will acquire stw_framebuffer::mutex. stw_framebuffer_release + * must be called when done + */ +struct stw_framebuffer * +stw_framebuffer_from_hwnd( + HWND hwnd ); + +/** + * Search a framebuffer with a matching HDC. + * + * This function will acquire stw_framebuffer::mutex. stw_framebuffer_release + * must be called when done + */ +struct stw_framebuffer * +stw_framebuffer_from_hdc( + HDC hdc ); + +BOOL +stw_framebuffer_present_locked(HDC hdc, + struct stw_framebuffer *fb, + struct pipe_resource *res); + +void +stw_framebuffer_update( + struct stw_framebuffer *fb); + +/** + * Release stw_framebuffer::mutex lock. This framebuffer must not be accessed + * after calling this function, as it may have been deleted by another thread + * in the meanwhile. + */ +void +stw_framebuffer_release( + struct stw_framebuffer *fb); + +/** + * Cleanup any existing framebuffers when exiting application. + */ +void +stw_framebuffer_cleanup(void); + +#endif /* STW_FRAMEBUFFER_H */ diff --git a/lib/mesa/src/gallium/state_trackers/wgl/stw_getprocaddress.c b/lib/mesa/src/gallium/state_trackers/wgl/stw_getprocaddress.c new file mode 100644 index 000000000..33949b660 --- /dev/null +++ b/lib/mesa/src/gallium/state_trackers/wgl/stw_getprocaddress.c @@ -0,0 +1,112 @@ +/************************************************************************** + * + * Copyright 2008 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS 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 + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include <windows.h> + +#define WGL_WGLEXT_PROTOTYPES + +#include <GL/gl.h> +#include <GL/wglext.h> + +#include "glapi/glapi.h" +#include "stw_device.h" +#include "stw_icd.h" +#include "stw_nopfuncs.h" + +struct stw_extension_entry +{ + const char *name; + PROC proc; +}; + +#define STW_EXTENSION_ENTRY(P) { #P, (PROC) P } + +static const struct stw_extension_entry stw_extension_entries[] = { + + /* WGL_ARB_extensions_string */ + STW_EXTENSION_ENTRY( wglGetExtensionsStringARB ), + + /* WGL_ARB_pbuffer */ + STW_EXTENSION_ENTRY( wglCreatePbufferARB ), + STW_EXTENSION_ENTRY( wglGetPbufferDCARB ), + STW_EXTENSION_ENTRY( wglReleasePbufferDCARB ), + STW_EXTENSION_ENTRY( wglDestroyPbufferARB ), + STW_EXTENSION_ENTRY( wglQueryPbufferARB ), + + /* WGL_ARB_pixel_format */ + STW_EXTENSION_ENTRY( wglChoosePixelFormatARB ), + STW_EXTENSION_ENTRY( wglGetPixelFormatAttribfvARB ), + STW_EXTENSION_ENTRY( wglGetPixelFormatAttribivARB ), + + /* WGL_EXT_extensions_string */ + STW_EXTENSION_ENTRY( wglGetExtensionsStringEXT ), + + /* WGL_EXT_swap_interval */ + STW_EXTENSION_ENTRY( wglGetSwapIntervalEXT ), + STW_EXTENSION_ENTRY( wglSwapIntervalEXT ), + + /* WGL_ARB_create_context */ + STW_EXTENSION_ENTRY( wglCreateContextAttribsARB ), + + { NULL, NULL } +}; + +PROC APIENTRY +DrvGetProcAddress( + LPCSTR lpszProc ) +{ + const struct stw_extension_entry *entry; + PROC p; + + if (!stw_dev) + return NULL; + + if (lpszProc[0] == 'w' && lpszProc[1] == 'g' && lpszProc[2] == 'l') + for (entry = stw_extension_entries; entry->name; entry++) + if (strcmp( lpszProc, entry->name ) == 0) + return entry->proc; + + if (lpszProc[0] == 'g' && lpszProc[1] == 'l') { + p = (PROC) _glapi_get_proc_address(lpszProc); + if (p) + return p; + } + + /* If we get here, we'd normally just return NULL, but since some apps + * (like Viewperf12) crash when they try to use the null pointer, try + * returning a pointer to a no-op function instead. + */ + p = stw_get_nop_function(lpszProc); + if (p) { + debug_printf("wglGetProcAddress(\"%s\") returning no-op function\n", + lpszProc); + return p; + } + + debug_printf("wglGetProcAddress(\"%s\") returning NULL\n", lpszProc); + return NULL; +} diff --git a/lib/mesa/src/gallium/state_trackers/wgl/stw_icd.h b/lib/mesa/src/gallium/state_trackers/wgl/stw_icd.h new file mode 100644 index 000000000..9f386c9c1 --- /dev/null +++ b/lib/mesa/src/gallium/state_trackers/wgl/stw_icd.h @@ -0,0 +1,618 @@ +/************************************************************************** + * + * Copyright 2008-2009 Vmware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS 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 + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * @file + * + * This header defines the interface used by the system's opengl32.dll and the + * Installable Client Driver (ICD). + */ + +#ifndef STW_ICD_H +#define STW_ICD_H + + +#include <windows.h> + +#include "GL/gl.h" + + +typedef ULONG DHGLRC; + +#define OPENGL_VERSION_110_ENTRIES 336 + +struct __GLdispatchTableRec +{ + void (GLAPIENTRY * NewList)(GLuint, GLenum); + void (GLAPIENTRY * EndList)(void); + void (GLAPIENTRY * CallList)(GLuint); + void (GLAPIENTRY * CallLists)(GLsizei, GLenum, const GLvoid *); + void (GLAPIENTRY * DeleteLists)(GLuint, GLsizei); + GLuint (GLAPIENTRY * GenLists)(GLsizei); + void (GLAPIENTRY * ListBase)(GLuint); + void (GLAPIENTRY * Begin)(GLenum); + void (GLAPIENTRY * Bitmap)(GLsizei, GLsizei, GLfloat, GLfloat, GLfloat, GLfloat, const GLubyte *); + void (GLAPIENTRY * Color3b)(GLbyte, GLbyte, GLbyte); + void (GLAPIENTRY * Color3bv)(const GLbyte *); + void (GLAPIENTRY * Color3d)(GLdouble, GLdouble, GLdouble); + void (GLAPIENTRY * Color3dv)(const GLdouble *); + void (GLAPIENTRY * Color3f)(GLfloat, GLfloat, GLfloat); + void (GLAPIENTRY * Color3fv)(const GLfloat *); + void (GLAPIENTRY * Color3i)(GLint, GLint, GLint); + void (GLAPIENTRY * Color3iv)(const GLint *); + void (GLAPIENTRY * Color3s)(GLshort, GLshort, GLshort); + void (GLAPIENTRY * Color3sv)(const GLshort *); + void (GLAPIENTRY * Color3ub)(GLubyte, GLubyte, GLubyte); + void (GLAPIENTRY * Color3ubv)(const GLubyte *); + void (GLAPIENTRY * Color3ui)(GLuint, GLuint, GLuint); + void (GLAPIENTRY * Color3uiv)(const GLuint *); + void (GLAPIENTRY * Color3us)(GLushort, GLushort, GLushort); + void (GLAPIENTRY * Color3usv)(const GLushort *); + void (GLAPIENTRY * Color4b)(GLbyte, GLbyte, GLbyte, GLbyte); + void (GLAPIENTRY * Color4bv)(const GLbyte *); + void (GLAPIENTRY * Color4d)(GLdouble, GLdouble, GLdouble, GLdouble); + void (GLAPIENTRY * Color4dv)(const GLdouble *); + void (GLAPIENTRY * Color4f)(GLfloat, GLfloat, GLfloat, GLfloat); + void (GLAPIENTRY * Color4fv)(const GLfloat *); + void (GLAPIENTRY * Color4i)(GLint, GLint, GLint, GLint); + void (GLAPIENTRY * Color4iv)(const GLint *); + void (GLAPIENTRY * Color4s)(GLshort, GLshort, GLshort, GLshort); + void (GLAPIENTRY * Color4sv)(const GLshort *); + void (GLAPIENTRY * Color4ub)(GLubyte, GLubyte, GLubyte, GLubyte); + void (GLAPIENTRY * Color4ubv)(const GLubyte *); + void (GLAPIENTRY * Color4ui)(GLuint, GLuint, GLuint, GLuint); + void (GLAPIENTRY * Color4uiv)(const GLuint *); + void (GLAPIENTRY * Color4us)(GLushort, GLushort, GLushort, GLushort); + void (GLAPIENTRY * Color4usv)(const GLushort *); + void (GLAPIENTRY * EdgeFlag)(GLboolean); + void (GLAPIENTRY * EdgeFlagv)(const GLboolean *); + void (GLAPIENTRY * End)(void); + void (GLAPIENTRY * Indexd)(GLdouble); + void (GLAPIENTRY * Indexdv)(const GLdouble *); + void (GLAPIENTRY * Indexf)(GLfloat); + void (GLAPIENTRY * Indexfv)(const GLfloat *); + void (GLAPIENTRY * Indexi)(GLint); + void (GLAPIENTRY * Indexiv)(const GLint *); + void (GLAPIENTRY * Indexs)(GLshort); + void (GLAPIENTRY * Indexsv)(const GLshort *); + void (GLAPIENTRY * Normal3b)(GLbyte, GLbyte, GLbyte); + void (GLAPIENTRY * Normal3bv)(const GLbyte *); + void (GLAPIENTRY * Normal3d)(GLdouble, GLdouble, GLdouble); + void (GLAPIENTRY * Normal3dv)(const GLdouble *); + void (GLAPIENTRY * Normal3f)(GLfloat, GLfloat, GLfloat); + void (GLAPIENTRY * Normal3fv)(const GLfloat *); + void (GLAPIENTRY * Normal3i)(GLint, GLint, GLint); + void (GLAPIENTRY * Normal3iv)(const GLint *); + void (GLAPIENTRY * Normal3s)(GLshort, GLshort, GLshort); + void (GLAPIENTRY * Normal3sv)(const GLshort *); + void (GLAPIENTRY * RasterPos2d)(GLdouble, GLdouble); + void (GLAPIENTRY * RasterPos2dv)(const GLdouble *); + void (GLAPIENTRY * RasterPos2f)(GLfloat, GLfloat); + void (GLAPIENTRY * RasterPos2fv)(const GLfloat *); + void (GLAPIENTRY * RasterPos2i)(GLint, GLint); + void (GLAPIENTRY * RasterPos2iv)(const GLint *); + void (GLAPIENTRY * RasterPos2s)(GLshort, GLshort); + void (GLAPIENTRY * RasterPos2sv)(const GLshort *); + void (GLAPIENTRY * RasterPos3d)(GLdouble, GLdouble, GLdouble); + void (GLAPIENTRY * RasterPos3dv)(const GLdouble *); + void (GLAPIENTRY * RasterPos3f)(GLfloat, GLfloat, GLfloat); + void (GLAPIENTRY * RasterPos3fv)(const GLfloat *); + void (GLAPIENTRY * RasterPos3i)(GLint, GLint, GLint); + void (GLAPIENTRY * RasterPos3iv)(const GLint *); + void (GLAPIENTRY * RasterPos3s)(GLshort, GLshort, GLshort); + void (GLAPIENTRY * RasterPos3sv)(const GLshort *); + void (GLAPIENTRY * RasterPos4d)(GLdouble, GLdouble, GLdouble, GLdouble); + void (GLAPIENTRY * RasterPos4dv)(const GLdouble *); + void (GLAPIENTRY * RasterPos4f)(GLfloat, GLfloat, GLfloat, GLfloat); + void (GLAPIENTRY * RasterPos4fv)(const GLfloat *); + void (GLAPIENTRY * RasterPos4i)(GLint, GLint, GLint, GLint); + void (GLAPIENTRY * RasterPos4iv)(const GLint *); + void (GLAPIENTRY * RasterPos4s)(GLshort, GLshort, GLshort, GLshort); + void (GLAPIENTRY * RasterPos4sv)(const GLshort *); + void (GLAPIENTRY * Rectd)(GLdouble, GLdouble, GLdouble, GLdouble); + void (GLAPIENTRY * Rectdv)(const GLdouble *, const GLdouble *); + void (GLAPIENTRY * Rectf)(GLfloat, GLfloat, GLfloat, GLfloat); + void (GLAPIENTRY * Rectfv)(const GLfloat *, const GLfloat *); + void (GLAPIENTRY * Recti)(GLint, GLint, GLint, GLint); + void (GLAPIENTRY * Rectiv)(const GLint *, const GLint *); + void (GLAPIENTRY * Rects)(GLshort, GLshort, GLshort, GLshort); + void (GLAPIENTRY * Rectsv)(const GLshort *, const GLshort *); + void (GLAPIENTRY * TexCoord1d)(GLdouble); + void (GLAPIENTRY * TexCoord1dv)(const GLdouble *); + void (GLAPIENTRY * TexCoord1f)(GLfloat); + void (GLAPIENTRY * TexCoord1fv)(const GLfloat *); + void (GLAPIENTRY * TexCoord1i)(GLint); + void (GLAPIENTRY * TexCoord1iv)(const GLint *); + void (GLAPIENTRY * TexCoord1s)(GLshort); + void (GLAPIENTRY * TexCoord1sv)(const GLshort *); + void (GLAPIENTRY * TexCoord2d)(GLdouble, GLdouble); + void (GLAPIENTRY * TexCoord2dv)(const GLdouble *); + void (GLAPIENTRY * TexCoord2f)(GLfloat, GLfloat); + void (GLAPIENTRY * TexCoord2fv)(const GLfloat *); + void (GLAPIENTRY * TexCoord2i)(GLint, GLint); + void (GLAPIENTRY * TexCoord2iv)(const GLint *); + void (GLAPIENTRY * TexCoord2s)(GLshort, GLshort); + void (GLAPIENTRY * TexCoord2sv)(const GLshort *); + void (GLAPIENTRY * TexCoord3d)(GLdouble, GLdouble, GLdouble); + void (GLAPIENTRY * TexCoord3dv)(const GLdouble *); + void (GLAPIENTRY * TexCoord3f)(GLfloat, GLfloat, GLfloat); + void (GLAPIENTRY * TexCoord3fv)(const GLfloat *); + void (GLAPIENTRY * TexCoord3i)(GLint, GLint, GLint); + void (GLAPIENTRY * TexCoord3iv)(const GLint *); + void (GLAPIENTRY * TexCoord3s)(GLshort, GLshort, GLshort); + void (GLAPIENTRY * TexCoord3sv)(const GLshort *); + void (GLAPIENTRY * TexCoord4d)(GLdouble, GLdouble, GLdouble, GLdouble); + void (GLAPIENTRY * TexCoord4dv)(const GLdouble *); + void (GLAPIENTRY * TexCoord4f)(GLfloat, GLfloat, GLfloat, GLfloat); + void (GLAPIENTRY * TexCoord4fv)(const GLfloat *); + void (GLAPIENTRY * TexCoord4i)(GLint, GLint, GLint, GLint); + void (GLAPIENTRY * TexCoord4iv)(const GLint *); + void (GLAPIENTRY * TexCoord4s)(GLshort, GLshort, GLshort, GLshort); + void (GLAPIENTRY * TexCoord4sv)(const GLshort *); + void (GLAPIENTRY * Vertex2d)(GLdouble, GLdouble); + void (GLAPIENTRY * Vertex2dv)(const GLdouble *); + void (GLAPIENTRY * Vertex2f)(GLfloat, GLfloat); + void (GLAPIENTRY * Vertex2fv)(const GLfloat *); + void (GLAPIENTRY * Vertex2i)(GLint, GLint); + void (GLAPIENTRY * Vertex2iv)(const GLint *); + void (GLAPIENTRY * Vertex2s)(GLshort, GLshort); + void (GLAPIENTRY * Vertex2sv)(const GLshort *); + void (GLAPIENTRY * Vertex3d)(GLdouble, GLdouble, GLdouble); + void (GLAPIENTRY * Vertex3dv)(const GLdouble *); + void (GLAPIENTRY * Vertex3f)(GLfloat, GLfloat, GLfloat); + void (GLAPIENTRY * Vertex3fv)(const GLfloat *); + void (GLAPIENTRY * Vertex3i)(GLint, GLint, GLint); + void (GLAPIENTRY * Vertex3iv)(const GLint *); + void (GLAPIENTRY * Vertex3s)(GLshort, GLshort, GLshort); + void (GLAPIENTRY * Vertex3sv)(const GLshort *); + void (GLAPIENTRY * Vertex4d)(GLdouble, GLdouble, GLdouble, GLdouble); + void (GLAPIENTRY * Vertex4dv)(const GLdouble *); + void (GLAPIENTRY * Vertex4f)(GLfloat, GLfloat, GLfloat, GLfloat); + void (GLAPIENTRY * Vertex4fv)(const GLfloat *); + void (GLAPIENTRY * Vertex4i)(GLint, GLint, GLint, GLint); + void (GLAPIENTRY * Vertex4iv)(const GLint *); + void (GLAPIENTRY * Vertex4s)(GLshort, GLshort, GLshort, GLshort); + void (GLAPIENTRY * Vertex4sv)(const GLshort *); + void (GLAPIENTRY * ClipPlane)(GLenum, const GLdouble *); + void (GLAPIENTRY * ColorMaterial)(GLenum, GLenum); + void (GLAPIENTRY * CullFace)(GLenum); + void (GLAPIENTRY * Fogf)(GLenum, GLfloat); + void (GLAPIENTRY * Fogfv)(GLenum, const GLfloat *); + void (GLAPIENTRY * Fogi)(GLenum, GLint); + void (GLAPIENTRY * Fogiv)(GLenum, const GLint *); + void (GLAPIENTRY * FrontFace)(GLenum); + void (GLAPIENTRY * Hint)(GLenum, GLenum); + void (GLAPIENTRY * Lightf)(GLenum, GLenum, GLfloat); + void (GLAPIENTRY * Lightfv)(GLenum, GLenum, const GLfloat *); + void (GLAPIENTRY * Lighti)(GLenum, GLenum, GLint); + void (GLAPIENTRY * Lightiv)(GLenum, GLenum, const GLint *); + void (GLAPIENTRY * LightModelf)(GLenum, GLfloat); + void (GLAPIENTRY * LightModelfv)(GLenum, const GLfloat *); + void (GLAPIENTRY * LightModeli)(GLenum, GLint); + void (GLAPIENTRY * LightModeliv)(GLenum, const GLint *); + void (GLAPIENTRY * LineStipple)(GLint, GLushort); + void (GLAPIENTRY * LineWidth)(GLfloat); + void (GLAPIENTRY * Materialf)(GLenum, GLenum, GLfloat); + void (GLAPIENTRY * Materialfv)(GLenum, GLenum, const GLfloat *); + void (GLAPIENTRY * Materiali)(GLenum, GLenum, GLint); + void (GLAPIENTRY * Materialiv)(GLenum, GLenum, const GLint *); + void (GLAPIENTRY * PointSize)(GLfloat); + void (GLAPIENTRY * PolygonMode)(GLenum, GLenum); + void (GLAPIENTRY * PolygonStipple)(const GLubyte *); + void (GLAPIENTRY * Scissor)(GLint, GLint, GLsizei, GLsizei); + void (GLAPIENTRY * ShadeModel)(GLenum); + void (GLAPIENTRY * TexParameterf)(GLenum, GLenum, GLfloat); + void (GLAPIENTRY * TexParameterfv)(GLenum, GLenum, const GLfloat *); + void (GLAPIENTRY * TexParameteri)(GLenum, GLenum, GLint); + void (GLAPIENTRY * TexParameteriv)(GLenum, GLenum, const GLint *); + void (GLAPIENTRY * TexImage1D)(GLenum, GLint, GLint, GLsizei, GLint, GLenum, GLenum, const GLvoid *); + void (GLAPIENTRY * TexImage2D)(GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); + void (GLAPIENTRY * TexEnvf)(GLenum, GLenum, GLfloat); + void (GLAPIENTRY * TexEnvfv)(GLenum, GLenum, const GLfloat *); + void (GLAPIENTRY * TexEnvi)(GLenum, GLenum, GLint); + void (GLAPIENTRY * TexEnviv)(GLenum, GLenum, const GLint *); + void (GLAPIENTRY * TexGend)(GLenum, GLenum, GLdouble); + void (GLAPIENTRY * TexGendv)(GLenum, GLenum, const GLdouble *); + void (GLAPIENTRY * TexGenf)(GLenum, GLenum, GLfloat); + void (GLAPIENTRY * TexGenfv)(GLenum, GLenum, const GLfloat *); + void (GLAPIENTRY * TexGeni)(GLenum, GLenum, GLint); + void (GLAPIENTRY * TexGeniv)(GLenum, GLenum, const GLint *); + void (GLAPIENTRY * FeedbackBuffer)(GLsizei, GLenum, GLfloat *); + void (GLAPIENTRY * SelectBuffer)(GLsizei, GLuint *); + GLint (GLAPIENTRY * RenderMode)(GLenum); + void (GLAPIENTRY * InitNames)(void); + void (GLAPIENTRY * LoadName)(GLuint); + void (GLAPIENTRY * PassThrough)(GLfloat); + void (GLAPIENTRY * PopName)(void); + void (GLAPIENTRY * PushName)(GLuint); + void (GLAPIENTRY * DrawBuffer)(GLenum); + void (GLAPIENTRY * Clear)(GLbitfield); + void (GLAPIENTRY * ClearAccum)(GLfloat, GLfloat, GLfloat, GLfloat); + void (GLAPIENTRY * ClearIndex)(GLfloat); + void (GLAPIENTRY * ClearColor)(GLclampf, GLclampf, GLclampf, GLclampf); + void (GLAPIENTRY * ClearStencil)(GLint); + void (GLAPIENTRY * ClearDepth)(GLclampd); + void (GLAPIENTRY * StencilMask)(GLuint); + void (GLAPIENTRY * ColorMask)(GLboolean, GLboolean, GLboolean, GLboolean); + void (GLAPIENTRY * DepthMask)(GLboolean); + void (GLAPIENTRY * IndexMask)(GLuint); + void (GLAPIENTRY * Accum)(GLenum, GLfloat); + void (GLAPIENTRY * Disable)(GLenum); + void (GLAPIENTRY * Enable)(GLenum); + void (GLAPIENTRY * Finish)(void); + void (GLAPIENTRY * Flush)(void); + void (GLAPIENTRY * PopAttrib)(void); + void (GLAPIENTRY * PushAttrib)(GLbitfield); + void (GLAPIENTRY * Map1d)(GLenum, GLdouble, GLdouble, GLint, GLint, const GLdouble *); + void (GLAPIENTRY * Map1f)(GLenum, GLfloat, GLfloat, GLint, GLint, const GLfloat *); + void (GLAPIENTRY * Map2d)(GLenum, GLdouble, GLdouble, GLint, GLint, GLdouble, GLdouble, GLint, GLint, const GLdouble *); + void (GLAPIENTRY * Map2f)(GLenum, GLfloat, GLfloat, GLint, GLint, GLfloat, GLfloat, GLint, GLint, const GLfloat *); + void (GLAPIENTRY * MapGrid1d)(GLint, GLdouble, GLdouble); + void (GLAPIENTRY * MapGrid1f)(GLint, GLfloat, GLfloat); + void (GLAPIENTRY * MapGrid2d)(GLint, GLdouble, GLdouble, GLint, GLdouble, GLdouble); + void (GLAPIENTRY * MapGrid2f)(GLint, GLfloat, GLfloat, GLint, GLfloat, GLfloat); + void (GLAPIENTRY * EvalCoord1d)(GLdouble); + void (GLAPIENTRY * EvalCoord1dv)(const GLdouble *); + void (GLAPIENTRY * EvalCoord1f)(GLfloat); + void (GLAPIENTRY * EvalCoord1fv)(const GLfloat *); + void (GLAPIENTRY * EvalCoord2d)(GLdouble, GLdouble); + void (GLAPIENTRY * EvalCoord2dv)(const GLdouble *); + void (GLAPIENTRY * EvalCoord2f)(GLfloat, GLfloat); + void (GLAPIENTRY * EvalCoord2fv)(const GLfloat *); + void (GLAPIENTRY * EvalMesh1)(GLenum, GLint, GLint); + void (GLAPIENTRY * EvalPoint1)(GLint); + void (GLAPIENTRY * EvalMesh2)(GLenum, GLint, GLint, GLint, GLint); + void (GLAPIENTRY * EvalPoint2)(GLint, GLint); + void (GLAPIENTRY * AlphaFunc)(GLenum, GLclampf); + void (GLAPIENTRY * BlendFunc)(GLenum, GLenum); + void (GLAPIENTRY * LogicOp)(GLenum); + void (GLAPIENTRY * StencilFunc)(GLenum, GLint, GLuint); + void (GLAPIENTRY * StencilOp)(GLenum, GLenum, GLenum); + void (GLAPIENTRY * DepthFunc)(GLenum); + void (GLAPIENTRY * PixelZoom)(GLfloat, GLfloat); + void (GLAPIENTRY * PixelTransferf)(GLenum, GLfloat); + void (GLAPIENTRY * PixelTransferi)(GLenum, GLint); + void (GLAPIENTRY * PixelStoref)(GLenum, GLfloat); + void (GLAPIENTRY * PixelStorei)(GLenum, GLint); + void (GLAPIENTRY * PixelMapfv)(GLenum, GLint, const GLfloat *); + void (GLAPIENTRY * PixelMapuiv)(GLenum, GLint, const GLuint *); + void (GLAPIENTRY * PixelMapusv)(GLenum, GLint, const GLushort *); + void (GLAPIENTRY * ReadBuffer)(GLenum); + void (GLAPIENTRY * CopyPixels)(GLint, GLint, GLsizei, GLsizei, GLenum); + void (GLAPIENTRY * ReadPixels)(GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, GLvoid *); + void (GLAPIENTRY * DrawPixels)(GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); + void (GLAPIENTRY * GetBooleanv)(GLenum, GLboolean *); + void (GLAPIENTRY * GetClipPlane)(GLenum, GLdouble *); + void (GLAPIENTRY * GetDoublev)(GLenum, GLdouble *); + GLenum (GLAPIENTRY * GetError)(void); + void (GLAPIENTRY * GetFloatv)(GLenum, GLfloat *); + void (GLAPIENTRY * GetIntegerv)(GLenum, GLint *); + void (GLAPIENTRY * GetLightfv)(GLenum, GLenum, GLfloat *); + void (GLAPIENTRY * GetLightiv)(GLenum, GLenum, GLint *); + void (GLAPIENTRY * GetMapdv)(GLenum, GLenum, GLdouble *); + void (GLAPIENTRY * GetMapfv)(GLenum, GLenum, GLfloat *); + void (GLAPIENTRY * GetMapiv)(GLenum, GLenum, GLint *); + void (GLAPIENTRY * GetMaterialfv)(GLenum, GLenum, GLfloat *); + void (GLAPIENTRY * GetMaterialiv)(GLenum, GLenum, GLint *); + void (GLAPIENTRY * GetPixelMapfv)(GLenum, GLfloat *); + void (GLAPIENTRY * GetPixelMapuiv)(GLenum, GLuint *); + void (GLAPIENTRY * GetPixelMapusv)(GLenum, GLushort *); + void (GLAPIENTRY * GetPolygonStipple)(GLubyte *); + const GLubyte * (GLAPIENTRY * GetString)(GLenum); + void (GLAPIENTRY * GetTexEnvfv)(GLenum, GLenum, GLfloat *); + void (GLAPIENTRY * GetTexEnviv)(GLenum, GLenum, GLint *); + void (GLAPIENTRY * GetTexGendv)(GLenum, GLenum, GLdouble *); + void (GLAPIENTRY * GetTexGenfv)(GLenum, GLenum, GLfloat *); + void (GLAPIENTRY * GetTexGeniv)(GLenum, GLenum, GLint *); + void (GLAPIENTRY * GetTexImage)(GLenum, GLint, GLenum, GLenum, GLvoid *); + void (GLAPIENTRY * GetTexParameterfv)(GLenum, GLenum, GLfloat *); + void (GLAPIENTRY * GetTexParameteriv)(GLenum, GLenum, GLint *); + void (GLAPIENTRY * GetTexLevelParameterfv)(GLenum, GLint, GLenum, GLfloat *); + void (GLAPIENTRY * GetTexLevelParameteriv)(GLenum, GLint, GLenum, GLint *); + GLboolean (GLAPIENTRY * IsEnabled)(GLenum); + GLboolean (GLAPIENTRY * IsList)(GLuint); + void (GLAPIENTRY * DepthRange)(GLclampd, GLclampd); + void (GLAPIENTRY * Frustum)(GLdouble, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble); + void (GLAPIENTRY * LoadIdentity)(void); + void (GLAPIENTRY * LoadMatrixf)(const GLfloat *); + void (GLAPIENTRY * LoadMatrixd)(const GLdouble *); + void (GLAPIENTRY * MatrixMode)(GLenum); + void (GLAPIENTRY * MultMatrixf)(const GLfloat *); + void (GLAPIENTRY * MultMatrixd)(const GLdouble *); + void (GLAPIENTRY * Ortho)(GLdouble, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble); + void (GLAPIENTRY * PopMatrix)(void); + void (GLAPIENTRY * PushMatrix)(void); + void (GLAPIENTRY * Rotated)(GLdouble, GLdouble, GLdouble, GLdouble); + void (GLAPIENTRY * Rotatef)(GLfloat, GLfloat, GLfloat, GLfloat); + void (GLAPIENTRY * Scaled)(GLdouble, GLdouble, GLdouble); + void (GLAPIENTRY * Scalef)(GLfloat, GLfloat, GLfloat); + void (GLAPIENTRY * Translated)(GLdouble, GLdouble, GLdouble); + void (GLAPIENTRY * Translatef)(GLfloat, GLfloat, GLfloat); + void (GLAPIENTRY * Viewport)(GLint, GLint, GLsizei, GLsizei); + void (GLAPIENTRY * ArrayElement)(GLint); + void (GLAPIENTRY * BindTexture)(GLenum, GLuint); + void (GLAPIENTRY * ColorPointer)(GLint, GLenum, GLsizei, const GLvoid *); + void (GLAPIENTRY * DisableClientState)(GLenum); + void (GLAPIENTRY * DrawArrays)(GLenum, GLint, GLsizei); + void (GLAPIENTRY * DrawElements)(GLenum, GLsizei, GLenum, const GLvoid *); + void (GLAPIENTRY * EdgeFlagPointer)(GLsizei, const GLvoid *); + void (GLAPIENTRY * EnableClientState)(GLenum); + void (GLAPIENTRY * IndexPointer)(GLenum, GLsizei, const GLvoid *); + void (GLAPIENTRY * Indexub)(GLubyte); + void (GLAPIENTRY * Indexubv)(const GLubyte *); + void (GLAPIENTRY * InterleavedArrays)(GLenum, GLsizei, const GLvoid *); + void (GLAPIENTRY * NormalPointer)(GLenum, GLsizei, const GLvoid *); + void (GLAPIENTRY * PolygonOffset)(GLfloat, GLfloat); + void (GLAPIENTRY * TexCoordPointer)(GLint, GLenum, GLsizei, const GLvoid *); + void (GLAPIENTRY * VertexPointer)(GLint, GLenum, GLsizei, const GLvoid *); + GLboolean (GLAPIENTRY * AreTexturesResident)(GLsizei, const GLuint *, GLboolean *); + void (GLAPIENTRY * CopyTexImage1D)(GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLint); + void (GLAPIENTRY * CopyTexImage2D)(GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint); + void (GLAPIENTRY * CopyTexSubImage1D)(GLenum, GLint, GLint, GLint, GLint, GLsizei); + void (GLAPIENTRY * CopyTexSubImage2D)(GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); + void (GLAPIENTRY * DeleteTextures)(GLsizei, const GLuint *); + void (GLAPIENTRY * GenTextures)(GLsizei, GLuint *); + void (GLAPIENTRY * GetPointerv)(GLenum, GLvoid **); + GLboolean (GLAPIENTRY * IsTexture)(GLuint); + void (GLAPIENTRY * PrioritizeTextures)(GLsizei, const GLuint *, const GLclampf *); + void (GLAPIENTRY * TexSubImage1D)(GLenum, GLint, GLint, GLsizei, GLenum, GLenum, const GLvoid *); + void (GLAPIENTRY * TexSubImage2D)(GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); + void (GLAPIENTRY * PopClientAttrib)(void); + void (GLAPIENTRY * PushClientAttrib)(GLbitfield); +}; + +typedef struct __GLdispatchTableRec GLDISPATCHTABLE; + +typedef struct _GLCLTPROCTABLE +{ + int cEntries; + GLDISPATCHTABLE glDispatchTable; +} GLCLTPROCTABLE, * PGLCLTPROCTABLE; + +typedef VOID (APIENTRY * PFN_SETPROCTABLE)(PGLCLTPROCTABLE); + +/** + * Presentation data passed to opengl32!wglCbPresentBuffers. + * + * Pure software drivers don't need to worry about this -- if they stick to the + * GDI API then will integrate with the Desktop Window Manager (DWM) without + * problems. Hardware drivers, however, cannot present directly to the primary + * surface while the DWM is active, as DWM gets exclusive access to the primary + * surface. + * + * Proper DWM integration requires: + * - advertise the PFD_SUPPORT_COMPOSITION flag + * - redirect glFlush/glfinish/wglSwapBuffers into a surface shared with the + * DWM process. + * + * @sa http://www.opengl.org/pipeline/article/vol003_7/ + * @sa http://blogs.msdn.com/greg_schechter/archive/2006/05/02/588934.aspx + */ +typedef struct _GLCBPRESENTBUFFERSDATA +{ + /** + * wglCbPresentBuffers enforces this to be 2. + */ + DWORD magic1; + + /** + * wglCbPresentBuffers enforces to be 0 or 1, but it is most commonly + * set to 0. + */ + DWORD magic2; + + /** + * Locally unique identifier (LUID) of the graphics adapter. + * + * This should contain the value returned by D3DKMTOpenAdapterFromHdc. It + * is passed to dwmapi!DwmpDxGetWindowSharedSurface in order to obtain + * the shared surface handle for the bound drawable (window). + * + * @sa http://msdn.microsoft.com/en-us/library/ms799177.aspx + */ + LUID AdapterLuid; + + /** + * This is passed unmodified to DrvPresentBuffers + */ + LPVOID pPrivateData; + + /** + * Client area rectangle to update, relative to the window upper-left corner. + */ + RECT rect; +} GLCBPRESENTBUFFERSDATA, *PGLCBPRESENTBUFFERSDATA; + +/** + * Callbacks supplied to DrvSetCallbackProcs by the OpenGL runtime. + * + * Pointers to several callback functions in opengl32.dll. + */ +typedef struct _GLCALLBACKTABLE +{ + /** + * Set per-thread driver private data. + * + * Unused. + **/ + void (APIENTRY *wglCbSetCurrentValue)(void *pvData); + + /** + * Get per-thread private data. + * + * Unused. + */ + void * (APIENTRY *wglCbGetCurrentValue)(void); + + /** + * Get the ICD GHGLRC handle corresponding to the specified hglrc handle. + * + * Currently unused. + */ + DHGLRC (APIENTRY *wglCbGetDhglrc)(HGLRC hglrc); + + /** Unused */ + PROC wglCbGetDdHandle; + + /** + * Queue a present composition. + * + * Makes the runtime call DrvPresentBuffers with the composition information. + */ + BOOL (APIENTRY *wglCbPresentBuffers)(HDC hdc, PGLCBPRESENTBUFFERSDATA data); + +} GLCALLBACKTABLE; + +typedef struct _GLPRESENTBUFFERSDATA +{ + /** + * The shared surface handle. + * + * Return by dwmapi!DwmpDxGetWindowSharedSurface. + * + * @sa http://channel9.msdn.com/forums/TechOff/251261-Help-Getting-the-shared-window-texture-out-of-DWM-/ + */ + HANDLE hSharedSurface; + + LUID AdapterLuid; + + /** + * Present history token. + * + * This is returned by dwmapi!DwmpDxGetWindowSharedSurface and + * should be passed to D3DKMTRender in D3DKMT_RENDER::PresentHistoryToken. + * + * @sa http://msdn.microsoft.com/en-us/library/ms799176.aspx + */ + ULONGLONG PresentHistoryToken; + + /** Same as GLCBPRESENTBUFFERSDATA::pPrivateData */ + LPVOID pPrivateData; +} GLPRESENTBUFFERSDATA, *PGLPRESENTBUFFERSDATA; + +BOOL APIENTRY +DrvCopyContext( + DHGLRC dhrcSource, + DHGLRC dhrcDest, + UINT fuMask ); + +DHGLRC APIENTRY +DrvCreateLayerContext( + HDC hdc, + INT iLayerPlane ); + +DHGLRC APIENTRY +DrvCreateContext( + HDC hdc ); + +BOOL APIENTRY +DrvDeleteContext( + DHGLRC dhglrc ); + +BOOL APIENTRY +DrvDescribeLayerPlane( + HDC hdc, + INT iPixelFormat, + INT iLayerPlane, + UINT nBytes, + LPLAYERPLANEDESCRIPTOR plpd ); + +LONG APIENTRY +DrvDescribePixelFormat( + HDC hdc, + INT iPixelFormat, + ULONG cjpfd, + PIXELFORMATDESCRIPTOR *ppfd ); + +int APIENTRY +DrvGetLayerPaletteEntries( + HDC hdc, + INT iLayerPlane, + INT iStart, + INT cEntries, + COLORREF *pcr ); + +PROC APIENTRY +DrvGetProcAddress( + LPCSTR lpszProc ); + +BOOL APIENTRY +DrvPresentBuffers(HDC hdc, PGLPRESENTBUFFERSDATA data); + +BOOL APIENTRY +DrvRealizeLayerPalette( + HDC hdc, + INT iLayerPlane, + BOOL bRealize ); + +BOOL APIENTRY +DrvReleaseContext( + DHGLRC dhglrc ); + +void APIENTRY +DrvSetCallbackProcs( + INT nProcs, + PROC *pProcs ); + +PGLCLTPROCTABLE APIENTRY +DrvSetContext( + HDC hdc, + DHGLRC dhglrc, + PFN_SETPROCTABLE pfnSetProcTable ); + +int APIENTRY +DrvSetLayerPaletteEntries( + HDC hdc, + INT iLayerPlane, + INT iStart, + INT cEntries, + CONST COLORREF *pcr ); + +BOOL APIENTRY +DrvSetPixelFormat( + HDC hdc, + LONG iPixelFormat ); + +BOOL APIENTRY +DrvShareLists( + DHGLRC dhglrc1, + DHGLRC dhglrc2 ); + +BOOL APIENTRY +DrvSwapBuffers( + HDC hdc ); + +BOOL APIENTRY +DrvSwapLayerBuffers( + HDC hdc, + UINT fuPlanes ); + +BOOL APIENTRY +DrvValidateVersion( + ULONG ulVersion ); + +#endif /* STW_ICD_H */ diff --git a/lib/mesa/src/gallium/state_trackers/wgl/stw_nopfuncs.c b/lib/mesa/src/gallium/state_trackers/wgl/stw_nopfuncs.c new file mode 100644 index 000000000..d69c0134f --- /dev/null +++ b/lib/mesa/src/gallium/state_trackers/wgl/stw_nopfuncs.c @@ -0,0 +1,464 @@ +/************************************************************************** + * + * Copyright 2015 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS 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 + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * No-op GL API functions. + * + * Some OpenGL apps (like Viewperf12) call wglGetProcAddress() to get + * a pointer to an extension function, get a NULL pointer, but don't bother + * to check for NULL before jumping through the pointer. This causes a + * crash. + * + * As a work-around we provide some no-op functions here to avoid those + * crashes. + */ + +#include <GL/gl.h> +#include "stw_nopfuncs.h" +#include "util/u_debug.h" + + +static void +warning(const char *name) +{ + /* use name+4 to skip "nop_" prefix */ + _debug_printf("Application calling unsupported %s function\n", name+4); +} + +static void APIENTRY +nop_glBindMultiTextureEXT(GLenum texunit, GLenum target, GLuint texture) +{ + warning(__func__); +} + +static void APIENTRY +nop_glColor3hNV(GLhalfNV red, GLhalfNV green, GLhalfNV blue) +{ + warning(__func__); +} + +static void APIENTRY +nop_glColor3hvNV(const GLhalfNV *v) +{ + warning(__func__); +} + +static void APIENTRY +nop_glColor4hNV(GLhalfNV red, GLhalfNV green, GLhalfNV blue, GLhalfNV alpha) +{ + warning(__func__); +} + +static void APIENTRY +nop_glColor4hvNV(const GLhalfNV *v) +{ + warning(__func__); +} + +static void APIENTRY +nop_glDisableClientStateIndexedEXT(GLenum array, GLuint index) +{ + warning(__func__); +} + +static void APIENTRY +nop_glEnableClientStateIndexedEXT(GLenum array, GLuint index) +{ + warning(__func__); +} + +static void APIENTRY +nop_glFogCoordhNV(GLhalfNV fog) +{ + warning(__func__); +} + +static void APIENTRY +nop_glFogCoordhvNV(const GLhalfNV *fog) +{ + warning(__func__); +} + +static void APIENTRY +nop_glGetNamedBufferParameterivEXT(GLuint buffer, GLenum pname, GLint *params) +{ + warning(__func__); +} + +static void APIENTRY +nop_glGetNamedBufferSubDataEXT(GLuint buffer, GLintptr offset, GLsizeiptr size, void *data) +{ + warning(__func__); +} + +static void *APIENTRY +nop_glMapNamedBufferEXT(GLuint buffer, GLenum access) +{ + warning(__func__); + return NULL; +} + +static void APIENTRY +nop_glMatrixLoadfEXT(GLenum mode, const GLfloat *m) +{ + warning(__func__); +} + +static void APIENTRY +nop_glMatrixLoadIdentityEXT(GLenum mode) +{ + warning(__func__); +} + +static void APIENTRY +nop_glMultiTexCoord1hNV(GLenum target, GLhalfNV s) +{ + warning(__func__); +} + +static void APIENTRY +nop_glMultiTexCoord1hvNV(GLenum target, const GLhalfNV *v) +{ + warning(__func__); +} + +static void APIENTRY +nop_glMultiTexCoord2hNV(GLenum target, GLhalfNV s, GLhalfNV t) +{ + warning(__func__); +} + +static void APIENTRY +nop_glMultiTexCoord2hvNV(GLenum target, const GLhalfNV *v) +{ + warning(__func__); +} + +static void APIENTRY +nop_glMultiTexCoord3hNV(GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r) +{ + warning(__func__); +} + +static void APIENTRY +nop_glMultiTexCoord3hvNV(GLenum target, const GLhalfNV *v) +{ + warning(__func__); +} + +static void APIENTRY +nop_glMultiTexCoord4hNV(GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q) +{ + warning(__func__); +} + +static void APIENTRY +nop_glMultiTexCoord4hvNV(GLenum target, const GLhalfNV *v) +{ + warning(__func__); +} + +static void APIENTRY +nop_glMultiTexCoordPointerEXT(GLenum texunit, GLint size, GLenum type, GLsizei stride, const void *pointer) +{ + warning(__func__); +} + +static void APIENTRY +nop_glMultiTexEnvfEXT(GLenum texunit, GLenum target, GLenum pname, GLfloat param) +{ + warning(__func__); +} + +static void APIENTRY +nop_glMultiTexEnvfvEXT(GLenum texunit, GLenum target, GLenum pname, const GLfloat *params) +{ + warning(__func__); +} + +static void APIENTRY +nop_glMultiTexEnviEXT(GLenum texunit, GLenum target, GLenum pname, GLint param) +{ + warning(__func__); +} + +static void APIENTRY +nop_glMultiTexGenfvEXT(GLenum texunit, GLenum coord, GLenum pname, const GLfloat *params) +{ + warning(__func__); +} + +static void APIENTRY +nop_glMultiTexGeniEXT(GLenum texunit, GLenum coord, GLenum pname, GLint param) +{ + warning(__func__); +} + +static void APIENTRY +nop_glNamedBufferDataEXT(GLuint buffer, GLsizeiptr size, const void *data, GLenum usage) +{ + warning(__func__); +} + +static void APIENTRY +nop_glNamedBufferSubDataEXT(GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data) +{ + warning(__func__); +} + +static void APIENTRY +nop_glNamedProgramLocalParameter4fvEXT(GLuint program, GLenum target, GLuint index, const GLfloat *params) +{ + warning(__func__); +} + +static void APIENTRY +nop_glNamedProgramLocalParameters4fvEXT(GLuint program, GLenum target, GLuint index, GLsizei count, const GLfloat *params) +{ + warning(__func__); +} + +static void APIENTRY +nop_glNormal3hNV(GLhalfNV nx, GLhalfNV ny, GLhalfNV nz) +{ + warning(__func__); +} + +static void APIENTRY +nop_glNormal3hvNV(const GLhalfNV *v) +{ + warning(__func__); +} + +static void APIENTRY +nop_glPatchParameterfv(GLenum pname, const GLfloat *values) +{ + warning(__func__); +} + +static void APIENTRY +nop_glPatchParameteri(GLenum pname, GLint value) +{ + warning(__func__); +} + +static void APIENTRY +nop_glSecondaryColor3hNV(GLhalfNV red, GLhalfNV green, GLhalfNV blue) +{ + warning(__func__); +} + +static void APIENTRY +nop_glSecondaryColor3hvNV(const GLhalfNV *v) +{ + warning(__func__); +} + +static void APIENTRY +nop_glTexCoord1hNV(GLhalfNV s) +{ + warning(__func__); +} + +static void APIENTRY +nop_glTexCoord1hvNV(const GLhalfNV *v) +{ + warning(__func__); +} + +static void APIENTRY +nop_glTexCoord2hNV(GLhalfNV s, GLhalfNV t) +{ + warning(__func__); +} + +static void APIENTRY +nop_glTexCoord2hvNV(const GLhalfNV *v) +{ + warning(__func__); +} + +static void APIENTRY +nop_glTexCoord3hNV(GLhalfNV s, GLhalfNV t, GLhalfNV r) +{ + warning(__func__); +} + +static void APIENTRY +nop_glTexCoord3hvNV(const GLhalfNV *v) +{ + warning(__func__); +} + +static void APIENTRY +nop_glTexCoord4hNV(GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q) +{ + warning(__func__); +} + +static void APIENTRY +nop_glTexCoord4hvNV(const GLhalfNV *v) +{ + warning(__func__); +} + +static void APIENTRY +nop_glTextureParameterfEXT(GLuint texture, GLenum target, GLenum pname, GLfloat param) +{ + warning(__func__); +} + +static void APIENTRY +nop_glTextureParameterfvEXT(GLuint texture, GLenum target, GLenum pname, const GLfloat *params) +{ + warning(__func__); +} + +static void APIENTRY +nop_glTextureParameteriEXT(GLuint texture, GLenum target, GLenum pname, GLint param) +{ + warning(__func__); +} + +static GLboolean APIENTRY +nop_glUnmapNamedBufferEXT(GLuint buffer) +{ + warning(__func__); + return GL_FALSE; +} + +static void APIENTRY +nop_glVertex2hNV(GLhalfNV x, GLhalfNV y) +{ + warning(__func__); +} + +static void APIENTRY +nop_glVertex2hvNV(const GLhalfNV *v) +{ + warning(__func__); +} + +static void APIENTRY +nop_glVertex3hNV(GLhalfNV x, GLhalfNV y, GLhalfNV z) +{ + warning(__func__); +} + +static void APIENTRY +nop_glVertex3hvNV(const GLhalfNV *v) +{ + warning(__func__); +} + +static void APIENTRY +nop_glVertex4hNV(GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w) +{ + warning(__func__); +} + +static void APIENTRY +nop_glVertex4hvNV(const GLhalfNV *v) +{ + warning(__func__); +} + + +PROC +stw_get_nop_function(const char *name) +{ + struct { + const char *name; + PROC p; + } table[] = { + { "glBindMultiTextureEXT", (PROC) nop_glBindMultiTextureEXT }, + { "glColor3hNV", (PROC) nop_glColor3hNV }, + { "glColor3hvNV", (PROC) nop_glColor3hvNV }, + { "glColor4hNV", (PROC) nop_glColor4hNV }, + { "glColor4hvNV", (PROC) nop_glColor4hvNV }, + { "glDisableClientStateIndexedEXT", (PROC) nop_glDisableClientStateIndexedEXT }, + { "glEnableClientStateIndexedEXT", (PROC) nop_glEnableClientStateIndexedEXT }, + { "glFogCoordhNV", (PROC) nop_glFogCoordhNV }, + { "glFogCoordhvNV", (PROC) nop_glFogCoordhvNV }, + { "glGetNamedBufferParameterivEXT", (PROC) nop_glGetNamedBufferParameterivEXT }, + { "glGetNamedBufferSubDataEXT", (PROC) nop_glGetNamedBufferSubDataEXT }, + { "glMapNamedBufferEXT", (PROC) nop_glMapNamedBufferEXT }, + { "glMatrixLoadfEXT", (PROC) nop_glMatrixLoadfEXT }, + { "glMatrixLoadIdentityEXT", (PROC) nop_glMatrixLoadIdentityEXT }, + { "glMultiTexCoord1hNV", (PROC) nop_glMultiTexCoord1hNV }, + { "glMultiTexCoord1hvNV", (PROC) nop_glMultiTexCoord1hvNV }, + { "glMultiTexCoord2hNV", (PROC) nop_glMultiTexCoord2hNV }, + { "glMultiTexCoord2hvNV", (PROC) nop_glMultiTexCoord2hvNV }, + { "glMultiTexCoord3hNV", (PROC) nop_glMultiTexCoord3hNV }, + { "glMultiTexCoord3hvNV", (PROC) nop_glMultiTexCoord3hvNV }, + { "glMultiTexCoord4hNV", (PROC) nop_glMultiTexCoord4hNV }, + { "glMultiTexCoord4hvNV", (PROC) nop_glMultiTexCoord4hvNV }, + { "glMultiTexCoordPointerEXT", (PROC) nop_glMultiTexCoordPointerEXT }, + { "glMultiTexEnvfEXT", (PROC) nop_glMultiTexEnvfEXT }, + { "glMultiTexEnvfvEXT", (PROC) nop_glMultiTexEnvfvEXT }, + { "glMultiTexEnviEXT", (PROC) nop_glMultiTexEnviEXT }, + { "glMultiTexGenfvEXT", (PROC) nop_glMultiTexGenfvEXT }, + { "glMultiTexGeniEXT", (PROC) nop_glMultiTexGeniEXT }, + { "glNamedBufferDataEXT", (PROC) nop_glNamedBufferDataEXT }, + { "glNamedBufferSubDataEXT", (PROC) nop_glNamedBufferSubDataEXT }, + { "glNamedProgramLocalParameter4fvEXT", (PROC) nop_glNamedProgramLocalParameter4fvEXT }, + { "glNamedProgramLocalParameters4fvEXT", (PROC) nop_glNamedProgramLocalParameters4fvEXT }, + { "glNormal3hNV", (PROC) nop_glNormal3hNV }, + { "glNormal3hvNV", (PROC) nop_glNormal3hvNV }, + { "glPatchParameterfv", (PROC) nop_glPatchParameterfv }, + { "glPatchParameteri", (PROC) nop_glPatchParameteri }, + { "glSecondaryColor3hNV", (PROC) nop_glSecondaryColor3hNV }, + { "glSecondaryColor3hvNV", (PROC) nop_glSecondaryColor3hvNV }, + { "glTexCoord1hNV", (PROC) nop_glTexCoord1hNV }, + { "glTexCoord1hvNV", (PROC) nop_glTexCoord1hvNV }, + { "glTexCoord2hNV", (PROC) nop_glTexCoord2hNV }, + { "glTexCoord2hvNV", (PROC) nop_glTexCoord2hvNV }, + { "glTexCoord3hNV", (PROC) nop_glTexCoord3hNV }, + { "glTexCoord3hvNV", (PROC) nop_glTexCoord3hvNV }, + { "glTexCoord4hNV", (PROC) nop_glTexCoord4hNV }, + { "glTexCoord4hvNV", (PROC) nop_glTexCoord4hvNV }, + { "glTextureParameterfEXT", (PROC) nop_glTextureParameterfEXT }, + { "glTextureParameterfvEXT", (PROC) nop_glTextureParameterfvEXT }, + { "glTextureParameteriEXT", (PROC) nop_glTextureParameteriEXT }, + { "glUnmapNamedBufferEXT", (PROC) nop_glUnmapNamedBufferEXT }, + { "glVertex2hNV", (PROC) nop_glVertex2hNV }, + { "glVertex2hvNV", (PROC) nop_glVertex2hvNV }, + { "glVertex3hNV", (PROC) nop_glVertex3hNV }, + { "glVertex3hvNV", (PROC) nop_glVertex3hvNV }, + { "glVertex4hNV", (PROC) nop_glVertex4hNV }, + { "glVertex4hvNV", (PROC) nop_glVertex4hvNV }, + { NULL, NULL } + }; + + int i; + + for (i = 0; table[i].name; i++) { + if (strcmp(table[i].name, name) == 0) + return table[i].p; + } + return NULL; +} diff --git a/lib/mesa/src/gallium/state_trackers/wgl/stw_nopfuncs.h b/lib/mesa/src/gallium/state_trackers/wgl/stw_nopfuncs.h new file mode 100644 index 000000000..f00d420ac --- /dev/null +++ b/lib/mesa/src/gallium/state_trackers/wgl/stw_nopfuncs.h @@ -0,0 +1,11 @@ + + +#ifndef STW_NOPFUNCS_H +#define STW_NOPFUNCS_H + + +PROC +stw_get_nop_function(const char *name); + + +#endif /* STW_NOPFUNCS_H */ diff --git a/lib/mesa/src/gallium/state_trackers/wgl/stw_pixelformat.c b/lib/mesa/src/gallium/state_trackers/wgl/stw_pixelformat.c new file mode 100644 index 000000000..db6cf8ee3 --- /dev/null +++ b/lib/mesa/src/gallium/state_trackers/wgl/stw_pixelformat.c @@ -0,0 +1,458 @@ +/************************************************************************** + * + * Copyright 2008 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS 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 + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "pipe/p_format.h" +#include "pipe/p_defines.h" +#include "pipe/p_screen.h" + +#include "util/u_format.h" +#include "util/u_debug.h" +#include "util/u_memory.h" + +#include "stw_icd.h" +#include "stw_device.h" +#include "stw_pixelformat.h" +#include "stw_tls.h" + + +struct stw_pf_color_info +{ + enum pipe_format format; + struct { + unsigned char red; + unsigned char green; + unsigned char blue; + unsigned char alpha; + } bits; + struct { + unsigned char red; + unsigned char green; + unsigned char blue; + unsigned char alpha; + } shift; +}; + +struct stw_pf_depth_info +{ + enum pipe_format format; + struct { + unsigned char depth; + unsigned char stencil; + } bits; +}; + + +/* NOTE: order matters, since in otherwise equal circumstances the first + * format listed will get chosen */ + +static const struct stw_pf_color_info +stw_pf_color[] = { + /* no-alpha */ + { PIPE_FORMAT_B8G8R8X8_UNORM, { 8, 8, 8, 0}, {16, 8, 0, 0} }, + { PIPE_FORMAT_X8R8G8B8_UNORM, { 8, 8, 8, 0}, { 8, 16, 24, 0} }, + { PIPE_FORMAT_B5G6R5_UNORM, { 5, 6, 5, 0}, {11, 5, 0, 0} }, + /* alpha */ + { PIPE_FORMAT_B8G8R8A8_UNORM, { 8, 8, 8, 8}, {16, 8, 0, 24} }, + { PIPE_FORMAT_A8R8G8B8_UNORM, { 8, 8, 8, 8}, { 8, 16, 24, 0} }, +#if 0 + { PIPE_FORMAT_R10G10B10A2_UNORM, {10, 10, 10, 2}, { 0, 10, 20, 30} }, +#endif + { PIPE_FORMAT_B5G5R5A1_UNORM, { 5, 5, 5, 1}, {10, 5, 0, 15} }, + { PIPE_FORMAT_B4G4R4A4_UNORM, { 4, 4, 4, 4}, {16, 4, 0, 12} } +}; + +static const struct stw_pf_color_info +stw_pf_color_extended[] = { + { PIPE_FORMAT_R32G32B32A32_FLOAT, { 32, 32, 32, 32}, { 0, 32, 64, 96} } +}; + +static const struct stw_pf_depth_info +stw_pf_depth_stencil[] = { + /* pure depth */ + { PIPE_FORMAT_Z32_UNORM, {32, 0} }, + { PIPE_FORMAT_X8Z24_UNORM, {24, 0} }, + { PIPE_FORMAT_Z24X8_UNORM, {24, 0} }, + { PIPE_FORMAT_Z16_UNORM, {16, 0} }, + /* combined depth-stencil */ + { PIPE_FORMAT_Z24_UNORM_S8_UINT, {24, 8} }, + { PIPE_FORMAT_S8_UINT_Z24_UNORM, {24, 8} } +}; + + +static const boolean +stw_pf_doublebuffer[] = { + FALSE, + TRUE, +}; + + +const unsigned +stw_pf_multisample[] = { + 0, + 4, + 8, + 16 +}; + + +static void +stw_pixelformat_add( + struct stw_device *stw_dev, + boolean extended, + const struct stw_pf_color_info *color, + const struct stw_pf_depth_info *depth, + unsigned accum, + boolean doublebuffer, + unsigned samples ) +{ + struct stw_pixelformat_info *pfi; + + assert(stw_dev->pixelformat_extended_count < STW_MAX_PIXELFORMATS); + if(stw_dev->pixelformat_extended_count >= STW_MAX_PIXELFORMATS) + return; + + assert(util_format_get_component_bits(color->format, UTIL_FORMAT_COLORSPACE_RGB, 0) == color->bits.red); + assert(util_format_get_component_bits(color->format, UTIL_FORMAT_COLORSPACE_RGB, 1) == color->bits.green); + assert(util_format_get_component_bits(color->format, UTIL_FORMAT_COLORSPACE_RGB, 2) == color->bits.blue); + assert(util_format_get_component_bits(color->format, UTIL_FORMAT_COLORSPACE_RGB, 3) == color->bits.alpha); + assert(util_format_get_component_bits(depth->format, UTIL_FORMAT_COLORSPACE_ZS, 0) == depth->bits.depth); + assert(util_format_get_component_bits(depth->format, UTIL_FORMAT_COLORSPACE_ZS, 1) == depth->bits.stencil); + + pfi = &stw_dev->pixelformats[stw_dev->pixelformat_extended_count]; + + memset(pfi, 0, sizeof *pfi); + + pfi->pfd.nSize = sizeof pfi->pfd; + pfi->pfd.nVersion = 1; + + pfi->pfd.dwFlags = PFD_SUPPORT_OPENGL; + + /* TODO: also support non-native pixel formats */ + if (!extended) { + pfi->pfd.dwFlags |= PFD_DRAW_TO_WINDOW; + } + + /* See http://www.opengl.org/pipeline/article/vol003_7/ */ + pfi->pfd.dwFlags |= PFD_SUPPORT_COMPOSITION; + + if (doublebuffer) + pfi->pfd.dwFlags |= PFD_DOUBLEBUFFER | PFD_SWAP_EXCHANGE; + + pfi->pfd.iPixelType = PFD_TYPE_RGBA; + + pfi->pfd.cColorBits = color->bits.red + color->bits.green + color->bits.blue + color->bits.alpha; + pfi->pfd.cRedBits = color->bits.red; + pfi->pfd.cRedShift = color->shift.red; + pfi->pfd.cGreenBits = color->bits.green; + pfi->pfd.cGreenShift = color->shift.green; + pfi->pfd.cBlueBits = color->bits.blue; + pfi->pfd.cBlueShift = color->shift.blue; + pfi->pfd.cAlphaBits = color->bits.alpha; + pfi->pfd.cAlphaShift = color->shift.alpha; + pfi->pfd.cAccumBits = 4*accum; + pfi->pfd.cAccumRedBits = accum; + pfi->pfd.cAccumGreenBits = accum; + pfi->pfd.cAccumBlueBits = accum; + pfi->pfd.cAccumAlphaBits = accum; + pfi->pfd.cDepthBits = depth->bits.depth; + pfi->pfd.cStencilBits = depth->bits.stencil; + pfi->pfd.cAuxBuffers = 0; + pfi->pfd.iLayerType = 0; + pfi->pfd.bReserved = 0; + pfi->pfd.dwLayerMask = 0; + pfi->pfd.dwVisibleMask = 0; + pfi->pfd.dwDamageMask = 0; + + /* + * since state trackers can allocate depth/stencil/accum buffers, we provide + * only color buffers here + */ + pfi->stvis.buffer_mask = ST_ATTACHMENT_FRONT_LEFT_MASK; + if (doublebuffer) + pfi->stvis.buffer_mask |= ST_ATTACHMENT_BACK_LEFT_MASK; + + pfi->stvis.color_format = color->format; + pfi->stvis.depth_stencil_format = depth->format; + + pfi->stvis.accum_format = (accum) ? + PIPE_FORMAT_R16G16B16A16_SNORM : PIPE_FORMAT_NONE; + + pfi->stvis.samples = samples; + pfi->stvis.render_buffer = ST_ATTACHMENT_INVALID; + + ++stw_dev->pixelformat_extended_count; + + if(!extended) { + ++stw_dev->pixelformat_count; + assert(stw_dev->pixelformat_count == stw_dev->pixelformat_extended_count); + } +} + + +/** + * Add the depth/stencil/accum/ms variants for a particular color format. + */ +static unsigned +add_color_format_variants(const struct stw_pf_color_info *color, + boolean extended) +{ + struct pipe_screen *screen = stw_dev->screen; + unsigned ms, db, ds, acc; + unsigned bind_flags = PIPE_BIND_RENDER_TARGET; + unsigned num_added = 0; + int force_samples = 0; + + /* Since GLUT for Windows doesn't support MSAA we have an env var + * to force all pixel formats to have a particular number of samples. + */ + { + const char *samples= getenv("SVGA_FORCE_MSAA"); + if (samples) + force_samples = atoi(samples); + } + + if (!extended) { + bind_flags |= PIPE_BIND_DISPLAY_TARGET; + } + + for (ms = 0; ms < Elements(stw_pf_multisample); ms++) { + unsigned samples = stw_pf_multisample[ms]; + + if (force_samples && samples != force_samples) + continue; + + if (!screen->is_format_supported(screen, color->format, + PIPE_TEXTURE_2D, samples, bind_flags)) { + continue; + } + + for (db = 0; db < Elements(stw_pf_doublebuffer); db++) { + unsigned doublebuffer = stw_pf_doublebuffer[db]; + + for (ds = 0; ds < Elements(stw_pf_depth_stencil); ds++) { + const struct stw_pf_depth_info *depth = &stw_pf_depth_stencil[ds]; + + if (!screen->is_format_supported(screen, depth->format, + PIPE_TEXTURE_2D, samples, + PIPE_BIND_DEPTH_STENCIL)) { + continue; + } + + for (acc = 0; acc < 2; acc++) { + stw_pixelformat_add(stw_dev, extended, color, depth, + acc * 16, doublebuffer, samples); + num_added++; + } + } + } + } + + return num_added; +} + + +void +stw_pixelformat_init( void ) +{ + unsigned i; + unsigned num_formats = 0; + + assert( !stw_dev->pixelformat_count ); + assert( !stw_dev->pixelformat_extended_count ); + + /* normal, displayable formats */ + for (i = 0; i < Elements(stw_pf_color); i++) { + num_formats += add_color_format_variants(&stw_pf_color[i], FALSE); + } + assert(num_formats > 0); + + /* extended, pbuffer-only formats */ + for (i = 0; i < Elements(stw_pf_color_extended); i++) { + add_color_format_variants(&stw_pf_color_extended[i], TRUE); + } + + assert( stw_dev->pixelformat_count <= stw_dev->pixelformat_extended_count ); + assert( stw_dev->pixelformat_extended_count <= STW_MAX_PIXELFORMATS ); +} + +uint +stw_pixelformat_get_count( void ) +{ + return stw_dev->pixelformat_count; +} + +uint +stw_pixelformat_get_extended_count( void ) +{ + return stw_dev->pixelformat_extended_count; +} + +const struct stw_pixelformat_info * +stw_pixelformat_get_info( int iPixelFormat ) +{ + unsigned index; + + if (iPixelFormat <= 0) { + return NULL; + } + + index = iPixelFormat - 1; + if (index >= stw_dev->pixelformat_extended_count) { + return NULL; + } + + return &stw_dev->pixelformats[index]; +} + + +LONG APIENTRY +DrvDescribePixelFormat( + HDC hdc, + INT iPixelFormat, + ULONG cjpfd, + PIXELFORMATDESCRIPTOR *ppfd ) +{ + uint count; + const struct stw_pixelformat_info *pfi; + + (void) hdc; + + if (!stw_dev) + return 0; + + count = stw_pixelformat_get_count(); + + if (ppfd == NULL) + return count; + if (cjpfd != sizeof( PIXELFORMATDESCRIPTOR )) + return 0; + + pfi = stw_pixelformat_get_info( iPixelFormat ); + if (!pfi) { + return 0; + } + + memcpy(ppfd, &pfi->pfd, sizeof( PIXELFORMATDESCRIPTOR )); + + return count; +} + +BOOL APIENTRY +DrvDescribeLayerPlane( + HDC hdc, + INT iPixelFormat, + INT iLayerPlane, + UINT nBytes, + LPLAYERPLANEDESCRIPTOR plpd ) +{ + assert(0); + return FALSE; +} + +int APIENTRY +DrvGetLayerPaletteEntries( + HDC hdc, + INT iLayerPlane, + INT iStart, + INT cEntries, + COLORREF *pcr ) +{ + assert(0); + return 0; +} + +int APIENTRY +DrvSetLayerPaletteEntries( + HDC hdc, + INT iLayerPlane, + INT iStart, + INT cEntries, + CONST COLORREF *pcr ) +{ + assert(0); + return 0; +} + +BOOL APIENTRY +DrvRealizeLayerPalette( + HDC hdc, + INT iLayerPlane, + BOOL bRealize ) +{ + assert(0); + return FALSE; +} + +/* Only used by the wgl code, but have it here to avoid exporting the + * pixelformat.h functionality. + */ +int stw_pixelformat_choose( HDC hdc, + CONST PIXELFORMATDESCRIPTOR *ppfd ) +{ + uint count; + uint index; + uint bestindex; + uint bestdelta; + + (void) hdc; + + count = stw_pixelformat_get_extended_count(); + bestindex = 0; + bestdelta = ~0U; + + for (index = 1; index <= count; index++) { + uint delta = 0; + const struct stw_pixelformat_info *pfi = stw_pixelformat_get_info( index ); + + if (!(ppfd->dwFlags & PFD_DOUBLEBUFFER_DONTCARE) && + !!(ppfd->dwFlags & PFD_DOUBLEBUFFER) != + !!(pfi->pfd.dwFlags & PFD_DOUBLEBUFFER)) + continue; + + /* FIXME: Take in account individual channel bits */ + if (ppfd->cColorBits != pfi->pfd.cColorBits) + delta += 8; + + if (ppfd->cDepthBits != pfi->pfd.cDepthBits) + delta += 4; + + if (ppfd->cStencilBits != pfi->pfd.cStencilBits) + delta += 2; + + if (ppfd->cAlphaBits != pfi->pfd.cAlphaBits) + delta++; + + if (delta < bestdelta) { + bestindex = index; + bestdelta = delta; + if (bestdelta == 0) + break; + } + } + + return bestindex; +} diff --git a/lib/mesa/src/gallium/state_trackers/wgl/stw_pixelformat.h b/lib/mesa/src/gallium/state_trackers/wgl/stw_pixelformat.h new file mode 100644 index 000000000..58ef7442a --- /dev/null +++ b/lib/mesa/src/gallium/state_trackers/wgl/stw_pixelformat.h @@ -0,0 +1,67 @@ +/************************************************************************** + * + * Copyright 2008 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS 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 + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef STW_PIXELFORMAT_H +#define STW_PIXELFORMAT_H + +#include <windows.h> + +#ifndef PFD_SUPPORT_COMPOSITION +#define PFD_SUPPORT_COMPOSITION 0x00008000 +#endif + +#include "pipe/p_compiler.h" +#include "pipe/p_format.h" +#include "state_tracker/st_api.h" + +struct stw_pixelformat_info +{ + PIXELFORMATDESCRIPTOR pfd; + + struct st_visual stvis; +}; + +void +stw_pixelformat_init( void ); + +uint +stw_pixelformat_get_count( void ); + +uint +stw_pixelformat_get_extended_count( void ); + +const struct stw_pixelformat_info * +stw_pixelformat_get_info( int iPixelFormat ); + +int +stw_pixelformat_choose( HDC hdc, + CONST PIXELFORMATDESCRIPTOR *ppfd ); + +int +stw_pixelformat_get(HDC hdc); + +#endif /* STW_PIXELFORMAT_H */ diff --git a/lib/mesa/src/gallium/state_trackers/wgl/stw_st.c b/lib/mesa/src/gallium/state_trackers/wgl/stw_st.c new file mode 100644 index 000000000..b41171a91 --- /dev/null +++ b/lib/mesa/src/gallium/state_trackers/wgl/stw_st.c @@ -0,0 +1,289 @@ +/* + * Mesa 3-D graphics library + * + * Copyright (C) 2010 LunarG Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS 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 SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Chia-I Wu <olv@lunarg.com> + */ + +#include "util/u_memory.h" +#include "util/u_inlines.h" +#include "util/u_atomic.h" +#include "state_tracker/st_gl_api.h" /* for st_gl_api_create */ + +#include "stw_st.h" +#include "stw_device.h" +#include "stw_framebuffer.h" +#include "stw_pixelformat.h" + +struct stw_st_framebuffer { + struct st_framebuffer_iface base; + + struct stw_framebuffer *fb; + struct st_visual stvis; + + struct pipe_resource *textures[ST_ATTACHMENT_COUNT]; + unsigned texture_width, texture_height; + unsigned texture_mask; +}; + +static inline struct stw_st_framebuffer * +stw_st_framebuffer(struct st_framebuffer_iface *stfb) +{ + return (struct stw_st_framebuffer *) stfb; +} + +/** + * Remove outdated textures and create the requested ones. + */ +static void +stw_st_framebuffer_validate_locked(struct st_framebuffer_iface *stfb, + unsigned width, unsigned height, + unsigned mask) +{ + struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb); + struct pipe_resource templ; + unsigned i; + + /* remove outdated textures */ + if (stwfb->texture_width != width || stwfb->texture_height != height) { + for (i = 0; i < ST_ATTACHMENT_COUNT; i++) + pipe_resource_reference(&stwfb->textures[i], NULL); + } + + memset(&templ, 0, sizeof(templ)); + templ.target = PIPE_TEXTURE_2D; + templ.width0 = width; + templ.height0 = height; + templ.depth0 = 1; + templ.array_size = 1; + templ.last_level = 0; + templ.nr_samples = stwfb->stvis.samples; + + for (i = 0; i < ST_ATTACHMENT_COUNT; i++) { + enum pipe_format format; + unsigned bind; + + /* the texture already exists or not requested */ + if (stwfb->textures[i] || !(mask & (1 << i))) { + /* remember the texture */ + if (stwfb->textures[i]) + mask |= (1 << i); + continue; + } + + switch (i) { + case ST_ATTACHMENT_FRONT_LEFT: + case ST_ATTACHMENT_BACK_LEFT: + format = stwfb->stvis.color_format; + bind = PIPE_BIND_DISPLAY_TARGET | + PIPE_BIND_SAMPLER_VIEW | + PIPE_BIND_RENDER_TARGET; + break; + case ST_ATTACHMENT_DEPTH_STENCIL: + format = stwfb->stvis.depth_stencil_format; + bind = PIPE_BIND_DEPTH_STENCIL; + break; + default: + format = PIPE_FORMAT_NONE; + break; + } + + if (format != PIPE_FORMAT_NONE) { + templ.format = format; + templ.bind = bind; + + stwfb->textures[i] = + stw_dev->screen->resource_create(stw_dev->screen, &templ); + } + } + + stwfb->texture_width = width; + stwfb->texture_height = height; + stwfb->texture_mask = mask; +} + +static boolean +stw_st_framebuffer_validate(struct st_context_iface *stctx, + struct st_framebuffer_iface *stfb, + const enum st_attachment_type *statts, + unsigned count, + struct pipe_resource **out) +{ + struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb); + unsigned statt_mask, i; + + statt_mask = 0x0; + for (i = 0; i < count; i++) + statt_mask |= 1 << statts[i]; + + pipe_mutex_lock(stwfb->fb->mutex); + + if (stwfb->fb->must_resize || (statt_mask & ~stwfb->texture_mask)) { + stw_st_framebuffer_validate_locked(&stwfb->base, + stwfb->fb->width, stwfb->fb->height, statt_mask); + stwfb->fb->must_resize = FALSE; + } + + for (i = 0; i < count; i++) { + out[i] = NULL; + pipe_resource_reference(&out[i], stwfb->textures[statts[i]]); + } + + stw_framebuffer_release(stwfb->fb); + + return TRUE; +} + +/** + * Present an attachment of the framebuffer. + */ +static boolean +stw_st_framebuffer_present_locked(HDC hdc, + struct st_framebuffer_iface *stfb, + enum st_attachment_type statt) +{ + struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb); + struct pipe_resource *resource; + + resource = stwfb->textures[statt]; + if (resource) { + stw_framebuffer_present_locked(hdc, stwfb->fb, resource); + } + + return TRUE; +} + +static boolean +stw_st_framebuffer_flush_front(struct st_context_iface *stctx, + struct st_framebuffer_iface *stfb, + enum st_attachment_type statt) +{ + struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb); + boolean ret; + HDC hDC; + + pipe_mutex_lock(stwfb->fb->mutex); + + /* We must not cache HDCs anywhere, as they can be invalidated by the + * application, or screen resolution changes. */ + + hDC = GetDC(stwfb->fb->hWnd); + + ret = stw_st_framebuffer_present_locked(hDC, &stwfb->base, statt); + + ReleaseDC(stwfb->fb->hWnd, hDC); + + return ret; +} + +/** + * Create a framebuffer interface. + */ +struct st_framebuffer_iface * +stw_st_create_framebuffer(struct stw_framebuffer *fb) +{ + struct stw_st_framebuffer *stwfb; + + stwfb = CALLOC_STRUCT(stw_st_framebuffer); + if (!stwfb) + return NULL; + + stwfb->fb = fb; + stwfb->stvis = fb->pfi->stvis; + + stwfb->base.visual = &stwfb->stvis; + p_atomic_set(&stwfb->base.stamp, 1); + stwfb->base.flush_front = stw_st_framebuffer_flush_front; + stwfb->base.validate = stw_st_framebuffer_validate; + + return &stwfb->base; +} + +/** + * Destroy a framebuffer interface. + */ +void +stw_st_destroy_framebuffer_locked(struct st_framebuffer_iface *stfb) +{ + struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb); + int i; + + for (i = 0; i < ST_ATTACHMENT_COUNT; i++) + pipe_resource_reference(&stwfb->textures[i], NULL); + + FREE(stwfb); +} + +/** + * Swap the buffers of the given framebuffer. + */ +boolean +stw_st_swap_framebuffer_locked(HDC hdc, struct st_framebuffer_iface *stfb) +{ + struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb); + unsigned front = ST_ATTACHMENT_FRONT_LEFT, back = ST_ATTACHMENT_BACK_LEFT; + struct pipe_resource *ptex; + unsigned mask; + + /* swap the textures */ + ptex = stwfb->textures[front]; + stwfb->textures[front] = stwfb->textures[back]; + stwfb->textures[back] = ptex; + + /* convert to mask */ + front = 1 << front; + back = 1 << back; + + /* swap the bits in mask */ + mask = stwfb->texture_mask & ~(front | back); + if (stwfb->texture_mask & front) + mask |= back; + if (stwfb->texture_mask & back) + mask |= front; + stwfb->texture_mask = mask; + + front = ST_ATTACHMENT_FRONT_LEFT; + return stw_st_framebuffer_present_locked(hdc, &stwfb->base, front); +} + + +/** + * Return the pipe_resource that correspond to given buffer. + */ +struct pipe_resource * +stw_get_framebuffer_resource(struct st_framebuffer_iface *stfb, + enum st_attachment_type att) +{ + struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb); + return stwfb->textures[att]; +} + + +/** + * Create an st_api of the state tracker. + */ +struct st_api * +stw_st_create_api(void) +{ + return st_gl_api_create(); +} diff --git a/lib/mesa/src/gallium/state_trackers/wgl/stw_st.h b/lib/mesa/src/gallium/state_trackers/wgl/stw_st.h new file mode 100644 index 000000000..1c855a0a2 --- /dev/null +++ b/lib/mesa/src/gallium/state_trackers/wgl/stw_st.h @@ -0,0 +1,53 @@ +/* + * Mesa 3-D graphics library + * + * Copyright (C) 2010 LunarG Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS 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 SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Chia-I Wu <olv@lunarg.com> + */ + +#ifndef STW_ST_H +#define STW_ST_H + +#include <windows.h> + +#include "state_tracker/st_api.h" + +struct stw_framebuffer; + +struct st_api * +stw_st_create_api(void); + +struct st_framebuffer_iface * +stw_st_create_framebuffer(struct stw_framebuffer *fb); + +void +stw_st_destroy_framebuffer_locked(struct st_framebuffer_iface *stfb); + +boolean +stw_st_swap_framebuffer_locked(HDC hdc, struct st_framebuffer_iface *stfb); + +struct pipe_resource * +stw_get_framebuffer_resource(struct st_framebuffer_iface *stfb, + enum st_attachment_type att); + +#endif /* STW_ST_H */ diff --git a/lib/mesa/src/gallium/state_trackers/wgl/stw_tls.c b/lib/mesa/src/gallium/state_trackers/wgl/stw_tls.c new file mode 100644 index 000000000..041066f50 --- /dev/null +++ b/lib/mesa/src/gallium/state_trackers/wgl/stw_tls.c @@ -0,0 +1,305 @@ +/************************************************************************** + * + * Copyright 2009-2013 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS 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 + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include <windows.h> +#include <tlhelp32.h> + +#include "pipe/p_compiler.h" +#include "util/u_debug.h" +#include "stw_tls.h" + +static DWORD tlsIndex = TLS_OUT_OF_INDEXES; + + +/** + * Static mutex to protect the access to g_pendingTlsData global and + * stw_tls_data::next member. + */ +static CRITICAL_SECTION g_mutex = { + (PCRITICAL_SECTION_DEBUG)-1, -1, 0, 0, 0, 0 +}; + +/** + * There is no way to invoke TlsSetValue for a different thread, so we + * temporarily put the thread data for non-current threads here. + */ +static struct stw_tls_data *g_pendingTlsData = NULL; + + +static inline struct stw_tls_data * +stw_tls_data_create(DWORD dwThreadId); + +static struct stw_tls_data * +stw_tls_lookup_pending_data(DWORD dwThreadId); + + +boolean +stw_tls_init(void) +{ + tlsIndex = TlsAlloc(); + if (tlsIndex == TLS_OUT_OF_INDEXES) { + return FALSE; + } + + /* + * DllMain is called with DLL_THREAD_ATTACH only for threads created after + * the DLL is loaded by the process. So enumerate and add our hook to all + * previously existing threads. + * + * XXX: Except for the current thread since it there is an explicit + * stw_tls_init_thread() call for it later on. + */ + if (1) { + DWORD dwCurrentProcessId = GetCurrentProcessId(); + DWORD dwCurrentThreadId = GetCurrentThreadId(); + HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, dwCurrentProcessId); + if (hSnapshot != INVALID_HANDLE_VALUE) { + THREADENTRY32 te; + te.dwSize = sizeof te; + if (Thread32First(hSnapshot, &te)) { + do { + if (te.dwSize >= FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) + + sizeof te.th32OwnerProcessID) { + if (te.th32OwnerProcessID == dwCurrentProcessId) { + if (te.th32ThreadID != dwCurrentThreadId) { + struct stw_tls_data *data; + data = stw_tls_data_create(te.th32ThreadID); + if (data) { + EnterCriticalSection(&g_mutex); + data->next = g_pendingTlsData; + g_pendingTlsData = data; + LeaveCriticalSection(&g_mutex); + } + } + } + } + te.dwSize = sizeof te; + } while (Thread32Next(hSnapshot, &te)); + } + CloseHandle(hSnapshot); + } + } + + return TRUE; +} + + +/** + * Install windows hook for a given thread (not necessarily the current one). + */ +static inline struct stw_tls_data * +stw_tls_data_create(DWORD dwThreadId) +{ + struct stw_tls_data *data; + + if (0) { + debug_printf("%s(0x%04lx)\n", __FUNCTION__, dwThreadId); + } + + data = calloc(1, sizeof *data); + if (!data) { + goto no_data; + } + + data->dwThreadId = dwThreadId; + + data->hCallWndProcHook = SetWindowsHookEx(WH_CALLWNDPROC, + stw_call_window_proc, + NULL, + dwThreadId); + if (data->hCallWndProcHook == NULL) { + goto no_hook; + } + + return data; + +no_hook: + free(data); +no_data: + return NULL; +} + +/** + * Destroy the per-thread data/hook. + * + * It is important to remove all hooks when unloading our DLL, otherwise our + * hook function might be called after it is no longer there. + */ +static void +stw_tls_data_destroy(struct stw_tls_data *data) +{ + assert(data); + if (!data) { + return; + } + + if (0) { + debug_printf("%s(0x%04lx)\n", __FUNCTION__, data->dwThreadId); + } + + if (data->hCallWndProcHook) { + UnhookWindowsHookEx(data->hCallWndProcHook); + data->hCallWndProcHook = NULL; + } + + free(data); +} + +boolean +stw_tls_init_thread(void) +{ + struct stw_tls_data *data; + + if (tlsIndex == TLS_OUT_OF_INDEXES) { + return FALSE; + } + + data = stw_tls_data_create(GetCurrentThreadId()); + if (!data) { + return FALSE; + } + + TlsSetValue(tlsIndex, data); + + return TRUE; +} + +void +stw_tls_cleanup_thread(void) +{ + struct stw_tls_data *data; + + if (tlsIndex == TLS_OUT_OF_INDEXES) { + return; + } + + data = (struct stw_tls_data *) TlsGetValue(tlsIndex); + if (data) { + TlsSetValue(tlsIndex, NULL); + } else { + /* See if there this thread's data in on the pending list */ + data = stw_tls_lookup_pending_data(GetCurrentThreadId()); + } + + if (data) { + stw_tls_data_destroy(data); + } +} + +void +stw_tls_cleanup(void) +{ + if (tlsIndex != TLS_OUT_OF_INDEXES) { + /* + * Destroy all items in g_pendingTlsData linked list. + */ + EnterCriticalSection(&g_mutex); + while (g_pendingTlsData) { + struct stw_tls_data * data = g_pendingTlsData; + g_pendingTlsData = data->next; + stw_tls_data_destroy(data); + } + LeaveCriticalSection(&g_mutex); + + TlsFree(tlsIndex); + tlsIndex = TLS_OUT_OF_INDEXES; + } +} + +/* + * Search for the current thread in the g_pendingTlsData linked list. + * + * It will remove and return the node on success, or return NULL on failure. + */ +static struct stw_tls_data * +stw_tls_lookup_pending_data(DWORD dwThreadId) +{ + struct stw_tls_data ** p_data; + struct stw_tls_data *data = NULL; + + EnterCriticalSection(&g_mutex); + for (p_data = &g_pendingTlsData; *p_data; p_data = &(*p_data)->next) { + if ((*p_data)->dwThreadId == dwThreadId) { + data = *p_data; + + /* + * Unlink the node. + */ + *p_data = data->next; + data->next = NULL; + + break; + } + } + LeaveCriticalSection(&g_mutex); + + return data; +} + +struct stw_tls_data * +stw_tls_get_data(void) +{ + struct stw_tls_data *data; + + if (tlsIndex == TLS_OUT_OF_INDEXES) { + return NULL; + } + + data = (struct stw_tls_data *) TlsGetValue(tlsIndex); + if (!data) { + DWORD dwCurrentThreadId = GetCurrentThreadId(); + + /* + * Search for the current thread in the g_pendingTlsData linked list. + */ + data = stw_tls_lookup_pending_data(dwCurrentThreadId); + + if (!data) { + /* + * This should be impossible now. + */ + assert(!"Failed to find thread data for thread id"); + + /* + * DllMain is called with DLL_THREAD_ATTACH only by threads created + * after the DLL is loaded by the process + */ + data = stw_tls_data_create(dwCurrentThreadId); + if (!data) { + return NULL; + } + } + + TlsSetValue(tlsIndex, data); + } + + assert(data); + assert(data->dwThreadId = GetCurrentThreadId()); + assert(data->next == NULL); + + return data; +} diff --git a/lib/mesa/src/gallium/state_trackers/wgl/stw_tls.h b/lib/mesa/src/gallium/state_trackers/wgl/stw_tls.h new file mode 100644 index 000000000..07cfe3168 --- /dev/null +++ b/lib/mesa/src/gallium/state_trackers/wgl/stw_tls.h @@ -0,0 +1,63 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS 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 + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef STW_TLS_H +#define STW_TLS_H + +#include <windows.h> + +struct stw_tls_data +{ + DWORD dwThreadId; + + HHOOK hCallWndProcHook; + + struct stw_tls_data *next; +}; + +boolean +stw_tls_init(void); + +boolean +stw_tls_init_thread(void); + +void +stw_tls_cleanup_thread(void); + +void +stw_tls_cleanup(void); + +struct stw_tls_data * +stw_tls_get_data(void); + +LRESULT CALLBACK +stw_call_window_proc( + int nCode, + WPARAM wParam, + LPARAM lParam ); + +#endif /* STW_TLS_H */ diff --git a/lib/mesa/src/gallium/state_trackers/wgl/stw_wgl.c b/lib/mesa/src/gallium/state_trackers/wgl/stw_wgl.c new file mode 100644 index 000000000..5146e6a5b --- /dev/null +++ b/lib/mesa/src/gallium/state_trackers/wgl/stw_wgl.c @@ -0,0 +1,357 @@ +/************************************************************************** + * + * Copyright 2008 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS 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 + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * @file + * + * Fake WGL API implementation. + * + * These functions implement the WGL API, on top of the ICD DDI, so that the + * resulting DLL can be used as a drop-in replacement for the system's + * opengl32.dll. + * + * These functions never get called for ICD drivers, which use exclusively the + * ICD DDI, i.e., the Drv* entrypoints. + */ + +#include <windows.h> + +#include "util/u_debug.h" +#include "stw_icd.h" +#include "stw_context.h" +#include "stw_pixelformat.h" +#include "stw_wgl.h" +#include "stw_ext_context.h" + + +static void +overrideOpenGL32EntryPoints(void); + +WINGDIAPI BOOL APIENTRY +wglCopyContext( + HGLRC hglrcSrc, + HGLRC hglrcDst, + UINT mask ) +{ + return DrvCopyContext( (DHGLRC)(UINT_PTR)hglrcSrc, + (DHGLRC)(UINT_PTR)hglrcDst, + mask ); +} + +WINGDIAPI HGLRC APIENTRY +wglCreateContext( + HDC hdc ) +{ + overrideOpenGL32EntryPoints(); + return (HGLRC) DrvCreateContext(hdc); +} + +WINGDIAPI HGLRC APIENTRY +wglCreateLayerContext( + HDC hdc, + int iLayerPlane ) +{ + overrideOpenGL32EntryPoints(); + return (HGLRC) DrvCreateLayerContext( hdc, iLayerPlane ); +} + +WINGDIAPI BOOL APIENTRY +wglDeleteContext( + HGLRC hglrc ) +{ + return DrvDeleteContext((DHGLRC)(UINT_PTR)hglrc ); +} + + +WINGDIAPI HGLRC APIENTRY +wglGetCurrentContext( VOID ) +{ + return (HGLRC)(UINT_PTR)stw_get_current_context(); +} + +WINGDIAPI HDC APIENTRY +wglGetCurrentDC( VOID ) +{ + return stw_get_current_dc(); +} + +WINGDIAPI BOOL APIENTRY +wglMakeCurrent( + HDC hdc, + HGLRC hglrc ) +{ + return DrvSetContext( hdc, (DHGLRC)(UINT_PTR)hglrc, NULL ) ? TRUE : FALSE; +} + + +WINGDIAPI BOOL APIENTRY +wglSwapBuffers( + HDC hdc ) +{ + return DrvSwapBuffers( hdc ); +} + + +WINGDIAPI DWORD WINAPI +wglSwapMultipleBuffers(UINT n, + CONST WGLSWAP *ps) +{ + UINT i; + + for (i =0; i < n; ++i) + wglSwapBuffers(ps->hdc); + + return 0; +} + + +WINGDIAPI BOOL APIENTRY +wglSwapLayerBuffers( + HDC hdc, + UINT fuPlanes ) +{ + return DrvSwapLayerBuffers( hdc, fuPlanes ); +} + +WINGDIAPI PROC APIENTRY +wglGetProcAddress( + LPCSTR lpszProc ) +{ + return DrvGetProcAddress( lpszProc ); +} + + +WINGDIAPI int APIENTRY +wglChoosePixelFormat( + HDC hdc, + CONST PIXELFORMATDESCRIPTOR *ppfd ) +{ + if (ppfd->nSize != sizeof( PIXELFORMATDESCRIPTOR ) || ppfd->nVersion != 1) + return 0; + if (ppfd->iPixelType != PFD_TYPE_RGBA) + return 0; + if (!(ppfd->dwFlags & PFD_DRAW_TO_WINDOW)) + return 0; + if (!(ppfd->dwFlags & PFD_SUPPORT_OPENGL)) + return 0; + if (ppfd->dwFlags & PFD_DRAW_TO_BITMAP) + return 0; + if (ppfd->dwFlags & PFD_SUPPORT_GDI) + return 0; + if (!(ppfd->dwFlags & PFD_STEREO_DONTCARE) && (ppfd->dwFlags & PFD_STEREO)) + return 0; + + return stw_pixelformat_choose( hdc, ppfd ); +} + +WINGDIAPI int APIENTRY +wglDescribePixelFormat( + HDC hdc, + int iPixelFormat, + UINT nBytes, + LPPIXELFORMATDESCRIPTOR ppfd ) +{ + return DrvDescribePixelFormat( hdc, iPixelFormat, nBytes, ppfd ); +} + +WINGDIAPI int APIENTRY +wglGetPixelFormat( + HDC hdc ) +{ + return stw_pixelformat_get( hdc ); +} + +WINGDIAPI BOOL APIENTRY +wglSetPixelFormat( + HDC hdc, + int iPixelFormat, + const PIXELFORMATDESCRIPTOR *ppfd ) +{ + /* SetPixelFormat (hence wglSetPixelFormat) must not touch ppfd, per + * http://msdn.microsoft.com/en-us/library/dd369049(v=vs.85).aspx + */ + (void) ppfd; + + return DrvSetPixelFormat( hdc, iPixelFormat ); +} + + +WINGDIAPI BOOL APIENTRY +wglUseFontBitmapsA( + HDC hdc, + DWORD first, + DWORD count, + DWORD listBase ) +{ + (void) hdc; + (void) first; + (void) count; + (void) listBase; + + assert( 0 ); + + return FALSE; +} + +WINGDIAPI BOOL APIENTRY +wglShareLists( + HGLRC hglrc1, + HGLRC hglrc2 ) +{ + return DrvShareLists((DHGLRC)(UINT_PTR)hglrc1, + (DHGLRC)(UINT_PTR)hglrc2); +} + +WINGDIAPI BOOL APIENTRY +wglUseFontBitmapsW( + HDC hdc, + DWORD first, + DWORD count, + DWORD listBase ) +{ + (void) hdc; + (void) first; + (void) count; + (void) listBase; + + assert( 0 ); + + return FALSE; +} + +WINGDIAPI BOOL APIENTRY +wglUseFontOutlinesA( + HDC hdc, + DWORD first, + DWORD count, + DWORD listBase, + FLOAT deviation, + FLOAT extrusion, + int format, + LPGLYPHMETRICSFLOAT lpgmf ) +{ + (void) hdc; + (void) first; + (void) count; + (void) listBase; + (void) deviation; + (void) extrusion; + (void) format; + (void) lpgmf; + + assert( 0 ); + + return FALSE; +} + +WINGDIAPI BOOL APIENTRY +wglUseFontOutlinesW( + HDC hdc, + DWORD first, + DWORD count, + DWORD listBase, + FLOAT deviation, + FLOAT extrusion, + int format, + LPGLYPHMETRICSFLOAT lpgmf ) +{ + (void) hdc; + (void) first; + (void) count; + (void) listBase; + (void) deviation; + (void) extrusion; + (void) format; + (void) lpgmf; + + assert( 0 ); + + return FALSE; +} + +WINGDIAPI BOOL APIENTRY +wglDescribeLayerPlane( + HDC hdc, + int iPixelFormat, + int iLayerPlane, + UINT nBytes, + LPLAYERPLANEDESCRIPTOR plpd ) +{ + return DrvDescribeLayerPlane(hdc, iPixelFormat, iLayerPlane, nBytes, plpd); +} + +WINGDIAPI int APIENTRY +wglSetLayerPaletteEntries( + HDC hdc, + int iLayerPlane, + int iStart, + int cEntries, + CONST COLORREF *pcr ) +{ + return DrvSetLayerPaletteEntries(hdc, iLayerPlane, iStart, cEntries, pcr); +} + +WINGDIAPI int APIENTRY +wglGetLayerPaletteEntries( + HDC hdc, + int iLayerPlane, + int iStart, + int cEntries, + COLORREF *pcr ) +{ + return DrvGetLayerPaletteEntries(hdc, iLayerPlane, iStart, cEntries, pcr); +} + +WINGDIAPI BOOL APIENTRY +wglRealizeLayerPalette( + HDC hdc, + int iLayerPlane, + BOOL bRealize ) +{ + (void) hdc; + (void) iLayerPlane; + (void) bRealize; + + assert( 0 ); + + return FALSE; +} + + +/* When this library is used as a opengl32.dll drop-in replacement, ensure we + * use the wglCreate/Destroy entrypoints above, and not the true opengl32.dll, + * which could happen if this library's name is not opengl32.dll exactly. + * + * For example, Qt 5.4 bundles this as opengl32sw.dll: + * https://blog.qt.io/blog/2014/11/27/qt-weekly-21-dynamic-opengl-implementation-loading-in-qt-5-4/ + */ +static void +overrideOpenGL32EntryPoints(void) +{ + wglCreateContext_func = &wglCreateContext; + wglDeleteContext_func = &wglDeleteContext; +} diff --git a/lib/mesa/src/gallium/state_trackers/wgl/stw_wgl.h b/lib/mesa/src/gallium/state_trackers/wgl/stw_wgl.h new file mode 100644 index 000000000..31a391d96 --- /dev/null +++ b/lib/mesa/src/gallium/state_trackers/wgl/stw_wgl.h @@ -0,0 +1,79 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS 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 + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef STW_WGL_H_ +#define STW_WGL_H_ + + +#include <windows.h> + +#include <GL/gl.h> + + +/* + * Undeclared APIs exported by opengl32.dll + */ + +WINGDIAPI BOOL WINAPI +wglSwapBuffers(HDC hdc); + +WINGDIAPI int WINAPI +wglChoosePixelFormat(HDC hdc, + CONST PIXELFORMATDESCRIPTOR *ppfd); + +WINGDIAPI int WINAPI +wglDescribePixelFormat(HDC hdc, + int iPixelFormat, + UINT nBytes, + LPPIXELFORMATDESCRIPTOR ppfd); + +WINGDIAPI int WINAPI +wglGetPixelFormat(HDC hdc); + +WINGDIAPI BOOL WINAPI +wglSetPixelFormat(HDC hdc, + int iPixelFormat, + CONST PIXELFORMATDESCRIPTOR *ppfd); + +#ifndef WGL_SWAPMULTIPLE_MAX + +typedef struct _WGLSWAP +{ + HDC hdc; + UINT uiFlags; +} WGLSWAP; + +#define WGL_SWAPMULTIPLE_MAX 16 + +WINGDIAPI DWORD WINAPI +wglSwapMultipleBuffers(UINT n, + CONST WGLSWAP *ps); + +#endif /* !WGL_SWAPMULTIPLE_MAX */ + + +#endif /* STW_WGL_H_ */ diff --git a/lib/mesa/src/gallium/state_trackers/wgl/stw_winsys.h b/lib/mesa/src/gallium/state_trackers/wgl/stw_winsys.h new file mode 100644 index 000000000..281b201bc --- /dev/null +++ b/lib/mesa/src/gallium/state_trackers/wgl/stw_winsys.h @@ -0,0 +1,107 @@ +/************************************************************************** + * + * Copyright 2008-2009 Vmware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS 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 + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef STW_WINSYS_H +#define STW_WINSYS_H + +#include <windows.h> /* for HDC */ + +#include "pipe/p_compiler.h" + +struct pipe_screen; +struct pipe_context; +struct pipe_resource; + +struct stw_shared_surface; + +struct stw_winsys +{ + struct pipe_screen * + (*create_screen)( void ); + + /* XXX is it actually possible to have non-zero level/layer ??? */ + /** + * Present the color buffer to the window associated with the device context. + */ + void + (*present)( struct pipe_screen *screen, + struct pipe_resource *res, + HDC hDC ); + + /** + * Locally unique identifier (LUID) of the graphics adapter. + * + * @sa GLCBPRESENTBUFFERSDATA::AdapterLuid; + */ + boolean + (*get_adapter_luid)( struct pipe_screen *screen, + LUID *pAdapterLuid ); + + /** + * Open a shared surface (optional). + * + * @sa GLCBPRESENTBUFFERSDATA::hSharedSurface; + */ + struct stw_shared_surface * + (*shared_surface_open)(struct pipe_screen *screen, + HANDLE hSharedSurface); + + /** + * Close a shared surface (optional). + */ + void + (*shared_surface_close)(struct pipe_screen *screen, + struct stw_shared_surface *surface); + + /** + * Compose into a shared surface (optional). + * + * Blit the color buffer into a shared surface. + * + * @sa GLPRESENTBUFFERSDATA::PresentHistoryToken. + */ + void + (*compose)( struct pipe_screen *screen, + struct pipe_resource *res, + struct stw_shared_surface *dest, + LPCRECT pRect, + ULONGLONG PresentHistoryToken ); +}; + +boolean +stw_init(const struct stw_winsys *stw_winsys); + +boolean +stw_init_thread(void); + +void +stw_cleanup_thread(void); + +void +stw_cleanup(void); + +#endif /* STW_WINSYS_H */ |