From 254b69510800fd3f5e1a05b59bb503257f808719 Mon Sep 17 00:00:00 2001
From: foreman
Date: Tue, 17 Mar 2015 10:53:04 -0400
Subject: [PATCH] P4 to Git Change 1131417 by gandryey@gera-w8 on 2015/03/17
10:31:57
ECR #304775 - Mipmaps support
- Create views for the specified mip level in the transfer operations
- OCL requires just one mip level transfer. Thus we could keep the original blit kernels and just create a view for the specified mip level.
Affected files ...
... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_memobj.cpp#75 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpudevice.cpp#500 edit
... //depot/stg/opencl/drivers/opencl/runtime/platform/memory.cpp#119 edit
... //depot/stg/opencl/drivers/opencl/runtime/platform/memory.hpp#90 edit
---
opencl/api/opencl/amdocl/cl_memobj.cpp | 123 +++++++++++++++++++++++++
1 file changed, 123 insertions(+)
diff --git a/opencl/api/opencl/amdocl/cl_memobj.cpp b/opencl/api/opencl/amdocl/cl_memobj.cpp
index fdc74e7065..495277f57e 100644
--- a/opencl/api/opencl/amdocl/cl_memobj.cpp
+++ b/opencl/api/opencl/amdocl/cl_memobj.cpp
@@ -264,6 +264,21 @@ validateImageDescriptor(
return true;
}
+class ImageViewRef : public amd::EmbeddedObject
+{
+private:
+ amd::Image* ref_;
+ // Do not copy image view references.
+ ImageViewRef& operator = (const ImageViewRef& sref);
+
+public:
+ explicit ImageViewRef(): ref_(NULL) { }
+ ~ImageViewRef() { if (ref_ != NULL) { ref_->release(); } }
+
+ ImageViewRef& operator = (amd::Image* sref) { ref_ = sref; return *this;}
+ amd::Image* operator ()() const { return ref_; }
+};
+
/*! \brief Create a buffer object.
*
* \param context is a valid OpenCL context used to create the buffer object.
@@ -2333,6 +2348,21 @@ RUNTIME_ENTRY(cl_int, clEnqueueReadImage, (
amd::Coord3D srcOrigin(origin[0], origin[1], origin[2]);
amd::Coord3D srcRegion(region[0], region[1], region[2]);
+ ImageViewRef mip;
+ if (srcImage->getMipLevels() > 1) {
+ // Create a view for the specified mip level
+ mip = srcImage->createView(srcImage->getContext(),
+ srcImage->getImageFormat(), NULL, origin[srcImage->getDims()]);
+ if (mip() == NULL) {
+ return CL_OUT_OF_HOST_MEMORY;
+ }
+ // Reset the mip level value to 0, since a view was created
+ if (srcImage->getDims() < 3) {
+ srcOrigin.c[srcImage->getDims()] = 0;
+ }
+ srcImage = mip();
+ }
+
if (!srcImage->validateRegion(srcOrigin, srcRegion) ||
!srcImage->isSliceValid(row_pitch, slice_pitch, region[1])) {
return CL_INVALID_VALUE;
@@ -2375,6 +2405,7 @@ RUNTIME_ENTRY(cl_int, clEnqueueReadImage, (
if (event == NULL) {
command->release();
}
+
return CL_SUCCESS;
}
RUNTIME_EXIT
@@ -2515,6 +2546,20 @@ RUNTIME_ENTRY(cl_int, clEnqueueWriteImage, (
amd::Coord3D dstOrigin(origin[0], origin[1], origin[2]);
amd::Coord3D dstRegion(region[0], region[1], region[2]);
+ ImageViewRef mip;
+ if (dstImage->getMipLevels() > 1) {
+ // Create a view for the specified mip level
+ mip = dstImage->createView(dstImage->getContext(),
+ dstImage->getImageFormat(), NULL, origin[dstImage->getDims()]);
+ if (mip() == NULL) {
+ return CL_OUT_OF_HOST_MEMORY;
+ }
+ // Reset the mip level value to 0, since a view was created
+ if (dstImage->getDims() < 3) {
+ dstOrigin.c[dstImage->getDims()] = 0;
+ }
+ dstImage = mip();
+ }
if (!dstImage->validateRegion(dstOrigin, dstRegion) ||
!dstImage->isSliceValid(input_row_pitch, input_slice_pitch, region[1])) {
@@ -2676,10 +2721,40 @@ RUNTIME_ENTRY(cl_int, clEnqueueCopyImage, (
amd::Coord3D dstOrigin(dst_origin[0], dst_origin[1], dst_origin[2]);
amd::Coord3D copyRegion(region[0], region[1], region[2]);
+ ImageViewRef srcMip;
+ if (srcImage->getMipLevels() > 1) {
+ // Create a view for the specified mip level
+ srcMip = srcImage->createView(srcImage->getContext(),
+ srcImage->getImageFormat(), NULL, src_origin[srcImage->getDims()]);
+ if (srcMip() == NULL) {
+ return CL_OUT_OF_HOST_MEMORY;
+ }
+ // Reset the mip level value to 0, since a view was created
+ if (srcImage->getDims() < 3) {
+ srcOrigin.c[srcImage->getDims()] = 0;
+ }
+ srcImage = srcMip();
+ }
+
if (!srcImage->validateRegion(srcOrigin, copyRegion)) {
return CL_INVALID_VALUE;
}
+ ImageViewRef dstMip;
+ if (dstImage->getMipLevels() > 1) {
+ // Create a view for the specified mip level
+ dstMip = dstImage->createView(dstImage->getContext(),
+ dstImage->getImageFormat(), NULL, dst_origin[dstImage->getDims()]);
+ if (dstMip() == NULL) {
+ return CL_OUT_OF_HOST_MEMORY;
+ }
+ // Reset the mip level value to 0, since a view was created
+ if (dstImage->getDims() < 3) {
+ dstOrigin.c[dstImage->getDims()] = 0;
+ }
+ dstImage = dstMip();
+ }
+
if (!dstImage->validateRegion(dstOrigin, copyRegion)) {
return CL_INVALID_VALUE;
}
@@ -2856,6 +2931,21 @@ RUNTIME_ENTRY(cl_int, clEnqueueCopyImageToBuffer, (
amd::Coord3D copySize(region[0] * region[1] * region[2] *
srcImage->getImageFormat().getElementSize(), 0, 0);
+ ImageViewRef mip;
+ if (srcImage->getMipLevels() > 1) {
+ // Create a view for the specified mip level
+ mip = srcImage->createView(srcImage->getContext(),
+ srcImage->getImageFormat(), NULL, src_origin[srcImage->getDims()]);
+ if (mip() == NULL) {
+ return CL_OUT_OF_HOST_MEMORY;
+ }
+ // Reset the mip level value to 0, since a view was created
+ if (srcImage->getDims() < 3) {
+ srcOrigin.c[srcImage->getDims()] = 0;
+ }
+ srcImage = mip();
+ }
+
if (!srcImage->validateRegion(srcOrigin, srcRegion) ||
!dstBuffer->validateRegion(dstOffset, copySize)) {
return CL_INVALID_VALUE;
@@ -3007,6 +3097,21 @@ RUNTIME_ENTRY(cl_int, clEnqueueCopyBufferToImage, (
amd::Coord3D copySize(region[0] * region[1] * region[2] *
dstImage->getImageFormat().getElementSize(), 0, 0);
+ ImageViewRef mip;
+ if (dstImage->getMipLevels() > 1) {
+ // Create a view for the specified mip level
+ mip = dstImage->createView(dstImage->getContext(),
+ dstImage->getImageFormat(), NULL, dst_origin[dstImage->getDims()]);
+ if (mip() == NULL) {
+ return CL_OUT_OF_HOST_MEMORY;
+ }
+ // Reset the mip level value to 0, since a view was created
+ if (dstImage->getDims() < 3) {
+ dstOrigin.c[dstImage->getDims()] = 0;
+ }
+ dstImage = mip();
+ }
+
if (!srcBuffer->validateRegion(srcOffset, copySize) ||
!dstImage->validateRegion(dstOrigin, dstRegion)) {
return CL_INVALID_VALUE;
@@ -3460,6 +3565,23 @@ RUNTIME_ENTRY_RET(void *, clEnqueueMapImage, (
amd::Coord3D srcOrigin(origin[0], origin[1], origin[2]);
amd::Coord3D srcRegion(region[0], region[1], region[2]);
+
+ ImageViewRef mip;
+ if (srcImage->getMipLevels() > 1) {
+ // Create a view for the specified mip level
+ mip = srcImage->createView(srcImage->getContext(),
+ srcImage->getImageFormat(), NULL, origin[srcImage->getDims()]);
+ if (mip() == NULL) {
+ *not_null(errcode_ret) = CL_OUT_OF_HOST_MEMORY;
+ return NULL;
+ }
+ // Reset the mip level value to 0, since a view was created
+ if (srcImage->getDims() < 3) {
+ srcOrigin.c[srcImage->getDims()] = 0;
+ }
+ srcImage = mip();
+ }
+
if (!srcImage->validateRegion(srcOrigin, srcRegion)) {
*not_null(errcode_ret) = CL_INVALID_VALUE;
return NULL;
@@ -3528,6 +3650,7 @@ RUNTIME_ENTRY_RET(void *, clEnqueueMapImage, (
*not_null(errcode_ret) = CL_SUCCESS;
srcImage->incMapCount();
+
return mapPtr;
}
RUNTIME_EXIT