GXS.CUDA.API.pas 73 KB

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