GXS.CUDA.Graphics.pas 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153
  1. //
  2. // The graphics engine GLXEngine. The unit of GXScene for Delphi
  3. //
  4. unit GXS.CUDA.Graphics;
  5. interface
  6. uses
  7. Winapi.OpenGL,
  8. Winapi.OpenGLext,
  9. System.SysUtils,
  10. System.Classes,
  11. FMX.Dialogs,
  12. CUDA.Import,
  13. GXS.CUDA.API,
  14. GXS.Context,
  15. GXS.State,
  16. GXS.Scene,
  17. GXS.Graphics,
  18. GXS.Material,
  19. GXS.Texture,
  20. GXSL.Shader,
  21. GXSL.Parameter,
  22. GXS.RenderContextInfo;
  23. type
  24. TCUDAVertexAttribute = class;
  25. TCUDAVertexAttributes = class;
  26. TOnBeforeKernelLaunch = procedure(Sender: TCUDAVertexAttribute) of object;
  27. TCUDAVertexAttribute = class(TCollectionItem)
  28. private
  29. FName: string;
  30. FType: TgxSLDataType;
  31. FFunc: TCUDAFunction;
  32. FLocation: Integer;
  33. FOnBeforeKernelLaunch: TOnBeforeKernelLaunch;
  34. procedure SetName(const AName: string);
  35. procedure SetType(AType: TgxSLDataType);
  36. procedure SetFunc(AFunc: TCUDAFunction);
  37. function GetLocation: Integer;
  38. function GetOwner: TCUDAVertexAttributes; reintroduce;
  39. public
  40. constructor Create(ACollection: TCollection); override;
  41. procedure NotifyChange(Sender: TObject);
  42. property Location: Integer read GetLocation;
  43. published
  44. property Name: string read FName write SetName;
  45. property GLSLType: TgxSLDataType read FType write SetType;
  46. property KernelFunction: TCUDAFunction read FFunc write SetFunc;
  47. property OnBeforeKernelLaunch: TOnBeforeKernelLaunch read
  48. FOnBeforeKernelLaunch write FOnBeforeKernelLaunch;
  49. end;
  50. TCUDAVertexAttributes = class(TOwnedCollection)
  51. private
  52. procedure SetItems(Index: Integer; const AValue: TCUDAVertexAttribute);
  53. function GetItems(Index: Integer): TCUDAVertexAttribute;
  54. public
  55. constructor Create(AOwner: TComponent);
  56. procedure NotifyChange(Sender: TObject);
  57. function MakeUniqueName(const ANameRoot: string): string;
  58. function GetAttributeByName(const AName: string): TCUDAVertexAttribute;
  59. function Add: TCUDAVertexAttribute;
  60. property Attributes[Index: Integer]: TCUDAVertexAttribute read GetItems
  61. write SetItems; default;
  62. end;
  63. TFeedBackMeshPrimitive = (fbmpPoint, fbmpLine, fbmpTriangle);
  64. TFeedBackMeshLaunching = (fblCommon, fblOnePerAtttribute);
  65. TgxCustomFeedBackMesh = class(TgxBaseSceneObject)
  66. private
  67. FGeometryResource: TCUDAGraphicResource;
  68. FAttributes: TCUDAVertexAttributes;
  69. FVAO: TgxVertexArrayHandle;
  70. FVBO: TgxVBOArrayBufferHandle;
  71. FEBO: TgxVBOElementArrayHandle;
  72. FPrimitiveType: TFeedBackMeshPrimitive;
  73. FVertexNumber: Integer;
  74. FElementNumber: Integer;
  75. FShader: TgxSLShader;
  76. FCommonFunc: TCUDAFunction;
  77. FLaunching: TFeedBackMeshLaunching;
  78. FBlend: Boolean;
  79. procedure SetAttributes(AValue: TCUDAVertexAttributes);
  80. procedure SetPrimitiveType(AValue: TFeedBackMeshPrimitive);
  81. procedure SetVertexNumber(AValue: Integer);
  82. procedure SetElementNumber(AValue: Integer);
  83. procedure SetShader(AShader: TgxSLShader);
  84. procedure SetCommonFunc(AFunc: TCUDAFunction);
  85. protected
  86. procedure Notification(AComponent: TComponent;
  87. Operation: TOperation); override;
  88. procedure RefreshAttributes;
  89. procedure AllocateHandles;
  90. procedure LaunchKernels;
  91. protected
  92. property Attributes: TCUDAVertexAttributes read FAttributes write SetAttributes;
  93. // GXSL shader as material. If it absent or disabled - nothing be drawen.
  94. property Shader: TgxSLShader read FShader write SetShader;
  95. // Primitive type.
  96. property PrimitiveType: TFeedBackMeshPrimitive read FPrimitiveType
  97. write SetPrimitiveType default fbmpPoint;
  98. // Number of vertexes in array buffer.
  99. property VertexNumber: Integer read FVertexNumber
  100. write SetVertexNumber default 1;
  101. // Number of indexes in element buffer. Zero to disable.
  102. property ElementNumber: Integer read FElementNumber
  103. write SetElementNumber default 0;
  104. (* Used for all attributes and elements if Launching = fblCommon
  105. otherwise used own attribute function and this for elements. *)
  106. property CommonKernelFunction: TCUDAFunction read FCommonFunc
  107. write SetCommonFunc;
  108. (* Define mode of manufacturer launching:
  109. fblCommon - single launch for all,
  110. flOnePerAtttribute - one launch per attribute and elements *)
  111. property Launching: TFeedBackMeshLaunching read FLaunching
  112. write FLaunching default fblCommon;
  113. // Defines if the object uses blending for object sorting purposes.
  114. property Blend: Boolean read FBlend write FBlend default False;
  115. public
  116. constructor Create(AOwner: TComponent); override;
  117. destructor Destroy; override;
  118. procedure DoRender(var ARci: TgxRenderContextInfo;
  119. ARenderSelf, ARenderChildren: Boolean); override;
  120. property ArrayBufferHandle: TgxVBOArrayBufferHandle read FVBO;
  121. property ElementArrayHandle: TgxVBOElementArrayHandle read FEBO;
  122. end;
  123. TgxFeedBackMesh = class(TgxCustomFeedBackMesh)
  124. published
  125. property Attributes;
  126. property Shader;
  127. property PrimitiveType;
  128. property VertexNumber;
  129. property ElementNumber;
  130. property CommonKernelFunction;
  131. property Launching;
  132. property Blend;
  133. property ObjectsSorting;
  134. property VisibilityCulling;
  135. property Direction;
  136. property PitchAngle;
  137. property Position;
  138. property RollAngle;
  139. property Scale;
  140. property ShowAxes;
  141. property TurnAngle;
  142. property Up;
  143. property Visible;
  144. property Pickable;
  145. property OnProgress;
  146. property OnPicked;
  147. property Behaviours;
  148. property Effects;
  149. end;
  150. TCUDAImageResource = class(TCUDAGraphicResource)
  151. private
  152. fMaterialLibrary: TgxMaterialLibrary;
  153. fTextureName: TgxLibMaterialName;
  154. procedure SetMaterialLibrary(const Value: TgxMaterialLibrary);
  155. procedure SetTextureName(const Value: TgxLibMaterialName);
  156. protected
  157. procedure AllocateHandles; override;
  158. procedure DestroyHandles; override;
  159. procedure Notification(AComponent: TComponent; Operation: TOperation);
  160. override;
  161. public
  162. constructor Create(AOwner: TComponent); override;
  163. destructor Destroy; override;
  164. procedure MapResources; override;
  165. procedure UnMapResources; override;
  166. procedure BindArrayToTexture(var cudaArray: TCUDAMemData;
  167. ALeyer, ALevel: LOngWord); override;
  168. published
  169. property TextureName: TgxLibMaterialName read fTextureName write
  170. SetTextureName;
  171. property MaterialLibrary: TgxMaterialLibrary read fMaterialLibrary write
  172. SetMaterialLibrary;
  173. property Mapping;
  174. end;
  175. TCUDAGeometryResource = class(TCUDAGraphicResource)
  176. private
  177. FFeedBackMesh: TgxCustomFeedBackMesh;
  178. procedure SetFeedBackMesh(const Value: TgxCustomFeedBackMesh);
  179. function GetAttribArraySize(AAttr: TCUDAVertexAttribute): LongWord;
  180. protected
  181. procedure AllocateHandles; override;
  182. procedure DestroyHandles; override;
  183. procedure Notification(AComponent: TComponent;
  184. Operation: TOperation); override;
  185. function GetAttributeArraySize(const AName: string): LongWord; override;
  186. function GetAttributeArrayAddress(const AName: string): Pointer; override;
  187. function GetElementArrayDataSize: LongWord; override;
  188. function GetElementArrayAddress: Pointer; override;
  189. public
  190. constructor Create(AOwner: TComponent); override;
  191. destructor Destroy; override;
  192. procedure MapResources; override;
  193. procedure UnMapResources; override;
  194. property AttributeDataSize[const AttribName: string]: LongWord read
  195. GetAttributeArraySize;
  196. property AttributeDataAddress[const AttribName: string]: Pointer read
  197. GetAttributeArrayAddress;
  198. property IndexDataSize: LongWord read GetElementArrayDataSize;
  199. property IndexDataAddress: Pointer read GetElementArrayAddress;
  200. published
  201. property FeedBackMesh: TgxCustomFeedBackMesh read FFeedBackMesh write
  202. SetFeedBackMesh;
  203. property Mapping;
  204. end;
  205. //-----------------------------------------
  206. implementation
  207. //-----------------------------------------
  208. uses
  209. Stage.Strings,
  210. Stage.TextureFormat;
  211. // ------------------
  212. // ------------------ TCUDAImageResource ------------------
  213. // ------------------
  214. constructor TCUDAImageResource.Create(AOwner: TComponent);
  215. begin
  216. inherited Create(AOwner);
  217. fHandle[0] := nil;
  218. fResourceType := rtTexture;
  219. FGLContextHandle := TgxVirtualHandle.Create;
  220. FGLContextHandle.OnAllocate := OnGLHandleAllocate;
  221. FGLContextHandle.OnDestroy := OnGLHandleDestroy;
  222. end;
  223. destructor TCUDAImageResource.Destroy;
  224. begin
  225. FGLContextHandle.Destroy;
  226. inherited;
  227. end;
  228. procedure TCUDAImageResource.SetMaterialLibrary(const Value:
  229. TgxMaterialLibrary);
  230. begin
  231. if fMaterialLibrary <> Value then
  232. begin
  233. if Assigned(fMaterialLibrary) then
  234. fMaterialLibrary.RemoveFreeNotification(Self);
  235. fMaterialLibrary := Value;
  236. if Assigned(fMaterialLibrary) then
  237. begin
  238. fMaterialLibrary.FreeNotification(Self);
  239. if fMaterialLibrary.TextureByName(fTextureName) <> nil then
  240. DestroyHandles;
  241. end;
  242. end;
  243. end;
  244. procedure TCUDAImageResource.SetTextureName(const Value: TgxLibMaterialName);
  245. begin
  246. if fTextureName <> Value then
  247. begin
  248. fTextureName := Value;
  249. DestroyHandles;
  250. end;
  251. end;
  252. procedure TCUDAImageResource.UnMapResources;
  253. begin
  254. if FMapCounter > 0 then
  255. Dec(FMapCounter);
  256. if FMapCounter = 0 then
  257. begin
  258. if Assigned(FHandle[0]) then
  259. begin
  260. Context.Requires;
  261. FStatus := cuGraphicsUnMapResources(1, @FHandle[0], nil);
  262. Context.Release;
  263. if FStatus <> CUDA_SUCCESS then
  264. Abort;
  265. end;
  266. end;
  267. end;
  268. procedure TCUDAImageResource.AllocateHandles;
  269. const
  270. cMapping: array[TCUDAMapping] of TCUgraphicsMapResourceFlags = (
  271. CU_GRAPHICS_MAP_RESOURCE_FLAGS_NONE,
  272. CU_GRAPHICS_MAP_RESOURCE_FLAGS_READ_ONLY,
  273. CU_GRAPHICS_MAP_RESOURCE_FLAGS_WRITE_DISCARD);
  274. var
  275. LTexture: TgxTexture;
  276. glHandle: LongWord;
  277. begin
  278. FGLContextHandle.AllocateHandle;
  279. if FGLContextHandle.IsDataNeedUpdate
  280. and Assigned(FMaterialLibrary)
  281. and (Length(FTextureName) > 0) then
  282. begin
  283. inherited;
  284. LTexture := FMaterialLibrary.TextureByName(FTextureName);
  285. if Assigned(LTexture) then
  286. begin
  287. glHandle := LTexture.AllocateHandle;
  288. if glHandle = 0 then
  289. Abort;
  290. Context.Requires;
  291. DestroyHandles;
  292. FStatus := cuGraphicsGLRegisterImage(
  293. FHandle[0],
  294. glHandle,
  295. DecodeTextureTarget(LTexture.Image.NativeTextureTarget),
  296. cMapping[fMapping]);
  297. Context.Release;
  298. if FStatus <> CUDA_SUCCESS then
  299. Abort;
  300. FGLContextHandle.NotifyDataUpdated;
  301. end;
  302. end;
  303. end;
  304. procedure TCUDAImageResource.DestroyHandles;
  305. begin
  306. if Assigned(FHandle[0]) then
  307. begin
  308. inherited;
  309. Context.Requires;
  310. FStatus := cuGraphicsUnregisterResource(FHandle[0]);
  311. Context.Release;
  312. FHandle[0] := nil;
  313. FGLContextHandle.NotifyChangesOfData;
  314. end;
  315. end;
  316. procedure TCUDAImageResource.MapResources;
  317. begin
  318. AllocateHandles;
  319. if FMapCounter = 0 then
  320. begin
  321. if Assigned(FHandle[0]) then
  322. begin
  323. Context.Requires;
  324. FStatus := cuGraphicsMapResources(1, @FHandle[0], nil);
  325. Context.Release;
  326. if FStatus <> CUDA_SUCCESS then
  327. Abort;
  328. end;
  329. end;
  330. Inc(FMapCounter);
  331. end;
  332. procedure TCUDAImageResource.Notification(AComponent: TComponent; Operation:
  333. TOperation);
  334. begin
  335. inherited;
  336. if (AComponent = fMaterialLibrary) and (Operation = opRemove) then
  337. begin
  338. fMaterialLibrary := nil;
  339. fTextureName := '';
  340. DestroyHandles;
  341. end;
  342. end;
  343. procedure TCUDAImageResource.BindArrayToTexture(var cudaArray: TCUDAMemData;
  344. ALeyer, ALevel: LOngWord);
  345. var
  346. LTexture: TgxTexture;
  347. newArray: PCUarray;
  348. begin
  349. if FMapCounter = 0 then
  350. begin
  351. ShowMessage(strFailToBindArrayToTex);
  352. Abort;
  353. end;
  354. Context.Requires;
  355. FStatus := cuGraphicsSubResourceGetMappedArray(
  356. newArray, FHandle[0], ALeyer, ALevel);
  357. Context.Release;
  358. if FStatus <> CUDA_SUCCESS then
  359. Abort;
  360. LTexture := FMaterialLibrary.TextureByName(FTextureName);
  361. SetArray(cudaArray, newArray, True, LTexture.TexDepth > 0);
  362. end;
  363. // ------------------
  364. // ------------------ TCUDAGeometryResource ------------------
  365. // ------------------
  366. constructor TCUDAGeometryResource.Create(AOwner: TComponent);
  367. begin
  368. inherited Create(AOwner);
  369. FHandle[0] := nil;
  370. FHandle[1] := nil;
  371. FResourceType := rtBuffer;
  372. FMapCounter := 0;
  373. FGLContextHandle := TgxVirtualHandle.Create;
  374. FGLContextHandle.OnAllocate := OnGLHandleAllocate;
  375. FGLContextHandle.OnDestroy := OnGLHandleDestroy;
  376. end;
  377. destructor TCUDAGeometryResource.Destroy;
  378. begin
  379. FeedBackMesh := nil;
  380. FGLContextHandle.Destroy;
  381. inherited;
  382. end;
  383. procedure TCUDAGeometryResource.SetFeedBackMesh(const Value:
  384. TgxCustomFeedBackMesh);
  385. begin
  386. if FFeedBackMesh <> Value then
  387. begin
  388. if Assigned(FFeedBackMesh) then
  389. begin
  390. FFeedBackMesh.RemoveFreeNotification(Self);
  391. FFeedBackMesh.FGeometryResource := nil;
  392. end;
  393. FFeedBackMesh := Value;
  394. if Assigned(FFeedBackMesh) then
  395. begin
  396. FFeedBackMesh.FreeNotification(Self);
  397. FFeedBackMesh.FGeometryResource := Self;
  398. end;
  399. DestroyHandles;
  400. end;
  401. end;
  402. procedure TCUDAGeometryResource.AllocateHandles;
  403. const
  404. cMapping: array[TCUDAMapping] of TCUgraphicsMapResourceFlags = (
  405. CU_GRAPHICS_MAP_RESOURCE_FLAGS_NONE,
  406. CU_GRAPHICS_MAP_RESOURCE_FLAGS_READ_ONLY,
  407. CU_GRAPHICS_MAP_RESOURCE_FLAGS_WRITE_DISCARD);
  408. begin
  409. inherited;
  410. FGLContextHandle.AllocateHandle;
  411. if FGLContextHandle.IsDataNeedUpdate then
  412. begin
  413. if FFeedBackMesh.FVBO.IsDataNeedUpdate then
  414. FFeedBackMesh.AllocateHandles;
  415. Context.Requires;
  416. DestroyHandles;
  417. // Register vertex array
  418. FStatus := cuGraphicsGLRegisterBuffer(
  419. FHandle[0],
  420. FFeedBackMesh.FVBO.Handle,
  421. cMapping[FMapping]);
  422. // Register element array
  423. if FFeedBackMesh.ElementNumber > 0 then
  424. CollectStatus(
  425. cuGraphicsGLRegisterBuffer(
  426. FHandle[1],
  427. FFeedBackMesh.FEBO.Handle,
  428. cMapping[FMapping]));
  429. Context.Release;
  430. if FStatus <> CUDA_SUCCESS then
  431. Abort;
  432. FGLContextHandle.NotifyDataUpdated;
  433. end;
  434. end;
  435. procedure TCUDAGeometryResource.DestroyHandles;
  436. begin
  437. if Assigned(fHandle[0]) or Assigned(fHandle[1]) then
  438. begin
  439. inherited;
  440. Context.Requires;
  441. while FMapCounter > 0 do
  442. UnMapResources;
  443. FStatus := CUDA_SUCCESS;
  444. if Assigned(fHandle[0]) then
  445. begin
  446. CollectStatus(cuGraphicsUnregisterResource(fHandle[0]));
  447. fHandle[0] := nil;
  448. end;
  449. if Assigned(fHandle[1]) then
  450. begin
  451. CollectStatus(cuGraphicsUnregisterResource(fHandle[1]));
  452. fHandle[1] := nil;
  453. end;
  454. Context.Release;
  455. FGLContextHandle.NotifyChangesOfData;
  456. end;
  457. end;
  458. procedure TCUDAGeometryResource.Notification(AComponent: TComponent;
  459. Operation:
  460. TOperation);
  461. begin
  462. inherited;
  463. if (AComponent = FFeedBackMesh) and (Operation = opRemove) then
  464. begin
  465. FeedBackMesh := nil;
  466. DestroyHandles;
  467. end;
  468. end;
  469. procedure TCUDAGeometryResource.MapResources;
  470. var
  471. count: Integer;
  472. begin
  473. AllocateHandles;
  474. if FMapCounter = 0 then
  475. begin
  476. if Assigned(FHandle[0]) then
  477. begin
  478. count := 1;
  479. if Assigned(FHandle[1]) then
  480. Inc(count);
  481. Context.Requires;
  482. FStatus := cuGraphicsMapResources(count, @FHandle[0], nil);
  483. Context.Release;
  484. if FStatus <> CUDA_SUCCESS then
  485. Abort;
  486. end;
  487. end;
  488. Inc(FMapCounter);
  489. end;
  490. procedure TCUDAGeometryResource.UnMapResources;
  491. var
  492. count: Integer;
  493. begin
  494. if FMapCounter > 0 then
  495. Dec(FMapCounter);
  496. if FMapCounter = 0 then
  497. begin
  498. if Assigned(FHandle[0]) then
  499. begin
  500. count := 1;
  501. if Assigned(FHandle[1]) then
  502. Inc(count);
  503. Context.Requires;
  504. FStatus := cuGraphicsUnMapResources(count, @FHandle[0], nil);
  505. Context.Release;
  506. if FStatus <> CUDA_SUCCESS then
  507. Abort;
  508. end;
  509. end;
  510. end;
  511. function TCUDAGeometryResource.GetAttribArraySize(AAttr: TCUDAVertexAttribute): LongWord;
  512. var
  513. typeSize: LongWord;
  514. begin
  515. case AAttr.GLSLType of
  516. GLSLType1F: typeSize := SizeOf(Single);
  517. GLSLType2F: typeSize := 2 * SizeOf(Single);
  518. GLSLType3F: typeSize := 3 * SizeOf(Single);
  519. GLSLType4F: typeSize := 4 * SizeOf(Single);
  520. GLSLType1I: typeSize := SizeOf(Integer);
  521. GLSLType2I: typeSize := 2 * SizeOf(Integer);
  522. GLSLType3I: typeSize := 3 * SizeOf(Integer);
  523. GLSLType4I: typeSize := 4 * SizeOf(Integer);
  524. GLSLType1UI: typeSize := SizeOf(Integer);
  525. GLSLType2UI: typeSize := 2 * SizeOf(Integer);
  526. GLSLType3UI: typeSize := 3 * SizeOf(Integer);
  527. GLSLType4UI: typeSize := 4 * SizeOf(Integer);
  528. GLSLTypeMat2F: typeSize := 4 * SizeOf(Single);
  529. GLSLTypeMat3F: typeSize := 9 * SizeOf(Single);
  530. GLSLTypeMat4F: typeSize := 16 * SizeOf(Single);
  531. else
  532. begin
  533. Assert(False, strErrorEx + strUnknownType);
  534. typeSize := 0;
  535. end;
  536. end;
  537. Result := Cardinal(FFeedBackMesh.VertexNumber) * typeSize;
  538. end;
  539. function TCUDAGeometryResource.GetAttributeArraySize(
  540. const AName: string): LongWord;
  541. var
  542. LAttr: TCUDAVertexAttribute;
  543. begin
  544. Result := 0;
  545. LAttr := FFeedBackMesh.Attributes.GetAttributeByName(AName);
  546. if not Assigned(LAttr) then
  547. exit;
  548. if LAttr.GLSLType = GLSLTypeUndefined then
  549. exit;
  550. Result := GetAttribArraySize(LAttr);
  551. end;
  552. function TCUDAGeometryResource.GetAttributeArrayAddress(
  553. const AName: string): Pointer;
  554. var
  555. i: Integer;
  556. Size: Cardinal;
  557. MapPtr: Pointer;
  558. LAttr: TCUDAVertexAttribute;
  559. begin
  560. Result := nil;
  561. if FMapCounter = 0 then
  562. exit;
  563. LAttr := FFeedBackMesh.Attributes.GetAttributeByName(AName);
  564. if not Assigned(LAttr) then
  565. exit;
  566. for i := 0 to LAttr.Index - 1 do
  567. Inc(PByte(Result), GetAttribArraySize(FFeedBackMesh.Attributes[i]));
  568. Context.Requires;
  569. MapPtr := nil;
  570. FStatus := cuGraphicsResourceGetMappedPointer(
  571. MapPtr, Size, FHandle[0]);
  572. Context.Release;
  573. if FStatus <> CUDA_SUCCESS then
  574. Abort;
  575. if Cardinal(Result) + GetAttribArraySize(LAttr) > Size then
  576. begin
  577. ShowMessage(strOutOfAttribSize);
  578. Abort;
  579. end;
  580. Inc(Pbyte(Result), Cardinal(MapPtr));
  581. end;
  582. function TCUDAGeometryResource.GetElementArrayDataSize: LongWord;
  583. begin
  584. Result := FFeedBackMesh.ElementNumber * SizeOf(LongWord);
  585. end;
  586. function TCUDAGeometryResource.GetElementArrayAddress: Pointer;
  587. var
  588. Size: Cardinal;
  589. MapPtr: Pointer;
  590. begin
  591. Result := nil;
  592. if (FHandle[1] = nil) and (FMapCounter = 0) then
  593. exit;
  594. Context.Requires;
  595. MapPtr := nil;
  596. FStatus := cuGraphicsResourceGetMappedPointer(MapPtr, Size, FHandle[1]);
  597. Context.Release;
  598. if FStatus <> CUDA_SUCCESS then
  599. Abort;
  600. if GetElementArrayDataSize > Size then
  601. begin
  602. ShowMessage(strOutOfElementSize);
  603. Abort;
  604. end;
  605. Inc(Pbyte(Result), Cardinal(MapPtr));
  606. end;
  607. // -----------------------
  608. // ----------------------- TCUDAVertexAttribute -------------------
  609. // -----------------------
  610. constructor TCUDAVertexAttribute.Create(ACollection: TCollection);
  611. begin
  612. inherited;
  613. FName := GetOwner.MakeUniqueName('Attrib');
  614. FType := GLSLTypeUndefined;
  615. FLocation := -1;
  616. end;
  617. procedure TCUDAVertexAttribute.SetFunc(AFunc: TCUDAFunction);
  618. var
  619. LMesh: TgxCustomFeedBackMesh;
  620. begin
  621. LMesh := TgxCustomFeedBackMesh(GetOwner.GetOwner);
  622. if Assigned(FFunc) then
  623. FFunc.RemoveFreeNotification(LMesh);
  624. FFunc := AFunc;
  625. if Assigned(FFunc) then
  626. FFunc.FreeNotification(LMesh);
  627. end;
  628. procedure TCUDAVertexAttribute.SetName(const AName: string);
  629. begin
  630. if AName <> FName then
  631. begin
  632. FName := '';
  633. FName := GetOwner.MakeUniqueName(AName);
  634. NotifyChange(Self);
  635. end;
  636. end;
  637. procedure TCUDAVertexAttribute.SetType(AType: TgxSLDataType);
  638. begin
  639. if AType <> FType then
  640. begin
  641. FType := AType;
  642. NotifyChange(Self);
  643. end;
  644. end;
  645. function TCUDAVertexAttribute.GetLocation: Integer;
  646. begin
  647. if FLocation < 0 then
  648. FLocation := glGetAttribLocation(
  649. CurrentContext.gxStates.CurrentProgram,
  650. PGLChar(String(FName)));
  651. Result := FLocation;
  652. end;
  653. function TCUDAVertexAttribute.GetOwner: TCUDAVertexAttributes;
  654. begin
  655. Result := TCUDAVertexAttributes(Collection);
  656. end;
  657. procedure TCUDAVertexAttribute.NotifyChange(Sender: TObject);
  658. begin
  659. GetOwner.NotifyChange(Self);
  660. end;
  661. // -----------------------
  662. // ----------------------- TCUDAVertexAttributes -------------------
  663. // -----------------------
  664. function TCUDAVertexAttributes.Add: TCUDAVertexAttribute;
  665. begin
  666. Result := (inherited Add) as TCUDAVertexAttribute;
  667. end;
  668. constructor TCUDAVertexAttributes.Create(AOwner: TComponent);
  669. begin
  670. inherited Create(AOwner, TCUDAVertexAttribute);
  671. end;
  672. function TCUDAVertexAttributes.GetAttributeByName(
  673. const AName: string): TCUDAVertexAttribute;
  674. var
  675. I: Integer;
  676. A: TCUDAVertexAttribute;
  677. begin
  678. // Brute-force, there no need optimization
  679. for I := 0 to Count - 1 do
  680. begin
  681. A := TCUDAVertexAttribute(Items[i]);
  682. if A.Name = AName then
  683. Exit(A);
  684. end;
  685. Result := nil;
  686. end;
  687. function TCUDAVertexAttributes.GetItems(Index: Integer): TCUDAVertexAttribute;
  688. begin
  689. Result := TCUDAVertexAttribute(inherited Items[index]);
  690. end;
  691. function TCUDAVertexAttributes.MakeUniqueName(const ANameRoot: string): string;
  692. var
  693. I: Integer;
  694. begin
  695. Result := ANameRoot;
  696. I := 1;
  697. while GetAttributeByName(Result) <> nil do
  698. begin
  699. Result := ANameRoot + IntToStr(I);
  700. Inc(I);
  701. end;
  702. end;
  703. procedure TCUDAVertexAttributes.NotifyChange(Sender: TObject);
  704. begin
  705. TgxCustomFeedBackMesh(GetOwner).NotifyChange(Self);
  706. end;
  707. procedure TCUDAVertexAttributes.SetItems(Index: Integer;
  708. const AValue: TCUDAVertexAttribute);
  709. begin
  710. inherited Items[index] := AValue;
  711. end;
  712. // -----------------------
  713. // ----------------------- TgxCustomFeedBackMesh -------------------
  714. // -----------------------
  715. procedure TgxCustomFeedBackMesh.AllocateHandles;
  716. var
  717. I, L: Integer;
  718. Size, Offset: Cardinal;
  719. GR: TCUDAGeometryResource;
  720. EnabledLocations: array[0..VERTEX_ATTR_NUM - 1] of Boolean;
  721. begin
  722. FVAO.AllocateHandle;
  723. FVBO.AllocateHandle;
  724. FEBO.AllocateHandle;
  725. if Assigned(FGeometryResource) then
  726. begin
  727. GR := TCUDAGeometryResource(FGeometryResource);
  728. size := 0;
  729. for I := 0 to Attributes.Count - 1 do
  730. Inc(size, GR.GetAttribArraySize(Attributes[I]));
  731. FVAO.Bind;
  732. FVBO.BindBufferData(nil, size, GL_STREAM_DRAW);
  733. if FElementNumber > 0 then
  734. FEBO.BindBufferData(nil, GR.GetElementArrayDataSize, GL_STREAM_DRAW)
  735. else
  736. FEBO.UnBind; // Just in case
  737. // Predisable attributes
  738. for I := 0 to VERTEX_ATTR_NUM - 1 do
  739. EnabledLocations[I] := false;
  740. Offset := 0;
  741. for I := 0 to Attributes.Count - 1 do
  742. begin
  743. L := Attributes[I].Location;
  744. if L > -1 then
  745. begin
  746. EnabledLocations[I] := True;
  747. case Attributes[I].GLSLType of
  748. GLSLType1F:
  749. glVertexAttribPointer(L, 1, GL_FLOAT, 0, 0, pointer(Offset));
  750. GLSLType2F:
  751. glVertexAttribPointer(L, 2, GL_FLOAT, 0, 0, pointer(Offset));
  752. GLSLType3F:
  753. glVertexAttribPointer(L, 3, GL_FLOAT, 0, 0, pointer(Offset));
  754. GLSLType4F:
  755. glVertexAttribPointer(L, 4, GL_FLOAT, 0, 0, pointer(Offset));
  756. GLSLType1I:
  757. glVertexAttribIPointer(L, 1, GL_INT, 0, pointer(Offset));
  758. GLSLType2I:
  759. glVertexAttribIPointer(L, 2, GL_INT, 0, pointer(Offset));
  760. GLSLType3I:
  761. glVertexAttribIPointer(L, 3, GL_INT, 0, pointer(Offset));
  762. GLSLType4I:
  763. glVertexAttribIPointer(L, 4, GL_INT, 0, pointer(Offset));
  764. GLSLType1UI:
  765. glVertexAttribIPointer(L, 1, GL_UNSIGNED_INT, 0, pointer(Offset));
  766. GLSLType2UI:
  767. glVertexAttribIPointer(L, 2, GL_UNSIGNED_INT, 0, pointer(Offset));
  768. GLSLType3UI:
  769. glVertexAttribIPointer(L, 3, GL_UNSIGNED_INT, 0, pointer(Offset));
  770. GLSLType4UI:
  771. glVertexAttribIPointer(L, 4, GL_UNSIGNED_INT, 0, pointer(Offset));
  772. GLSLTypeMat2F:
  773. glVertexAttribPointer(L, 4, GL_FLOAT, 0, 0, pointer(Offset));
  774. GLSLTypeMat3F:
  775. glVertexAttribPointer(L, 9, GL_FLOAT, 0, 0, pointer(Offset));
  776. GLSLTypeMat4F:
  777. glVertexAttribPointer(L, 16, GL_FLOAT, 0, 0, pointer(Offset));
  778. end; // of case
  779. end;
  780. Inc(Offset, GR.GetAttribArraySize(Attributes[I]));
  781. end;
  782. // Enable engagement attributes array
  783. begin
  784. for I := VERTEX_ATTR_NUM - 1 downto 0 do
  785. if EnabledLocations[I] then
  786. glEnableVertexAttribArray(I)
  787. else
  788. glDisableVertexAttribArray(I);
  789. end;
  790. FVAO.UnBind;
  791. FVAO.NotifyDataUpdated;
  792. end;
  793. end;
  794. constructor TgxCustomFeedBackMesh.Create(AOwner: TComponent);
  795. begin
  796. inherited;
  797. ObjectStyle := ObjectStyle + [osDirectDraw];
  798. FAttributes := TCUDAVertexAttributes.Create(Self);
  799. FVAO := TgxVertexArrayHandle.Create;
  800. FVBO := TgxVBOArrayBufferHandle.Create;
  801. FEBO := TgxVBOElementArrayHandle.Create;
  802. FPrimitiveType := fbmpPoint;
  803. FLaunching := fblCommon;
  804. FVertexNumber := 1;
  805. FElementNumber := 0;
  806. FBlend := False;
  807. end;
  808. destructor TgxCustomFeedBackMesh.Destroy;
  809. begin
  810. Shader := nil;
  811. FAttributes.Destroy;
  812. FVAO.Destroy;
  813. FVBO.Destroy;
  814. FEBO.Destroy;
  815. inherited;
  816. end;
  817. procedure TgxCustomFeedBackMesh.LaunchKernels;
  818. var
  819. i: Integer;
  820. GR: TCUDAGeometryResource;
  821. // IR: TCUDAGLImageResource;
  822. begin
  823. if Assigned(FGeometryResource) then
  824. begin
  825. // Produce geometry resource
  826. GR := TCUDAGeometryResource(FGeometryResource);
  827. GR.MapResources;
  828. // Produce vertex attributes
  829. case Launching of
  830. fblCommon:
  831. begin
  832. for I := 0 to FAttributes.Count - 1 do
  833. with FAttributes.Attributes[I] do
  834. if Assigned(OnBeforeKernelLaunch) then
  835. OnBeforeKernelLaunch(FAttributes.Attributes[I]);
  836. if Assigned(FCommonFunc) then
  837. FCommonFunc.Launch;
  838. end;
  839. fblOnePerAtttribute:
  840. begin
  841. for I := 0 to FAttributes.Count - 1 do
  842. with FAttributes.Attributes[I] do
  843. begin
  844. if Assigned(OnBeforeKernelLaunch) then
  845. OnBeforeKernelLaunch(FAttributes.Attributes[I]);
  846. if Assigned(KernelFunction) then
  847. KernelFunction.Launch;
  848. end;
  849. end;
  850. else
  851. Assert(False, strErrorEx + strUnknownType);
  852. end;
  853. // Produce indexes
  854. if (GR.GetElementArrayDataSize > 0)
  855. and Assigned(FCommonFunc) then
  856. FCommonFunc.Launch;
  857. GR.UnMapResources;
  858. end;
  859. end;
  860. // // Produce image resource
  861. // else if FGLResource is TCUDAGLImageResource then
  862. // begin
  863. // IR := TCUDAGLImageResource(FGLResource);
  864. // IR.MapResources;
  865. // if Assigned(FBeforeLaunch) then
  866. // FBeforeLaunch(Self, 0);
  867. // if Assigned(FManufacturer) then
  868. // FManufacturer.Launch;
  869. // IR.UnMapResources;
  870. // end;
  871. procedure TgxCustomFeedBackMesh.DoRender(var ARci: TgxRenderContextInfo; ARenderSelf,
  872. ARenderChildren: Boolean);
  873. const
  874. cPrimitives: array[TFeedBackMeshPrimitive] of GLEnum =
  875. (GL_POINTS, GL_LINES, GL_TRIANGLES);
  876. begin
  877. if ARenderSelf
  878. and not (csDesigning in ComponentState)
  879. and Assigned(FShader)
  880. and Assigned(FGeometryResource) then
  881. try
  882. FShader.Apply(ARci, Self);
  883. if FVAO.IsDataNeedUpdate then
  884. AllocateHandles;
  885. // Produce mesh data
  886. LaunchKernels;
  887. // Draw mesh
  888. FVAO.Bind;
  889. // Multipass Shader Loop
  890. repeat
  891. // Render mesh
  892. if FElementNumber > 0 then
  893. begin
  894. glDrawElements(
  895. cPrimitives[FPrimitiveType],
  896. FElementNumber,
  897. GL_UNSIGNED_INT,
  898. nil);
  899. end
  900. else
  901. begin
  902. glDrawArrays(
  903. cPrimitives[FPrimitiveType],
  904. 0,
  905. FVertexNumber);
  906. end;
  907. until not FShader.UnApply(ARci);
  908. FVAO.UnBind;
  909. except
  910. Visible := False;
  911. end;
  912. if ARenderChildren then
  913. Self.RenderChildren(0, Count - 1, ARci);
  914. end;
  915. procedure TgxCustomFeedBackMesh.Notification(AComponent: TComponent;
  916. Operation: TOperation);
  917. var
  918. I: Integer;
  919. begin
  920. if Operation = opRemove then
  921. begin
  922. if AComponent = Shader then
  923. Shader := nil
  924. else if AComponent = FCommonFunc then
  925. CommonKernelFunction := nil
  926. else if AComponent is TCUDAFunction then
  927. begin
  928. for I := 0 to FAttributes.Count - 1 do
  929. if FAttributes[I].KernelFunction = AComponent then
  930. FAttributes[I].KernelFunction := nil;
  931. end;
  932. end;
  933. inherited;
  934. end;
  935. procedure TgxCustomFeedBackMesh.RefreshAttributes;
  936. var
  937. I: Integer;
  938. AttribInfo: TgxActiveAttribArray;
  939. begin
  940. if Assigned(FShader) and FShader.Enabled then
  941. begin
  942. FShader.FailedInitAction := fiaSilentDisable;
  943. Scene.CurrentBuffer.RenderingContext.Activate;
  944. try
  945. AttribInfo := FShader.GetActiveAttribs;
  946. except
  947. FShader.Enabled := False;
  948. Scene.CurrentBuffer.RenderingContext.Deactivate;
  949. exit;
  950. end;
  951. Scene.CurrentBuffer.RenderingContext.Deactivate;
  952. FAttributes.Clear;
  953. for I := 0 to High(AttribInfo) do
  954. begin
  955. with FAttributes.Add do
  956. begin
  957. Name := AttribInfo[I].Name;
  958. GLSLType := AttribInfo[I].AType;
  959. FLocation := AttribInfo[I].Location;
  960. end;
  961. end;
  962. FVAO.NotifyChangesOfData;
  963. end;
  964. end;
  965. procedure TgxCustomFeedBackMesh.SetAttributes(AValue: TCUDAVertexAttributes);
  966. begin
  967. FAttributes.Assign(AValue);
  968. end;
  969. procedure TgxCustomFeedBackMesh.SetCommonFunc(AFunc: TCUDAFunction);
  970. begin
  971. if AFunc <> FCommonFunc then
  972. begin
  973. if Assigned(FCommonFunc) then
  974. FCommonFunc.RemoveFreeNotification(Self);
  975. FCommonFunc := AFunc;
  976. if Assigned(FCommonFunc) then
  977. FCommonFunc.FreeNotification(Self);
  978. end;
  979. end;
  980. procedure TgxCustomFeedBackMesh.SetElementNumber(AValue: Integer);
  981. begin
  982. if AValue < 0 then
  983. AValue := 0;
  984. FElementNumber := AValue;
  985. FVAO.NotifyChangesOfData;
  986. end;
  987. procedure TgxCustomFeedBackMesh.SetPrimitiveType(AValue: TFeedBackMeshPrimitive);
  988. begin
  989. FPrimitiveType := AValue;
  990. end;
  991. procedure TgxCustomFeedBackMesh.SetShader(AShader: TgxslShader);
  992. begin
  993. if AShader <> FShader then
  994. begin
  995. if Assigned(FShader) then
  996. FShader.RemoveFreeNotification(Self);
  997. FShader := AShader;
  998. if Assigned(FShader) then
  999. FShader.FreeNotification(Self);
  1000. if not (csLoading in ComponentState) then
  1001. RefreshAttributes;
  1002. end;
  1003. end;
  1004. procedure TgxCustomFeedBackMesh.SetVertexNumber(AValue: Integer);
  1005. begin
  1006. if AValue < 1 then
  1007. AValue := 1;
  1008. FVertexNumber := AValue;
  1009. FVAO.NotifyChangesOfData;
  1010. end;
  1011. //----------------------------------
  1012. initialization
  1013. //----------------------------------
  1014. RegisterClasses([TCUDAImageResource, TCUDAGeometryResource,
  1015. TgxCustomFeedBackMesh, TgxFeedBackMesh]);
  1016. end.