diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c index cfe6ebb8..5021632e 100644 --- a/libs/vkd3d/resource.c +++ b/libs/vkd3d/resource.c @@ -460,11 +460,15 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_Map(ID3D12Resource *iface, UINT TRACE("iface %p, sub_resource %u, read_range %p, data %p.\n", iface, sub_resource, read_range, data); - FIXME("Ignoring read range %p.\n", read_range); - device = resource->device; vk_procs = &device->vk_procs; + if (!is_cpu_accessible_heap(&resource->heap_properties)) + { + WARN("Resource is not CPU accessible.\n"); + return E_INVALIDARG; + } + if (resource->desc.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER) { /* Textures seem to be mappable only on UMA adapters. */ @@ -478,6 +482,8 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_Map(ID3D12Resource *iface, UINT return E_NOTIMPL; } + FIXME("Ignoring read range %p.\n", read_range); + if (!resource->map_count) { if ((vr = VK_CALL(vkMapMemory(device->vk_device, resource->vk_memory, @@ -692,6 +698,8 @@ static HRESULT d3d12_committed_resource_init(struct d3d12_resource *resource, st resource->map_count = 0; resource->map_data = NULL; + resource->heap_properties = *heap_properties; + resource->device = device; ID3D12Device_AddRef(&device->ID3D12Device_iface); @@ -740,6 +748,8 @@ HRESULT vkd3d_create_image_resource(ID3D12Device *device, const D3D12_RESOURCE_D object->external = true; object->map_count = 0; object->map_data = NULL; + memset(&object->heap_properties, 0, sizeof(object->heap_properties)); + object->heap_properties.Type = D3D12_HEAP_TYPE_DEFAULT; object->device = d3d12_device; ID3D12Device_AddRef(&d3d12_device->ID3D12Device_iface); diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 833e7c93..3adf82d0 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -133,6 +133,8 @@ struct d3d12_resource unsigned int map_count; void *map_data; + D3D12_HEAP_PROPERTIES heap_properties; + struct d3d12_device *device; }; @@ -368,6 +370,18 @@ 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) +{ + if (properties->Type == D3D12_HEAP_TYPE_DEFAULT) + return false; + if (properties->Type == D3D12_HEAP_TYPE_CUSTOM) + { + return properties->CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE + || properties->CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_WRITE_BACK; + } + return true; +} + HRESULT return_interface(IUnknown *iface, REFIID iface_riid, REFIID requested_riid, void **object) DECLSPEC_HIDDEN; diff --git a/tests/d3d12.c b/tests/d3d12.c index 94fc87fb..399f44c1 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -2716,7 +2716,7 @@ static void test_map_resource(void) /* Resources on a DEFAULT heap cannot be mapped. */ hr = ID3D12Resource_Map(resource, 0, NULL, &data); - todo(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr); ID3D12Resource_Release(resource);