test/binding: inherit Device from Handle
diff --git a/tests/blit_tests.cpp b/tests/blit_tests.cpp
index d93ef25..1a2a8e0 100644
--- a/tests/blit_tests.cpp
+++ b/tests/blit_tests.cpp
@@ -764,10 +764,10 @@
     memset(&event_info, 0, sizeof(event_info));
     event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
 
-    err = vkCreateEvent(dev_.obj(), &event_info, &event);
+    err = vkCreateEvent(dev_.handle(), &event_info, &event);
     ASSERT_VK_SUCCESS(err);
 
-    err = vkGetObjectMemoryRequirements(dev_.obj(), VK_OBJECT_TYPE_EVENT, event, &mem_req);
+    err = vkGetObjectMemoryRequirements(dev_.handle(), VK_OBJECT_TYPE_EVENT, event, &mem_req);
     ASSERT_VK_SUCCESS(err);
 
     if (mem_req.size) {
@@ -780,14 +780,14 @@
         err = dev_.phy().set_memory_type(mem_req.memoryTypeBits, &mem_info, 0);
         ASSERT_VK_SUCCESS(err);
 
-        err = vkAllocMemory(dev_.obj(), &mem_info, &event_mem);
+        err = vkAllocMemory(dev_.handle(), &mem_info, &event_mem);
         ASSERT_VK_SUCCESS(err);
 
-        err = vkBindObjectMemory(dev_.obj(), VK_OBJECT_TYPE_EVENT, event, event_mem, 0);
+        err = vkBindObjectMemory(dev_.handle(), VK_OBJECT_TYPE_EVENT, event, event_mem, 0);
         ASSERT_VK_SUCCESS(err);
     }
 
-    err = vkResetEvent(dev_.obj(), event);
+    err = vkResetEvent(dev_.handle(), event);
     ASSERT_VK_SUCCESS(err);
 
     for (int i = 0; i < ARRAY_SIZE(bufs); i++) {
@@ -841,12 +841,12 @@
     EXPECT_EQ(0x11111111, data[0]);
     bufs[2].unmap();
 
-    err = vkDestroyObject(dev_.obj(), VK_OBJECT_TYPE_EVENT, event);
+    err = vkDestroyObject(dev_.handle(), VK_OBJECT_TYPE_EVENT, event);
     ASSERT_VK_SUCCESS(err);
 
     if (mem_req.size) {
         // All done with event memory, clean up
-        err = vkFreeMemory(dev_.obj(), event_mem);
+        err = vkFreeMemory(dev_.handle(), event_mem);
         ASSERT_VK_SUCCESS(err);
     }
 }
diff --git a/tests/image_tests.cpp b/tests/image_tests.cpp
index dd60907..6193dca 100644
--- a/tests/image_tests.cpp
+++ b/tests/image_tests.cpp
@@ -73,7 +73,7 @@
     void CreateImageView(VkImageViewCreateInfo* pCreateInfo,
                          VkImageView* pView);
     void DestroyImageView(VkImageView imageView);
-    VkDevice device() {return m_device->obj();}
+    VkDevice device() {return m_device->handle();}
 
 protected:
     vk_testing::Device *m_device;
diff --git a/tests/init.cpp b/tests/init.cpp
index 8d71265..4c1881e 100644
--- a/tests/init.cpp
+++ b/tests/init.cpp
@@ -75,7 +75,7 @@
     void CreateShaderTest();
     void CreateShader(VkShader *pshader);
 
-    VkDevice device() {return m_device->obj();}
+    VkDevice device() {return m_device->handle();}
 
 protected:
     VkApplicationInfo app_info;
@@ -343,7 +343,7 @@
     const VkPhysicalDeviceQueueProperties props = device->phy().queue_properties()[queue_node_index];
     for (que_idx = 0; que_idx < props.queueCount; que_idx++) {
         // TODO: Need to add support for separate MEMMGR and work queues, including synchronization
-        err = vkGetDeviceQueue(device->obj(), queue_node_index, que_idx, &queue);
+        err = vkGetDeviceQueue(device->handle(), queue_node_index, que_idx, &queue);
         ASSERT_EQ(VK_SUCCESS, err) << "vkGetDeviceQueue: " << qname << " queue #" << que_idx << ": Failed with error: " << vk_result_string(err);
     }
 }
diff --git a/tests/vkrenderframework.h b/tests/vkrenderframework.h
index 33c7047..5105495 100644
--- a/tests/vkrenderframework.h
+++ b/tests/vkrenderframework.h
@@ -41,7 +41,7 @@
                 std::vector<const char *> &layers,
                 std::vector<const char *> &extension_names);
 
-    VkDevice device() { return obj(); }
+    VkDevice device() { return handle(); }
     void get_device_queue();
 
     uint32_t                               id;
diff --git a/tests/vktestbinding.cpp b/tests/vktestbinding.cpp
index aad7cb5..230a566 100644
--- a/tests/vktestbinding.cpp
+++ b/tests/vktestbinding.cpp
@@ -31,7 +31,7 @@
     do {                                                                        \
         obj_type obj;                                                           \
         dev_ = &dev;                                                        \
-        if (EXPECT(create_func(dev.obj(), __VA_ARGS__, &obj) == VK_SUCCESS))    \
+        if (EXPECT(create_func(dev.handle(), __VA_ARGS__, &obj) == VK_SUCCESS)) \
             base_type::init(obj, vk_object_type);                               \
     } while (0)
 
@@ -280,7 +280,7 @@
 {
     uint32_t num_allocations = 1;
     std::vector<VkMemoryRequirements> info =
-        get_memory_reqs<VkMemoryRequirements>(dev_->obj(), type(), obj(), 0);
+        get_memory_reqs<VkMemoryRequirements>(dev_->handle(), type(), obj(), 0);
     EXPECT(info.size() == num_allocations);
     if (info.size() == 1 && !info[0].size)
         info.clear();
@@ -307,7 +307,7 @@
         return;
 
     if (own())
-        EXPECT(vkDestroyObject(dev_->obj(), type(), obj()) == VK_SUCCESS);
+        EXPECT(vkDestroyObject(dev_->handle(), type(), obj()) == VK_SUCCESS);
 
     if (internal_mems_) {
         delete[] internal_mems_;
@@ -321,7 +321,7 @@
 void Object::bind_memory(const GpuMemory &mem, VkDeviceSize mem_offset)
 {
     bound = true;
-    EXPECT(vkBindObjectMemory(dev_->obj(), type(), obj(), mem.obj(), mem_offset) == VK_SUCCESS);
+    EXPECT(vkBindObjectMemory(dev_->handle(), type(), obj(), mem.obj(), mem_offset) == VK_SUCCESS);
 }
 
 void Object::alloc_memory()
@@ -404,7 +404,7 @@
         queues_[i].clear();
     }
 
-    EXPECT(vkDestroyDevice(obj()) == VK_SUCCESS);
+    EXPECT(vkDestroyDevice(handle()) == VK_SUCCESS);
 }
 
 void Device::init(std::vector<const char *> &layers, std::vector<const char *> &extensions)
@@ -439,10 +439,10 @@
 
 void Device::init(const VkDeviceCreateInfo &info)
 {
-    VkDevice obj;
-    if (EXPECT(vkCreateDevice(phy_.handle(), &info, &obj) == VK_SUCCESS)) {
-        base_type::init(obj, VK_OBJECT_TYPE_DEVICE);
-    }
+    VkDevice dev;
+
+    if (EXPECT(vkCreateDevice(phy_.handle(), &info, &dev) == VK_SUCCESS))
+        Handle::init(dev);
 
     init_queues();
     init_formats();
@@ -467,7 +467,7 @@
 
         for (uint32_t j = 0; j < queue_props[i].queueCount; j++) {
             // TODO: Need to add support for separate MEMMGR and work queues, including synchronization
-            err = vkGetDeviceQueue(obj(), i, j, &queue);
+            err = vkGetDeviceQueue(handle(), i, j, &queue);
             EXPECT(err == VK_SUCCESS);
 
             if (queue_props[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
@@ -520,13 +520,13 @@
 
 void Device::wait()
 {
-    EXPECT(vkDeviceWaitIdle(obj()) == VK_SUCCESS);
+    EXPECT(vkDeviceWaitIdle(handle()) == VK_SUCCESS);
 }
 
 VkResult Device::wait(const std::vector<const Fence *> &fences, bool wait_all, uint64_t timeout)
 {
     const std::vector<VkFence> fence_objs = make_objects<VkFence>(fences);
-    VkResult err = vkWaitForFences(obj(), fence_objs.size(), &fence_objs[0], wait_all, timeout);
+    VkResult err = vkWaitForFences(handle(), fence_objs.size(), &fence_objs[0], wait_all, timeout);
     EXPECT(err == VK_SUCCESS || err == VK_TIMEOUT);
 
     return err;
@@ -534,7 +534,7 @@
 
 VkResult Device::update_descriptor_sets(const std::vector<VkWriteDescriptorSet> &writes, const std::vector<VkCopyDescriptorSet> &copies)
 {
-    return vkUpdateDescriptorSets(obj(), writes.size(), &writes[0], copies.size(), &copies[0]);
+    return vkUpdateDescriptorSets(handle(), writes.size(), &writes[0], copies.size(), &copies[0]);
 }
 
 void Queue::submit(const std::vector<const CmdBuffer *> &cmds, Fence &fence)
@@ -572,7 +572,7 @@
 GpuMemory::~GpuMemory()
 {
     if (initialized() && own())
-        EXPECT(vkFreeMemory(dev_->obj(), obj()) == VK_SUCCESS);
+        EXPECT(vkFreeMemory(dev_->handle(), obj()) == VK_SUCCESS);
 }
 
 void GpuMemory::init(const Device &dev, const VkMemoryAllocInfo &info)
@@ -589,7 +589,7 @@
 const void *GpuMemory::map(VkFlags flags) const
 {
     void *data;
-    if (!EXPECT(vkMapMemory(dev_->obj(), obj(), 0 ,0, flags, &data) == VK_SUCCESS))
+    if (!EXPECT(vkMapMemory(dev_->handle(), obj(), 0 ,0, flags, &data) == VK_SUCCESS))
         data = NULL;
 
     return data;
@@ -598,7 +598,7 @@
 void *GpuMemory::map(VkFlags flags)
 {
     void *data;
-    if (!EXPECT(vkMapMemory(dev_->obj(), obj(), 0, 0, flags, &data) == VK_SUCCESS))
+    if (!EXPECT(vkMapMemory(dev_->handle(), obj(), 0, 0, flags, &data) == VK_SUCCESS))
         data = NULL;
 
     return data;
@@ -606,7 +606,7 @@
 
 void GpuMemory::unmap() const
 {
-    EXPECT(vkUnmapMemory(dev_->obj(), obj()) == VK_SUCCESS);
+    EXPECT(vkUnmapMemory(dev_->handle(), obj()) == VK_SUCCESS);
 }
 
 void Fence::init(const Device &dev, const VkFenceCreateInfo &info)
@@ -629,12 +629,12 @@
 
 void Event::set()
 {
-    EXPECT(vkSetEvent(dev_->obj(), obj()) == VK_SUCCESS);
+    EXPECT(vkSetEvent(dev_->handle(), obj()) == VK_SUCCESS);
 }
 
 void Event::reset()
 {
-    EXPECT(vkResetEvent(dev_->obj(), obj()) == VK_SUCCESS);
+    EXPECT(vkResetEvent(dev_->handle(), obj()) == VK_SUCCESS);
 }
 
 void QueryPool::init(const Device &dev, const VkQueryPoolCreateInfo &info)
@@ -646,7 +646,7 @@
 VkResult QueryPool::results(uint32_t start, uint32_t count, size_t size, void *data)
 {
     size_t tmp = size;
-    VkResult err = vkGetQueryPoolResults(dev_->obj(), obj(), start, count, &tmp, data, 0);
+    VkResult err = vkGetQueryPoolResults(dev_->handle(), obj(), start, count, &tmp, data, 0);
     if (err == VK_SUCCESS) {
         if (!EXPECT(tmp == size))
             memset(data, 0, size);
@@ -734,7 +734,7 @@
 {
     VkSubresourceLayout data;
     size_t size = sizeof(data);
-    if (!EXPECT(vkGetImageSubresourceLayout(dev_->obj(), obj(), &subres, &data) == VK_SUCCESS && size == sizeof(data)))
+    if (!EXPECT(vkGetImageSubresourceLayout(dev_->handle(), obj(), &subres, &data) == VK_SUCCESS && size == sizeof(data)))
         memset(&data, 0, sizeof(data));
 
     return data;
@@ -773,7 +773,7 @@
      */
     VkShaderModule sh;
     dev_ = &dev;
-    VkResult err = vkCreateShaderModule(dev.obj(), &info, &sh);
+    VkResult err = vkCreateShaderModule(dev.handle(), &info, &sh);
     if (err == VK_SUCCESS)
         Object::init(sh, VK_OBJECT_TYPE_SHADER_MODULE);
 
@@ -793,7 +793,7 @@
      */
     VkShader sh;
     dev_ = &dev;
-    VkResult err = vkCreateShader(dev.obj(), &info, &sh);
+    VkResult err = vkCreateShader(dev.handle(), &info, &sh);
     if (err == VK_SUCCESS)
         Object::init(sh, VK_OBJECT_TYPE_SHADER);
 
@@ -806,11 +806,11 @@
     VkPipelineCacheCreateInfo ci;
     memset((void *) &ci, 0, sizeof(VkPipelineCacheCreateInfo));
     ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
-    VkResult err = vkCreatePipelineCache(dev.obj(), &ci, &cache);
+    VkResult err = vkCreatePipelineCache(dev.handle(), &ci, &cache);
     if (err == VK_SUCCESS) {
         DERIVED_OBJECT_TYPE_INIT(vkCreateGraphicsPipelines, dev, VK_OBJECT_TYPE_PIPELINE, cache, 1, &info);
         alloc_memory();
-        vkDestroyPipelineCache(dev.obj(), cache);
+        vkDestroyPipelineCache(dev.handle(), cache);
     }
 }
 
@@ -822,13 +822,14 @@
     dev_ = &dev;
     memset((void *) &ci, 0, sizeof(VkPipelineCacheCreateInfo));
     ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
-    VkResult err = vkCreatePipelineCache(dev.obj(), &ci, &cache);
+    VkResult err = vkCreatePipelineCache(dev.handle(), &ci, &cache);
+    EXPECT(err == VK_SUCCESS);
     if (err == VK_SUCCESS) {
-        err = vkCreateGraphicsPipelines(dev.obj(), cache, 1, &info, &pipe);
+        err = vkCreateGraphicsPipelines(dev.handle(), cache, 1, &info, &pipe);
         if (err == VK_SUCCESS) {
             Object::init(pipe, VK_OBJECT_TYPE_PIPELINE);
             alloc_memory();
-            vkDestroyPipelineCache(dev.obj(), cache);
+            vkDestroyPipelineCache(dev.handle(), cache);
         }
     }
 
@@ -842,15 +843,14 @@
     VkPipelineCacheCreateInfo ci;
     memset((void *) &ci, 0, sizeof(VkPipelineCacheCreateInfo));
     ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
-    VkResult err = vkCreatePipelineCache(dev.obj(), &ci, &cache);
+    VkResult err = vkCreatePipelineCache(dev.handle(), &ci, &cache);
     if (err == VK_SUCCESS) {
         DERIVED_OBJECT_TYPE_INIT(vkCreateComputePipelines, dev, VK_OBJECT_TYPE_PIPELINE, cache, 1, &info);
         alloc_memory();
-        vkDestroyPipelineCache(dev.obj(), cache);
+        vkDestroyPipelineCache(dev.handle(), cache);
     }
 }
 
-
 void Sampler::init(const Device &dev, const VkSamplerCreateInfo &info)
 {
     DERIVED_OBJECT_TYPE_INIT(vkCreateSampler, dev, VK_OBJECT_TYPE_SAMPLER, &info);
@@ -881,7 +881,7 @@
 
 void DescriptorPool::reset()
 {
-    EXPECT(vkResetDescriptorPool(dev_->obj(), obj()) == VK_SUCCESS);
+    EXPECT(vkResetDescriptorPool(dev_->handle(), obj()) == VK_SUCCESS);
 }
 
 std::vector<DescriptorSet *> DescriptorPool::alloc_sets(const Device &dev, VkDescriptorSetUsage usage, const std::vector<const DescriptorSetLayout *> &layouts)
@@ -892,7 +892,7 @@
     set_objs.resize(layout_objs.size());
 
     uint32_t set_count;
-    VkResult err = vkAllocDescriptorSets(dev_->obj(), obj(), usage, layout_objs.size(), &layout_objs[0], &set_objs[0], &set_count);
+    VkResult err = vkAllocDescriptorSets(dev_->handle(), obj(), usage, layout_objs.size(), &layout_objs[0], &set_objs[0], &set_count);
     if (err == VK_SUCCESS)
         EXPECT(set_count == set_objs.size());
     set_objs.resize(set_count);
diff --git a/tests/vktestbinding.h b/tests/vktestbinding.h
index 87cfe3f..e0df3fc 100644
--- a/tests/vktestbinding.h
+++ b/tests/vktestbinding.h
@@ -254,13 +254,11 @@
     explicit DerivedObject(const Device &dev, T obj) : C(dev, obj, V) {}
 };
 
-class Device : public DerivedObject<VkDevice, BaseObject, VK_OBJECT_TYPE_DEVICE> {
+class Device : public internal::Handle<VkDevice> {
 public:
     explicit Device(VkPhysicalDevice phy) : phy_(phy) {}
     ~Device();
 
-    VkDevice device() const { return obj(); }
-
     // vkCreateDevice()
     void init(const VkDeviceCreateInfo &info);
     void init(std::vector<const char*> &layers, std::vector<const char *> &extensions); // all queues, all extensions, etc
@@ -269,7 +267,7 @@
     const PhysicalDevice &phy() const { return phy_; }
 
     // vkGetDeviceProcAddr()
-    void *get_proc(const char *name) const { return vkGetDeviceProcAddr(obj(), name); }
+    void *get_proc(const char *name) const { return vkGetDeviceProcAddr(handle(), name); }
 
     // vkGetDeviceQueue()
     const std::vector<Queue *> &graphics_queues() const { return queues_[GRAPHICS]; }
@@ -379,7 +377,7 @@
     void init(const Device &dev, const VkFenceCreateInfo &info);
 
     // vkGetFenceStatus()
-    VkResult status() const { return vkGetFenceStatus(dev_->obj(), obj()); }
+    VkResult status() const { return vkGetFenceStatus(dev_->handle(), obj()); }
 
     static VkFenceCreateInfo create_info(VkFenceCreateFlags flags);
     static VkFenceCreateInfo create_info();
@@ -401,7 +399,7 @@
     // vkGetEventStatus()
     // vkSetEvent()
     // vkResetEvent()
-    VkResult status() const { return vkGetEventStatus(dev_->obj(), obj()); }
+    VkResult status() const { return vkGetEventStatus(dev_->handle(), obj()); }
     void set();
     void reset();
 
diff --git a/tests/vktestframework.cpp b/tests/vktestframework.cpp
index 6eefa25..f2f1d66 100644
--- a/tests/vktestframework.cpp
+++ b/tests/vktestframework.cpp
@@ -681,7 +681,7 @@
     swap_chain.swapModeFlags = VK_SWAP_MODE_FLIP_BIT_WSI |
                                VK_SWAP_MODE_BLIT_BIT_WSI;
 
-    err = m_fpCreateSwapChainWSI(m_device.obj(), &swap_chain, &m_swap_chain);
+    err = m_fpCreateSwapChainWSI(m_device.handle(), &swap_chain, &m_swap_chain);
     assert(!err);
 
     VkSwapChainImageInfoWSI infos[2];