Map/unmap enqueue fixes [6/n]: Support multiple map operations

- Dont make cpu/gpu writes on read-only unmap
- Read/Write on limited map range only
- Overlaps checks for non read-only maps
- Fixed cmd type on returned event

Change-Id: I98ca542e8d369d2426a87279f86cadb0bf3db299
This commit is contained in:
Dunajski, Bartosz
2018-02-17 22:26:28 +01:00
committed by sys_ocldev
parent 42baecd2d4
commit dd44a87d5f
37 changed files with 1685 additions and 264 deletions

2
Jenkinsfile vendored
View File

@@ -2,4 +2,4 @@
neoDependenciesRev='735095-769' neoDependenciesRev='735095-769'
strategy='EQUAL' strategy='EQUAL'
allowedF=42 allowedF=42
allowedCD=340 allowedCD=338

View File

@@ -2483,9 +2483,6 @@ cl_int CL_API_CALL clEnqueueUnmapMemObject(cl_command_queue commandQueue,
if (pMemObj->peekClMemObjType() == CL_MEM_OBJECT_PIPE) { if (pMemObj->peekClMemObjType() == CL_MEM_OBJECT_PIPE) {
return CL_INVALID_MEM_OBJECT; return CL_INVALID_MEM_OBJECT;
} }
if (!mappedPtr || mappedPtr != pMemObj->getMappedPtr()) {
return CL_INVALID_VALUE;
}
retVal = pCommandQueue->enqueueUnmapMemObject(pMemObj, mappedPtr, numEventsInWaitList, eventWaitList, event); retVal = pCommandQueue->enqueueUnmapMemObject(pMemObj, mappedPtr, numEventsInWaitList, eventWaitList, event);
} }

View File

@@ -457,14 +457,21 @@ bool CommandQueue::sendPerfCountersConfig() {
} }
cl_int CommandQueue::enqueueWriteMemObjForUnmap(MemObj *memObj, void *mappedPtr, EventsRequest &eventsRequest) { cl_int CommandQueue::enqueueWriteMemObjForUnmap(MemObj *memObj, void *mappedPtr, EventsRequest &eventsRequest) {
cl_int retVal; cl_int retVal = CL_SUCCESS;
MapInfo unmapInfo;
if (!memObj->findMappedPtr(mappedPtr, unmapInfo)) {
return CL_INVALID_VALUE;
}
if (!unmapInfo.readOnly) {
if (memObj->peekClMemObjType() == CL_MEM_OBJECT_BUFFER) { if (memObj->peekClMemObjType() == CL_MEM_OBJECT_BUFFER) {
auto buffer = castToObject<Buffer>(memObj); auto buffer = castToObject<Buffer>(memObj);
retVal = enqueueWriteBuffer(buffer, CL_TRUE, buffer->getMappedOffset()[0], buffer->getMappedSize()[0], mappedPtr, retVal = enqueueWriteBuffer(buffer, CL_TRUE, unmapInfo.offset[0], unmapInfo.size[0], mappedPtr,
eventsRequest.numEventsInWaitList, eventsRequest.eventWaitList, eventsRequest.outEvent); eventsRequest.numEventsInWaitList, eventsRequest.eventWaitList, eventsRequest.outEvent);
} else { } else {
auto image = castToObject<Image>(memObj); auto image = castToObject<Image>(memObj);
retVal = enqueueWriteImage(image, CL_FALSE, &image->getMappedOffset()[0], &image->getMappedSize()[0], retVal = enqueueWriteImage(image, CL_FALSE, &unmapInfo.offset[0], &unmapInfo.size[0],
image->getHostPtrRowPitch(), image->getHostPtrSlicePitch(), mappedPtr, image->getHostPtrRowPitch(), image->getHostPtrSlicePitch(), mappedPtr,
eventsRequest.numEventsInWaitList, eventsRequest.eventWaitList, eventsRequest.outEvent); eventsRequest.numEventsInWaitList, eventsRequest.eventWaitList, eventsRequest.outEvent);
bool mustCallFinish = true; bool mustCallFinish = true;
@@ -477,29 +484,48 @@ cl_int CommandQueue::enqueueWriteMemObjForUnmap(MemObj *memObj, void *mappedPtr,
finish(true); finish(true);
} }
} }
} else {
retVal = enqueueMarkerWithWaitList(eventsRequest.numEventsInWaitList, eventsRequest.eventWaitList, eventsRequest.outEvent);
}
if (retVal == CL_SUCCESS) {
memObj->removeMappedPtr(mappedPtr);
if (eventsRequest.outEvent) {
auto event = castToObject<Event>(*eventsRequest.outEvent);
event->setCmdType(CL_COMMAND_UNMAP_MEM_OBJECT);
}
}
return retVal; return retVal;
} }
void *CommandQueue::enqueueReadMemObjForMap(TransferProperties &transferProperties, EventsRequest &eventsRequest, cl_int &errcodeRet) { void *CommandQueue::enqueueReadMemObjForMap(TransferProperties &transferProperties, EventsRequest &eventsRequest, cl_int &errcodeRet) {
void *returnPtr = ptrOffset(transferProperties.memObj->getBasePtrForMap(), void *returnPtr = ptrOffset(transferProperties.memObj->getBasePtrForMap(),
transferProperties.memObj->calculateOffsetForMapping(transferProperties.offsetPtr)); transferProperties.memObj->calculateOffsetForMapping(transferProperties.offset));
if (!transferProperties.memObj->addMappedPtr(returnPtr, transferProperties.memObj->calculateMappedPtrLength(transferProperties.size),
transferProperties.mapFlags, transferProperties.size, transferProperties.offset)) {
errcodeRet = CL_INVALID_OPERATION;
return nullptr;
}
if (transferProperties.memObj->peekClMemObjType() == CL_MEM_OBJECT_BUFFER) { if (transferProperties.memObj->peekClMemObjType() == CL_MEM_OBJECT_BUFFER) {
auto buffer = castToObject<Buffer>(transferProperties.memObj); auto buffer = castToObject<Buffer>(transferProperties.memObj);
errcodeRet = enqueueReadBuffer(buffer, transferProperties.blocking, *transferProperties.offsetPtr, *transferProperties.sizePtr, returnPtr, errcodeRet = enqueueReadBuffer(buffer, transferProperties.blocking, transferProperties.offset[0], transferProperties.size[0], returnPtr,
eventsRequest.numEventsInWaitList, eventsRequest.eventWaitList, eventsRequest.outEvent); eventsRequest.numEventsInWaitList, eventsRequest.eventWaitList, eventsRequest.outEvent);
} else { } else {
auto image = castToObject<Image>(transferProperties.memObj); auto image = castToObject<Image>(transferProperties.memObj);
errcodeRet = enqueueReadImage(image, transferProperties.blocking, transferProperties.offsetPtr, transferProperties.sizePtr, errcodeRet = enqueueReadImage(image, transferProperties.blocking, &transferProperties.offset[0], &transferProperties.size[0],
image->getHostPtrRowPitch(), image->getHostPtrSlicePitch(), returnPtr, eventsRequest.numEventsInWaitList, image->getHostPtrRowPitch(), image->getHostPtrSlicePitch(), returnPtr, eventsRequest.numEventsInWaitList,
eventsRequest.eventWaitList, eventsRequest.outEvent); eventsRequest.eventWaitList, eventsRequest.outEvent);
} }
if (errcodeRet == CL_SUCCESS) { if (errcodeRet != CL_SUCCESS) {
transferProperties.memObj->setMapInfo(returnPtr, transferProperties.sizePtr, transferProperties.offsetPtr); transferProperties.memObj->removeMappedPtr(returnPtr);
} else { return nullptr;
returnPtr = nullptr; }
if (eventsRequest.outEvent) {
auto event = castToObject<Event>(*eventsRequest.outEvent);
event->setCmdType(transferProperties.cmdType);
} }
return returnPtr; return returnPtr;
} }
@@ -528,7 +554,7 @@ void *CommandQueue::enqueueMapBuffer(Buffer *buffer, cl_bool blockingMap,
const cl_event *eventWaitList, cl_event *event, const cl_event *eventWaitList, cl_event *event,
cl_int &errcodeRet) { cl_int &errcodeRet) {
TransferProperties transferProperties(buffer, CL_COMMAND_MAP_BUFFER, blockingMap != CL_FALSE, &offset, &size, nullptr); TransferProperties transferProperties(buffer, CL_COMMAND_MAP_BUFFER, mapFlags, blockingMap != CL_FALSE, &offset, &size, nullptr);
EventsRequest eventsRequest(numEventsInWaitList, eventWaitList, event); EventsRequest eventsRequest(numEventsInWaitList, eventWaitList, event);
return enqueueMapMemObject(transferProperties, eventsRequest, errcodeRet); return enqueueMapMemObject(transferProperties, eventsRequest, errcodeRet);
@@ -542,7 +568,7 @@ void *CommandQueue::enqueueMapImage(Image *image, cl_bool blockingMap,
const cl_event *eventWaitList, cl_event *event, const cl_event *eventWaitList, cl_event *event,
cl_int &errcodeRet) { cl_int &errcodeRet) {
TransferProperties transferProperties(image, CL_COMMAND_MAP_IMAGE, blockingMap != CL_FALSE, TransferProperties transferProperties(image, CL_COMMAND_MAP_IMAGE, mapFlags, blockingMap != CL_FALSE,
const_cast<size_t *>(origin), const_cast<size_t *>(region), nullptr); const_cast<size_t *>(origin), const_cast<size_t *>(region), nullptr);
EventsRequest eventsRequest(numEventsInWaitList, eventWaitList, event); EventsRequest eventsRequest(numEventsInWaitList, eventWaitList, event);
@@ -559,7 +585,7 @@ void *CommandQueue::enqueueMapImage(Image *image, cl_bool blockingMap,
cl_int CommandQueue::enqueueUnmapMemObject(MemObj *memObj, void *mappedPtr, cl_uint numEventsInWaitList, const cl_event *eventWaitList, cl_event *event) { cl_int CommandQueue::enqueueUnmapMemObject(MemObj *memObj, void *mappedPtr, cl_uint numEventsInWaitList, const cl_event *eventWaitList, cl_event *event) {
TransferProperties transferProperties(memObj, CL_COMMAND_UNMAP_MEM_OBJECT, false, nullptr, nullptr, mappedPtr); TransferProperties transferProperties(memObj, CL_COMMAND_UNMAP_MEM_OBJECT, 0, false, nullptr, nullptr, mappedPtr);
EventsRequest eventsRequest(numEventsInWaitList, eventWaitList, event); EventsRequest eventsRequest(numEventsInWaitList, eventWaitList, event);
return enqueueUnmapMemObject(transferProperties, eventsRequest); return enqueueUnmapMemObject(transferProperties, eventsRequest);
@@ -569,6 +595,9 @@ void CommandQueue::enqueueBlockedMapUnmapOperation(const cl_event *eventWaitList
size_t numEventsInWaitlist, size_t numEventsInWaitlist,
MapOperationType opType, MapOperationType opType,
MemObj *memObj, MemObj *memObj,
MemObjSizeArray &copySize,
MemObjOffsetArray &copyOffset,
bool readOnly,
EventBuilder &externalEventBuilder) { EventBuilder &externalEventBuilder) {
auto &commandStreamReceiver = device->getCommandStreamReceiver(); auto &commandStreamReceiver = device->getCommandStreamReceiver();
@@ -585,7 +614,7 @@ void CommandQueue::enqueueBlockedMapUnmapOperation(const cl_event *eventWaitList
} }
//store task data in event //store task data in event
auto cmd = std::unique_ptr<Command>(new CommandMapUnmap(opType, *memObj, commandStreamReceiver, *this)); auto cmd = std::unique_ptr<Command>(new CommandMapUnmap(opType, *memObj, copySize, copyOffset, readOnly, commandStreamReceiver, *this));
eventBuilder->getEvent()->setCommand(std::move(cmd)); eventBuilder->getEvent()->setCommand(std::move(cmd));
//bind output event with input events //bind output event with input events

View File

@@ -385,6 +385,9 @@ class CommandQueue : public BaseObject<_cl_command_queue> {
size_t numEventsInWaitlist, size_t numEventsInWaitlist,
MapOperationType opType, MapOperationType opType,
MemObj *memObj, MemObj *memObj,
MemObjSizeArray &copySize,
MemObjOffsetArray &copyOffset,
bool readOnly,
EventBuilder &externalEventBuilder); EventBuilder &externalEventBuilder);
// taskCount of last task // taskCount of last task

View File

@@ -30,12 +30,30 @@
namespace OCLRT { namespace OCLRT {
void *CommandQueue::cpuDataTransferHandler(TransferProperties &transferProperties, EventsRequest &eventsRequest, cl_int &retVal) { void *CommandQueue::cpuDataTransferHandler(TransferProperties &transferProperties, EventsRequest &eventsRequest, cl_int &retVal) {
MapInfo unmapInfo;
void *returnPtr = nullptr; void *returnPtr = nullptr;
EventBuilder eventBuilder; EventBuilder eventBuilder;
bool eventCompleted = false; bool eventCompleted = false;
bool mapOperation = transferProperties.cmdType == CL_COMMAND_MAP_BUFFER || transferProperties.cmdType == CL_COMMAND_MAP_IMAGE;
auto image = castToObject<Image>(transferProperties.memObj);
ErrorCodeHelper err(&retVal, CL_SUCCESS); ErrorCodeHelper err(&retVal, CL_SUCCESS);
auto image = castToObject<Image>(transferProperties.memObj); if (mapOperation) {
returnPtr = ptrOffset(transferProperties.memObj->getCpuAddressForMapping(),
transferProperties.memObj->calculateOffsetForMapping(transferProperties.offset));
if (!transferProperties.memObj->addMappedPtr(returnPtr, transferProperties.memObj->calculateMappedPtrLength(transferProperties.size),
transferProperties.mapFlags, transferProperties.size, transferProperties.offset)) {
err.set(CL_INVALID_OPERATION);
return nullptr;
}
} else if (transferProperties.cmdType == CL_COMMAND_UNMAP_MEM_OBJECT) {
if (!transferProperties.memObj->findMappedPtr(transferProperties.ptr, unmapInfo)) {
err.set(CL_INVALID_VALUE);
return nullptr;
}
transferProperties.memObj->removeMappedPtr(unmapInfo.ptr);
}
if (eventsRequest.outEvent) { if (eventsRequest.outEvent) {
eventBuilder.create<Event>(this, transferProperties.cmdType, Event::eventNotReady, Event::eventNotReady); eventBuilder.create<Event>(this, transferProperties.cmdType, Event::eventNotReady, Event::eventNotReady);
@@ -62,10 +80,14 @@ void *CommandQueue::cpuDataTransferHandler(TransferProperties &transferPropertie
transferProperties.cmdType == CL_COMMAND_MAP_IMAGE || transferProperties.cmdType == CL_COMMAND_MAP_IMAGE ||
transferProperties.cmdType == CL_COMMAND_UNMAP_MEM_OBJECT)) { transferProperties.cmdType == CL_COMMAND_UNMAP_MEM_OBJECT)) {
// Pass size and offset only. Unblocked command will call transferData(size, offset) method
enqueueBlockedMapUnmapOperation(eventsRequest.eventWaitList, enqueueBlockedMapUnmapOperation(eventsRequest.eventWaitList,
static_cast<size_t>(eventsRequest.numEventsInWaitList), static_cast<size_t>(eventsRequest.numEventsInWaitList),
transferProperties.cmdType == CL_COMMAND_UNMAP_MEM_OBJECT ? UNMAP : MAP, mapOperation ? MAP : UNMAP,
transferProperties.memObj, transferProperties.memObj,
mapOperation ? transferProperties.size : unmapInfo.size,
mapOperation ? transferProperties.offset : unmapInfo.offset,
mapOperation ? transferProperties.mapFlags == CL_MAP_READ : unmapInfo.readOnly,
eventBuilder); eventBuilder);
} }
@@ -94,40 +116,30 @@ void *CommandQueue::cpuDataTransferHandler(TransferProperties &transferPropertie
switch (transferProperties.cmdType) { switch (transferProperties.cmdType) {
case CL_COMMAND_MAP_BUFFER: case CL_COMMAND_MAP_BUFFER:
if (!transferProperties.memObj->isMemObjZeroCopy()) { if (!transferProperties.memObj->isMemObjZeroCopy()) {
transferProperties.memObj->transferDataToHostPtr({{transferProperties.memObj->getSize(), 0, 0}}, {{0, 0, 0}}); transferProperties.memObj->transferDataToHostPtr(transferProperties.size, transferProperties.offset);
eventCompleted = true; eventCompleted = true;
} }
break; break;
case CL_COMMAND_MAP_IMAGE: case CL_COMMAND_MAP_IMAGE:
if (!image->isMemObjZeroCopy()) { if (!image->isMemObjZeroCopy()) {
auto &imgDesc = image->getImageDesc(); image->transferDataToHostPtr(transferProperties.size, transferProperties.offset);
std::array<size_t, 3> copySize = {{getValidParam(imgDesc.image_width),
getValidParam(imgDesc.image_height),
getValidParam((std::max(imgDesc.image_depth, imgDesc.image_array_size)))}};
image->transferDataToHostPtr(copySize, {{0, 0, 0}});
eventCompleted = true; eventCompleted = true;
} }
break; break;
case CL_COMMAND_UNMAP_MEM_OBJECT: case CL_COMMAND_UNMAP_MEM_OBJECT:
if (!transferProperties.memObj->isMemObjZeroCopy()) { if (!transferProperties.memObj->isMemObjZeroCopy()) {
std::array<size_t, 3> copySize = {{transferProperties.memObj->getSize(), 0, 0}}; if (!unmapInfo.readOnly) {
if (image) { transferProperties.memObj->transferDataFromHostPtr(unmapInfo.size, unmapInfo.offset);
auto imgDesc = image->getImageDesc();
copySize = {{getValidParam(imgDesc.image_width),
getValidParam(imgDesc.image_height),
getValidParam((std::max(imgDesc.image_depth, imgDesc.image_array_size)))}};
} }
transferProperties.memObj->transferDataFromHostPtr(copySize, {{0, 0, 0}});
eventCompleted = true; eventCompleted = true;
} }
transferProperties.memObj->decMapCount();
break; break;
case CL_COMMAND_READ_BUFFER: case CL_COMMAND_READ_BUFFER:
memcpy_s(transferProperties.ptr, *transferProperties.sizePtr, ptrOffset(transferProperties.memObj->getCpuAddressForMemoryTransfer(), *transferProperties.offsetPtr), *transferProperties.sizePtr); memcpy_s(transferProperties.ptr, transferProperties.size[0], ptrOffset(transferProperties.memObj->getCpuAddressForMemoryTransfer(), transferProperties.offset[0]), transferProperties.size[0]);
eventCompleted = true; eventCompleted = true;
break; break;
case CL_COMMAND_WRITE_BUFFER: case CL_COMMAND_WRITE_BUFFER:
memcpy_s(ptrOffset(transferProperties.memObj->getCpuAddressForMemoryTransfer(), *transferProperties.offsetPtr), *transferProperties.sizePtr, transferProperties.ptr, *transferProperties.sizePtr); memcpy_s(ptrOffset(transferProperties.memObj->getCpuAddressForMemoryTransfer(), transferProperties.offset[0]), transferProperties.size[0], transferProperties.ptr, transferProperties.size[0]);
eventCompleted = true; eventCompleted = true;
break; break;
case CL_COMMAND_MARKER: case CL_COMMAND_MARKER:
@@ -150,12 +162,6 @@ void *CommandQueue::cpuDataTransferHandler(TransferProperties &transferPropertie
providePerformanceHint(transferProperties); providePerformanceHint(transferProperties);
} }
if (transferProperties.cmdType == CL_COMMAND_MAP_BUFFER || transferProperties.cmdType == CL_COMMAND_MAP_IMAGE) {
returnPtr = ptrOffset(transferProperties.memObj->getCpuAddressForMapping(),
transferProperties.memObj->calculateOffsetForMapping(transferProperties.offsetPtr));
transferProperties.memObj->setMapInfo(returnPtr, transferProperties.sizePtr, transferProperties.offsetPtr);
}
return returnPtr; // only map returns pointer return returnPtr; // only map returns pointer
} }

View File

@@ -51,7 +51,7 @@ cl_int CommandQueueHw<GfxFamily>::enqueueReadBuffer(
buffer->isReadWriteOnCpuAllowed(blockingRead, numEventsInWaitList, ptr, size)) && buffer->isReadWriteOnCpuAllowed(blockingRead, numEventsInWaitList, ptr, size)) &&
context->getDevice(0)->getDeviceInfo().cpuCopyAllowed) { context->getDevice(0)->getDeviceInfo().cpuCopyAllowed) {
if (!isMemTransferNeeded) { if (!isMemTransferNeeded) {
TransferProperties transferProperties(buffer, CL_COMMAND_MARKER, true, &offset, &size, ptr); TransferProperties transferProperties(buffer, CL_COMMAND_MARKER, 0, true, &offset, &size, ptr);
EventsRequest eventsRequest(numEventsInWaitList, eventWaitList, event); EventsRequest eventsRequest(numEventsInWaitList, eventWaitList, event);
cpuDataTransferHandler(transferProperties, eventsRequest, retVal); cpuDataTransferHandler(transferProperties, eventsRequest, retVal);
if (event) { if (event) {
@@ -64,7 +64,7 @@ cl_int CommandQueueHw<GfxFamily>::enqueueReadBuffer(
} }
return retVal; return retVal;
} }
TransferProperties transferProperties(buffer, CL_COMMAND_READ_BUFFER, true, &offset, &size, ptr); TransferProperties transferProperties(buffer, CL_COMMAND_READ_BUFFER, 0, true, &offset, &size, ptr);
EventsRequest eventsRequest(numEventsInWaitList, eventWaitList, event); EventsRequest eventsRequest(numEventsInWaitList, eventWaitList, event);
cpuDataTransferHandler(transferProperties, eventsRequest, retVal); cpuDataTransferHandler(transferProperties, eventsRequest, retVal);

View File

@@ -50,7 +50,7 @@ cl_int CommandQueueHw<GfxFamily>::enqueueWriteBuffer(
buffer->isReadWriteOnCpuAllowed(blockingWrite, numEventsInWaitList, const_cast<void *>(ptr), size)) && buffer->isReadWriteOnCpuAllowed(blockingWrite, numEventsInWaitList, const_cast<void *>(ptr), size)) &&
context->getDevice(0)->getDeviceInfo().cpuCopyAllowed) { context->getDevice(0)->getDeviceInfo().cpuCopyAllowed) {
if (!isMemTransferNeeded) { if (!isMemTransferNeeded) {
TransferProperties transferProperties(buffer, CL_COMMAND_MARKER, true, &offset, &size, const_cast<void *>(ptr)); TransferProperties transferProperties(buffer, CL_COMMAND_MARKER, 0, true, &offset, &size, const_cast<void *>(ptr));
EventsRequest eventsRequest(numEventsInWaitList, eventWaitList, event); EventsRequest eventsRequest(numEventsInWaitList, eventWaitList, event);
cpuDataTransferHandler(transferProperties, eventsRequest, retVal); cpuDataTransferHandler(transferProperties, eventsRequest, retVal);
@@ -64,7 +64,7 @@ cl_int CommandQueueHw<GfxFamily>::enqueueWriteBuffer(
} }
return retVal; return retVal;
} }
TransferProperties transferProperties(buffer, CL_COMMAND_WRITE_BUFFER, true, &offset, &size, const_cast<void *>(ptr)); TransferProperties transferProperties(buffer, CL_COMMAND_WRITE_BUFFER, 0, true, &offset, &size, const_cast<void *>(ptr));
EventsRequest eventsRequest(numEventsInWaitList, eventWaitList, event); EventsRequest eventsRequest(numEventsInWaitList, eventWaitList, event);
cpuDataTransferHandler(transferProperties, eventsRequest, retVal); cpuDataTransferHandler(transferProperties, eventsRequest, retVal);

View File

@@ -61,6 +61,7 @@ set(RUNTIME_SRCS_HELPERS_BASE
${CMAKE_CURRENT_SOURCE_DIR}/preamble.h ${CMAKE_CURRENT_SOURCE_DIR}/preamble.h
${CMAKE_CURRENT_SOURCE_DIR}/preamble.inl ${CMAKE_CURRENT_SOURCE_DIR}/preamble.inl
${CMAKE_CURRENT_SOURCE_DIR}/properties_helper.h ${CMAKE_CURRENT_SOURCE_DIR}/properties_helper.h
${CMAKE_CURRENT_SOURCE_DIR}/properties_helper.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ptr_math.h ${CMAKE_CURRENT_SOURCE_DIR}/ptr_math.h
${CMAKE_CURRENT_SOURCE_DIR}/queue_helpers.h ${CMAKE_CURRENT_SOURCE_DIR}/queue_helpers.h
${CMAKE_CURRENT_SOURCE_DIR}/sampler_helpers.h ${CMAKE_CURRENT_SOURCE_DIR}/sampler_helpers.h

View File

@@ -0,0 +1,42 @@
/*
* Copyright (c) 2018, Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include "runtime/helpers/properties_helper.h"
#include "runtime/mem_obj/mem_obj.h"
namespace OCLRT {
TransferProperties::TransferProperties(MemObj *memObj, cl_command_type cmdType, cl_map_flags mapFlags, bool blocking,
size_t *offsetPtr, size_t *sizePtr, void *ptr)
: memObj(memObj), cmdType(cmdType), mapFlags(mapFlags), blocking(blocking), ptr(ptr) {
// no size or offset passed for unmap operation
if (cmdType != CL_COMMAND_UNMAP_MEM_OBJECT) {
if (memObj->peekClMemObjType() == CL_MEM_OBJECT_BUFFER) {
size[0] = *sizePtr;
offset[0] = *offsetPtr;
} else {
size = {{sizePtr[0], sizePtr[1], sizePtr[2]}};
offset = {{offsetPtr[0], offsetPtr[1], offsetPtr[2]}};
}
}
}
} // namespace OCLRT

View File

@@ -45,27 +45,32 @@ struct EventsRequest {
cl_event *outEvent; cl_event *outEvent;
}; };
using MemObjSizeArray = std::array<size_t, 3>;
using MemObjOffsetArray = std::array<size_t, 3>;
struct TransferProperties { struct TransferProperties {
TransferProperties() = delete; TransferProperties() = delete;
TransferProperties(MemObj *memObj, cl_command_type cmdType, bool blocking, size_t *offsetPtr, size_t *sizePtr, void *ptr) TransferProperties(MemObj *memObj, cl_command_type cmdType, cl_map_flags mapFlags, bool blocking, size_t *offsetPtr, size_t *sizePtr,
: memObj(memObj), cmdType(cmdType), blocking(blocking), offsetPtr(offsetPtr), sizePtr(sizePtr), ptr(ptr){}; void *ptr);
MemObj *memObj; MemObj *memObj;
cl_command_type cmdType; cl_command_type cmdType;
cl_map_flags mapFlags;
bool blocking; bool blocking;
size_t *offsetPtr; MemObjOffsetArray offset = {{0, 0, 0}};
size_t *sizePtr; MemObjSizeArray size = {{0, 0, 0}};
void *ptr; void *ptr;
}; };
struct MapInfo { struct MapInfo {
using SizeArray = std::array<size_t, 3>; MapInfo() = default;
using OffsetArray = std::array<size_t, 3>; MapInfo(void *ptr, size_t ptrLength, MemObjSizeArray size, MemObjOffsetArray offset) : ptr(ptr), ptrLength(ptrLength), size(size), offset(offset) {}
void *ptr = nullptr; void *ptr = nullptr;
SizeArray size = {{0, 0, 0}}; size_t ptrLength = 0;
OffsetArray offset = {{0, 0, 0}}; MemObjSizeArray size = {{0, 0, 0}};
MemObjOffsetArray offset = {{0, 0, 0}};
bool readOnly = false;
}; };
} // namespace OCLRT } // namespace OCLRT

View File

@@ -27,7 +27,7 @@
#include "runtime/device/device.h" #include "runtime/device/device.h"
#include "runtime/device_queue/device_queue.h" #include "runtime/device_queue/device_queue.h"
#include "runtime/gtpin/gtpin_notify.h" #include "runtime/gtpin/gtpin_notify.h"
#include "runtime/mem_obj/image.h" #include "runtime/mem_obj/mem_obj.h"
#include "runtime/memory_manager/surface.h" #include "runtime/memory_manager/surface.h"
#include "runtime/helpers/aligned_memory.h" #include "runtime/helpers/aligned_memory.h"
#include "runtime/helpers/string.h" #include "runtime/helpers/string.h"
@@ -46,8 +46,9 @@ KernelOperation::~KernelOperation() {
alignedFree(commandStream->getBase()); alignedFree(commandStream->getBase());
} }
CommandMapUnmap::CommandMapUnmap(MapOperationType op, MemObj &memObj, CommandStreamReceiver &csr, CommandQueue &cmdQ) CommandMapUnmap::CommandMapUnmap(MapOperationType op, MemObj &memObj, MemObjSizeArray &copySize, MemObjOffsetArray &copyOffset, bool readOnly,
: memObj(memObj), csr(csr), cmdQ(cmdQ), op(op) { CommandStreamReceiver &csr, CommandQueue &cmdQ)
: memObj(memObj), copySize(copySize), copyOffset(copyOffset), readOnly(readOnly), csr(csr), cmdQ(cmdQ), op(op) {
memObj.incRefInternal(); memObj.incRefInternal();
} }
@@ -91,21 +92,11 @@ CompletionStamp &CommandMapUnmap::submit(uint32_t taskLevel, bool terminated) {
cmdQ.waitUntilComplete(completionStamp.taskCount, completionStamp.flushStamp); cmdQ.waitUntilComplete(completionStamp.taskCount, completionStamp.flushStamp);
if (!memObj.isMemObjZeroCopy()) { if (!memObj.isMemObjZeroCopy()) {
std::array<size_t, 3> copySize = {{memObj.getSize(), 0, 0}};
auto image = castToObject<Image>(&memObj);
if (image) {
auto &imgDesc = image->getImageDesc();
copySize = {{getValidParam(imgDesc.image_width),
getValidParam(imgDesc.image_height),
getValidParam((std::max(imgDesc.image_depth, imgDesc.image_array_size)))}};
}
if (op == MAP) { if (op == MAP) {
memObj.transferDataToHostPtr(copySize, {{0, 0, 0}}); memObj.transferDataToHostPtr(copySize, copyOffset);
} else { } else if (!readOnly) {
DEBUG_BREAK_IF(op != UNMAP); DEBUG_BREAK_IF(op != UNMAP);
memObj.transferDataFromHostPtr(copySize, {{0, 0, 0}}); memObj.transferDataFromHostPtr(copySize, copyOffset);
} }
} }

View File

@@ -25,6 +25,7 @@
#include "runtime/indirect_heap/indirect_heap.h" #include "runtime/indirect_heap/indirect_heap.h"
#include "runtime/utilities/iflist.h" #include "runtime/utilities/iflist.h"
#include "runtime/helpers//completion_stamp.h" #include "runtime/helpers//completion_stamp.h"
#include "runtime/helpers/properties_helper.h"
#include <memory> #include <memory>
#include <vector> #include <vector>
@@ -59,12 +60,16 @@ class Command : public IFNode<Command> {
class CommandMapUnmap : public Command { class CommandMapUnmap : public Command {
public: public:
CommandMapUnmap(MapOperationType op, MemObj &memObj, CommandStreamReceiver &csr, CommandQueue &cmdQ); CommandMapUnmap(MapOperationType op, MemObj &memObj, MemObjSizeArray &copySize, MemObjOffsetArray &copyOffset, bool readOnly,
CommandStreamReceiver &csr, CommandQueue &cmdQ);
~CommandMapUnmap() override; ~CommandMapUnmap() override;
CompletionStamp &submit(uint32_t taskLevel, bool terminated) override; CompletionStamp &submit(uint32_t taskLevel, bool terminated) override;
private: private:
MemObj &memObj; MemObj &memObj;
MemObjSizeArray copySize;
MemObjOffsetArray copyOffset;
bool readOnly;
CommandStreamReceiver &csr; CommandStreamReceiver &csr;
CommandQueue &cmdQ; CommandQueue &cmdQ;
MapOperationType op; MapOperationType op;

View File

@@ -28,6 +28,8 @@ set(RUNTIME_SRCS_MEM_OBJ
${CMAKE_CURRENT_SOURCE_DIR}/image.h ${CMAKE_CURRENT_SOURCE_DIR}/image.h
${CMAKE_CURRENT_SOURCE_DIR}/image.inl ${CMAKE_CURRENT_SOURCE_DIR}/image.inl
${CMAKE_CURRENT_SOURCE_DIR}/image_factory_init.inl ${CMAKE_CURRENT_SOURCE_DIR}/image_factory_init.inl
${CMAKE_CURRENT_SOURCE_DIR}/map_operations_handler.cpp
${CMAKE_CURRENT_SOURCE_DIR}/map_operations_handler.h
${CMAKE_CURRENT_SOURCE_DIR}/mem_obj.cpp ${CMAKE_CURRENT_SOURCE_DIR}/mem_obj.cpp
${CMAKE_CURRENT_SOURCE_DIR}/mem_obj.h ${CMAKE_CURRENT_SOURCE_DIR}/mem_obj.h
${CMAKE_CURRENT_SOURCE_DIR}/pipe.cpp ${CMAKE_CURRENT_SOURCE_DIR}/pipe.cpp

View File

@@ -298,11 +298,11 @@ void Buffer::transferData(void *dst, void *src, size_t copySize, size_t copyOffs
memcpy_s(dstPtr, copySize, srcPtr, copySize); memcpy_s(dstPtr, copySize, srcPtr, copySize);
} }
void Buffer::transferDataToHostPtr(std::array<size_t, 3> copySize, std::array<size_t, 3> copyOffset) { void Buffer::transferDataToHostPtr(MemObjSizeArray &copySize, MemObjOffsetArray &copyOffset) {
transferData(hostPtr, memoryStorage, copySize[0], copyOffset[0]); transferData(hostPtr, memoryStorage, copySize[0], copyOffset[0]);
} }
void Buffer::transferDataFromHostPtr(std::array<size_t, 3> copySize, std::array<size_t, 3> copyOffset) { void Buffer::transferDataFromHostPtr(MemObjSizeArray &copySize, MemObjOffsetArray &copyOffset) {
transferData(memoryStorage, hostPtr, copySize[0], copyOffset[0]); transferData(memoryStorage, hostPtr, copySize[0], copyOffset[0]);
} }

View File

@@ -100,8 +100,8 @@ class Buffer : public MemObj {
static size_t calculateHostPtrSize(const size_t *origin, const size_t *region, size_t rowPitch, size_t slicePitch); static size_t calculateHostPtrSize(const size_t *origin, const size_t *region, size_t rowPitch, size_t slicePitch);
void transferDataToHostPtr(std::array<size_t, 3> copySize, std::array<size_t, 3> copyOffset) override; void transferDataToHostPtr(MemObjSizeArray &copySize, MemObjOffsetArray &copyOffset) override;
void transferDataFromHostPtr(std::array<size_t, 3> copySize, std::array<size_t, 3> copyOffset) override; void transferDataFromHostPtr(MemObjSizeArray &copySize, MemObjOffsetArray &copyOffset) override;
bool isReadWriteOnCpuAllowed(cl_bool blocking, cl_uint numEventsInWaitList, void *ptr, size_t size); bool isReadWriteOnCpuAllowed(cl_bool blocking, cl_uint numEventsInWaitList, void *ptr, size_t size);

View File

@@ -842,13 +842,13 @@ Image *Image::redescribe() {
return image; return image;
} }
void Image::transferDataToHostPtr(std::array<size_t, 3> copySize, std::array<size_t, 3> copyOffset) { void Image::transferDataToHostPtr(MemObjSizeArray &copySize, MemObjOffsetArray &copyOffset) {
transferData(hostPtr, hostPtrRowPitch, hostPtrSlicePitch, transferData(hostPtr, hostPtrRowPitch, hostPtrSlicePitch,
graphicsAllocation->getUnderlyingBuffer(), imageDesc.image_row_pitch, imageDesc.image_slice_pitch, graphicsAllocation->getUnderlyingBuffer(), imageDesc.image_row_pitch, imageDesc.image_slice_pitch,
copySize, copyOffset); copySize, copyOffset);
} }
void Image::transferDataFromHostPtr(std::array<size_t, 3> copySize, std::array<size_t, 3> copyOffset) { void Image::transferDataFromHostPtr(MemObjSizeArray &copySize, MemObjOffsetArray &copyOffset) {
transferData(memoryStorage, imageDesc.image_row_pitch, imageDesc.image_slice_pitch, transferData(memoryStorage, imageDesc.image_row_pitch, imageDesc.image_slice_pitch,
hostPtr, hostPtrRowPitch, hostPtrSlicePitch, hostPtr, hostPtrRowPitch, hostPtrSlicePitch,
copySize, copyOffset); copySize, copyOffset);
@@ -1189,7 +1189,7 @@ bool Image::hasAlphaChannel(const cl_image_format *imageFormat) {
(channelOrder == CL_ABGR); (channelOrder == CL_ABGR);
} }
size_t Image::calculateOffsetForMapping(size_t *origin) const { size_t Image::calculateOffsetForMapping(const MemObjOffsetArray &origin) const {
size_t rowPitch = mappingOnCpuAllowed() ? imageDesc.image_row_pitch : getHostPtrRowPitch(); size_t rowPitch = mappingOnCpuAllowed() ? imageDesc.image_row_pitch : getHostPtrRowPitch();
size_t slicePitch = mappingOnCpuAllowed() ? imageDesc.image_slice_pitch : getHostPtrSlicePitch(); size_t slicePitch = mappingOnCpuAllowed() ? imageDesc.image_slice_pitch : getHostPtrSlicePitch();

View File

@@ -133,8 +133,8 @@ class Image : public MemObj {
const cl_image_format &getImageFormat() const; const cl_image_format &getImageFormat() const;
const SurfaceFormatInfo &getSurfaceFormatInfo() const; const SurfaceFormatInfo &getSurfaceFormatInfo() const;
void transferDataToHostPtr(std::array<size_t, 3> copySize, std::array<size_t, 3> copyOffset) override; void transferDataToHostPtr(MemObjSizeArray &copySize, MemObjOffsetArray &copyOffset) override;
void transferDataFromHostPtr(std::array<size_t, 3> copySize, std::array<size_t, 3> copyOffset) override; void transferDataFromHostPtr(MemObjSizeArray &copySize, MemObjOffsetArray &copyOffset) override;
Image *redescribe(); Image *redescribe();
Image *redescribeFillImage(); Image *redescribeFillImage();
@@ -171,7 +171,7 @@ class Image : public MemObj {
cl_int writeNV12Planes(const void *hostPtr, size_t hostPtrRowPitch); cl_int writeNV12Planes(const void *hostPtr, size_t hostPtrRowPitch);
void setMcsSurfaceInfo(McsSurfaceInfo &info) { mcsSurfaceInfo = info; } void setMcsSurfaceInfo(McsSurfaceInfo &info) { mcsSurfaceInfo = info; }
const McsSurfaceInfo &getMcsSurfaceInfo() { return mcsSurfaceInfo; } const McsSurfaceInfo &getMcsSurfaceInfo() { return mcsSurfaceInfo; }
size_t calculateOffsetForMapping(size_t *origin) const override; size_t calculateOffsetForMapping(const MemObjOffsetArray &origin) const override;
const bool isTiledImage; const bool isTiledImage;
@@ -190,9 +190,6 @@ class Image : public MemObj {
const SurfaceFormatInfo *surfaceFormatInfo = nullptr, const SurfaceFormatInfo *surfaceFormatInfo = nullptr,
const SurfaceOffsets *surfaceOffsets = nullptr); const SurfaceOffsets *surfaceOffsets = nullptr);
void setMappedOffset(size_t *offset) override { mapInfo.offset = {{offset[0], offset[1], offset[2]}}; }
void setMappedSize(size_t *size) override { mapInfo.size = {{size[0], size[1], size[2]}}; }
void getOsSpecificImageInfo(const cl_mem_info &paramName, size_t *srcParamSize, void **srcParam); void getOsSpecificImageInfo(const cl_mem_info &paramName, size_t *srcParamSize, void **srcParam);
void transferData(void *dst, size_t dstRowPitch, size_t dstSlicePitch, void transferData(void *dst, size_t dstRowPitch, size_t dstSlicePitch,

View File

@@ -0,0 +1,88 @@
/*
* Copyright (c) 2018, Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include "runtime/mem_obj/map_operations_handler.h"
#include "runtime/helpers/ptr_math.h"
using namespace OCLRT;
size_t MapOperationsHandler::size() const {
std::lock_guard<std::mutex> lock(mtx);
return mappedPointers.size();
}
bool MapOperationsHandler::add(void *ptr, size_t ptrLength, cl_map_flags &mapFlags, MemObjSizeArray &size, MemObjOffsetArray &offset) {
std::lock_guard<std::mutex> lock(mtx);
MapInfo mapInfo(ptr, ptrLength, size, offset);
mapInfo.readOnly = (mapFlags == CL_MAP_READ);
if (isOverlapping(mapInfo)) {
return false;
}
mappedPointers.push_back(mapInfo);
return true;
}
bool MapOperationsHandler::isOverlapping(MapInfo &inputMapInfo) {
if (inputMapInfo.readOnly) {
return false;
}
auto inputStartPtr = inputMapInfo.ptr;
auto inputEndPtr = ptrOffset(inputStartPtr, inputMapInfo.ptrLength);
for (auto &mapInfo : mappedPointers) {
auto mappedStartPtr = mapInfo.ptr;
auto mappedEndPtr = ptrOffset(mappedStartPtr, mapInfo.ptrLength);
// Requested ptr starts before or inside existing ptr range and overlapping end
if (inputStartPtr < mappedEndPtr && inputEndPtr >= mappedStartPtr) {
return true;
}
}
return false;
}
bool MapOperationsHandler::find(void *mappedPtr, MapInfo &outMapInfo) {
std::lock_guard<std::mutex> lock(mtx);
for (auto &mapInfo : mappedPointers) {
if (mapInfo.ptr == mappedPtr) {
outMapInfo = mapInfo;
return true;
}
}
return false;
}
void MapOperationsHandler::remove(void *mappedPtr) {
std::lock_guard<std::mutex> lock(mtx);
auto endIter = mappedPointers.end();
for (auto it = mappedPointers.begin(); it != endIter; it++) {
if (it->ptr == mappedPtr) {
std::iter_swap(it, mappedPointers.end() - 1);
mappedPointers.pop_back();
break;
}
}
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright (c) 2018, Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#pragma once
#include "runtime/helpers/properties_helper.h"
#include <vector>
#include <mutex>
namespace OCLRT {
class MapOperationsHandler {
public:
virtual ~MapOperationsHandler() = default;
bool add(void *ptr, size_t ptrLength, cl_map_flags &mapFlags, MemObjSizeArray &size, MemObjOffsetArray &offset);
void remove(void *mappedPtr);
bool find(void *mappedPtr, MapInfo &outMapInfo);
size_t size() const;
protected:
bool isOverlapping(MapInfo &inputMapInfo);
std::vector<MapInfo> mappedPointers;
mutable std::mutex mtx;
};
} // namespace OCLRT

View File

@@ -59,7 +59,7 @@ MemObj::~MemObj() {
if (allocatedMapPtr != nullptr) { if (allocatedMapPtr != nullptr) {
needWait = true; needWait = true;
} }
if (mapInfo.ptr && !getCpuAddressForMapping()) { if (mapOperationsHandler.size() > 0 && !getCpuAddressForMapping()) {
needWait = true; needWait = true;
} }
if (!destructorCallbacks.empty()) { if (!destructorCallbacks.empty()) {
@@ -112,6 +112,7 @@ cl_int MemObj::getMemObjectInfo(cl_mem_info paramName,
void *srcParam = nullptr; void *srcParam = nullptr;
cl_bool usesSVMPointer; cl_bool usesSVMPointer;
cl_uint refCnt = 0; cl_uint refCnt = 0;
cl_uint mapCount = 0;
cl_mem clAssociatedMemObject = static_cast<cl_mem>(this->associatedMemObject); cl_mem clAssociatedMemObject = static_cast<cl_mem>(this->associatedMemObject);
cl_context ctx = nullptr; cl_context ctx = nullptr;
@@ -160,6 +161,7 @@ cl_int MemObj::getMemObjectInfo(cl_mem_info paramName,
case CL_MEM_MAP_COUNT: case CL_MEM_MAP_COUNT:
srcParamSize = sizeof(mapCount); srcParamSize = sizeof(mapCount);
mapCount = static_cast<cl_uint>(mapOperationsHandler.size());
srcParam = &mapCount; srcParam = &mapCount;
break; break;
@@ -214,22 +216,10 @@ CompletionStamp MemObj::getCompletionStamp() const {
return completionStamp; return completionStamp;
} }
void MemObj::setMappedPtr(void *mappedPtr) {
mapInfo.ptr = mappedPtr;
}
void MemObj::setAllocatedMapPtr(void *allocatedMapPtr) { void MemObj::setAllocatedMapPtr(void *allocatedMapPtr) {
this->allocatedMapPtr = allocatedMapPtr; this->allocatedMapPtr = allocatedMapPtr;
} }
void MemObj::incMapCount() {
this->mapCount++;
};
void MemObj::decMapCount() {
this->mapCount--;
};
cl_mem_flags MemObj::getFlags() const { cl_mem_flags MemObj::getFlags() const {
return flags; return flags;
} }
@@ -341,11 +331,7 @@ void *MemObj::getBasePtrForMap() {
} }
} }
void MemObj::setMapInfo(void *mappedPtr, size_t *size, size_t *offset) { bool MemObj::addMappedPtr(void *ptr, size_t ptrLength, cl_map_flags &mapFlags, MemObjSizeArray &size, MemObjOffsetArray &offset) {
TakeOwnershipWrapper<MemObj> memObjOwnership(*this); return mapOperationsHandler.add(ptr, ptrLength, mapFlags, size, offset);
setMappedPtr(mappedPtr);
setMappedSize(size);
setMappedOffset(offset);
incMapCount();
} }
} // namespace OCLRT } // namespace OCLRT

View File

@@ -25,11 +25,10 @@
#include "runtime/helpers/base_object.h" #include "runtime/helpers/base_object.h"
#include "runtime/helpers/completion_stamp.h" #include "runtime/helpers/completion_stamp.h"
#include "runtime/sharings/sharing.h" #include "runtime/sharings/sharing.h"
#include "runtime/helpers/properties_helper.h" #include "runtime/mem_obj/map_operations_handler.h"
#include <atomic> #include <atomic>
#include <cstdint> #include <cstdint>
#include <vector> #include <vector>
#include <array>
namespace OCLRT { namespace OCLRT {
class GraphicsAllocation; class GraphicsAllocation;
@@ -76,25 +75,21 @@ class MemObj : public BaseObject<_cl_mem> {
void setCompletionStamp(CompletionStamp completionStamp, Device *pDevice, CommandQueue *pCmdQ); void setCompletionStamp(CompletionStamp completionStamp, Device *pDevice, CommandQueue *pCmdQ);
CompletionStamp getCompletionStamp() const; CompletionStamp getCompletionStamp() const;
void setMapInfo(void *mappedPtr, size_t *size, size_t *offset); bool addMappedPtr(void *ptr, size_t ptrLength, cl_map_flags &mapFlags, MemObjSizeArray &size, MemObjOffsetArray &offset);
bool findMappedPtr(void *mappedPtr, MapInfo &outMapInfo) { return mapOperationsHandler.find(mappedPtr, outMapInfo); }
void removeMappedPtr(void *mappedPtr) { return mapOperationsHandler.remove(mappedPtr); }
void *getBasePtrForMap(); void *getBasePtrForMap();
void *getMappedPtr() const { return mapInfo.ptr; };
MOCKABLE_VIRTUAL void setAllocatedMapPtr(void *allocatedMapPtr); MOCKABLE_VIRTUAL void setAllocatedMapPtr(void *allocatedMapPtr);
void *getAllocatedMapPtr() const { return allocatedMapPtr; } void *getAllocatedMapPtr() const { return allocatedMapPtr; }
MapInfo::SizeArray getMappedSize() const { return mapInfo.size; }
MapInfo::OffsetArray getMappedOffset() const { return mapInfo.offset; }
void setHostPtrMinSize(size_t size); void setHostPtrMinSize(size_t size);
void releaseAllocatedMapPtr(); void releaseAllocatedMapPtr();
void incMapCount();
void decMapCount();
bool isMemObjZeroCopy() const; bool isMemObjZeroCopy() const;
bool isMemObjWithHostPtrSVM() const; bool isMemObjWithHostPtrSVM() const;
virtual void transferDataToHostPtr(std::array<size_t, 3> copySize, std::array<size_t, 3> copyOffset) { UNRECOVERABLE_IF(true); }; virtual void transferDataToHostPtr(MemObjSizeArray &copySize, MemObjOffsetArray &copyOffset) { UNRECOVERABLE_IF(true); };
virtual void transferDataFromHostPtr(std::array<size_t, 3> copySize, std::array<size_t, 3> copyOffset) { UNRECOVERABLE_IF(true); }; virtual void transferDataFromHostPtr(MemObjSizeArray &copySize, MemObjOffsetArray &copyOffset) { UNRECOVERABLE_IF(true); };
GraphicsAllocation *getGraphicsAllocation(); GraphicsAllocation *getGraphicsAllocation();
GraphicsAllocation *getMcsAllocation() { return mcsAllocation; } GraphicsAllocation *getMcsAllocation() { return mcsAllocation; }
@@ -124,16 +119,13 @@ class MemObj : public BaseObject<_cl_mem> {
void destroyGraphicsAllocation(GraphicsAllocation *allocation, bool asyncDestroy); void destroyGraphicsAllocation(GraphicsAllocation *allocation, bool asyncDestroy);
bool checkIfMemoryTransferIsRequired(size_t offsetInMemObjest, size_t offsetInHostPtr, const void *ptr, cl_command_type cmdType); bool checkIfMemoryTransferIsRequired(size_t offsetInMemObjest, size_t offsetInHostPtr, const void *ptr, cl_command_type cmdType);
bool mappingOnCpuAllowed() const { return !allowTiling() && !peekSharingHandler(); } bool mappingOnCpuAllowed() const { return !allowTiling() && !peekSharingHandler(); }
virtual size_t calculateOffsetForMapping(size_t *offset) const { return *offset; } virtual size_t calculateOffsetForMapping(const MemObjOffsetArray &offset) const { return offset[0]; }
size_t calculateMappedPtrLength(const MemObjSizeArray &size) const { return calculateOffsetForMapping(size); }
cl_mem_object_type peekClMemObjType() const { return memObjectType; } cl_mem_object_type peekClMemObjType() const { return memObjectType; }
protected: protected:
void getOsSpecificMemObjectInfo(const cl_mem_info &paramName, size_t *srcParamSize, void **srcParam); void getOsSpecificMemObjectInfo(const cl_mem_info &paramName, size_t *srcParamSize, void **srcParam);
void setMappedPtr(void *mappedPtr);
virtual void setMappedSize(size_t *size) { mapInfo.size[0] = *size; }
virtual void setMappedOffset(size_t *offset) { mapInfo.offset[0] = *offset; }
Context *context; Context *context;
cl_mem_object_type memObjectType; cl_mem_object_type memObjectType;
cl_mem_flags flags; cl_mem_flags flags;
@@ -142,10 +134,9 @@ class MemObj : public BaseObject<_cl_mem> {
void *memoryStorage; void *memoryStorage;
void *hostPtr; void *hostPtr;
void *allocatedMapPtr = nullptr; void *allocatedMapPtr = nullptr;
MapInfo mapInfo; MapOperationsHandler mapOperationsHandler;
size_t offset = 0; size_t offset = 0;
MemObj *associatedMemObject = nullptr; MemObj *associatedMemObject = nullptr;
std::atomic<uint32_t> mapCount{0};
cl_uint refCount = 0; cl_uint refCount = 0;
CompletionStamp completionStamp; CompletionStamp completionStamp;
CommandQueue *cmdQueuePtr = nullptr; CommandQueue *cmdQueuePtr = nullptr;

View File

@@ -46,8 +46,9 @@ TEST_F(clEnqueueUnmapMemObjTests, givenValidAddressWhenUnmappingThenReturnSucces
EXPECT_EQ(CL_SUCCESS, retVal); EXPECT_EQ(CL_SUCCESS, retVal);
} }
TEST_F(clEnqueueUnmapMemObjTests, givenInvalidAddressWhenUnmappingThenReturnError) { TEST_F(clEnqueueUnmapMemObjTests, givenInvalidAddressWhenUnmappingOnCpuThenReturnError) {
auto buffer = std::unique_ptr<Buffer>(BufferHelper<BufferUseHostPtr<>>::create(pContext)); auto buffer = std::unique_ptr<Buffer>(BufferHelper<BufferUseHostPtr<>>::create(pContext));
EXPECT_TRUE(buffer->mappingOnCpuAllowed());
cl_int retVal = CL_SUCCESS; cl_int retVal = CL_SUCCESS;
auto mappedPtr = clEnqueueMapBuffer(pCommandQueue, buffer.get(), CL_TRUE, CL_MAP_READ, 0, 1, 0, nullptr, nullptr, &retVal); auto mappedPtr = clEnqueueMapBuffer(pCommandQueue, buffer.get(), CL_TRUE, CL_MAP_READ, 0, 1, 0, nullptr, nullptr, &retVal);
@@ -63,17 +64,19 @@ TEST_F(clEnqueueUnmapMemObjTests, givenInvalidAddressWhenUnmappingThenReturnErro
EXPECT_EQ(CL_INVALID_VALUE, retVal); EXPECT_EQ(CL_INVALID_VALUE, retVal);
} }
TEST_F(clEnqueueUnmapMemObjTests, givenNullAddressWhenUnmappingThenReturnError) { TEST_F(clEnqueueUnmapMemObjTests, givenInvalidAddressWhenUnmappingOnGpuThenReturnError) {
auto buffer = std::unique_ptr<Buffer>(BufferHelper<BufferUseHostPtr<>>::create(pContext)); auto buffer = std::unique_ptr<Buffer>(BufferHelper<BufferUseHostPtr<>>::create(pContext));
buffer->setSharingHandler(new SharingHandler());
EXPECT_FALSE(buffer->mappingOnCpuAllowed());
cl_int retVal = CL_SUCCESS; cl_int retVal = CL_SUCCESS;
clEnqueueMapBuffer(pCommandQueue, buffer.get(), CL_TRUE, CL_MAP_READ, 0, 1, 0, nullptr, nullptr, &retVal); auto mappedPtr = clEnqueueMapBuffer(pCommandQueue, buffer.get(), CL_TRUE, CL_MAP_READ, 0, 1, 0, nullptr, nullptr, &retVal);
EXPECT_EQ(CL_SUCCESS, retVal); EXPECT_EQ(CL_SUCCESS, retVal);
retVal = clEnqueueUnmapMemObject( retVal = clEnqueueUnmapMemObject(
pCommandQueue, pCommandQueue,
buffer.get(), buffer.get(),
nullptr, ptrOffset(mappedPtr, buffer->getSize() + 1),
0, 0,
nullptr, nullptr,
nullptr); nullptr);

View File

@@ -98,6 +98,8 @@ set(IGDRCL_SRCS_tests_command_queue
"${CMAKE_CURRENT_SOURCE_DIR}/local_id_tests.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/local_id_tests.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/local_work_size_tests.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/local_work_size_tests.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/multi_dispatch_info_tests.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/multi_dispatch_info_tests.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/multiple_map_buffer_tests.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/multiple_map_image_tests.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/oom_buffer_tests.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/oom_buffer_tests.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/oom_image_tests.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/oom_image_tests.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/oom_tests.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/oom_tests.cpp"

View File

@@ -58,9 +58,6 @@ struct CommandQueueHwTest
using ContextFixture::SetUp; using ContextFixture::SetUp;
CommandQueueHwTest() {
}
void SetUp() override { void SetUp() override {
MemoryManagementFixture::SetUp(); MemoryManagementFixture::SetUp();
DeviceFixture::SetUp(); DeviceFixture::SetUp();
@@ -114,10 +111,13 @@ HWTEST_F(CommandQueueHwTest, enqueueBlockedMapUnmapOperationCreatesVirtualEvent)
pHwQ->virtualEvent = nullptr; pHwQ->virtualEvent = nullptr;
MockEventBuilder eventBuilder; MockEventBuilder eventBuilder;
MemObjSizeArray size = {{1, 1, 1}};
MemObjOffsetArray offset = {{0, 0, 0}};
pHwQ->enqueueBlockedMapUnmapOperation(nullptr, pHwQ->enqueueBlockedMapUnmapOperation(nullptr,
0, 0,
MAP, MAP,
&buffer, &buffer,
size, offset, false,
eventBuilder); eventBuilder);
ASSERT_NE(nullptr, pHwQ->virtualEvent); ASSERT_NE(nullptr, pHwQ->virtualEvent);
@@ -126,7 +126,6 @@ HWTEST_F(CommandQueueHwTest, enqueueBlockedMapUnmapOperationCreatesVirtualEvent)
} }
HWTEST_F(CommandQueueHwTest, givenBlockedMapBufferCallWhenMemObjectIsPassedToCommandThenItsRefCountIsBeingIncreased) { HWTEST_F(CommandQueueHwTest, givenBlockedMapBufferCallWhenMemObjectIsPassedToCommandThenItsRefCountIsBeingIncreased) {
CommandQueueHw<FamilyType> *pHwQ = reinterpret_cast<CommandQueueHw<FamilyType> *>(pCmdQ); CommandQueueHw<FamilyType> *pHwQ = reinterpret_cast<CommandQueueHw<FamilyType> *>(pCmdQ);
MockBuffer buffer; MockBuffer buffer;
pHwQ->virtualEvent = nullptr; pHwQ->virtualEvent = nullptr;
@@ -134,10 +133,13 @@ HWTEST_F(CommandQueueHwTest, givenBlockedMapBufferCallWhenMemObjectIsPassedToCom
auto currentRefCount = buffer.getRefInternalCount(); auto currentRefCount = buffer.getRefInternalCount();
MockEventBuilder eventBuilder; MockEventBuilder eventBuilder;
MemObjSizeArray size = {{1, 1, 1}};
MemObjOffsetArray offset = {{0, 0, 0}};
pHwQ->enqueueBlockedMapUnmapOperation(nullptr, pHwQ->enqueueBlockedMapUnmapOperation(nullptr,
0, 0,
MAP, MAP,
&buffer, &buffer,
size, offset, false,
eventBuilder); eventBuilder);
EXPECT_EQ(currentRefCount + 1, buffer.getRefInternalCount()); EXPECT_EQ(currentRefCount + 1, buffer.getRefInternalCount());
@@ -149,7 +151,6 @@ HWTEST_F(CommandQueueHwTest, givenBlockedMapBufferCallWhenMemObjectIsPassedToCom
} }
HWTEST_F(CommandQueueHwTest, givenNoReturnEventWhenCallingEnqueueBlockedMapUnmapOperationThenVirtualEventIncrementsCommandQueueInternalRefCount) { HWTEST_F(CommandQueueHwTest, givenNoReturnEventWhenCallingEnqueueBlockedMapUnmapOperationThenVirtualEventIncrementsCommandQueueInternalRefCount) {
CommandQueueHw<FamilyType> *pHwQ = reinterpret_cast<CommandQueueHw<FamilyType> *>(pCmdQ); CommandQueueHw<FamilyType> *pHwQ = reinterpret_cast<CommandQueueHw<FamilyType> *>(pCmdQ);
MockBuffer buffer; MockBuffer buffer;
@@ -158,10 +159,13 @@ HWTEST_F(CommandQueueHwTest, givenNoReturnEventWhenCallingEnqueueBlockedMapUnmap
auto initialRefCountInternal = pHwQ->getRefInternalCount(); auto initialRefCountInternal = pHwQ->getRefInternalCount();
MockEventBuilder eventBuilder; MockEventBuilder eventBuilder;
MemObjSizeArray size = {{1, 1, 1}};
MemObjOffsetArray offset = {{0, 0, 0}};
pHwQ->enqueueBlockedMapUnmapOperation(nullptr, pHwQ->enqueueBlockedMapUnmapOperation(nullptr,
0, 0,
MAP, MAP,
&buffer, &buffer,
size, offset, false,
eventBuilder); eventBuilder);
ASSERT_NE(nullptr, pHwQ->virtualEvent); ASSERT_NE(nullptr, pHwQ->virtualEvent);
@@ -174,7 +178,6 @@ HWTEST_F(CommandQueueHwTest, givenNoReturnEventWhenCallingEnqueueBlockedMapUnmap
} }
HWTEST_F(CommandQueueHwTest, addMapUnmapToWaitlistEventsDoesntAddDependenciesIntoChild) { HWTEST_F(CommandQueueHwTest, addMapUnmapToWaitlistEventsDoesntAddDependenciesIntoChild) {
auto buffer = new MockBuffer; auto buffer = new MockBuffer;
CommandQueueHw<FamilyType> *pHwQ = reinterpret_cast<CommandQueueHw<FamilyType> *>(pCmdQ); CommandQueueHw<FamilyType> *pHwQ = reinterpret_cast<CommandQueueHw<FamilyType> *>(pCmdQ);
auto returnEvent = new Event(pHwQ, CL_COMMAND_MAP_BUFFER, 0, 0); auto returnEvent = new Event(pHwQ, CL_COMMAND_MAP_BUFFER, 0, 0);
@@ -184,10 +187,13 @@ HWTEST_F(CommandQueueHwTest, addMapUnmapToWaitlistEventsDoesntAddDependenciesInt
pHwQ->virtualEvent = nullptr; pHwQ->virtualEvent = nullptr;
MockEventBuilder eventBuilder(returnEvent); MockEventBuilder eventBuilder(returnEvent);
MemObjSizeArray size = {{1, 1, 1}};
MemObjOffsetArray offset = {{0, 0, 0}};
pHwQ->enqueueBlockedMapUnmapOperation(&eventWaitList, pHwQ->enqueueBlockedMapUnmapOperation(&eventWaitList,
1, 1,
MAP, MAP,
buffer, buffer,
size, offset, false,
eventBuilder); eventBuilder);
EXPECT_EQ(returnEvent, pHwQ->virtualEvent); EXPECT_EQ(returnEvent, pHwQ->virtualEvent);
@@ -201,15 +207,17 @@ HWTEST_F(CommandQueueHwTest, addMapUnmapToWaitlistEventsDoesntAddDependenciesInt
} }
HWTEST_F(CommandQueueHwTest, givenMapCommandWhenZeroStateCommandIsSubmittedThenTaskCountIsBeingWaited) { HWTEST_F(CommandQueueHwTest, givenMapCommandWhenZeroStateCommandIsSubmittedThenTaskCountIsBeingWaited) {
auto buffer = new MockBuffer; auto buffer = new MockBuffer;
CommandQueueHw<FamilyType> *pHwQ = reinterpret_cast<CommandQueueHw<FamilyType> *>(pCmdQ); CommandQueueHw<FamilyType> *pHwQ = reinterpret_cast<CommandQueueHw<FamilyType> *>(pCmdQ);
MockEventBuilder eventBuilder; MockEventBuilder eventBuilder;
MemObjSizeArray size = {{1, 1, 1}};
MemObjOffsetArray offset = {{0, 0, 0}};
pHwQ->enqueueBlockedMapUnmapOperation(nullptr, pHwQ->enqueueBlockedMapUnmapOperation(nullptr,
0, 0,
MAP, MAP,
buffer, buffer,
size, offset, false,
eventBuilder); eventBuilder);
EXPECT_NE(nullptr, pHwQ->virtualEvent); EXPECT_NE(nullptr, pHwQ->virtualEvent);
@@ -220,17 +228,19 @@ HWTEST_F(CommandQueueHwTest, givenMapCommandWhenZeroStateCommandIsSubmittedThenT
} }
HWTEST_F(CommandQueueHwTest, enqueueBlockedMapUnmapOperationInjectedCommand) { HWTEST_F(CommandQueueHwTest, enqueueBlockedMapUnmapOperationInjectedCommand) {
CommandQueueHw<FamilyType> *pHwQ = reinterpret_cast<CommandQueueHw<FamilyType> *>(pCmdQ); CommandQueueHw<FamilyType> *pHwQ = reinterpret_cast<CommandQueueHw<FamilyType> *>(pCmdQ);
Event *returnEvent = new Event(pHwQ, CL_COMMAND_MAP_BUFFER, 0, 0); Event *returnEvent = new Event(pHwQ, CL_COMMAND_MAP_BUFFER, 0, 0);
auto buffer = new MockBuffer; auto buffer = new MockBuffer;
pHwQ->virtualEvent = nullptr; pHwQ->virtualEvent = nullptr;
MockEventBuilder eventBuilder(returnEvent); MockEventBuilder eventBuilder(returnEvent);
MemObjSizeArray size = {{1, 1, 1}};
MemObjOffsetArray offset = {{0, 0, 0}};
pHwQ->enqueueBlockedMapUnmapOperation(nullptr, pHwQ->enqueueBlockedMapUnmapOperation(nullptr,
0, 0,
MAP, MAP,
buffer, buffer,
size, offset, false,
eventBuilder); eventBuilder);
eventBuilder.finalizeAndRelease(); eventBuilder.finalizeAndRelease();
@@ -245,7 +255,6 @@ HWTEST_F(CommandQueueHwTest, enqueueBlockedMapUnmapOperationInjectedCommand) {
} }
HWTEST_F(CommandQueueHwTest, enqueueBlockedMapUnmapOperationPreviousEventHasNotInjectedChild) { HWTEST_F(CommandQueueHwTest, enqueueBlockedMapUnmapOperationPreviousEventHasNotInjectedChild) {
auto buffer = new MockBuffer; auto buffer = new MockBuffer;
CommandQueueHw<FamilyType> *pHwQ = reinterpret_cast<CommandQueueHw<FamilyType> *>(pCmdQ); CommandQueueHw<FamilyType> *pHwQ = reinterpret_cast<CommandQueueHw<FamilyType> *>(pCmdQ);
Event *returnEvent = new Event(pHwQ, CL_COMMAND_MAP_BUFFER, 0, 0); Event *returnEvent = new Event(pHwQ, CL_COMMAND_MAP_BUFFER, 0, 0);
@@ -258,10 +267,13 @@ HWTEST_F(CommandQueueHwTest, enqueueBlockedMapUnmapOperationPreviousEventHasNotI
pHwQ->virtualEvent->incRefInternal(); pHwQ->virtualEvent->incRefInternal();
MockEventBuilder eventBuilder(returnEvent); MockEventBuilder eventBuilder(returnEvent);
MemObjSizeArray size = {{1, 1, 1}};
MemObjOffsetArray offset = {{0, 0, 0}};
pHwQ->enqueueBlockedMapUnmapOperation(nullptr, pHwQ->enqueueBlockedMapUnmapOperation(nullptr,
0, 0,
MAP, MAP,
buffer, buffer,
size, offset, false,
eventBuilder); eventBuilder);
EXPECT_EQ(returnEvent, pHwQ->virtualEvent); EXPECT_EQ(returnEvent, pHwQ->virtualEvent);
@@ -771,14 +783,14 @@ struct MockBuilder : BuiltinDispatchInfoBuilder {
}; };
HWTEST_F(CommandQueueHwTest, givenCommandQueueThatIsBlockedAndUsesCpuCopyWhenEventIsReturnedItIsNotReady) { HWTEST_F(CommandQueueHwTest, givenCommandQueueThatIsBlockedAndUsesCpuCopyWhenEventIsReturnedItIsNotReady) {
CommandQueueHw<FamilyType> *cmdQHw = static_cast<CommandQueueHw<FamilyType> *>(this->pCmdQ); CommandQueueHw<FamilyType> *cmdQHw = static_cast<CommandQueueHw<FamilyType> *>(this->pCmdQ);
MockBuffer buffer;
cl_event returnEvent = nullptr; cl_event returnEvent = nullptr;
auto retVal = CL_SUCCESS; auto retVal = CL_SUCCESS;
cmdQHw->taskLevel = Event::eventNotReady; cmdQHw->taskLevel = Event::eventNotReady;
size_t offset = 0; size_t offset = 0;
size_t size = 4096u; size_t size = 4096u;
TransferProperties transferProperties(nullptr, CL_COMMAND_READ_BUFFER, false, &offset, &size, nullptr); TransferProperties transferProperties(&buffer, CL_COMMAND_READ_BUFFER, 0, false, &offset, &size, nullptr);
EventsRequest eventsRequest(0, nullptr, &returnEvent); EventsRequest eventsRequest(0, nullptr, &returnEvent);
cmdQHw->cpuDataTransferHandler(transferProperties, eventsRequest, retVal); cmdQHw->cpuDataTransferHandler(transferProperties, eventsRequest, retVal);
EXPECT_EQ(CL_SUCCESS, retVal); EXPECT_EQ(CL_SUCCESS, retVal);

View File

@@ -273,10 +273,11 @@ TEST_F(EnqueueMapBufferTest, MapBufferReturnsSuccess) {
EXPECT_EQ(CL_SUCCESS, retVal); EXPECT_EQ(CL_SUCCESS, retVal);
} }
TEST_F(EnqueueMapBufferTest, givenNonBlockingMapBufferOnZeroCopyBufferWhenItIsCalledThenSynchronizationIsNotMadeUntilWaitForEvents) { TEST_F(EnqueueMapBufferTest, givenNonBlockingReadOnlyMapBufferOnZeroCopyBufferWhenItIsCalledThenSynchronizationIsNotMadeUntilWaitForEvents) {
DebugManagerStateRestore dbgRestore; DebugManagerStateRestore dbgRestore;
DebugManager.flags.EnableAsyncEventsHandler.set(false); DebugManager.flags.EnableAsyncEventsHandler.set(false);
cl_event eventReturned = nullptr; cl_event mapEventReturned = nullptr;
cl_event unmapEventReturned = nullptr;
*pTagMemory = 0; *pTagMemory = 0;
MockKernelWithInternals kernel(*pDevice); MockKernelWithInternals kernel(*pDevice);
size_t GWS = 1; size_t GWS = 1;
@@ -316,7 +317,7 @@ TEST_F(EnqueueMapBufferTest, givenNonBlockingMapBufferOnZeroCopyBufferWhenItIsCa
8, 8,
0, 0,
nullptr, nullptr,
&eventReturned, &mapEventReturned,
&retVal); &retVal);
EXPECT_NE(nullptr, ptrResult); EXPECT_NE(nullptr, ptrResult);
EXPECT_EQ(CL_SUCCESS, retVal); EXPECT_EQ(CL_SUCCESS, retVal);
@@ -327,20 +328,21 @@ TEST_F(EnqueueMapBufferTest, givenNonBlockingMapBufferOnZeroCopyBufferWhenItIsCa
taskCount = commandStreamReceiver.peekTaskCount(); taskCount = commandStreamReceiver.peekTaskCount();
EXPECT_EQ(1u, taskCount); EXPECT_EQ(1u, taskCount);
auto neoEvent = castToObject<Event>(eventReturned); auto neoEvent = castToObject<Event>(mapEventReturned);
//if task count of csr is higher then event task count with proper dc flushing then we are fine //if task count of csr is higher then event task count with proper dc flushing then we are fine
EXPECT_EQ(1u, neoEvent->getCompletionStamp()); EXPECT_EQ(1u, neoEvent->getCompletionStamp());
//this can't be completed as task count is not reached yet //this can't be completed as task count is not reached yet
EXPECT_FALSE(neoEvent->updateStatusAndCheckCompletion()); EXPECT_FALSE(neoEvent->updateStatusAndCheckCompletion());
EXPECT_TRUE(CL_COMMAND_MAP_BUFFER == neoEvent->getCommandType());
auto callbackCalled = 0u; auto callbackCalled = 0u;
*pTagMemory += 4; *pTagMemory += 4;
clSetEventCallback(eventReturned, CL_COMPLETE, E2Clb::SignalEv2, (void *)&callbackCalled); clSetEventCallback(mapEventReturned, CL_COMPLETE, E2Clb::SignalEv2, (void *)&callbackCalled);
//wait for events needs to flush DC as event requires this. //wait for events needs to flush DC as event requires this.
retVal = clWaitForEvents(1, &eventReturned); retVal = clWaitForEvents(1, &mapEventReturned);
EXPECT_EQ(CL_SUCCESS, retVal); EXPECT_EQ(CL_SUCCESS, retVal);
//wait for event do not sent flushTask //wait for event do not sent flushTask
@@ -357,13 +359,105 @@ TEST_F(EnqueueMapBufferTest, givenNonBlockingMapBufferOnZeroCopyBufferWhenItIsCa
ptrResult, ptrResult,
0, 0,
nullptr, nullptr,
nullptr); &unmapEventReturned);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(1u, commandStreamReceiver.peekTaskCount());
auto unmapEvent = castToObject<Event>(unmapEventReturned);
EXPECT_TRUE(CL_COMMAND_UNMAP_MEM_OBJECT == unmapEvent->getCommandType());
retVal = clWaitForEvents(1, &unmapEventReturned);
EXPECT_EQ(CL_SUCCESS, retVal); EXPECT_EQ(CL_SUCCESS, retVal);
retVal = clReleaseMemObject(buffer); retVal = clReleaseMemObject(buffer);
EXPECT_EQ(CL_SUCCESS, retVal); EXPECT_EQ(CL_SUCCESS, retVal);
clReleaseEvent(eventReturned); clReleaseEvent(mapEventReturned);
clReleaseEvent(unmapEventReturned);
}
TEST_F(EnqueueMapBufferTest, givenNonReadOnlyBufferWhenMappedOnGpuThenSetValidEventCmds) {
DebugManagerStateRestore dbgRestore;
DebugManager.flags.EnableAsyncEventsHandler.set(false);
cl_event mapEventReturned = nullptr;
cl_event unmapEventReturned = nullptr;
*pTagMemory = 5;
std::unique_ptr<Buffer> buffer(Buffer::create(BufferDefaults::context, CL_MEM_READ_WRITE, 20, nullptr, retVal));
buffer->setSharingHandler(new SharingHandler());
buffer->forceDisallowCPUCopy = true;
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_NE(nullptr, buffer.get());
auto &commandStreamReceiver = pDevice->getCommandStreamReceiver();
EXPECT_EQ(0u, commandStreamReceiver.peekTaskCount());
auto ptrResult = clEnqueueMapBuffer(pCmdQ, buffer.get(), CL_FALSE, CL_MAP_WRITE, 0, 8, 0,
nullptr, &mapEventReturned, &retVal);
EXPECT_NE(nullptr, ptrResult);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(1u, commandStreamReceiver.peekTaskCount());
auto mapEvent = castToObject<Event>(mapEventReturned);
EXPECT_TRUE(CL_COMMAND_MAP_BUFFER == mapEvent->getCommandType());
retVal = clWaitForEvents(1, &mapEventReturned);
EXPECT_EQ(CL_SUCCESS, retVal);
retVal = clEnqueueUnmapMemObject(pCmdQ, buffer.get(), ptrResult, 0, nullptr, &unmapEventReturned);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(2u, commandStreamReceiver.peekTaskCount());
auto unmapEvent = castToObject<Event>(unmapEventReturned);
EXPECT_TRUE(CL_COMMAND_UNMAP_MEM_OBJECT == unmapEvent->getCommandType());
retVal = clWaitForEvents(1, &unmapEventReturned);
EXPECT_EQ(CL_SUCCESS, retVal);
clReleaseEvent(mapEventReturned);
clReleaseEvent(unmapEventReturned);
}
TEST_F(EnqueueMapBufferTest, givenReadOnlyBufferWhenMappedOnGpuThenSetValidEventCmds) {
DebugManagerStateRestore dbgRestore;
DebugManager.flags.EnableAsyncEventsHandler.set(false);
cl_event mapEventReturned = nullptr;
cl_event unmapEventReturned = nullptr;
*pTagMemory = 5;
std::unique_ptr<Buffer> buffer(Buffer::create(BufferDefaults::context, CL_MEM_READ_WRITE, 20, nullptr, retVal));
buffer->setSharingHandler(new SharingHandler());
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_NE(nullptr, buffer.get());
auto &commandStreamReceiver = pDevice->getCommandStreamReceiver();
EXPECT_EQ(0u, commandStreamReceiver.peekTaskCount());
auto ptrResult = clEnqueueMapBuffer(pCmdQ, buffer.get(), CL_FALSE, CL_MAP_READ, 0, 8, 0,
nullptr, &mapEventReturned, &retVal);
EXPECT_NE(nullptr, ptrResult);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(1u, commandStreamReceiver.peekTaskCount());
auto mapEvent = castToObject<Event>(mapEventReturned);
EXPECT_TRUE(CL_COMMAND_MAP_BUFFER == mapEvent->getCommandType());
retVal = clWaitForEvents(1, &mapEventReturned);
EXPECT_EQ(CL_SUCCESS, retVal);
retVal = clEnqueueUnmapMemObject(pCmdQ, buffer.get(), ptrResult, 0, nullptr, &unmapEventReturned);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(1u, commandStreamReceiver.peekTaskCount());
auto unmapEvent = castToObject<Event>(unmapEventReturned);
EXPECT_TRUE(CL_COMMAND_UNMAP_MEM_OBJECT == unmapEvent->getCommandType());
retVal = clWaitForEvents(1, &unmapEventReturned);
EXPECT_EQ(CL_SUCCESS, retVal);
clReleaseEvent(mapEventReturned);
clReleaseEvent(unmapEventReturned);
} }
TEST_F(EnqueueMapBufferTest, givenNonBlockingMapBufferAfterL3IsAlreadyFlushedThenEventIsSignaledAsCompleted) { TEST_F(EnqueueMapBufferTest, givenNonBlockingMapBufferAfterL3IsAlreadyFlushedThenEventIsSignaledAsCompleted) {
@@ -582,13 +676,18 @@ TEST_F(EnqueueMapBufferTest, givenBufferWithoutUseHostPtrFlagWhenMappedOnCpuThen
auto mappedPtr = clEnqueueMapBuffer(pCmdQ, buffer.get(), CL_FALSE, CL_MAP_READ, mapOffset, mapSize, 0, nullptr, nullptr, &retVal); auto mappedPtr = clEnqueueMapBuffer(pCmdQ, buffer.get(), CL_FALSE, CL_MAP_READ, mapOffset, mapSize, 0, nullptr, nullptr, &retVal);
EXPECT_NE(nullptr, mappedPtr); EXPECT_NE(nullptr, mappedPtr);
EXPECT_EQ(mapOffset, buffer->getMappedOffset()[0]); MapInfo mappedInfo;
EXPECT_EQ(0u, buffer->getMappedOffset()[1]); auto success = buffer->findMappedPtr(mappedPtr, mappedInfo);
EXPECT_EQ(0u, buffer->getMappedOffset()[2]); EXPECT_TRUE(success);
EXPECT_NE(nullptr, mappedInfo.ptr);
EXPECT_EQ(mapSize, buffer->getMappedSize()[0]); EXPECT_EQ(mapOffset, mappedInfo.offset[0]);
EXPECT_EQ(0u, buffer->getMappedSize()[1]); EXPECT_EQ(0u, mappedInfo.offset[1]);
EXPECT_EQ(0u, buffer->getMappedSize()[2]); EXPECT_EQ(0u, mappedInfo.offset[2]);
EXPECT_EQ(mapSize, mappedInfo.size[0]);
EXPECT_EQ(0u, mappedInfo.size[1]);
EXPECT_EQ(0u, mappedInfo.size[2]);
auto expectedPtr = ptrOffset(buffer->getCpuAddressForMapping(), mapOffset); auto expectedPtr = ptrOffset(buffer->getCpuAddressForMapping(), mapOffset);
@@ -607,13 +706,18 @@ TEST_F(EnqueueMapBufferTest, givenBufferWithUseHostPtrFlagWhenMappedOnCpuThenSet
auto mappedPtr = clEnqueueMapBuffer(pCmdQ, buffer.get(), CL_FALSE, CL_MAP_READ, mapOffset, mapSize, 0, nullptr, nullptr, &retVal); auto mappedPtr = clEnqueueMapBuffer(pCmdQ, buffer.get(), CL_FALSE, CL_MAP_READ, mapOffset, mapSize, 0, nullptr, nullptr, &retVal);
EXPECT_NE(nullptr, mappedPtr); EXPECT_NE(nullptr, mappedPtr);
EXPECT_EQ(mapOffset, buffer->getMappedOffset()[0]); MapInfo mappedInfo;
EXPECT_EQ(0u, buffer->getMappedOffset()[1]); auto success = buffer->findMappedPtr(mappedPtr, mappedInfo);
EXPECT_EQ(0u, buffer->getMappedOffset()[2]); EXPECT_TRUE(success);
EXPECT_NE(nullptr, mappedInfo.ptr);
EXPECT_EQ(mapSize, buffer->getMappedSize()[0]); EXPECT_EQ(mapOffset, mappedInfo.offset[0]);
EXPECT_EQ(0u, buffer->getMappedSize()[1]); EXPECT_EQ(0u, mappedInfo.offset[1]);
EXPECT_EQ(0u, buffer->getMappedSize()[2]); EXPECT_EQ(0u, mappedInfo.offset[2]);
EXPECT_EQ(mapSize, mappedInfo.size[0]);
EXPECT_EQ(0u, mappedInfo.size[1]);
EXPECT_EQ(0u, mappedInfo.size[2]);
auto expectedPtr = ptrOffset(buffer->getCpuAddressForMapping(), mapOffset); auto expectedPtr = ptrOffset(buffer->getCpuAddressForMapping(), mapOffset);

View File

@@ -225,12 +225,13 @@ TEST_F(EnqueueMapImageTest, checkRetVal) {
EXPECT_EQ(imageSlicePitch, imageSlicePitchRef); EXPECT_EQ(imageSlicePitch, imageSlicePitchRef);
} }
TEST_F(EnqueueMapImageTest, MapImageWaitEvent) { TEST_F(EnqueueMapImageTest, givenNonReadOnlyMapWithOutEventWhenMappedThenSetEventAndIncraseTaskCountFromWriteImage) {
DebugManagerStateRestore dbgRestore; DebugManagerStateRestore dbgRestore;
DebugManager.flags.EnableAsyncEventsHandler.set(false); DebugManager.flags.EnableAsyncEventsHandler.set(false);
cl_event eventReturned = nullptr; cl_event mapEventReturned = nullptr;
cl_event unmapEventReturned = nullptr;
uint32_t tagHW = 0; uint32_t tagHW = 0;
auto mapFlags = CL_MAP_READ; auto mapFlags = CL_MAP_WRITE;
const size_t origin[3] = {0, 0, 0}; const size_t origin[3] = {0, 0, 0};
const size_t region[3] = {1, 1, 1}; const size_t region[3] = {1, 1, 1};
size_t imageRowPitch = 0; size_t imageRowPitch = 0;
@@ -268,18 +269,20 @@ TEST_F(EnqueueMapImageTest, MapImageWaitEvent) {
&imageSlicePitch, &imageSlicePitch,
0, 0,
nullptr, nullptr,
&eventReturned, &mapEventReturned,
retVal); retVal);
EXPECT_NE(nullptr, ptr); EXPECT_NE(nullptr, ptr);
EXPECT_EQ(CL_SUCCESS, retVal); EXPECT_EQ(CL_SUCCESS, retVal);
auto mapEvent = castToObject<Event>(mapEventReturned);
EXPECT_TRUE(CL_COMMAND_MAP_IMAGE == mapEvent->getCommandType());
taskCount = commandStreamReceiver.peekTaskCount(); taskCount = commandStreamReceiver.peekTaskCount();
EXPECT_EQ(3u, taskCount); EXPECT_EQ(3u, taskCount);
clSetEventCallback(eventReturned, CL_COMPLETE, E2Clb::SignalEv2, (void *)pTagMemory); clSetEventCallback(mapEventReturned, CL_COMPLETE, E2Clb::SignalEv2, (void *)pTagMemory);
retVal = clWaitForEvents(1, &eventReturned); retVal = clWaitForEvents(1, &mapEventReturned);
EXPECT_EQ(CL_SUCCESS, retVal); EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(4u, *pTagMemory); EXPECT_EQ(4u, *pTagMemory);
taskCount = commandStreamReceiver.peekTaskCount(); taskCount = commandStreamReceiver.peekTaskCount();
@@ -292,13 +295,60 @@ TEST_F(EnqueueMapImageTest, MapImageWaitEvent) {
ptr, ptr,
0, 0,
nullptr, nullptr,
nullptr); &unmapEventReturned);
EXPECT_EQ(CL_SUCCESS, retVal); EXPECT_EQ(CL_SUCCESS, retVal);
auto unmapEvent = castToObject<Event>(unmapEventReturned);
EXPECT_TRUE(CL_COMMAND_UNMAP_MEM_OBJECT == unmapEvent->getCommandType());
retVal = clWaitForEvents(1, &unmapEventReturned);
taskCount = commandStreamReceiver.peekTaskCount(); taskCount = commandStreamReceiver.peekTaskCount();
EXPECT_EQ(4u, taskCount); EXPECT_EQ(4u, taskCount);
clReleaseEvent(eventReturned); clReleaseEvent(mapEventReturned);
clReleaseEvent(unmapEventReturned);
}
TEST_F(EnqueueMapImageTest, givenReadOnlyMapWithOutEventWhenMappedThenSetEventAndDontIncraseTaskCountFromWriteImage) {
DebugManagerStateRestore dbgRestore;
DebugManager.flags.EnableAsyncEventsHandler.set(false);
cl_event mapEventReturned = nullptr;
cl_event unmapEventReturned = nullptr;
auto mapFlags = CL_MAP_READ;
const size_t origin[3] = {0, 0, 0};
const size_t region[3] = {1, 1, 1};
*pTagMemory = 5;
auto &commandStreamReceiver = pDevice->getCommandStreamReceiver();
EXPECT_EQ(1u, commandStreamReceiver.peekTaskCount());
auto ptr = pCmdQ->enqueueMapImage(image, false, mapFlags, origin, region, nullptr, nullptr, 0,
nullptr, &mapEventReturned, retVal);
EXPECT_NE(nullptr, ptr);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(2u, commandStreamReceiver.peekTaskCount());
auto mapEvent = castToObject<Event>(mapEventReturned);
EXPECT_TRUE(CL_COMMAND_MAP_IMAGE == mapEvent->getCommandType());
retVal = clWaitForEvents(1, &mapEventReturned);
EXPECT_EQ(CL_SUCCESS, retVal);
retVal = clEnqueueUnmapMemObject(pCmdQ, image, ptr, 0, nullptr, &unmapEventReturned);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(2u, commandStreamReceiver.peekTaskCount());
auto unmapEvent = castToObject<Event>(unmapEventReturned);
EXPECT_TRUE(CL_COMMAND_UNMAP_MEM_OBJECT == unmapEvent->getCommandType());
retVal = clWaitForEvents(1, &unmapEventReturned);
EXPECT_EQ(CL_SUCCESS, retVal);
clReleaseEvent(mapEventReturned);
clReleaseEvent(unmapEventReturned);
} }
HWTEST_F(EnqueueMapImageTest, MapImageEventProperties) { HWTEST_F(EnqueueMapImageTest, MapImageEventProperties) {
@@ -448,8 +498,8 @@ TEST_F(EnqueueMapImageTest, GivenNonZeroCopyImageWhenMappedWithOffsetThenCorrect
delete nonZeroCopyImage; delete nonZeroCopyImage;
} }
HWTEST_F(EnqueueMapImageTest, givenSharingHandlerWhenMapAndUnmapOnNonTiledImageIsCalledThenMakeGpuCopy) { HWTEST_F(EnqueueMapImageTest, givenSharingHandlerWhenNonReadOnlyMapAndUnmapOnNonTiledImageIsCalledThenMakeGpuCopy) {
auto image = ImageHelper<ImageUseHostPtr<Image1dDefaults>>::create(context); std::unique_ptr<Image> image(ImageHelper<ImageUseHostPtr<Image1dDefaults>>::create(context));
ASSERT_NE(nullptr, image); ASSERT_NE(nullptr, image);
image->setSharingHandler(new SharingHandler()); image->setSharingHandler(new SharingHandler());
EXPECT_FALSE(image->allowTiling()); EXPECT_FALSE(image->allowTiling());
@@ -462,17 +512,40 @@ HWTEST_F(EnqueueMapImageTest, givenSharingHandlerWhenMapAndUnmapOnNonTiledImageI
size_t origin[] = {0, 0, 0}; size_t origin[] = {0, 0, 0};
size_t region[] = {1, 1, 1}; size_t region[] = {1, 1, 1};
void *data = clEnqueueMapImage(pCmdQ, image, CL_TRUE, CL_MAP_READ, origin, region, nullptr, nullptr, 0, NULL, NULL, &retVal); void *data = clEnqueueMapImage(pCmdQ, image.get(), CL_TRUE, CL_MAP_WRITE, origin, region, nullptr, nullptr, 0, NULL, NULL, &retVal);
EXPECT_NE(nullptr, data); EXPECT_NE(nullptr, data);
EXPECT_EQ(CL_SUCCESS, retVal); EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(2u, pCmdQ->taskCount); EXPECT_EQ(2u, pCmdQ->taskCount);
EXPECT_EQ(2u, pCmdQ->taskLevel); EXPECT_EQ(2u, pCmdQ->taskLevel);
retVal = clEnqueueUnmapMemObject(pCmdQ, image, data, 0, NULL, NULL); retVal = clEnqueueUnmapMemObject(pCmdQ, image.get(), data, 0, NULL, NULL);
EXPECT_EQ(3u, pCmdQ->taskCount); EXPECT_EQ(3u, pCmdQ->taskCount);
EXPECT_EQ(3u, pCmdQ->taskLevel); EXPECT_EQ(3u, pCmdQ->taskLevel);
}
delete image; HWTEST_F(EnqueueMapImageTest, givenSharingHandlerWhenReadOnlyMapAndUnmapOnNonTiledImageIsCalledThenMakeGpuCopy) {
std::unique_ptr<Image> image(ImageHelper<ImageUseHostPtr<Image1dDefaults>>::create(context));
ASSERT_NE(nullptr, image);
image->setSharingHandler(new SharingHandler());
EXPECT_FALSE(image->allowTiling());
auto &csr = pDevice->getUltCommandStreamReceiver<FamilyType>();
csr.taskCount = 1;
csr.taskLevel = 1;
pCmdQ->taskCount = 1;
pCmdQ->taskLevel = 1;
size_t origin[] = {0, 0, 0};
size_t region[] = {1, 1, 1};
void *data = clEnqueueMapImage(pCmdQ, image.get(), CL_TRUE, CL_MAP_READ, origin, region, nullptr, nullptr, 0, NULL, NULL, &retVal);
EXPECT_NE(nullptr, data);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(2u, pCmdQ->taskCount);
EXPECT_EQ(2u, pCmdQ->taskLevel);
retVal = clEnqueueUnmapMemObject(pCmdQ, image.get(), data, 0, NULL, NULL);
EXPECT_EQ(2u, pCmdQ->taskCount);
EXPECT_EQ(2u, pCmdQ->taskLevel);
} }
HWTEST_F(EnqueueMapImageTest, givenImageWithouUsetHostPtrFlagWhenMappedOnCpuThenSetAllMapProperties) { HWTEST_F(EnqueueMapImageTest, givenImageWithouUsetHostPtrFlagWhenMappedOnCpuThenSetAllMapProperties) {
@@ -485,15 +558,20 @@ HWTEST_F(EnqueueMapImageTest, givenImageWithouUsetHostPtrFlagWhenMappedOnCpuThen
void *mappedPtr = clEnqueueMapImage(pCmdQ, image.get(), CL_TRUE, CL_MAP_READ, origin, region, nullptr, nullptr, 0, NULL, NULL, &retVal); void *mappedPtr = clEnqueueMapImage(pCmdQ, image.get(), CL_TRUE, CL_MAP_READ, origin, region, nullptr, nullptr, 0, NULL, NULL, &retVal);
EXPECT_NE(nullptr, mappedPtr); EXPECT_NE(nullptr, mappedPtr);
EXPECT_EQ(origin[0], image->getMappedOffset()[0]); MapInfo mappedInfo;
EXPECT_EQ(origin[1], image->getMappedOffset()[1]); auto success = image->findMappedPtr(mappedPtr, mappedInfo);
EXPECT_EQ(origin[2], image->getMappedOffset()[2]); EXPECT_TRUE(success);
EXPECT_NE(nullptr, mappedInfo.ptr);
EXPECT_EQ(region[0], image->getMappedSize()[0]); EXPECT_EQ(origin[0], mappedInfo.offset[0]);
EXPECT_EQ(region[1], image->getMappedSize()[1]); EXPECT_EQ(origin[1], mappedInfo.offset[1]);
EXPECT_EQ(region[2], image->getMappedSize()[2]); EXPECT_EQ(origin[2], mappedInfo.offset[2]);
auto expectedPtr = ptrOffset(image->getCpuAddressForMapping(), image->calculateOffsetForMapping(origin)); EXPECT_EQ(region[0], mappedInfo.size[0]);
EXPECT_EQ(region[1], mappedInfo.size[1]);
EXPECT_EQ(region[2], mappedInfo.size[2]);
auto expectedPtr = ptrOffset(image->getCpuAddressForMapping(), image->calculateOffsetForMapping(mappedInfo.offset));
EXPECT_EQ(mappedPtr, expectedPtr); EXPECT_EQ(mappedPtr, expectedPtr);
} }
@@ -508,15 +586,20 @@ HWTEST_F(EnqueueMapImageTest, givenImageWithUseHostPtrFlagWhenMappedOnCpuThenSet
void *mappedPtr = clEnqueueMapImage(pCmdQ, image.get(), CL_TRUE, CL_MAP_READ, origin, region, nullptr, nullptr, 0, NULL, NULL, &retVal); void *mappedPtr = clEnqueueMapImage(pCmdQ, image.get(), CL_TRUE, CL_MAP_READ, origin, region, nullptr, nullptr, 0, NULL, NULL, &retVal);
EXPECT_NE(nullptr, mappedPtr); EXPECT_NE(nullptr, mappedPtr);
EXPECT_EQ(origin[0], image->getMappedOffset()[0]); MapInfo mappedInfo;
EXPECT_EQ(origin[1], image->getMappedOffset()[1]); auto success = image->findMappedPtr(mappedPtr, mappedInfo);
EXPECT_EQ(origin[2], image->getMappedOffset()[2]); EXPECT_TRUE(success);
EXPECT_NE(nullptr, mappedInfo.ptr);
EXPECT_EQ(region[0], image->getMappedSize()[0]); EXPECT_EQ(origin[0], mappedInfo.offset[0]);
EXPECT_EQ(region[1], image->getMappedSize()[1]); EXPECT_EQ(origin[1], mappedInfo.offset[1]);
EXPECT_EQ(region[2], image->getMappedSize()[2]); EXPECT_EQ(origin[2], mappedInfo.offset[2]);
auto expectedPtr = ptrOffset(image->getCpuAddressForMapping(), image->calculateOffsetForMapping(origin)); EXPECT_EQ(region[0], mappedInfo.size[0]);
EXPECT_EQ(region[1], mappedInfo.size[1]);
EXPECT_EQ(region[2], mappedInfo.size[2]);
auto expectedPtr = ptrOffset(image->getCpuAddressForMapping(), image->calculateOffsetForMapping(mappedInfo.offset));
EXPECT_EQ(mappedPtr, expectedPtr); EXPECT_EQ(mappedPtr, expectedPtr);
} }

View File

@@ -0,0 +1,384 @@
/*
* Copyright (c) 2018, Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include "runtime/command_queue/command_queue_hw.h"
#include "runtime/mem_obj/buffer.h"
#include "unit_tests/fixtures/device_fixture.h"
#include "unit_tests/mocks/mock_context.h"
#include "test.h"
using namespace OCLRT;
struct MultipleMapBufferTest : public DeviceFixture, public ::testing::Test {
template <typename T>
struct MockBuffer : public BufferHw<T> {
using Buffer::mapOperationsHandler;
template <class... Params>
MockBuffer(Params... params) : BufferHw<T>(params...) {
this->createFunction = BufferHw<T>::create;
};
void transferDataToHostPtr(MemObjSizeArray &copySize, MemObjOffsetArray &copyOffset) override {
this->copySize = copySize[0];
this->copyOffset = copyOffset[0];
transferToHostPtrCalled++;
};
void transferDataFromHostPtr(MemObjSizeArray &copySize, MemObjOffsetArray &copyOffset) override {
this->copySize = copySize[0];
this->copyOffset = copyOffset[0];
transferFromHostPtrCalled++;
};
size_t copySize = 0;
size_t copyOffset = 0;
uint32_t transferToHostPtrCalled = 0;
uint32_t transferFromHostPtrCalled = 0;
};
template <typename T>
struct MockCmdQ : public CommandQueueHw<T> {
MockCmdQ(Context *context, Device *device) : CommandQueueHw<T>(context, device, 0) {}
cl_int enqueueReadBuffer(Buffer *buffer, cl_bool blockingRead, size_t offset, size_t size, void *ptr,
cl_uint numEventsInWaitList, const cl_event *eventWaitList, cl_event *event) override {
enqueueSize = size;
enqueueOffset = offset;
readBufferCalled++;
if (failOnReadBuffer) {
return CL_OUT_OF_RESOURCES;
}
return CommandQueueHw<T>::enqueueReadBuffer(buffer, blockingRead, offset, size, ptr, numEventsInWaitList, eventWaitList, event);
}
cl_int enqueueWriteBuffer(Buffer *buffer, cl_bool blockingWrite, size_t offset, size_t cb, const void *ptr,
cl_uint numEventsInWaitList, const cl_event *eventWaitList, cl_event *event) override {
enqueueSize = cb;
enqueueOffset = offset;
unmapPtr = ptr;
writeBufferCalled++;
if (failOnWriteBuffer) {
return CL_OUT_OF_RESOURCES;
}
return CommandQueueHw<T>::enqueueWriteBuffer(buffer, blockingWrite, offset, cb, ptr, numEventsInWaitList, eventWaitList, event);
}
cl_int enqueueMarkerWithWaitList(cl_uint numEventsInWaitList, const cl_event *eventWaitList, cl_event *event) override {
enqueueMarkerCalled++;
return CommandQueueHw<T>::enqueueMarkerWithWaitList(numEventsInWaitList, eventWaitList, event);
}
uint32_t writeBufferCalled = 0;
uint32_t readBufferCalled = 0;
uint32_t enqueueMarkerCalled = 0;
bool failOnReadBuffer = false;
bool failOnWriteBuffer = false;
size_t enqueueSize = 0;
size_t enqueueOffset = 0;
const void *unmapPtr = nullptr;
};
template <typename FamilyType>
std::unique_ptr<MockBuffer<FamilyType>> createMockBuffer(bool mapOnGpu) {
auto mockAlloc = pDevice->getMemoryManager()->allocateGraphicsMemory(1024);
auto buffer = new MockBuffer<FamilyType>(context, 0, 1024, mockAlloc->getUnderlyingBuffer(), mockAlloc->getUnderlyingBuffer(),
mockAlloc, false, false, false);
if (mapOnGpu) {
buffer->setSharingHandler(new SharingHandler());
}
return std::unique_ptr<MockBuffer<FamilyType>>(buffer);
}
template <typename FamilyType>
std::unique_ptr<MockCmdQ<FamilyType>> createMockCmdQ() {
return std::unique_ptr<MockCmdQ<FamilyType>>(new MockCmdQ<FamilyType>(context, pDevice));
}
void SetUp() override {
DeviceFixture::SetUp();
context = new MockContext(pDevice);
}
void TearDown() override {
delete context;
DeviceFixture::TearDown();
}
MockContext *context = nullptr;
cl_int retVal = CL_INVALID_VALUE;
};
HWTEST_F(MultipleMapBufferTest, givenValidReadAndWriteBufferWhenMappedOnGpuThenAddMappedPtrAndRemoveOnUnmap) {
auto buffer = createMockBuffer<FamilyType>(true);
auto cmdQ = createMockCmdQ<FamilyType>();
EXPECT_FALSE(buffer->mappingOnCpuAllowed());
size_t offset = 1;
size_t size = 3;
void *mappedPtr = clEnqueueMapBuffer(cmdQ.get(), buffer.get(), CL_FALSE, CL_MAP_WRITE, offset, size, 0, nullptr, nullptr, nullptr);
EXPECT_NE(nullptr, mappedPtr);
EXPECT_EQ(1u, buffer->mapOperationsHandler.size());
EXPECT_EQ(cmdQ->readBufferCalled, 1u);
EXPECT_EQ(cmdQ->enqueueSize, size);
EXPECT_EQ(cmdQ->enqueueOffset, offset);
retVal = clEnqueueUnmapMemObject(cmdQ.get(), buffer.get(), mappedPtr, 0, nullptr, nullptr);
EXPECT_EQ(0u, buffer->mapOperationsHandler.size());
EXPECT_EQ(cmdQ->writeBufferCalled, 1u);
EXPECT_EQ(cmdQ->enqueueSize, size);
EXPECT_EQ(cmdQ->enqueueOffset, offset);
EXPECT_EQ(cmdQ->unmapPtr, mappedPtr);
}
HWTEST_F(MultipleMapBufferTest, givenReadOnlyMapWhenUnmappedOnGpuThenEnqueueMarker) {
auto buffer = createMockBuffer<FamilyType>(true);
auto cmdQ = createMockCmdQ<FamilyType>();
EXPECT_FALSE(buffer->mappingOnCpuAllowed());
size_t offset = 1;
size_t size = 3;
void *mappedPtr = clEnqueueMapBuffer(cmdQ.get(), buffer.get(), CL_FALSE, CL_MAP_READ, offset, size, 0, nullptr, nullptr, nullptr);
EXPECT_NE(nullptr, mappedPtr);
EXPECT_EQ(1u, buffer->mapOperationsHandler.size());
EXPECT_EQ(cmdQ->readBufferCalled, 1u);
retVal = clEnqueueUnmapMemObject(cmdQ.get(), buffer.get(), mappedPtr, 0, nullptr, nullptr);
EXPECT_EQ(0u, buffer->mapOperationsHandler.size());
EXPECT_EQ(cmdQ->writeBufferCalled, 0u);
EXPECT_EQ(cmdQ->enqueueMarkerCalled, 1u);
}
HWTEST_F(MultipleMapBufferTest, givenNotMappedPtrWhenUnmapedOnGpuThenReturnError) {
auto buffer = createMockBuffer<FamilyType>(true);
auto cmdQ = createMockCmdQ<FamilyType>();
EXPECT_FALSE(buffer->mappingOnCpuAllowed());
EXPECT_EQ(0u, buffer->mapOperationsHandler.size());
retVal = clEnqueueUnmapMemObject(cmdQ.get(), buffer.get(), buffer->getBasePtrForMap(), 0, nullptr, nullptr);
EXPECT_EQ(CL_INVALID_VALUE, retVal);
}
HWTEST_F(MultipleMapBufferTest, givenErrorFromReadBufferWhenMappedOnGpuThenDontAddMappedPtr) {
auto buffer = createMockBuffer<FamilyType>(true);
auto cmdQ = createMockCmdQ<FamilyType>();
EXPECT_FALSE(buffer->mappingOnCpuAllowed());
cmdQ->failOnReadBuffer = true;
size_t offset = 1;
size_t size = 3;
void *mappedPtr = clEnqueueMapBuffer(cmdQ.get(), buffer.get(), CL_FALSE, CL_MAP_READ, offset, size, 0, nullptr, nullptr, &retVal);
EXPECT_EQ(nullptr, mappedPtr);
EXPECT_EQ(CL_OUT_OF_RESOURCES, retVal);
EXPECT_EQ(0u, buffer->mapOperationsHandler.size());
}
HWTEST_F(MultipleMapBufferTest, givenErrorFromWriteBufferWhenUnmappedOnGpuThenDontRemoveMappedPtr) {
auto buffer = createMockBuffer<FamilyType>(true);
auto cmdQ = createMockCmdQ<FamilyType>();
EXPECT_FALSE(buffer->mappingOnCpuAllowed());
cmdQ->failOnWriteBuffer = true;
size_t offset = 1;
size_t size = 3;
void *mappedPtr = clEnqueueMapBuffer(cmdQ.get(), buffer.get(), CL_FALSE, CL_MAP_WRITE, offset, size, 0, nullptr, nullptr, &retVal);
EXPECT_NE(nullptr, mappedPtr);
EXPECT_EQ(1u, buffer->mapOperationsHandler.size());
retVal = clEnqueueUnmapMemObject(cmdQ.get(), buffer.get(), mappedPtr, 0, nullptr, nullptr);
EXPECT_EQ(1u, cmdQ->writeBufferCalled);
EXPECT_EQ(CL_OUT_OF_RESOURCES, retVal);
EXPECT_EQ(1u, buffer->mapOperationsHandler.size());
}
HWTEST_F(MultipleMapBufferTest, givenUnblockedQueueWhenMappedOnCpuThenAddMappedPtrAndRemoveOnUnmap) {
auto buffer = createMockBuffer<FamilyType>(false);
auto cmdQ = createMockCmdQ<FamilyType>();
EXPECT_TRUE(buffer->mappingOnCpuAllowed());
size_t offset = 1;
size_t size = 3;
void *mappedPtr = clEnqueueMapBuffer(cmdQ.get(), buffer.get(), CL_FALSE, CL_MAP_WRITE, offset, size, 0, nullptr, nullptr, &retVal);
EXPECT_NE(nullptr, mappedPtr);
EXPECT_EQ(1u, buffer->mapOperationsHandler.size());
EXPECT_EQ(1u, buffer->transferToHostPtrCalled);
EXPECT_EQ(buffer->copySize, size);
EXPECT_EQ(buffer->copyOffset, offset);
retVal = clEnqueueUnmapMemObject(cmdQ.get(), buffer.get(), mappedPtr, 0, nullptr, nullptr);
EXPECT_EQ(0u, buffer->mapOperationsHandler.size());
EXPECT_EQ(1u, buffer->transferFromHostPtrCalled);
EXPECT_EQ(buffer->copySize, size);
EXPECT_EQ(buffer->copyOffset, offset);
}
HWTEST_F(MultipleMapBufferTest, givenUnblockedQueueWhenReadOnlyMappedOnCpuThenDontMakeCpuCopy) {
auto buffer = createMockBuffer<FamilyType>(false);
auto cmdQ = createMockCmdQ<FamilyType>();
EXPECT_TRUE(buffer->mappingOnCpuAllowed());
size_t offset = 1;
size_t size = 3;
void *mappedPtr = clEnqueueMapBuffer(cmdQ.get(), buffer.get(), CL_FALSE, CL_MAP_READ, offset, size, 0, nullptr, nullptr, &retVal);
EXPECT_NE(nullptr, mappedPtr);
EXPECT_EQ(1u, buffer->mapOperationsHandler.size());
EXPECT_EQ(1u, buffer->transferToHostPtrCalled);
retVal = clEnqueueUnmapMemObject(cmdQ.get(), buffer.get(), mappedPtr, 0, nullptr, nullptr);
EXPECT_EQ(0u, buffer->mapOperationsHandler.size());
EXPECT_EQ(0u, buffer->transferFromHostPtrCalled);
}
HWTEST_F(MultipleMapBufferTest, givenBlockedQueueWhenMappedOnCpuThenAddMappedPtrAndRemoveOnUnmap) {
auto buffer = createMockBuffer<FamilyType>(false);
auto cmdQ = createMockCmdQ<FamilyType>();
EXPECT_TRUE(buffer->mappingOnCpuAllowed());
UserEvent mapEvent, unmapEvent;
cl_event clMapEvent = &mapEvent;
cl_event clUnmapEvent = &unmapEvent;
size_t offset = 1;
size_t size = 3;
void *mappedPtr = clEnqueueMapBuffer(cmdQ.get(), buffer.get(), CL_FALSE, CL_MAP_WRITE, offset, size, 1, &clMapEvent, nullptr, &retVal);
mapEvent.setStatus(CL_COMPLETE);
EXPECT_NE(nullptr, mappedPtr);
EXPECT_EQ(1u, buffer->mapOperationsHandler.size());
EXPECT_EQ(buffer->copySize, size);
EXPECT_EQ(buffer->copyOffset, offset);
EXPECT_EQ(1u, buffer->transferToHostPtrCalled);
retVal = clEnqueueUnmapMemObject(cmdQ.get(), buffer.get(), mappedPtr, 1, &clUnmapEvent, nullptr);
unmapEvent.setStatus(CL_COMPLETE);
EXPECT_EQ(0u, buffer->mapOperationsHandler.size());
EXPECT_EQ(buffer->copySize, size);
EXPECT_EQ(buffer->copyOffset, offset);
EXPECT_EQ(1u, buffer->transferFromHostPtrCalled);
}
HWTEST_F(MultipleMapBufferTest, givenBlockedQueueWhenMappedReadOnlyOnCpuThenDontMakeCpuCopy) {
auto buffer = createMockBuffer<FamilyType>(false);
auto cmdQ = createMockCmdQ<FamilyType>();
EXPECT_TRUE(buffer->mappingOnCpuAllowed());
UserEvent mapEvent, unmapEvent;
cl_event clMapEvent = &mapEvent;
cl_event clUnmapEvent = &unmapEvent;
size_t offset = 1;
size_t size = 3;
void *mappedPtr = clEnqueueMapBuffer(cmdQ.get(), buffer.get(), CL_FALSE, CL_MAP_READ, offset, size, 1, &clMapEvent, nullptr, &retVal);
mapEvent.setStatus(CL_COMPLETE);
EXPECT_NE(nullptr, mappedPtr);
EXPECT_EQ(1u, buffer->transferToHostPtrCalled);
EXPECT_EQ(1u, buffer->mapOperationsHandler.size());
retVal = clEnqueueUnmapMemObject(cmdQ.get(), buffer.get(), mappedPtr, 1, &clUnmapEvent, nullptr);
unmapEvent.setStatus(CL_COMPLETE);
EXPECT_EQ(0u, buffer->mapOperationsHandler.size());
EXPECT_EQ(0u, buffer->transferFromHostPtrCalled);
}
HWTEST_F(MultipleMapBufferTest, givenInvalidPtrWhenUnmappedOnCpuThenReturnError) {
auto buffer = createMockBuffer<FamilyType>(false);
auto cmdQ = createMockCmdQ<FamilyType>();
EXPECT_TRUE(buffer->mappingOnCpuAllowed());
retVal = clEnqueueUnmapMemObject(cmdQ.get(), buffer.get(), buffer->getBasePtrForMap(), 0, nullptr, nullptr);
EXPECT_EQ(CL_INVALID_VALUE, retVal);
}
HWTEST_F(MultipleMapBufferTest, givenMultimpleMapsWhenUnmappingThenRemoveCorrectPointers) {
auto buffer = createMockBuffer<FamilyType>(true);
auto cmdQ = createMockCmdQ<FamilyType>();
MapInfo mappedPtrs[3] = {
{nullptr, 1, {{1, 0, 0}}, {{1, 0, 0}}},
{nullptr, 1, {{2, 0, 0}}, {{2, 0, 0}}},
{nullptr, 1, {{5, 0, 0}}, {{5, 0, 0}}},
};
for (size_t i = 0; i < 3; i++) {
mappedPtrs[i].ptr = clEnqueueMapBuffer(cmdQ.get(), buffer.get(), CL_FALSE, CL_MAP_WRITE,
mappedPtrs[i].offset[0], mappedPtrs[i].size[0], 0, nullptr, nullptr, &retVal);
EXPECT_NE(nullptr, mappedPtrs[i].ptr);
EXPECT_EQ(i + 1, buffer->mapOperationsHandler.size());
EXPECT_EQ(cmdQ->enqueueSize, mappedPtrs[i].size[0]);
EXPECT_EQ(cmdQ->enqueueOffset, mappedPtrs[i].offset[0]);
}
// reordered unmap
clEnqueueUnmapMemObject(cmdQ.get(), buffer.get(), mappedPtrs[1].ptr, 0, nullptr, nullptr);
EXPECT_EQ(2u, buffer->mapOperationsHandler.size());
EXPECT_EQ(cmdQ->unmapPtr, mappedPtrs[1].ptr);
EXPECT_EQ(cmdQ->enqueueSize, mappedPtrs[1].size[0]);
EXPECT_EQ(cmdQ->enqueueOffset, mappedPtrs[1].offset[0]);
clEnqueueUnmapMemObject(cmdQ.get(), buffer.get(), mappedPtrs[2].ptr, 0, nullptr, nullptr);
EXPECT_EQ(1u, buffer->mapOperationsHandler.size());
EXPECT_EQ(cmdQ->unmapPtr, mappedPtrs[2].ptr);
EXPECT_EQ(cmdQ->enqueueSize, mappedPtrs[2].size[0]);
EXPECT_EQ(cmdQ->enqueueOffset, mappedPtrs[2].offset[0]);
clEnqueueUnmapMemObject(cmdQ.get(), buffer.get(), mappedPtrs[0].ptr, 0, nullptr, nullptr);
EXPECT_EQ(0u, buffer->mapOperationsHandler.size());
EXPECT_EQ(cmdQ->unmapPtr, mappedPtrs[0].ptr);
EXPECT_EQ(cmdQ->enqueueSize, mappedPtrs[0].size[0]);
EXPECT_EQ(cmdQ->enqueueOffset, mappedPtrs[0].offset[0]);
}
HWTEST_F(MultipleMapBufferTest, givenOverlapingPtrWhenMappingOnGpuForWriteThenReturnError) {
auto buffer = createMockBuffer<FamilyType>(true);
auto cmdQ = createMockCmdQ<FamilyType>();
EXPECT_FALSE(buffer->mappingOnCpuAllowed());
size_t offset = 1;
size_t size = 3;
void *mappedPtr = clEnqueueMapBuffer(cmdQ.get(), buffer.get(), CL_FALSE, CL_MAP_READ, offset, size, 0, nullptr, nullptr, &retVal);
EXPECT_NE(nullptr, mappedPtr);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(1u, buffer->mapOperationsHandler.size());
offset++;
void *mappedPtr2 = clEnqueueMapBuffer(cmdQ.get(), buffer.get(), CL_FALSE, CL_MAP_WRITE, offset, size, 0, nullptr, nullptr, &retVal);
EXPECT_EQ(nullptr, mappedPtr2);
EXPECT_EQ(CL_INVALID_OPERATION, retVal);
EXPECT_EQ(1u, buffer->mapOperationsHandler.size());
}
HWTEST_F(MultipleMapBufferTest, givenOverlapingPtrWhenMappingOnCpuForWriteThenReturnError) {
auto buffer = createMockBuffer<FamilyType>(false);
auto cmdQ = createMockCmdQ<FamilyType>();
EXPECT_TRUE(buffer->mappingOnCpuAllowed());
size_t offset = 1;
size_t size = 3;
void *mappedPtr = clEnqueueMapBuffer(cmdQ.get(), buffer.get(), CL_FALSE, CL_MAP_READ, offset, size, 0, nullptr, nullptr, &retVal);
EXPECT_NE(nullptr, mappedPtr);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(1u, buffer->mapOperationsHandler.size());
offset++;
void *mappedPtr2 = clEnqueueMapBuffer(cmdQ.get(), buffer.get(), CL_FALSE, CL_MAP_WRITE, offset, size, 0, nullptr, nullptr, &retVal);
EXPECT_EQ(nullptr, mappedPtr2);
EXPECT_EQ(CL_INVALID_OPERATION, retVal);
EXPECT_EQ(1u, buffer->mapOperationsHandler.size());
}

View File

@@ -0,0 +1,393 @@
/*
* Copyright (c) 2018, Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include "runtime/gmm_helper/gmm_helper.h"
#include "runtime/command_queue/command_queue_hw.h"
#include "unit_tests/fixtures/device_fixture.h"
#include "unit_tests/fixtures/image_fixture.h"
#include "unit_tests/mocks/mock_context.h"
#include "test.h"
using namespace OCLRT;
struct MultipleMapImageTest : public DeviceFixture, public ::testing::Test {
template <typename T>
struct MockImage : public ImageHw<T> {
using Image::mapOperationsHandler;
template <class... Params>
MockImage(Params... params) : ImageHw<T>(params...) {
this->createFunction = ImageHw<T>::create;
};
void transferDataToHostPtr(MemObjSizeArray &copySize, MemObjOffsetArray &copyOffset) override {
copyRegion = copySize;
copyOrigin = copyOffset;
transferToHostPtrCalled++;
};
void transferDataFromHostPtr(MemObjSizeArray &copySize, MemObjOffsetArray &copyOffset) override {
copyRegion = copySize;
copyOrigin = copyOffset;
transferFromHostPtrCalled++;
};
MemObjSizeArray copyRegion = {{0, 0, 0}};
MemObjOffsetArray copyOrigin = {{0, 0, 0}};
uint32_t transferToHostPtrCalled = 0;
uint32_t transferFromHostPtrCalled = 0;
};
template <typename T>
struct MockCmdQ : public CommandQueueHw<T> {
MockCmdQ(Context *context, Device *device) : CommandQueueHw<T>(context, device, 0) {}
cl_int enqueueReadImage(Image *srcImage, cl_bool blockingRead, const size_t *origin, const size_t *region, size_t rowPitch, size_t slicePitch, void *ptr,
cl_uint numEventsInWaitList, const cl_event *eventWaitList, cl_event *event) override {
enqueueRegion = {{region[0], region[1], region[2]}};
enqueueOrigin = {{origin[0], origin[1], origin[2]}};
readImageCalled++;
if (failOnReadImage) {
return CL_OUT_OF_RESOURCES;
}
return CommandQueueHw<T>::enqueueReadImage(srcImage, blockingRead, origin, region, rowPitch, slicePitch, ptr, numEventsInWaitList, eventWaitList, event);
}
cl_int enqueueWriteImage(Image *dstImage, cl_bool blockingWrite, const size_t *origin, const size_t *region, size_t inputRowPitch,
size_t inputSlicePitch, const void *ptr, cl_uint numEventsInWaitList, const cl_event *eventWaitList,
cl_event *event) override {
enqueueRegion = {{region[0], region[1], region[2]}};
enqueueOrigin = {{origin[0], origin[1], origin[2]}};
unmapPtr = ptr;
writeImageCalled++;
if (failOnWriteImage) {
return CL_OUT_OF_RESOURCES;
}
return CommandQueueHw<T>::enqueueWriteImage(dstImage, blockingWrite, origin, region, inputRowPitch, inputSlicePitch, ptr,
numEventsInWaitList, eventWaitList, event);
}
cl_int enqueueMarkerWithWaitList(cl_uint numEventsInWaitList, const cl_event *eventWaitList, cl_event *event) override {
enqueueMarkerCalled++;
return CommandQueueHw<T>::enqueueMarkerWithWaitList(numEventsInWaitList, eventWaitList, event);
}
uint32_t writeImageCalled = 0;
uint32_t readImageCalled = 0;
uint32_t enqueueMarkerCalled = 0;
bool failOnReadImage = false;
bool failOnWriteImage = false;
MemObjSizeArray enqueueRegion = {{0, 0, 0}};
MemObjOffsetArray enqueueOrigin = {{0, 0, 0}};
const void *unmapPtr = nullptr;
};
template <typename Traits, typename FamilyType>
std::unique_ptr<MockImage<FamilyType>> createMockImage() {
auto mockAlloc = pDevice->getMemoryManager()->allocateGraphicsMemory(1024);
auto tiledImage = Gmm::allowTiling(Traits::imageDesc);
auto surfaceFormat = Image::getSurfaceFormatFromTable(Traits::flags, &Traits::imageFormat);
auto img = new MockImage<FamilyType>(context, Traits::flags, 1024, Traits::hostPtr,
Traits::imageFormat, Traits::imageDesc, false, mockAlloc, false,
tiledImage, 0, surfaceFormat);
return std::unique_ptr<MockImage<FamilyType>>(img);
}
template <typename FamilyType>
std::unique_ptr<MockCmdQ<FamilyType>> createMockCmdQ() {
return std::unique_ptr<MockCmdQ<FamilyType>>(new MockCmdQ<FamilyType>(context, pDevice));
}
void SetUp() override {
DeviceFixture::SetUp();
context = new MockContext(pDevice);
}
void TearDown() override {
delete context;
DeviceFixture::TearDown();
}
MockContext *context = nullptr;
cl_int retVal = CL_INVALID_VALUE;
};
HWTEST_F(MultipleMapImageTest, givenValidReadAndWriteImageWhenMappedOnGpuThenAddMappedPtrAndRemoveOnUnmap) {
auto image = createMockImage<Image2dDefaults, FamilyType>();
auto cmdQ = createMockCmdQ<FamilyType>();
EXPECT_FALSE(image->mappingOnCpuAllowed());
MemObjOffsetArray origin = {{1, 2, 1}};
MemObjSizeArray region = {{3, 4, 1}};
void *mappedPtr = clEnqueueMapImage(cmdQ.get(), image.get(), CL_TRUE, CL_MAP_WRITE, &origin[0], &region[0], nullptr, nullptr, 0, nullptr, nullptr, &retVal);
EXPECT_NE(nullptr, mappedPtr);
EXPECT_EQ(1u, image->mapOperationsHandler.size());
EXPECT_EQ(cmdQ->enqueueRegion, region);
EXPECT_EQ(cmdQ->enqueueOrigin, origin);
EXPECT_EQ(cmdQ->readImageCalled, 1u);
retVal = clEnqueueUnmapMemObject(cmdQ.get(), image.get(), mappedPtr, 0, nullptr, nullptr);
EXPECT_EQ(0u, image->mapOperationsHandler.size());
EXPECT_EQ(cmdQ->enqueueRegion, region);
EXPECT_EQ(cmdQ->enqueueOrigin, origin);
EXPECT_EQ(cmdQ->unmapPtr, mappedPtr);
EXPECT_EQ(cmdQ->writeImageCalled, 1u);
}
HWTEST_F(MultipleMapImageTest, givenReadOnlyMapWhenUnmappedOnGpuThenEnqueueMarker) {
auto image = createMockImage<Image2dDefaults, FamilyType>();
auto cmdQ = createMockCmdQ<FamilyType>();
EXPECT_FALSE(image->mappingOnCpuAllowed());
MemObjOffsetArray origin = {{1, 2, 1}};
MemObjSizeArray region = {{3, 4, 1}};
void *mappedPtr = clEnqueueMapImage(cmdQ.get(), image.get(), CL_TRUE, CL_MAP_READ, &origin[0], &region[0], nullptr, nullptr, 0, nullptr, nullptr, &retVal);
EXPECT_NE(nullptr, mappedPtr);
EXPECT_EQ(1u, image->mapOperationsHandler.size());
EXPECT_EQ(cmdQ->enqueueRegion, region);
EXPECT_EQ(cmdQ->enqueueOrigin, origin);
EXPECT_EQ(cmdQ->readImageCalled, 1u);
retVal = clEnqueueUnmapMemObject(cmdQ.get(), image.get(), mappedPtr, 0, nullptr, nullptr);
EXPECT_EQ(0u, image->mapOperationsHandler.size());
EXPECT_EQ(cmdQ->writeImageCalled, 0u);
EXPECT_EQ(cmdQ->enqueueMarkerCalled, 1u);
}
HWTEST_F(MultipleMapImageTest, givenNotMappedPtrWhenUnmapedOnGpuThenReturnError) {
auto image = createMockImage<Image2dDefaults, FamilyType>();
auto cmdQ = createMockCmdQ<FamilyType>();
EXPECT_FALSE(image->mappingOnCpuAllowed());
EXPECT_EQ(0u, image->mapOperationsHandler.size());
retVal = clEnqueueUnmapMemObject(cmdQ.get(), image.get(), image->getBasePtrForMap(), 0, nullptr, nullptr);
EXPECT_EQ(CL_INVALID_VALUE, retVal);
}
HWTEST_F(MultipleMapImageTest, givenErrorFromReadImageWhenMappedOnGpuThenDontAddMappedPtr) {
auto image = createMockImage<Image2dDefaults, FamilyType>();
auto cmdQ = createMockCmdQ<FamilyType>();
EXPECT_FALSE(image->mappingOnCpuAllowed());
cmdQ->failOnReadImage = true;
size_t origin[] = {2, 1, 1};
size_t region[] = {2, 1, 1};
void *mappedPtr = clEnqueueMapImage(cmdQ.get(), image.get(), CL_TRUE, CL_MAP_READ, origin, region, nullptr, nullptr, 0, nullptr, nullptr, &retVal);
EXPECT_EQ(nullptr, mappedPtr);
EXPECT_EQ(CL_OUT_OF_RESOURCES, retVal);
EXPECT_EQ(0u, image->mapOperationsHandler.size());
}
HWTEST_F(MultipleMapImageTest, givenErrorFromWriteImageWhenUnmappedOnGpuThenDontRemoveMappedPtr) {
auto image = createMockImage<Image2dDefaults, FamilyType>();
auto cmdQ = createMockCmdQ<FamilyType>();
EXPECT_FALSE(image->mappingOnCpuAllowed());
cmdQ->failOnWriteImage = true;
size_t origin[] = {2, 1, 1};
size_t region[] = {2, 1, 1};
void *mappedPtr = clEnqueueMapImage(cmdQ.get(), image.get(), CL_TRUE, CL_MAP_WRITE, origin, region, nullptr, nullptr, 0, nullptr, nullptr, &retVal);
EXPECT_NE(nullptr, mappedPtr);
EXPECT_EQ(1u, image->mapOperationsHandler.size());
retVal = clEnqueueUnmapMemObject(cmdQ.get(), image.get(), mappedPtr, 0, nullptr, nullptr);
EXPECT_EQ(CL_OUT_OF_RESOURCES, retVal);
EXPECT_EQ(cmdQ->writeImageCalled, 1u);
EXPECT_EQ(1u, image->mapOperationsHandler.size());
}
HWTEST_F(MultipleMapImageTest, givenUnblockedQueueWhenMappedOnCpuThenAddMappedPtrAndRemoveOnUnmap) {
auto image = createMockImage<Image1dDefaults, FamilyType>();
auto cmdQ = createMockCmdQ<FamilyType>();
EXPECT_TRUE(image->mappingOnCpuAllowed());
MemObjOffsetArray origin = {{1, 2, 1}};
MemObjSizeArray region = {{3, 4, 1}};
void *mappedPtr = clEnqueueMapImage(cmdQ.get(), image.get(), CL_TRUE, CL_MAP_WRITE, &origin[0], &region[0], nullptr, nullptr, 0, nullptr, nullptr, &retVal);
EXPECT_NE(nullptr, mappedPtr);
EXPECT_EQ(1u, image->mapOperationsHandler.size());
EXPECT_EQ(1u, image->transferToHostPtrCalled);
EXPECT_EQ(image->copyRegion, region);
EXPECT_EQ(image->copyOrigin, origin);
retVal = clEnqueueUnmapMemObject(cmdQ.get(), image.get(), mappedPtr, 0, nullptr, nullptr);
EXPECT_EQ(0u, image->mapOperationsHandler.size());
EXPECT_EQ(1u, image->transferFromHostPtrCalled);
EXPECT_EQ(image->copyRegion, region);
EXPECT_EQ(image->copyOrigin, origin);
}
HWTEST_F(MultipleMapImageTest, givenUnblockedQueueWhenReadOnlyMappedOnCpuThenDontMakeCpuCopy) {
auto image = createMockImage<Image1dDefaults, FamilyType>();
auto cmdQ = createMockCmdQ<FamilyType>();
EXPECT_TRUE(image->mappingOnCpuAllowed());
MemObjOffsetArray origin = {{1, 2, 1}};
MemObjSizeArray region = {{3, 4, 1}};
void *mappedPtr = clEnqueueMapImage(cmdQ.get(), image.get(), CL_TRUE, CL_MAP_READ, &origin[0], &region[0], nullptr, nullptr, 0, nullptr, nullptr, &retVal);
EXPECT_NE(nullptr, mappedPtr);
EXPECT_EQ(1u, image->mapOperationsHandler.size());
EXPECT_EQ(1u, image->transferToHostPtrCalled);
EXPECT_EQ(image->copyRegion, region);
EXPECT_EQ(image->copyOrigin, origin);
retVal = clEnqueueUnmapMemObject(cmdQ.get(), image.get(), mappedPtr, 0, nullptr, nullptr);
EXPECT_EQ(0u, image->mapOperationsHandler.size());
EXPECT_EQ(0u, image->transferFromHostPtrCalled);
}
HWTEST_F(MultipleMapImageTest, givenBlockedQueueWhenMappedOnCpuThenAddMappedPtrAndRemoveOnUnmap) {
auto image = createMockImage<Image1dDefaults, FamilyType>();
auto cmdQ = createMockCmdQ<FamilyType>();
EXPECT_TRUE(image->mappingOnCpuAllowed());
UserEvent mapEvent, unmapEvent;
cl_event clMapEvent = &mapEvent;
cl_event clUnmapEvent = &unmapEvent;
MemObjOffsetArray origin = {{1, 2, 1}};
MemObjSizeArray region = {{3, 4, 1}};
void *mappedPtr = clEnqueueMapImage(cmdQ.get(), image.get(), CL_FALSE, CL_MAP_WRITE, &origin[0], &region[0], nullptr, nullptr, 1, &clMapEvent, nullptr, &retVal);
mapEvent.setStatus(CL_COMPLETE);
EXPECT_NE(nullptr, mappedPtr);
EXPECT_EQ(1u, image->transferToHostPtrCalled);
EXPECT_EQ(1u, image->mapOperationsHandler.size());
EXPECT_EQ(image->copyRegion, region);
EXPECT_EQ(image->copyOrigin, origin);
retVal = clEnqueueUnmapMemObject(cmdQ.get(), image.get(), mappedPtr, 1, &clUnmapEvent, nullptr);
unmapEvent.setStatus(CL_COMPLETE);
EXPECT_EQ(0u, image->mapOperationsHandler.size());
EXPECT_EQ(1u, image->transferFromHostPtrCalled);
EXPECT_EQ(image->copyRegion, region);
EXPECT_EQ(image->copyOrigin, origin);
}
HWTEST_F(MultipleMapImageTest, givenBlockedQueueWhenMappedReadOnlyOnCpuThenDontMakeCpuCopy) {
auto image = createMockImage<Image1dDefaults, FamilyType>();
auto cmdQ = createMockCmdQ<FamilyType>();
EXPECT_TRUE(image->mappingOnCpuAllowed());
UserEvent mapEvent, unmapEvent;
cl_event clMapEvent = &mapEvent;
cl_event clUnmapEvent = &unmapEvent;
MemObjOffsetArray origin = {{1, 2, 1}};
MemObjSizeArray region = {{3, 4, 1}};
void *mappedPtr = clEnqueueMapImage(cmdQ.get(), image.get(), CL_FALSE, CL_MAP_READ, &origin[0], &region[0], nullptr, nullptr, 1, &clMapEvent, nullptr, &retVal);
mapEvent.setStatus(CL_COMPLETE);
EXPECT_NE(nullptr, mappedPtr);
EXPECT_EQ(1u, image->transferToHostPtrCalled);
EXPECT_EQ(1u, image->mapOperationsHandler.size());
EXPECT_EQ(image->copyRegion, region);
EXPECT_EQ(image->copyOrigin, origin);
retVal = clEnqueueUnmapMemObject(cmdQ.get(), image.get(), mappedPtr, 1, &clUnmapEvent, nullptr);
unmapEvent.setStatus(CL_COMPLETE);
EXPECT_EQ(0u, image->mapOperationsHandler.size());
EXPECT_EQ(0u, image->transferFromHostPtrCalled);
}
HWTEST_F(MultipleMapImageTest, givenInvalidPtrWhenUnmappedOnCpuThenReturnError) {
auto image = createMockImage<Image1dDefaults, FamilyType>();
auto cmdQ = createMockCmdQ<FamilyType>();
EXPECT_TRUE(image->mappingOnCpuAllowed());
retVal = clEnqueueUnmapMemObject(cmdQ.get(), image.get(), image->getBasePtrForMap(), 0, nullptr, nullptr);
EXPECT_EQ(CL_INVALID_VALUE, retVal);
}
HWTEST_F(MultipleMapImageTest, givenMultimpleMapsWhenUnmappingThenRemoveCorrectPointers) {
auto image = createMockImage<Image3dDefaults, FamilyType>();
auto cmdQ = createMockCmdQ<FamilyType>();
MapInfo mappedPtrs[3] = {
{nullptr, 1, {{1, 1, 1}}, {{1, 1, 1}}},
{nullptr, 1, {{4, 4, 2}}, {{4, 4, 4}}},
{nullptr, 1, {{10, 10, 10}}, {{10, 10, 10}}}};
for (size_t i = 0; i < 3; i++) {
mappedPtrs[i].ptr = clEnqueueMapImage(cmdQ.get(), image.get(), CL_TRUE, CL_MAP_WRITE, &mappedPtrs[i].offset[0], &mappedPtrs[i].size[0],
nullptr, nullptr, 0, nullptr, nullptr, &retVal);
EXPECT_NE(nullptr, mappedPtrs[i].ptr);
EXPECT_EQ(i + 1, image->mapOperationsHandler.size());
EXPECT_EQ(cmdQ->enqueueRegion, mappedPtrs[i].size);
EXPECT_EQ(cmdQ->enqueueOrigin, mappedPtrs[i].offset);
}
// reordered unmap
clEnqueueUnmapMemObject(cmdQ.get(), image.get(), mappedPtrs[1].ptr, 0, nullptr, nullptr);
EXPECT_EQ(2u, image->mapOperationsHandler.size());
EXPECT_EQ(cmdQ->unmapPtr, mappedPtrs[1].ptr);
EXPECT_EQ(cmdQ->enqueueRegion, mappedPtrs[1].size);
EXPECT_EQ(cmdQ->enqueueOrigin, mappedPtrs[1].offset);
clEnqueueUnmapMemObject(cmdQ.get(), image.get(), mappedPtrs[2].ptr, 0, nullptr, nullptr);
EXPECT_EQ(1u, image->mapOperationsHandler.size());
EXPECT_EQ(cmdQ->unmapPtr, mappedPtrs[2].ptr);
EXPECT_EQ(cmdQ->enqueueRegion, mappedPtrs[2].size);
EXPECT_EQ(cmdQ->enqueueOrigin, mappedPtrs[2].offset);
clEnqueueUnmapMemObject(cmdQ.get(), image.get(), mappedPtrs[0].ptr, 0, nullptr, nullptr);
EXPECT_EQ(0u, image->mapOperationsHandler.size());
EXPECT_EQ(cmdQ->unmapPtr, mappedPtrs[0].ptr);
EXPECT_EQ(cmdQ->enqueueRegion, mappedPtrs[0].size);
EXPECT_EQ(cmdQ->enqueueOrigin, mappedPtrs[0].offset);
}
HWTEST_F(MultipleMapImageTest, givenOverlapingPtrWhenMappingOnGpuForWriteThenReturnError) {
auto image = createMockImage<Image2dDefaults, FamilyType>();
auto cmdQ = createMockCmdQ<FamilyType>();
EXPECT_FALSE(image->mappingOnCpuAllowed());
MemObjOffsetArray origin = {{1, 2, 1}};
MemObjSizeArray region = {{3, 4, 1}};
void *mappedPtr = clEnqueueMapImage(cmdQ.get(), image.get(), CL_TRUE, CL_MAP_READ, &origin[0], &region[0], nullptr, nullptr, 0, nullptr, nullptr, &retVal);
EXPECT_NE(nullptr, mappedPtr);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(1u, image->mapOperationsHandler.size());
origin[0]++;
void *mappedPtr2 = clEnqueueMapImage(cmdQ.get(), image.get(), CL_TRUE, CL_MAP_WRITE, &origin[0], &region[0], nullptr, nullptr, 0, nullptr, nullptr, &retVal);
EXPECT_EQ(nullptr, mappedPtr2);
EXPECT_EQ(CL_INVALID_OPERATION, retVal);
EXPECT_EQ(1u, image->mapOperationsHandler.size());
}
HWTEST_F(MultipleMapImageTest, givenOverlapingPtrWhenMappingOnCpuForWriteThenReturnError) {
auto image = createMockImage<Image1dDefaults, FamilyType>();
auto cmdQ = createMockCmdQ<FamilyType>();
EXPECT_TRUE(image->mappingOnCpuAllowed());
MemObjOffsetArray origin = {{1, 2, 1}};
MemObjSizeArray region = {{3, 4, 1}};
void *mappedPtr = clEnqueueMapImage(cmdQ.get(), image.get(), CL_TRUE, CL_MAP_READ, &origin[0], &region[0], nullptr, nullptr, 0, nullptr, nullptr, &retVal);
EXPECT_NE(nullptr, mappedPtr);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(1u, image->mapOperationsHandler.size());
origin[0]++;
void *mappedPtr2 = clEnqueueMapImage(cmdQ.get(), image.get(), CL_TRUE, CL_MAP_WRITE, &origin[0], &region[0], nullptr, nullptr, 0, nullptr, nullptr, &retVal);
EXPECT_EQ(nullptr, mappedPtr2);
EXPECT_EQ(CL_INVALID_OPERATION, retVal);
EXPECT_EQ(1u, image->mapOperationsHandler.size());
}

View File

@@ -633,7 +633,9 @@ TEST_F(InternalsEventTest, processBlockedCommandsMapOperation) {
auto &csr = pDevice->getCommandStreamReceiver(); auto &csr = pDevice->getCommandStreamReceiver();
auto buffer = new MockBuffer; auto buffer = new MockBuffer;
event.setCommand(std::unique_ptr<Command>(new CommandMapUnmap(MAP, *buffer, csr, *pCmdQ))); MemObjSizeArray size = {{1, 1, 1}};
MemObjOffsetArray offset = {{0, 0, 0}};
event.setCommand(std::unique_ptr<Command>(new CommandMapUnmap(MAP, *buffer, size, offset, false, csr, *pCmdQ)));
auto taskLevelBefore = csr.peekTaskLevel(); auto taskLevelBefore = csr.peekTaskLevel();
@@ -653,7 +655,9 @@ TEST_F(InternalsEventTest, processBlockedCommandsMapOperationNonZeroCopyBuffer)
auto &csr = pDevice->getCommandStreamReceiver(); auto &csr = pDevice->getCommandStreamReceiver();
auto buffer = new UnalignedBuffer; auto buffer = new UnalignedBuffer;
event.setCommand(std::unique_ptr<Command>(new CommandMapUnmap(MAP, *buffer, csr, *pCmdQ))); MemObjSizeArray size = {{1, 1, 1}};
MemObjOffsetArray offset = {{0, 0, 0}};
event.setCommand(std::unique_ptr<Command>(new CommandMapUnmap(MAP, *buffer, size, offset, false, csr, *pCmdQ)));
auto taskLevelBefore = csr.peekTaskLevel(); auto taskLevelBefore = csr.peekTaskLevel();
@@ -738,7 +742,9 @@ TEST_F(InternalsEventTest, GIVENProfilingWHENMapOperationTHENTimesSet) {
auto &csr = pDevice->getCommandStreamReceiver(); auto &csr = pDevice->getCommandStreamReceiver();
UnalignedBuffer buffer; UnalignedBuffer buffer;
event->setCommand(std::unique_ptr<Command>(new CommandMapUnmap(MAP, buffer, csr, *pCmdQ))); MemObjSizeArray size = {{1, 1, 1}};
MemObjOffsetArray offset = {{0, 0, 0}};
event->setCommand(std::unique_ptr<Command>(new CommandMapUnmap(MAP, buffer, size, offset, false, csr, *pCmdQ)));
auto taskLevelBefore = csr.peekTaskLevel(); auto taskLevelBefore = csr.peekTaskLevel();
@@ -762,7 +768,9 @@ TEST_F(InternalsEventTest, processBlockedCommandsUnMapOperation) {
auto &csr = pDevice->getCommandStreamReceiver(); auto &csr = pDevice->getCommandStreamReceiver();
auto buffer = new UnalignedBuffer; auto buffer = new UnalignedBuffer;
event.setCommand(std::unique_ptr<Command>(new CommandMapUnmap(UNMAP, *buffer, csr, *pCmdQ))); MemObjSizeArray size = {{1, 1, 1}};
MemObjOffsetArray offset = {{0, 0, 0}};
event.setCommand(std::unique_ptr<Command>(new CommandMapUnmap(UNMAP, *buffer, size, offset, false, csr, *pCmdQ)));
auto taskLevelBefore = csr.peekTaskLevel(); auto taskLevelBefore = csr.peekTaskLevel();
@@ -783,7 +791,9 @@ TEST_F(InternalsEventTest, processBlockedCommandsUnMapOperationNonZeroCopyBuffer
auto &csr = pDevice->getCommandStreamReceiver(); auto &csr = pDevice->getCommandStreamReceiver();
auto buffer = new UnalignedBuffer; auto buffer = new UnalignedBuffer;
event.setCommand(std::unique_ptr<Command>(new CommandMapUnmap(UNMAP, *buffer, csr, *pCmdQ))); MemObjSizeArray size = {{1, 1, 1}};
MemObjOffsetArray offset = {{0, 0, 0}};
event.setCommand(std::unique_ptr<Command>(new CommandMapUnmap(UNMAP, *buffer, size, offset, false, csr, *pCmdQ)));
auto taskLevelBefore = csr.peekTaskLevel(); auto taskLevelBefore = csr.peekTaskLevel();
@@ -939,7 +949,9 @@ HWTEST_F(InternalsEventTest, GivenBufferWithoutZeroCopyOnCommandMapOrUnmapFlushe
MockCsr<FamilyType> csr(executionStamp); MockCsr<FamilyType> csr(executionStamp);
csr.setMemoryManager(pDevice->getMemoryManager()); csr.setMemoryManager(pDevice->getMemoryManager());
auto commandMap = std::unique_ptr<Command>(new CommandMapUnmap(MAP, buffer, csr, *pCmdQ)); MemObjSizeArray size = {{4, 1, 1}};
MemObjOffsetArray offset = {{0, 0, 0}};
auto commandMap = std::unique_ptr<Command>(new CommandMapUnmap(MAP, buffer, size, offset, false, csr, *pCmdQ));
EXPECT_EQ(0, executionStamp); EXPECT_EQ(0, executionStamp);
EXPECT_EQ(-1, csr.flushTaskStamp); EXPECT_EQ(-1, csr.flushTaskStamp);
EXPECT_EQ(-1, buffer.dataTransferedStamp); EXPECT_EQ(-1, buffer.dataTransferedStamp);
@@ -957,7 +969,8 @@ HWTEST_F(InternalsEventTest, GivenBufferWithoutZeroCopyOnCommandMapOrUnmapFlushe
csr.flushTaskStamp = -1; csr.flushTaskStamp = -1;
buffer.dataTransferedStamp = -1; buffer.dataTransferedStamp = -1;
buffer.swapCopyDirection(); buffer.swapCopyDirection();
auto commandUnMap = std::unique_ptr<Command>(new CommandMapUnmap(UNMAP, buffer, csr, *pCmdQ));
auto commandUnMap = std::unique_ptr<Command>(new CommandMapUnmap(UNMAP, buffer, size, offset, false, csr, *pCmdQ));
EXPECT_EQ(0, executionStamp); EXPECT_EQ(0, executionStamp);
EXPECT_EQ(-1, csr.flushTaskStamp); EXPECT_EQ(-1, csr.flushTaskStamp);
EXPECT_EQ(-1, buffer.dataTransferedStamp); EXPECT_EQ(-1, buffer.dataTransferedStamp);

View File

@@ -39,7 +39,10 @@ TEST(CommandTest, mapUnmapSubmitWithoutTerminateFlagFlushesCsr) {
MockBuffer buffer; MockBuffer buffer;
auto initialTaskCount = csr.peekTaskCount(); auto initialTaskCount = csr.peekTaskCount();
std::unique_ptr<Command> command(new CommandMapUnmap(MapOperationType::MAP, buffer, csr, *cmdQ.get()));
MemObjSizeArray size = {{1, 1, 1}};
MemObjOffsetArray offset = {{0, 0, 0}};
std::unique_ptr<Command> command(new CommandMapUnmap(MapOperationType::MAP, buffer, size, offset, false, csr, *cmdQ.get()));
CompletionStamp completionStamp = command->submit(20, false); CompletionStamp completionStamp = command->submit(20, false);
auto expectedTaskCount = initialTaskCount + 1; auto expectedTaskCount = initialTaskCount + 1;
@@ -53,7 +56,10 @@ TEST(CommandTest, mapUnmapSubmitWithTerminateFlagAbortsFlush) {
MockBuffer buffer; MockBuffer buffer;
auto initialTaskCount = csr.peekTaskCount(); auto initialTaskCount = csr.peekTaskCount();
std::unique_ptr<Command> command(new CommandMapUnmap(MapOperationType::MAP, buffer, csr, *cmdQ.get()));
MemObjSizeArray size = {{1, 1, 1}};
MemObjOffsetArray offset = {{0, 0, 0}};
std::unique_ptr<Command> command(new CommandMapUnmap(MapOperationType::MAP, buffer, size, offset, false, csr, *cmdQ.get()));
CompletionStamp completionStamp = command->submit(20, true); CompletionStamp completionStamp = command->submit(20, true);
auto submitTaskCount = csr.peekTaskCount(); auto submitTaskCount = csr.peekTaskCount();

View File

@@ -43,6 +43,7 @@ set(IGDRCL_SRCS_tests_mem_obj
"${CMAKE_CURRENT_SOURCE_DIR}/image_array_size_tests.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/image_array_size_tests.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/image2d_from_buffer_tests.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/image2d_from_buffer_tests.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/image_tiled_tests.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/image_tiled_tests.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/map_operations_handler_tests.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/mem_obj_tests.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/mem_obj_tests.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/mem_obj_destruction_tests.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/mem_obj_destruction_tests.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/nv12_image_tests.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/nv12_image_tests.cpp"

View File

@@ -44,6 +44,28 @@ TEST(Buffer, FromCL_nullptr_returnsNullPtr) {
EXPECT_EQ(nullptr, castToObject<Buffer>(nullptr)); EXPECT_EQ(nullptr, castToObject<Buffer>(nullptr));
} }
TEST(Buffer, giveBufferWhenAskedForPtrOffsetForMappingThenReturnCorrectValue) {
MockContext ctx;
cl_int retVal;
std::unique_ptr<Buffer> buffer(Buffer::create(&ctx, 0, 1, nullptr, retVal));
MemObjOffsetArray offset = {{4, 5, 6}};
auto retOffset = buffer->calculateOffsetForMapping(offset);
EXPECT_EQ(offset[0], retOffset);
}
TEST(Buffer, givenBufferWhenAskedForPtrLengthThenReturnCorrectValue) {
MockContext ctx;
cl_int retVal;
std::unique_ptr<Buffer> buffer(Buffer::create(&ctx, 0, 1, nullptr, retVal));
MemObjSizeArray size = {{4, 5, 6}};
auto retOffset = buffer->calculateMappedPtrLength(size);
EXPECT_EQ(size[0], retOffset);
}
class BufferTest : public DeviceFixture, class BufferTest : public DeviceFixture,
public testing::TestWithParam<uint64_t /*cl_mem_flags*/> { public testing::TestWithParam<uint64_t /*cl_mem_flags*/> {
public: public:
@@ -827,7 +849,7 @@ HWTEST_F(BufferUnmapTest, givenBufferWithSharingHandlerWhenUnmappingThenUseEnque
buffer->setSharingHandler(new SharingHandler()); buffer->setSharingHandler(new SharingHandler());
EXPECT_NE(nullptr, buffer->peekSharingHandler()); EXPECT_NE(nullptr, buffer->peekSharingHandler());
auto mappedPtr = clEnqueueMapBuffer(&cmdQ, buffer.get(), CL_TRUE, CL_MAP_READ, 0, 1, 0, nullptr, nullptr, &retVal); auto mappedPtr = clEnqueueMapBuffer(&cmdQ, buffer.get(), CL_TRUE, CL_MAP_WRITE, 0, 1, 0, nullptr, nullptr, &retVal);
EXPECT_EQ(CL_SUCCESS, retVal); EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(0u, cmdQ.EnqueueWriteBufferCounter); EXPECT_EQ(0u, cmdQ.EnqueueWriteBufferCounter);
@@ -863,9 +885,9 @@ TEST_F(BufferTransferTests, givenBufferWhenTransferToHostPtrCalledThenCopyReques
MockContext context(pDevice); MockContext context(pDevice);
auto retVal = CL_SUCCESS; auto retVal = CL_SUCCESS;
const size_t bufferSize = 100; const size_t bufferSize = 100;
size_t copyOffset = 20;
size_t copySize = 10;
size_t ignoredParam = 123; size_t ignoredParam = 123;
MemObjOffsetArray copyOffset = {{20, ignoredParam, ignoredParam}};
MemObjSizeArray copySize = {{10, ignoredParam, ignoredParam}};
uint8_t hostPtr[bufferSize] = {}; uint8_t hostPtr[bufferSize] = {};
uint8_t expectedHostPtr[bufferSize] = {}; uint8_t expectedHostPtr[bufferSize] = {};
@@ -875,20 +897,20 @@ TEST_F(BufferTransferTests, givenBufferWhenTransferToHostPtrCalledThenCopyReques
auto srcPtr = buffer->getCpuAddress(); auto srcPtr = buffer->getCpuAddress();
EXPECT_NE(srcPtr, hostPtr); EXPECT_NE(srcPtr, hostPtr);
memset(srcPtr, 123, bufferSize); memset(srcPtr, 123, bufferSize);
memset(ptrOffset(expectedHostPtr, copyOffset), 123, copySize); memset(ptrOffset(expectedHostPtr, copyOffset[0]), 123, copySize[0]);
buffer->transferDataToHostPtr({{copySize, ignoredParam, ignoredParam}}, {{copyOffset, ignoredParam, ignoredParam}}); buffer->transferDataToHostPtr(copySize, copyOffset);
EXPECT_TRUE(memcmp(hostPtr, expectedHostPtr, copySize) == 0); EXPECT_TRUE(memcmp(hostPtr, expectedHostPtr, copySize[0]) == 0);
} }
TEST_F(BufferTransferTests, givenBufferWhenTransferFromHostPtrCalledThenCopyRequestedSizeAndOffsetOnly) { TEST_F(BufferTransferTests, givenBufferWhenTransferFromHostPtrCalledThenCopyRequestedSizeAndOffsetOnly) {
MockContext context(pDevice); MockContext context(pDevice);
auto retVal = CL_SUCCESS; auto retVal = CL_SUCCESS;
const size_t bufferSize = 100; const size_t bufferSize = 100;
size_t copyOffset = 20;
size_t copySize = 10;
size_t ignoredParam = 123; size_t ignoredParam = 123;
MemObjOffsetArray copyOffset = {{20, ignoredParam, ignoredParam}};
MemObjSizeArray copySize = {{10, ignoredParam, ignoredParam}};
uint8_t hostPtr[bufferSize] = {}; uint8_t hostPtr[bufferSize] = {};
uint8_t expectedBufferMemory[bufferSize] = {}; uint8_t expectedBufferMemory[bufferSize] = {};
@@ -897,9 +919,9 @@ TEST_F(BufferTransferTests, givenBufferWhenTransferFromHostPtrCalledThenCopyRequ
EXPECT_NE(buffer->getCpuAddress(), hostPtr); EXPECT_NE(buffer->getCpuAddress(), hostPtr);
memset(hostPtr, 123, bufferSize); memset(hostPtr, 123, bufferSize);
memset(ptrOffset(expectedBufferMemory, copyOffset), 123, copySize); memset(ptrOffset(expectedBufferMemory, copyOffset[0]), 123, copySize[0]);
buffer->transferDataFromHostPtr({{copySize, ignoredParam, ignoredParam}}, {{copyOffset, ignoredParam, ignoredParam}}); buffer->transferDataFromHostPtr(copySize, copyOffset);
EXPECT_TRUE(memcmp(expectedBufferMemory, buffer->getCpuAddress(), copySize) == 0); EXPECT_TRUE(memcmp(expectedBufferMemory, buffer->getCpuAddress(), copySize[0]) == 0);
} }

View File

@@ -70,10 +70,11 @@ class ImageUnmapTest : public ::testing::Test {
HWTEST_F(ImageUnmapTest, givenImageWhenUnmapMemObjIsCalledThenEnqueueNonBlockingMapImage) { HWTEST_F(ImageUnmapTest, givenImageWhenUnmapMemObjIsCalledThenEnqueueNonBlockingMapImage) {
std::unique_ptr<MyMockCommandQueue<FamilyType>> commandQueue(new MyMockCommandQueue<FamilyType>(&context)); std::unique_ptr<MyMockCommandQueue<FamilyType>> commandQueue(new MyMockCommandQueue<FamilyType>(&context));
void *ptr = alignedMalloc(MemoryConstants::cacheLineSize, MemoryConstants::cacheLineSize); void *ptr = alignedMalloc(MemoryConstants::cacheLineSize, MemoryConstants::cacheLineSize);
size_t origin[3] = {0, 0, 0}; MemObjOffsetArray origin = {{0, 0, 0}};
size_t region[3] = {1, 1, 1}; MemObjSizeArray region = {{1, 1, 1}};
image->setAllocatedMapPtr(ptr); image->setAllocatedMapPtr(ptr);
image->setMapInfo(ptr, region, origin); cl_map_flags mapFlags = CL_MAP_WRITE;
image->addMappedPtr(ptr, 1, mapFlags, region, origin);
commandQueue->enqueueUnmapMemObject(image.get(), ptr, 0, nullptr, nullptr); commandQueue->enqueueUnmapMemObject(image.get(), ptr, 0, nullptr, nullptr);
EXPECT_EQ(ptr, commandQueue->passedPtr); EXPECT_EQ(ptr, commandQueue->passedPtr);
EXPECT_EQ((cl_bool)CL_FALSE, commandQueue->passedBlockingWrite); EXPECT_EQ((cl_bool)CL_FALSE, commandQueue->passedBlockingWrite);
@@ -83,13 +84,23 @@ HWTEST_F(ImageUnmapTest, givenImageWhenUnmapMemObjIsCalledThenEnqueueNonBlocking
HWTEST_F(ImageUnmapTest, givenImageWhenUnmapMemObjIsCalledWithMemUseHostPtrAndWithoutEventsThenFinishIsCalled) { HWTEST_F(ImageUnmapTest, givenImageWhenUnmapMemObjIsCalledWithMemUseHostPtrAndWithoutEventsThenFinishIsCalled) {
std::unique_ptr<MyMockCommandQueue<FamilyType>> commandQueue(new MyMockCommandQueue<FamilyType>(&context)); std::unique_ptr<MyMockCommandQueue<FamilyType>> commandQueue(new MyMockCommandQueue<FamilyType>(&context));
image.reset(ImageHelper<ImageUseHostPtr<Image3dDefaults>>::create(&context)); image.reset(ImageHelper<ImageUseHostPtr<Image3dDefaults>>::create(&context));
commandQueue->enqueueUnmapMemObject(image.get(), nullptr, 0, nullptr, nullptr); auto ptr = image->getBasePtrForMap();
MemObjOffsetArray origin = {{0, 0, 0}};
MemObjSizeArray region = {{1, 1, 1}};
cl_map_flags mapFlags = CL_MAP_WRITE;
image->addMappedPtr(ptr, 1, mapFlags, region, origin);
commandQueue->enqueueUnmapMemObject(image.get(), ptr, 0, nullptr, nullptr);
EXPECT_EQ(1u, commandQueue->finishCalled); EXPECT_EQ(1u, commandQueue->finishCalled);
} }
HWTEST_F(ImageUnmapTest, givenImageWhenUnmapMemObjIsCalledWithoutMemUseHostPtrThenFinishIsCalled) { HWTEST_F(ImageUnmapTest, givenImageWhenUnmapMemObjIsCalledWithoutMemUseHostPtrThenFinishIsCalled) {
std::unique_ptr<MyMockCommandQueue<FamilyType>> commandQueue(new MyMockCommandQueue<FamilyType>(&context)); std::unique_ptr<MyMockCommandQueue<FamilyType>> commandQueue(new MyMockCommandQueue<FamilyType>(&context));
commandQueue->enqueueUnmapMemObject(image.get(), nullptr, 0, nullptr, nullptr); auto ptr = image->getBasePtrForMap();
MemObjOffsetArray origin = {{0, 0, 0}};
MemObjSizeArray region = {{1, 1, 1}};
cl_map_flags mapFlags = CL_MAP_WRITE;
image->addMappedPtr(ptr, 2, mapFlags, region, origin);
commandQueue->enqueueUnmapMemObject(image.get(), ptr, 0, nullptr, nullptr);
EXPECT_EQ(1u, commandQueue->finishCalled); EXPECT_EQ(1u, commandQueue->finishCalled);
} }
@@ -110,7 +121,12 @@ HWTEST_F(ImageUnmapTest, givenImageWhenUnmapMemObjIsCalledWithMemUseHostPtrAndWi
MockEvent<UserEvent> mockEvent(&context); MockEvent<UserEvent> mockEvent(&context);
mockEvent.setStatus(0); mockEvent.setStatus(0);
cl_event clEvent = &mockEvent; cl_event clEvent = &mockEvent;
commandQueue->enqueueUnmapMemObject(image.get(), nullptr, 1, &clEvent, nullptr); auto ptr = image->getBasePtrForMap();
MemObjOffsetArray origin = {{0, 0, 0}};
MemObjSizeArray region = {{1, 1, 1}};
cl_map_flags mapFlags = CL_MAP_WRITE;
image->addMappedPtr(ptr, 1, mapFlags, region, origin);
commandQueue->enqueueUnmapMemObject(image.get(), ptr, 1, &clEvent, nullptr);
EXPECT_EQ(1u, commandQueue->finishCalled); EXPECT_EQ(1u, commandQueue->finishCalled);
} }

View File

@@ -770,8 +770,9 @@ TEST_F(ImageTransfer, GivenNonZeroCopyImageWhenDataTransferedFromHostPtrToMemSto
memset((char *)unalignedHostPtr + imageSize, 2, 100 - 4); memset((char *)unalignedHostPtr + imageSize, 2, 100 - 4);
auto &imgDesc = imageNonZeroCopy->getImageDesc(); auto &imgDesc = imageNonZeroCopy->getImageDesc();
imageNonZeroCopy->transferDataFromHostPtr({{imgDesc.image_width, imgDesc.image_height, imgDesc.image_depth}}, MemObjOffsetArray copyOffset = {{0, 0, 0}};
{{0, 0, 0}}); MemObjSizeArray copySize = {{imgDesc.image_width, imgDesc.image_height, imgDesc.image_depth}};
imageNonZeroCopy->transferDataFromHostPtr(copySize, copyOffset);
void *foundData = memchr(memoryStorage, 2, memoryStorageSize); void *foundData = memchr(memoryStorage, 2, memoryStorageSize);
EXPECT_EQ(0, foundData); EXPECT_EQ(0, foundData);
@@ -805,8 +806,9 @@ TEST_F(ImageTransfer, GivenNonZeroCopyNonZeroRowPitchImageWhenDataIsTransferedFr
memset((char *)unalignedHostPtr + imageSize, 2, 100 - 4); memset((char *)unalignedHostPtr + imageSize, 2, 100 - 4);
auto &imgDesc = imageNonZeroCopy->getImageDesc(); auto &imgDesc = imageNonZeroCopy->getImageDesc();
imageNonZeroCopy->transferDataFromHostPtr({{imgDesc.image_width, imgDesc.image_height, imgDesc.image_depth}}, MemObjOffsetArray copyOffset = {{0, 0, 0}};
{{0, 0, 0}}); MemObjSizeArray copySize = {{imgDesc.image_width, imgDesc.image_height, imgDesc.image_depth}};
imageNonZeroCopy->transferDataFromHostPtr(copySize, copyOffset);
void *foundData = memchr(memoryStorage, 2, memoryStorageSize); void *foundData = memchr(memoryStorage, 2, memoryStorageSize);
EXPECT_EQ(0, foundData); EXPECT_EQ(0, foundData);
@@ -863,8 +865,9 @@ TEST_F(ImageTransfer, GivenNonZeroCopyNonZeroRowPitchWithExtraBytes1DArrayImageW
if (run == 1) { if (run == 1) {
auto &imgDesc = imageNonZeroCopy->getImageDesc(); auto &imgDesc = imageNonZeroCopy->getImageDesc();
imageNonZeroCopy->transferDataFromHostPtr({{imgDesc.image_width, imgDesc.image_height, imgDesc.image_depth}}, MemObjOffsetArray copyOffset = {{0, 0, 0}};
{{0, 0, 0}}); MemObjSizeArray copySize = {{imgDesc.image_width, imgDesc.image_height, imgDesc.image_depth}};
imageNonZeroCopy->transferDataFromHostPtr(copySize, copyOffset);
} }
for (size_t arrayIndex = 0; arrayIndex < imageCount; ++arrayIndex) { for (size_t arrayIndex = 0; arrayIndex < imageCount; ++arrayIndex) {
@@ -884,8 +887,9 @@ TEST_F(ImageTransfer, GivenNonZeroCopyNonZeroRowPitchWithExtraBytes1DArrayImageW
} }
auto &imgDesc = imageNonZeroCopy->getImageDesc(); auto &imgDesc = imageNonZeroCopy->getImageDesc();
imageNonZeroCopy->transferDataToHostPtr({{imgDesc.image_width, imgDesc.image_height, imgDesc.image_depth}}, MemObjOffsetArray copyOffset = {{0, 0, 0}};
{{0, 0, 0}}); MemObjSizeArray copySize = {{imgDesc.image_width, imgDesc.image_height, imgDesc.image_depth}};
imageNonZeroCopy->transferDataToHostPtr(copySize, copyOffset);
row = static_cast<uint32_t *>(unalignedHostPtr); row = static_cast<uint32_t *>(unalignedHostPtr);
@@ -997,7 +1001,7 @@ TEST(ImageTest, givenImageWhenAskedForPtrOffsetForGpuMappingThenReturnCorrectVal
std::unique_ptr<Image> image(ImageHelper<Image3dDefaults>::create(&ctx)); std::unique_ptr<Image> image(ImageHelper<Image3dDefaults>::create(&ctx));
EXPECT_FALSE(image->mappingOnCpuAllowed()); EXPECT_FALSE(image->mappingOnCpuAllowed());
size_t origin[3] = {4, 5, 6}; MemObjOffsetArray origin = {{4, 5, 6}};
auto retOffset = image->calculateOffsetForMapping(origin); auto retOffset = image->calculateOffsetForMapping(origin);
size_t expectedOffset = image->getSurfaceFormatInfo().ImageElementSizeInBytes * origin[0] + size_t expectedOffset = image->getSurfaceFormatInfo().ImageElementSizeInBytes * origin[0] +
@@ -1011,10 +1015,9 @@ TEST(ImageTest, givenImageWhenAskedForPtrOffsetForCpuMappingThenReturnCorrectVal
DebugManager.flags.ForceLinearImages.set(true); DebugManager.flags.ForceLinearImages.set(true);
MockContext ctx; MockContext ctx;
std::unique_ptr<Image> image(ImageHelper<Image3dDefaults>::create(&ctx)); std::unique_ptr<Image> image(ImageHelper<Image3dDefaults>::create(&ctx));
EXPECT_TRUE(image->mappingOnCpuAllowed()); EXPECT_TRUE(image->mappingOnCpuAllowed());
size_t origin[3] = {4, 5, 6}; MemObjOffsetArray origin = {{4, 5, 6}};
auto retOffset = image->calculateOffsetForMapping(origin); auto retOffset = image->calculateOffsetForMapping(origin);
size_t expectedOffset = image->getSurfaceFormatInfo().ImageElementSizeInBytes * origin[0] + size_t expectedOffset = image->getSurfaceFormatInfo().ImageElementSizeInBytes * origin[0] +
@@ -1023,3 +1026,34 @@ TEST(ImageTest, givenImageWhenAskedForPtrOffsetForCpuMappingThenReturnCorrectVal
EXPECT_EQ(expectedOffset, retOffset); EXPECT_EQ(expectedOffset, retOffset);
} }
TEST(ImageTest, givenImageWhenAskedForPtrLengthForGpuMappingThenReturnCorrectValue) {
MockContext ctx;
std::unique_ptr<Image> image(ImageHelper<Image3dDefaults>::create(&ctx));
EXPECT_FALSE(image->mappingOnCpuAllowed());
MemObjSizeArray region = {{4, 5, 6}};
auto retLength = image->calculateMappedPtrLength(region);
size_t expectedLength = image->getSurfaceFormatInfo().ImageElementSizeInBytes * region[0] +
image->getHostPtrRowPitch() * region[1] + image->getHostPtrSlicePitch() * region[2];
EXPECT_EQ(expectedLength, retLength);
}
TEST(ImageTest, givenImageWhenAskedForPtrLengthForCpuMappingThenReturnCorrectValue) {
DebugManagerStateRestore restore;
DebugManager.flags.ForceLinearImages.set(true);
MockContext ctx;
std::unique_ptr<Image> image(ImageHelper<Image3dDefaults>::create(&ctx));
EXPECT_TRUE(image->mappingOnCpuAllowed());
MemObjSizeArray region = {{4, 5, 6}};
auto retLength = image->calculateMappedPtrLength(region);
size_t expectedLength = image->getSurfaceFormatInfo().ImageElementSizeInBytes * region[0] +
image->getImageDesc().image_row_pitch * region[1] +
image->getImageDesc().image_slice_pitch * region[2];
EXPECT_EQ(expectedLength, retLength);
}

View File

@@ -0,0 +1,176 @@
/*
* Copyright (c) 2018, Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include "runtime/helpers/ptr_math.h"
#include "runtime/mem_obj/map_operations_handler.h"
#include "test.h"
#include <tuple>
using namespace OCLRT;
struct MockMapOperationsHandler : public MapOperationsHandler {
using MapOperationsHandler::isOverlapping;
using MapOperationsHandler::mappedPointers;
};
struct MapOperationsHandlerTests : public ::testing::Test {
MockMapOperationsHandler mockHandler;
MapInfo mappedPtrs[3] = {
{(void *)0x1000, 1, {{1, 2, 3}}, {{4, 5, 6}}},
{(void *)0x2000, 1, {{7, 8, 9}}, {{10, 11, 12}}},
{(void *)0x3000, 1, {{13, 14, 15}}, {{16, 17, 18}}},
};
cl_map_flags mapFlags = CL_MAP_READ;
};
TEST_F(MapOperationsHandlerTests, givenMapInfoWhenFindingThenReturnCorrectvalues) {
for (size_t i = 0; i < 3; i++) {
EXPECT_TRUE(mockHandler.add(mappedPtrs[i].ptr, mappedPtrs[i].ptrLength, mapFlags, mappedPtrs[i].size, mappedPtrs[i].offset));
}
EXPECT_EQ(3u, mockHandler.size());
for (int i = 2; i >= 0; i--) {
MapInfo receivedMapInfo;
EXPECT_TRUE(mockHandler.find(mappedPtrs[i].ptr, receivedMapInfo));
EXPECT_EQ(receivedMapInfo.ptr, mappedPtrs[i].ptr);
EXPECT_EQ(receivedMapInfo.size, mappedPtrs[i].size);
EXPECT_EQ(receivedMapInfo.offset, mappedPtrs[i].offset);
}
}
TEST_F(MapOperationsHandlerTests, givenMapInfoWhenRemovingThenRemoveCorrectPointers) {
for (size_t i = 0; i < 3; i++) {
mockHandler.add(mappedPtrs[i].ptr, mappedPtrs[i].ptrLength, mapFlags, mappedPtrs[i].size, mappedPtrs[i].offset);
}
for (int i = 2; i >= 0; i--) {
mockHandler.remove(mappedPtrs[i].ptr);
MapInfo receivedMapInfo;
EXPECT_FALSE(mockHandler.find(mappedPtrs[i].ptr, receivedMapInfo));
}
EXPECT_EQ(0u, mockHandler.size());
}
TEST_F(MapOperationsHandlerTests, givenMappedPtrsWhenDoubleRemovedThenDoNothing) {
mockHandler.add(mappedPtrs[0].ptr, mappedPtrs[0].ptrLength, mapFlags, mappedPtrs[0].size, mappedPtrs[0].offset);
mockHandler.add(mappedPtrs[1].ptr, mappedPtrs[1].ptrLength, mapFlags, mappedPtrs[0].size, mappedPtrs[0].offset);
EXPECT_EQ(2u, mockHandler.size());
mockHandler.remove(mappedPtrs[1].ptr);
mockHandler.remove(mappedPtrs[1].ptr);
EXPECT_EQ(1u, mockHandler.size());
MapInfo receivedMapInfo;
EXPECT_FALSE(mockHandler.find(mappedPtrs[1].ptr, receivedMapInfo));
EXPECT_TRUE(mockHandler.find(mappedPtrs[0].ptr, receivedMapInfo));
}
TEST_F(MapOperationsHandlerTests, givenMapInfoWhenAddedThenSetReadOnlyFlag) {
mapFlags = CL_MAP_READ;
mockHandler.add(mappedPtrs[0].ptr, mappedPtrs[0].ptrLength, mapFlags, mappedPtrs[0].size, mappedPtrs[0].offset);
EXPECT_TRUE(mockHandler.mappedPointers.back().readOnly);
mockHandler.remove(mappedPtrs[0].ptr);
mapFlags = CL_MAP_WRITE;
mockHandler.add(mappedPtrs[0].ptr, mappedPtrs[0].ptrLength, mapFlags, mappedPtrs[0].size, mappedPtrs[0].offset);
EXPECT_FALSE(mockHandler.mappedPointers.back().readOnly);
mockHandler.remove(mappedPtrs[0].ptr);
mapFlags = CL_MAP_WRITE_INVALIDATE_REGION;
mockHandler.add(mappedPtrs[0].ptr, mappedPtrs[0].ptrLength, mapFlags, mappedPtrs[0].size, mappedPtrs[0].offset);
EXPECT_FALSE(mockHandler.mappedPointers.back().readOnly);
mockHandler.remove(mappedPtrs[0].ptr);
mapFlags = CL_MAP_READ | CL_MAP_WRITE;
mockHandler.add(mappedPtrs[0].ptr, mappedPtrs[0].ptrLength, mapFlags, mappedPtrs[0].size, mappedPtrs[0].offset);
EXPECT_FALSE(mockHandler.mappedPointers.back().readOnly);
mockHandler.remove(mappedPtrs[0].ptr);
mapFlags = CL_MAP_READ | CL_MAP_WRITE_INVALIDATE_REGION;
mockHandler.add(mappedPtrs[0].ptr, mappedPtrs[0].ptrLength, mapFlags, mappedPtrs[0].size, mappedPtrs[0].offset);
EXPECT_FALSE(mockHandler.mappedPointers.back().readOnly);
mockHandler.remove(mappedPtrs[0].ptr);
}
TEST_F(MapOperationsHandlerTests, givenNonReadOnlyOverlappingPtrWhenAddingThenReturnFalseAndDontAdd) {
mapFlags = CL_MAP_WRITE;
mappedPtrs->readOnly = false;
mockHandler.add(mappedPtrs[0].ptr, mappedPtrs[0].ptrLength, mapFlags, mappedPtrs[0].size, mappedPtrs[0].offset);
EXPECT_EQ(1u, mockHandler.size());
EXPECT_FALSE(mockHandler.mappedPointers.back().readOnly);
EXPECT_TRUE(mockHandler.isOverlapping(mappedPtrs[0]));
EXPECT_FALSE(mockHandler.add(mappedPtrs[0].ptr, mappedPtrs[0].ptrLength, mapFlags, mappedPtrs[0].size, mappedPtrs[0].offset));
EXPECT_EQ(1u, mockHandler.size());
}
TEST_F(MapOperationsHandlerTests, givenReadOnlyOverlappingPtrWhenAddingThenReturnTrueAndAdd) {
mapFlags = CL_MAP_READ;
mappedPtrs->readOnly = true;
mockHandler.add(mappedPtrs[0].ptr, mappedPtrs[0].ptrLength, mapFlags, mappedPtrs[0].size, mappedPtrs[0].offset);
EXPECT_EQ(1u, mockHandler.size());
EXPECT_TRUE(mockHandler.mappedPointers.back().readOnly);
EXPECT_FALSE(mockHandler.isOverlapping(mappedPtrs[0]));
EXPECT_TRUE(mockHandler.add(mappedPtrs[0].ptr, mappedPtrs[0].ptrLength, mapFlags, mappedPtrs[0].size, mappedPtrs[0].offset));
EXPECT_EQ(2u, mockHandler.size());
EXPECT_TRUE(mockHandler.mappedPointers.back().readOnly);
}
const std::tuple<void *, size_t, void *, size_t, bool> overlappingCombinations[] = {
// mappedPtrStart, mappedPtrLength, requestPtrStart, requestPtrLength, expectOverlap
std::make_tuple((void *)5000, 50, (void *)4000, 1, false), //requested before, non-overlapping
std::make_tuple((void *)5000, 50, (void *)4999, 10, true), //requested before, overlapping inside
std::make_tuple((void *)5000, 50, (void *)4999, 100, true), //requested before, overlapping outside
std::make_tuple((void *)5000, 50, (void *)5001, 1, true), //requested inside, overlapping inside
std::make_tuple((void *)5000, 50, (void *)5001, 100, true), //requested inside, overlapping outside
std::make_tuple((void *)5000, 50, (void *)6000, 1, false), //requested after, non-overlapping
std::make_tuple((void *)5000, 50, (void *)5000, 1, true), //requested on start, overlapping inside
std::make_tuple((void *)5000, 50, (void *)5000, 100, true), //requested on start, overlapping outside
};
struct MapOperationsHandlerOverlapTests : public ::testing::WithParamInterface<std::tuple<void *, size_t, void *, size_t, bool>>,
public ::testing::Test {};
TEST_P(MapOperationsHandlerOverlapTests, givenAlreadyMappedPtrWhenAskingForOverlapThenReturnCorrectValue) {
cl_map_flags mapFlags = CL_MAP_WRITE;
void *mappedPtr = std::get<0>(GetParam());
size_t mappedPtrLength = std::get<1>(GetParam());
void *requestedPtr = std::get<2>(GetParam());
size_t requestedPtrLength = std::get<3>(GetParam());
bool expectOverlap = std::get<4>(GetParam());
// size and offset arrays are ignored
MapInfo mappedInfo(mappedPtr, mappedPtrLength, {{0, 0, 0}}, {{0, 0, 0}});
MapInfo requestedInfo(requestedPtr, requestedPtrLength, {{0, 0, 0}}, {{0, 0, 0}});
requestedInfo.readOnly = false;
MockMapOperationsHandler mockHandler;
mockHandler.add(mappedInfo.ptr, mappedInfo.ptrLength, mapFlags, mappedInfo.size, mappedInfo.offset);
EXPECT_EQ(expectOverlap, mockHandler.isOverlapping(requestedInfo));
}
INSTANTIATE_TEST_CASE_P(MapOperationsHandlerOverlapTests,
MapOperationsHandlerOverlapTests,
::testing::ValuesIn(overlappingCombinations));

View File

@@ -189,13 +189,14 @@ HWTEST_P(MemObjAsyncDestructionTest, givenUsedMemObjWithAsyncDestructionsEnabled
if (!hasAllocatedMappedPtr) { if (!hasAllocatedMappedPtr) {
delete memObj; delete memObj;
allocation = memoryManager->allocateGraphicsMemory(size, MemoryConstants::pageSize); allocation = memoryManager->allocateGraphicsMemory(size, MemoryConstants::pageSize);
size_t origin[3] = {0, 0, 0}; MemObjOffsetArray origin = {{0, 0, 0}};
size_t region[3] = {1, 1, 1}; MemObjSizeArray region = {{1, 1, 1}};
cl_map_flags mapFlags = CL_MAP_READ;
memObj = new MemObj(&context, CL_MEM_OBJECT_BUFFER, memObj = new MemObj(&context, CL_MEM_OBJECT_BUFFER,
CL_MEM_READ_WRITE, CL_MEM_READ_WRITE,
size, size,
storage, nullptr, allocation, true, false, false); storage, nullptr, allocation, true, false, false);
memObj->setMapInfo(storage, region, origin); memObj->addMappedPtr(storage, 1, mapFlags, region, origin);
} else { } else {
memObj->setAllocatedMapPtr(storage); memObj->setAllocatedMapPtr(storage);
} }

View File

@@ -59,13 +59,6 @@ TEST(MemObj, GivenMemObjWhenInititalizedFromHostPtrThenInitializeFields) {
EXPECT_EQ(&buffer, memObj.getHostPtr()); EXPECT_EQ(&buffer, memObj.getHostPtr());
EXPECT_EQ(size, memObj.getSize()); EXPECT_EQ(size, memObj.getSize());
EXPECT_EQ(static_cast<cl_mem_flags>(CL_MEM_USE_HOST_PTR), memObj.getFlags()); EXPECT_EQ(static_cast<cl_mem_flags>(CL_MEM_USE_HOST_PTR), memObj.getFlags());
EXPECT_EQ(nullptr, memObj.getMappedPtr());
EXPECT_EQ(0u, memObj.getMappedSize()[0]);
EXPECT_EQ(0u, memObj.getMappedSize()[1]);
EXPECT_EQ(0u, memObj.getMappedSize()[2]);
EXPECT_EQ(0u, memObj.getMappedOffset()[0]);
EXPECT_EQ(0u, memObj.getMappedOffset()[1]);
EXPECT_EQ(0u, memObj.getMappedOffset()[2]);
} }
TEST(MemObj, givenMemObjectWhenAskedForTransferToHostPtrThenDoNothing) { TEST(MemObj, givenMemObjectWhenAskedForTransferToHostPtrThenDoNothing) {
@@ -80,7 +73,9 @@ TEST(MemObj, givenMemObjectWhenAskedForTransferToHostPtrThenDoNothing) {
memset(memObj.getCpuAddress(), 123, size); memset(memObj.getCpuAddress(), 123, size);
memset(hostPtr, 0, size); memset(hostPtr, 0, size);
EXPECT_THROW(memObj.transferDataToHostPtr({{size, 0, 0}}, {{0, 0, 0}}), std::exception); MemObjOffsetArray copyOffset = {{0, 0, 0}};
MemObjSizeArray copySize = {{size, 0, 0}};
EXPECT_THROW(memObj.transferDataToHostPtr(copySize, copyOffset), std::exception);
EXPECT_TRUE(memcmp(hostPtr, expectedHostPtr, size) == 0); EXPECT_TRUE(memcmp(hostPtr, expectedHostPtr, size) == 0);
} }
@@ -97,26 +92,13 @@ TEST(MemObj, givenMemObjectWhenAskedForTransferFromHostPtrThenDoNothing) {
memset(memObj.getCpuAddress(), 123, size); memset(memObj.getCpuAddress(), 123, size);
memset(expectedBufferPtr, 123, size); memset(expectedBufferPtr, 123, size);
EXPECT_THROW(memObj.transferDataFromHostPtr({{size, 0, 0}}, {{0, 0, 0}}), std::exception); MemObjOffsetArray copyOffset = {{0, 0, 0}};
MemObjSizeArray copySize = {{size, 0, 0}};
EXPECT_THROW(memObj.transferDataFromHostPtr(copySize, copyOffset), std::exception);
EXPECT_TRUE(memcmp(memObj.getCpuAddress(), expectedBufferPtr, size) == 0); EXPECT_TRUE(memcmp(memObj.getCpuAddress(), expectedBufferPtr, size) == 0);
} }
TEST(MemObj, givenMemObjWhenAllocatedMappedPtrIsSetThenGetMappedPtrIsDifferentThanAllocatedMappedPtr) {
void *mockPtr = (void *)0x01234;
MockContext context;
MemObj memObj(&context, CL_MEM_OBJECT_BUFFER, CL_MEM_USE_HOST_PTR,
1, nullptr, nullptr, nullptr, true, false, false);
EXPECT_EQ(nullptr, memObj.getAllocatedMapPtr());
EXPECT_EQ(nullptr, memObj.getMappedPtr());
memObj.setAllocatedMapPtr(mockPtr);
EXPECT_EQ(mockPtr, memObj.getAllocatedMapPtr());
EXPECT_NE(mockPtr, memObj.getMappedPtr());
memObj.setAllocatedMapPtr(nullptr);
}
TEST(MemObj, givenHostPtrAndUseHostPtrFlagWhenAskingForBaseMapPtrThenReturnHostPtr) { TEST(MemObj, givenHostPtrAndUseHostPtrFlagWhenAskingForBaseMapPtrThenReturnHostPtr) {
uint8_t hostPtr = 0; uint8_t hostPtr = 0;
MockContext context; MockContext context;