mesa/src/gfxstream/codegen/scripts/cereal/encoder.py
Gurchetan Singh 2f161c31e3 gfxstream: guest: nuke Android HealthMonitor
The HealthMonitor is hang detection at the API Vulkan
encoder level.

It's actually not used in CF/AAOS/Emualtor.  The
plan for AOSP is actually to increase the amount
of Android CTS that are run against gfxstream to
increase health/stability, for example (b/347288539).

So if we consistently pass CTS on main with gfxstream
(as is the plan), HealthMonitoring would be somewhat
redundant.

Also, AndroidHealthMonitor is somewhat duplicated with
libaemu's HealthMonitor as well.

Also, nuke EncoderAutoLock while we're at it.  It also
is unused code.

Reviewed-by: Aaron Ruby <aruby@blackberry.com>
Acked-by: Yonggang Luo <luoyonggang@gmail.com>
Acked-by: Adam Jackson <ajax@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27246>
2024-09-19 20:06:02 +00:00

686 lines
24 KiB
Python

import copy
from .common.codegen import CodeGen, VulkanWrapperGenerator
from .common.vulkantypes import \
VulkanAPI, makeVulkanTypeSimple, iterateVulkanType
from .marshaling import VulkanMarshalingCodegen
from .reservedmarshaling import VulkanReservedMarshalingCodegen
from .counting import VulkanCountingCodegen
from .handlemap import HandleMapCodegen
from .deepcopy import DeepcopyCodegen
from .transform import TransformCodegen, genTransformsForVulkanType
from .wrapperdefs import API_PREFIX_RESERVEDMARSHAL
from .wrapperdefs import API_PREFIX_MARSHAL
from .wrapperdefs import API_PREFIX_UNMARSHAL
from .wrapperdefs import ROOT_TYPE_DEFAULT_VALUE
from .wrapperdefs import VULKAN_STREAM_TYPE_GUEST
encoder_decl_preamble = """
class VkEncoder {
public:
VkEncoder(gfxstream::guest::IOStream* stream);
~VkEncoder();
#include "VkEncoder.h.inl"
"""
encoder_decl_postamble = """
private:
class Impl;
std::unique_ptr<Impl> mImpl;
};
"""
encoder_impl_preamble ="""
using namespace gfxstream::vk;
using gfxstream::guest::BumpPool;
#include "VkEncoder.cpp.inl"
#define VALIDATE_RET(retType, success, validate) \\
retType goldfish_vk_validateResult = validate; \\
if (goldfish_vk_validateResult != success) return goldfish_vk_validateResult; \\
#define VALIDATE_VOID(validate) \\
VkResult goldfish_vk_validateResult = validate; \\
if (goldfish_vk_validateResult != VK_SUCCESS) return; \\
"""
STREAM = "stream"
RESOURCES = "sResourceTracker"
POOL = "pool"
ENCODER_PREVALIDATED_APIS = [
"vkFlushMappedMemoryRanges",
"vkInvalidateMappedMemoryRanges",
]
ENCODER_CUSTOM_RESOURCE_PREPROCESS = [
"vkMapMemoryIntoAddressSpaceGOOGLE",
"vkDestroyDevice",
]
ENCODER_CUSTOM_RESOURCE_POSTPROCESS = [
"vkCreateInstance",
"vkCreateDevice",
"vkMapMemoryIntoAddressSpaceGOOGLE",
"vkGetPhysicalDeviceFeatures2",
"vkGetPhysicalDeviceFeatures2KHR",
"vkGetPhysicalDeviceProperties",
"vkGetPhysicalDeviceProperties2",
"vkGetPhysicalDeviceProperties2KHR",
"vkCreateDescriptorUpdateTemplate",
"vkCreateDescriptorUpdateTemplateKHR",
"vkGetPhysicalDeviceExternalSemaphoreProperties",
"vkGetPhysicalDeviceExternalSemaphorePropertiesKHR",
"vkGetDeviceQueue",
"vkGetDeviceQueue2",
]
ENCODER_EXPLICIT_FLUSHED_APIS = [
"vkEndCommandBufferAsyncGOOGLE",
"vkQueueSubmitAsyncGOOGLE",
"vkQueueBindSparseAsyncGOOGLE",
"vkQueueWaitIdleAsyncGOOGLE",
"vkQueueSignalReleaseImageANDROID",
"vkDestroyDevice",
]
SUCCESS_RET_TYPES = {
"VkResult" : "VK_SUCCESS",
"void" : None,
# TODO: Put up success results for other return types here.
}
ENCODER_THIS_PARAM = makeVulkanTypeSimple(False, "VkEncoder", 1, "this")
# Common components of encoding a Vulkan API call
def make_event_handler_call(
handler_access,
api,
context_param,
input_result_param,
cgen,
suffix=""):
extraParams = [context_param.paramName]
if input_result_param:
extraParams.append(input_result_param)
return cgen.makeCallExpr( \
"%s->on_%s%s" % (handler_access, api.name, suffix),
extraParams + \
[p.paramName for p in api.parameters[:-1]])
def emit_custom_pre_validate(typeInfo, api, cgen):
if api.name in ENCODER_PREVALIDATED_APIS:
callExpr = \
make_event_handler_call( \
"mImpl->validation()", api,
ENCODER_THIS_PARAM,
SUCCESS_RET_TYPES[api.getRetTypeExpr()],
cgen)
if api.getRetTypeExpr() == "void":
cgen.stmt("VALIDATE_VOID(%s)" % callExpr)
else:
cgen.stmt("VALIDATE_RET(%s, %s, %s)" % \
(api.getRetTypeExpr(),
SUCCESS_RET_TYPES[api.getRetTypeExpr()],
callExpr))
def emit_custom_resource_preprocess(typeInfo, api, cgen):
if api.name in ENCODER_CUSTOM_RESOURCE_PREPROCESS:
cgen.stmt( \
make_event_handler_call( \
"sResourceTracker", api,
ENCODER_THIS_PARAM,
SUCCESS_RET_TYPES[api.getRetTypeExpr()],
cgen, suffix="_pre"))
def emit_custom_resource_postprocess(typeInfo, api, cgen):
if api.name in ENCODER_CUSTOM_RESOURCE_POSTPROCESS:
cgen.stmt(make_event_handler_call( \
"sResourceTracker",
api,
ENCODER_THIS_PARAM,
api.getRetVarExpr(),
cgen))
def emit_count_marshal(typeInfo, param, cgen):
res = \
iterateVulkanType(
typeInfo, param,
VulkanCountingCodegen( \
cgen, "sFeatureBits", param.paramName, "countPtr", ROOT_TYPE_DEFAULT_VALUE,
"count_"))
if not res:
cgen.stmt("(void)%s" % param.paramName)
def emit_marshal(typeInfo, param, cgen):
forOutput = param.isHandleType() and ("out" in param.inout)
if forOutput:
cgen.stmt("/* is handle, possibly out */")
res = \
iterateVulkanType(
typeInfo, param,
VulkanReservedMarshalingCodegen( \
cgen, "guest", STREAM, ROOT_TYPE_DEFAULT_VALUE, param.paramName, "streamPtrPtr",
API_PREFIX_RESERVEDMARSHAL,
"" if forOutput else "get_host_u64_",
direction="write"))
if not res:
cgen.stmt("(void)%s" % param.paramName)
if forOutput:
cgen.stmt("/* is handle, possibly out */")
def emit_unmarshal(typeInfo, param, cgen):
iterateVulkanType(
typeInfo, param,
VulkanMarshalingCodegen( \
cgen, STREAM, ROOT_TYPE_DEFAULT_VALUE, param.paramName,
API_PREFIX_UNMARSHAL, direction="read"))
def emit_deepcopy(typeInfo, param, cgen):
res = \
iterateVulkanType(typeInfo, param, DeepcopyCodegen(
cgen, [param.paramName, "local_" + param.paramName], "pool", ROOT_TYPE_DEFAULT_VALUE, "deepcopy_"))
if not res:
cgen.stmt("(void)%s" % param.paramName)
def emit_transform(typeInfo, param, cgen, variant="tohost"):
res = \
iterateVulkanType(typeInfo, param, TransformCodegen( \
cgen, param.paramName, "sResourceTracker", "transform_%s_" % variant, variant))
if not res:
cgen.stmt("(void)%s" % param.paramName)
def emit_handlemap_create(typeInfo, param, cgen):
iterateVulkanType(typeInfo, param, HandleMapCodegen(
cgen, None, "sResourceTracker", "handlemap_",
lambda vtype: typeInfo.isHandleType(vtype.typeName)
))
def custom_encoder_args(api):
params = ["this"]
if api.getRetVarExpr() is not None:
params.append(api.getRetVarExpr())
return params
def emit_handlemap_destroy(typeInfo, param, cgen):
iterateVulkanType(typeInfo, param, HandleMapCodegen(
cgen, None, "sResourceTracker->destroyMapping()", "handlemap_",
lambda vtype: typeInfo.isHandleType(vtype.typeName)
))
class EncodingParameters(object):
def __init__(self, api):
self.localCopied = []
self.toWrite = []
self.toRead = []
self.toCreate = []
self.toDestroy = []
for param in api.parameters:
param.action = None
param.inout = "in"
if param.paramName == "doLock":
continue
if param.possiblyOutput():
param.inout += "out"
self.toWrite.append(param)
self.toRead.append(param)
if param.isCreatedBy(api):
self.toCreate.append(param)
param.action = "create"
else:
if param.paramName == "doLock":
continue
if param.isDestroyedBy(api):
self.toDestroy.append(param)
param.action = "destroy"
localCopyParam = \
param.getForNonConstAccess().withModifiedName( \
"local_" + param.paramName)
self.localCopied.append((param, localCopyParam))
self.toWrite.append(localCopyParam)
def emit_parameter_encode_preamble_write(typeInfo, api, cgen):
emit_custom_pre_validate(typeInfo, api, cgen);
emit_custom_resource_preprocess(typeInfo, api, cgen);
cgen.stmt("auto %s = mImpl->stream()" % STREAM)
cgen.stmt("auto %s = mImpl->pool()" % POOL)
# cgen.stmt("%s->setHandleMapping(%s->unwrapMapping())" % (STREAM, RESOURCES))
encodingParams = EncodingParameters(api)
for (_, localCopyParam) in encodingParams.localCopied:
cgen.stmt(cgen.makeRichCTypeDecl(localCopyParam))
def emit_parameter_encode_copy_unwrap_count(typeInfo, api, cgen, customUnwrap=None):
encodingParams = EncodingParameters(api)
for (origParam, localCopyParam) in encodingParams.localCopied:
shouldCustomCopy = \
customUnwrap and \
origParam.paramName in customUnwrap and \
"copyOp" in customUnwrap[origParam.paramName]
shouldCustomMap = \
customUnwrap and \
origParam.paramName in customUnwrap and \
"mapOp" in customUnwrap[origParam.paramName]
if shouldCustomCopy:
customUnwrap[origParam.paramName]["copyOp"](cgen, origParam, localCopyParam)
else:
# if this is a pointer type and we don't do custom copy nor unwrap,
# and the transform doesn't end up doing anything,
# don't deepcopy, just cast it.
avoidDeepcopy = False
if origParam.pointerIndirectionLevels > 0:
testCgen = CodeGen()
genTransformsForVulkanType("sResourceTracker", origParam, lambda p: testCgen.generalAccess(p, parentVarName = None, asPtr = True), lambda p: testCgen.generalLengthAccess(p, parentVarName = None), testCgen)
emit_transform(typeInfo, origParam, testCgen, variant="tohost")
if "" == testCgen.swapCode():
avoidDeepcopy = True
if avoidDeepcopy:
cgen.line("// Avoiding deepcopy for %s" % origParam.paramName)
cgen.stmt("%s = (%s%s)%s" % (localCopyParam.paramName, localCopyParam.typeName, "*" * origParam.pointerIndirectionLevels, origParam.paramName))
else:
emit_deepcopy(typeInfo, origParam, cgen)
for (origParam, localCopyParam) in encodingParams.localCopied:
shouldCustomMap = \
customUnwrap and \
origParam.paramName in customUnwrap and \
"mapOp" in customUnwrap[origParam.paramName]
if shouldCustomMap:
customUnwrap[origParam.paramName]["mapOp"](cgen, origParam, localCopyParam)
else:
if localCopyParam.typeName == "VkAllocationCallbacks":
cgen.stmt("%s = nullptr" % localCopyParam.paramName)
apiForTransform = \
api.withCustomParameters( \
map(lambda p: p[1], \
encodingParams.localCopied))
# Apply transforms if applicable.
# Apply transform to API itself:
genTransformsForVulkanType(
"sResourceTracker",
apiForTransform,
lambda p: cgen.generalAccess(p, parentVarName = None, asPtr = True),
lambda p: cgen.generalLengthAccess(p, parentVarName = None),
cgen)
# For all local copied parameters, run the transforms
for localParam in apiForTransform.parameters:
if "doLock" in localParam.paramName:
continue
emit_transform(typeInfo, localParam, cgen, variant="tohost")
cgen.stmt("size_t count = 0")
cgen.stmt("size_t* countPtr = &count")
cgen.beginBlock()
# Use counting stream to calculate the packet size.
for p in encodingParams.toWrite:
emit_count_marshal(typeInfo, p, cgen)
cgen.endBlock()
def is_cmdbuf_dispatch(api):
return "VkCommandBuffer" == api.parameters[0].typeName
def emit_parameter_encode_write_packet_info(typeInfo, api, cgen):
# Seqno and skipping dispatch serialize are for use with VULKAN_STREAM_FEATURE_QUEUE_SUBMIT_WITH_COMMANDS_BIT
doSeqno = True
doDispatchSerialize = True
if is_cmdbuf_dispatch(api):
doSeqno = False
doDispatchSerialize = False
if doSeqno:
cgen.stmt("uint32_t packetSize_%s = 4 + 4 + (queueSubmitWithCommandsEnabled ? 4 : 0) + count" % (api.name))
else:
cgen.stmt("uint32_t packetSize_%s = 4 + 4 + count" % (api.name))
if not doDispatchSerialize:
cgen.stmt("if (queueSubmitWithCommandsEnabled) packetSize_%s -= 8" % api.name)
cgen.stmt("uint8_t* streamPtr = %s->reserve(packetSize_%s)" % (STREAM, api.name))
cgen.stmt("uint8_t* packetBeginPtr = streamPtr")
cgen.stmt("uint8_t** streamPtrPtr = &streamPtr")
cgen.stmt("uint32_t opcode_%s = OP_%s" % (api.name, api.name))
if doSeqno:
cgen.stmt("uint32_t seqno; if (queueSubmitWithCommandsEnabled) seqno = ResourceTracker::nextSeqno()")
cgen.stmt("memcpy(streamPtr, &opcode_%s, sizeof(uint32_t)); streamPtr += sizeof(uint32_t)" % api.name)
cgen.stmt("memcpy(streamPtr, &packetSize_%s, sizeof(uint32_t)); streamPtr += sizeof(uint32_t)" % api.name)
if doSeqno:
cgen.line("if (queueSubmitWithCommandsEnabled) { memcpy(streamPtr, &seqno, sizeof(uint32_t)); streamPtr += sizeof(uint32_t); }")
def emit_parameter_encode_do_parameter_write(typeInfo, api, cgen):
encodingParams = EncodingParameters(api)
dispatchDone = False
for p in encodingParams.toWrite:
if is_cmdbuf_dispatch(api) and not dispatchDone:
cgen.beginIf("!queueSubmitWithCommandsEnabled")
emit_marshal(typeInfo, p, cgen)
cgen.endIf()
else:
emit_marshal(typeInfo, p, cgen)
dispatchDone = True
def emit_parameter_encode_read(typeInfo, api, cgen):
encodingParams = EncodingParameters(api)
for p in encodingParams.toRead:
if p.action == "create":
cgen.stmt(
"%s->setHandleMapping(%s->createMapping())" % \
(STREAM, RESOURCES))
emit_unmarshal(typeInfo, p, cgen)
if p.action == "create":
cgen.stmt(
"%s->unsetHandleMapping()" % STREAM)
emit_transform(typeInfo, p, cgen, variant="fromhost")
def emit_post(typeInfo, api, cgen):
encodingParams = EncodingParameters(api)
emit_custom_resource_postprocess(typeInfo, api, cgen)
for p in encodingParams.toDestroy:
emit_handlemap_destroy(typeInfo, p, cgen)
doSeqno = True
if is_cmdbuf_dispatch(api):
doSeqno = False
retType = api.getRetTypeExpr()
if api.name in ENCODER_EXPLICIT_FLUSHED_APIS:
cgen.stmt("stream->flush()");
return
if doSeqno:
if retType == "void":
encodingParams = EncodingParameters(api)
if 0 == len(encodingParams.toRead):
cgen.stmt("stream->flush()");
def emit_pool_free(cgen):
cgen.stmt("++encodeCount")
cgen.beginIf("0 == encodeCount % POOL_CLEAR_INTERVAL")
cgen.stmt("pool->freeAll()")
cgen.stmt("%s->clearPool()" % STREAM)
cgen.endIf()
def emit_return_unmarshal(typeInfo, api, cgen):
retType = api.getRetTypeExpr()
if retType == "void":
return
retVar = api.getRetVarExpr()
cgen.stmt("%s %s = (%s)0" % (retType, retVar, retType))
cgen.stmt("%s->read(&%s, %s)" % \
(STREAM, retVar, cgen.sizeofExpr(api.retType)))
def emit_return(typeInfo, api, cgen):
if api.getRetTypeExpr() == "void":
return
retVar = api.getRetVarExpr()
cgen.stmt("return %s" % retVar)
def emit_lock(cgen):
cgen.stmt("(void)doLock");
cgen.stmt("bool queueSubmitWithCommandsEnabled = sFeatureBits & VULKAN_STREAM_FEATURE_QUEUE_SUBMIT_WITH_COMMANDS_BIT")
cgen.stmt("if (!queueSubmitWithCommandsEnabled && doLock) this->lock()")
def emit_unlock(cgen):
cgen.stmt("if (!queueSubmitWithCommandsEnabled && doLock) this->unlock()")
def emit_debug_log(typeInfo, api, cgen):
logFormat = []
logVargs = []
for param in api.parameters:
if param.paramName == "doLock":
continue
paramFormatSpecifier = param.getPrintFormatSpecifier()
if not paramFormatSpecifier:
continue
logFormat.append(param.paramName + ":" + paramFormatSpecifier)
logVargs.append(param.paramName)
logFormatStr = ", ".join(logFormat)
logVargsStr = ", ".join(logVargs)
cgen.stmt("ENCODER_DEBUG_LOG(\"%s(%s)\", %s)" % (api.name, logFormatStr, logVargsStr))
def emit_default_encoding(typeInfo, api, cgen):
emit_debug_log(typeInfo, api, cgen)
emit_lock(cgen)
emit_parameter_encode_preamble_write(typeInfo, api, cgen)
emit_parameter_encode_copy_unwrap_count(typeInfo, api, cgen)
emit_parameter_encode_write_packet_info(typeInfo, api, cgen)
emit_parameter_encode_do_parameter_write(typeInfo, api, cgen)
emit_parameter_encode_read(typeInfo, api, cgen)
emit_return_unmarshal(typeInfo, api, cgen)
emit_post(typeInfo, api, cgen)
emit_pool_free(cgen)
emit_unlock(cgen)
emit_return(typeInfo, api, cgen)
## Custom encoding definitions##################################################
def emit_only_goldfish_custom(typeInfo, api, cgen):
emit_lock(cgen)
cgen.vkApiCall( \
api,
customPrefix="sResourceTracker->on_",
customParameters=custom_encoder_args(api) + \
[p.paramName for p in api.parameters[:-1]])
emit_unlock(cgen)
emit_return(typeInfo, api, cgen)
def emit_only_resource_event(typeInfo, api, cgen):
cgen.stmt("(void)doLock");
input_result = None
retExpr = api.getRetVarExpr()
if retExpr:
retType = api.getRetTypeExpr()
input_result = SUCCESS_RET_TYPES[retType]
cgen.stmt("%s %s = (%s)0" % (retType, retExpr, retType))
cgen.stmt(
(("%s = " % retExpr) if retExpr else "") +
make_event_handler_call(
"sResourceTracker",
api,
ENCODER_THIS_PARAM,
input_result, cgen))
if retExpr:
emit_return(typeInfo, api, cgen)
def emit_with_custom_unwrap(custom):
def call(typeInfo, api, cgen):
emit_lock(cgen)
emit_parameter_encode_preamble_write(typeInfo, api, cgen)
emit_parameter_encode_copy_unwrap_count(
typeInfo, api, cgen, customUnwrap=custom)
emit_parameter_encode_write_packet_info(typeInfo, api, cgen)
emit_parameter_encode_do_parameter_write(typeInfo, api, cgen)
emit_parameter_encode_read(typeInfo, api, cgen)
emit_return_unmarshal(typeInfo, api, cgen)
emit_pool_free(cgen)
emit_unlock(cgen)
emit_return(typeInfo, api, cgen)
return call
def encode_vkFlushMappedMemoryRanges(typeInfo, api, cgen):
emit_lock(cgen)
emit_parameter_encode_preamble_write(typeInfo, api, cgen)
emit_parameter_encode_copy_unwrap_count(typeInfo, api, cgen)
def emit_flush_ranges(streamVar):
cgen.beginIf("!sResourceTracker->usingDirectMapping()")
cgen.beginFor("uint32_t i = 0", "i < memoryRangeCount", "++i")
cgen.stmt("auto range = pMemoryRanges[i]")
cgen.stmt("auto memory = pMemoryRanges[i].memory")
cgen.stmt("auto size = pMemoryRanges[i].size")
cgen.stmt("auto offset = pMemoryRanges[i].offset")
cgen.stmt("uint64_t streamSize = 0")
cgen.stmt("if (!memory) { %s->write(&streamSize, sizeof(uint64_t)); continue; }" % streamVar)
cgen.stmt("auto hostPtr = sResourceTracker->getMappedPointer(memory)")
cgen.stmt("auto actualSize = size == VK_WHOLE_SIZE ? sResourceTracker->getMappedSize(memory) : size")
cgen.stmt("if (!hostPtr) { %s->write(&streamSize, sizeof(uint64_t)); continue; }" % streamVar)
cgen.stmt("streamSize = actualSize")
cgen.stmt("%s->write(&streamSize, sizeof(uint64_t))" % streamVar)
cgen.stmt("uint8_t* targetRange = hostPtr + offset")
cgen.stmt("%s->write(targetRange, actualSize)" % streamVar)
cgen.endFor()
cgen.endIf()
emit_parameter_encode_write_packet_info(typeInfo, api, cgen)
emit_parameter_encode_do_parameter_write(typeInfo, api, cgen)
emit_flush_ranges(STREAM)
emit_parameter_encode_read(typeInfo, api, cgen)
emit_return_unmarshal(typeInfo, api, cgen)
emit_pool_free(cgen)
emit_unlock(cgen)
emit_return(typeInfo, api, cgen)
def encode_vkInvalidateMappedMemoryRanges(typeInfo, api, cgen):
emit_lock(cgen)
emit_parameter_encode_preamble_write(typeInfo, api, cgen)
emit_parameter_encode_copy_unwrap_count(typeInfo, api, cgen)
emit_parameter_encode_write_packet_info(typeInfo, api, cgen)
emit_parameter_encode_do_parameter_write(typeInfo, api, cgen)
emit_parameter_encode_read(typeInfo, api, cgen)
emit_return_unmarshal(typeInfo, api, cgen)
def emit_invalidate_ranges(streamVar):
cgen.beginIf("!sResourceTracker->usingDirectMapping()")
cgen.beginFor("uint32_t i = 0", "i < memoryRangeCount", "++i")
cgen.stmt("auto range = pMemoryRanges[i]")
cgen.stmt("auto memory = pMemoryRanges[i].memory")
cgen.stmt("auto size = pMemoryRanges[i].size")
cgen.stmt("auto offset = pMemoryRanges[i].offset")
cgen.stmt("uint64_t streamSize = 0")
cgen.stmt("if (!memory) { %s->read(&streamSize, sizeof(uint64_t)); continue; }" % streamVar)
cgen.stmt("auto hostPtr = sResourceTracker->getMappedPointer(memory)")
cgen.stmt("auto actualSize = size == VK_WHOLE_SIZE ? sResourceTracker->getMappedSize(memory) : size")
cgen.stmt("if (!hostPtr) { %s->read(&streamSize, sizeof(uint64_t)); continue; }" % streamVar)
cgen.stmt("streamSize = actualSize")
cgen.stmt("%s->read(&streamSize, sizeof(uint64_t))" % streamVar)
cgen.stmt("uint8_t* targetRange = hostPtr + offset")
cgen.stmt("%s->read(targetRange, actualSize)" % streamVar)
cgen.endFor()
cgen.endIf()
emit_invalidate_ranges(STREAM)
emit_pool_free(cgen)
emit_unlock(cgen)
emit_return(typeInfo, api, cgen)
def emit_manual_inline(typeInfo, api, cgen):
cgen.line("#include \"%s_encode_impl.cpp.inl\"" % api.name)
def unwrap_vkCreateImage_pCreateInfo():
def mapOp(cgen, orig, local):
cgen.stmt("sResourceTracker->unwrap_vkCreateImage_pCreateInfo(%s, %s)" %
(orig.paramName, local.paramName))
return { "pCreateInfo" : { "mapOp" : mapOp } }
def unwrap_vkBindImageMemory2_pBindInfos():
def mapOp(cgen, orig, local):
cgen.stmt("sResourceTracker->unwrap_VkBindImageMemory2_pBindInfos(bindInfoCount, %s, %s)" %
(orig.paramName, local.paramName))
return { "pBindInfos" : { "mapOp" : mapOp } }
def unwrap_vkAcquireImageANDROID_nativeFenceFd():
def mapOp(cgen, orig, local):
cgen.stmt("sResourceTracker->unwrap_vkAcquireImageANDROID_nativeFenceFd(%s, &%s)" %
(orig.paramName, local.paramName))
return { "nativeFenceFd" : { "mapOp" : mapOp } }
custom_encodes = {
"vkMapMemory" : emit_only_resource_event,
"vkUnmapMemory" : emit_only_resource_event,
"vkFlushMappedMemoryRanges" : encode_vkFlushMappedMemoryRanges,
"vkInvalidateMappedMemoryRanges" : encode_vkInvalidateMappedMemoryRanges,
"vkCreateImage" : emit_with_custom_unwrap(unwrap_vkCreateImage_pCreateInfo()),
"vkCreateImageWithRequirementsGOOGLE" : emit_with_custom_unwrap(unwrap_vkCreateImage_pCreateInfo()),
"vkBindImageMemory2": emit_with_custom_unwrap(unwrap_vkBindImageMemory2_pBindInfos()),
"vkAcquireImageANDROID" : emit_with_custom_unwrap(unwrap_vkAcquireImageANDROID_nativeFenceFd()),
"vkQueueFlushCommandsGOOGLE" : emit_manual_inline,
}
class VulkanEncoder(VulkanWrapperGenerator):
def __init__(self, module, typeInfo):
VulkanWrapperGenerator.__init__(self, module, typeInfo)
self.typeInfo = typeInfo
self.cgenHeader = CodeGen()
self.cgenHeader.incrIndent()
self.cgenImpl = CodeGen()
def onBegin(self,):
self.module.appendHeader(encoder_decl_preamble)
self.module.appendImpl(encoder_impl_preamble)
def onGenCmd(self, cmdinfo, name, alias):
VulkanWrapperGenerator.onGenCmd(self, cmdinfo, name, alias)
api = copy.deepcopy(self.typeInfo.apis[name])
api.parameters.append(makeVulkanTypeSimple(False, "uint32_t", 0, "doLock"))
self.cgenHeader.stmt(self.cgenHeader.makeFuncProto(api))
apiImpl = api.withModifiedName("VkEncoder::" + api.name)
self.module.appendHeader(self.cgenHeader.swapCode())
def emit_function_impl(cgen):
if api.name in custom_encodes.keys():
custom_encodes[api.name](self.typeInfo, api, cgen)
else:
emit_default_encoding(self.typeInfo, api, cgen)
self.module.appendImpl(self.cgenImpl.makeFuncImpl(apiImpl, emit_function_impl))
def onEnd(self,):
self.module.appendHeader(encoder_decl_postamble)
self.cgenHeader.decrIndent()