1# -*- coding: utf-8 -*-
2
3#-------------------------------------------------------------------------
4# drawElements Quality Program utilities
5# --------------------------------------
6#
7# Copyright 2015 The Android Open Source Project
8#
9# Licensed under the Apache License, Version 2.0 (the "License");
10# you may not use this file except in compliance with the License.
11# You may obtain a copy of the License at
12#
13#      http://www.apache.org/licenses/LICENSE-2.0
14#
15# Unless required by applicable law or agreed to in writing, software
16# distributed under the License is distributed on an "AS IS" BASIS,
17# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18# See the License for the specific language governing permissions and
19# limitations under the License.
20#
21#-------------------------------------------------------------------------
22
23from src_util import *
24import re
25
26class LogSpec:
27	def __init__ (self, argInPrints, argOutPrints = {}, returnPrint = None):
28		self.argInPrints	= argInPrints
29		self.argOutPrints	= argOutPrints
30		self.returnPrint	= returnPrint
31
32def enum (group):
33	return lambda name: "get%sStr(%s)" % (group, name)
34
35def pointer (size):
36	return lambda name: "getPointerStr(%s, %s)" % (name, size)
37
38def enumPointer (group, size):
39	return lambda name: "getEnumPointerStr(%(name)s, %(size)s, %(nameFunc)s)" % {"name": name, "size": size, "nameFunc": ("get%sName" % group)}
40
41def booleanPointer (size):
42	return lambda name: "getBooleanPointerStr(%s, %s)" % (name, size)
43
44def textureUnit (name):
45	return "getTextureUnitStr(%s)" % name
46
47def voidPointer (name):
48	return "toHex(reinterpret_cast<deUintptr>(static_cast<const void*>(%s)))" % name
49
50def fnPointer (name):
51	return "toHex(reinterpret_cast<deUintptr>(%s))" % name
52
53stringVal = lambda name: "getStringStr(%s)" % name
54
55# Special rules for printing call arguments
56CALL_LOG_SPECS = {
57	"glActiveTexture":						LogSpec({0: textureUnit}),
58	"glBeginQuery":							LogSpec({0: enum("QueryTarget")}),
59	"glBeginTransformFeedback":				LogSpec({0: enum("PrimitiveType")}),
60	"glBindBuffer":							LogSpec({0: enum("BufferTarget")}),
61	"glBindBufferBase":						LogSpec({0: enum("BufferTarget")}),
62	"glBindBufferRange":					LogSpec({0: enum("BufferTarget")}),
63	"glBindFramebuffer":					LogSpec({0: enum("FramebufferTarget")}),
64	"glBindRenderbuffer":					LogSpec({0: enum("FramebufferTarget")}),
65	"glBindTexture":						LogSpec({0: enum("TextureTarget")}),
66	"glBindTransformFeedback":				LogSpec({0: enum("TransformFeedbackTarget")}),
67	"glBlendEquation":						LogSpec({0: enum("BlendEquation")}),
68	"glBlendEquationSeparate":				LogSpec({0: enum("BlendEquation"), 1: enum("BlendEquation")}),
69	"glBlendEquationi":						LogSpec({1: enum("BlendEquation")}),
70	"glBlendEquationSeparatei":				LogSpec({1: enum("BlendEquation"), 2: enum("BlendEquation")}),
71	"glBlendFunc":							LogSpec({0: enum("BlendFactor"), 1: enum("BlendFactor")}),
72	"glBlendFuncSeparate":					LogSpec({0: enum("BlendFactor"), 1: enum("BlendFactor"), 2: enum("BlendFactor"), 3: enum("BlendFactor")}),
73	"glBlitFramebuffer":					LogSpec({8: enum("BufferMask"), 9: enum("TextureFilter")}),
74	"glBufferData":							LogSpec({0: enum("BufferTarget"), 3: enum("Usage")}),
75	"glBufferSubData":						LogSpec({0: enum("BufferTarget")}),
76	"glCheckFramebufferStatus":				LogSpec({0: enum("FramebufferTarget")}, returnPrint = enum("FramebufferStatus")),
77	"glClear":								LogSpec({0: enum("BufferMask")}),
78	"glClearBufferfv":						LogSpec({0: enum("Buffer")}),
79	"glClearBufferfi":						LogSpec({0: enum("Buffer")}),
80	"glClearBufferiv":						LogSpec({0: enum("Buffer")}),
81	"glClearBufferuiv":						LogSpec({0: enum("Buffer")}),
82	"glCompressedTexImage2D":				LogSpec({0: enum("TextureTarget"), 2: enum("CompressedTexFormat")}),
83	"glCompressedTexSubImage2D":			LogSpec({0: enum("TextureTarget"), 6: enum("CompressedTexFormat")}),
84	"glCopyTexImage1D":						LogSpec({0: enum("TextureTarget"), 2: enum("PixelFormat")}),
85	"glCopyTexImage2D":						LogSpec({0: enum("TextureTarget"), 2: enum("PixelFormat")}),
86	"glCreateShader":						LogSpec({0: enum("ShaderType")}),
87	"glCullFace":							LogSpec({0: enum("Face")}),
88	"glDeleteBuffers":						LogSpec({1: pointer(size = "n")}),
89	"glDeleteFramebuffers":					LogSpec({1: pointer(size = "n")}),
90	"glDeleteQueries":						LogSpec({1: pointer(size = "n")}),
91	"glDeleteRenderbuffers":				LogSpec({1: pointer(size = "n")}),
92	"glDeleteBuffers":						LogSpec({1: pointer(size = "n")}),
93	"glDeleteTextures":						LogSpec({1: pointer(size = "n")}),
94	"glDeleteVertexArrays":					LogSpec({1: pointer(size = "n")}),
95	"glDeleteProgramPipelines":				LogSpec({1: pointer(size = "n")}),
96	"glDepthFunc":							LogSpec({0: enum("CompareFunc")}),
97	"glDisable":							LogSpec({0: enum("EnableCap")}),
98	"glDisablei":							LogSpec({0: enum("IndexedEnableCap")}),
99	"glDrawArrays":							LogSpec({0: enum("PrimitiveType")}),
100	"glDrawArraysInstanced":				LogSpec({0: enum("PrimitiveType")}),
101	"glDrawBuffers":						LogSpec({1: enumPointer("DrawReadBuffer", size = "n")}),
102	"glDrawElements":						LogSpec({0: enum("PrimitiveType"), 2: enum("Type")}),
103	"glDrawElementsInstanced":				LogSpec({0: enum("PrimitiveType"), 2: enum("Type")}),
104	"glDrawRangeElements":					LogSpec({0: enum("PrimitiveType"), 4: enum("Type")}),
105	"glDrawArraysIndirect":					LogSpec({0: enum("PrimitiveType")}),
106	"glDrawElementsIndirect":				LogSpec({0: enum("PrimitiveType"), 1: enum("Type")}),
107	"glDrawElementsBaseVertex":				LogSpec({0: enum("PrimitiveType"), 2: enum("Type")}),
108	"glDrawElementsInstancedBaseVertex":	LogSpec({0: enum("PrimitiveType"), 2: enum("Type")}),
109	"glDrawRangeElementsBaseVertex":		LogSpec({0: enum("PrimitiveType"), 4: enum("Type")}),
110	"glMultiDrawArrays":					LogSpec({0: enum("PrimitiveType")}),
111	"glMultiDrawElements":					LogSpec({0: enum("PrimitiveType"), 2: enum("Type")}),
112	"glMultiDrawElementsBaseVertex":		LogSpec({0: enum("PrimitiveType"), 2: enum("Type")}),
113	"glEnable":								LogSpec({0: enum("EnableCap")}),
114	"glEnablei":							LogSpec({0: enum("IndexedEnableCap")}),
115	"glEndQuery":							LogSpec({0: enum("QueryTarget")}),
116	"glFramebufferRenderbuffer":			LogSpec({0: enum("FramebufferTarget"), 1: enum("FramebufferAttachment"), 2: enum("FramebufferTarget")}),
117	"glFramebufferTexture2D":				LogSpec({0: enum("FramebufferTarget"), 1: enum("FramebufferAttachment"), 2: enum("TextureTarget")}),
118	"glFramebufferTextureLayer":			LogSpec({0: enum("FramebufferTarget"), 1: enum("FramebufferAttachment")}),
119	"glFramebufferTexture":					LogSpec({0: enum("FramebufferTarget"), 1: enum("FramebufferAttachment")}),
120	"glFramebufferParameteri":				LogSpec({0: enum("FramebufferTarget"), 1: enum("FramebufferParameter")}),
121	"glFrontFace":							LogSpec({0: enum("Winding")}),
122	"glGenBuffers":							LogSpec({}, argOutPrints = {1: pointer(size = "n")}),
123	"glGenerateMipmap":						LogSpec({0: enum("TextureTarget")}),
124	"glGenFramebuffers":					LogSpec({}, argOutPrints = {1: pointer(size = "n")}),
125	"glGenQueries":							LogSpec({}, argOutPrints = {1: pointer(size = "n")}),
126	"glGenRenderbuffers":					LogSpec({}, argOutPrints = {1: pointer(size = "n")}),
127	"glGenTextures":						LogSpec({}, argOutPrints = {1: pointer(size = "n")}),
128	"glGenTransformFeedbacks":				LogSpec({}, argOutPrints = {1: pointer(size = "n")}),
129	"glGenVertexArrays":					LogSpec({}, argOutPrints = {1: pointer(size = "n")}),
130	"glGenProgramPipelines":				LogSpec({}, argOutPrints = {1: pointer(size = "n")}),
131#	"glGetActiveAttrib":
132	"glGetActiveUniform":					LogSpec({}, argOutPrints = {3: pointer(size = "1"), 4: pointer(size = "1"), 5: enumPointer("ShaderVarType", size = "1"), 6: stringVal}),
133	"glGetActiveUniformsiv":				LogSpec({2: pointer(size = "uniformCount"), 3: enum("UniformParam")}, argOutPrints = {4: pointer(size = "uniformCount")}),
134#	"glGetAttachedShaders":
135	"glGetBooleanv":
136		LogSpec(
137			{
138				0: enum("GettableState"),
139				1: voidPointer					# second argument has type of GLboolean* (aka. char*). Prevent
140												# wrapper from attempting to print the argument as a C string.
141			},
142			argOutPrints = {1: booleanPointer(size = "getBasicQueryNumArgsOut(pname)")}),
143	"glGetBufferParameteriv":				LogSpec({0: enum("BufferTarget"), 1: enum("BufferQuery")}),
144	"glGetBufferParameteri64v":				LogSpec({0: enum("BufferTarget"), 1: enum("BufferQuery")}),
145	"glGetError":							LogSpec({}, returnPrint = enum("Error")),
146	"glGetFloatv":							LogSpec({0: enum("GettableState")}, argOutPrints = {1: pointer(size = "getBasicQueryNumArgsOut(pname)")}),
147	"glGetFramebufferAttachmentParameteriv":
148		LogSpec(
149			{
150				0: enum("FramebufferTarget"),
151				1: enum("FramebufferAttachment"),
152				2: enum("FramebufferAttachmentParameter")
153			},
154			argOutPrints = {3: lambda name: "getFramebufferAttachmentParameterValueStr(pname, %s)" % name}),
155	"glGetFramebufferParameteriv":			LogSpec({0: enum("FramebufferTarget"), 1: enum("FramebufferParameter")}, argOutPrints = {2: pointer(size = "1")}),
156	"glGetIntegerv":						LogSpec({0: enum("GettableState")}, argOutPrints = {1: pointer(size = "getBasicQueryNumArgsOut(pname)")}),
157	"glGetInteger64v":						LogSpec({0: enum("GettableState")}, argOutPrints = {1: pointer(size = "getBasicQueryNumArgsOut(pname)")}),
158	"glGetIntegeri_v":						LogSpec({0: enum("GettableIndexedState")}, argOutPrints = {2:pointer(size = "getIndexedQueryNumArgsOut(target)")}),
159	"glGetInteger64i_v":						LogSpec({0: enum("GettableIndexedState")}, argOutPrints = {2: pointer(size = "getIndexedQueryNumArgsOut(target)")}),
160	"glGetBooleani_v":
161		LogSpec(
162			{
163				0: enum("GettableIndexedState"),
164				2: voidPointer					# last argument has type of GLboolean* (aka. char*). Prevent
165												# wrapper from attempting to print the argument as a C string.
166			},
167			argOutPrints = {2: booleanPointer(size = "getIndexedQueryNumArgsOut(target)")}),
168	"glGetInternalformativ":				LogSpec({0: enum("InternalFormatTarget"), 1: enum("PixelFormat"), 2: enum("InternalFormatParameter")}, argOutPrints = {4: pointer(size = "bufSize")}),
169	"glGetMultisamplefv":					LogSpec({0: enum("MultisampleParameter")}, argOutPrints = {2: pointer(size = "2")}),
170	"glGetPointerv":						LogSpec({0: enum("PointerState")}, argOutPrints = {1: pointer(size = "1")}),
171	"glGetProgramiv":						LogSpec({1: enum("ProgramParam")}, argOutPrints = {2: pointer(size = "getProgramQueryNumArgsOut(pname)")}),
172	"glGetProgramInfoLog":					LogSpec({3: voidPointer}, argOutPrints = {2: pointer(size = "1")}),
173	"glGetProgramPipelineiv":				LogSpec({1: enum("PipelineParam")}, argOutPrints = {2: pointer(size = "1")}),
174	"glGetProgramPipelineInfoLog":			LogSpec({3: voidPointer}, argOutPrints = {2: pointer(size = "1")}),
175	"glGetQueryiv":							LogSpec({0: enum("QueryTarget"), 1: enum("QueryParam")}, argOutPrints = {2: pointer(size = "1")}),
176	"glGetQueryObjectiv":					LogSpec({1: enum("QueryObjectParam")}, argOutPrints = {2: pointer(size = "1")}),
177	"glGetQueryObjectuiv":					LogSpec({1: enum("QueryObjectParam")}, argOutPrints = {2: pointer(size = "1")}),
178	"glGetQueryObjecti64v":					LogSpec({1: enum("QueryObjectParam")}, argOutPrints = {2: pointer(size = "1")}),
179	"glGetQueryObjectui64v":				LogSpec({1: enum("QueryObjectParam")}, argOutPrints = {2: pointer(size = "1")}),
180	"glGetRenderbufferParameteriv":			LogSpec({0: enum("FramebufferTarget"), 1: enum("RenderbufferParameter")}),
181	"glGetSamplerParameterfv":				LogSpec({1: enum("TextureParameter")}, argOutPrints = {2: pointer(size = "getTextureParamQueryNumArgsOut(pname)")}),
182	"glGetSamplerParameteriv":				LogSpec({1: enum("TextureParameter")}, argOutPrints = {2: pointer(size = "getTextureParamQueryNumArgsOut(pname)")}),
183	"glGetSamplerParameterIiv":				LogSpec({1: enum("TextureParameter")}, argOutPrints = {2: pointer(size = "getTextureParamQueryNumArgsOut(pname)")}),
184	"glGetSamplerParameterIuiv":			LogSpec({1: enum("TextureParameter")}, argOutPrints = {2: pointer(size = "getTextureParamQueryNumArgsOut(pname)")}),
185	"glGetShaderiv":						LogSpec({1: enum("ShaderParam")}, argOutPrints = {2: pointer(size = "1")}),
186	"glGetShaderInfoLog":					LogSpec({3: voidPointer}, argOutPrints = {2: pointer(size = "1")}),
187	"glGetShaderPrecisionFormat":			LogSpec({0: enum("ShaderType"), 1: enum("PrecisionFormatType")}),
188#	"glGetShaderSource":
189	"glGetString":							LogSpec({0: enum("GettableString")}, returnPrint=stringVal),
190	"glGetStringi":							LogSpec({0: enum("GettableString")}, returnPrint=stringVal),
191	"glGetTexParameterfv":					LogSpec({0: enum("TextureTarget"), 1: enum("TextureParameter")}, argOutPrints = {2: pointer(size = "getTextureParamQueryNumArgsOut(pname)")}),
192	"glGetTexParameteriv":					LogSpec({0: enum("TextureTarget"), 1: enum("TextureParameter")}, argOutPrints = {2: pointer(size = "getTextureParamQueryNumArgsOut(pname)")}),
193	"glGetTexParameterIiv":					LogSpec({0: enum("TextureTarget"), 1: enum("TextureParameter")}, argOutPrints = {2: pointer(size = "getTextureParamQueryNumArgsOut(pname)")}),
194	"glGetTexParameterIuiv":				LogSpec({0: enum("TextureTarget"), 1: enum("TextureParameter")}, argOutPrints = {2: pointer(size = "getTextureParamQueryNumArgsOut(pname)")}),
195	"glGetTexLevelParameterfv":				LogSpec({0: enum("TextureTarget"), 2: enum("TextureLevelParameter")}, argOutPrints = {3: pointer(size = "1")}),
196	"glGetTexLevelParameteriv":				LogSpec({0: enum("TextureTarget"), 2: enum("TextureLevelParameter")}, argOutPrints = {3: pointer(size = "1")}),
197#	"glGetUniformfv":
198#	"glGetUniformiv":
199	"glGetUniformIndices":					LogSpec({2: pointer(size = "uniformCount")}, argOutPrints = {3: pointer(size = "uniformCount")}),
200	"glGetVertexAttribfv":					LogSpec({1: enum("VertexAttribParameterName")}, argOutPrints = {2: pointer(size = "getAttributeQueryNumArgsOut(pname)")}),
201	"glGetVertexAttribiv":					LogSpec({1: enum("VertexAttribParameterName")}, argOutPrints = {2: pointer(size = "getAttributeQueryNumArgsOut(pname)")}),
202	"glGetVertexAttribIiv":					LogSpec({1: enum("VertexAttribParameterName")}, argOutPrints = {2: pointer(size = "getAttributeQueryNumArgsOut(pname)")}),
203	"glGetVertexAttribIuiv":				LogSpec({1: enum("VertexAttribParameterName")}, argOutPrints = {2: pointer(size = "getAttributeQueryNumArgsOut(pname)")}),
204#	"glGetVertexAttribPointerv":
205	"glHint":								LogSpec({0: enum("Hint"), 1: enum("HintMode")}),
206	"glIsEnabled":							LogSpec({0: enum("EnableCap")}),
207	"glIsEnabledi":							LogSpec({0: enum("IndexedEnableCap")}),
208	"glPixelStorei":						LogSpec({0: enum("PixelStoreParameter")}),
209	"glReadBuffer":							LogSpec({0: enum("DrawReadBuffer")}),
210	"glReadPixels":							LogSpec({4: enum("PixelFormat"), 5: enum("Type")}),
211	"glRenderbufferStorage":				LogSpec({0: enum("FramebufferTarget"), 1: enum("PixelFormat")}),
212	"glRenderbufferStorageMultisample":		LogSpec({0: enum("FramebufferTarget"), 2: enum("PixelFormat")}),
213	"glStencilFunc":						LogSpec({0: enum("CompareFunc")}),
214	"glStencilFuncSeparate":				LogSpec({0: enum("Face"), 1: enum("CompareFunc")}),
215	"glStencilMaskSeparate":				LogSpec({0: enum("Face")}),
216	"glStencilOp":							LogSpec({0: enum("StencilOp"), 1: enum("StencilOp"), 2: enum("StencilOp")}),
217	"glStencilOpSeparate":					LogSpec({0: enum("Face"), 1: enum("StencilOp"), 2: enum("StencilOp"), 3: enum("StencilOp")}),
218	"glTexImage1D":							LogSpec({0: enum("TextureTarget"), 2: enum("PixelFormat"), 5: enum("PixelFormat"), 6: enum("Type")}),
219	"glTexImage2D":							LogSpec({0: enum("TextureTarget"), 2: enum("PixelFormat"), 6: enum("PixelFormat"), 7: enum("Type")}),
220	"glTexImage2DMultisample":				LogSpec({0: enum("TextureTarget"), 2: enum("PixelFormat"), 5: enum("Boolean")}),
221	"glTexImage3D":							LogSpec({0: enum("TextureTarget"), 2: enum("PixelFormat"), 7: enum("PixelFormat"), 8: enum("Type")}),
222	"glTexStorage2D":						LogSpec({0: enum("TextureTarget"), 2: enum("PixelFormat")}),
223	"glTexStorage3D":						LogSpec({0: enum("TextureTarget"), 2: enum("PixelFormat")}),
224	"glTexStorage2DMultisample":			LogSpec({0: enum("TextureTarget"), 2: enum("PixelFormat"), 5: enum("Boolean")}),
225	"glTexStorage3DMultisample":			LogSpec({0: enum("TextureTarget"), 2: enum("PixelFormat"), 6: enum("Boolean")}),
226	# \todo [2012-03-08 pyry] Pointer values..
227	"glTexParameterf":						LogSpec({0: enum("TextureTarget"), 1: enum("TextureParameter")}),
228	"glTexParameteri":						LogSpec({0: enum("TextureTarget"), 1: enum("TextureParameter"), 2: lambda name: "getTextureParameterValueStr(pname, %s)" % name}),
229	"glTexParameterfv":						LogSpec({0: enum("TextureTarget"), 1: enum("TextureParameter"), 2: pointer(size = "getTextureParamNumArgs(pname)")}),
230	"glTexParameteriv":						LogSpec({0: enum("TextureTarget"), 1: enum("TextureParameter"), 2: pointer(size = "getTextureParamNumArgs(pname)")}),
231	"glTexParameterIiv":					LogSpec({0: enum("TextureTarget"), 1: enum("TextureParameter"), 2: pointer(size = "getTextureParamNumArgs(pname)")}),
232	"glTexParameterIuiv":					LogSpec({0: enum("TextureTarget"), 1: enum("TextureParameter"), 2: pointer(size = "getTextureParamNumArgs(pname)")}),
233	"glSamplerParameterf":					LogSpec({1: enum("TextureParameter")}),
234	"glSamplerParameteri":					LogSpec({1: enum("TextureParameter"), 2: lambda name: "getTextureParameterValueStr(pname, %s)" % name}),
235	"glSamplerParameterfv":					LogSpec({1: enum("TextureParameter"), 2: pointer(size = "getTextureParamNumArgs(pname)")}),
236	"glSamplerParameteriv":					LogSpec({1: enum("TextureParameter"), 2: pointer(size = "getTextureParamNumArgs(pname)")}),
237	"glSamplerParameterIiv":				LogSpec({1: enum("TextureParameter"), 2: pointer(size = "getTextureParamNumArgs(pname)")}),
238	"glSamplerParameterIuiv":				LogSpec({1: enum("TextureParameter"), 2: pointer(size = "getTextureParamNumArgs(pname)")}),
239	"glTexSubImage1D":						LogSpec({0: enum("TextureTarget"), 4: enum("PixelFormat"), 5: enum("Type")}),
240	"glTexSubImage2D":						LogSpec({0: enum("TextureTarget"), 6: enum("PixelFormat"), 7: enum("Type")}),
241	"glTexSubImage3D":						LogSpec({0: enum("TextureTarget"), 8: enum("PixelFormat"), 9: enum("Type")}),
242	"glUniform1fv":							LogSpec({2: pointer(size = "(count * 1)")}),
243	"glUniform1iv":							LogSpec({2: pointer(size = "(count * 1)")}),
244	"glUniform1uiv":						LogSpec({2: pointer(size = "(count * 1)")}),
245	"glUniform2fv":							LogSpec({2: pointer(size = "(count * 2)")}),
246	"glUniform2iv":							LogSpec({2: pointer(size = "(count * 2)")}),
247	"glUniform2uiv":						LogSpec({2: pointer(size = "(count * 2)")}),
248	"glUniform3fv":							LogSpec({2: pointer(size = "(count * 3)")}),
249	"glUniform3iv":							LogSpec({2: pointer(size = "(count * 3)")}),
250	"glUniform3uiv":						LogSpec({2: pointer(size = "(count * 3)")}),
251	"glUniform4fv":							LogSpec({2: pointer(size = "(count * 4)")}),
252	"glUniform4iv":							LogSpec({2: pointer(size = "(count * 4)")}),
253	"glUniform4uiv":						LogSpec({2: pointer(size = "(count * 4)")}),
254	"glUniformMatrix2fv":					LogSpec({3: pointer(size = "(count * 2*2)")}),
255	"glUniformMatrix3fv":					LogSpec({3: pointer(size = "(count * 3*3)")}),
256	"glUniformMatrix4fv":					LogSpec({3: pointer(size = "(count * 4*4)")}),
257	"glUniformMatrix2x3fv":					LogSpec({3: pointer(size = "(count * 2*3)")}),
258	"glUniformMatrix2x4fv":					LogSpec({3: pointer(size = "(count * 2*4)")}),
259	"glUniformMatrix3x2fv":					LogSpec({3: pointer(size = "(count * 3*2)")}),
260	"glUniformMatrix3x4fv":					LogSpec({3: pointer(size = "(count * 3*4)")}),
261	"glUniformMatrix4x2fv":					LogSpec({3: pointer(size = "(count * 4*2)")}),
262	"glUniformMatrix4x3fv":					LogSpec({3: pointer(size = "(count * 4*3)")}),
263	"glUseProgramStages":					LogSpec({1: enum("ShaderTypeMask")}),
264	"glPatchParameteri":					LogSpec({0: enum("PatchParam")}),
265	"glProgramParameteri":					LogSpec({1: enum("ProgramParam")}),
266	"glProgramUniform1fv":					LogSpec({3: pointer(size = "(count * 1)")}),
267	"glProgramUniform1iv":					LogSpec({3: pointer(size = "(count * 1)")}),
268	"glProgramUniform1uiv":					LogSpec({3: pointer(size = "(count * 1)")}),
269	"glProgramUniform2fv":					LogSpec({3: pointer(size = "(count * 2)")}),
270	"glProgramUniform2iv":					LogSpec({3: pointer(size = "(count * 2)")}),
271	"glProgramUniform2uiv":					LogSpec({3: pointer(size = "(count * 2)")}),
272	"glProgramUniform3fv":					LogSpec({3: pointer(size = "(count * 3)")}),
273	"glProgramUniform3iv":					LogSpec({3: pointer(size = "(count * 3)")}),
274	"glProgramUniform3uiv":					LogSpec({3: pointer(size = "(count * 3)")}),
275	"glProgramUniform4fv":					LogSpec({3: pointer(size = "(count * 4)")}),
276	"glProgramUniform4iv":					LogSpec({3: pointer(size = "(count * 4)")}),
277	"glProgramUniform4uiv":					LogSpec({3: pointer(size = "(count * 4)")}),
278	"glProgramUniformMatrix2fv":			LogSpec({4: pointer(size = "(count * 2*2)")}),
279	"glProgramUniformMatrix3fv":			LogSpec({4: pointer(size = "(count * 3*3)")}),
280	"glProgramUniformMatrix4fv":			LogSpec({4: pointer(size = "(count * 4*4)")}),
281	"glProgramUniformMatrix2x3fv":			LogSpec({4: pointer(size = "(count * 2*3)")}),
282	"glProgramUniformMatrix2x4fv":			LogSpec({4: pointer(size = "(count * 2*4)")}),
283	"glProgramUniformMatrix3x2fv":			LogSpec({4: pointer(size = "(count * 3*2)")}),
284	"glProgramUniformMatrix3x4fv":			LogSpec({4: pointer(size = "(count * 3*4)")}),
285	"glProgramUniformMatrix4x3fv":			LogSpec({4: pointer(size = "(count * 4*3)")}),
286	"glProgramUniformMatrix4x2fv":			LogSpec({4: pointer(size = "(count * 4*2)")}),
287	"glProvokingVertex":					LogSpec({0: enum("ProvokingVertex")}),
288	"glVertexAttrib1fv":					LogSpec({1: pointer(size = "1")}),
289	"glVertexAttrib2fv":					LogSpec({1: pointer(size = "2")}),
290	"glVertexAttrib3fv":					LogSpec({1: pointer(size = "3")}),
291	"glVertexAttrib4fv":					LogSpec({1: pointer(size = "4")}),
292	"glVertexAttrib1sv":					LogSpec({1: pointer(size = "1")}),
293	"glVertexAttrib2sv":					LogSpec({1: pointer(size = "2")}),
294	"glVertexAttrib3sv":					LogSpec({1: pointer(size = "3")}),
295	"glVertexAttrib4sv":					LogSpec({1: pointer(size = "4")}),
296	"glVertexAttrib1dv":					LogSpec({1: pointer(size = "1")}),
297	"glVertexAttrib2dv":					LogSpec({1: pointer(size = "2")}),
298	"glVertexAttrib3dv":					LogSpec({1: pointer(size = "3")}),
299	"glVertexAttrib4dv":					LogSpec({1: pointer(size = "4")}),
300	"glVertexAttrib4bv":					LogSpec({1: pointer(size = "4")}),
301	"glVertexAttrib4iv":					LogSpec({1: pointer(size = "4")}),
302	"glVertexAttrib4ubv":					LogSpec({1: pointer(size = "4")}),
303	"glVertexAttrib4usv":					LogSpec({1: pointer(size = "4")}),
304	"glVertexAttrib4uiv":					LogSpec({1: pointer(size = "4")}),
305	"glVertexAttrib4Nbv":					LogSpec({1: pointer(size = "4")}),
306	"glVertexAttrib4Nsv":					LogSpec({1: pointer(size = "4")}),
307	"glVertexAttrib4Niv":					LogSpec({1: pointer(size = "4")}),
308	"glVertexAttrib4Nubv":					LogSpec({1: pointer(size = "4")}),
309	"glVertexAttrib4Nusv":					LogSpec({1: pointer(size = "4")}),
310	"glVertexAttrib4Nuiv":					LogSpec({1: pointer(size = "4")}),
311	"glVertexAttribI1iv":					LogSpec({1: pointer(size = "1")}),
312	"glVertexAttribI2iv":					LogSpec({1: pointer(size = "2")}),
313	"glVertexAttribI3iv":					LogSpec({1: pointer(size = "3")}),
314	"glVertexAttribI4iv":					LogSpec({1: pointer(size = "4")}),
315	"glVertexAttribI1uiv":					LogSpec({1: pointer(size = "1")}),
316	"glVertexAttribI2uiv":					LogSpec({1: pointer(size = "2")}),
317	"glVertexAttribI3uiv":					LogSpec({1: pointer(size = "3")}),
318	"glVertexAttribI4uiv":					LogSpec({1: pointer(size = "4")}),
319	"glVertexAttribI4bv":					LogSpec({1: pointer(size = "4")}),
320	"glVertexAttribI4sv":					LogSpec({1: pointer(size = "4")}),
321	"glVertexAttribI4ubv":					LogSpec({1: pointer(size = "4")}),
322	"glVertexAttribI4usv":					LogSpec({1: pointer(size = "4")}),
323	"glVertexAttribPointer":				LogSpec({2: enum("Type")}),
324	"glVertexAttribIPointer":				LogSpec({2: enum("Type")}),
325	"glVertexAttribFormat":					LogSpec({2: enum("Type")}),
326	"glVertexAttribIFormat":				LogSpec({2: enum("Type")}),
327	"glInvalidateFramebuffer":				LogSpec({0: enum("FramebufferTarget"), 2: enumPointer("InvalidateAttachment", "numAttachments")}),
328	"glInvalidateSubFramebuffer":			LogSpec({0: enum("FramebufferTarget"), 2: enumPointer("InvalidateAttachment", "numAttachments")}),
329	"glMapBufferRange":						LogSpec({0: enum("BufferTarget"), 3: enum("BufferMapFlags")}),
330	"glUnmapBuffer":						LogSpec({0: enum("BufferTarget")}),
331	"glFlushMappedBufferRange":				LogSpec({0: enum("BufferTarget")}),
332	"glMemoryBarrier":						LogSpec({0: enum("MemoryBarrierFlags")}),
333	"glBindImageTexture":					LogSpec({5: enum("ImageAccess"), 6: enum("PixelFormat")}),
334	"glGetProgramResourceIndex":			LogSpec({1: enum("ProgramInterface")}),
335	"glGetProgramResourceiv":
336		LogSpec(
337			{
338				1: enum("ProgramInterface"),
339				4: enumPointer("ProgramResourceProperty", "propCount")
340			},
341			argOutPrints =
342			{
343				6: pointer(size = "1"),
344				7: pointer(size = "((length == DE_NULL) ? (bufSize) : ((bufSize < *length) ? (bufSize) : (*length)))")
345			}),
346	"glDebugMessageInsert":					LogSpec({0: enum("DebugMessageSource"), 1: enum("DebugMessageType"), 3: enum("DebugMessageSeverity")}),
347	"glDebugMessageControl":				LogSpec({0: enum("DebugMessageSource"), 1: enum("DebugMessageType"), 2: enum("DebugMessageSeverity"), 4: pointer(size = "(count)")}),
348	"glDebugMessageCallback":				LogSpec({0: fnPointer, 1: voidPointer}),
349	"glPushDebugGroup":						LogSpec({0: enum("DebugMessageSource")}),
350	"glTexBuffer":							LogSpec({0: enum("BufferTarget"), 1: enum("PixelFormat")}),
351	"glTexBufferRange":						LogSpec({0: enum("BufferTarget"), 1: enum("PixelFormat")}),
352}
353
354def glwPrefix (string):
355	return re.sub(r'\bGL', 'glw::GL', string)
356
357def prefixedParams (command):
358	if len(command.params) > 0:
359		return ", ".join(glwPrefix(param.declaration) for param in command.params)
360	else:
361		return "void"
362
363def commandLogWrapperMemberDecl (command):
364	return "%s\t%s\t(%s);" % (glwPrefix(command.type), command.name, prefixedParams(command))
365
366def getVarDefaultPrint (type, varName):
367	if re.match(r'^const +GLchar *\*$', type):
368		return "getStringStr(%s)" % varName
369	elif re.match(r'(GLubyte|GLbyte|GLenum|GLushort|GLbitfield|\*)$', type):
370		return "toHex(%s)" % varName
371	elif type == 'GLboolean':
372		return "getBooleanStr(%s)" % varName
373	elif re.match(r'^(const +)?.+ *\*$', type) and not re.match(r'^(const +)?void *\*$', type):
374		# non-void pointer type, always cast to void* to avoid unforeseen consequences of
375		# implicit assumptions (such as char* should be printed as a zero-terminated string)
376		# \note use static_cast to break the build if function pointer is supplied
377		return "toHex(reinterpret_cast<deUintptr>(static_cast<const void*>(%s)))" % varName
378	else:
379		return varName
380
381def commandLogWrapperMemberDef (command):
382	src = ""
383	try:
384		logSpec = CALL_LOG_SPECS[command.name]
385	except KeyError:
386		logSpec = None
387
388	src += "\n"
389	src += "%s CallLogWrapper::%s (%s)\n{\n" % (glwPrefix(command.type), command.name, prefixedParams(command))
390
391	# Append paramemetrs
392	callPrintItems = ["\"%s(\"" % command.name]
393	for paramNdx, param in enumerate(command.params):
394		if paramNdx > 0:
395			callPrintItems.append("\", \"")
396
397		if logSpec and paramNdx in logSpec.argInPrints:
398			callPrintItems.append(logSpec.argInPrints[paramNdx](param.name))
399		else:
400			callPrintItems.append(getVarDefaultPrint(param.type, param.name))
401
402	callPrintItems += ["\");\"", "TestLog::EndMessage"]
403
404	src += "\tif (m_enableLog)\n"
405	src += "\t\tm_log << TestLog::Message << %s;\n" % " << ".join(callPrintItems)
406
407	callStr = "m_gl.%s(%s)" % (getFunctionMemberName(command.name), ", ".join([p.name for p in command.params]))
408
409	isVoid	= command.type == 'void'
410	if isVoid:
411		src += "\t%s;\n" % callStr
412	else:
413		src += "\t%s returnValue = %s;\n" % (glwPrefix(command.type), callStr)
414
415	if logSpec and len(logSpec.argOutPrints) > 0:
416		# Print values returned in pointers
417		src += "\tif (m_enableLog)\n"
418		printouts = ""
419		numPrintouts = 0
420
421		for paramNdx, param in enumerate(command.params):
422			if paramNdx in logSpec.argOutPrints:
423				printouts += "\t\tm_log << TestLog::Message << \"// %s = \" << %s << TestLog::EndMessage;\n" % (param.name, logSpec.argOutPrints[paramNdx](param.name))
424				numPrintouts += 1
425
426		# If print handlers do not match the actual command, that is very likely an error. Check
427		# print handlers is a subset of all arguments.
428		if numPrintouts == 0 or len(set(logSpec.argOutPrints.keys()) - set(range(len(command.params)))) > 0:
429			raise Exception("Invalid print handlers when processing command %s" % command.name)
430
431		if numPrintouts != 1:
432			src += "\t{\n"
433		src += printouts
434		if numPrintouts != 1:
435			src += "\t}\n"
436
437	if not isVoid:
438		# Print return value
439		returnPrint = getVarDefaultPrint(command.type, "returnValue")
440		if logSpec and logSpec.returnPrint:
441			returnPrint = logSpec.returnPrint("returnValue")
442
443		src += "\tif (m_enableLog)\n"
444		src += "\t\tm_log << TestLog::Message << \"// \" << %s << \" returned\" << TestLog::EndMessage;\n" % returnPrint
445		src += "\treturn returnValue;\n"
446
447	src += "}"
448	return src
449
450def genCallLogWrapper (iface):
451	genCommandList(iface, commandLogWrapperMemberDecl, OPENGL_DIR, "gluCallLogWrapperApi.inl", True)
452	genCommandList(iface, commandLogWrapperMemberDef, OPENGL_DIR, "gluCallLogWrapper.inl", False)
453
454if __name__ == "__main__":
455	genCallLogWrapper(getHybridInterface())
456