[PATCH vkd3d 7/8] libs/vkd3d: Implement d3d12_device_CreateHeap().
Józef Kucia
joseph.kucia at gmail.com
Fri Jul 20 07:30:18 CDT 2018
From: Józef Kucia <jkucia at codeweavers.com>
Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---
libs/vkd3d/device.c | 15 +++-
libs/vkd3d/resource.c | 204 +++++++++++++++++++++++++++++++++++++++++++++
libs/vkd3d/vkd3d_private.h | 16 +++-
3 files changed, 230 insertions(+), 5 deletions(-)
diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c
index 176b0d452979..6fa001779180 100644
--- a/libs/vkd3d/device.c
+++ b/libs/vkd3d/device.c
@@ -1853,12 +1853,19 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommittedResource(ID3D12Devi
}
static HRESULT STDMETHODCALLTYPE d3d12_device_CreateHeap(ID3D12Device *iface,
- const D3D12_HEAP_DESC *desc, REFIID riid, void **heap)
+ const D3D12_HEAP_DESC *desc, REFIID iid, void **heap)
{
- FIXME("iface %p, desc %p, riid %s, heap %p stub!\n",
- iface, desc, debugstr_guid(riid), heap);
+ struct d3d12_device *device = impl_from_ID3D12Device(iface);
+ struct d3d12_heap *object;
+ HRESULT hr;
- return E_NOTIMPL;
+ TRACE("iface %p, desc %p, iid %s, heap %p.\n",
+ iface, desc, debugstr_guid(iid), heap);
+
+ if (FAILED(hr = d3d12_heap_create(device, desc, &object)))
+ return hr;
+
+ return return_interface(&object->ID3D12Heap_iface, &IID_ID3D12Heap, iid, heap);
}
static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePlacedResource(ID3D12Device *iface,
diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c
index 9fa98b085271..1456c4b925e7 100644
--- a/libs/vkd3d/resource.c
+++ b/libs/vkd3d/resource.c
@@ -18,6 +18,210 @@
#include "vkd3d_private.h"
+/* ID3D12Heap */
+static inline struct d3d12_heap *impl_from_ID3D12Heap(ID3D12Heap *iface)
+{
+ return CONTAINING_RECORD(iface, struct d3d12_heap, ID3D12Heap_iface);
+}
+
+static HRESULT STDMETHODCALLTYPE d3d12_heap_QueryInterface(ID3D12Heap *iface,
+ REFIID iid, void **object)
+{
+ TRACE("iface %p, iid %s, object %p.\n", iface, debugstr_guid(iid), object);
+
+ if (IsEqualGUID(iid, &IID_ID3D12Heap)
+ || IsEqualGUID(iid, &IID_ID3D12Pageable)
+ || IsEqualGUID(iid, &IID_ID3D12DeviceChild)
+ || IsEqualGUID(iid, &IID_ID3D12Object)
+ || IsEqualGUID(iid, &IID_IUnknown))
+ {
+ ID3D12Heap_AddRef(iface);
+ *object = iface;
+ return S_OK;
+ }
+
+ WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
+
+ *object = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG STDMETHODCALLTYPE d3d12_heap_AddRef(ID3D12Heap *iface)
+{
+ struct d3d12_heap *heap = impl_from_ID3D12Heap(iface);
+ ULONG refcount = InterlockedIncrement(&heap->refcount);
+
+ TRACE("%p increasing refcount to %u.\n", heap, refcount);
+
+ return refcount;
+}
+
+static ULONG STDMETHODCALLTYPE d3d12_heap_Release(ID3D12Heap *iface)
+{
+ struct d3d12_heap *heap = impl_from_ID3D12Heap(iface);
+ ULONG refcount = InterlockedDecrement(&heap->refcount);
+
+ TRACE("%p decreasing refcount to %u.\n", heap, refcount);
+
+ if (!refcount)
+ {
+ struct d3d12_device *device = heap->device;
+
+ vkd3d_free(heap);
+
+ ID3D12Device_Release(&device->ID3D12Device_iface);
+ }
+
+ return refcount;
+}
+
+static HRESULT STDMETHODCALLTYPE d3d12_heap_GetPrivateData(ID3D12Heap *iface,
+ REFGUID guid, UINT *data_size, void *data)
+{
+ FIXME("iface %p, guid %s, data_size %p, data %p stub!", iface, debugstr_guid(guid), data_size, data);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT STDMETHODCALLTYPE d3d12_heap_SetPrivateData(ID3D12Heap *iface,
+ REFGUID guid, UINT data_size, const void *data)
+{
+ FIXME("iface %p, guid %s, data_size %u, data %p stub!\n", iface, debugstr_guid(guid), data_size, data);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT STDMETHODCALLTYPE d3d12_heap_SetPrivateDataInterface(ID3D12Heap *iface,
+ REFGUID guid, const IUnknown *data)
+{
+ FIXME("iface %p, guid %s, data %p stub!\n", iface, debugstr_guid(guid), data);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT STDMETHODCALLTYPE d3d12_heap_SetName(ID3D12Heap *iface, const WCHAR *name)
+{
+ struct d3d12_heap *heap = impl_from_ID3D12Heap(iface);
+
+ FIXME("iface %p, name %s stub!\n", iface, debugstr_w(name, heap->device->wchar_size));
+
+ return E_NOTIMPL;
+}
+
+static HRESULT STDMETHODCALLTYPE d3d12_heap_GetDevice(ID3D12Heap *iface,
+ REFIID riid, void **device)
+{
+ struct d3d12_heap *heap = impl_from_ID3D12Heap(iface);
+
+ TRACE("iface %p, riid %s, device %p.\n", iface, debugstr_guid(riid), device);
+
+ return ID3D12Device_QueryInterface(&heap->device->ID3D12Device_iface, riid, device);
+}
+
+static D3D12_HEAP_DESC * STDMETHODCALLTYPE d3d12_heap_GetDesc(ID3D12Heap *iface,
+ D3D12_HEAP_DESC *desc)
+{
+ struct d3d12_heap *heap = impl_from_ID3D12Heap(iface);
+
+ TRACE("iface %p, desc %p.\n", iface, desc);
+
+ *desc = heap->desc;
+ return desc;
+}
+
+static const struct ID3D12HeapVtbl d3d12_heap_vtbl =
+{
+ /* IUnknown methods */
+ d3d12_heap_QueryInterface,
+ d3d12_heap_AddRef,
+ d3d12_heap_Release,
+ /* ID3D12Object methods */
+ d3d12_heap_GetPrivateData,
+ d3d12_heap_SetPrivateData,
+ d3d12_heap_SetPrivateDataInterface,
+ d3d12_heap_SetName,
+ /* ID3D12DeviceChild methods */
+ d3d12_heap_GetDevice,
+ /* ID3D12Heap methods */
+ d3d12_heap_GetDesc,
+};
+
+static HRESULT validate_heap_desc(const D3D12_HEAP_DESC *desc)
+{
+ if (!desc->SizeInBytes)
+ {
+ WARN("Invalid size %"PRIu64".\n", desc->SizeInBytes);
+ return E_INVALIDARG;
+ }
+
+ if (desc->Alignment != D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT
+ && desc->Alignment != D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT)
+ {
+ WARN("Invalid alignment %"PRIu64".\n", desc->Alignment);
+ return E_INVALIDARG;
+ }
+
+ if (desc->Flags & D3D12_HEAP_FLAG_ALLOW_DISPLAY)
+ {
+ WARN("D3D12_HEAP_FLAG_ALLOW_DISPLAY is only for committed resources.\n");
+ return E_INVALIDARG;
+ }
+
+ return S_OK;
+}
+
+static HRESULT d3d12_heap_init(struct d3d12_heap *heap,
+ struct d3d12_device *device, const D3D12_HEAP_DESC *desc)
+{
+ HRESULT hr;
+
+ heap->ID3D12Heap_iface.lpVtbl = &d3d12_heap_vtbl;
+ heap->refcount = 1;
+
+ heap->desc = *desc;
+
+ if (!heap->desc.Properties.CreationNodeMask)
+ heap->desc.Properties.CreationNodeMask = 1;
+ if (!heap->desc.Properties.VisibleNodeMask)
+ heap->desc.Properties.VisibleNodeMask = 1;
+
+ debug_ignored_node_mask(heap->desc.Properties.CreationNodeMask);
+ debug_ignored_node_mask(heap->desc.Properties.VisibleNodeMask);
+
+ if (!heap->desc.Alignment)
+ heap->desc.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
+
+ if (FAILED(hr = validate_heap_desc(&heap->desc)))
+ return hr;
+
+ heap->device = device;
+ ID3D12Device_AddRef(&device->ID3D12Device_iface);
+
+ return S_OK;
+}
+
+HRESULT d3d12_heap_create(struct d3d12_device *device,
+ const D3D12_HEAP_DESC *desc, struct d3d12_heap **heap)
+{
+ struct d3d12_heap *object;
+ HRESULT hr;
+
+ if (!(object = vkd3d_malloc(sizeof(*object))))
+ return E_OUTOFMEMORY;
+
+ if (FAILED(hr = d3d12_heap_init(object, device, desc)))
+ {
+ vkd3d_free(object);
+ return hr;
+ }
+
+ TRACE("Created heap %p.\n", object);
+
+ *heap = object;
+
+ return S_OK;
+}
+
static VkImageType vk_image_type_from_d3d12_resource_dimension(D3D12_RESOURCE_DIMENSION dimension)
{
switch (dimension)
diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h
index 0adc2e4949cc..8efb9304a554 100644
--- a/libs/vkd3d/vkd3d_private.h
+++ b/libs/vkd3d/vkd3d_private.h
@@ -180,6 +180,20 @@ struct d3d12_fence
HRESULT d3d12_fence_create(struct d3d12_device *device,
UINT64 initial_value, D3D12_FENCE_FLAGS flags, struct d3d12_fence **fence) DECLSPEC_HIDDEN;
+/* ID3D12Heap */
+struct d3d12_heap
+{
+ ID3D12Heap ID3D12Heap_iface;
+ LONG refcount;
+
+ D3D12_HEAP_DESC desc;
+
+ struct d3d12_device *device;
+};
+
+HRESULT d3d12_heap_create(struct d3d12_device *device,
+ const D3D12_HEAP_DESC *desc, struct d3d12_heap **heap) DECLSPEC_HIDDEN;
+
#define VKD3D_RESOURCE_PUBLIC_FLAGS \
(VKD3D_RESOURCE_INITIAL_STATE_TRANSITION | VKD3D_RESOURCE_PRESENT_STATE_TRANSITION)
#define VKD3D_RESOURCE_EXTERNAL 0x00000004
@@ -766,7 +780,7 @@ bool check_feature_level_support(D3D_FEATURE_LEVEL feature_level) DECLSPEC_HIDDE
bool is_valid_resource_state(D3D12_RESOURCE_STATES state) DECLSPEC_HIDDEN;
bool is_write_resource_state(D3D12_RESOURCE_STATES state) DECLSPEC_HIDDEN;
-static inline bool is_cpu_accessible_heap(const struct D3D12_HEAP_PROPERTIES *properties)
+static inline bool is_cpu_accessible_heap(const D3D12_HEAP_PROPERTIES *properties)
{
if (properties->Type == D3D12_HEAP_TYPE_DEFAULT)
return false;
--
2.16.4
More information about the wine-devel
mailing list