/* * Copyright (c) Advanced Micro Devices, Inc., or its affiliates. * * SPDX-License-Identifier: MIT */ #pragma once #include "interop_d3d10.hpp" #include "platform/context.hpp" #include "platform/memory.hpp" #include namespace amd { typedef struct { union { UINT ByteWidth; UINT Width; }; UINT Height; UINT Depth; } D3D11ObjSize_t; typedef struct { D3D11_USAGE d3d11Usage_; UINT bindFlags_; UINT cpuAccessFlags_; UINT miscFlags_; UINT structureByteStride_; } D3D11Flags_t; typedef struct { D3D11_RESOURCE_DIMENSION objDim_; D3D11ObjSize_t objSize_; D3D11Flags_t objFlags_; UINT mipLevels_; UINT arraySize_; DXGI_FORMAT dxgiFormat_; DXGI_SAMPLE_DESC dxgiSampleDesc_; } D3D11ObjDesc_t; //! Class D3D11Object keeps all the info about the D3D11 object //! from which the CL object is created class D3D11Object : public InteropObject { private: ID3D11Resource* pD3D11Aux_; bool releaseResources_; static std::vector>> resources_; protected: //! Global lock. static Monitor resLock_; ID3D11Resource* pD3D11Res_; ID3D11Resource* pD3D11ResOrig_; ID3D11Query* pQuery_; D3D11ObjDesc_t objDesc_; UINT subRes_; INT plane_; public: // Default constructor D3D11Object() : pD3D11Aux_(nullptr), releaseResources_(false), pD3D11Res_(nullptr), pD3D11ResOrig_(nullptr), pQuery_(nullptr), subRes_(NULL), plane_(NULL) { memset(&objDesc_, 0, sizeof(objDesc_)); } // Copy constructor D3D11Object(D3D11Object& d3d11obj) : pQuery_(NULL) { *this = d3d11obj; this->releaseResources_ = true; // Add reference to the D3D11 resource to prevent its disappearance if (pD3D11ResOrig_) { pD3D11ResOrig_->AddRef(); } else if (pD3D11Res_) { pD3D11Res_->AddRef(); } assert(pD3D11Res_ != pD3D11ResOrig_); } //! Virtual destructor virtual ~D3D11Object() { ScopedLock sl(resLock_); if (releaseResources_) { // Decrement reference to the D3D11 objects if (pD3D11Res_) pD3D11Res_->Release(); if (pD3D11Aux_) pD3D11Aux_->Release(); if (pD3D11ResOrig_) pD3D11ResOrig_->Release(); if (pQuery_) pQuery_->Release(); // Check if this resource has already been used for interop if (resources_.size()) { for (auto it = resources_.cbegin(); it != resources_.cend(); it++) { if (((pD3D11ResOrig_ && (*it).first == (void*)pD3D11ResOrig_) || ((*it).first == (void*)pD3D11Res_)) && (*it).second.first == subRes_ && (*it).second.second == plane_) { resources_.erase(it); break; } } } } } static int initD3D11Object(const Context& amdContext, ID3D11Resource* pRes, UINT subresource, D3D11Object& obj, INT plane = -1); D3D11Object* asD3D11Object() { return this; } //! D3D11Object query functions to get D3D11 info from member variables ID3D11Resource* getD3D11Resource() const { return pD3D11Res_; } ID3D11Resource* getD3D11ResOrig() const { return pD3D11ResOrig_; } ID3D11Query* getQuery() const { return pQuery_; } Monitor& getResLock() { return resLock_; } UINT getWidth() const { return objDesc_.objSize_.Width; } UINT getHeight() const { return objDesc_.objSize_.Height; } UINT getDepth() const { return objDesc_.objSize_.Depth; } size_t getElementBytes(DXGI_FORMAT dxgiFomat, cl_uint plane); size_t getElementBytes() { return getElementBytes(objDesc_.dxgiFormat_, plane_); } DXGI_FORMAT getDxgiFormat() { return objDesc_.dxgiFormat_; } UINT getSubresource() const { return subRes_; } INT getPlane() const { return plane_; } const D3D11ObjDesc_t* getObjDesc() const { return &objDesc_; } cl_uint getMiscFlag(void); //! Returns bytes per pixel > 0 if conversion successful, 0 otherwise; //! if formats are not compatible, cl format channel //! order and type are set to 0 cl_image_format getCLFormatFromDXGI(DXGI_FORMAT dxgiFmt, cl_uint plane); cl_image_format getCLFormatFromDXGI() { return getCLFormatFromDXGI(objDesc_.dxgiFormat_, plane_); } size_t getResourceByteSize(); // On acquire copy data from original resource to shared resource virtual bool copyOrigToShared(); // On release copy data from shared copy to the original resource virtual bool copySharedToOrig(); }; //! Class BufferD3D11 is derived from classes Buffer and D3D11Object //! where the former keeps all data for CL object and //! the latter keeps all data for D3D11 object class BufferD3D11 : public D3D11Object, public Buffer { protected: //! Initializes the device memory array which is nested // after'BufferD3D11' object in memory layout. virtual void initDeviceMemory(); public: //! BufferD3D11 constructor just calls constructors of base classes //! to pass down the parameters BufferD3D11(Context& amdContext, cl_mem_flags clFlags, D3D11Object& d3d11obj) : // Call base classes constructors D3D11Object(d3d11obj), Buffer(amdContext, clFlags, d3d11obj.getResourceByteSize()) { setInteropObj(this); } virtual ~BufferD3D11() {} }; //! Class Image1DD3D11 is derived from classes Image1D and D3D11Object //! where the former keeps all data for CL object and //! the latter keeps all data for D3D11 object class Image1DD3D11 : public D3D11Object, public Image { protected: //! Initializes the device memory array which is nested // after'Image1DD3D11' object in memory layout. virtual void initDeviceMemory(); public: //! Image1DD3D11 constructor just calls constructors of base classes //! to pass down the parameters Image1DD3D11(Context& amdContext, cl_mem_flags clFlags, D3D11Object& d3d11obj) : // Call base classes constructors D3D11Object(d3d11obj), Image(amdContext, CL_MEM_OBJECT_IMAGE1D, clFlags, getCLFormatFromDXGI(d3d11obj.getDxgiFormat(), d3d11obj.getPlane()), // format, d3d11obj.getWidth(), 1, 1, d3d11obj.getWidth() * d3d11obj.getElementBytes(), // rowPitch), 0) { setInteropObj(this); } virtual ~Image1DD3D11() {} }; //! Class Image2DD3D11 is derived from classes Image2D and D3D11Object //! where the former keeps all data for CL object and //! the latter keeps all data for D3D11 object class Image2DD3D11 : public Image, public D3D11Object { protected: //! Initializes the device memory array which is nested // after'Image2DD3D11' object in memory layout. virtual void initDeviceMemory(); public: //! Image2DD3D11 constructor just calls constructors of base classes //! to pass down the parameters Image2DD3D11(Context& amdContext, cl_mem_flags clFlags, D3D11Object& d3d11obj) : // Call base classes constructors D3D11Object(d3d11obj), Image(amdContext, CL_MEM_OBJECT_IMAGE2D, clFlags, getCLFormatFromDXGI(d3d11obj.getDxgiFormat(), d3d11obj.getPlane()), // format, d3d11obj.getWidth(), d3d11obj.getHeight(), 1, d3d11obj.getWidth() * d3d11obj.getElementBytes(), // rowPitch), 0) { setInteropObj(this); } virtual ~Image2DD3D11() {} }; //! Class Image3DD3D11 is derived from classes Image3D and D3D11Object //! where the former keeps all data for CL object and //! the latter keeps all data for D3D11 object class Image3DD3D11 : public D3D11Object, public Image { protected: //! Initializes the device memory array which is nested // after'Image3DD3D11' object in memory layout. virtual void initDeviceMemory(); public: //! Image2DD3D11 constructor just calls constructors of base classes //! to pass down the parameters Image3DD3D11(Context& amdContext, cl_mem_flags clFlags, D3D11Object& d3d11obj) : // Call base classes constructors D3D11Object(d3d11obj), Image(amdContext, CL_MEM_OBJECT_IMAGE3D, clFlags, getCLFormatFromDXGI(d3d11obj.getDxgiFormat(), d3d11obj.getPlane()), // format, d3d11obj.getWidth(), d3d11obj.getHeight(), d3d11obj.getDepth(), d3d11obj.getWidth() * d3d11obj.getElementBytes(), // rowPitch), d3d11obj.getWidth() * d3d11obj.getHeight() * d3d11obj.getElementBytes()) { setInteropObj(this); } virtual ~Image3DD3D11() {} }; } // namespace amd