diff --git a/rocclr/runtime/device/device.hpp b/rocclr/runtime/device/device.hpp index 2e699dcb0c..b05c79ef43 100644 --- a/rocclr/runtime/device/device.hpp +++ b/rocclr/runtime/device/device.hpp @@ -111,6 +111,8 @@ enum OclExtensions { ClKhrSubGroups, ClKhrGlEvent, ClKhrDepthImages, + ClKhrMipMapImage, + ClKhrMipMapImageWrites, ClExtTotal }; @@ -152,6 +154,8 @@ OclExtensionsString[] = { "cl_khr_subgroups ", "cl_khr_gl_event ", "cl_khr_depth_images ", + "cl_khr_mipmap_image ", + "cl_khr_mipmap_image_writes ", NULL }; diff --git a/rocclr/runtime/device/gpu/gpublit.cpp b/rocclr/runtime/device/gpu/gpublit.cpp index a0411a33f8..438dcdc141 100644 --- a/rocclr/runtime/device/gpu/gpublit.cpp +++ b/rocclr/runtime/device/gpu/gpublit.cpp @@ -2826,7 +2826,8 @@ KernelBlitManager::createView( parent.cal()->depth_, format.type_, format.channelOrder_, - parent.cal()->imageType_); + parent.cal()->imageType_, + 1); // Create resource if (NULL != gpuImage) { diff --git a/rocclr/runtime/device/gpu/gpudevice.cpp b/rocclr/runtime/device/gpu/gpudevice.cpp index 2b18e64548..a11508a67d 100644 --- a/rocclr/runtime/device/gpu/gpudevice.cpp +++ b/rocclr/runtime/device/gpu/gpudevice.cpp @@ -276,13 +276,12 @@ Device::Engines::getRequested(uint engines, gslEngineDescriptor* desc) const Device::XferBuffers::~XferBuffers() { // Destroy temporary buffer for reads - for (std::list::const_iterator i = freeBuffers_.begin(); - i != freeBuffers_.end(); ++i) { + for (const auto& buf : freeBuffers_) { // CPU optimization: unmap staging buffer just once - if (!(*i)->cal()->cardMemory_) { - (*i)->unmap(NULL); + if (!buf->cal()->cardMemory_) { + buf->unmap(NULL); } - delete (*i); + delete buf; } freeBuffers_.clear(); } @@ -1748,7 +1747,8 @@ Device::createImage(amd::Memory& owner, bool directAccess) const image.getDepth(), format.type_, format.channelOrder_, - image.getType()); + image.getType(), + image.getMipLevels()); // Create resource if (NULL != gpuImage) { @@ -2001,7 +2001,8 @@ Device::createView(amd::Memory& owner, const device::Memory& parent) const image.getDepth(), format.type_, format.channelOrder_, - image.getType()); + image.getType(), + image.getMipLevels()); // Create resource if (NULL != gpuImage) { @@ -2223,13 +2224,11 @@ Device::removeVACache(const Memory* memory) const void* end = reinterpret_cast
(start) + memory->owner()->getSize(); // Find VA cache entry for the specified memory - std::list::const_iterator it; - for (it = vaCacheList_->begin(); it != vaCacheList_->end(); ++it) { - VACacheEntry* entry = *it; + for (const auto& entry : *vaCacheList_) { if (entry->startAddress_ == start) { CondLog((entry->endAddress_ != end), "Incorrect VA range"); - vaCacheList_->remove(entry); delete entry; + vaCacheList_->remove(entry); break; } } @@ -2241,9 +2240,7 @@ Device::findMemoryFromVA(const void* ptr, size_t* offset) const { // VA cache access must be serialised amd::ScopedLock lk(*vaCacheAccess_); - std::list::const_iterator it; - for (it = vaCacheList_->begin(); it != vaCacheList_->end(); ++it) { - VACacheEntry* entry = *it; + for (const auto& entry : *vaCacheList_) { if ((entry->startAddress_ <= ptr) && (entry->endAddress_ > ptr)) { *offset = static_cast(reinterpret_cast(ptr) - reinterpret_cast(entry->startAddress_)); diff --git a/rocclr/runtime/device/gpu/gpumemory.cpp b/rocclr/runtime/device/gpu/gpumemory.cpp index 7a659c15d2..9873a17eb1 100644 --- a/rocclr/runtime/device/gpu/gpumemory.cpp +++ b/rocclr/runtime/device/gpu/gpumemory.cpp @@ -105,10 +105,11 @@ Memory::Memory( size_t depth, cmSurfFmt format, gslChannelOrder chOrder, - cl_mem_object_type imageType + cl_mem_object_type imageType, + uint mipLevels ) : device::Memory(owner) - , Resource(gpuDev, width, height, depth, format, chOrder, imageType) + , Resource(gpuDev, width, height, depth, format, chOrder, imageType, mipLevels) , hb_(NULL) { init(); @@ -126,10 +127,11 @@ Memory::Memory( size_t depth, cmSurfFmt format, gslChannelOrder chOrder, - cl_mem_object_type imageType + cl_mem_object_type imageType, + uint mipLevels ) : device::Memory(size) - , Resource(gpuDev, width, height, depth, format, chOrder, imageType) + , Resource(gpuDev, width, height, depth, format, chOrder, imageType, mipLevels) , hb_(NULL) { init(); @@ -602,7 +604,6 @@ Memory::syncCacheFromHost(VirtualGPU& gpu, device::Memory::SyncFlags syncFlags) // Update all available views, since we sync the parent if ((owner()->subBuffers().size() != 0) && (hasUpdates || !syncFlags.skipViews_)) { - std::list::const_iterator it; device::Memory::SyncFlags syncFlagsTmp; // Sync views from parent, so parent has to be skipped @@ -619,14 +620,13 @@ Memory::syncCacheFromHost(VirtualGPU& gpu, device::Memory::SyncFlags syncFlags) } amd::ScopedLock lock(owner()->lockMemoryOps()); - for (it = owner()->subBuffers().begin(); - it != owner()->subBuffers().end(); ++it) { + for (auto& sub : owner()->subBuffers()) { //! \note Don't allow subbuffer's allocation in the worker thread. //! It may cause a system lock, because possible resource //! destruction, heap reallocation or subbuffer allocation static const bool AllocSubBuffer = false; device::Memory* devSub = - (*it)->getDeviceMemory(dev(), AllocSubBuffer); + sub->getDeviceMemory(dev(), AllocSubBuffer); if (NULL != devSub) { gpu::Memory* gpuSub = reinterpret_cast(devSub); gpuSub->syncCacheFromHost(gpu, syncFlagsTmp); @@ -728,7 +728,6 @@ Memory::syncHostFromCache(device::Memory::SyncFlags syncFlags) // Update all available views, since we sync the parent if ((owner()->subBuffers().size() != 0) && (hasUpdates || !syncFlags.skipViews_)) { - std::list::const_iterator it; device::Memory::SyncFlags syncFlagsTmp; // Sync views from parent, so parent has to be skipped @@ -745,14 +744,13 @@ Memory::syncHostFromCache(device::Memory::SyncFlags syncFlags) } amd::ScopedLock lock(owner()->lockMemoryOps()); - for (it = owner()->subBuffers().begin(); - it != owner()->subBuffers().end(); ++it) { + for (auto& sub : owner()->subBuffers()) { //! \note Don't allow subbuffer's allocation in the worker thread. //! It may cause a system lock, because possible resource //! destruction, heap reallocation or subbuffer allocation static const bool AllocSubBuffer = false; device::Memory* devSub = - (*it)->getDeviceMemory(dev(), AllocSubBuffer); + sub->getDeviceMemory(dev(), AllocSubBuffer); if (NULL != devSub) { gpu::Memory* gpuSub = reinterpret_cast(devSub); gpuSub->syncHostFromCache(syncFlagsTmp); diff --git a/rocclr/runtime/device/gpu/gpumemory.hpp b/rocclr/runtime/device/gpu/gpumemory.hpp index 11d4f088ad..c6ccb4b23e 100644 --- a/rocclr/runtime/device/gpu/gpumemory.hpp +++ b/rocclr/runtime/device/gpu/gpumemory.hpp @@ -82,7 +82,8 @@ public: size_t depth, //!< Allocated memory depth cmSurfFmt format, //!< Memory format gslChannelOrder chOrder, //!< Channel order - cl_mem_object_type imageType //!< CL image type + cl_mem_object_type imageType, //!< CL image type + uint mipLevels //!< The number of mip levels ); //! Constructor memory for images (without global heap allocaton) @@ -94,7 +95,8 @@ public: size_t depth, //!< Allocated memory depth cmSurfFmt format, //!< Memory format gslChannelOrder chOrder, //!< Channel order - cl_mem_object_type imageType //!< CL image type + cl_mem_object_type imageType, //!< CL image type + uint mipLevels //!< The number of mip levels ); //! Default destructor @@ -276,9 +278,10 @@ public: size_t depth, //!< Allocated memory depth cmSurfFmt format, //!< Memory format gslChannelOrder chOrder, //!< Channel order - cl_mem_object_type imageType //!< CL image type + cl_mem_object_type imageType, //!< CL image type + uint mipLevels //!< The number of mip levels ) - : gpu::Memory(gpuDev, owner, width, height, depth, format, chOrder, imageType) + : gpu::Memory(gpuDev, owner, width, height, depth, format, chOrder, imageType, mipLevels) {} //! Image constructor @@ -290,9 +293,10 @@ public: size_t depth, //!< Allocated memory depth cmSurfFmt format, //!< Memory format gslChannelOrder chOrder, //!< Channel order - cl_mem_object_type imageType //!< CL image type + cl_mem_object_type imageType, //!< CL image type + uint mipLevels //!< The number of mip levels ) - : gpu::Memory(gpuDev, size, width, height, depth, format, chOrder, imageType) + : gpu::Memory(gpuDev, size, width, height, depth, format, chOrder, imageType, mipLevels) {} //! Allocate memory for API-level maps diff --git a/rocclr/runtime/device/gpu/gpuresource.cpp b/rocclr/runtime/device/gpu/gpuresource.cpp index 987ebb2d4d..ffea2c9293 100644 --- a/rocclr/runtime/device/gpu/gpuresource.cpp +++ b/rocclr/runtime/device/gpu/gpuresource.cpp @@ -77,6 +77,7 @@ Resource::Resource( cal_.width_ = width; cal_.height_ = 1; cal_.depth_ = 1; + cal_.mipLevels_ = 1; cal_.format_ = format; cal_.flags_ = 0; cal_.pitch_ = 0; @@ -99,7 +100,8 @@ Resource::Resource( size_t depth, cmSurfFmt format, gslChannelOrder chOrder, - cl_mem_object_type imageType) + cl_mem_object_type imageType, + uint mipLevels) : elementSize_(0) , gpuDevice_(gpuDev) , mapCount_(0) @@ -121,6 +123,7 @@ Resource::Resource( cal_.width_ = width; cal_.height_ = height; cal_.depth_ = depth; + cal_.mipLevels_ = mipLevels; cal_.format_ = format; cal_.flags_ = 0; cal_.pitch_ = 0; @@ -435,7 +438,7 @@ Resource::create(MemoryType memType, CreateParams* params, bool heap) desc.format = cal()->format_; desc.channelOrder = cal()->channelOrder_; desc.flags = cal()->flags_; - desc.mipLevels = 0; + desc.mipLevels = cal()->mipLevels_; desc.systemMemory = NULL; do { @@ -2023,7 +2026,6 @@ GslResourceReference* ResourceCache::findCalResource(Resource::CalResourceDesc* desc) { amd::ScopedLock l(&lockCacheOps_); - bool found = false; GslResourceReference* ref = NULL; size_t size = getResourceSize(desc); @@ -2034,10 +2036,8 @@ ResourceCache::findCalResource(Resource::CalResourceDesc* desc) } // Serach the right resource through the cache list - std::list >::const_iterator it; - for (it = resCache_.begin(); it != resCache_.end(); ++it) { - Resource::CalResourceDesc* entry = it->first; + for (const auto& it: resCache_) { + Resource::CalResourceDesc* entry = it.first; // Find if we can reuse this entry if ((entry->dimension_ == desc->dimension_) && (entry->type_ == desc->type_) && @@ -2047,19 +2047,15 @@ ResourceCache::findCalResource(Resource::CalResourceDesc* desc) (entry->channelOrder_ == desc->channelOrder_) && (entry->format_ == desc->format_) && (entry->flags_ == desc->flags_)) { - ref = it->second; - delete it->first; - found = true; + ref = it.second; + delete it.first; + // Remove the found etry from the cache + resCache_.remove(it); + cacheSize_ -= size; break; } } - if (found) { - // Remove the found etry from the cache - resCache_.remove(*it); - cacheSize_ -= size; - } - return ref; } diff --git a/rocclr/runtime/device/gpu/gpuresource.hpp b/rocclr/runtime/device/gpu/gpuresource.hpp index 7ce8b593ac..c2c72b7cc6 100644 --- a/rocclr/runtime/device/gpu/gpuresource.hpp +++ b/rocclr/runtime/device/gpu/gpuresource.hpp @@ -158,6 +158,7 @@ public: size_t width_; //!< CAL resource width size_t height_; //!< CAL resource height size_t depth_; //!< CAL resource depth + uint mipLevels_; //!< Number of mip levels cmSurfFmt format_; //!< GSL resource format CALuint flags_; //!< CAL resource flags, used in creation size_t pitch_; //!< CAL resource pitch, valid if locked @@ -194,7 +195,8 @@ public: size_t depth, //!< resource depth cmSurfFmt format, //!< resource format gslChannelOrder chOrder, //!< resource channel order - cl_mem_object_type imageType //!< CL image type + cl_mem_object_type imageType, //!< CL image type + uint mipLevels = 1 //!< Number of mip levels ); //! Destructor of the resource diff --git a/rocclr/runtime/device/gpu/gpusettings.cpp b/rocclr/runtime/device/gpu/gpusettings.cpp index ae965c01f5..848aaf9a61 100644 --- a/rocclr/runtime/device/gpu/gpusettings.cpp +++ b/rocclr/runtime/device/gpu/gpusettings.cpp @@ -134,7 +134,6 @@ Settings::Settings() // Use host queue for device enqueuing by default useDeviceQueue_ = GPU_USE_DEVICE_QUEUE; - } bool @@ -282,11 +281,13 @@ Settings::create( if (ciPlus_) { libSelector_ = amd::GPU_Library_CI; #if defined(_LP64) - oclVersion_ = !reportAsOCL12Device && calAttr.isOpenCL200Device ? XCONCAT(OpenCL, XCONCAT(OPENCL_MAJOR, OPENCL_MINOR)) : OpenCL12; + oclVersion_ = !reportAsOCL12Device && calAttr.isOpenCL200Device ? + XCONCAT(OpenCL, XCONCAT(OPENCL_MAJOR, OPENCL_MINOR)) : OpenCL12; #endif if (GPU_FORCE_OCL20_32BIT) { force32BitOcl20_ = true; - oclVersion_ = !reportAsOCL12Device && calAttr.isOpenCL200Device ? XCONCAT(OpenCL, XCONCAT(OPENCL_MAJOR, OPENCL_MINOR)) : OpenCL12; + oclVersion_ = !reportAsOCL12Device && calAttr.isOpenCL200Device ? + XCONCAT(OpenCL, XCONCAT(OPENCL_MAJOR, OPENCL_MINOR)) : OpenCL12; } if (hsail_ || (OPENCL_VERSION < 200)) { oclVersion_ = OpenCL12; @@ -432,6 +433,11 @@ Settings::create( enableExtension(ClKhrSubGroups); enableExtension(ClKhrDepthImages); + if (GPU_MIPMAP) { + enableExtension(ClKhrMipMapImage); + enableExtension(ClKhrMipMapImageWrites); + } + // Enable HW debug if (GPU_ENABLE_HW_DEBUG) { enableHwDebug_ = true; diff --git a/rocclr/runtime/device/gpu/gslbe/src/rt/GSLDevice.cpp b/rocclr/runtime/device/gpu/gslbe/src/rt/GSLDevice.cpp index fbe5342e65..5477bb2025 100644 --- a/rocclr/runtime/device/gpu/gslbe/src/rt/GSLDevice.cpp +++ b/rocclr/runtime/device/gpu/gslbe/src/rt/GSLDevice.cpp @@ -780,6 +780,10 @@ CALGSLDevice::resAlloc(const CALresourceDesc* desc) const attribs.channelOrder = desc->channelOrder; attribs.type = desc->dimension; + if (desc->mipLevels > 1) { + attribs.levels = desc->mipLevels; + attribs.mipmap = true; + } switch (desc->dimension) { case GSL_MOA_BUFFER: diff --git a/rocclr/runtime/platform/memory.cpp b/rocclr/runtime/platform/memory.cpp index c03e10d5bf..b3fc22ed56 100644 --- a/rocclr/runtime/platform/memory.cpp +++ b/rocclr/runtime/platform/memory.cpp @@ -550,9 +550,15 @@ Pipe::initDeviceMemory() Image::Image( const Format& format, - Image& parent) : - Memory(parent, 0, 0, parent.getWidth() * parent.getHeight() * parent.getDepth() * format.getElementSize()) , - impl_(format, Coord3D(parent.getWidth() * parent.getImageFormat().getElementSize() / format.getElementSize(), parent.getHeight(), parent.getDepth()), parent.getRowPitch(), parent.getSlicePitch(), parent.getBytePitch()) + Image& parent) + : Memory(parent, 0, 0, parent.getWidth() * parent.getHeight() * + parent.getDepth() * format.getElementSize()) + , impl_(format, Coord3D(parent.getWidth() * + parent.getImageFormat().getElementSize() / + format.getElementSize(), parent.getHeight(), + parent.getDepth()), parent.getRowPitch(), + parent.getSlicePitch(), parent.getBytePitch()) + , mipLevels_(1) { initDimension(); } @@ -566,10 +572,11 @@ Image::Image( size_t height, size_t depth, size_t rowPitch, - size_t slicePitch) : - Memory(context, type, flags, - width * height * depth * format.getElementSize()) , - impl_(format, Coord3D(width, height, depth), rowPitch, slicePitch) + size_t slicePitch, + uint mipLevels) + : Memory(context, type, flags, width * height * depth * format.getElementSize()) + , impl_(format, Coord3D(width, height, depth), rowPitch, slicePitch) + , mipLevels_(mipLevels) { initDimension(); } @@ -583,10 +590,10 @@ Image::Image( size_t height, size_t depth, size_t rowPitch, - size_t slicePitch) : - Memory(buffer, flags, 0, - buffer.getSize(), type) , - impl_(format, Coord3D(width, height, depth), rowPitch, slicePitch) + size_t slicePitch) + : Memory(buffer, flags, 0, buffer.getSize(), type) + , impl_(format, Coord3D(width, height, depth), rowPitch, slicePitch) + , mipLevels_(1) { initDimension(); } @@ -600,17 +607,16 @@ Image::validateDimensions( size_t depth, size_t arraySize) { - std::vector::const_iterator it; bool sizePass = false; switch (type) { case CL_MEM_OBJECT_IMAGE3D: if ((width == 0) || (height == 0) || (depth < 1)) { return false; } - for (it = devices.begin(); it != devices.end(); ++it) { - if (((*it)->info().image3DMaxWidth_ >= width) && - ((*it)->info().image3DMaxHeight_ >= height) && - ((*it)->info().image3DMaxDepth_ >= depth)) { + for (const auto& dev : devices) { + if ((dev->info().image3DMaxWidth_ >= width) && + (dev->info().image3DMaxHeight_ >= height) && + (dev->info().image3DMaxDepth_ >= depth)) { return true; } } @@ -619,8 +625,8 @@ Image::validateDimensions( if (arraySize == 0) { return false; } - for (it = devices.begin(); it != devices.end(); ++it) { - if ((*it)->info().imageMaxArraySize_ >= arraySize) { + for (const auto& dev : devices) { + if (dev->info().imageMaxArraySize_ >= arraySize) { sizePass = true; break; } @@ -633,9 +639,9 @@ Image::validateDimensions( if ((width == 0) || (height == 0)) { return false; } - for (it = devices.begin(); it != devices.end(); ++it) { - if (((*it)->info().image2DMaxHeight_ >= height) && - ((*it)->info().image2DMaxWidth_ >= width)) { + for (const auto dev : devices) { + if ((dev->info().image2DMaxHeight_ >= height) && + (dev->info().image2DMaxWidth_ >= width)) { return true; } } @@ -645,8 +651,8 @@ Image::validateDimensions( return false; } - for (it = devices.begin(); it != devices.end(); ++it) { - if ((*it)->info().imageMaxArraySize_ >= arraySize) { + for (const auto& dev : devices) { + if (dev->info().imageMaxArraySize_ >= arraySize) { sizePass = true; break; } @@ -659,8 +665,8 @@ Image::validateDimensions( if (width == 0) { return false; } - for (it = devices.begin(); it != devices.end(); ++it) { - if ((*it)->info().image2DMaxWidth_ >= width) { + for (const auto& dev : devices) { + if (dev->info().image2DMaxWidth_ >= width) { return true; } } @@ -669,8 +675,8 @@ Image::validateDimensions( if (width == 0) { return false; } - for (it = devices.begin(); it != devices.end(); ++it) { - if ((*it)->info().imageMaxBufferSize_ >= width) { + for (const auto& dev : devices) { + if (dev->info().imageMaxBufferSize_ >= width) { return true; } } @@ -1488,7 +1494,7 @@ bool SvmBuffer::Contains(uintptr_t ptr) { ScopedLock lock(AllocatedLock_); - std::map::iterator it = Allocated_.upper_bound(ptr); + auto it = Allocated_.upper_bound(ptr); if (it == Allocated_.begin()) { return false; } diff --git a/rocclr/runtime/platform/memory.hpp b/rocclr/runtime/platform/memory.hpp index 24b5db1c7e..dab5a2b44f 100644 --- a/rocclr/runtime/platform/memory.hpp +++ b/rocclr/runtime/platform/memory.hpp @@ -490,10 +490,10 @@ public: struct Impl { - const amd::Coord3D region_; - size_t rp_; - size_t sp_; - const Format format_; + const amd::Coord3D region_; //!< Image size + size_t rp_; //!< Image row pitch + size_t sp_; //!< Image slice pitch + const Format format_; //!< Image format void* reserved_; size_t bp_; @@ -505,6 +505,7 @@ public: private: Impl impl_; //!< Image object description size_t dim_; //!< Image dimension + uint mipLevels_; //!< The number of mip levels protected: Image( @@ -532,7 +533,8 @@ public: size_t height, size_t depth, size_t rowPitch, - size_t slicePitch); + size_t slicePitch, + uint mipLevels = 1); Image( Buffer& buffer, @@ -612,10 +614,13 @@ public: //! Returns image's slice pitch in bytes size_t getSlicePitch() const { return impl_.sp_; } + //! Returns image's slice pitch in bytes + uint getMipLevels() const { return mipLevels_; } + //! Get the image covered region const Coord3D& getRegion() const { return impl_.region_; } - //! Sets the byte pitch obtained from HWL. + //! Sets the byte pitch obtained from HWL void setBytePitch(size_t bytePitch) { impl_.bp_ = bytePitch; } //! Creates and initializes device (cache) memory for all devices diff --git a/rocclr/runtime/utils/flags.hpp b/rocclr/runtime/utils/flags.hpp index 6b18aaaf96..211b7dd323 100644 --- a/rocclr/runtime/utils/flags.hpp +++ b/rocclr/runtime/utils/flags.hpp @@ -168,8 +168,8 @@ release(bool, HSA_ENABLE_ATOMICS_32B, false, \ "1 = Enable SVM atomics in 32 bits (HSA backend-only). Any other value keeps then disabled.") \ release(bool, GPU_IFH_MODE, false, \ "1 = Enable GPU IFH (infinitely fast hardware) mode. Any other value keeps setting disabled.") \ -release(bool, HSAIL_IMAGE_HANDLE_ENABLE, false, \ - "Pass image/sampler SRD as pointer instead of blob") \ +release(bool, GPU_MIPMAP, false, \ + "Enables GPU mipmap extension") \ debug(bool, GPU_FORCE_SINGLE_FP_DENORM, false, \ "Forces reporting CL_FP_DENORM bit for single precision") \ debug(bool, OCL_FORCE_CPU_SVM, false, \