1from .common.codegen import CodeGen, VulkanWrapperGenerator, VulkanAPIWrapper 2from .common.vulkantypes import \ 3 VulkanAPI, makeVulkanTypeSimple, iterateVulkanType, DISPATCHABLE_HANDLE_TYPES, NON_DISPATCHABLE_HANDLE_TYPES 4 5from .marshaling import VulkanMarshalingCodegen 6from .reservedmarshaling import VulkanReservedMarshalingCodegen 7from .transform import TransformCodegen, genTransformsForVulkanType 8 9from .wrapperdefs import API_PREFIX_MARSHAL 10from .wrapperdefs import API_PREFIX_UNMARSHAL, API_PREFIX_RESERVEDUNMARSHAL 11from .wrapperdefs import VULKAN_STREAM_TYPE 12from .wrapperdefs import ROOT_TYPE_DEFAULT_VALUE 13from .wrapperdefs import RELAXED_APIS 14 15from copy import copy 16 17SKIPPED_DECODER_DELETES = [ 18 "vkFreeDescriptorSets", 19] 20 21DELAYED_DECODER_DELETES = [ 22 "vkDestroyPipelineLayout", 23] 24 25decoder_decl_preamble = """ 26 27class IOStream; 28 29class VkDecoder { 30public: 31 VkDecoder(); 32 ~VkDecoder(); 33 void setForSnapshotLoad(bool forSnapshotLoad); 34 size_t decode(void* buf, size_t bufsize, IOStream* stream, uint32_t* seqnoPtr); 35private: 36 class Impl; 37 std::unique_ptr<Impl> mImpl; 38}; 39""" 40 41decoder_impl_preamble =""" 42using emugl::vkDispatch; 43 44using namespace goldfish_vk; 45 46class VkDecoder::Impl { 47public: 48 Impl() : m_logCalls(android::base::getEnvironmentVariable("ANDROID_EMU_VK_LOG_CALLS") == "1"), 49 m_vk(vkDispatch()), 50 m_state(VkDecoderGlobalState::get()), 51 m_boxedHandleUnwrapMapping(m_state), 52 m_boxedHandleCreateMapping(m_state), 53 m_boxedHandleDestroyMapping(m_state), 54 m_boxedHandleUnwrapAndDeleteMapping(m_state), 55 m_boxedHandleUnwrapAndDeletePreserveBoxedMapping(m_state) { } 56 %s* stream() { return &m_vkStream; } 57 VulkanMemReadingStream* readStream() { return &m_vkMemReadingStream; } 58 59 void setForSnapshotLoad(bool forSnapshotLoad) { 60 m_forSnapshotLoad = forSnapshotLoad; 61 } 62 63 size_t decode(void* buf, size_t bufsize, IOStream* stream, uint32_t* seqnoPtr); 64 65private: 66 bool m_logCalls; 67 bool m_forSnapshotLoad = false; 68 VulkanDispatch* m_vk; 69 VkDecoderGlobalState* m_state; 70 %s m_vkStream { nullptr }; 71 VulkanMemReadingStream m_vkMemReadingStream { nullptr }; 72 BoxedHandleUnwrapMapping m_boxedHandleUnwrapMapping; 73 BoxedHandleCreateMapping m_boxedHandleCreateMapping; 74 BoxedHandleDestroyMapping m_boxedHandleDestroyMapping; 75 BoxedHandleUnwrapAndDeleteMapping m_boxedHandleUnwrapAndDeleteMapping; 76 android::base::BumpPool m_pool; 77 BoxedHandleUnwrapAndDeletePreserveBoxedMapping m_boxedHandleUnwrapAndDeletePreserveBoxedMapping; 78}; 79 80VkDecoder::VkDecoder() : 81 mImpl(new VkDecoder::Impl()) { } 82 83VkDecoder::~VkDecoder() = default; 84 85void VkDecoder::setForSnapshotLoad(bool forSnapshotLoad) { 86 mImpl->setForSnapshotLoad(forSnapshotLoad); 87} 88 89size_t VkDecoder::decode(void* buf, size_t bufsize, IOStream* stream, uint32_t* seqnoPtr) { 90 return mImpl->decode(buf, bufsize, stream, seqnoPtr); 91} 92 93// VkDecoder::Impl::decode to follow 94""" % (VULKAN_STREAM_TYPE, VULKAN_STREAM_TYPE) 95 96READ_STREAM = "vkReadStream" 97WRITE_STREAM = "vkStream" 98 99# Driver workarounds for APIs that don't work well multithreaded 100driver_workarounds_global_lock_apis = [ \ 101 "vkCreatePipelineLayout", 102 "vkDestroyPipelineLayout", 103] 104 105def emit_param_decl_for_reading(param, cgen): 106 if param.staticArrExpr: 107 cgen.stmt( 108 cgen.makeRichCTypeDecl(param.getForNonConstAccess())) 109 else: 110 cgen.stmt( 111 cgen.makeRichCTypeDecl(param)) 112 113def emit_unmarshal(typeInfo, param, cgen, output = False, destroy = False, noUnbox = False): 114 if destroy: 115 iterateVulkanType(typeInfo, param, VulkanReservedMarshalingCodegen( 116 cgen, 117 READ_STREAM, 118 ROOT_TYPE_DEFAULT_VALUE, 119 param.paramName, 120 "readStreamPtrPtr", 121 API_PREFIX_RESERVEDUNMARSHAL, 122 "", 123 direction="read", 124 dynAlloc=True)) 125 lenAccess = cgen.generalLengthAccess(param) 126 lenAccessGuard = cgen.generalLengthAccessGuard(param) 127 if None == lenAccess or "1" == lenAccess: 128 cgen.stmt("boxed_%s_preserve = %s" % (param.paramName, param.paramName)) 129 cgen.stmt("%s = unbox_%s(%s)" % (param.paramName, param.typeName, param.paramName)) 130 else: 131 if lenAccessGuard is not None: 132 cgen.beginIf(lenAccessGuard) 133 cgen.beginFor("uint32_t i = 0", "i < %s" % lenAccess, "++i") 134 cgen.stmt("boxed_%s_preserve[i] = %s[i]" % (param.paramName, param.paramName)) 135 cgen.stmt("((%s*)(%s))[i] = unbox_%s(%s[i])" % (param.typeName, param.paramName, param.typeName, param.paramName)) 136 cgen.endFor() 137 if lenAccessGuard is not None: 138 cgen.endIf() 139 else: 140 if noUnbox: 141 cgen.line("// No unbox for %s" % (param.paramName)) 142 iterateVulkanType(typeInfo, param, VulkanReservedMarshalingCodegen( 143 cgen, 144 READ_STREAM, 145 ROOT_TYPE_DEFAULT_VALUE, 146 param.paramName, 147 "readStreamPtrPtr", 148 API_PREFIX_RESERVEDUNMARSHAL, 149 "" if (output or noUnbox) else "unbox_", 150 direction="read", 151 dynAlloc=True)) 152 153def emit_dispatch_unmarshal(typeInfo, param, cgen, globalWrapped): 154 if globalWrapped: 155 cgen.stmt("// Begin global wrapped dispatchable handle unboxing for %s" % param.paramName) 156 iterateVulkanType(typeInfo, param, VulkanReservedMarshalingCodegen( 157 cgen, 158 READ_STREAM, 159 ROOT_TYPE_DEFAULT_VALUE, 160 param.paramName, 161 "readStreamPtrPtr", 162 API_PREFIX_RESERVEDUNMARSHAL, 163 "", 164 direction="read", 165 dynAlloc=True)) 166 else: 167 cgen.stmt("// Begin non wrapped dispatchable handle unboxing for %s" % param.paramName) 168 # cgen.stmt("%s->unsetHandleMapping()" % READ_STREAM) 169 iterateVulkanType(typeInfo, param, VulkanReservedMarshalingCodegen( 170 cgen, 171 READ_STREAM, 172 ROOT_TYPE_DEFAULT_VALUE, 173 param.paramName, 174 "readStreamPtrPtr", 175 API_PREFIX_RESERVEDUNMARSHAL, 176 "", 177 direction="read", 178 dynAlloc=True)) 179 cgen.stmt("auto unboxed_%s = unbox_%s(%s)" % 180 (param.paramName, param.typeName, param.paramName)) 181 cgen.stmt("auto vk = dispatch_%s(%s)" % 182 (param.typeName, param.paramName)) 183 cgen.stmt("// End manual dispatchable handle unboxing for %s" % param.paramName) 184 185def emit_transform(typeInfo, param, cgen, variant="tohost"): 186 res = \ 187 iterateVulkanType(typeInfo, param, TransformCodegen( \ 188 cgen, param.paramName, "m_state", "transform_%s_" % variant, variant)) 189 if not res: 190 cgen.stmt("(void)%s" % param.paramName) 191 192def emit_marshal(typeInfo, param, cgen, handleMapOverwrites=False): 193 iterateVulkanType(typeInfo, param, VulkanMarshalingCodegen( 194 cgen, 195 WRITE_STREAM, 196 ROOT_TYPE_DEFAULT_VALUE, 197 param.paramName, 198 API_PREFIX_MARSHAL, 199 direction="write", 200 handleMapOverwrites=handleMapOverwrites)) 201 202class DecodingParameters(object): 203 def __init__(self, api): 204 self.params = [] 205 self.toRead = [] 206 self.toWrite = [] 207 208 i = 0 209 210 for param in api.parameters: 211 param.nonDispatchableHandleCreate = False 212 param.nonDispatchableHandleDestroy = False 213 param.dispatchHandle = False 214 param.dispatchableHandleCreate = False 215 param.dispatchableHandleDestroy = False 216 217 if i == 0 and param.isDispatchableHandleType(): 218 param.dispatchHandle = True 219 220 if param.isNonDispatchableHandleType() and param.isCreatedBy(api): 221 param.nonDispatchableHandleCreate = True 222 223 if param.isNonDispatchableHandleType() and param.isDestroyedBy(api): 224 param.nonDispatchableHandleDestroy = True 225 226 if param.isDispatchableHandleType() and param.isCreatedBy(api): 227 param.dispatchableHandleCreate = True 228 229 if param.isDispatchableHandleType() and param.isDestroyedBy(api): 230 param.dispatchableHandleDestroy = True 231 232 self.toRead.append(param) 233 234 if param.possiblyOutput(): 235 self.toWrite.append(param) 236 237 self.params.append(param) 238 239 i += 1 240 241def emit_call_log(api, cgen): 242 decodingParams = DecodingParameters(api) 243 paramsToRead = decodingParams.toRead 244 245 cgen.beginIf("m_logCalls") 246 paramLogFormat = "" 247 paramLogArgs = [] 248 for p in paramsToRead: 249 paramLogFormat += "0x%llx " 250 for p in paramsToRead: 251 paramLogArgs.append("(unsigned long long)%s" % (p.paramName)) 252 cgen.stmt("fprintf(stderr, \"stream %%p: call %s %s\\n\", ioStream, %s)" % (api.name, paramLogFormat, ", ".join(paramLogArgs))) 253 cgen.endIf() 254 255def emit_decode_parameters(typeInfo, api, cgen, globalWrapped=False): 256 257 decodingParams = DecodingParameters(api) 258 259 paramsToRead = decodingParams.toRead 260 261 for p in paramsToRead: 262 emit_param_decl_for_reading(p, cgen) 263 264 i = 0 265 for p in paramsToRead: 266 lenAccess = cgen.generalLengthAccess(p) 267 268 if p.dispatchHandle: 269 emit_dispatch_unmarshal(typeInfo, p, cgen, globalWrapped) 270 else: 271 destroy = p.nonDispatchableHandleDestroy or p.dispatchableHandleDestroy 272 noUnbox = api.name == "vkQueueFlushCommandsGOOGLE" and p.paramName == "commandBuffer" 273 274 if p.nonDispatchableHandleDestroy or p.dispatchableHandleDestroy: 275 destroy = True 276 cgen.stmt("// Begin manual non dispatchable handle destroy unboxing for %s" % p.paramName) 277 if None == lenAccess or "1" == lenAccess: 278 cgen.stmt("%s boxed_%s_preserve" % (p.typeName, p.paramName)) 279 else: 280 cgen.stmt("%s* boxed_%s_preserve; %s->alloc((void**)&boxed_%s_preserve, %s * sizeof(%s))" % (p.typeName, p.paramName, READ_STREAM, p.paramName, lenAccess, p.typeName)) 281 282 if p.possiblyOutput(): 283 cgen.stmt("// Begin manual dispatchable handle unboxing for %s" % p.paramName) 284 cgen.stmt("%s->unsetHandleMapping()" % READ_STREAM) 285 286 emit_unmarshal(typeInfo, p, cgen, output = p.possiblyOutput(), destroy = destroy, noUnbox = noUnbox) 287 i += 1 288 289 for p in paramsToRead: 290 emit_transform(typeInfo, p, cgen, variant="tohost"); 291 292 emit_call_log(api, cgen) 293 294def emit_dispatch_call(api, cgen): 295 296 decodingParams = DecodingParameters(api) 297 298 customParams = [] 299 300 delay = api.name in DELAYED_DECODER_DELETES 301 302 for (i, p) in enumerate(api.parameters): 303 customParam = p.paramName 304 if decodingParams.params[i].dispatchHandle: 305 customParam = "unboxed_%s" % p.paramName 306 customParams.append(customParam) 307 308 if delay: 309 cgen.line("std::function<void()> delayed_remove_callback = [vk, %s]() {" % ", ".join(customParams)) 310 311 if api.name in driver_workarounds_global_lock_apis: 312 if delay: 313 cgen.stmt("auto state = VkDecoderGlobalState::get()") 314 cgen.stmt("// state already locked") 315 else: 316 cgen.stmt("m_state->lock()") 317 318 cgen.vkApiCall(api, customPrefix="vk->", customParameters=customParams) 319 320 if api.name in driver_workarounds_global_lock_apis: 321 if not delay: 322 cgen.stmt("m_state->unlock()") 323 # for delayed remove, state is already locked, so we do not need to 324 # unlock 325 326 if delay: 327 cgen.line("};") 328 329def emit_global_state_wrapped_call(api, cgen): 330 if api.name in DELAYED_DECODER_DELETES: 331 print("Error: Cannot generate a global state wrapped call that is also a delayed delete (yet)"); 332 raise 333 334 customParams = ["&m_pool"] + list(map(lambda p: p.paramName, api.parameters)) 335 cgen.vkApiCall(api, customPrefix="m_state->on_", \ 336 customParameters=customParams) 337 338def emit_decode_parameters_writeback(typeInfo, api, cgen, autobox=True): 339 decodingParams = DecodingParameters(api) 340 341 paramsToWrite = decodingParams.toWrite 342 343 cgen.stmt("%s->unsetHandleMapping()" % WRITE_STREAM) 344 345 handleMapOverwrites = False 346 347 for p in paramsToWrite: 348 emit_transform(typeInfo, p, cgen, variant="fromhost") 349 350 handleMapOverwrites = False 351 352 if p.nonDispatchableHandleCreate or p.dispatchableHandleCreate: 353 handleMapOverwrites = True 354 355 if autobox and p.nonDispatchableHandleCreate: 356 cgen.stmt("// Begin auto non dispatchable handle create for %s" % p.paramName) 357 cgen.stmt("if (%s == VK_SUCCESS) %s->setHandleMapping(&m_boxedHandleCreateMapping)" % \ 358 (api.getRetVarExpr(), WRITE_STREAM)) 359 360 if (not autobox) and p.nonDispatchableHandleCreate: 361 cgen.stmt("// Begin manual non dispatchable handle create for %s" % p.paramName) 362 cgen.stmt("%s->unsetHandleMapping()" % WRITE_STREAM) 363 364 emit_marshal(typeInfo, p, cgen, handleMapOverwrites=handleMapOverwrites) 365 366 if autobox and p.nonDispatchableHandleCreate: 367 cgen.stmt("// Begin auto non dispatchable handle create for %s" % p.paramName) 368 cgen.stmt("%s->setHandleMapping(&m_boxedHandleUnwrapMapping)" % WRITE_STREAM) 369 370 if (not autobox) and p.nonDispatchableHandleCreate: 371 cgen.stmt("// Begin manual non dispatchable handle create for %s" % p.paramName) 372 cgen.stmt("%s->setHandleMapping(&m_boxedHandleUnwrapMapping)" % WRITE_STREAM) 373 374def emit_decode_return_writeback(api, cgen): 375 retTypeName = api.getRetTypeExpr() 376 if retTypeName != "void": 377 retVar = api.getRetVarExpr() 378 cgen.stmt("%s->write(&%s, %s)" % 379 (WRITE_STREAM, retVar, cgen.sizeofExpr(api.retType))) 380 381def emit_decode_finish(api, cgen): 382 decodingParams = DecodingParameters(api) 383 retTypeName = api.getRetTypeExpr() 384 paramsToWrite = decodingParams.toWrite 385 386 if retTypeName != "void" or len(paramsToWrite) != 0: 387 cgen.stmt("%s->commitWrite()" % WRITE_STREAM) 388 389def emit_destroyed_handle_cleanup(api, cgen): 390 decodingParams = DecodingParameters(api) 391 paramsToRead = decodingParams.toRead 392 393 skipDelete = api.name in SKIPPED_DECODER_DELETES 394 395 if skipDelete: 396 cgen.line("// Skipping handle cleanup for %s" % api.name) 397 return 398 399 for p in paramsToRead: 400 if p.dispatchHandle: 401 pass 402 else: 403 lenAccess = cgen.generalLengthAccess(p) 404 lenAccessGuard = cgen.generalLengthAccess(p) 405 destroy = p.nonDispatchableHandleDestroy or p.dispatchableHandleDestroy 406 if destroy: 407 if None == lenAccess or "1" == lenAccess: 408 if api.name in DELAYED_DECODER_DELETES: 409 cgen.stmt("delayed_delete_%s(boxed_%s_preserve, unboxed_device, delayed_remove_callback)" % (p.typeName, p.paramName)) 410 else: 411 cgen.stmt("delete_%s(boxed_%s_preserve)" % (p.typeName, p.paramName)) 412 else: 413 if lenAccessGuard is not None: 414 cgen.beginIf(lenAccessGuard) 415 cgen.beginFor("uint32_t i = 0", "i < %s" % lenAccess, "++i") 416 if api.name in DELAYED_DECODER_DELETES: 417 cgen.stmt("delayed_delete_%s(boxed_%s_preserve[i], unboxed_device, delayed_remove_callback)" % (p.typeName, p.paramName)) 418 else: 419 cgen.stmt("delete_%s(boxed_%s_preserve[i])" % (p.typeName, p.paramName)) 420 cgen.endFor() 421 if lenAccessGuard is not None: 422 cgen.endIf() 423 424def emit_pool_free(cgen): 425 cgen.stmt("%s->clearPool()" % READ_STREAM) 426 427def emit_seqno_incr(api, cgen): 428 cgen.stmt("if (queueSubmitWithCommandsEnabled) __atomic_fetch_add(seqnoPtr, 1, __ATOMIC_SEQ_CST)") 429 430def emit_snapshot(typeInfo, api, cgen): 431 432 cgen.stmt("%s->setReadPos((uintptr_t)(*readStreamPtrPtr) - (uintptr_t)snapshotTraceBegin)" % READ_STREAM) 433 cgen.stmt("size_t snapshotTraceBytes = %s->endTrace()" % READ_STREAM) 434 435 additionalParams = [ \ 436 makeVulkanTypeSimple(True, "uint8_t", 1, "snapshotTraceBegin"), 437 makeVulkanTypeSimple(False, "size_t", 0, "snapshotTraceBytes"), 438 makeVulkanTypeSimple(False, "android::base::BumpPool", 1, "&m_pool"), 439 ] 440 441 retTypeName = api.getRetTypeExpr() 442 if retTypeName != "void": 443 retVar = api.getRetVarExpr() 444 additionalParams.append(makeVulkanTypeSimple(False, retTypeName, 0, retVar)) 445 446 paramsForSnapshot = [] 447 448 decodingParams = DecodingParameters(api) 449 450 for p in decodingParams.toRead: 451 if p.nonDispatchableHandleDestroy or (not p.dispatchHandle and p.dispatchableHandleDestroy): 452 paramsForSnapshot.append(p.withModifiedName("boxed_%s_preserve" % p.paramName)) 453 else: 454 paramsForSnapshot.append(p) 455 456 customParams = additionalParams + paramsForSnapshot 457 458 apiForSnapshot = \ 459 api.withCustomReturnType(makeVulkanTypeSimple(False, "void", 0, "void")). \ 460 withCustomParameters(customParams) 461 462 cgen.beginIf("m_state->snapshotsEnabled()") 463 cgen.vkApiCall(apiForSnapshot, customPrefix="m_state->snapshot()->") 464 cgen.endIf() 465 466def emit_default_decoding(typeInfo, api, cgen): 467 isAcquire = api.name in RELAXED_APIS 468 emit_decode_parameters(typeInfo, api, cgen) 469 470 if isAcquire: 471 emit_seqno_incr(api, cgen) 472 473 emit_dispatch_call(api, cgen) 474 emit_decode_parameters_writeback(typeInfo, api, cgen) 475 emit_decode_return_writeback(api, cgen) 476 emit_decode_finish(api, cgen) 477 emit_snapshot(typeInfo, api, cgen) 478 emit_destroyed_handle_cleanup(api, cgen) 479 emit_pool_free(cgen) 480 481 if not isAcquire: 482 emit_seqno_incr(api, cgen) 483 484def emit_global_state_wrapped_decoding(typeInfo, api, cgen): 485 isAcquire = api.name in RELAXED_APIS 486 487 emit_decode_parameters(typeInfo, api, cgen, globalWrapped=True) 488 489 if isAcquire: 490 emit_seqno_incr(api, cgen) 491 492 emit_global_state_wrapped_call(api, cgen) 493 emit_decode_parameters_writeback(typeInfo, api, cgen, autobox=False) 494 emit_decode_return_writeback(api, cgen) 495 emit_decode_finish(api, cgen) 496 emit_snapshot(typeInfo, api, cgen) 497 emit_destroyed_handle_cleanup(api, cgen) 498 emit_pool_free(cgen) 499 if not isAcquire: 500 emit_seqno_incr(api, cgen) 501 502## Custom decoding definitions################################################## 503def decode_vkFlushMappedMemoryRanges(typeInfo, api, cgen): 504 emit_decode_parameters(typeInfo, api, cgen) 505 506 cgen.beginIf("!m_state->usingDirectMapping()") 507 cgen.beginFor("uint32_t i = 0", "i < memoryRangeCount", "++i") 508 cgen.stmt("auto range = pMemoryRanges[i]") 509 cgen.stmt("auto memory = pMemoryRanges[i].memory") 510 cgen.stmt("auto size = pMemoryRanges[i].size") 511 cgen.stmt("auto offset = pMemoryRanges[i].offset") 512 cgen.stmt("uint64_t readStream = 0") 513 cgen.stmt("memcpy(&readStream, *readStreamPtrPtr, sizeof(uint64_t)); *readStreamPtrPtr += sizeof(uint64_t)") 514 cgen.stmt("auto hostPtr = m_state->getMappedHostPointer(memory)") 515 cgen.stmt("if (!hostPtr && readStream > 0) abort()") 516 cgen.stmt("if (!hostPtr) continue") 517 cgen.stmt("uint8_t* targetRange = hostPtr + offset") 518 cgen.stmt("memcpy(targetRange, *readStreamPtrPtr, readStream); *readStreamPtrPtr += readStream") 519 cgen.endFor() 520 cgen.endIf() 521 522 emit_dispatch_call(api, cgen) 523 emit_decode_parameters_writeback(typeInfo, api, cgen) 524 emit_decode_return_writeback(api, cgen) 525 emit_decode_finish(api, cgen) 526 emit_snapshot(typeInfo, api, cgen); 527 emit_pool_free(cgen) 528 emit_seqno_incr(api, cgen) 529 530def decode_vkInvalidateMappedMemoryRanges(typeInfo, api, cgen): 531 emit_decode_parameters(typeInfo, api, cgen) 532 emit_dispatch_call(api, cgen) 533 emit_decode_parameters_writeback(typeInfo, api, cgen) 534 emit_decode_return_writeback(api, cgen) 535 536 cgen.beginIf("!m_state->usingDirectMapping()") 537 cgen.beginFor("uint32_t i = 0", "i < memoryRangeCount", "++i") 538 cgen.stmt("auto range = pMemoryRanges[i]") 539 cgen.stmt("auto memory = range.memory") 540 cgen.stmt("auto size = range.size") 541 cgen.stmt("auto offset = range.offset") 542 cgen.stmt("auto hostPtr = m_state->getMappedHostPointer(memory)") 543 cgen.stmt("auto actualSize = size == VK_WHOLE_SIZE ? m_state->getDeviceMemorySize(memory) : size") 544 cgen.stmt("uint64_t writeStream = 0") 545 cgen.stmt("if (!hostPtr) { %s->write(&writeStream, sizeof(uint64_t)); continue; }" % WRITE_STREAM) 546 cgen.stmt("uint8_t* targetRange = hostPtr + offset") 547 cgen.stmt("writeStream = actualSize") 548 cgen.stmt("%s->write(&writeStream, sizeof(uint64_t))" % WRITE_STREAM) 549 cgen.stmt("%s->write(targetRange, actualSize)" % WRITE_STREAM) 550 cgen.endFor() 551 cgen.endIf() 552 553 emit_decode_finish(api, cgen) 554 emit_snapshot(typeInfo, api, cgen); 555 emit_pool_free(cgen) 556 emit_seqno_incr(api, cgen) 557 558custom_decodes = { 559 "vkEnumerateInstanceVersion" : emit_global_state_wrapped_decoding, 560 "vkCreateInstance" : emit_global_state_wrapped_decoding, 561 "vkDestroyInstance" : emit_global_state_wrapped_decoding, 562 "vkEnumeratePhysicalDevices" : emit_global_state_wrapped_decoding, 563 564 "vkGetPhysicalDeviceFeatures" : emit_global_state_wrapped_decoding, 565 "vkGetPhysicalDeviceFeatures2" : emit_global_state_wrapped_decoding, 566 "vkGetPhysicalDeviceFeatures2KHR" : emit_global_state_wrapped_decoding, 567 "vkGetPhysicalDeviceFormatProperties" : emit_global_state_wrapped_decoding, 568 "vkGetPhysicalDeviceFormatProperties2" : emit_global_state_wrapped_decoding, 569 "vkGetPhysicalDeviceFormatProperties2KHR" : emit_global_state_wrapped_decoding, 570 "vkGetPhysicalDeviceImageFormatProperties" : emit_global_state_wrapped_decoding, 571 "vkGetPhysicalDeviceImageFormatProperties2" : emit_global_state_wrapped_decoding, 572 "vkGetPhysicalDeviceImageFormatProperties2KHR" : emit_global_state_wrapped_decoding, 573 "vkGetPhysicalDeviceProperties" : emit_global_state_wrapped_decoding, 574 "vkGetPhysicalDeviceProperties2" : emit_global_state_wrapped_decoding, 575 "vkGetPhysicalDeviceProperties2KHR" : emit_global_state_wrapped_decoding, 576 577 "vkGetPhysicalDeviceMemoryProperties" : emit_global_state_wrapped_decoding, 578 "vkGetPhysicalDeviceMemoryProperties2" : emit_global_state_wrapped_decoding, 579 "vkGetPhysicalDeviceMemoryProperties2KHR" : emit_global_state_wrapped_decoding, 580 581 "vkGetPhysicalDeviceExternalSemaphoreProperties" : emit_global_state_wrapped_decoding, 582 "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR" : emit_global_state_wrapped_decoding, 583 584 "vkEnumerateDeviceExtensionProperties" : emit_global_state_wrapped_decoding, 585 586 "vkCreateBuffer" : emit_global_state_wrapped_decoding, 587 "vkDestroyBuffer" : emit_global_state_wrapped_decoding, 588 589 "vkBindBufferMemory" : emit_global_state_wrapped_decoding, 590 "vkBindBufferMemory2" : emit_global_state_wrapped_decoding, 591 "vkBindBufferMemory2KHR" : emit_global_state_wrapped_decoding, 592 593 "vkCreateDevice" : emit_global_state_wrapped_decoding, 594 "vkGetDeviceQueue" : emit_global_state_wrapped_decoding, 595 "vkDestroyDevice" : emit_global_state_wrapped_decoding, 596 597 "vkBindImageMemory" : emit_global_state_wrapped_decoding, 598 "vkCreateImage" : emit_global_state_wrapped_decoding, 599 "vkCreateImageView" : emit_global_state_wrapped_decoding, 600 "vkCreateSampler" : emit_global_state_wrapped_decoding, 601 "vkDestroyImage" : emit_global_state_wrapped_decoding, 602 "vkDestroyImageView" : emit_global_state_wrapped_decoding, 603 "vkDestroySampler" : emit_global_state_wrapped_decoding, 604 "vkCmdCopyBufferToImage" : emit_global_state_wrapped_decoding, 605 "vkCmdCopyImage" : emit_global_state_wrapped_decoding, 606 "vkCmdCopyImageToBuffer" : emit_global_state_wrapped_decoding, 607 "vkGetImageMemoryRequirements" : emit_global_state_wrapped_decoding, 608 "vkGetImageMemoryRequirements2" : emit_global_state_wrapped_decoding, 609 "vkGetImageMemoryRequirements2KHR" : emit_global_state_wrapped_decoding, 610 611 "vkCreateDescriptorSetLayout" : emit_global_state_wrapped_decoding, 612 "vkDestroyDescriptorSetLayout" : emit_global_state_wrapped_decoding, 613 "vkCreateDescriptorPool" : emit_global_state_wrapped_decoding, 614 "vkDestroyDescriptorPool" : emit_global_state_wrapped_decoding, 615 "vkResetDescriptorPool" : emit_global_state_wrapped_decoding, 616 "vkAllocateDescriptorSets" : emit_global_state_wrapped_decoding, 617 "vkFreeDescriptorSets" : emit_global_state_wrapped_decoding, 618 619 "vkUpdateDescriptorSets" : emit_global_state_wrapped_decoding, 620 621 "vkAllocateMemory" : emit_global_state_wrapped_decoding, 622 "vkFreeMemory" : emit_global_state_wrapped_decoding, 623 "vkMapMemory" : emit_global_state_wrapped_decoding, 624 "vkUnmapMemory" : emit_global_state_wrapped_decoding, 625 "vkFlushMappedMemoryRanges" : decode_vkFlushMappedMemoryRanges, 626 "vkInvalidateMappedMemoryRanges" : decode_vkInvalidateMappedMemoryRanges, 627 628 "vkAllocateCommandBuffers" : emit_global_state_wrapped_decoding, 629 "vkCmdExecuteCommands" : emit_global_state_wrapped_decoding, 630 "vkQueueSubmit" : emit_global_state_wrapped_decoding, 631 "vkQueueWaitIdle" : emit_global_state_wrapped_decoding, 632 "vkBeginCommandBuffer" : emit_global_state_wrapped_decoding, 633 "vkResetCommandBuffer" : emit_global_state_wrapped_decoding, 634 "vkFreeCommandBuffers" : emit_global_state_wrapped_decoding, 635 "vkCreateCommandPool" : emit_global_state_wrapped_decoding, 636 "vkDestroyCommandPool" : emit_global_state_wrapped_decoding, 637 "vkResetCommandPool" : emit_global_state_wrapped_decoding, 638 "vkCmdPipelineBarrier" : emit_global_state_wrapped_decoding, 639 "vkCmdBindPipeline" : emit_global_state_wrapped_decoding, 640 "vkCmdBindDescriptorSets" : emit_global_state_wrapped_decoding, 641 642 "vkCreateRenderPass" : emit_global_state_wrapped_decoding, 643 644 # VK_ANDROID_native_buffer 645 "vkGetSwapchainGrallocUsageANDROID" : emit_global_state_wrapped_decoding, 646 "vkGetSwapchainGrallocUsage2ANDROID" : emit_global_state_wrapped_decoding, 647 "vkAcquireImageANDROID" : emit_global_state_wrapped_decoding, 648 "vkQueueSignalReleaseImageANDROID" : emit_global_state_wrapped_decoding, 649 650 "vkCreateSemaphore" : emit_global_state_wrapped_decoding, 651 "vkGetSemaphoreFdKHR" : emit_global_state_wrapped_decoding, 652 "vkImportSemaphoreFdKHR" : emit_global_state_wrapped_decoding, 653 "vkDestroySemaphore" : emit_global_state_wrapped_decoding, 654 655 "vkCreateFence" : emit_global_state_wrapped_decoding, 656 "vkDestroyFence" : emit_global_state_wrapped_decoding, 657 658 # VK_GOOGLE_gfxstream 659 "vkFreeMemorySyncGOOGLE" : emit_global_state_wrapped_decoding, 660 "vkMapMemoryIntoAddressSpaceGOOGLE" : emit_global_state_wrapped_decoding, 661 "vkGetMemoryHostAddressInfoGOOGLE" : emit_global_state_wrapped_decoding, 662 663 # VK_GOOGLE_color_buffer 664 "vkRegisterImageColorBufferGOOGLE" : emit_global_state_wrapped_decoding, 665 "vkRegisterBufferColorBufferGOOGLE" : emit_global_state_wrapped_decoding, 666 667 # Descriptor update templates 668 "vkCreateDescriptorUpdateTemplate" : emit_global_state_wrapped_decoding, 669 "vkCreateDescriptorUpdateTemplateKHR" : emit_global_state_wrapped_decoding, 670 "vkDestroyDescriptorUpdateTemplate" : emit_global_state_wrapped_decoding, 671 "vkDestroyDescriptorUpdateTemplateKHR" : emit_global_state_wrapped_decoding, 672 "vkUpdateDescriptorSetWithTemplateSizedGOOGLE" : emit_global_state_wrapped_decoding, 673 674 # VK_GOOGLE_gfxstream 675 "vkBeginCommandBufferAsyncGOOGLE" : emit_global_state_wrapped_decoding, 676 "vkEndCommandBufferAsyncGOOGLE" : emit_global_state_wrapped_decoding, 677 "vkResetCommandBufferAsyncGOOGLE" : emit_global_state_wrapped_decoding, 678 "vkCommandBufferHostSyncGOOGLE" : emit_global_state_wrapped_decoding, 679 "vkCreateImageWithRequirementsGOOGLE" : emit_global_state_wrapped_decoding, 680 "vkCreateBufferWithRequirementsGOOGLE" : emit_global_state_wrapped_decoding, 681 "vkQueueHostSyncGOOGLE" : emit_global_state_wrapped_decoding, 682 "vkQueueSubmitAsyncGOOGLE" : emit_global_state_wrapped_decoding, 683 "vkQueueWaitIdleAsyncGOOGLE" : emit_global_state_wrapped_decoding, 684 "vkQueueBindSparseAsyncGOOGLE" : emit_global_state_wrapped_decoding, 685 "vkGetLinearImageLayoutGOOGLE" : emit_global_state_wrapped_decoding, 686 "vkQueueFlushCommandsGOOGLE" : emit_global_state_wrapped_decoding, 687 "vkQueueCommitDescriptorSetUpdatesGOOGLE" : emit_global_state_wrapped_decoding, 688 "vkCollectDescriptorPoolIdsGOOGLE" : emit_global_state_wrapped_decoding, 689} 690 691class VulkanDecoder(VulkanWrapperGenerator): 692 def __init__(self, module, typeInfo): 693 VulkanWrapperGenerator.__init__(self, module, typeInfo) 694 self.typeInfo = typeInfo 695 self.cgen = CodeGen() 696 697 def onBegin(self,): 698 self.module.appendHeader(decoder_decl_preamble) 699 self.module.appendImpl(decoder_impl_preamble) 700 701 self.module.appendImpl( 702 "size_t VkDecoder::Impl::decode(void* buf, size_t len, IOStream* ioStream, uint32_t* seqnoPtr)\n") 703 704 self.cgen.beginBlock() # function body 705 706 self.cgen.stmt("if (len < 8) return 0;") 707 self.cgen.stmt("bool queueSubmitWithCommandsEnabled = feature_is_enabled(kFeature_VulkanQueueSubmitWithCommands)") 708 self.cgen.stmt("unsigned char *ptr = (unsigned char *)buf") 709 self.cgen.stmt("const unsigned char* const end = (const unsigned char*)buf + len") 710 711 self.cgen.beginIf("m_forSnapshotLoad") 712 self.cgen.stmt("ptr += m_state->setCreatedHandlesForSnapshotLoad(ptr)"); 713 self.cgen.endIf() 714 715 self.cgen.line("while (end - ptr >= 8)") 716 self.cgen.beginBlock() # while loop 717 718 self.cgen.stmt("uint32_t opcode = *(uint32_t *)ptr") 719 self.cgen.stmt("int32_t packetLen = *(int32_t *)(ptr + 4)") 720 self.cgen.stmt("if (end - ptr < packetLen) return ptr - (unsigned char*)buf") 721 722 self.cgen.stmt("stream()->setStream(ioStream)") 723 self.cgen.stmt("VulkanStream* %s = stream()" % WRITE_STREAM) 724 self.cgen.stmt("VulkanMemReadingStream* %s = readStream()" % READ_STREAM) 725 self.cgen.stmt("%s->setBuf((uint8_t*)(ptr + 8))" % READ_STREAM) 726 self.cgen.stmt("uint8_t* readStreamPtr = %s->getBuf(); uint8_t** readStreamPtrPtr = &readStreamPtr" % READ_STREAM) 727 self.cgen.stmt("uint8_t* snapshotTraceBegin = %s->beginTrace()" % READ_STREAM) 728 self.cgen.stmt("%s->setHandleMapping(&m_boxedHandleUnwrapMapping)" % READ_STREAM) 729 self.cgen.line(""" 730 if (queueSubmitWithCommandsEnabled && ((opcode >= OP_vkFirst && opcode < OP_vkLast) || (opcode >= OP_vkFirst_old && opcode < OP_vkLast_old))) { 731 uint32_t seqno; memcpy(&seqno, *readStreamPtrPtr, sizeof(uint32_t)); *readStreamPtrPtr += sizeof(uint32_t); 732 if (seqnoPtr && !m_forSnapshotLoad) { 733 while ((seqno - __atomic_load_n(seqnoPtr, __ATOMIC_SEQ_CST) != 1)); 734 } 735 } 736 """) 737 self.cgen.stmt("auto vk = m_vk") 738 739 self.cgen.line("switch (opcode)") 740 self.cgen.beginBlock() # switch stmt 741 742 self.module.appendImpl(self.cgen.swapCode()) 743 744 def onGenCmd(self, cmdinfo, name, alias): 745 typeInfo = self.typeInfo 746 cgen = self.cgen 747 api = typeInfo.apis[name] 748 749 cgen.line("case OP_%s:" % name) 750 cgen.beginBlock() 751 cgen.stmt("android::base::beginTrace(\"%s decode\")" % name) 752 753 if api.name in custom_decodes.keys(): 754 custom_decodes[api.name](typeInfo, api, cgen) 755 else: 756 emit_default_decoding(typeInfo, api, cgen) 757 758 cgen.stmt("android::base::endTrace()") 759 cgen.stmt("break") 760 cgen.endBlock() 761 self.module.appendImpl(self.cgen.swapCode()) 762 763 def onEnd(self,): 764 self.cgen.line("default:") 765 self.cgen.beginBlock() 766 self.cgen.stmt("m_pool.freeAll()") 767 self.cgen.stmt("return ptr - (unsigned char *)buf") 768 self.cgen.endBlock() 769 770 self.cgen.endBlock() # switch stmt 771 772 self.cgen.stmt("ptr += packetLen") 773 self.cgen.endBlock() # while loop 774 775 self.cgen.beginIf("m_forSnapshotLoad") 776 self.cgen.stmt("m_state->clearCreatedHandlesForSnapshotLoad()"); 777 self.cgen.endIf() 778 779 self.cgen.stmt("m_pool.freeAll()") 780 self.cgen.stmt("return ptr - (unsigned char*)buf;") 781 self.cgen.endBlock() # function body 782 self.module.appendImpl(self.cgen.swapCode()) 783