2
0

GXS.GPURegister.pas 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440
  1. //
  2. // The graphics GaLaXy Engine. The unit of GXScene
  3. //
  4. unit GXS.GPURegister;
  5. (* Registration unit for GPU Computing package *)
  6. interface
  7. uses
  8. System.Classes,
  9. System.SysUtils,
  10. /// DesignIntf,
  11. /// DesignEditors,
  12. {
  13. ToolsAPI,
  14. STREDIT,
  15. }
  16. GXS.CUDA.Context,
  17. GXS.CUDA.API,
  18. GXS.CUDA.Compiler,
  19. GXS.CUDA.FFTPlan,
  20. GXS.CUDA.Graphics,
  21. Stage.Strings;
  22. procedure Register;
  23. type
  24. TCUDAEditor = class(TComponentEditor)
  25. public
  26. procedure Edit; override;
  27. procedure ExecuteVerb(Index: Integer); override;
  28. function GetVerb(Index: Integer): string; override;
  29. function GetVerbCount: Integer; override;
  30. end;
  31. TCUDACompilerEditor = class(TComponentEditor)
  32. public
  33. procedure Edit; override;
  34. procedure ExecuteVerb(Index: Integer); override;
  35. function GetVerb(Index: Integer): string; override;
  36. function GetVerbCount: Integer; override;
  37. end;
  38. TCUDACompilerSourceProperty = class(TStringProperty)
  39. private
  40. FModuleList: TStringList;
  41. procedure RefreshModuleList;
  42. public
  43. constructor Create(const ADesigner: IDesigner; APropCount: Integer); override;
  44. destructor Destroy; override;
  45. function GetAttributes: TPropertyAttributes; override;
  46. procedure GetValues(Proc: TGetStrProc); override;
  47. procedure SetValue(const Value: String); override;
  48. end;
  49. TCUDADeviceProperty = class(TStringProperty)
  50. private
  51. FDeviceList: TStringList;
  52. public
  53. constructor Create(const ADesigner: IDesigner; APropCount: Integer); override;
  54. destructor Destroy; override;
  55. function GetAttributes: TPropertyAttributes; override;
  56. procedure GetValues(Proc: TGetStrProc); override;
  57. procedure SetValue(const Value: String); override;
  58. end;
  59. implementation //--------------------------------------------------------------
  60. uses
  61. FMxCUDAEditor,
  62. CUDA.RunTime,
  63. CUDA.Parser;
  64. function FindCuFile(var AModuleName: string): Boolean;
  65. var
  66. proj: IOTAProject;
  67. I: Integer;
  68. LModule: IOTAModuleInfo;
  69. LName: string;
  70. begin
  71. proj := GetActiveProject;
  72. if proj <> nil then
  73. begin
  74. for I := 0 to proj.GetModuleCount - 1 do
  75. begin
  76. LModule := proj.GetModule(I);
  77. LName := ExtractFileName(LModule.FileName);
  78. if LName = AModuleName then
  79. begin
  80. AModuleName := LModule.FileName;
  81. exit(True);
  82. end;
  83. end;
  84. end;
  85. Result := False;
  86. end;
  87. // ------------------
  88. // ------------------ TCUDAEditor ------------------
  89. // ------------------
  90. procedure TCUDAEditor.Edit;
  91. begin
  92. with CUDAEditorForm do
  93. begin
  94. SetCUDAEditorClient(TCUDA(Self.Component), Self.Designer);
  95. Show;
  96. end;
  97. end;
  98. procedure TCUDAEditor.ExecuteVerb(Index: Integer);
  99. begin
  100. case Index of
  101. 0: Edit;
  102. end;
  103. end;
  104. function TCUDAEditor.GetVerb(Index: Integer): string;
  105. begin
  106. case Index of
  107. 0: Result := 'Show CUDA Items Editor';
  108. end;
  109. end;
  110. function TCUDAEditor.GetVerbCount: Integer;
  111. begin
  112. Result := 1;
  113. end;
  114. // ------------------
  115. // ------------------ TCUDACompilerEditor ------------------
  116. // ------------------
  117. procedure TCUDACompilerEditor.Edit;
  118. var
  119. CUDACompiler: TCUDACompiler;
  120. I, J: Integer;
  121. func: TCUDAFunction;
  122. tex: TCUDATexture;
  123. cnst: TCUDAConstant;
  124. param: TCUDAFuncParam;
  125. parent: TCUDAModule;
  126. info: TCUDAModuleInfo;
  127. bUseless: Boolean;
  128. useless: array of TCUDAComponent;
  129. CTN: TChannelTypeAndNum;
  130. procedure CreateFuncParams;
  131. var
  132. K: Integer;
  133. begin
  134. for K := 0 to High(info.Func[I].Args) do
  135. begin
  136. param := TCUDAFuncParam(Designer.CreateComponent(TCUDAFuncParam,
  137. func, 0, 0, 0, 0));
  138. param.Master := TCUDAComponent(func);
  139. param.KernelName := info.Func[I].Args[K].Name;
  140. param.Name := func.KernelName+'_'+param.KernelName;
  141. param.DataType := info.Func[I].Args[K].DataType;
  142. param.CustomType := info.Func[I].Args[K].CustomType;
  143. param.Reference := info.Func[I].Args[K].Ref;
  144. end;
  145. end;
  146. begin
  147. CUDACompiler := TCUDACompiler(Self.Component);
  148. if CUDACompiler.Compile then
  149. begin
  150. info := CUDACompiler.ModuleInfo;
  151. parent := TCUDAModule(info.Owner);
  152. // Create kernel's functions
  153. for I := 0 to High(info.Func) do
  154. begin
  155. func := parent.KernelFunction[info.Func[I].KernelName];
  156. if not Assigned(func) then
  157. begin
  158. func := TCUDAFunction(Designer.CreateComponent(TCUDAFunction,
  159. info.Owner, 0, 0, 0, 0));
  160. func.Master := TCUDAComponent(info.Owner);
  161. func.KernelName := info.Func[I].KernelName;
  162. func.Name := TCUDAComponent(info.Owner).MakeUniqueName(info.Func[I].Name);
  163. end
  164. else
  165. begin
  166. // destroy old parameters
  167. while func.ItemsCount > 0 do
  168. func.Items[0].Destroy;
  169. end;
  170. try
  171. bUseless := func.Handle = nil;
  172. except
  173. bUseless := True;
  174. end;
  175. if bUseless then
  176. begin
  177. Designer.SelectComponent(func);
  178. Designer.DeleteSelection(True);
  179. func := nil;
  180. end
  181. else
  182. CreateFuncParams;
  183. end;
  184. // Create kernel's textures
  185. for I := 0 to High(info.TexRef) do
  186. begin
  187. tex := parent.KernelTexture[info.TexRef[I].Name];
  188. if not Assigned(tex) then
  189. begin
  190. tex := TCUDATexture(Designer.CreateComponent(TCUDATexture,
  191. info.Owner, 0, 0, 0, 0));
  192. tex.Master := TCUDAComponent(info.Owner);
  193. tex.KernelName := info.TexRef[I].Name;
  194. tex.Name := tex.KernelName;
  195. tex.ReadAsInteger := (info.TexRef[I].ReadMode = cudaReadModeElementType);
  196. CTN := GetChannelTypeAndNum(info.TexRef[I].DataType);
  197. tex.Format := CTN.F;
  198. end;
  199. tex.ChannelNum := CTN.C;
  200. try
  201. bUseless := tex.Handle = nil;
  202. except
  203. bUseless := True;
  204. end;
  205. if bUseless then
  206. begin
  207. Designer.SelectComponent(tex);
  208. Designer.DeleteSelection(True);
  209. end;
  210. end;
  211. // Create kernel's constants
  212. for I := 0 to High(info.Constant) do
  213. begin
  214. cnst := parent.KernelConstant[info.Constant[I].Name];
  215. if not Assigned(cnst) then
  216. begin
  217. cnst := TCUDAConstant(Designer.CreateComponent(TCUDAConstant,
  218. info.Owner, 0, 0, 0, 0));
  219. cnst.Master := TCUDAComponent(info.Owner);
  220. cnst.KernelName := info.Constant[I].Name;
  221. cnst.Name := cnst.KernelName;
  222. cnst.DataType := info.Constant[I].DataType;
  223. cnst.CustomType := info.Constant[I].CustomType;
  224. cnst.IsValueDefined := info.Constant[I].DefValue;
  225. end;
  226. try
  227. bUseless := cnst.DeviceAddress = nil;
  228. except
  229. bUseless := True;
  230. end;
  231. if bUseless then
  232. begin
  233. Designer.SelectComponent(cnst);
  234. Designer.DeleteSelection(True);
  235. end;
  236. end;
  237. // Delete useless components
  238. SetLength(useless, parent.ItemsCount);
  239. j := 0;
  240. for i := 0 to parent.ItemsCount - 1 do
  241. begin
  242. if not TCUDAComponent(parent.Items[i]).IsAllocated then
  243. begin
  244. useless[j] := parent.Items[i];
  245. inc(j);
  246. end;
  247. end;
  248. for i := 0 to j - 1 do
  249. useless[i].Destroy;
  250. end;
  251. Designer.Modified;
  252. end;
  253. procedure TCUDACompilerEditor.ExecuteVerb(Index: Integer);
  254. begin
  255. case Index of
  256. 0: Edit;
  257. end;
  258. end;
  259. function TCUDACompilerEditor.GetVerb(Index: Integer): string;
  260. begin
  261. case Index of
  262. 0: Result := 'Compile Module';
  263. end;
  264. end;
  265. function TCUDACompilerEditor.GetVerbCount: Integer;
  266. begin
  267. Result := 1;
  268. end;
  269. // ------------------
  270. // ------------------ TCUDACompilerSourceProperty ------------------
  271. // ------------------
  272. constructor TCUDACompilerSourceProperty.Create(
  273. const ADesigner: IDesigner; APropCount: Integer);
  274. begin
  275. inherited;
  276. FModuleList := TStringList.Create;
  277. end;
  278. destructor TCUDACompilerSourceProperty.Destroy;
  279. begin
  280. FModuleList.Destroy;
  281. inherited;
  282. end;
  283. procedure TCUDACompilerSourceProperty.RefreshModuleList;
  284. var
  285. proj: IOTAProject;
  286. I: Integer;
  287. LModule: IOTAModuleInfo;
  288. LName: string;
  289. begin
  290. FModuleList.Clear;
  291. FModuleList.Add('none');
  292. proj := GetActiveProject;
  293. if proj <> nil then
  294. begin
  295. for I := 0 to proj.GetModuleCount - 1 do
  296. begin
  297. LModule := proj.GetModule(I);
  298. LName := UpperCase(ExtractFileExt(LModule.FileName));
  299. if LName = '.CU' then
  300. FModuleList.Add(LModule.FileName);
  301. end;
  302. end;
  303. end;
  304. function TCUDACompilerSourceProperty.GetAttributes;
  305. begin
  306. Result := [paValueList];
  307. end;
  308. procedure TCUDACompilerSourceProperty.GetValues(Proc: TGetStrProc);
  309. var
  310. I : Integer;
  311. begin
  312. RefreshModuleList;
  313. for I := 0 to FModuleList.Count - 1 do
  314. Proc(ExtractFileName(FModuleList[I]));
  315. end;
  316. procedure TCUDACompilerSourceProperty.SetValue(const Value: String);
  317. var
  318. I, J: Integer;
  319. begin
  320. RefreshModuleList;
  321. J := -1;
  322. for I := 1 to FModuleList.Count - 1 do
  323. if Value = ExtractFileName(FModuleList[I]) then
  324. begin
  325. J := I;
  326. Break;
  327. end;
  328. if J > 0 then
  329. begin
  330. TCUDACompiler(GetComponent(0)).SetSourceCodeFile(FModuleList[J]);
  331. SetStrValue(ExtractFileName(Value));
  332. end
  333. else
  334. begin
  335. SetStrValue('none');
  336. end;
  337. Modified;
  338. end;
  339. // ------------------
  340. // ------------------ TCUDADeviceProperty ------------------
  341. // ------------------
  342. constructor TCUDADeviceProperty.Create(const ADesigner: IDesigner; APropCount: Integer);
  343. begin
  344. inherited;
  345. FDeviceList := TStringList.Create;
  346. end;
  347. destructor TCUDADeviceProperty.Destroy;
  348. begin
  349. FDeviceList.Destroy;
  350. inherited;
  351. end;
  352. function TCUDADeviceProperty.GetAttributes: TPropertyAttributes;
  353. begin
  354. Result := [paValueList];
  355. end;
  356. procedure TCUDADeviceProperty.GetValues(Proc: TGetStrProc);
  357. begin
  358. CUDAContextManager.FillUnusedDeviceList(FDeviceList);
  359. end;
  360. procedure TCUDADeviceProperty.SetValue(const Value: String);
  361. var
  362. I: Integer;
  363. begin
  364. for I := 0 to FDeviceList.Count - 1 do
  365. if Value = FDeviceList[I] then
  366. begin
  367. SetStrValue(Value);
  368. Break;
  369. end;
  370. Modified;
  371. end;
  372. procedure Register;
  373. begin
  374. RegisterComponents('GPU Computing', [TCUDA, TCUDADevice, TCUDACompiler]);
  375. RegisterComponentEditor(TCUDA, TCUDAEditor);
  376. RegisterComponentEditor(TCUDACompiler, TCUDACompilerEditor);
  377. RegisterPropertyEditor(TypeInfo(string), TCUDACompiler, 'ProjectModule',
  378. TCUDACompilerSourceProperty);
  379. RegisterPropertyEditor(TypeInfo(string), TCUDADevice, 'SelectDevice',
  380. TCUDADeviceProperty);
  381. RegisterNoIcon([TCUDAModule, TCUDAMemData, TCUDAFunction, TCUDATexture,
  382. TCUDAFFTPlan, TCUDAImageResource, TCUDAGeometryResource, TCUDAConstant, TCUDAFuncParam]);
  383. ObjectManager.RegisterSceneObject(TgxFeedBackMesh, 'GPU generated mesh', 'GPU Computing', HInstance);
  384. end;
  385. initialization //--------------------------------------------------------------
  386. vFindCuFileFunc := FindCuFile;
  387. end.