[vulkan] Generate code for pre-validation in encoder
bug: 111137294
bug: 120118806
Sometimes, we don't even want to send any bytes over to the host if
there is something really fishy with an API call.
The flush/invalidate range API is especially risky since the user could
end up wanting to set UINT64_MAX and stuff.
As a first step, add mechanism to generate those validation calls in the
guest-side encoder.
Change-Id: Id6034f6e2f55209f099faf4e38be191a835084c6
diff --git a/registry/vulkan/xml/cereal/common/codegen.py b/registry/vulkan/xml/cereal/common/codegen.py
index b01345d..3eeff24 100644
--- a/registry/vulkan/xml/cereal/common/codegen.py
+++ b/registry/vulkan/xml/cereal/common/codegen.py
@@ -175,20 +175,21 @@
def leftline(self, code):
self.code += code + "\n"
+ def makeCallExpr(self, funcName, parameters):
+ return funcName + "(%s)" % (", ".join(parameters))
+
def funcCall(self, lhs, funcName, parameters):
res = self.indent()
if lhs is not None:
res += lhs + " = "
- res += funcName + "(%s);\n" % (", ".join(parameters))
-
+ res += self.makeCallExpr(funcName, parameters) + ";\n"
self.code += res
def funcCallRet(self, _lhs, funcName, parameters):
res = self.indent()
- res += "return " + funcName + "(%s);\n" % (", ".join(parameters))
-
+ res += "return " + self.makeCallExpr(funcName, parameters) + ";\n"
self.code += res
# Given a VulkanType object, generate a C type declaration
diff --git a/registry/vulkan/xml/cereal/encoder.py b/registry/vulkan/xml/cereal/encoder.py
index b6cc1ff..c61d6b3 100644
--- a/registry/vulkan/xml/cereal/encoder.py
+++ b/registry/vulkan/xml/cereal/encoder.py
@@ -46,6 +46,15 @@
VkEncoder::VkEncoder(IOStream *stream) :
mImpl(new VkEncoder::Impl(stream)) { }
+
+#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; \\
+
"""
COUNTING_STREAM = "countingStream"
@@ -53,7 +62,30 @@
RESOURCES = "resources"
POOL = "pool"
+ENCODER_PREVALIDATED_APIS = [
+ "vkFlushMappedMemoryRanges",
+ "vkInvalidateMappedMemoryRanges",
+]
+
+SUCCESS_RET_TYPES = {
+ "VkResult" : "VK_SUCCESS",
+ # TODO: Put up success results for other return types here.
+}
+
# Common components of encoding a Vulkan API call
+def emit_custom_prevalidate(typeInfo, api, cgen):
+ if api.name in ENCODER_PREVALIDATED_APIS:
+ if api.getRetTypeExpr() == "void":
+ cgen.stmt("VALIDATE_VOID(%s)" % \
+ cgen.makeCallExpr("validate_%s" % api.name,
+ [p.paramName for p in api.parameters]))
+ else:
+ cgen.stmt("VALIDATE_RET(%s, %s, %s)" % \
+ (api.getRetTypeExpr(), \
+ SUCCESS_RET_TYPES[api.getRetTypeExpr()],
+ cgen.makeCallExpr("validate_%s" % api.name, \
+ [p.paramName for p in api.parameters]))) \
+
def emit_count_marshal(typeInfo, param, cgen):
res = \
iterateVulkanType(
@@ -151,6 +183,8 @@
self.toWrite.append(localCopyParam)
def emit_parameter_encode_preamble_write(typeInfo, api, cgen):
+ emit_custom_prevalidate(typeInfo, api, cgen);
+
cgen.stmt("auto %s = mImpl->stream()" % STREAM)
cgen.stmt("auto %s = mImpl->countingStream()" % COUNTING_STREAM)
cgen.stmt("auto %s = mImpl->resources()" % RESOURCES)
diff --git a/registry/vulkan/xml/cerealgenerator.py b/registry/vulkan/xml/cerealgenerator.py
index b4e58d7..aa57b2c 100644
--- a/registry/vulkan/xml/cerealgenerator.py
+++ b/registry/vulkan/xml/cerealgenerator.py
@@ -150,6 +150,7 @@
-DVK_NO_PROTOTYPES \\
LOCAL_SRC_FILES := Resources.cpp \\
+ Validation.cpp \\
VulkanStream.cpp \\
VulkanHandleMapping.cpp \\
ResourceTracker.cpp \\
@@ -166,6 +167,7 @@
#include "IOStream.h"
#include "Resources.h"
#include "ResourceTracker.h"
+#include "Validation.h"
#include "VulkanStream.h"
#include "android/base/AlignedBuf.h"