CUDA.PropEditors.pas 9.6 KB

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