GLS.CUDA.pas 77 KB

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