CUDA.APIComps.pas 74 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943
  1. //
  2. // The graphics platform GLScene https://github.com/glscene
  3. //
  4. unit CUDA.APIComps;
  5. (* CUDA API routines implementation *)
  6. interface
  7. {$I GLScene.inc}
  8. uses
  9. System.Types,
  10. System.Classes,
  11. System.SysUtils,
  12. GLS.PersistentClasses,
  13. GLS.BaseClasses,
  14. GLS.Context,
  15. GLS.VectorGeometry,
  16. GLS.VectorTypes,
  17. GLS.VectorLists,
  18. GLS.Graphics,
  19. GLS.Strings,
  20. GLS.Utils,
  21. CUDA.Import,
  22. CUDA.RunTime,
  23. CUDA.Parser,
  24. CUDA.FourierTransform,
  25. CUDA.Compiler,
  26. CUDA.Context,
  27. CUDA.DataAccess;
  28. type
  29. TCUDAChange = (cuchDevice, cuchContext, cuchSize, cuchAddresMode, cuchFlag,
  30. cuchFilterMode, cuchArray, cuchFormat, cuchMapping);
  31. TCUDAChanges = set of TCUDAChange;
  32. TCuAddresMode = (amWrap, amClamp, amMirror);
  33. TCuFilterMode = (fmPoint, fmLinear);
  34. TCUDAChannelType = (ctUndefined, ctUInt8, ctUInt16, ctUInt32, ctInt8, ctInt16,
  35. ctInt32, ctHalfFloat, ctFloat, ctDouble);
  36. type
  37. TCUDAChannelNum = (cnOne, cnTwo, cnThree, cnFour);
  38. TChannelTypeAndNum = record
  39. F: TCUDAChannelType;
  40. C: TCUDAChannelNum;
  41. end;
  42. TCUDAMapping = (grmDefault, grmReadOnly, grmWriteDiscard);
  43. TCUDAComponent = class(TCUDAHandlesMaster)
  44. private
  45. FMaster: TCUDAComponent;
  46. FItems: TGLPersistentObjectList;
  47. procedure SetMaster(AMaster: TCUDAComponent);
  48. function GetItem(const i: Integer): TCUDAComponent;
  49. function GetItemsCount: Integer;
  50. protected
  51. FStatus: TCUresult;
  52. FChanges: TCUDAChanges;
  53. function GetContext: TCUDAContext; override;
  54. procedure CollectStatus(AStatus: TCUresult);
  55. procedure GetChildren(AProc: TGetChildProc; Root: TComponent); override;
  56. procedure AddItem(AItem: TCUDAComponent);
  57. procedure RemoveItem(AItem: TCUDAComponent);
  58. procedure DeleteItems;
  59. procedure SetName(const NewName: TComponentName); override;
  60. function GetIsAllocated: Boolean; virtual; abstract;
  61. public
  62. destructor Destroy; override;
  63. procedure CuNotifyChange(AChange: TCUDAChange); virtual;
  64. function GetParentComponent: TComponent; override;
  65. procedure SetParentComponent(Value: TComponent); override;
  66. function HasParent: Boolean; override;
  67. function GetItemByName(const name: string): TCUDAComponent;
  68. function MakeUniqueName(const BaseName: string): string;
  69. property Master: TCUDAComponent read FMaster write SetMaster;
  70. property Context: TCUDAContext read GetContext;
  71. property Items[const i: Integer]: TCUDAComponent read GetItem;
  72. property ItemsCount: Integer read GetItemsCount;
  73. property Status: TCUresult read FStatus;
  74. // Return true if handle is allocated (i.e. component has device object)
  75. property IsAllocated: Boolean read GetIsAllocated;
  76. end;
  77. TCUDAComponentClass = class of TCUDAComponent;
  78. TCUDAMemData = class;
  79. TCUDAFunction = class;
  80. TCUDATexture = class;
  81. TGLCUDA = class;
  82. TCUDAConstant = class;
  83. TCUDAModule = class(TCUDAComponent)
  84. private
  85. FHandle: PCUmodule;
  86. FCode: TStringList;
  87. FCodeType: TGLCUDACompilerOutput;
  88. FCompiler: TGLCUDACompiler;
  89. procedure SetCode(const Value: TStringList);
  90. procedure SetCompiler(const Value: TGLCUDACompiler);
  91. function GetKernelFunction(const AName: string): TCUDAFunction;
  92. function GetKernelTexture(const AName: string): TCUDATexture;
  93. function GetKernelConstant(const AName: string): TCUDAConstant;
  94. protected
  95. procedure AllocateHandles; override;
  96. procedure DestroyHandles; override;
  97. procedure OnChangeCode(Sender: TObject);
  98. procedure Loaded; override;
  99. function GetContext: TCUDAContext; override;
  100. function GetIsAllocated: Boolean; override;
  101. public
  102. constructor Create(AOwner: TComponent); override;
  103. destructor Destroy; override;
  104. procedure Assign(Source: TPersistent); override;
  105. procedure LoadFromFile(const AFilename: string);
  106. procedure LoadFromSource;
  107. procedure Unload;
  108. procedure LoadAndCompile;
  109. property Context: TCUDAContext read GetContext;
  110. property CodeType: TGLCUDACompilerOutput read FCodeType;
  111. property KernelFunction[const AName: string]: TCUDAFunction
  112. read GetKernelFunction;
  113. property KernelTexture[const AName: string]: TCUDATexture
  114. read GetKernelTexture;
  115. property KernelConstant[const AName: string]: TCUDAConstant
  116. read GetKernelConstant;
  117. published
  118. property Code: TStringList read FCode write SetCode;
  119. property Compiler: TGLCUDACompiler read FCompiler write SetCompiler;
  120. end;
  121. TGLResourceType = (rtTexture, rtBuffer);
  122. // Abstract class of graphic resources.
  123. TCUDAGraphicResource = class(TCUDAComponent)
  124. protected
  125. FHandle: array [0 .. 7] of PCUgraphicsResource;
  126. FMapping: TCUDAMapping;
  127. FResourceType: TGLResourceType;
  128. FGLContextHandle: TGLVirtualHandle;
  129. FMapCounter: Integer;
  130. function GetIsAllocated: Boolean; override;
  131. procedure OnGLHandleAllocate(Sender: TGLVirtualHandle;
  132. var Handle: Cardinal);
  133. procedure OnGLHandleDestroy(Sender: TGLVirtualHandle; var Handle: Cardinal);
  134. procedure BindArrayToTexture(var cudaArray: TCUDAMemData;
  135. ALeyer, ALevel: LongWord); virtual; abstract;
  136. procedure SetArray(var AArray: TCUDAMemData; AHandle: PCUarray;
  137. ForGLTexture, Volume: Boolean);
  138. function GetAttributeArraySize(const Attr: string): LongWord; virtual; abstract;
  139. function GetAttributeArrayAddress(const Attr: string): Pointer; virtual;
  140. abstract;
  141. function GetElementArrayDataSize: LongWord; virtual; abstract;
  142. function GetElementArrayAddress: Pointer; virtual; abstract;
  143. procedure SetMapping(const Value: TCUDAMapping); virtual;
  144. property Mapping: TCUDAMapping read FMapping write SetMapping
  145. default grmDefault;
  146. public
  147. procedure MapResources; virtual; abstract;
  148. procedure UnMapResources; virtual; abstract;
  149. end;
  150. TCUDAMemType = (mtHost, mtDevice, mtArray);
  151. TCUDAMemMapFlag =
  152. (
  153. mmfPortable, // Memory is shared between contexts
  154. mmfFastWrite // Fast write, slow read
  155. );
  156. TCUDAMemMapFlags = set of TCUDAMemMapFlag;
  157. TCUDAMemData = class(TCUDAComponent)
  158. private
  159. FData: TCUdeviceptr;
  160. FMappedMemory: TCUdeviceptr;
  161. FHandle: PCUarray;
  162. FWidth: Integer;
  163. FHeight: Integer;
  164. FDepth: Integer;
  165. FPitch: Cardinal;
  166. FElementSize: Integer;
  167. FDataSize: Integer;
  168. FChannelsType: TCUDAChannelType;
  169. fChannelsNum: TCUDAChannelNum;
  170. FMemoryType: TCUDAMemType;
  171. FTexture: TCUDATexture;
  172. FOpenGLRefArray: Boolean;
  173. FMapping: Boolean;
  174. procedure SetMemoryType(const AType: TCUDAMemType);
  175. procedure SetWidth(const Value: Integer);
  176. procedure SetHeight(const Value: Integer);
  177. procedure SetDepth(const Value: Integer);
  178. procedure SetChannelType(const Value: TCUDAChannelType);
  179. procedure SetChannelNum(const Value: TCUDAChannelNum);
  180. function GetData: TCUdeviceptr;
  181. function GetArrayHandle: PCUarray;
  182. protected
  183. procedure AllocateHandles; override;
  184. procedure DestroyHandles; override;
  185. function GetIsAllocated: Boolean; override;
  186. public
  187. constructor Create(AOwner: TComponent); override;
  188. destructor Destroy; override;
  189. procedure CuNotifyChange(AChange: TCUDAChange); override;
  190. (* Map device and array memory to host or host memory to device.
  191. Mapping is necessary for modifying device data.
  192. When mapped host memory - it can be accessed in device side
  193. via MappedHostAddress. *)
  194. procedure Map(const AFlags: TCUDAMemMapFlags = []);
  195. // Done mapping operation.
  196. procedure UnMap;
  197. function Data<EType>(X: Integer): GCUDAHostElementAccess<EType>; overload;
  198. function Data<EType>(X, Y: Integer): GCUDAHostElementAccess<EType>; overload;
  199. function Data<EType>(X, Y, Z: Integer): GCUDAHostElementAccess<EType>; overload;
  200. // Fill device data
  201. procedure FillMem(const Value);
  202. procedure CopyTo(const ADstMemData: TCUDAMemData); overload;
  203. procedure CopyTo(const AGLImage: TGLImage); overload;
  204. // Copy data to Graphic resource.
  205. procedure CopyTo(const AGLGraphic: TCUDAGraphicResource;
  206. aAttr: string = ''); overload;
  207. procedure CopyFrom(const ASrcMemData: TCUDAMemData); overload;
  208. procedure CopyFrom(const AGLImage: TGLBitmap32); overload;
  209. procedure CopyFrom(const AGLGraphic: TCUDAGraphicResource;
  210. aAttr: string = ''); overload;
  211. procedure SubCopyTo(const ADstMemData: TCUDAMemData;
  212. ASrcXYZ, ADstXYZ, ASizes: IntElement.TVector3);
  213. property ElementSize: Integer read FElementSize;
  214. property DataSize: Integer read FDataSize;
  215. property Pitch: Cardinal read fPitch;
  216. property RawData: TCUdeviceptr read GetData;
  217. property MappedMemoryAddress: TCUdeviceptr read FMappedMemory;
  218. property ArrayHandle: PCUarray read GetArrayHandle;
  219. published
  220. property Width: Integer read fWidth write SetWidth default 256;
  221. property Height: Integer read fHeight write SetHeight default 0;
  222. property Depth: Integer read fDepth write SetDepth default 0;
  223. property MemoryType: TCUDAMemType read FMemoryType write SetMemoryType
  224. default mtHost;
  225. property ChannelsType: TCUDAChannelType read fChannelsType
  226. write SetChannelType default ctInt8;
  227. property ChannelsNum: TCUDAChannelNum read fChannelsNum write SetChannelNum
  228. default cnOne;
  229. end;
  230. TCUDAUniform = class(TCUDAComponent)
  231. protected
  232. FHandle: TCUdeviceptr;
  233. FSize: Cardinal;
  234. FKernelName: string;
  235. FType: TCUDAType;
  236. FCustomType: string;
  237. FRef: Boolean;
  238. FDefined: Boolean;
  239. procedure SetKernelName(const AName: string);
  240. procedure SetType(AValue: TCUDAType);
  241. procedure SetCustomType(const AValue: string);
  242. procedure SetSize(const AValue: Cardinal);
  243. procedure SetRef(AValue: Boolean);
  244. procedure SetDefined(AValue: Boolean);
  245. property KernelName: string read FKernelName write SetKernelName;
  246. property DataType: TCUDAType read FType write SetType;
  247. property CustomType: string read FCustomType write SetCustomType;
  248. property Size: Cardinal read FSize write SetSize;
  249. property Reference: Boolean read FRef write SetRef;
  250. function GetIsAllocated: Boolean; override;
  251. public
  252. constructor Create(AOwner: TComponent); override;
  253. destructor Destroy; override;
  254. property IsValueDefined: Boolean read FDefined write SetDefined;
  255. end;
  256. TCUDAConstant = class(TCUDAUniform)
  257. protected
  258. procedure AllocateHandles; override;
  259. procedure DestroyHandles; override;
  260. function GetDeviceAddress: TCUdeviceptr;
  261. public
  262. property DeviceAddress: TCUdeviceptr read GetDeviceAddress;
  263. published
  264. property KernelName;
  265. property DataType;
  266. property CustomType;
  267. property Size;
  268. property Reference;
  269. end;
  270. TCUDAFuncParam = class(TCUDAUniform)
  271. protected
  272. procedure AllocateHandles; override;
  273. procedure DestroyHandles; override;
  274. public
  275. constructor Create(AOwner: TComponent); override;
  276. published
  277. property KernelName;
  278. property DataType;
  279. property CustomType;
  280. property Size;
  281. property Reference;
  282. end;
  283. TCUDAFunction = class(TCUDAComponent)
  284. private
  285. FKernelName: string;
  286. FHandle: PCUfunction;
  287. FAutoSync: Boolean;
  288. FBlockShape: TCUDADimensions;
  289. FGrid: TCUDADimensions;
  290. ParamOffset: Integer;
  291. FLaunching: Boolean;
  292. FOnParameterSetup: TNotifyEvent;
  293. procedure SetBlockShape(const AShape: TCUDADimensions);
  294. procedure SetGrid(const AGrid: TCUDADimensions);
  295. procedure SetKernelName(const AName: string);
  296. function GetHandle: PCUfunction;
  297. procedure SetSharedMemorySize(Value: Integer);
  298. function GetSharedMemorySize: Integer;
  299. function GetMaxThreadPerBlock: Integer;
  300. function GetConstMemorySize: Integer;
  301. function GetLocalMemorySize: Integer;
  302. function GetNumRegisters: Integer;
  303. function GetParameter(const AName: string): TCUDAFuncParam;
  304. protected
  305. procedure AllocateHandles; override;
  306. procedure DestroyHandles; override;
  307. function GetIsAllocated: Boolean; override;
  308. public
  309. constructor Create(AOwner: TComponent); override;
  310. destructor Destroy; override;
  311. procedure SetParam(Value: Integer); overload;
  312. procedure SetParam(Value: Cardinal); overload;
  313. procedure SetParam(Value: Single); overload;
  314. procedure SetParam(Value: TVector2i); overload;
  315. procedure SetParam(Value: TVector3i); overload;
  316. procedure SetParam(Value: TVector4i); overload;
  317. procedure SetParam(Value: TVector2f); overload;
  318. procedure SetParam(Value: TVector3f); overload;
  319. procedure SetParam(Value: TVector4f); overload;
  320. procedure SetParam(MemData: TCUDAMemData); overload;
  321. procedure SetParam(TexRef: TCUDATexture); overload;
  322. procedure SetParam(Ptr: Pointer); overload;
  323. property Parameters[const AName: string]: TCUDAFuncParam read GetParameter;
  324. procedure Launch(Grided: Boolean = true);
  325. property Handle: PCUfunction read GetHandle;
  326. property SharedMemorySize: Integer read GetSharedMemorySize
  327. write SetSharedMemorySize;
  328. property MaxThreadPerBlock: Integer read GetMaxThreadPerBlock;
  329. property ConstMemorySize: Integer read GetConstMemorySize;
  330. property LocalMemorySize: Integer read GetLocalMemorySize;
  331. property NumRegisters: Integer read GetNumRegisters;
  332. published
  333. property KernelName: string read FKernelName write SetKernelName;
  334. property AutoSync: Boolean read FAutoSync write FAutoSync default true;
  335. property BlockShape: TCUDADimensions read FBlockShape write SetBlockShape;
  336. property Grid: TCUDADimensions read FGrid write SetGrid;
  337. property OnParameterSetup: TNotifyEvent read FOnParameterSetup
  338. write FOnParameterSetup;
  339. end;
  340. TCUDATexture = class(TCUDAComponent)
  341. private
  342. FKernelName: string;
  343. FHandle: PCUtexref;
  344. fArray: TCUDAMemData;
  345. fAddressModeS, fAddressModeT, fAddressModeR: TCuAddresMode;
  346. fNormalizedCoord: Boolean;
  347. fReadAsInteger: Boolean;
  348. fFilterMode: TCuFilterMode;
  349. fFormat: TCUDAChannelType;
  350. fChannelNum: TCUDAChannelNum;
  351. procedure SetKernelName(const AName: string);
  352. procedure SetAddressModeS(const AMode: TCuAddresMode);
  353. procedure SetAddressModeT(const AMode: TCuAddresMode);
  354. procedure SetAddressModeR(const AMode: TCuAddresMode);
  355. procedure SetNormalizedCoord(const flag: Boolean);
  356. procedure SetReadAsInteger(const flag: Boolean);
  357. procedure SetFilterMode(const mode: TCuFilterMode);
  358. procedure SetFormat(AValue: TCUDAChannelType);
  359. procedure SetChannelNum(AValue: TCUDAChannelNum);
  360. procedure SetArray(Value: TCUDAMemData);
  361. function GetHandle: PCUtexref;
  362. protected
  363. procedure AllocateHandles; override;
  364. procedure DestroyHandles; override;
  365. function GetIsAllocated: Boolean; override;
  366. public
  367. constructor Create(AOwner: TComponent); override;
  368. destructor Destroy; override;
  369. property Handle: PCUtexref read GetHandle;
  370. published
  371. property KernelName: string read FKernelName write SetKernelName;
  372. property AddressModeS: TCuAddresMode read fAddressModeS
  373. write SetAddressModeS default amClamp;
  374. property AddressModeT: TCuAddresMode read fAddressModeT
  375. write SetAddressModeT default amClamp;
  376. property AddressModeR: TCuAddresMode read fAddressModeR
  377. write SetAddressModeR default amClamp;
  378. property NormalizedCoord: Boolean read fNormalizedCoord
  379. write SetNormalizedCoord default true;
  380. property ReadAsInteger: Boolean read fReadAsInteger write SetReadAsInteger
  381. default false;
  382. property FilterMode: TCuFilterMode read fFilterMode write SetFilterMode
  383. default fmPoint;
  384. property Format: TCUDAChannelType read fFormat write SetFormat;
  385. property ChannelNum: TCUDAChannelNum read fChannelNum write SetChannelNum;
  386. property MemDataArray: TCUDAMemData read fArray write SetArray;
  387. end;
  388. TGLCUDA = class(TCUDAComponent)
  389. private
  390. fDevice: TGLCUDADevice;
  391. fContext: TCUDAContext;
  392. FOnOpenGLInteropInit: TOnOpenGLInteropInit;
  393. procedure SetDevice(const Value: TGLCUDADevice);
  394. procedure SetOnOpenGLInteropInit(AEvent: TOnOpenGLInteropInit);
  395. function GetModule(const i: Integer): TCUDAModule;
  396. protected
  397. procedure Notification(AComponent: TComponent;
  398. Operation: TOperation); override;
  399. function GetContext: TCUDAContext; override;
  400. function GetIsAllocated: Boolean; override;
  401. public
  402. constructor Create(AOwner: TComponent); override;
  403. destructor Destroy; override;
  404. property Context: TCUDAContext read GetContext;
  405. property Modules[const i: Integer]: TCUDAModule read GetModule;
  406. published
  407. property ComputingDevice: TGLCUDADevice read fDevice write SetDevice;
  408. property OnOpenGLInteropInit: TOnOpenGLInteropInit read FOnOpenGLInteropInit
  409. write SetOnOpenGLInteropInit;
  410. end;
  411. function GetChannelTypeAndNum(AType: TCUDAType): TChannelTypeAndNum;
  412. procedure RegisterCUDAComponentNameChangeEvent(ANotifyEvent: TNotifyEvent);
  413. procedure DeRegisterCUDAComponentNameChangeEvent;
  414. //-----------------------------------------------------------------
  415. implementation
  416. //-----------------------------------------------------------------
  417. const
  418. cAddressMode: array [TCuAddresMode] of TCUaddress_mode =
  419. (CU_TR_ADDRESS_MODE_WRAP, CU_TR_ADDRESS_MODE_CLAMP,
  420. CU_TR_ADDRESS_MODE_MIRROR);
  421. cFilterMode: array [TCuFilterMode] of TCUfilter_mode =
  422. (CU_TR_FILTER_MODE_POINT, CU_TR_FILTER_MODE_LINEAR);
  423. const
  424. cCUDATypeToTexFormat: array [TCUDAType] of TChannelTypeAndNum =
  425. ((F: ctUndefined; C: cnOne), (F: ctInt8; C: cnOne), (F: ctUInt8; C: cnOne),
  426. (F: ctInt8; C: cnTwo), (F: ctUInt8; C: cnTwo), (F: ctInt8; C: cnThree),
  427. (F: ctUInt8; C: cnThree), (F: ctInt8; C: cnFour), (F: ctUInt8; C: cnFour),
  428. (F: ctInt16; C: cnOne), (F: ctUInt16; C: cnOne), (F: ctInt16; C: cnTwo),
  429. (F: ctUInt16; C: cnTwo), (F: ctInt16; C: cnThree), (F: ctUInt16;
  430. C: cnThree), (F: ctInt16; C: cnFour), (F: ctUInt16; C: cnFour), (F: ctInt32;
  431. C: cnOne), (F: ctUInt32; C: cnOne), (F: ctInt32; C: cnTwo), (F: ctUInt32;
  432. C: cnTwo), (F: ctInt32; C: cnThree), (F: ctUInt32; C: cnThree), (F: ctInt32;
  433. C: cnFour), (F: ctUInt32; C: cnFour), (F: ctUndefined; C: cnOne),
  434. (F: ctUndefined; C: cnOne), (F: ctUndefined; C: cnTwo), (F: ctUndefined;
  435. C: cnTwo), (F: ctUndefined; C: cnThree), (F: ctUndefined; C: cnThree),
  436. (F: ctUndefined; C: cnFour), (F: ctUndefined; C: cnFour), (F: ctFloat;
  437. C: cnOne), (F: ctFloat; C: cnTwo), (F: ctFloat; C: cnThree), (F: ctFloat;
  438. C: cnFour), (F: ctUndefined; C: cnOne), (F: ctUndefined; C: cnOne),
  439. (F: ctUndefined; C: cnTwo), (F: ctUndefined; C: cnTwo), (F: ctUndefined;
  440. C: cnThree), (F: ctUndefined; C: cnThree), (F: ctUndefined; C: cnFour),
  441. (F: ctUndefined; C: cnFour), (F: ctUndefined; C: cnOne), (F: ctUndefined;
  442. C: cnTwo), (F: ctUndefined; C: cnThree), (F: ctUndefined; C: cnFour),
  443. (F: ctInt8; C: cnOne), (F: ctInt16; C: cnOne), (F: ctInt32; C: cnOne),
  444. (F: ctUInt8; C: cnOne), (F: ctUInt16; C: cnOne), (F: ctUInt32; C: cnOne));
  445. cChannelTypeSize: array [TCUDAChannelType] of Integer =
  446. (0, 1, 2, 4, 1, 2, 4, 2, 4, 8);
  447. var
  448. GLVirtualHandleCounter: Cardinal = 1;
  449. vCUDAComponentNameChangeEvent: TNotifyEvent;
  450. function GetChannelTypeAndNum(AType: TCUDAType): TChannelTypeAndNum;
  451. begin
  452. Result := cCUDATypeToTexFormat[AType];
  453. end;
  454. procedure CUDAEnumToChannelDesc(const Fmt: TCUarray_format; const nCh: LongWord;
  455. out oFormat: TCUDAChannelType; out oNum: TCUDAChannelNum);
  456. begin
  457. case Fmt of
  458. CU_AD_FORMAT_UNSIGNED_INT8:
  459. oFormat := ctUInt8;
  460. CU_AD_FORMAT_UNSIGNED_INT16:
  461. oFormat := ctUInt16;
  462. CU_AD_FORMAT_UNSIGNED_INT32:
  463. oFormat := ctUInt32;
  464. CU_AD_FORMAT_SIGNED_INT8:
  465. oFormat := ctUInt8;
  466. CU_AD_FORMAT_SIGNED_INT16:
  467. oFormat := ctUInt16;
  468. CU_AD_FORMAT_SIGNED_INT32:
  469. oFormat := ctUInt32;
  470. CU_AD_FORMAT_HALF:
  471. oFormat := ctHalfFloat;
  472. CU_AD_FORMAT_FLOAT:
  473. oFormat := ctFloat;
  474. end;
  475. case nCh of
  476. 1: oNum := cnOne;
  477. 2: oNum := cnTwo;
  478. 3: oNum := cnThree;
  479. 4: oNum := cnFour;
  480. end;
  481. end;
  482. procedure RegisterCUDAComponentNameChangeEvent(ANotifyEvent: TNotifyEvent);
  483. begin
  484. vCUDAComponentNameChangeEvent := ANotifyEvent;
  485. end;
  486. procedure DeRegisterCUDAComponentNameChangeEvent;
  487. begin
  488. vCUDAComponentNameChangeEvent := nil;
  489. end;
  490. // ------------------
  491. // ------------------ TGLCUDA ------------------
  492. // ------------------
  493. constructor TGLCUDA.Create(AOwner: TComponent);
  494. begin
  495. inherited Create(AOwner);
  496. fDevice := nil;
  497. fContext := TCUDAContext.Create;
  498. FChanges := [];
  499. end;
  500. destructor TGLCUDA.Destroy;
  501. begin
  502. ComputingDevice := nil;
  503. fContext.Destroy;
  504. inherited;
  505. end;
  506. procedure TGLCUDA.Notification(AComponent: TComponent; Operation: TOperation);
  507. begin
  508. if (Operation = opRemove) and (AComponent = fDevice) then
  509. ComputingDevice := nil;
  510. inherited;
  511. end;
  512. procedure TGLCUDA.SetDevice(const Value: TGLCUDADevice);
  513. begin
  514. if Value <> fDevice then
  515. begin
  516. if Assigned(Value) and not Value.Suitable then
  517. exit;
  518. if Assigned(fDevice) then
  519. fDevice.RemoveFreeNotification(Self);
  520. fDevice := Value;
  521. if Assigned(fDevice) then
  522. begin
  523. fDevice.FreeNotification(Self);
  524. CuNotifyChange(cuchDevice);
  525. end;
  526. end;
  527. end;
  528. procedure TGLCUDA.SetOnOpenGLInteropInit(AEvent: TOnOpenGLInteropInit);
  529. begin
  530. FOnOpenGLInteropInit := AEvent;
  531. CuNotifyChange(cuchContext);
  532. end;
  533. function TGLCUDA.GetContext: TCUDAContext;
  534. begin
  535. if cuchDevice in FChanges then
  536. begin
  537. if Assigned(fDevice) then
  538. fContext.Device := fDevice.Device
  539. else
  540. fContext.Device := nil;
  541. Exclude(FChanges, cuchDevice);
  542. Include(FChanges, cuchContext);
  543. end;
  544. if (cuchContext in FChanges) and Assigned(fDevice) then
  545. begin
  546. // Getting OpenGL context to make interoperability
  547. fContext.OnOpenGLInteropInit := FOnOpenGLInteropInit;
  548. CUDAContextManager.CreateContext(fContext);
  549. Exclude(FChanges, cuchContext);
  550. end;
  551. Result := fContext;
  552. end;
  553. function TGLCUDA.GetIsAllocated: Boolean;
  554. begin
  555. Result := FContext.IsValid;
  556. end;
  557. function TGLCUDA.GetModule(const i: Integer): TCUDAModule;
  558. var
  559. j, k: Integer;
  560. begin
  561. Result := nil;
  562. k := 0;
  563. for j := 0 to FItems.Count - 1 do
  564. begin
  565. if FItems[j] is TCUDAModule then
  566. begin
  567. if k = i then
  568. exit(TCUDAModule(FItems[j]))
  569. else
  570. Inc(k);
  571. end;
  572. end;
  573. end;
  574. // ------------------
  575. // ------------------ TCUDAModule ------------------
  576. // ------------------
  577. constructor TCUDAModule.Create(AOwner: TComponent);
  578. begin
  579. inherited Create(AOwner);
  580. FHandle := nil;
  581. FCode := TStringList.Create;
  582. TStringList(FCode).OnChange := OnChangeCode;
  583. end;
  584. destructor TCUDAModule.Destroy;
  585. begin
  586. Unload;
  587. FCode.Destroy;
  588. if Assigned(FCompiler) then
  589. FCompiler.Product := nil;
  590. inherited;
  591. end;
  592. procedure TCUDAModule.Assign(Source: TPersistent);
  593. var
  594. module: TCUDAModule;
  595. begin
  596. if Source is TCUDAModule then
  597. begin
  598. DestroyHandles;
  599. module := TCUDAModule(Source);
  600. FCode.Assign(module.FCode);
  601. FCodeType := module.FCodeType;
  602. AllocateHandles;
  603. end;
  604. inherited Assign(Source);
  605. end;
  606. procedure TCUDAModule.SetCompiler(const Value: TGLCUDACompiler);
  607. begin
  608. if Value <> FCompiler then
  609. begin
  610. // Compiler must used by only one module
  611. if Assigned(Value) and Assigned(Value.Product) then
  612. exit;
  613. FCompiler := Value;
  614. if Assigned(FCompiler) then
  615. FCompiler.Product := FCode;
  616. end;
  617. end;
  618. function TCUDAModule.GetContext: TCUDAContext;
  619. begin
  620. if Assigned(FMaster) and (FMaster is TGLCUDA) then
  621. Result := TGLCUDA(FMaster).Context
  622. else
  623. begin
  624. Result := nil;
  625. {$IFDEF USE_LOGGING}
  626. LogErrorFmt('Invalid master of module "%s"', [Name]);
  627. {$ENDIF}
  628. Abort;
  629. end;
  630. end;
  631. function TCUDAModule.GetIsAllocated: Boolean;
  632. begin
  633. Result := Assigned(FHandle);
  634. end;
  635. procedure TCUDAModule.Loaded;
  636. var
  637. I: Integer;
  638. begin
  639. inherited Loaded;
  640. LoadFromSource;
  641. for i := ItemsCount - 1 downto 0 do
  642. Items[i].AllocateHandles;
  643. end;
  644. procedure TCUDAModule.AllocateHandles;
  645. var
  646. func: TCUDAFunction;
  647. tex: TCUDATexture;
  648. cnst: TCUDAConstant;
  649. Param: TCUDAFuncParam;
  650. i, j: Integer;
  651. useless: array of TCUDAComponent;
  652. info: TCUDAModuleInfo;
  653. bFail: Boolean;
  654. begin
  655. LoadFromSource;
  656. if Assigned(FCompiler) then
  657. begin
  658. info := FCompiler.ModuleInfo;
  659. info.Owner := Self;
  660. // Runtime module deployment
  661. if not(csDesigning in ComponentState) and Assigned(FCompiler) then
  662. begin
  663. // Redefine function and texture with same names
  664. for i := 0 to High(info.func) do
  665. begin
  666. func := GetKernelFunction(info.func[i].Name);
  667. if not Assigned(func) then
  668. begin
  669. func := TCUDAFunction.Create(Self);
  670. func.Master := Self;
  671. func.FKernelName := info.func[i].KernelName;
  672. func.Name := MakeUniqueName(info.func[i].Name);
  673. end
  674. else
  675. func.DeleteItems;
  676. try
  677. bFail := func.Handle = nil;
  678. except
  679. bFail := True;
  680. end;
  681. if bFail then
  682. func.Destroy
  683. else
  684. begin
  685. for j := 0 to High(info.func[i].Args) do
  686. begin
  687. Param := TCUDAFuncParam.Create(func);
  688. Param.Master := TCUDAComponent(func);
  689. Param.FKernelName := info.func[i].Args[j].Name;
  690. Param.Name := func.KernelName + '_' + Param.KernelName;
  691. Param.FType := info.func[i].Args[j].DataType;
  692. Param.FCustomType := info.func[i].Args[j].CustomType;
  693. Param.FRef := info.func[i].Args[j].Ref;
  694. // Lock properties
  695. Param.AllocateHandles;
  696. end;
  697. end;
  698. end;
  699. for i := 0 to High(info.TexRef) do
  700. begin
  701. tex := GetKernelTexture(info.TexRef[i].Name);
  702. if not Assigned(tex) then
  703. begin
  704. tex := TCUDATexture.Create(Self);
  705. tex.Master := Self;
  706. tex.FKernelName := info.TexRef[i].Name;
  707. tex.fReadAsInteger :=
  708. (info.TexRef[i].ReadMode = cudaReadModeElementType);
  709. tex.fFormat := cCUDATypeToTexFormat[info.TexRef[i].DataType].F;
  710. tex.fChannelNum := cCUDATypeToTexFormat[info.TexRef[i].DataType].C;
  711. tex.Name := MakeUniqueName(tex.FKernelName);
  712. end;
  713. try
  714. bFail := tex.Handle = nil;
  715. except
  716. bFail := True;
  717. end;
  718. if bFail then
  719. tex.Destroy;
  720. end;
  721. for i := 0 to High(info.Constant) do
  722. begin
  723. cnst := GetKernelConstant(info.Constant[i].Name);
  724. if not Assigned(cnst) then
  725. begin
  726. cnst := TCUDAConstant.Create(Self);
  727. cnst.Master := Self;
  728. cnst.FKernelName := info.Constant[i].Name;
  729. cnst.FType := info.Constant[i].DataType;
  730. cnst.FCustomType := info.Constant[i].CustomType;
  731. cnst.Name := MakeUniqueName(cnst.FKernelName);
  732. cnst.IsValueDefined := info.Constant[i].DefValue;
  733. end;
  734. try
  735. bFail := cnst.DeviceAddress = nil;
  736. except
  737. bFail := True;
  738. end;
  739. if bFail then
  740. cnst.Destroy;
  741. end;
  742. // Delete useless components
  743. SetLength(useless, ItemsCount);
  744. j := 0;
  745. for i := 0 to ItemsCount - 1 do
  746. if not Items[i].IsAllocated then
  747. begin
  748. useless[j] := Items[i];
  749. Inc(j);
  750. end;
  751. for i := 0 to j - 1 do
  752. useless[i].Destroy;
  753. end;
  754. end;
  755. end;
  756. procedure TCUDAModule.DestroyHandles;
  757. var
  758. I: Integer;
  759. begin
  760. for I := 0 to ItemsCount - 1 do
  761. TCUDAComponent(Items[I]).DestroyHandles;
  762. end;
  763. procedure TCUDAModule.LoadFromFile(const AFilename: string);
  764. var
  765. Status: TCUresult;
  766. ext: string;
  767. AnsiFileName: AnsiString;
  768. begin
  769. if FileExists(AFilename) then
  770. begin
  771. ext := ExtractFileExt(AFilename);
  772. System.Delete(ext, 1, 1);
  773. ext := AnsiLowerCase(ext);
  774. FCodeType := codeUndefined;
  775. if ext = 'ptx' then
  776. FCodeType := codePtx;
  777. if ext = 'cubin' then
  778. FCodeType := codeCubin;
  779. if ext = 'gpu' then
  780. FCodeType := codeGpu;
  781. if (FCodeType = codePtx) or (FCodeType = codeCubin) then
  782. begin
  783. Unload;
  784. Context.Requires;
  785. AnsiFileName := AnsiString(AFilename);
  786. Status := cuModuleLoad(FHandle, PAnsiChar(AnsiFileName));
  787. Context.Release;
  788. if Status <> CUDA_SUCCESS then
  789. Abort;
  790. FCode.LoadFromFile(AFilename);
  791. Compiler := nil;
  792. AllocateHandles;
  793. end
  794. else
  795. {$IFDEF USE_LOGGING}
  796. LogErrorFmt('%s.LoadFromFile: file extension must be ptx or cubin', [Self.ClassName]);
  797. {$ENDIF}
  798. end
  799. else
  800. {$IFDEF USE_LOGGING}
  801. LogErrorFmt(strFailedOpenFile, [AFilename]);
  802. {$ENDIF}
  803. end;
  804. procedure TCUDAModule.LoadFromSource;
  805. var
  806. Text: AnsiString;
  807. begin
  808. Text := AnsiString(FCode.Text);
  809. if Length(Text) > 0 then
  810. begin
  811. DestroyHandles;
  812. Text := Text + #00;
  813. Context.Requires;
  814. FStatus := cuModuleLoadData(FHandle, PAnsiChar(Text));
  815. Context.Release;
  816. if FStatus <> CUDA_SUCCESS then
  817. Abort;
  818. end;
  819. end;
  820. procedure TCUDAModule.LoadAndCompile;
  821. begin
  822. AllocateHandles;
  823. end;
  824. procedure TCUDAModule.Unload;
  825. begin
  826. if Assigned(FHandle) then
  827. begin
  828. DestroyHandles;
  829. DeleteItems;
  830. Context.Requires;
  831. FStatus := cuModuleUnload(FHandle);
  832. Context.Release;
  833. FHandle := nil;
  834. end;
  835. end;
  836. procedure TCUDAModule.OnChangeCode(Sender: TObject);
  837. begin
  838. if not(csLoading in ComponentState) and (Sender is TGLCUDACompiler) then
  839. begin
  840. AllocateHandles;
  841. end;
  842. end;
  843. procedure TCUDAModule.SetCode(const Value: TStringList);
  844. begin
  845. FCode.Assign(Value);
  846. end;
  847. function TCUDAModule.GetKernelFunction(const AName: string): TCUDAFunction;
  848. var
  849. i: Integer;
  850. item: TComponent;
  851. begin
  852. Result := nil;
  853. for i := 0 to Self.ItemsCount - 1 do
  854. begin
  855. item := Items[i];
  856. if item is TCUDAFunction then
  857. if TCUDAFunction(item).KernelName = AName then
  858. exit(TCUDAFunction(item));
  859. end;
  860. end;
  861. function TCUDAModule.GetKernelTexture(const AName: string): TCUDATexture;
  862. var
  863. i: Integer;
  864. item: TComponent;
  865. begin
  866. Result := nil;
  867. for i := 0 to Self.ItemsCount - 1 do
  868. begin
  869. item := Items[i];
  870. if item is TCUDATexture then
  871. if TCUDATexture(item).KernelName = AName then
  872. exit(TCUDATexture(item));
  873. end;
  874. end;
  875. function TCUDAModule.GetKernelConstant(const AName: string): TCUDAConstant;
  876. var
  877. i: Integer;
  878. item: TComponent;
  879. begin
  880. Result := nil;
  881. for i := 0 to Self.ItemsCount - 1 do
  882. begin
  883. item := Items[i];
  884. if item is TCUDAConstant then
  885. if TCUDAConstant(item).KernelName = AName then
  886. exit(TCUDAConstant(item));
  887. end;
  888. end;
  889. // ------------------
  890. // ------------------ TCUDAComponent ------------------
  891. // ------------------
  892. destructor TCUDAComponent.Destroy;
  893. begin
  894. if Assigned(FMaster) then
  895. FMaster.RemoveItem(Self);
  896. if Assigned(FItems) then
  897. begin
  898. DeleteItems;
  899. FItems.Free;
  900. end;
  901. inherited;
  902. end;
  903. procedure TCUDAComponent.CuNotifyChange(AChange: TCUDAChange);
  904. begin
  905. Include(FChanges, AChange);
  906. end;
  907. function TCUDAComponent.GetContext: TCUDAContext;
  908. begin
  909. if Self is TGLCUDA then
  910. Result := TGLCUDA(Self).Context
  911. else
  912. Result := TGLCUDA(FMaster).Context;
  913. end;
  914. procedure TCUDAComponent.CollectStatus(AStatus: TCUresult);
  915. begin
  916. if AStatus <> CUDA_SUCCESS then
  917. FStatus := AStatus;
  918. end;
  919. procedure TCUDAComponent.GetChildren(AProc: TGetChildProc; Root: TComponent);
  920. var
  921. i: Integer;
  922. begin
  923. if Assigned(FItems) then
  924. for i := 0 to FItems.Count - 1 do
  925. if not IsSubComponent(TComponent(FItems.List^[i])) then
  926. AProc(TComponent(FItems.List^[i]));
  927. end;
  928. procedure TCUDAComponent.SetParentComponent(Value: TComponent);
  929. begin
  930. inherited;
  931. if Self is TGLCUDA then
  932. exit;
  933. if Value <> FMaster then
  934. Master := TCUDAComponent(Value);
  935. end;
  936. function TCUDAComponent.GetParentComponent: TComponent;
  937. begin
  938. Result := FMaster;
  939. end;
  940. function TCUDAComponent.HasParent: Boolean;
  941. begin
  942. Result := Assigned(FMaster);
  943. end;
  944. procedure TCUDAComponent.SetMaster(AMaster: TCUDAComponent);
  945. begin
  946. if Assigned(FMaster) then
  947. FMaster.RemoveItem(Self);
  948. FMaster := AMaster;
  949. if Assigned(FMaster) then
  950. FMaster.AddItem(Self);
  951. end;
  952. procedure TCUDAComponent.SetName(const NewName: TComponentName);
  953. begin
  954. if Name <> NewName then
  955. begin
  956. inherited SetName(NewName);
  957. if Assigned(vCUDAComponentNameChangeEvent) then
  958. vCUDAComponentNameChangeEvent(Self);
  959. end;
  960. end;
  961. procedure TCUDAComponent.AddItem(AItem: TCUDAComponent);
  962. begin
  963. if not Assigned(FItems) then
  964. FItems := TGLPersistentObjectList.Create;
  965. FItems.Add(AItem);
  966. end;
  967. procedure TCUDAComponent.RemoveItem(AItem: TCUDAComponent);
  968. begin
  969. if not Assigned(FItems) then
  970. exit;
  971. if AItem.FMaster = Self then
  972. begin
  973. if AItem.Owner = Self then
  974. RemoveComponent(AItem);
  975. FItems.Remove(AItem);
  976. AItem.FMaster := nil;
  977. end;
  978. end;
  979. procedure TCUDAComponent.DeleteItems;
  980. var
  981. child: TCUDAComponent;
  982. begin
  983. if Assigned(FItems) then
  984. while FItems.Count > 0 do
  985. begin
  986. child := TCUDAComponent(FItems.Pop);
  987. child.Free;
  988. end;
  989. end;
  990. function TCUDAComponent.GetItem(const i: Integer): TCUDAComponent;
  991. begin
  992. if Assigned(FItems) and (i < FItems.Count) then
  993. Result := TCUDAComponent(FItems[i])
  994. else
  995. Result := nil;
  996. end;
  997. function TCUDAComponent.GetItemsCount: Integer;
  998. begin
  999. if Assigned(FItems) then
  1000. Result := FItems.Count
  1001. else
  1002. Result := 0;
  1003. end;
  1004. function TCUDAComponent.GetItemByName(const name: string): TCUDAComponent;
  1005. var
  1006. i: Integer;
  1007. begin
  1008. Result := nil;
  1009. for i := 0 to GetItemsCount - 1 do
  1010. begin
  1011. if Items[i].Name = name then
  1012. begin
  1013. Result := Items[i];
  1014. exit;
  1015. end;
  1016. end;
  1017. end;
  1018. function TCUDAComponent.MakeUniqueName(const BaseName: string): string;
  1019. var
  1020. i: Integer;
  1021. begin
  1022. Result := BaseName + '1';
  1023. i := 2;
  1024. while GetItemByName(Result) <> nil do
  1025. begin
  1026. Result := BaseName + IntToStr(i);
  1027. Inc(i);
  1028. end;
  1029. end;
  1030. // ------------------
  1031. // ------------------ TCUDAFunction ------------------
  1032. // ------------------
  1033. constructor TCUDAFunction.Create(AOwner: TComponent);
  1034. begin
  1035. inherited Create(AOwner);
  1036. FHandle := nil;
  1037. FAutoSync := true;
  1038. FBlockShape := TCUDADimensions.Create(Self);
  1039. FGrid := TCUDADimensions.Create(Self);
  1040. FLaunching := false;
  1041. end;
  1042. destructor TCUDAFunction.Destroy;
  1043. begin
  1044. FBlockShape.Destroy;
  1045. FGrid.Destroy;
  1046. DestroyHandles;
  1047. inherited;
  1048. end;
  1049. procedure TCUDAFunction.AllocateHandles;
  1050. var
  1051. LModule: TCUDAModule;
  1052. ansiname: AnsiString;
  1053. pFunc: PCUfunction;
  1054. begin
  1055. DestroyHandles;
  1056. if not(FMaster is TCUDAModule) then
  1057. begin
  1058. {$IFDEF USE_LOGGING}
  1059. LogError(strModuleAbsent);
  1060. {$ENDIF}
  1061. Abort;
  1062. end;
  1063. if Length(FKernelName) = 0 then
  1064. exit;
  1065. LModule := TCUDAModule(FMaster);
  1066. if not Assigned(LModule.FHandle) then
  1067. exit;
  1068. with LModule.Context.Device do
  1069. begin
  1070. FBlockShape.MaxSizeX := MaxThreadsDim.SizeX;
  1071. FBlockShape.MaxSizeY := MaxThreadsDim.SizeY;
  1072. FBlockShape.MaxSizeZ := MaxThreadsDim.SizeZ;
  1073. FGrid.MaxSizeX := MaxGridSize.SizeX;
  1074. FGrid.MaxSizeY := MaxGridSize.SizeY;
  1075. FGrid.MaxSizeZ := MaxGridSize.SizeZ;
  1076. end;
  1077. ansiname := AnsiString(FKernelName);
  1078. Context.Requires;
  1079. FStatus := cuModuleGetFunction(pFunc, LModule.FHandle, PAnsiChar(ansiname));
  1080. Context.Release;
  1081. if FStatus = CUDA_SUCCESS then
  1082. FHandle := pFunc
  1083. else
  1084. Abort;
  1085. inherited;
  1086. end;
  1087. procedure TCUDAFunction.DestroyHandles;
  1088. var
  1089. i: Integer;
  1090. item: TComponent;
  1091. begin
  1092. if Assigned(FHandle) then
  1093. begin
  1094. for i := 0 to ItemsCount - 1 do
  1095. begin
  1096. item := Items[i];
  1097. if item is TCUDAFuncParam then
  1098. TCUDAFuncParam(item).DestroyHandles;
  1099. end;
  1100. FHandle := nil;
  1101. inherited;
  1102. end;
  1103. end;
  1104. procedure TCUDAFunction.SetBlockShape(const AShape: TCUDADimensions);
  1105. begin
  1106. FBlockShape.Assign(AShape);
  1107. end;
  1108. procedure TCUDAFunction.SetGrid(const AGrid: TCUDADimensions);
  1109. begin
  1110. FGrid.Assign(AGrid);
  1111. end;
  1112. procedure TCUDAFunction.SetKernelName(const AName: string);
  1113. begin
  1114. if csLoading in ComponentState then
  1115. FKernelName := AName
  1116. else if not Assigned(FHandle) then
  1117. begin
  1118. FKernelName := AName;
  1119. AllocateHandles;
  1120. end;
  1121. end;
  1122. procedure TCUDAFunction.SetParam(Value: Integer);
  1123. begin
  1124. if not FLaunching then
  1125. begin
  1126. {$IFDEF USE_LOGGING}
  1127. LogError(strWrongParamSetup);
  1128. {$ENDIF}
  1129. Abort;
  1130. end;
  1131. FStatus := cuParamSeti(FHandle, ParamOffset, PCardinal(@Value)^);
  1132. if FStatus <> CUDA_SUCCESS then
  1133. Abort;
  1134. Inc(ParamOffset, SizeOf(Cardinal));
  1135. end;
  1136. procedure TCUDAFunction.SetParam(Value: Cardinal);
  1137. begin
  1138. if not FLaunching then
  1139. begin
  1140. {$IFDEF USE_LOGGING}
  1141. LogError(strWrongParamSetup);
  1142. {$ENDIF}
  1143. Abort;
  1144. end;
  1145. FStatus := cuParamSeti(FHandle, ParamOffset, Value);
  1146. if FStatus <> CUDA_SUCCESS then
  1147. Abort;
  1148. Inc(ParamOffset, SizeOf(Cardinal));
  1149. end;
  1150. procedure TCUDAFunction.SetParam(Value: Single);
  1151. begin
  1152. if not FLaunching then
  1153. begin
  1154. {$IFDEF USE_LOGGING}
  1155. LogError(strWrongParamSetup);
  1156. {$ENDIF}
  1157. Abort;
  1158. end;
  1159. FStatus := cuParamSetf(FHandle, ParamOffset, Value);
  1160. if FStatus <> CUDA_SUCCESS then
  1161. Abort;
  1162. Inc(ParamOffset, SizeOf(Single));
  1163. end;
  1164. procedure TCUDAFunction.SetParam(Value: TVector2i);
  1165. begin
  1166. if not FLaunching then
  1167. begin
  1168. {$IFDEF USE_LOGGING}
  1169. LogError(strWrongParamSetup);
  1170. {$ENDIF}
  1171. Abort;
  1172. end;
  1173. FStatus := cuParamSetv(FHandle, ParamOffset, Value, SizeOf(TVector2i));
  1174. if FStatus <> CUDA_SUCCESS then
  1175. Abort;
  1176. Inc(ParamOffset, SizeOf(TVector2i));
  1177. end;
  1178. procedure TCUDAFunction.SetParam(Value: TVector3i);
  1179. begin
  1180. if not FLaunching then
  1181. begin
  1182. {$IFDEF USE_LOGGING}
  1183. LogError(strWrongParamSetup);
  1184. {$ENDIF}
  1185. Abort;
  1186. end;
  1187. FStatus := cuParamSetv(FHandle, ParamOffset, Value, SizeOf(TVector3i));
  1188. if FStatus <> CUDA_SUCCESS then
  1189. Abort;
  1190. Inc(ParamOffset, SizeOf(TVector3i));
  1191. end;
  1192. procedure TCUDAFunction.SetParam(Value: TVector4i);
  1193. begin
  1194. if not FLaunching then
  1195. begin
  1196. {$IFDEF USE_LOGGING}
  1197. LogError(strWrongParamSetup);
  1198. {$ENDIF}
  1199. Abort;
  1200. end;
  1201. FStatus := cuParamSetv(FHandle, ParamOffset, Value, SizeOf(TVector4i));
  1202. if FStatus <> CUDA_SUCCESS then
  1203. Abort;
  1204. Inc(ParamOffset, SizeOf(TVector4i));
  1205. end;
  1206. procedure TCUDAFunction.SetParam(Value: TVector2f);
  1207. begin
  1208. if not FLaunching then
  1209. begin
  1210. {$IFDEF USE_LOGGING}
  1211. LogError(strWrongParamSetup);
  1212. {$ENDIF}
  1213. Abort;
  1214. end;
  1215. FStatus := cuParamSetv(FHandle, ParamOffset, Value, SizeOf(TVector2f));
  1216. if FStatus <> CUDA_SUCCESS then
  1217. Abort;
  1218. Inc(ParamOffset, SizeOf(TVector2f));
  1219. end;
  1220. procedure TCUDAFunction.SetParam(Value: TVector3f);
  1221. begin
  1222. if not FLaunching then
  1223. begin
  1224. {$IFDEF USE_LOGGING}
  1225. LogError(strWrongParamSetup);
  1226. {$ENDIF}
  1227. Abort;
  1228. end;
  1229. FStatus := cuParamSetv(FHandle, ParamOffset, Value, SizeOf(TVector3f));
  1230. if FStatus <> CUDA_SUCCESS then
  1231. Abort;
  1232. Inc(ParamOffset, SizeOf(TVector4f));
  1233. end;
  1234. procedure TCUDAFunction.SetParam(Value: TVector4f);
  1235. begin
  1236. if not FLaunching then
  1237. begin
  1238. {$IFDEF USE_LOGGING}
  1239. LogError(strWrongParamSetup);
  1240. {$ENDIF}
  1241. Abort;
  1242. end;
  1243. FStatus := cuParamSetv(FHandle, ParamOffset, Value, SizeOf(TVector4f));
  1244. if FStatus <> CUDA_SUCCESS then
  1245. Abort;
  1246. Inc(ParamOffset, SizeOf(TVector4f));
  1247. end;
  1248. procedure TCUDAFunction.SetParam(MemData: TCUDAMemData);
  1249. begin
  1250. if not FLaunching then
  1251. begin
  1252. {$IFDEF USE_LOGGING}
  1253. LogError(strWrongParamSetup);
  1254. {$ENDIF}
  1255. Abort;
  1256. end;
  1257. FStatus := cuParamSeti(FHandle, ParamOffset, Cardinal(MemData.RawData));
  1258. if FStatus <> CUDA_SUCCESS then
  1259. Abort;
  1260. Inc(ParamOffset, SizeOf(Cardinal));
  1261. end;
  1262. procedure TCUDAFunction.SetParam(TexRef: TCUDATexture);
  1263. var
  1264. HTexRef: PCUtexref;
  1265. begin
  1266. if not FLaunching then
  1267. begin
  1268. {$IFDEF USE_LOGGING}
  1269. LogError(strWrongParamSetup);
  1270. {$ENDIF}
  1271. Abort;
  1272. end;
  1273. HTexRef := TexRef.Handle;
  1274. FStatus := cuParamSetTexRef(FHandle, CU_PARAM_TR_DEFAULT, HTexRef);
  1275. if FStatus <> CUDA_SUCCESS then
  1276. Abort;
  1277. end;
  1278. procedure TCUDAFunction.SetParam(Ptr: Pointer);
  1279. begin
  1280. if not FLaunching then
  1281. begin
  1282. {$IFDEF USE_LOGGING}
  1283. LogError(strWrongParamSetup);
  1284. {$ENDIF}
  1285. Abort;
  1286. end;
  1287. FStatus := cuParamSeti(FHandle, ParamOffset, Cardinal(Ptr));
  1288. if FStatus <> CUDA_SUCCESS then
  1289. Abort;
  1290. Inc(ParamOffset, SizeOf(Cardinal));
  1291. end;
  1292. procedure TCUDAFunction.Launch(Grided: Boolean = true);
  1293. begin
  1294. if not(FMaster is TCUDAModule) then
  1295. begin
  1296. {$IFDEF USE_LOGGING}
  1297. LogError(strModuleAbsent);
  1298. {$ENDIF}
  1299. Abort;
  1300. end;
  1301. if not Assigned(FHandle) then
  1302. begin
  1303. {$IFDEF USE_LOGGING}
  1304. LogErrorFmt(strFuncNotConnected, [Self.ClassName]);
  1305. {$ENDIF}
  1306. Abort;
  1307. end;
  1308. if FLaunching then
  1309. exit;
  1310. ParamOffset := 0;
  1311. Context.Requires;
  1312. FLaunching := true;
  1313. if Assigned(FOnParameterSetup) then
  1314. try
  1315. FOnParameterSetup(Self);
  1316. except
  1317. FLaunching := false;
  1318. Context.Release;
  1319. raise;
  1320. end;
  1321. FLaunching := false;
  1322. FStatus := cuParamSetSize(FHandle, ParamOffset);
  1323. CollectStatus(cuFuncSetBlockShape(FHandle, FBlockShape.SizeX,
  1324. FBlockShape.SizeY, FBlockShape.SizeZ));
  1325. if FStatus = CUDA_SUCCESS then
  1326. begin
  1327. // execute the kernel
  1328. if Grided then
  1329. FStatus := cuLaunchGrid(FHandle, FGrid.SizeX, FGrid.SizeY)
  1330. else
  1331. FStatus := cuLaunch(FHandle);
  1332. if FAutoSync then
  1333. CollectStatus(cuCtxSynchronize);
  1334. end;
  1335. Context.Release;
  1336. if FStatus <> CUDA_SUCCESS then
  1337. begin
  1338. {$IFDEF USE_LOGGING}
  1339. LogErrorFmt(strLaunchFailed, [Self.Name]);
  1340. {$ENDIF}
  1341. Abort;
  1342. end;
  1343. end;
  1344. function TCUDAFunction.GetHandle: PCUfunction;
  1345. begin
  1346. if FHandle = nil then
  1347. AllocateHandles;
  1348. Result := FHandle;
  1349. end;
  1350. function TCUDAFunction.GetIsAllocated: Boolean;
  1351. begin
  1352. Result := Assigned(FHandle);
  1353. end;
  1354. function TCUDAFunction.GetMaxThreadPerBlock: Integer;
  1355. begin
  1356. Context.Requires;
  1357. FStatus := cuFuncGetAttribute(Result,
  1358. CU_FUNC_ATTRIBUTE_MAX_THREADS_PER_BLOCK, Handle);
  1359. Context.Release;
  1360. if FStatus <> CUDA_SUCCESS then
  1361. Abort;
  1362. end;
  1363. function TCUDAFunction.GetSharedMemorySize: Integer;
  1364. begin
  1365. Context.Requires;
  1366. FStatus := cuFuncGetAttribute(Result,
  1367. CU_FUNC_ATTRIBUTE_SHARED_SIZE_BYTES, Handle);
  1368. Context.Release;
  1369. if FStatus <> CUDA_SUCCESS then
  1370. Abort;
  1371. end;
  1372. procedure TCUDAFunction.SetSharedMemorySize(Value: Integer);
  1373. var
  1374. MemPerBlock: NativeUInt;
  1375. begin
  1376. Context.Requires;
  1377. MemPerBlock := TGLCUDA(TCUDAModule(FMaster).FMaster)
  1378. .fDevice.Device.SharedMemPerBlock;
  1379. if Value < 0 then
  1380. Value := 0
  1381. else if Value > Integer(MemPerBlock) then
  1382. Value := MemPerBlock;
  1383. FStatus := cuFuncSetSharedSize(Handle, Value);
  1384. Context.Release;
  1385. if FStatus <> CUDA_SUCCESS then
  1386. Abort;
  1387. end;
  1388. function TCUDAFunction.GetConstMemorySize: Integer;
  1389. begin
  1390. Context.Requires;
  1391. FStatus := cuFuncGetAttribute(Result,
  1392. CU_FUNC_ATTRIBUTE_CONST_SIZE_BYTES, Handle);
  1393. Context.Release;
  1394. if FStatus <> CUDA_SUCCESS then
  1395. Abort;
  1396. end;
  1397. function TCUDAFunction.GetLocalMemorySize: Integer;
  1398. begin
  1399. Context.Requires;
  1400. FStatus := cuFuncGetAttribute(Result,
  1401. CU_FUNC_ATTRIBUTE_LOCAL_SIZE_BYTES, Handle);
  1402. Context.Release;
  1403. if FStatus <> CUDA_SUCCESS then
  1404. Abort;
  1405. end;
  1406. function TCUDAFunction.GetNumRegisters: Integer;
  1407. begin
  1408. Context.Requires;
  1409. FStatus := cuFuncGetAttribute(Result, CU_FUNC_ATTRIBUTE_NUM_REGS, Handle);
  1410. Context.Release;
  1411. if FStatus <> CUDA_SUCCESS then
  1412. Abort;
  1413. end;
  1414. function TCUDAFunction.GetParameter(const AName: string): TCUDAFuncParam;
  1415. var
  1416. i: Integer;
  1417. item: TComponent;
  1418. begin
  1419. Result := nil;
  1420. for i := 0 to Self.ItemsCount - 1 do
  1421. begin
  1422. item := Items[i];
  1423. if item is TCUDAFuncParam then
  1424. if TCUDAFuncParam(item).KernelName = AName then
  1425. exit(TCUDAFuncParam(item));
  1426. end;
  1427. end;
  1428. // ------------------
  1429. // ------------------ TCUDAMemData ------------------
  1430. // ------------------
  1431. constructor TCUDAMemData.Create(AOwner: TComponent);
  1432. begin
  1433. inherited Create(AOwner);
  1434. fData := nil;
  1435. FHandle := nil;
  1436. FMemoryType := mtHost;
  1437. fWidth := 256;
  1438. fHeight := 0;
  1439. fDepth := 0;
  1440. fPitch := 0;
  1441. fChannelsType := ctInt8;
  1442. fChannelsNum := cnOne;
  1443. FOpenGLRefArray := False;
  1444. FMapping := False;
  1445. end;
  1446. function TCUDAMemData.Data<EType>(X: Integer): GCUDAHostElementAccess<EType>;
  1447. var
  1448. ptr: PByte;
  1449. size: Integer;
  1450. begin
  1451. if (FMemoryType <> mtHost) and not FMapping then
  1452. begin
  1453. {$IFDEF USE_LOGGING}
  1454. LogError(strOnlyHostData);
  1455. {$ENDIF}
  1456. Abort;
  1457. end;
  1458. if FMapping then
  1459. ptr := PByte(FMappedMemory)
  1460. else
  1461. ptr := PByte(GetData);
  1462. size := ElementSize * X;
  1463. if size > DataSize then
  1464. begin
  1465. {$IFDEF USE_LOGGING}
  1466. LogError(strOutOfRange);
  1467. {$ENDIF}
  1468. Abort;
  1469. end;
  1470. Inc(ptr, size);
  1471. SetElementAccessAddress(ptr, ElementSize);
  1472. end;
  1473. function TCUDAMemData.Data<EType>(X, Y: Integer): GCUDAHostElementAccess<EType>;
  1474. var
  1475. ptr: PByte;
  1476. size: Integer;
  1477. begin
  1478. if (FMemoryType <> mtHost) and not FMapping then
  1479. begin
  1480. {$IFDEF USE_LOGGING}
  1481. LogError(strOnlyHostData);
  1482. {$ENDIF}
  1483. Abort;
  1484. end;
  1485. if FMapping then
  1486. ptr := PByte(FMappedMemory)
  1487. else
  1488. ptr := PByte(GetData);
  1489. size := ElementSize * (X + fWidth*Y);
  1490. if size > DataSize then
  1491. begin
  1492. {$IFDEF USE_LOGGING}
  1493. LogError(strOutOfRange);
  1494. {$ENDIF}
  1495. Abort;
  1496. end;
  1497. Inc(ptr, size);
  1498. SetElementAccessAddress(ptr, ElementSize);
  1499. end;
  1500. function TCUDAMemData.Data<EType>(X, Y, Z: Integer): GCUDAHostElementAccess<EType>;
  1501. var
  1502. ptr: PByte;
  1503. size: Integer;
  1504. begin
  1505. if (FMemoryType <> mtHost) and not FMapping then
  1506. begin
  1507. {$IFDEF USE_LOGGING}
  1508. LogError(strOnlyHostData);
  1509. {$ENDIF}
  1510. Abort;
  1511. end;
  1512. if FMapping then
  1513. ptr := PByte(FMappedMemory)
  1514. else
  1515. ptr := PByte(GetData);
  1516. size := ElementSize * (X + fWidth*(Y + Z * fHeight));
  1517. if size > DataSize then
  1518. begin
  1519. {$IFDEF USE_LOGGING}
  1520. LogError(strOutOfRange);
  1521. {$ENDIF}
  1522. Abort;
  1523. end;
  1524. Inc(ptr, size);
  1525. SetElementAccessAddress(ptr, ElementSize);
  1526. end;
  1527. destructor TCUDAMemData.Destroy;
  1528. begin
  1529. if Assigned(fTexture) then
  1530. fTexture.MemDataArray := nil;
  1531. DestroyHandles;
  1532. inherited;
  1533. end;
  1534. procedure TCUDAMemData.CuNotifyChange(AChange: TCUDAChange);
  1535. begin
  1536. inherited CuNotifyChange(AChange);
  1537. if Assigned(fTexture) then
  1538. fTexture.CuNotifyChange(cuchArray);
  1539. end;
  1540. procedure TCUDAMemData.SetMemoryType(const AType: TCUDAMemType);
  1541. begin
  1542. if FMemoryType <> AType then
  1543. begin
  1544. FMemoryType := AType;
  1545. if (AType = mtArray) and (fChannelsType = ctDouble) then
  1546. SetChannelType(ctFloat);
  1547. CuNotifyChange(cuchArray);
  1548. end;
  1549. end;
  1550. procedure TCUDAMemData.SetWidth(const Value: Integer);
  1551. begin
  1552. Assert(Value > 0);
  1553. if Value <> fWidth then
  1554. begin
  1555. fWidth := Value;
  1556. CuNotifyChange(cuchSize);
  1557. end;
  1558. end;
  1559. procedure TCUDAMemData.UnMap;
  1560. begin
  1561. if not FMapping then
  1562. begin
  1563. {$IFDEF USE_LOGGING}
  1564. LogErrorFmt(strFailUnmap, [Name]);
  1565. {$ENDIF}
  1566. Abort;
  1567. end;
  1568. Context.Requires;
  1569. case FMemoryType of
  1570. mtHost:
  1571. begin
  1572. FStatus := CUDA_SUCCESS;
  1573. end;
  1574. mtDevice:
  1575. begin
  1576. FStatus := cuMemcpyHtoD(GetData, FMappedMemory, DataSize);
  1577. if FStatus = CUDA_SUCCESS then
  1578. FStatus := cuMemFreeHost(FMappedMemory);
  1579. end;
  1580. mtArray:
  1581. begin
  1582. FStatus := cuMemcpyHtoA(GetArrayHandle, 0, FMappedMemory, DataSize);
  1583. if FStatus = CUDA_SUCCESS then
  1584. FStatus := cuMemFreeHost(FMappedMemory);
  1585. end;
  1586. end;
  1587. Context.Release;
  1588. if FStatus <> CUDA_SUCCESS then
  1589. Abort;
  1590. FMapping := False;
  1591. FMappedMemory := nil;
  1592. end;
  1593. procedure TCUDAMemData.SetHeight(const Value: Integer);
  1594. begin
  1595. Assert(Value >= 0);
  1596. if Value <> fHeight then
  1597. begin
  1598. fHeight := Value;
  1599. CuNotifyChange(cuchSize);
  1600. end;
  1601. end;
  1602. procedure TCUDAMemData.SetDepth(const Value: Integer);
  1603. begin
  1604. Assert(Value >= 0);
  1605. if Value <> fDepth then
  1606. begin
  1607. fDepth := Value;
  1608. CuNotifyChange(cuchSize);
  1609. end;
  1610. end;
  1611. procedure TCUDAMemData.SetChannelType(const Value: TCUDAChannelType);
  1612. begin
  1613. Assert(Value <> ctUndefined);
  1614. if (FMemoryType = mtArray) and (Value = ctDouble) then
  1615. exit;
  1616. if Value <> fChannelsType then
  1617. begin
  1618. fChannelsType := Value;
  1619. CuNotifyChange(cuchFormat);
  1620. end;
  1621. end;
  1622. procedure TCUDAMemData.SetChannelNum(const Value: TCUDAChannelNum);
  1623. begin
  1624. if Value <> fChannelsNum then
  1625. begin
  1626. fChannelsNum := Value;
  1627. CuNotifyChange(cuchFormat);
  1628. end;
  1629. end;
  1630. function TCUDAMemData.GetData: TCUdeviceptr;
  1631. begin
  1632. if not Assigned(fData) and (FChanges <> []) then
  1633. AllocateHandles;
  1634. Result := fData;
  1635. end;
  1636. function TCUDAMemData.GetArrayHandle: PCUarray;
  1637. begin
  1638. if not Assigned(FHandle) and (FChanges <> []) then
  1639. AllocateHandles;
  1640. Result := FHandle;
  1641. end;
  1642. procedure TCUDAMemData.AllocateHandles;
  1643. const
  1644. cArrayFormat: array [ctUInt8 .. ctFloat] of TCUarray_format =
  1645. (CU_AD_FORMAT_UNSIGNED_INT8, CU_AD_FORMAT_UNSIGNED_INT16,
  1646. CU_AD_FORMAT_UNSIGNED_INT32, CU_AD_FORMAT_SIGNED_INT8,
  1647. CU_AD_FORMAT_SIGNED_INT16, CU_AD_FORMAT_SIGNED_INT32, CU_AD_FORMAT_HALF,
  1648. CU_AD_FORMAT_FLOAT);
  1649. var
  1650. h, d: Integer;
  1651. Array2DDesc: TCUDA_ARRAY_DESCRIPTOR;
  1652. // Array3DDesc: TCUDA_ARRAY3D_DESCRIPTOR;
  1653. AlignedSize: Integer;
  1654. begin
  1655. DestroyHandles;
  1656. if cuchFormat in FChanges then
  1657. begin
  1658. FElementSize := cChannelTypeSize[fChannelsType] * (Ord(fChannelsNum) + 1);
  1659. end;
  1660. h := Height;
  1661. if h = 0 then
  1662. h := 1;
  1663. d := Depth;
  1664. if d = 0 then
  1665. d := 1;
  1666. FDataSize := Width * h * d * ElementSize;
  1667. FStatus := CUDA_SUCCESS;
  1668. Context.Requires;
  1669. case FMemoryType of
  1670. mtHost:
  1671. FStatus := cuMemAllocHost(fData, DataSize);
  1672. mtDevice:
  1673. begin
  1674. if fHeight > 1 then
  1675. begin
  1676. AlignedSize := RoundUpToPowerOf2(ElementSize);
  1677. if AlignedSize < 4 then
  1678. AlignedSize := 4;
  1679. if AlignedSize > 16 then
  1680. AlignedSize := 16;
  1681. FStatus := cuMemAllocPitch(TCUdeviceptr(fData), fPitch,
  1682. Width * ElementSize, fHeight, AlignedSize);
  1683. end
  1684. else
  1685. FStatus := cuMemAlloc(TCUdeviceptr(fData), DataSize);
  1686. end;
  1687. mtArray:
  1688. begin
  1689. Array2DDesc.Width := fWidth;
  1690. Array2DDesc.Height := fHeight;
  1691. Array2DDesc.Format := cArrayFormat[fChannelsType];
  1692. Array2DDesc.NumChannels := Ord(fChannelsNum) + 1;
  1693. FStatus := cuArrayCreate(FHandle, Array2DDesc);
  1694. end;
  1695. end;
  1696. Context.Release;
  1697. if FStatus <> CUDA_SUCCESS then
  1698. Abort;
  1699. FChanges := [];
  1700. inherited;
  1701. end;
  1702. procedure TCUDAMemData.DestroyHandles;
  1703. begin
  1704. case FMemoryType of
  1705. mtHost, mtDevice:
  1706. if fData = nil then
  1707. exit;
  1708. mtArray:
  1709. if FHandle = nil then
  1710. exit;
  1711. end;
  1712. inherited;
  1713. if not FOpenGLRefArray then
  1714. begin
  1715. Context.Requires;
  1716. case FMemoryType of
  1717. mtHost:
  1718. if Assigned(fData) then
  1719. cuMemFreeHost(fData);
  1720. mtDevice:
  1721. if Assigned(fData) then
  1722. cuMemFree(fData);
  1723. mtArray:
  1724. if Assigned(FHandle) then
  1725. begin
  1726. if Assigned(fTexture) then
  1727. fTexture.MemDataArray := nil;
  1728. cuArrayDestroy(FHandle);
  1729. end;
  1730. end;
  1731. Context.Release;
  1732. end;
  1733. FHandle := nil;
  1734. fData := nil;
  1735. fPitch := 0;
  1736. FDataSize := 0;
  1737. FElementSize := 0;
  1738. FOpenGLRefArray := False;
  1739. end;
  1740. procedure TCUDAMemData.FillMem(const Value);
  1741. var
  1742. Ptr: TCUdeviceptr;
  1743. RowSize: Integer;
  1744. begin
  1745. if FMemoryType = mtDevice then
  1746. begin
  1747. Ptr := GetData;
  1748. FStatus := CUDA_SUCCESS;
  1749. Context.Requires;
  1750. // 1D memory set
  1751. if fHeight = 0 then
  1752. begin
  1753. case fChannelsType of
  1754. ctUInt8, ctInt8:
  1755. FStatus := cuMemsetD8(Ptr, Byte(Value), DataSize);
  1756. ctUInt16, ctInt16, ctHalfFloat:
  1757. FStatus := cuMemsetD16(Ptr, Word(Value), DataSize div SizeOf(Word));
  1758. ctUInt32, ctInt32, ctFloat:
  1759. FStatus := cuMemsetD32(Ptr, DWord(Value), DataSize div SizeOf(DWord));
  1760. end;
  1761. end
  1762. // 2D memory set
  1763. else
  1764. begin
  1765. RowSize := (1 + Ord(fChannelsNum)) * fWidth;
  1766. case fChannelsType of
  1767. ctUInt8, ctInt8:
  1768. FStatus := cuMemsetD2D8(Ptr, fPitch, Byte(Value), RowSize, fHeight);
  1769. ctUInt16, ctInt16, ctHalfFloat:
  1770. FStatus := cuMemsetD2D16(Ptr, fPitch, Word(Value), RowSize,
  1771. fHeight);
  1772. ctUInt32, ctInt32, ctFloat:
  1773. FStatus := cuMemsetD2D32(Ptr, fPitch, DWord(Value),
  1774. RowSize, fHeight);
  1775. end;
  1776. end;
  1777. Context.Release;
  1778. if FStatus <> CUDA_SUCCESS then
  1779. Abort
  1780. end;
  1781. end;
  1782. procedure TCUDAMemData.CopyTo(const ADstMemData: TCUDAMemData);
  1783. var
  1784. copyParam2D: TCUDA_MEMCPY2D;
  1785. // copyParam3D: TCUDA_MEMCPY3D;
  1786. Size: Integer;
  1787. begin
  1788. if not Assigned(ADstMemData) then
  1789. exit;
  1790. Assert((fDepth = 0) and (ADstMemData.Depth = 0),
  1791. 'Volume copying not yet implemented');
  1792. FStatus := CUDA_SUCCESS;
  1793. if (Height = ADstMemData.Height) and (Height = 0) then
  1794. begin
  1795. // 1D copying
  1796. Size := MinInteger(DataSize, ADstMemData.DataSize);
  1797. Context.Requires;
  1798. case MemoryType of
  1799. mtHost:
  1800. case ADstMemData.MemoryType of
  1801. mtHost:
  1802. Move(RawData^, ADstMemData.RawData^, Size);
  1803. mtDevice:
  1804. FStatus := cuMemcpyHtoD(ADstMemData.RawData, RawData, Size);
  1805. mtArray:
  1806. FStatus := cuMemcpyHtoA(ADstMemData.ArrayHandle, 0, RawData, Size);
  1807. end;
  1808. mtDevice:
  1809. case ADstMemData.MemoryType of
  1810. mtHost:
  1811. FStatus := cuMemcpyDtoH(ADstMemData.RawData, RawData, Size);
  1812. mtDevice:
  1813. FStatus := cuMemcpyDtoD(ADstMemData.RawData, RawData, Size);
  1814. mtArray:
  1815. FStatus := cuMemcpyDtoA(ADstMemData.ArrayHandle, 0, RawData, Size);
  1816. end;
  1817. mtArray:
  1818. case ADstMemData.MemoryType of
  1819. mtHost:
  1820. FStatus := cuMemcpyAtoH(ADstMemData.RawData, ArrayHandle, 0, Size);
  1821. mtDevice:
  1822. FStatus := cuMemcpyAtoD(ADstMemData.RawData, ArrayHandle, 0, Size);
  1823. mtArray:
  1824. FStatus := cuMemcpyAtoA(ADstMemData.ArrayHandle, 0,
  1825. ArrayHandle, 0, Size);
  1826. end;
  1827. end;
  1828. Context.Release;
  1829. end
  1830. else
  1831. begin
  1832. // 2D copying
  1833. FillChar(copyParam2D, SizeOf(copyParam2D), 0);
  1834. // Setup source copy parameters
  1835. case MemoryType of
  1836. mtHost:
  1837. begin
  1838. copyParam2D.srcMemoryType := CU_MEMORYTYPE_HOST;
  1839. copyParam2D.srcHost := TCUdeviceptr(RawData);
  1840. end;
  1841. mtDevice:
  1842. begin
  1843. copyParam2D.srcMemoryType := CU_MEMORYTYPE_DEVICE;
  1844. copyParam2D.srcDevice := TCUdeviceptr(RawData);
  1845. end;
  1846. mtArray:
  1847. begin
  1848. copyParam2D.srcMemoryType := CU_MEMORYTYPE_ARRAY;
  1849. copyParam2D.srcArray := ArrayHandle;
  1850. end;
  1851. end;
  1852. copyParam2D.srcPitch := fPitch;
  1853. // Setup destination copy parameters
  1854. case ADstMemData.FMemoryType of
  1855. mtHost:
  1856. begin
  1857. copyParam2D.dstMemoryType := CU_MEMORYTYPE_HOST;
  1858. copyParam2D.dstHost := TCUdeviceptr(ADstMemData.RawData);
  1859. end;
  1860. mtDevice:
  1861. begin
  1862. copyParam2D.dstMemoryType := CU_MEMORYTYPE_DEVICE;
  1863. copyParam2D.dstDevice := TCUdeviceptr(ADstMemData.RawData);
  1864. end;
  1865. mtArray:
  1866. begin
  1867. copyParam2D.dstMemoryType := CU_MEMORYTYPE_ARRAY;
  1868. copyParam2D.dstArray := ADstMemData.ArrayHandle;
  1869. end;
  1870. end;
  1871. copyParam2D.dstPitch := ADstMemData.fPitch;
  1872. copyParam2D.WidthInBytes := Cardinal(MinInteger(ElementSize * Width,
  1873. ADstMemData.ElementSize * ADstMemData.Width));
  1874. copyParam2D.Height := MinInteger(fHeight, ADstMemData.Height);
  1875. Context.Requires;
  1876. FStatus := cuMemcpy2D(@copyParam2D);
  1877. Context.Release;
  1878. end;
  1879. if FStatus <> CUDA_SUCCESS then
  1880. Abort
  1881. end;
  1882. procedure TCUDAMemData.SubCopyTo(const ADstMemData: TCUDAMemData;
  1883. ASrcXYZ, ADstXYZ, ASizes: IntElement.TVector3);
  1884. var
  1885. copyParam2D: TCUDA_MEMCPY2D;
  1886. // copyParam3D: TCUDA_MEMCPY3D;
  1887. begin
  1888. if not Assigned(ADstMemData) then
  1889. exit;
  1890. // Clamp sizes
  1891. ASrcXYZ[0] := MinInteger(ASrcXYZ[0], Width - 1);
  1892. ASrcXYZ[1] := MinInteger(ASrcXYZ[1], MaxInteger(Height - 1, 0));
  1893. ASrcXYZ[2] := MinInteger(ASrcXYZ[2], MaxInteger(Depth - 1, 0));
  1894. ADstXYZ[0] := MinInteger(ADstXYZ[0], ADstMemData.Width - 1);
  1895. ADstXYZ[1] := MinInteger(ADstXYZ[1], MaxInteger(ADstMemData.Height - 1, 0));
  1896. ADstXYZ[2] := MinInteger(ADstXYZ[2], MaxInteger(ADstMemData.Depth - 1, 0));
  1897. ASizes[0] := MinInteger(ASizes[0], Width, ADstMemData.Width);
  1898. ASizes[1] := MinInteger(ASizes[1], Height, ADstMemData.Height);
  1899. ASizes[2] := MinInteger(ASizes[2], Depth, ADstMemData.Depth);
  1900. Assert(ASizes[2] = 0, 'Volume copying not yet implemented');
  1901. FStatus := CUDA_SUCCESS;
  1902. if ASizes[2] = 0 then
  1903. begin
  1904. // 2D copying
  1905. FillChar(copyParam2D, SizeOf(copyParam2D), 0);
  1906. // Setup source copy parameters
  1907. case MemoryType of
  1908. mtHost:
  1909. begin
  1910. copyParam2D.srcMemoryType := CU_MEMORYTYPE_HOST;
  1911. copyParam2D.srcHost := TCUdeviceptr(RawData);
  1912. end;
  1913. mtDevice:
  1914. begin
  1915. copyParam2D.srcMemoryType := CU_MEMORYTYPE_DEVICE;
  1916. copyParam2D.srcDevice := TCUdeviceptr(RawData);
  1917. end;
  1918. mtArray:
  1919. begin
  1920. copyParam2D.srcMemoryType := CU_MEMORYTYPE_ARRAY;
  1921. copyParam2D.srcArray := ArrayHandle;
  1922. end;
  1923. end;
  1924. copyParam2D.srcXInBytes := ASrcXYZ[0] * FElementSize;
  1925. copyParam2D.srcY := ASrcXYZ[1];
  1926. copyParam2D.srcPitch := fPitch;
  1927. // Setup destination copy parameters
  1928. case ADstMemData.FMemoryType of
  1929. mtHost:
  1930. begin
  1931. copyParam2D.dstMemoryType := CU_MEMORYTYPE_HOST;
  1932. copyParam2D.dstHost := TCUdeviceptr(ADstMemData.RawData);
  1933. end;
  1934. mtDevice:
  1935. begin
  1936. copyParam2D.dstMemoryType := CU_MEMORYTYPE_DEVICE;
  1937. copyParam2D.dstDevice := TCUdeviceptr(ADstMemData.RawData);
  1938. end;
  1939. mtArray:
  1940. begin
  1941. copyParam2D.dstMemoryType := CU_MEMORYTYPE_ARRAY;
  1942. copyParam2D.dstArray := ADstMemData.ArrayHandle;
  1943. end;
  1944. end;
  1945. copyParam2D.dstXInBytes := ADstXYZ[0] * ADstMemData.FElementSize;
  1946. copyParam2D.dstY := ADstXYZ[1];
  1947. copyParam2D.dstPitch := ADstMemData.fPitch;
  1948. copyParam2D.WidthInBytes := Cardinal(MinInteger(ElementSize * ASizes[0],
  1949. ADstMemData.ElementSize * ASizes[0]));
  1950. copyParam2D.Height := MaxInteger(ASizes[1], 1);
  1951. Context.Requires;
  1952. FStatus := cuMemcpy2D(@copyParam2D);
  1953. Context.Release;
  1954. end;
  1955. if FStatus <> CUDA_SUCCESS then
  1956. Abort
  1957. end;
  1958. procedure TCUDAMemData.CopyTo(const AGLImage: TGLBitmap32);
  1959. var
  1960. copyParam2D: TCUDA_MEMCPY2D;
  1961. // copyParam3D: TCUDA_MEMCPY3D;
  1962. begin
  1963. if not Assigned(AGLImage) then
  1964. exit;
  1965. Assert((fDepth = 0) and (AGLImage.Depth = 0),
  1966. 'Volume copying not yet implemented');
  1967. FillChar(copyParam2D, SizeOf(copyParam2D), 0);
  1968. // Setup source copy parameters
  1969. case FMemoryType of
  1970. mtHost:
  1971. begin
  1972. copyParam2D.srcMemoryType := CU_MEMORYTYPE_HOST;
  1973. copyParam2D.srcHost := TCUdeviceptr(RawData);
  1974. end;
  1975. mtDevice:
  1976. begin
  1977. copyParam2D.srcMemoryType := CU_MEMORYTYPE_DEVICE;
  1978. copyParam2D.srcDevice := TCUdeviceptr(RawData);
  1979. end;
  1980. mtArray:
  1981. begin
  1982. copyParam2D.srcMemoryType := CU_MEMORYTYPE_ARRAY;
  1983. copyParam2D.srcArray := ArrayHandle;
  1984. end;
  1985. end;
  1986. copyParam2D.srcPitch := fPitch;
  1987. // Setup destination copy parameters
  1988. copyParam2D.dstMemoryType := CU_MEMORYTYPE_HOST;
  1989. copyParam2D.dstHost := AGLImage.Data;
  1990. copyParam2D.dstPitch := AGLImage.ElementSize * AGLImage.Width;
  1991. copyParam2D.WidthInBytes :=
  1992. MinInteger(Cardinal(ElementSize * Width), copyParam2D.dstPitch);
  1993. copyParam2D.Height := MinInteger(Height, AGLImage.Height);
  1994. Context.Requires;
  1995. FStatus := cuMemcpy2D(@copyParam2D);
  1996. Context.Release;
  1997. if FStatus <> CUDA_SUCCESS then
  1998. Abort;
  1999. end;
  2000. procedure TCUDAMemData.CopyTo(const AGLGraphic: TCUDAGraphicResource;
  2001. aAttr: string);
  2002. var
  2003. pMap: TCUdeviceptr;
  2004. mapSize: Integer;
  2005. begin
  2006. if not Assigned(AGLGraphic.FHandle[0]) then
  2007. exit;
  2008. Context.Requires;
  2009. AGLGraphic.MapResources;
  2010. if AGLGraphic.FResourceType = rtBuffer then
  2011. begin
  2012. if Length(aAttr) = 0 then
  2013. begin
  2014. mapSize := AGLGraphic.GetElementArrayDataSize;
  2015. pMap := AGLGraphic.GetElementArrayAddress;
  2016. end
  2017. else
  2018. begin
  2019. mapSize := AGLGraphic.GetAttributeArraySize(aAttr);
  2020. pMap := AGLGraphic.GetAttributeArrayAddress(aAttr);
  2021. end;
  2022. end
  2023. else
  2024. begin
  2025. // TODO: image copying
  2026. AGLGraphic.UnMapResources;
  2027. Context.Release;
  2028. exit;
  2029. end;
  2030. FStatus := CUDA_SUCCESS;
  2031. case FMemoryType of
  2032. mtHost:
  2033. FStatus := cuMemcpyHtoD(pMap, RawData, MinInteger(DataSize, mapSize));
  2034. mtDevice:
  2035. FStatus := cuMemcpyDtoD(pMap, RawData, MinInteger(DataSize, mapSize));
  2036. mtArray:
  2037. FStatus := cuMemcpyAtoD(pMap, ArrayHandle, 0,
  2038. MinInteger(DataSize, mapSize));
  2039. end;
  2040. AGLGraphic.UnMapResources;
  2041. Context.Release;
  2042. if FStatus <> CUDA_SUCCESS then
  2043. Abort;
  2044. end;
  2045. procedure TCUDAMemData.CopyFrom(const ASrcMemData: TCUDAMemData);
  2046. begin
  2047. ASrcMemData.CopyTo(Self);
  2048. end;
  2049. procedure TCUDAMemData.CopyFrom(const AGLImage: TGLBitmap32);
  2050. var
  2051. copyParam2D: TCUDA_MEMCPY2D;
  2052. // copyParam3D: TCUDA_MEMCPY3D;
  2053. begin
  2054. if not Assigned(AGLImage) then
  2055. exit;
  2056. Assert((fDepth = 0) and (AGLImage.Depth = 0),
  2057. 'Volume copying not yet implemented');
  2058. FillChar(copyParam2D, SizeOf(copyParam2D), 0);
  2059. // Setup destination copy parameters
  2060. case FMemoryType of
  2061. mtHost:
  2062. begin
  2063. copyParam2D.dstMemoryType := CU_MEMORYTYPE_HOST;
  2064. copyParam2D.dstHost := TCUdeviceptr(RawData);
  2065. end;
  2066. mtDevice:
  2067. begin
  2068. copyParam2D.dstMemoryType := CU_MEMORYTYPE_DEVICE;
  2069. copyParam2D.dstDevice := TCUdeviceptr(RawData);
  2070. end;
  2071. mtArray:
  2072. begin
  2073. copyParam2D.dstMemoryType := CU_MEMORYTYPE_ARRAY;
  2074. copyParam2D.dstArray := ArrayHandle;
  2075. end;
  2076. end;
  2077. copyParam2D.dstPitch := fPitch;
  2078. // Setup source copy parameters
  2079. copyParam2D.srcMemoryType := CU_MEMORYTYPE_HOST;
  2080. copyParam2D.srcHost := AGLImage.Data;
  2081. copyParam2D.srcPitch := AGLImage.ElementSize * AGLImage.Width;
  2082. copyParam2D.WidthInBytes := MinInteger(
  2083. Cardinal(ElementSize * fWidth), copyParam2D.srcPitch);
  2084. copyParam2D.Height := MinInteger(fHeight, AGLImage.Height);
  2085. Context.Requires;
  2086. FStatus := cuMemcpy2D(@copyParam2D);
  2087. Context.Release;
  2088. if FStatus <> CUDA_SUCCESS then
  2089. Abort;
  2090. end;
  2091. procedure TCUDAMemData.CopyFrom(const AGLGraphic: TCUDAGraphicResource;
  2092. aAttr: string);
  2093. var
  2094. pMap: TCUdeviceptr;
  2095. mapSize: Integer;
  2096. begin
  2097. if not Assigned(AGLGraphic.FHandle[0]) then
  2098. exit;
  2099. Assert(fDepth = 0, 'Volume copying not yet implemented');
  2100. Context.Requires;
  2101. AGLGraphic.MapResources;
  2102. if AGLGraphic.fResourceType = rtBuffer then
  2103. begin
  2104. if Length(aAttr) = 0 then
  2105. begin
  2106. mapSize := AGLGraphic.GetElementArrayDataSize;
  2107. pMap := AGLGraphic.GetElementArrayAddress;
  2108. end
  2109. else
  2110. begin
  2111. mapSize := AGLGraphic.GetAttributeArraySize(aAttr);
  2112. pMap := AGLGraphic.GetAttributeArrayAddress(aAttr);
  2113. end;
  2114. end
  2115. else
  2116. begin
  2117. // TODO: image copying
  2118. AGLGraphic.UnMapResources;
  2119. Context.Release;
  2120. exit;
  2121. end;
  2122. FStatus := CUDA_SUCCESS;
  2123. case FMemoryType of
  2124. mtHost:
  2125. FStatus := cuMemcpyDtoH(RawData, pMap,
  2126. Cardinal(MinInteger(DataSize, mapSize)));
  2127. mtDevice:
  2128. FStatus := cuMemcpyDtoD(RawData, pMap,
  2129. Cardinal(MinInteger(DataSize, mapSize)));
  2130. mtArray:
  2131. FStatus := cuMemcpyDtoA(ArrayHandle, 0, pMap,
  2132. Cardinal(MinInteger(DataSize, mapSize)));
  2133. end;
  2134. AGLGraphic.UnMapResources;
  2135. Context.Release;
  2136. if FStatus <> CUDA_SUCCESS then
  2137. Abort;
  2138. end;
  2139. function TCUDAMemData.GetIsAllocated: Boolean;
  2140. begin
  2141. case FMemoryType of
  2142. mtHost, mtDevice: Result := Assigned(FData);
  2143. mtArray: Result := Assigned(FHandle);
  2144. else
  2145. Result := False;
  2146. end;
  2147. end;
  2148. procedure TCUDAMemData.Map(const AFlags: TCUDAMemMapFlags);
  2149. var
  2150. LFlag: Cardinal;
  2151. begin
  2152. if FMapping then
  2153. begin
  2154. {$IFDEF USE_LOGGING}
  2155. LogErrorFmt(strFailMap, [Name]);
  2156. {$ENDIF}
  2157. Abort;
  2158. end;
  2159. LFlag := 0;
  2160. if mmfPortable in AFlags then
  2161. LFlag := LFlag or CU_MEMHOSTALLOC_PORTABLE;
  2162. if mmfFastWrite in AFlags then
  2163. LFlag := LFlag or CU_MEMHOSTALLOC_WRITECOMBINED;
  2164. Context.Requires;
  2165. GetData;
  2166. case FMemoryType of
  2167. mtHost:
  2168. begin
  2169. FStatus := cuMemHostGetDevicePointer(
  2170. FMappedMemory, GetData, 0);
  2171. end;
  2172. mtDevice:
  2173. begin
  2174. FStatus := cuMemHostAlloc(
  2175. FMappedMemory, DataSize, LFlag);
  2176. if FStatus = CUDA_SUCCESS then
  2177. FStatus := cuMemcpyDtoH(
  2178. FMappedMemory, GetData, DataSize);
  2179. end;
  2180. mtArray:
  2181. begin
  2182. FStatus := cuMemHostAlloc(
  2183. FMappedMemory, DataSize, LFlag);
  2184. if FStatus = CUDA_SUCCESS then
  2185. FStatus := cuMemcpyAtoH(
  2186. FMappedMemory, GetArrayHandle, 0, DataSize);
  2187. end;
  2188. end;
  2189. Context.Release;
  2190. if FStatus <> CUDA_SUCCESS then
  2191. Abort;
  2192. FMapping := True;
  2193. end;
  2194. // ------------------
  2195. // ------------------ TCUDATexture ------------------
  2196. // ------------------
  2197. constructor TCUDATexture.Create(AOwner: TComponent);
  2198. begin
  2199. inherited Create(AOwner);
  2200. FHandle := nil;
  2201. fArray := nil;
  2202. AddressModeS := amClamp;
  2203. AddressModeT := amClamp;
  2204. AddressModeR := amClamp;
  2205. NormalizedCoord := true;
  2206. ReadAsInteger := false;
  2207. FilterMode := fmPoint;
  2208. fFormat := ctUndefined;
  2209. fChannelNum := cnOne;
  2210. end;
  2211. destructor TCUDATexture.Destroy;
  2212. begin
  2213. if Assigned(fArray) then
  2214. fArray.fTexture := nil;
  2215. DestroyHandles;
  2216. inherited;
  2217. end;
  2218. function TCUDATexture.GetHandle: PCUtexref;
  2219. begin
  2220. if not Assigned(FHandle) or (FChanges <> []) then
  2221. AllocateHandles;
  2222. Result := FHandle;
  2223. end;
  2224. function TCUDATexture.GetIsAllocated: Boolean;
  2225. begin
  2226. Result := Assigned(FHandle);
  2227. end;
  2228. procedure TCUDATexture.AllocateHandles;
  2229. var
  2230. pTex: PCUtexref;
  2231. LName: AnsiString;
  2232. LModule: TCUDAModule;
  2233. LFlag: Cardinal;
  2234. LFormat: TCUarray_format;
  2235. LChanels: Integer;
  2236. begin
  2237. if not(FMaster is TCUDAModule) then
  2238. begin
  2239. {$IFDEF USE_LOGGING}
  2240. LogError(strModuleAbsent);
  2241. {$ENDIF}
  2242. Abort;
  2243. end;
  2244. if Length(FKernelName) = 0 then
  2245. exit;
  2246. LModule := TCUDAModule(FMaster);
  2247. LName := AnsiString(FKernelName);
  2248. Context.Requires;
  2249. FStatus := cuModuleGetTexRef(pTex, LModule.FHandle, PAnsiChar(LName));
  2250. Context.Release;
  2251. if FStatus <> CUDA_SUCCESS then
  2252. Abort;
  2253. FHandle := pTex;
  2254. Context.Requires;
  2255. // Apply changes
  2256. if (cuchArray in FChanges) and Assigned(fArray) then
  2257. begin
  2258. CollectStatus(cuTexRefSetArray(FHandle, fArray.ArrayHandle,
  2259. CU_TRSA_OVERRIDE_FORMAT));
  2260. fArray.fTexture := Self;
  2261. // Update format
  2262. if cuTexRefGetFormat(LFormat, LChanels, FHandle) = CUDA_SUCCESS then
  2263. CUDAEnumToChannelDesc(LFormat, LChanels, fFormat, fChannelNum);
  2264. end;
  2265. if cuchAddresMode in FChanges then
  2266. begin
  2267. CollectStatus(cuTexRefSetAddressMode(FHandle, 0,
  2268. cAddressMode[fAddressModeS]));
  2269. CollectStatus(cuTexRefSetAddressMode(FHandle, 1,
  2270. cAddressMode[fAddressModeT]));
  2271. CollectStatus(cuTexRefSetAddressMode(FHandle, 2,
  2272. cAddressMode[fAddressModeR]));
  2273. end;
  2274. if cuchFlag in FChanges then
  2275. begin
  2276. LFlag := 0;
  2277. if fNormalizedCoord then
  2278. LFlag := LFlag or CU_TRSF_NORMALIZED_COORDINATES;
  2279. if fReadAsInteger then
  2280. LFlag := LFlag or CU_TRSF_READ_AS_INTEGER;
  2281. CollectStatus(cuTexRefSetFlags(FHandle, LFlag));
  2282. end;
  2283. if cuchFilterMode in FChanges then
  2284. CollectStatus(cuTexRefSetFilterMode(FHandle, cFilterMode[fFilterMode]));
  2285. Context.Release;
  2286. if FStatus <> CUDA_SUCCESS then
  2287. Abort;
  2288. FChanges := [];
  2289. inherited;
  2290. end;
  2291. procedure TCUDATexture.DestroyHandles;
  2292. begin
  2293. if Assigned(FHandle) then
  2294. begin
  2295. FHandle := nil;
  2296. inherited;
  2297. end;
  2298. end;
  2299. procedure TCUDATexture.SetKernelName(const AName: string);
  2300. begin
  2301. if csLoading in ComponentState then
  2302. FKernelName := AName
  2303. else if not Assigned(FHandle) then
  2304. begin
  2305. FKernelName := AName;
  2306. AllocateHandles;
  2307. end;
  2308. end;
  2309. // SetAddressModeS
  2310. //
  2311. procedure TCUDATexture.SetAddressModeS(const AMode: TCuAddresMode);
  2312. begin
  2313. if AMode <> fAddressModeS then
  2314. begin
  2315. fAddressModeS := AMode;
  2316. CuNotifyChange(cuchAddresMode);
  2317. end;
  2318. end;
  2319. procedure TCUDATexture.SetAddressModeT(const AMode: TCuAddresMode);
  2320. begin
  2321. if AMode <> fAddressModeT then
  2322. begin
  2323. fAddressModeT := AMode;
  2324. CuNotifyChange(cuchAddresMode);
  2325. end;
  2326. end;
  2327. procedure TCUDATexture.SetAddressModeR(const AMode: TCuAddresMode);
  2328. begin
  2329. if AMode <> fAddressModeR then
  2330. begin
  2331. fAddressModeR := AMode;
  2332. CuNotifyChange(cuchAddresMode);
  2333. end;
  2334. end;
  2335. procedure TCUDATexture.SetNormalizedCoord(const flag: Boolean);
  2336. begin
  2337. if flag <> fNormalizedCoord then
  2338. begin
  2339. fNormalizedCoord := flag;
  2340. CuNotifyChange(cuchFlag);
  2341. end;
  2342. end;
  2343. procedure TCUDATexture.SetReadAsInteger(const flag: Boolean);
  2344. begin
  2345. if flag <> fReadAsInteger then
  2346. begin
  2347. fReadAsInteger := flag;
  2348. CuNotifyChange(cuchFlag);
  2349. end;
  2350. end;
  2351. procedure TCUDATexture.SetFilterMode(const mode: TCuFilterMode);
  2352. begin
  2353. if mode <> fFilterMode then
  2354. begin
  2355. fFilterMode := mode;
  2356. CuNotifyChange(cuchFilterMode);
  2357. end;
  2358. end;
  2359. procedure TCUDATexture.SetFormat(AValue: TCUDAChannelType);
  2360. begin
  2361. if csLoading in ComponentState then
  2362. fFormat := AValue
  2363. else if not Assigned(FHandle) then
  2364. begin
  2365. fFormat := AValue;
  2366. CuNotifyChange(cuchFormat);
  2367. end;
  2368. end;
  2369. procedure TCUDATexture.SetArray(Value: TCUDAMemData);
  2370. begin
  2371. if Value <> fArray then
  2372. begin
  2373. if Assigned(fArray) then
  2374. fArray.fTexture := nil;
  2375. if Assigned(Value) then
  2376. begin
  2377. if Value.MemoryType <> mtArray then
  2378. Value := nil
  2379. else
  2380. begin
  2381. fFormat := Value.fChannelsType;
  2382. fChannelNum := Value.fChannelsNum;
  2383. if Assigned(Value.fTexture) then
  2384. Value.fTexture.MemDataArray := nil;
  2385. Value.fTexture := Self;
  2386. end;
  2387. end
  2388. else
  2389. begin
  2390. fFormat := ctUndefined;
  2391. fChannelNum := cnOne;
  2392. end;
  2393. fArray := Value;
  2394. CuNotifyChange(cuchArray);
  2395. end;
  2396. end;
  2397. procedure TCUDATexture.SetChannelNum(AValue: TCUDAChannelNum);
  2398. begin
  2399. if csLoading in ComponentState then
  2400. fChannelNum := AValue
  2401. else if not Assigned(FHandle) then
  2402. begin
  2403. fChannelNum := AValue;
  2404. CuNotifyChange(cuchFormat);
  2405. end;
  2406. end;
  2407. // ------------------
  2408. // ------------------ TCUDAGraphicResource ------------------
  2409. // ------------------
  2410. procedure TCUDAGraphicResource.SetMapping(const Value: TCUDAMapping);
  2411. begin
  2412. if fMapping <> Value then
  2413. begin
  2414. fMapping := Value;
  2415. CuNotifyChange(cuchMapping);
  2416. end;
  2417. end;
  2418. function TCUDAGraphicResource.GetIsAllocated: Boolean;
  2419. var
  2420. I: Integer;
  2421. begin
  2422. for I := 0 to High(FHandle) do
  2423. if Assigned(FHandle[I]) then
  2424. exit(True);
  2425. Result := False;
  2426. end;
  2427. procedure TCUDAGraphicResource.OnGLHandleAllocate(Sender: TGLVirtualHandle;
  2428. var Handle: Cardinal);
  2429. begin
  2430. Handle := GLVirtualHandleCounter;
  2431. Inc(GLVirtualHandleCounter);
  2432. end;
  2433. procedure TCUDAGraphicResource.OnGLHandleDestroy(Sender: TGLVirtualHandle;
  2434. var Handle: Cardinal);
  2435. begin
  2436. DestroyHandles;
  2437. end;
  2438. procedure TCUDAGraphicResource.SetArray(var AArray: TCUDAMemData;
  2439. AHandle: PCUarray; ForGLTexture, Volume: Boolean);
  2440. var
  2441. Desc2D: TCUDA_ARRAY_DESCRIPTOR;
  2442. Desc3D: TCUDA_ARRAY3D_DESCRIPTOR;
  2443. begin
  2444. Context.Requires;
  2445. // Get array descriptor
  2446. if Volume then
  2447. FStatus := cuArray3DGetDescriptor(Desc3D, AHandle)
  2448. else
  2449. FStatus := cuArrayGetDescriptor(Desc2D, AHandle);
  2450. Context.Release;
  2451. if FStatus <> CUDA_SUCCESS then
  2452. Abort;
  2453. // Set array parameters
  2454. if not Assigned(AArray) then
  2455. AArray := TCUDAMemData.Create(Owner);
  2456. with AArray do
  2457. begin
  2458. if FHandle <> AHandle then
  2459. begin
  2460. DestroyHandles;
  2461. FHandle := AHandle;
  2462. end;
  2463. FOpenGLRefArray := ForGLTexture;
  2464. FMemoryType := mtArray;
  2465. FPitch := 0;
  2466. if Volume then
  2467. begin
  2468. fWidth := Desc3D.Width;
  2469. fHeight := Desc3D.Height;
  2470. fDepth := Desc3D.Depth;
  2471. CUDAEnumToChannelDesc(Desc3D.Format, Desc3D.NumChannels, fChannelsType,
  2472. fChannelsNum);
  2473. end
  2474. else
  2475. begin
  2476. fWidth := Desc2D.Width;
  2477. fHeight := Desc2D.Height;
  2478. fDepth := 0;
  2479. CUDAEnumToChannelDesc(Desc2D.Format, Desc2D.NumChannels, fChannelsType,
  2480. fChannelsNum);
  2481. end;
  2482. FElementSize := cChannelTypeSize[fChannelsType] * (Ord(fChannelsNum) + 1);
  2483. end;
  2484. end;
  2485. // ------------------
  2486. // ------------------ TCUDAUniform ------------------
  2487. // ------------------
  2488. constructor TCUDAUniform.Create(AOwner: TComponent);
  2489. begin
  2490. inherited Create(AOwner);
  2491. FHandle := nil;
  2492. FSize := 0;
  2493. FType := TCUDAType.CustomType;
  2494. FDefined := false;
  2495. end;
  2496. destructor TCUDAUniform.Destroy;
  2497. begin
  2498. DestroyHandles;
  2499. inherited;
  2500. end;
  2501. function TCUDAUniform.GetIsAllocated: Boolean;
  2502. begin
  2503. Result := Assigned(FHandle);
  2504. end;
  2505. procedure TCUDAUniform.SetCustomType(const AValue: string);
  2506. begin
  2507. if csLoading in ComponentState then
  2508. FCustomType := AValue
  2509. else if not Assigned(FHandle) then
  2510. begin
  2511. FCustomType := AValue;
  2512. CuNotifyChange(cuchSize);
  2513. end;
  2514. end;
  2515. procedure TCUDAUniform.SetDefined(AValue: Boolean);
  2516. begin
  2517. if not Assigned(FHandle) then
  2518. FDefined := AValue;
  2519. end;
  2520. procedure TCUDAUniform.SetKernelName(const AName: string);
  2521. begin
  2522. if csLoading in ComponentState then
  2523. FKernelName := AName
  2524. else if not Assigned(FHandle) then
  2525. begin
  2526. FKernelName := AName;
  2527. CuNotifyChange(cuchSize);
  2528. end;
  2529. end;
  2530. procedure TCUDAUniform.SetSize(const AValue: Cardinal);
  2531. begin
  2532. if csLoading in ComponentState then
  2533. FSize := AValue
  2534. else if not Assigned(FHandle) then
  2535. begin
  2536. FSize := AValue;
  2537. CuNotifyChange(cuchSize);
  2538. end;
  2539. end;
  2540. procedure TCUDAUniform.SetType(AValue: TCUDAType);
  2541. begin
  2542. if csLoading in ComponentState then
  2543. FType := AValue
  2544. else if not Assigned(FHandle) then
  2545. begin
  2546. FType := AValue;
  2547. CuNotifyChange(cuchSize);
  2548. end;
  2549. end;
  2550. procedure TCUDAUniform.SetRef(AValue: Boolean);
  2551. begin
  2552. if csLoading in ComponentState then
  2553. FRef := AValue
  2554. else if not Assigned(FHandle) then
  2555. begin
  2556. FRef := AValue;
  2557. CuNotifyChange(cuchSize);
  2558. end;
  2559. end;
  2560. // ------------------
  2561. // ------------------ TCUDAConstant ------------------
  2562. // ------------------
  2563. procedure TCUDAConstant.AllocateHandles;
  2564. var
  2565. LName: AnsiString;
  2566. LModule: TCUDAModule;
  2567. begin
  2568. if not(FMaster is TCUDAModule) then
  2569. begin
  2570. {$IFDEF USE_LOGGING}
  2571. LogError(strModuleAbsent);
  2572. {$ENDIF}
  2573. Abort;
  2574. end;
  2575. if Length(FKernelName) = 0 then
  2576. exit;
  2577. LModule := TCUDAModule(FMaster);
  2578. LName := AnsiString(FKernelName);
  2579. DestroyHandles;
  2580. Context.Requires;
  2581. FStatus := cuModuleGetGlobal(FHandle, FSize, LModule.FHandle,
  2582. PAnsiChar(LName));
  2583. Context.Release;
  2584. if FStatus <> CUDA_SUCCESS then
  2585. Abort;
  2586. FChanges := [];
  2587. inherited;
  2588. end;
  2589. procedure TCUDAConstant.DestroyHandles;
  2590. begin
  2591. if Assigned(FHandle) then
  2592. begin
  2593. FHandle := nil;
  2594. inherited;
  2595. end;
  2596. end;
  2597. function TCUDAConstant.GetDeviceAddress: TCUdeviceptr;
  2598. begin
  2599. if (FChanges <> []) or (FHandle = nil) then
  2600. AllocateHandles;
  2601. Result := FHandle;
  2602. end;
  2603. // ------------------
  2604. // ------------------ TCUDAFuncParam ------------------
  2605. // ------------------
  2606. procedure TCUDAFuncParam.AllocateHandles;
  2607. begin
  2608. if Assigned(Master) and (Master is TCUDAFunction) then
  2609. begin
  2610. FHandle := TCUDAFunction(Master).FHandle;
  2611. if Assigned(FHandle) then
  2612. inherited;
  2613. end;
  2614. end;
  2615. constructor TCUDAFuncParam.Create(AOwner: TComponent);
  2616. begin
  2617. inherited;
  2618. FHandle := nil;
  2619. FRef := false;
  2620. end;
  2621. procedure TCUDAFuncParam.DestroyHandles;
  2622. begin
  2623. if Assigned(FHandle) then
  2624. begin
  2625. FHandle := nil;
  2626. inherited;
  2627. end;
  2628. end;
  2629. // ------------------------------------------------------------------
  2630. initialization
  2631. // ------------------------------------------------------------------
  2632. RegisterClasses([TGLCUDA, TGLCUDACompiler, TCUDAModule, TCUDAFunction,
  2633. TCUDATexture, TCUDAMemData, TCUDAConstant, TCUDAFuncParam]);
  2634. end.