[vulkan] Add validation mechanism to encoder

bug: 111137294
bug: 120118806

The places where validation interfaces with the encoder will
be autogenerated, while the logic of it is not...for now at least.

First, validate the flush/invalidate APIs to some approx degree
(it doesnt currently care whether the host visible regions were
actually mapped at the user level)

Change-Id: I0f942a8c889eb0dcd164b2fa12ef1b01ab617762
diff --git a/system/vulkan_enc/Android.mk b/system/vulkan_enc/Android.mk
index d64bbdb..f603445 100644
--- a/system/vulkan_enc/Android.mk
+++ b/system/vulkan_enc/Android.mk
@@ -41,6 +41,7 @@
     -DVK_NO_PROTOTYPES \
 
 LOCAL_SRC_FILES := Resources.cpp \
+    Validation.cpp \
     VulkanStream.cpp \
     VulkanHandleMapping.cpp \
     ResourceTracker.cpp \
diff --git a/system/vulkan_enc/CMakeLists.txt b/system/vulkan_enc/CMakeLists.txt
index a10b3a3..84f222d 100644
--- a/system/vulkan_enc/CMakeLists.txt
+++ b/system/vulkan_enc/CMakeLists.txt
@@ -1,8 +1,8 @@
 # This is an autogenerated file! Do not edit!
 # instead run make from .../device/generic/goldfish-opengl
 # which will re-generate this file.
-android_validate_sha256("${GOLDFISH_DEVICE_ROOT}/system/vulkan_enc/Android.mk" "3830d5a7d8d48fcd066853a00f57e2df9f8db9a30295f3bd9f3c9f6db604abe5")
-set(vulkan_enc_src Resources.cpp VulkanStream.cpp VulkanHandleMapping.cpp ResourceTracker.cpp VkEncoder.cpp goldfish_vk_extension_structs_guest.cpp goldfish_vk_marshaling_guest.cpp goldfish_vk_deepcopy_guest.cpp goldfish_vk_handlemap_guest.cpp)
+android_validate_sha256("${GOLDFISH_DEVICE_ROOT}/system/vulkan_enc/Android.mk" "39551e2c032c863c53f04162cf4228b7971ea5e0ef25a843bc586cc955290528")
+set(vulkan_enc_src Resources.cpp Validation.cpp VulkanStream.cpp VulkanHandleMapping.cpp ResourceTracker.cpp VkEncoder.cpp goldfish_vk_extension_structs_guest.cpp goldfish_vk_marshaling_guest.cpp goldfish_vk_deepcopy_guest.cpp goldfish_vk_handlemap_guest.cpp)
 android_add_shared_library(vulkan_enc)
 target_include_directories(vulkan_enc PRIVATE ${GOLDFISH_DEVICE_ROOT}/android-emu ${GOLDFISH_DEVICE_ROOT}/shared/OpenglCodecCommon ${GOLDFISH_DEVICE_ROOT}/system/vulkan_enc ${GOLDFISH_DEVICE_ROOT}/./host/include/libOpenglRender ${GOLDFISH_DEVICE_ROOT}/./system/include ${GOLDFISH_DEVICE_ROOT}/./../../../external/qemu/android/android-emugl/guest ${GOLDFISH_DEVICE_ROOT}/./../../../external/qemu/android/android-emugl/host/include ${GOLDFISH_DEVICE_ROOT}/./../../../external/qemu/android/android-emugl/host/include/vulkan)
 target_compile_definitions(vulkan_enc PRIVATE "-DWITH_GLES2" "-DPLATFORM_SDK_VERSION=29" "-DGOLDFISH_HIDL_GRALLOC" "-DEMULATOR_OPENGL_POST_O=1" "-DHOST_BUILD" "-DANDROID" "-DGL_GLEXT_PROTOTYPES" "-DPAGE_SIZE=4096" "-DGOLDFISH_VULKAN" "-DLOG_TAG=\"goldfish_vulkan\"" "-DVK_USE_PLATFORM_ANDROID_KHR" "-DVK_NO_PROTOTYPES")
diff --git a/system/vulkan_enc/ResourceTracker.h b/system/vulkan_enc/ResourceTracker.h
index 07dd421..13bea5f 100644
--- a/system/vulkan_enc/ResourceTracker.h
+++ b/system/vulkan_enc/ResourceTracker.h
@@ -41,6 +41,9 @@
     void setDeviceInfo(VkDevice device, VkPhysicalDevice physdev, VkPhysicalDeviceProperties props, VkPhysicalDeviceMemoryProperties memProps);
     bool isMemoryTypeHostVisible(VkDevice device, uint32_t typeIndex) const;
     VkDeviceSize getNonCoherentExtendedSize(VkDevice device, VkDeviceSize basicSize) const;
+    bool isValidMemoryRange(
+        VkDevice device,
+        const VkMappedMemoryRange& range) const;
 
   private:
     class Impl;
diff --git a/system/vulkan_enc/Validation.cpp b/system/vulkan_enc/Validation.cpp
new file mode 100644
index 0000000..8feed81
--- /dev/null
+++ b/system/vulkan_enc/Validation.cpp
@@ -0,0 +1,66 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+#include "Validation.h"
+
+#include "Resources.h"
+
+namespace goldfish_vk {
+
+static bool is_range_good(const VkMappedMemoryRange& range) {
+    const goldfish_VkDeviceMemory* mem =
+        as_goldfish_VkDeviceMemory(range.memory);
+
+    if (!mem || !mem->ptr) {
+        return false;
+    }
+
+    VkDeviceSize offset = range.offset;
+    VkDeviceSize size = range.size;
+
+    if (size == VK_WHOLE_SIZE) {
+        return offset <= mem->mappedSize;
+    };
+
+    return offset + size <= mem->mappedSize;
+}
+
+VkResult validate_vkFlushMappedMemoryRanges(
+    VkDevice,
+    uint32_t memoryRangeCount,
+    const VkMappedMemoryRange* pMemoryRanges) {
+
+    for (uint32_t i = 0; i < memoryRangeCount; ++i) {
+        if (!is_range_good(pMemoryRanges[i])) {
+            return VK_ERROR_OUT_OF_HOST_MEMORY;
+        }
+    }
+
+    return VK_SUCCESS;
+}
+
+VkResult validate_vkInvalidateMappedMemoryRanges(
+    VkDevice,
+    uint32_t memoryRangeCount,
+    const VkMappedMemoryRange* pMemoryRanges) {
+
+    for (uint32_t i = 0; i < memoryRangeCount; ++i) {
+        if (!is_range_good(pMemoryRanges[i])) {
+            return VK_ERROR_OUT_OF_HOST_MEMORY;
+        }
+    }
+
+    return VK_SUCCESS;
+}
+
+} // namespace goldfish_vk
diff --git a/system/vulkan_enc/Validation.h b/system/vulkan_enc/Validation.h
new file mode 100644
index 0000000..2200e35
--- /dev/null
+++ b/system/vulkan_enc/Validation.h
@@ -0,0 +1,30 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+#pragma once
+
+#include <vulkan/vulkan.h>
+
+namespace goldfish_vk {
+
+VkResult validate_vkFlushMappedMemoryRanges(
+    VkDevice device,
+    uint32_t memoryRangeCount,
+    const VkMappedMemoryRange* pMemoryRanges);
+
+VkResult validate_vkInvalidateMappedMemoryRanges(
+    VkDevice device,
+    uint32_t memoryRangeCount,
+    const VkMappedMemoryRange* pMemoryRanges);
+
+} // namespace goldfish_vk
\ No newline at end of file
diff --git a/system/vulkan_enc/VkEncoder.cpp b/system/vulkan_enc/VkEncoder.cpp
index f51744c..a247658 100644
--- a/system/vulkan_enc/VkEncoder.cpp
+++ b/system/vulkan_enc/VkEncoder.cpp
@@ -28,6 +28,7 @@
 #include "IOStream.h"
 #include "Resources.h"
 #include "ResourceTracker.h"
+#include "Validation.h"
 #include "VulkanStream.h"
 
 #include "android/base/AlignedBuf.h"
@@ -63,6 +64,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; \
+
 #ifdef VK_VERSION_1_0
 VkResult VkEncoder::vkCreateInstance(
     const VkInstanceCreateInfo* pCreateInfo,
@@ -1399,6 +1409,7 @@
     uint32_t memoryRangeCount,
     const VkMappedMemoryRange* pMemoryRanges)
 {
+    VALIDATE_RET(VkResult, VK_SUCCESS, validate_vkFlushMappedMemoryRanges(device, memoryRangeCount, pMemoryRanges));
     auto stream = mImpl->stream();
     auto countingStream = mImpl->countingStream();
     auto resources = mImpl->resources();
@@ -1489,6 +1500,7 @@
     uint32_t memoryRangeCount,
     const VkMappedMemoryRange* pMemoryRanges)
 {
+    VALIDATE_RET(VkResult, VK_SUCCESS, validate_vkInvalidateMappedMemoryRanges(device, memoryRangeCount, pMemoryRanges));
     auto stream = mImpl->stream();
     auto countingStream = mImpl->countingStream();
     auto resources = mImpl->resources();