1 //
2 // Copyright 2022 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // frame_capture_utils.cpp:
7 // ANGLE Frame capture common classes.
8 //
9
10 #include "common/frame_capture_utils.h"
11
12 namespace angle
13 {
14 namespace
15 {
16 // Keep the simplest nullptr string for easy C parsing.
17 constexpr char kNullPointerString[] = "0";
18 } // anonymous namespace
19
20 uint32_t ParamCapture::nextID = 0;
21
ParamCapture()22 ParamCapture::ParamCapture()
23 : type(ParamType::TGLenum), enumGroup(gl::GLESEnum::AllEnums), uniqueID(nextID++)
24 {}
25
ParamCapture(const char * nameIn,ParamType typeIn)26 ParamCapture::ParamCapture(const char *nameIn, ParamType typeIn)
27 : name(nameIn),
28 type(typeIn),
29 enumGroup(gl::GLESEnum::AllEnums),
30 bigGLEnum(gl::BigGLEnum::AllEnums),
31 uniqueID(nextID++)
32 {}
33
34 ParamCapture::~ParamCapture() = default;
35
ParamCapture(ParamCapture && other)36 ParamCapture::ParamCapture(ParamCapture &&other)
37 : type(ParamType::TGLenum),
38 enumGroup(gl::GLESEnum::AllEnums),
39 bigGLEnum(gl::BigGLEnum::AllEnums)
40 {
41 *this = std::move(other);
42 }
43
operator =(ParamCapture && other)44 ParamCapture &ParamCapture::operator=(ParamCapture &&other)
45 {
46 std::swap(name, other.name);
47 std::swap(type, other.type);
48 std::swap(value, other.value);
49 std::swap(enumGroup, other.enumGroup);
50 std::swap(bigGLEnum, other.bigGLEnum);
51 std::swap(data, other.data);
52 std::swap(arrayClientPointerIndex, other.arrayClientPointerIndex);
53 std::swap(readBufferSizeBytes, other.readBufferSizeBytes);
54 std::swap(dataNElements, other.dataNElements);
55 std::swap(uniqueID, other.uniqueID);
56 return *this;
57 }
58
ParamBuffer()59 ParamBuffer::ParamBuffer() {}
60
61 ParamBuffer::~ParamBuffer() = default;
62
ParamBuffer(ParamBuffer && other)63 ParamBuffer::ParamBuffer(ParamBuffer &&other)
64 {
65 *this = std::move(other);
66 }
67
operator =(ParamBuffer && other)68 ParamBuffer &ParamBuffer::operator=(ParamBuffer &&other)
69 {
70 std::swap(mParamCaptures, other.mParamCaptures);
71 std::swap(mClientArrayDataParam, other.mClientArrayDataParam);
72 std::swap(mReadBufferSize, other.mReadBufferSize);
73 std::swap(mReturnValueCapture, other.mReturnValueCapture);
74 return *this;
75 }
76
getParam(const char * paramName,ParamType paramType,int index)77 ParamCapture &ParamBuffer::getParam(const char *paramName, ParamType paramType, int index)
78 {
79 ParamCapture &capture = mParamCaptures[index];
80 ASSERT(capture.name == paramName);
81 ASSERT(capture.type == paramType);
82 return capture;
83 }
84
getParam(const char * paramName,ParamType paramType,int index) const85 const ParamCapture &ParamBuffer::getParam(const char *paramName,
86 ParamType paramType,
87 int index) const
88 {
89 return const_cast<ParamBuffer *>(this)->getParam(paramName, paramType, index);
90 }
91
getParamFlexName(const char * paramName1,const char * paramName2,ParamType paramType,int index)92 ParamCapture &ParamBuffer::getParamFlexName(const char *paramName1,
93 const char *paramName2,
94 ParamType paramType,
95 int index)
96 {
97 ParamCapture &capture = mParamCaptures[index];
98 ASSERT(capture.name == paramName1 || capture.name == paramName2);
99 ASSERT(capture.type == paramType);
100 return capture;
101 }
102
getParamFlexName(const char * paramName1,const char * paramName2,ParamType paramType,int index) const103 const ParamCapture &ParamBuffer::getParamFlexName(const char *paramName1,
104 const char *paramName2,
105 ParamType paramType,
106 int index) const
107 {
108 return const_cast<ParamBuffer *>(this)->getParamFlexName(paramName1, paramName2, paramType,
109 index);
110 }
111
addParam(ParamCapture && param)112 void ParamBuffer::addParam(ParamCapture &¶m)
113 {
114 if (param.arrayClientPointerIndex != -1)
115 {
116 ASSERT(mClientArrayDataParam == -1);
117 mClientArrayDataParam = static_cast<int>(mParamCaptures.size());
118 }
119
120 mReadBufferSize = std::max(param.readBufferSizeBytes, mReadBufferSize);
121 mParamCaptures.emplace_back(std::move(param));
122 }
123
addReturnValue(ParamCapture && returnValue)124 void ParamBuffer::addReturnValue(ParamCapture &&returnValue)
125 {
126 mReturnValueCapture = std::move(returnValue);
127 }
128
getNextParamName()129 const char *ParamBuffer::getNextParamName()
130 {
131 static const char *kParamNames[] = {"p0", "p1", "p2", "p3", "p4", "p5", "p6", "p7",
132 "p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15",
133 "p16", "p17", "p18", "p19", "p20", "p21", "p22"};
134 ASSERT(mParamCaptures.size() < ArraySize(kParamNames));
135 return kParamNames[mParamCaptures.size()];
136 }
137
getClientArrayPointerParameter()138 ParamCapture &ParamBuffer::getClientArrayPointerParameter()
139 {
140 ASSERT(hasClientArrayData());
141 return mParamCaptures[mClientArrayDataParam];
142 }
143
CallCapture(EntryPoint entryPointIn,ParamBuffer && paramsIn)144 CallCapture::CallCapture(EntryPoint entryPointIn, ParamBuffer &¶msIn)
145 : entryPoint(entryPointIn), params(std::move(paramsIn))
146 {}
147
CallCapture(const std::string & customFunctionNameIn,ParamBuffer && paramsIn)148 CallCapture::CallCapture(const std::string &customFunctionNameIn, ParamBuffer &¶msIn)
149 : entryPoint(EntryPoint::Invalid),
150 customFunctionName(customFunctionNameIn),
151 params(std::move(paramsIn))
152 {}
153
154 CallCapture::~CallCapture() = default;
155
CallCapture(CallCapture && other)156 CallCapture::CallCapture(CallCapture &&other)
157 {
158 *this = std::move(other);
159 }
160
operator =(CallCapture && other)161 CallCapture &CallCapture::operator=(CallCapture &&other)
162 {
163 std::swap(entryPoint, other.entryPoint);
164 std::swap(customFunctionName, other.customFunctionName);
165 std::swap(params, other.params);
166 std::swap(isActive, other.isActive);
167 std::swap(contextID, other.contextID);
168 std::swap(isSyncPoint, other.isSyncPoint);
169 return *this;
170 }
171
name() const172 const char *CallCapture::name() const
173 {
174 if (customFunctionName.empty())
175 {
176 ASSERT(entryPoint != EntryPoint::Invalid);
177 return angle::GetEntryPointName(entryPoint);
178 }
179 else
180 {
181 return customFunctionName.c_str();
182 }
183 }
184
185 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,GLboolean value)186 void WriteParamValueReplay<ParamType::TGLboolean>(std::ostream &os,
187 const CallCapture &call,
188 GLboolean value)
189 {
190 switch (value)
191 {
192 case GL_TRUE:
193 os << "GL_TRUE";
194 break;
195 case GL_FALSE:
196 os << "GL_FALSE";
197 break;
198 default:
199 os << "0x" << std::hex << std::uppercase << GLint(value);
200 }
201 }
202
203 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,GLboolean * value)204 void WriteParamValueReplay<ParamType::TGLbooleanPointer>(std::ostream &os,
205 const CallCapture &call,
206 GLboolean *value)
207 {
208 if (value == 0)
209 {
210 os << kNullPointerString;
211 }
212 else
213 {
214 os << "(GLboolean *)" << static_cast<int>(reinterpret_cast<uintptr_t>(value));
215 }
216 }
217
218 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,const void * value)219 void WriteParamValueReplay<ParamType::TvoidConstPointer>(std::ostream &os,
220 const CallCapture &call,
221 const void *value)
222 {
223 if (value == 0)
224 {
225 os << kNullPointerString;
226 }
227 else
228 {
229 os << "(const void *)" << static_cast<int>(reinterpret_cast<uintptr_t>(value));
230 }
231 }
232
233 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,void * value)234 void WriteParamValueReplay<ParamType::TvoidPointer>(std::ostream &os,
235 const CallCapture &call,
236 void *value)
237 {
238 if (value == 0 || value == nullptr)
239 {
240 os << kNullPointerString;
241 }
242 else
243 {
244 os << "(void *)" << static_cast<int>(reinterpret_cast<uintptr_t>(value));
245 }
246 }
247
248 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,const GLfloat * value)249 void WriteParamValueReplay<ParamType::TGLfloatConstPointer>(std::ostream &os,
250 const CallCapture &call,
251 const GLfloat *value)
252 {
253 if (value == 0)
254 {
255 os << kNullPointerString;
256 }
257 else
258 {
259 os << "(const GLfloat *)" << static_cast<int>(reinterpret_cast<uintptr_t>(value));
260 }
261 }
262
263 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,const GLint * value)264 void WriteParamValueReplay<ParamType::TGLintConstPointer>(std::ostream &os,
265 const CallCapture &call,
266 const GLint *value)
267 {
268 if (value == 0)
269 {
270 os << kNullPointerString;
271 }
272 else
273 {
274 os << "(const GLint *)" << static_cast<int>(reinterpret_cast<intptr_t>(value));
275 }
276 }
277
278 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,GLsizei * value)279 void WriteParamValueReplay<ParamType::TGLsizeiPointer>(std::ostream &os,
280 const CallCapture &call,
281 GLsizei *value)
282 {
283 if (value == 0)
284 {
285 os << kNullPointerString;
286 }
287 else
288 {
289 os << "(GLsizei *)" << static_cast<int>(reinterpret_cast<intptr_t>(value));
290 }
291 }
292
293 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,GLuint * value)294 void WriteParamValueReplay<ParamType::TGLuintPointer>(std::ostream &os,
295 const CallCapture &call,
296 GLuint *value)
297 {
298 if (value == 0)
299 {
300 os << kNullPointerString;
301 }
302 else
303 {
304 os << "(GLuint *)" << static_cast<int>(reinterpret_cast<uintptr_t>(value));
305 }
306 }
307
308 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,const GLuint * value)309 void WriteParamValueReplay<ParamType::TGLuintConstPointer>(std::ostream &os,
310 const CallCapture &call,
311 const GLuint *value)
312 {
313 if (value == 0)
314 {
315 os << kNullPointerString;
316 }
317 else
318 {
319 os << "(const GLuint *)" << static_cast<int>(reinterpret_cast<uintptr_t>(value));
320 }
321 }
322
323 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,GLDEBUGPROCKHR value)324 void WriteParamValueReplay<ParamType::TGLDEBUGPROCKHR>(std::ostream &os,
325 const CallCapture &call,
326 GLDEBUGPROCKHR value)
327 {}
328
329 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,GLDEBUGPROC value)330 void WriteParamValueReplay<ParamType::TGLDEBUGPROC>(std::ostream &os,
331 const CallCapture &call,
332 GLDEBUGPROC value)
333 {}
334
335 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,gl::BufferID value)336 void WriteParamValueReplay<ParamType::TBufferID>(std::ostream &os,
337 const CallCapture &call,
338 gl::BufferID value)
339 {
340 os << "gBufferMap[" << value.value << "]";
341 }
342
343 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,gl::FenceNVID value)344 void WriteParamValueReplay<ParamType::TFenceNVID>(std::ostream &os,
345 const CallCapture &call,
346 gl::FenceNVID value)
347 {
348 os << "gFenceNVMap[" << value.value << "]";
349 }
350
351 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,gl::FramebufferID value)352 void WriteParamValueReplay<ParamType::TFramebufferID>(std::ostream &os,
353 const CallCapture &call,
354 gl::FramebufferID value)
355 {
356 os << "gFramebufferMapPerContext[" << call.contextID.value << "][" << value.value << "]";
357 }
358
359 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,gl::MemoryObjectID value)360 void WriteParamValueReplay<ParamType::TMemoryObjectID>(std::ostream &os,
361 const CallCapture &call,
362 gl::MemoryObjectID value)
363 {
364 os << "gMemoryObjectMap[" << value.value << "]";
365 }
366
367 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,gl::ProgramPipelineID value)368 void WriteParamValueReplay<ParamType::TProgramPipelineID>(std::ostream &os,
369 const CallCapture &call,
370 gl::ProgramPipelineID value)
371 {
372 os << "gProgramPipelineMap[" << value.value << "]";
373 }
374
375 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,gl::QueryID value)376 void WriteParamValueReplay<ParamType::TQueryID>(std::ostream &os,
377 const CallCapture &call,
378 gl::QueryID value)
379 {
380 os << "gQueryMap[" << value.value << "]";
381 }
382
383 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,gl::RenderbufferID value)384 void WriteParamValueReplay<ParamType::TRenderbufferID>(std::ostream &os,
385 const CallCapture &call,
386 gl::RenderbufferID value)
387 {
388 os << "gRenderbufferMap[" << value.value << "]";
389 }
390
391 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,gl::SamplerID value)392 void WriteParamValueReplay<ParamType::TSamplerID>(std::ostream &os,
393 const CallCapture &call,
394 gl::SamplerID value)
395 {
396 os << "gSamplerMap[" << value.value << "]";
397 }
398
399 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,gl::SemaphoreID value)400 void WriteParamValueReplay<ParamType::TSemaphoreID>(std::ostream &os,
401 const CallCapture &call,
402 gl::SemaphoreID value)
403 {
404 os << "gSemaphoreMap[" << value.value << "]";
405 }
406
407 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,gl::ShaderProgramID value)408 void WriteParamValueReplay<ParamType::TShaderProgramID>(std::ostream &os,
409 const CallCapture &call,
410 gl::ShaderProgramID value)
411 {
412 os << "gShaderProgramMap[" << value.value << "]";
413 }
414
415 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,gl::SyncID value)416 void WriteParamValueReplay<ParamType::TSyncID>(std::ostream &os,
417 const CallCapture &call,
418 gl::SyncID value)
419 {
420 os << "gSyncMap2[" << value.value << "]";
421 }
422
423 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,gl::TextureID value)424 void WriteParamValueReplay<ParamType::TTextureID>(std::ostream &os,
425 const CallCapture &call,
426 gl::TextureID value)
427 {
428 os << "gTextureMap[" << value.value << "]";
429 }
430
431 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,gl::TransformFeedbackID value)432 void WriteParamValueReplay<ParamType::TTransformFeedbackID>(std::ostream &os,
433 const CallCapture &call,
434 gl::TransformFeedbackID value)
435 {
436 os << "gTransformFeedbackMap[" << value.value << "]";
437 }
438
439 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,gl::VertexArrayID value)440 void WriteParamValueReplay<ParamType::TVertexArrayID>(std::ostream &os,
441 const CallCapture &call,
442 gl::VertexArrayID value)
443 {
444 os << "gVertexArrayMap[" << value.value << "]";
445 }
446
447 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,gl::UniformLocation value)448 void WriteParamValueReplay<ParamType::TUniformLocation>(std::ostream &os,
449 const CallCapture &call,
450 gl::UniformLocation value)
451 {
452 if (value.value == -1)
453 {
454 os << "-1";
455 return;
456 }
457
458 os << "gUniformLocations[";
459
460 // Find the program from the call parameters.
461 std::vector<gl::ShaderProgramID> shaderProgramIDs;
462 if (FindResourceIDsInCall<gl::ShaderProgramID>(call, shaderProgramIDs))
463 {
464 ASSERT(shaderProgramIDs.size() == 1);
465 os << shaderProgramIDs[0].value;
466 }
467 else
468 {
469 os << "gCurrentProgram";
470 }
471
472 os << "][" << value.value << "]";
473 }
474
475 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,gl::UniformBlockIndex value)476 void WriteParamValueReplay<ParamType::TUniformBlockIndex>(std::ostream &os,
477 const CallCapture &call,
478 gl::UniformBlockIndex value)
479 {
480 // We do not support directly using uniform block indexes due to their multiple indirections.
481 // Use CaptureCustomUniformBlockBinding if you end up hitting this assertion.
482 UNREACHABLE();
483 }
484
485 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,GLubyte value)486 void WriteParamValueReplay<ParamType::TGLubyte>(std::ostream &os,
487 const CallCapture &call,
488 GLubyte value)
489 {
490 const int v = value;
491 os << v;
492 }
493
494 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,EGLDEBUGPROCKHR value)495 void WriteParamValueReplay<ParamType::TEGLDEBUGPROCKHR>(std::ostream &os,
496 const CallCapture &call,
497 EGLDEBUGPROCKHR value)
498 {
499 // It's not necessary to implement correct capture for these types.
500 os << "0";
501 }
502
503 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,EGLGetBlobFuncANDROID value)504 void WriteParamValueReplay<ParamType::TEGLGetBlobFuncANDROID>(std::ostream &os,
505 const CallCapture &call,
506 EGLGetBlobFuncANDROID value)
507 {
508 // It's not necessary to implement correct capture for these types.
509 os << "0";
510 }
511
512 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,EGLSetBlobFuncANDROID value)513 void WriteParamValueReplay<ParamType::TEGLSetBlobFuncANDROID>(std::ostream &os,
514 const CallCapture &call,
515 EGLSetBlobFuncANDROID value)
516 {
517 // It's not necessary to implement correct capture for these types.
518 os << "0";
519 }
520
521 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,egl::Config * value)522 void WriteParamValueReplay<ParamType::Tegl_ConfigPointer>(std::ostream &os,
523 const CallCapture &call,
524 egl::Config *value)
525 {
526 os << "EGL_NO_CONFIG_KHR";
527 }
528
529 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,egl::SurfaceID value)530 void WriteParamValueReplay<ParamType::TSurfaceID>(std::ostream &os,
531 const CallCapture &call,
532 egl::SurfaceID value)
533 {
534 os << "gSurfaceMap2[" << value.value << "]";
535 }
536
537 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,gl::ContextID value)538 void WriteParamValueReplay<ParamType::TContextID>(std::ostream &os,
539 const CallCapture &call,
540 gl::ContextID value)
541 {
542 os << "gContextMap2[" << value.value << "]";
543 }
544
545 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,egl::Display * value)546 void WriteParamValueReplay<ParamType::Tegl_DisplayPointer>(std::ostream &os,
547 const CallCapture &call,
548 egl::Display *value)
549 {
550 os << "gEGLDisplay";
551 }
552
553 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,egl::ImageID value)554 void WriteParamValueReplay<ParamType::TImageID>(std::ostream &os,
555 const CallCapture &call,
556 egl::ImageID value)
557 {
558 os << "gEGLImageMap2[" << value.value << "]";
559 }
560
561 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,EGLClientBuffer value)562 void WriteParamValueReplay<ParamType::TEGLClientBuffer>(std::ostream &os,
563 const CallCapture &call,
564 EGLClientBuffer value)
565 {
566 os << value;
567 }
568
569 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,egl::SyncID value)570 void WriteParamValueReplay<ParamType::Tegl_SyncID>(std::ostream &os,
571 const CallCapture &call,
572 egl::SyncID value)
573 {
574 os << "gEGLSyncMap[" << value.value << "]";
575 }
576
577 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,EGLAttrib * value)578 void WriteParamValueReplay<ParamType::TEGLAttribPointer>(std::ostream &os,
579 const CallCapture &call,
580 EGLAttrib *value)
581 {
582 if (value == 0)
583 {
584 os << kNullPointerString;
585 }
586 else
587 {
588 os << "(EGLAttrib *)" << static_cast<int>(reinterpret_cast<uintptr_t>(value));
589 }
590 }
591
592 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,const EGLAttrib * value)593 void WriteParamValueReplay<ParamType::TEGLAttribConstPointer>(std::ostream &os,
594 const CallCapture &call,
595 const EGLAttrib *value)
596 {
597 if (value == 0)
598 {
599 os << kNullPointerString;
600 }
601 else
602 {
603 os << "(const EGLAttrib *)" << static_cast<int>(reinterpret_cast<uintptr_t>(value));
604 }
605 }
606
607 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,const EGLint * value)608 void WriteParamValueReplay<ParamType::TEGLintConstPointer>(std::ostream &os,
609 const CallCapture &call,
610 const EGLint *value)
611 {
612 if (value == 0)
613 {
614 os << kNullPointerString;
615 }
616 else
617 {
618 os << "(const EGLint *)" << static_cast<int>(reinterpret_cast<uintptr_t>(value));
619 }
620 }
621
622 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,EGLint * value)623 void WriteParamValueReplay<ParamType::TEGLintPointer>(std::ostream &os,
624 const CallCapture &call,
625 EGLint *value)
626 {
627 if (value == 0)
628 {
629 os << kNullPointerString;
630 }
631 else
632 {
633 os << "(const EGLint *)" << static_cast<int>(reinterpret_cast<uintptr_t>(value));
634 }
635 }
636
637 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,EGLTime value)638 void WriteParamValueReplay<ParamType::TEGLTime>(std::ostream &os,
639 const CallCapture &call,
640 EGLTime value)
641 {
642 os << value << "ul";
643 }
644
645 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,EGLTimeKHR value)646 void WriteParamValueReplay<ParamType::TEGLTimeKHR>(std::ostream &os,
647 const CallCapture &call,
648 EGLTimeKHR value)
649 {
650 os << value << "ul";
651 }
652
653 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,GLGETBLOBPROCANGLE value)654 void WriteParamValueReplay<ParamType::TGLGETBLOBPROCANGLE>(std::ostream &os,
655 const CallCapture &call,
656 GLGETBLOBPROCANGLE value)
657 {
658 // It's not necessary to implement correct capture for these types.
659 os << "0";
660 }
661
662 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,GLSETBLOBPROCANGLE value)663 void WriteParamValueReplay<ParamType::TGLSETBLOBPROCANGLE>(std::ostream &os,
664 const CallCapture &call,
665 GLSETBLOBPROCANGLE value)
666 {
667 // It's not necessary to implement correct capture for these types.
668 os << "0";
669 }
670
671 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,const char * value)672 void WriteParamValueReplay<ParamType::TcharConstPointer>(std::ostream &os,
673 const CallCapture &call,
674 const char *value)
675 {
676 if (value)
677 {
678 os << "\"" << value << "\"";
679 }
680 else
681 {
682 os << NULL;
683 }
684 }
685
686 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,size_t * value)687 void WriteParamValueReplay<ParamType::Tsize_tPointer>(std::ostream &os,
688 const CallCapture &call,
689 size_t *value)
690 {
691 ASSERT(!value);
692 os << "NULL";
693 }
694
695 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,size_t const * value)696 void WriteParamValueReplay<ParamType::Tsize_tConstPointer>(std::ostream &os,
697 const CallCapture &call,
698 size_t const *value)
699 {
700 ASSERT(!value);
701 os << "NULL";
702 }
703
704 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,const char ** value)705 void WriteParamValueReplay<ParamType::TcharConstPointerPointer>(std::ostream &os,
706 const CallCapture &call,
707 const char **value)
708 {
709 ASSERT(!value);
710 os << "NULL";
711 }
712
713 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,const unsigned char ** value)714 void WriteParamValueReplay<ParamType::TcharUnsignedConstPointerPointer>(std::ostream &os,
715 const CallCapture &call,
716 const unsigned char **value)
717 {
718 ASSERT(!value);
719 os << "NULL";
720 }
721
722 #ifdef ANGLE_ENABLE_CL
723
724 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,cl_platform_id * value)725 void WriteParamValueReplay<ParamType::Tcl_platform_idPointer>(std::ostream &os,
726 const CallCapture &call,
727 cl_platform_id *value)
728 {
729 ASSERT(!value);
730 os << "NULL";
731 }
732
733 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,cl_uint * value)734 void WriteParamValueReplay<ParamType::Tcl_uintPointer>(std::ostream &os,
735 const CallCapture &call,
736 cl_uint *value)
737 {
738 ASSERT(!value);
739 os << "NULL";
740 }
741
742 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,cl_device_id * value)743 void WriteParamValueReplay<ParamType::Tcl_device_idPointer>(std::ostream &os,
744 const CallCapture &call,
745 cl_device_id *value)
746 {
747 ASSERT(!value);
748 os << "NULL";
749 }
750
751 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,cl_context_properties const * value)752 void WriteParamValueReplay<ParamType::Tcl_context_propertiesConstPointer>(
753 std::ostream &os,
754 const CallCapture &call,
755 cl_context_properties const *value)
756 {
757 ASSERT(!value);
758 os << "NULL";
759 }
760
761 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,cl_event * value)762 void WriteParamValueReplay<ParamType::Tcl_eventPointer>(std::ostream &os,
763 const CallCapture &call,
764 cl_event *value)
765 {
766 ASSERT(!value);
767 os << "NULL";
768 }
769
770 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,cl_event const * value)771 void WriteParamValueReplay<ParamType::Tcl_eventConstPointer>(std::ostream &os,
772 const CallCapture &call,
773 cl_event const *value)
774 {
775 ASSERT(!value);
776 os << "NULL";
777 }
778
779 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,cl_device_id const * value)780 void WriteParamValueReplay<ParamType::Tcl_device_idConstPointer>(std::ostream &os,
781 const CallCapture &call,
782 cl_device_id const *value)
783 {
784 ASSERT(!value);
785 os << "NULL";
786 }
787
788 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,cl_image_format * value)789 void WriteParamValueReplay<ParamType::Tcl_image_formatPointer>(std::ostream &os,
790 const CallCapture &call,
791 cl_image_format *value)
792 {
793 ASSERT(!value);
794 os << "NULL";
795 }
796
797 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,cl_int * value)798 void WriteParamValueReplay<ParamType::Tcl_intPointer>(std::ostream &os,
799 const CallCapture &call,
800 cl_int *value)
801 {
802 ASSERT(!value);
803 os << "NULL";
804 }
805
806 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,const cl_queue_properties * value)807 void WriteParamValueReplay<ParamType::Tcl_queue_propertiesConstPointer>(
808 std::ostream &os,
809 const CallCapture &call,
810 const cl_queue_properties *value)
811 {
812 ASSERT(!value);
813 os << "NULL";
814 }
815
816 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,const cl_command_queue_properties * value)817 void WriteParamValueReplay<ParamType::Tcl_command_queue_propertiesPointer>(
818 std::ostream &os,
819 const CallCapture &call,
820 const cl_command_queue_properties *value)
821 {
822 ASSERT(!value);
823 os << "NULL";
824 }
825
826 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,const cl_device_partition_property * value)827 void WriteParamValueReplay<ParamType::Tcl_device_partition_propertyConstPointer>(
828 std::ostream &os,
829 const CallCapture &call,
830 const cl_device_partition_property *value)
831 {
832 ASSERT(!value);
833 os << "NULL";
834 }
835
836 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,const cl_program * value)837 void WriteParamValueReplay<ParamType::Tcl_programConstPointer>(std::ostream &os,
838 const CallCapture &call,
839 const cl_program *value)
840 {
841 ASSERT(!value);
842 os << "NULL";
843 }
844
845 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,const cl_pipe_properties * value)846 void WriteParamValueReplay<ParamType::Tcl_pipe_propertiesConstPointer>(
847 std::ostream &os,
848 const CallCapture &call,
849 const cl_pipe_properties *value)
850 {
851 ASSERT(!value);
852 os << "NULL";
853 }
854
855 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,cl_ulong * value)856 void WriteParamValueReplay<ParamType::Tcl_ulongPointer>(std::ostream &os,
857 const CallCapture &call,
858 cl_ulong *value)
859 {
860 ASSERT(!value);
861 os << "NULL";
862 }
863
864 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,cl_callback_func_type value)865 void WriteParamValueReplay<ParamType::Tcl_callback_func_type>(std::ostream &os,
866 const CallCapture &call,
867 cl_callback_func_type value)
868 {
869 os << "NULL";
870 }
871
872 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,cl_context_destructor_func_type value)873 void WriteParamValueReplay<ParamType::Tcl_context_destructor_func_type>(
874 std::ostream &os,
875 const CallCapture &call,
876 cl_context_destructor_func_type value)
877 {
878 os << "NULL";
879 }
880
881 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,cl_context_func_type value)882 void WriteParamValueReplay<ParamType::Tcl_context_func_type>(std::ostream &os,
883 const CallCapture &call,
884 cl_context_func_type value)
885 {
886 os << "NULL";
887 }
888
889 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,cl_mem_destructor_func_type value)890 void WriteParamValueReplay<ParamType::Tcl_mem_destructor_func_type>(
891 std::ostream &os,
892 const CallCapture &call,
893 cl_mem_destructor_func_type value)
894 {
895 os << "NULL";
896 }
897
898 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,cl_program_func_type value)899 void WriteParamValueReplay<ParamType::Tcl_program_func_type>(std::ostream &os,
900 const CallCapture &call,
901 cl_program_func_type value)
902 {
903 os << "NULL";
904 }
905
906 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,cl_svm_free_callback_func_type value)907 void WriteParamValueReplay<ParamType::Tcl_svm_free_callback_func_type>(
908 std::ostream &os,
909 const CallCapture &call,
910 cl_svm_free_callback_func_type value)
911 {
912 os << "NULL";
913 }
914
915 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,cl_void_func_type value)916 void WriteParamValueReplay<ParamType::Tcl_void_func_type>(std::ostream &os,
917 const CallCapture &call,
918 cl_void_func_type value)
919 {
920 os << "NULL";
921 }
922
923 #endif
924
925 template <typename ParamValueType>
FindResourceIDsInCall(const CallCapture & call,std::vector<ParamValueType> & idsOut)926 bool FindResourceIDsInCall(const CallCapture &call, std::vector<ParamValueType> &idsOut)
927 {
928 const ParamType paramType = ParamValueTrait<ParamValueType>::typeID;
929 for (const ParamCapture ¶m : call.params.getParamCaptures())
930 {
931 if (param.type == paramType)
932 {
933 const ParamValueType id = AccessParamValue<ParamValueType>(paramType, param.value);
934 idsOut.push_back(id);
935 }
936 }
937
938 return !idsOut.empty();
939 }
940
941 // Explicit instantiation
942 template bool FindResourceIDsInCall<gl::TextureID>(const CallCapture &call,
943 std::vector<gl::TextureID> &idsOut);
944 template bool FindResourceIDsInCall<gl::ShaderProgramID>(const CallCapture &call,
945 std::vector<gl::ShaderProgramID> &idsOut);
946 } // namespace angle
947