You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
660 lines
24 KiB
660 lines
24 KiB
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(IOStream* stream);
|
|
~VkEncoder();
|
|
|
|
#include "VkEncoder.h.inl"
|
|
"""
|
|
|
|
encoder_decl_postamble = """
|
|
private:
|
|
class Impl;
|
|
std::unique_ptr<Impl> mImpl;
|
|
};
|
|
"""
|
|
|
|
encoder_impl_preamble ="""
|
|
|
|
using namespace goldfish_vk;
|
|
|
|
using android::aligned_buf_alloc;
|
|
using android::aligned_buf_free;
|
|
using android::base::guest::AutoLock;
|
|
using android::base::guest::Lock;
|
|
using android::base::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",
|
|
"vkGetPhysicalDeviceProperties",
|
|
"vkGetPhysicalDeviceProperties2",
|
|
"vkGetPhysicalDeviceProperties2KHR",
|
|
"vkGetPhysicalDeviceMemoryProperties",
|
|
"vkGetPhysicalDeviceMemoryProperties2",
|
|
"vkGetPhysicalDeviceMemoryProperties2KHR",
|
|
"vkCreateDescriptorUpdateTemplate",
|
|
"vkCreateDescriptorUpdateTemplateKHR",
|
|
"vkGetPhysicalDeviceExternalSemaphoreProperties",
|
|
"vkGetPhysicalDeviceExternalSemaphorePropertiesKHR",
|
|
]
|
|
|
|
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, 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** 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_default_encoding(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_VkNativeBufferANDROID():
|
|
def mapOp(cgen, orig, local):
|
|
cgen.stmt("sResourceTracker->unwrap_VkNativeBufferANDROID(%s, %s)" %
|
|
(orig.paramName, local.paramName))
|
|
return { "pCreateInfo" : { "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_VkNativeBufferANDROID()),
|
|
"vkCreateImageWithRequirementsGOOGLE" : emit_with_custom_unwrap(unwrap_VkNativeBufferANDROID()),
|
|
"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())
|
|
|
|
if api.name in custom_encodes.keys():
|
|
self.module.appendImpl(self.cgenImpl.makeFuncImpl(
|
|
apiImpl, lambda cgen: custom_encodes[api.name](self.typeInfo, api, cgen)))
|
|
else:
|
|
self.module.appendImpl(self.cgenImpl.makeFuncImpl(apiImpl,
|
|
lambda cgen: emit_default_encoding(self.typeInfo, api, cgen)))
|
|
|
|
def onEnd(self,):
|
|
self.module.appendHeader(encoder_decl_postamble)
|
|
self.cgenHeader.decrIndent()
|