Skip to content

Commit 3381dc2

Browse files
Fix for ReadWriteBufferRect with misaligned hostPtr
Change-Id: I026f3512e6501b7e3a4cd5b9b6e9010a0b3b8a72
1 parent 8feab5e commit 3381dc2

File tree

5 files changed

+172
-6
lines changed

5 files changed

+172
-6
lines changed

runtime/command_queue/enqueue_read_buffer_rect.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2017-2018 Intel Corporation
2+
* Copyright (C) 2017-2019 Intel Corporation
33
*
44
* SPDX-License-Identifier: MIT
55
*
@@ -83,11 +83,15 @@ cl_int CommandQueueHw<GfxFamily>::enqueueReadBufferRect(
8383
dstPtr = reinterpret_cast<void *>(hostPtrSurf.getAllocation()->getGpuAddressToPatch());
8484
}
8585

86+
void *alignedDstPtr = alignDown(dstPtr, 4);
87+
size_t dstPtrOffset = ptrDiff(dstPtr, alignedDstPtr);
88+
8689
BuiltinDispatchInfoBuilder::BuiltinOpParams dc;
8790
dc.srcMemObj = buffer;
88-
dc.dstPtr = dstPtr;
91+
dc.dstPtr = alignedDstPtr;
8992
dc.srcOffset = bufferOrigin;
9093
dc.dstOffset = hostOrigin;
94+
dc.dstOffset.x += dstPtrOffset;
9195
dc.size = region;
9296
dc.srcRowPitch = bufferRowPitch;
9397
dc.srcSlicePitch = bufferSlicePitch;

runtime/command_queue/enqueue_write_buffer_rect.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2017-2018 Intel Corporation
2+
* Copyright (C) 2017-2019 Intel Corporation
33
*
44
* SPDX-License-Identifier: MIT
55
*
@@ -82,10 +82,14 @@ cl_int CommandQueueHw<GfxFamily>::enqueueWriteBufferRect(
8282
srcPtr = reinterpret_cast<void *>(hostPtrSurf.getAllocation()->getGpuAddressToPatch());
8383
}
8484

85+
void *alignedSrcPtr = alignDown(srcPtr, 4);
86+
size_t srcPtrOffset = ptrDiff(srcPtr, alignedSrcPtr);
87+
8588
BuiltinDispatchInfoBuilder::BuiltinOpParams dc;
86-
dc.srcPtr = srcPtr;
89+
dc.srcPtr = alignedSrcPtr;
8790
dc.dstMemObj = buffer;
8891
dc.srcOffset = hostOrigin;
92+
dc.srcOffset.x += srcPtrOffset;
8993
dc.dstOffset = bufferOrigin;
9094
dc.size = region;
9195
dc.srcRowPitch = hostRowPitch;

unit_tests/aub_tests/command_queue/enqueue_read_buffer_rect_aub_tests.cpp

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2017-2018 Intel Corporation
2+
* Copyright (C) 2017-2019 Intel Corporation
33
*
44
* SPDX-License-Identifier: MIT
55
*
@@ -112,3 +112,83 @@ INSTANTIATE_TEST_CASE_P(AUBReadBufferRect_simple,
112112
::testing::Combine(
113113
::testing::Values(0, 1, 2, 3, 4),
114114
::testing::Values(0, 1, 2, 3, 4)));
115+
116+
struct AUBReadBufferRectUnaligned
117+
: public CommandEnqueueAUBFixture,
118+
public ::testing::Test {
119+
120+
void SetUp() override {
121+
CommandEnqueueAUBFixture::SetUp();
122+
}
123+
124+
void TearDown() override {
125+
CommandEnqueueAUBFixture::TearDown();
126+
}
127+
128+
template <typename FamilyType>
129+
void testReadBufferUnaligned(size_t offset, size_t size) {
130+
MockContext context(&pCmdQ->getDevice());
131+
132+
char srcMemory[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
133+
const auto bufferSize = sizeof(srcMemory);
134+
void *dstMemory = alignedMalloc(bufferSize, MemoryConstants::pageSize);
135+
memset(dstMemory, 0, bufferSize);
136+
char referenceMemory[bufferSize] = {0};
137+
138+
auto retVal = CL_INVALID_VALUE;
139+
140+
auto buffer = std::unique_ptr<Buffer>(Buffer::create(
141+
&context,
142+
CL_MEM_COPY_HOST_PTR,
143+
bufferSize,
144+
srcMemory,
145+
retVal));
146+
ASSERT_NE(nullptr, buffer);
147+
148+
buffer->forceDisallowCPUCopy = true;
149+
150+
// Map destination memory to GPU
151+
GraphicsAllocation *allocation = createResidentAllocationAndStoreItInCsr(dstMemory, bufferSize);
152+
auto dstMemoryGPUPtr = reinterpret_cast<char *>(allocation->getGpuAddress());
153+
154+
cl_bool blockingRead = CL_TRUE;
155+
156+
size_t rowPitch = bufferSize / 4;
157+
size_t slicePitch = 4 * rowPitch;
158+
size_t bufferOrigin[] = {0, 1, 0};
159+
size_t hostOrigin[] = {0, 0, 0};
160+
size_t region[] = {size, 1, 1};
161+
162+
retVal = pCmdQ->enqueueReadBufferRect(
163+
buffer.get(),
164+
blockingRead,
165+
bufferOrigin,
166+
hostOrigin,
167+
region,
168+
rowPitch,
169+
slicePitch,
170+
rowPitch,
171+
slicePitch,
172+
ptrOffset(dstMemory, offset),
173+
0,
174+
nullptr,
175+
nullptr);
176+
177+
EXPECT_EQ(CL_SUCCESS, retVal);
178+
179+
AUBCommandStreamFixture::expectMemory<FamilyType>(dstMemoryGPUPtr, referenceMemory, offset);
180+
AUBCommandStreamFixture::expectMemory<FamilyType>(ptrOffset(dstMemoryGPUPtr, offset), &srcMemory[rowPitch * bufferOrigin[1]], size);
181+
AUBCommandStreamFixture::expectMemory<FamilyType>(ptrOffset(dstMemoryGPUPtr, size + offset), referenceMemory, bufferSize - offset - size);
182+
alignedFree(dstMemory);
183+
}
184+
};
185+
186+
HWTEST_F(AUBReadBufferRectUnaligned, misalignedHostPtr) {
187+
const std::vector<size_t> offsets = {0, 1, 2, 3};
188+
const std::vector<size_t> sizes = {4, 3, 2, 1};
189+
for (auto offset : offsets) {
190+
for (auto size : sizes) {
191+
testReadBufferUnaligned<FamilyType>(offset, size);
192+
}
193+
}
194+
}

unit_tests/aub_tests/command_queue/enqueue_write_buffer_rect_aub_tests.cpp

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2017-2018 Intel Corporation
2+
* Copyright (C) 2017-2019 Intel Corporation
33
*
44
* SPDX-License-Identifier: MIT
55
*
@@ -113,3 +113,80 @@ INSTANTIATE_TEST_CASE_P(AUBWriteBufferRect_simple,
113113
::testing::Combine(
114114
::testing::Values(0, 1, 2, 3, 4),
115115
::testing::Values(0, 1, 2, 3, 4)));
116+
117+
struct AUBWriteBufferRectUnaligned
118+
: public CommandEnqueueAUBFixture,
119+
public ::testing::Test {
120+
121+
void SetUp() override {
122+
CommandEnqueueAUBFixture::SetUp();
123+
}
124+
125+
void TearDown() override {
126+
CommandEnqueueAUBFixture::TearDown();
127+
}
128+
129+
template <typename FamilyType>
130+
void testWriteBufferUnaligned(size_t offset, size_t size) {
131+
MockContext context(&pCmdQ->getDevice());
132+
133+
char srcMemory[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
134+
const auto bufferSize = sizeof(srcMemory);
135+
char dstMemory[bufferSize] = {0};
136+
char referenceMemory[bufferSize] = {0};
137+
138+
auto retVal = CL_INVALID_VALUE;
139+
140+
auto buffer = std::unique_ptr<Buffer>(Buffer::create(
141+
&context,
142+
CL_MEM_COPY_HOST_PTR,
143+
bufferSize,
144+
dstMemory,
145+
retVal));
146+
ASSERT_NE(nullptr, buffer);
147+
148+
buffer->forceDisallowCPUCopy = true;
149+
150+
uint8_t *pDestMemory = (uint8_t *)buffer->getGraphicsAllocation()->getGpuAddress();
151+
152+
cl_bool blockingWrite = CL_TRUE;
153+
154+
size_t rowPitch = bufferSize / 4;
155+
size_t slicePitch = 4 * rowPitch;
156+
size_t bufferOrigin[] = {0, 1, 0};
157+
size_t hostOrigin[] = {0, 0, 0};
158+
size_t region[] = {size, 1, 1};
159+
160+
retVal = pCmdQ->enqueueWriteBufferRect(
161+
buffer.get(),
162+
blockingWrite,
163+
bufferOrigin,
164+
hostOrigin,
165+
region,
166+
rowPitch,
167+
slicePitch,
168+
rowPitch,
169+
slicePitch,
170+
ptrOffset(srcMemory, offset),
171+
0,
172+
nullptr,
173+
nullptr);
174+
175+
EXPECT_EQ(CL_SUCCESS, retVal);
176+
pCmdQ->finish(true);
177+
178+
AUBCommandStreamFixture::expectMemory<FamilyType>(pDestMemory, referenceMemory, rowPitch);
179+
AUBCommandStreamFixture::expectMemory<FamilyType>(pDestMemory + rowPitch * bufferOrigin[1], ptrOffset(srcMemory, offset), size);
180+
AUBCommandStreamFixture::expectMemory<FamilyType>(pDestMemory + rowPitch * bufferOrigin[1] + size, referenceMemory, bufferSize - size - rowPitch);
181+
}
182+
};
183+
184+
HWTEST_F(AUBWriteBufferRectUnaligned, misalignedHostPtr) {
185+
const std::vector<size_t> offsets = {0, 1, 2, 3};
186+
const std::vector<size_t> sizes = {4, 3, 2, 1};
187+
for (auto offset : offsets) {
188+
for (auto size : sizes) {
189+
testWriteBufferUnaligned<FamilyType>(offset, size);
190+
}
191+
}
192+
}

unit_tests/scenarios/windows/enqueue_read_write_buffer_scenarios_windows_tests.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ HWTEST_F(EnqueueBufferWindowsTest, givenMisalignedHostPtrWhenEnqueueReadBufferCa
111111
kernel->getKernelInfo().kernelArgInfo[3].kernelArgPatchInfoVector[0].crossthreadOffset);
112112
EXPECT_EQ(ptrDiff(misalignedPtr, alignDown(misalignedPtr, 4)), *dstOffset);
113113
} else {
114+
// dstOffset arg should be 4 bytes in size, if that changes, above if path should be modified
114115
EXPECT_TRUE(false);
115116
}
116117
}

0 commit comments

Comments
 (0)