device.go 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200
  1. //go:build !js
  2. package wgpu
  3. /*
  4. #include <stdlib.h>
  5. #include "./lib/wgpu.h"
  6. extern void gowebgpu_error_callback_c(WGPUErrorType type, char const * message, void * userdata);
  7. static inline WGPUBindGroup gowebgpu_device_create_bind_group(WGPUDevice device, WGPUBindGroupDescriptor const * descriptor, void * error_userdata) {
  8. WGPUBindGroup ref = NULL;
  9. wgpuDevicePushErrorScope(device, WGPUErrorFilter_Validation);
  10. ref = wgpuDeviceCreateBindGroup(device, descriptor);
  11. wgpuDevicePopErrorScope(device, gowebgpu_error_callback_c, error_userdata);
  12. return ref;
  13. }
  14. static inline WGPUBindGroupLayout gowebgpu_device_create_bind_group_layout(WGPUDevice device, WGPUBindGroupLayoutDescriptor const * descriptor, void * error_userdata) {
  15. WGPUBindGroupLayout ref = NULL;
  16. wgpuDevicePushErrorScope(device, WGPUErrorFilter_Validation);
  17. ref = wgpuDeviceCreateBindGroupLayout(device, descriptor);
  18. wgpuDevicePopErrorScope(device, gowebgpu_error_callback_c, error_userdata);
  19. return ref;
  20. }
  21. static inline WGPUBuffer gowebgpu_device_create_buffer(WGPUDevice device, WGPUBufferDescriptor const * descriptor, void * error_userdata) {
  22. WGPUBuffer ref = NULL;
  23. wgpuDevicePushErrorScope(device, WGPUErrorFilter_Validation);
  24. ref = wgpuDeviceCreateBuffer(device, descriptor);
  25. wgpuDevicePopErrorScope(device, gowebgpu_error_callback_c, error_userdata);
  26. return ref;
  27. }
  28. static inline WGPUCommandEncoder gowebgpu_device_create_command_encoder(WGPUDevice device, WGPUCommandEncoderDescriptor const * descriptor, void * error_userdata) {
  29. WGPUCommandEncoder ref = NULL;
  30. wgpuDevicePushErrorScope(device, WGPUErrorFilter_Validation);
  31. ref = wgpuDeviceCreateCommandEncoder(device, descriptor);
  32. wgpuDevicePopErrorScope(device, gowebgpu_error_callback_c, error_userdata);
  33. return ref;
  34. }
  35. static inline WGPUComputePipeline gowebgpu_device_create_compute_pipeline(WGPUDevice device, WGPUComputePipelineDescriptor const * descriptor, void * error_userdata) {
  36. WGPUComputePipeline ref = NULL;
  37. wgpuDevicePushErrorScope(device, WGPUErrorFilter_Validation);
  38. ref = wgpuDeviceCreateComputePipeline(device, descriptor);
  39. wgpuDevicePopErrorScope(device, gowebgpu_error_callback_c, error_userdata);
  40. return ref;
  41. }
  42. static inline WGPUPipelineLayout gowebgpu_device_create_pipeline_layout(WGPUDevice device, WGPUPipelineLayoutDescriptor const * descriptor, void * error_userdata) {
  43. WGPUPipelineLayout ref = NULL;
  44. wgpuDevicePushErrorScope(device, WGPUErrorFilter_Validation);
  45. ref = wgpuDeviceCreatePipelineLayout(device, descriptor);
  46. wgpuDevicePopErrorScope(device, gowebgpu_error_callback_c, error_userdata);
  47. return ref;
  48. }
  49. static inline WGPUQuerySet gowebgpu_device_create_query_set(WGPUDevice device, WGPUQuerySetDescriptor const * descriptor, void * error_userdata) {
  50. WGPUQuerySet ref = NULL;
  51. wgpuDevicePushErrorScope(device, WGPUErrorFilter_Validation);
  52. ref = wgpuDeviceCreateQuerySet(device, descriptor);
  53. wgpuDevicePopErrorScope(device, gowebgpu_error_callback_c, error_userdata);
  54. return ref;
  55. }
  56. static inline WGPURenderPipeline gowebgpu_device_create_render_pipeline(WGPUDevice device, WGPURenderPipelineDescriptor const * descriptor, void * error_userdata) {
  57. WGPURenderPipeline ref = NULL;
  58. wgpuDevicePushErrorScope(device, WGPUErrorFilter_Validation);
  59. ref = wgpuDeviceCreateRenderPipeline(device, descriptor);
  60. wgpuDevicePopErrorScope(device, gowebgpu_error_callback_c, error_userdata);
  61. return ref;
  62. }
  63. static inline WGPUSampler gowebgpu_device_create_sampler(WGPUDevice device, WGPUSamplerDescriptor const * descriptor, void * error_userdata) {
  64. WGPUSampler ref = NULL;
  65. wgpuDevicePushErrorScope(device, WGPUErrorFilter_Validation);
  66. ref = wgpuDeviceCreateSampler(device, descriptor);
  67. wgpuDevicePopErrorScope(device, gowebgpu_error_callback_c, error_userdata);
  68. return ref;
  69. }
  70. static inline WGPUShaderModule gowebgpu_device_create_shader_module(WGPUDevice device, WGPUShaderModuleDescriptor const * descriptor, void * error_userdata) {
  71. WGPUShaderModule ref = NULL;
  72. wgpuDevicePushErrorScope(device, WGPUErrorFilter_Validation);
  73. ref = wgpuDeviceCreateShaderModule(device, descriptor);
  74. wgpuDevicePopErrorScope(device, gowebgpu_error_callback_c, error_userdata);
  75. return ref;
  76. }
  77. static inline WGPUTexture gowebgpu_device_create_texture(WGPUDevice device, WGPUTextureDescriptor const * descriptor, void * error_userdata) {
  78. WGPUTexture ref = NULL;
  79. wgpuDevicePushErrorScope(device, WGPUErrorFilter_Validation);
  80. ref = wgpuDeviceCreateTexture(device, descriptor);
  81. wgpuDevicePopErrorScope(device, gowebgpu_error_callback_c, error_userdata);
  82. return ref;
  83. }
  84. */
  85. import "C"
  86. import (
  87. "errors"
  88. "runtime/cgo"
  89. "unsafe"
  90. )
  91. type Device struct {
  92. ref C.WGPUDevice
  93. }
  94. type errorCallback func(typ ErrorType, message string)
  95. //export gowebgpu_error_callback_go
  96. func gowebgpu_error_callback_go(_type C.WGPUErrorType, message *C.char, userdata unsafe.Pointer) {
  97. handle := *(*cgo.Handle)(userdata)
  98. cb, ok := handle.Value().(errorCallback)
  99. if ok {
  100. cb(ErrorType(_type), C.GoString(message))
  101. }
  102. }
  103. func (p *Device) Release() { C.wgpuDeviceRelease(p.ref) }
  104. func (p *Device) CreateBindGroup(descriptor *BindGroupDescriptor) (*BindGroup, error) {
  105. var desc C.WGPUBindGroupDescriptor
  106. if descriptor != nil {
  107. if descriptor.Label != "" {
  108. label := C.CString(descriptor.Label)
  109. defer C.free(unsafe.Pointer(label))
  110. desc.label = label
  111. }
  112. if descriptor.Layout != nil {
  113. desc.layout = descriptor.Layout.ref
  114. }
  115. entryCount := len(descriptor.Entries)
  116. if entryCount > 0 {
  117. entries := C.malloc(C.size_t(entryCount) * C.size_t(unsafe.Sizeof(C.WGPUBindGroupEntry{})))
  118. defer C.free(entries)
  119. entriesSlice := unsafe.Slice((*C.WGPUBindGroupEntry)(entries), entryCount)
  120. for i, v := range descriptor.Entries {
  121. entry := C.WGPUBindGroupEntry{
  122. binding: C.uint32_t(v.Binding),
  123. offset: C.uint64_t(v.Offset),
  124. size: C.uint64_t(v.Size),
  125. }
  126. if v.Buffer != nil {
  127. entry.buffer = v.Buffer.ref
  128. }
  129. if v.Sampler != nil {
  130. entry.sampler = v.Sampler.ref
  131. }
  132. if v.TextureView != nil {
  133. entry.textureView = v.TextureView.ref
  134. }
  135. entriesSlice[i] = entry
  136. }
  137. desc.entryCount = C.size_t(entryCount)
  138. desc.entries = (*C.WGPUBindGroupEntry)(entries)
  139. }
  140. }
  141. var err error = nil
  142. var cb errorCallback = func(_ ErrorType, message string) {
  143. err = errors.New("wgpu.(*Device).CreateBindGroup(): " + message)
  144. }
  145. errorCallbackHandle := cgo.NewHandle(cb)
  146. defer errorCallbackHandle.Delete()
  147. ref := C.gowebgpu_device_create_bind_group(
  148. p.ref,
  149. &desc,
  150. unsafe.Pointer(&errorCallbackHandle),
  151. )
  152. if err != nil {
  153. C.wgpuBindGroupRelease(ref)
  154. return nil, err
  155. }
  156. return &BindGroup{ref}, nil
  157. }
  158. type BufferBindingLayout struct {
  159. Type BufferBindingType
  160. HasDynamicOffset bool
  161. MinBindingSize uint64
  162. }
  163. type SamplerBindingLayout struct {
  164. Type SamplerBindingType
  165. }
  166. type TextureBindingLayout struct {
  167. SampleType TextureSampleType
  168. ViewDimension TextureViewDimension
  169. Multisampled bool
  170. }
  171. type StorageTextureBindingLayout struct {
  172. Access StorageTextureAccess
  173. Format TextureFormat
  174. ViewDimension TextureViewDimension
  175. }
  176. type BindGroupLayoutEntry struct {
  177. Binding uint32
  178. Visibility ShaderStage
  179. Buffer BufferBindingLayout
  180. Sampler SamplerBindingLayout
  181. Texture TextureBindingLayout
  182. StorageTexture StorageTextureBindingLayout
  183. }
  184. func (p *Device) CreateBindGroupLayout(descriptor *BindGroupLayoutDescriptor) (*BindGroupLayout, error) {
  185. var desc C.WGPUBindGroupLayoutDescriptor
  186. if descriptor != nil {
  187. if descriptor.Label != "" {
  188. label := C.CString(descriptor.Label)
  189. defer C.free(unsafe.Pointer(label))
  190. desc.label = label
  191. }
  192. entryCount := len(descriptor.Entries)
  193. if entryCount > 0 {
  194. entries := C.malloc(C.size_t(entryCount) * C.size_t(unsafe.Sizeof(C.WGPUBindGroupLayoutEntry{})))
  195. defer C.free(entries)
  196. entriesSlice := unsafe.Slice((*C.WGPUBindGroupLayoutEntry)(entries), entryCount)
  197. for i, v := range descriptor.Entries {
  198. entriesSlice[i] = C.WGPUBindGroupLayoutEntry{
  199. nextInChain: nil,
  200. binding: C.uint32_t(v.Binding),
  201. visibility: C.WGPUShaderStageFlags(v.Visibility),
  202. buffer: C.WGPUBufferBindingLayout{
  203. nextInChain: nil,
  204. _type: C.WGPUBufferBindingType(v.Buffer.Type),
  205. hasDynamicOffset: cBool(v.Buffer.HasDynamicOffset),
  206. minBindingSize: C.uint64_t(v.Buffer.MinBindingSize),
  207. },
  208. sampler: C.WGPUSamplerBindingLayout{
  209. nextInChain: nil,
  210. _type: C.WGPUSamplerBindingType(v.Sampler.Type),
  211. },
  212. texture: C.WGPUTextureBindingLayout{
  213. nextInChain: nil,
  214. sampleType: C.WGPUTextureSampleType(v.Texture.SampleType),
  215. viewDimension: C.WGPUTextureViewDimension(v.Texture.ViewDimension),
  216. multisampled: cBool(v.Texture.Multisampled),
  217. },
  218. storageTexture: C.WGPUStorageTextureBindingLayout{
  219. nextInChain: nil,
  220. access: C.WGPUStorageTextureAccess(v.StorageTexture.Access),
  221. format: C.WGPUTextureFormat(v.StorageTexture.Format),
  222. viewDimension: C.WGPUTextureViewDimension(v.StorageTexture.ViewDimension),
  223. },
  224. }
  225. }
  226. desc.entryCount = C.size_t(entryCount)
  227. desc.entries = (*C.WGPUBindGroupLayoutEntry)(entries)
  228. }
  229. }
  230. var err error = nil
  231. var cb errorCallback = func(_ ErrorType, message string) {
  232. err = errors.New("wgpu.(*Device).CreateBindGroupLayout(): " + message)
  233. }
  234. errorCallbackHandle := cgo.NewHandle(cb)
  235. defer errorCallbackHandle.Delete()
  236. ref := C.gowebgpu_device_create_bind_group_layout(
  237. p.ref,
  238. &desc,
  239. unsafe.Pointer(&errorCallbackHandle),
  240. )
  241. if err != nil {
  242. C.wgpuBindGroupLayoutRelease(ref)
  243. return nil, err
  244. }
  245. return &BindGroupLayout{ref}, nil
  246. }
  247. func (p *Device) CreateBuffer(descriptor *BufferDescriptor) (*Buffer, error) {
  248. var desc C.WGPUBufferDescriptor
  249. if descriptor != nil {
  250. if descriptor.Label != "" {
  251. label := C.CString(descriptor.Label)
  252. defer C.free(unsafe.Pointer(label))
  253. desc.label = label
  254. }
  255. desc.usage = C.WGPUBufferUsageFlags(descriptor.Usage)
  256. desc.size = C.uint64_t(descriptor.Size)
  257. desc.mappedAtCreation = cBool(descriptor.MappedAtCreation)
  258. }
  259. var err error = nil
  260. var cb errorCallback = func(_ ErrorType, message string) {
  261. err = errors.New("wgpu.(*Device).CreateBuffer(): " + message)
  262. }
  263. errorCallbackHandle := cgo.NewHandle(cb)
  264. defer errorCallbackHandle.Delete()
  265. ref := C.gowebgpu_device_create_buffer(
  266. p.ref,
  267. &desc,
  268. unsafe.Pointer(&errorCallbackHandle),
  269. )
  270. if err != nil {
  271. C.wgpuBufferRelease(ref)
  272. return nil, err
  273. }
  274. C.wgpuDeviceReference(p.ref)
  275. return &Buffer{deviceRef: p.ref, ref: ref}, nil
  276. }
  277. func (p *Device) CreateCommandEncoder(descriptor *CommandEncoderDescriptor) (*CommandEncoder, error) {
  278. var desc *C.WGPUCommandEncoderDescriptor
  279. if descriptor != nil && descriptor.Label != "" {
  280. label := C.CString(descriptor.Label)
  281. defer C.free(unsafe.Pointer(label))
  282. desc = &C.WGPUCommandEncoderDescriptor{
  283. label: label,
  284. }
  285. }
  286. var err error = nil
  287. var cb errorCallback = func(_ ErrorType, message string) {
  288. err = errors.New("wgpu.(*Device).CreateCommandEncoder(): " + message)
  289. }
  290. errorCallbackHandle := cgo.NewHandle(cb)
  291. defer errorCallbackHandle.Delete()
  292. ref := C.gowebgpu_device_create_command_encoder(
  293. p.ref,
  294. desc,
  295. unsafe.Pointer(&errorCallbackHandle),
  296. )
  297. if err != nil {
  298. C.wgpuCommandEncoderRelease(ref)
  299. return nil, err
  300. }
  301. C.wgpuDeviceReference(p.ref)
  302. return &CommandEncoder{deviceRef: p.ref, ref: ref}, nil
  303. }
  304. type ConstantEntry struct {
  305. Key string
  306. Value float64
  307. }
  308. type ComputePipelineDescriptor struct {
  309. Label string
  310. Layout *PipelineLayout
  311. Compute ProgrammableStageDescriptor
  312. }
  313. func (p *Device) CreateComputePipeline(descriptor *ComputePipelineDescriptor) (*ComputePipeline, error) {
  314. var desc C.WGPUComputePipelineDescriptor
  315. if descriptor != nil {
  316. if descriptor.Label != "" {
  317. label := C.CString(descriptor.Label)
  318. defer C.free(unsafe.Pointer(label))
  319. desc.label = label
  320. }
  321. if descriptor.Layout != nil {
  322. desc.layout = descriptor.Layout.ref
  323. }
  324. var compute C.WGPUProgrammableStageDescriptor
  325. if descriptor.Compute.Module != nil {
  326. compute.module = descriptor.Compute.Module.ref
  327. }
  328. if descriptor.Compute.EntryPoint != "" {
  329. entryPoint := C.CString(descriptor.Compute.EntryPoint)
  330. defer C.free(unsafe.Pointer(entryPoint))
  331. compute.entryPoint = entryPoint
  332. }
  333. desc.compute = compute
  334. }
  335. var err error = nil
  336. var cb errorCallback = func(_ ErrorType, message string) {
  337. err = errors.New("wgpu.(*Device).CreateComputePipeline(): " + message)
  338. }
  339. errorCallbackHandle := cgo.NewHandle(cb)
  340. defer errorCallbackHandle.Delete()
  341. ref := C.gowebgpu_device_create_compute_pipeline(
  342. p.ref,
  343. &desc,
  344. unsafe.Pointer(&errorCallbackHandle),
  345. )
  346. if err != nil {
  347. C.wgpuComputePipelineRelease(ref)
  348. return nil, err
  349. }
  350. return &ComputePipeline{ref}, nil
  351. }
  352. type PushConstantRange struct {
  353. Stages ShaderStage
  354. Start uint32
  355. End uint32
  356. }
  357. type PipelineLayoutDescriptor struct {
  358. Label string
  359. BindGroupLayouts []*BindGroupLayout
  360. PushConstantRanges []PushConstantRange
  361. }
  362. func (p *Device) CreatePipelineLayout(descriptor *PipelineLayoutDescriptor) (*PipelineLayout, error) {
  363. var desc C.WGPUPipelineLayoutDescriptor
  364. if descriptor != nil {
  365. if descriptor.Label != "" {
  366. label := C.CString(descriptor.Label)
  367. defer C.free(unsafe.Pointer(label))
  368. desc.label = label
  369. }
  370. bindGroupLayoutCount := len(descriptor.BindGroupLayouts)
  371. if bindGroupLayoutCount > 0 {
  372. bindGroupLayouts := C.malloc(C.size_t(bindGroupLayoutCount) * C.size_t(unsafe.Sizeof(C.WGPUBindGroupLayout(nil))))
  373. defer C.free(bindGroupLayouts)
  374. bindGroupLayoutsSlice := unsafe.Slice((*C.WGPUBindGroupLayout)(bindGroupLayouts), bindGroupLayoutCount)
  375. for i, v := range descriptor.BindGroupLayouts {
  376. bindGroupLayoutsSlice[i] = v.ref
  377. }
  378. desc.bindGroupLayoutCount = C.size_t(bindGroupLayoutCount)
  379. desc.bindGroupLayouts = (*C.WGPUBindGroupLayout)(bindGroupLayouts)
  380. }
  381. if len(descriptor.PushConstantRanges) > 0 {
  382. pipelineLayoutExtras := (*C.WGPUPipelineLayoutExtras)(C.malloc(C.size_t(unsafe.Sizeof(C.WGPUPipelineLayoutExtras{}))))
  383. defer C.free(unsafe.Pointer(pipelineLayoutExtras))
  384. pipelineLayoutExtras.chain.next = nil
  385. pipelineLayoutExtras.chain.sType = C.WGPUSType_PipelineLayoutExtras
  386. pushConstantRangeCount := len(descriptor.PushConstantRanges)
  387. pushConstantRanges := C.malloc(C.size_t(pushConstantRangeCount) * C.size_t(unsafe.Sizeof(C.WGPUPushConstantRange{})))
  388. defer C.free(pushConstantRanges)
  389. pushConstantRangesSlice := unsafe.Slice((*C.WGPUPushConstantRange)(pushConstantRanges), pushConstantRangeCount)
  390. for i, v := range descriptor.PushConstantRanges {
  391. pushConstantRangesSlice[i] = C.WGPUPushConstantRange{
  392. stages: C.WGPUShaderStageFlags(v.Stages),
  393. start: C.uint32_t(v.Start),
  394. end: C.uint32_t(v.End),
  395. }
  396. }
  397. pipelineLayoutExtras.pushConstantRangeCount = C.size_t(pushConstantRangeCount)
  398. pipelineLayoutExtras.pushConstantRanges = (*C.WGPUPushConstantRange)(pushConstantRanges)
  399. desc.nextInChain = (*C.WGPUChainedStruct)(unsafe.Pointer(pipelineLayoutExtras))
  400. } else {
  401. desc.nextInChain = nil
  402. }
  403. }
  404. var err error = nil
  405. var cb errorCallback = func(_ ErrorType, message string) {
  406. err = errors.New("wgpu.(*Device).CreatePipelineLayout(): " + message)
  407. }
  408. errorCallbackHandle := cgo.NewHandle(cb)
  409. defer errorCallbackHandle.Delete()
  410. ref := C.gowebgpu_device_create_pipeline_layout(
  411. p.ref,
  412. &desc,
  413. unsafe.Pointer(&errorCallbackHandle),
  414. )
  415. if err != nil {
  416. C.wgpuPipelineLayoutRelease(ref)
  417. return nil, err
  418. }
  419. return &PipelineLayout{ref}, nil
  420. }
  421. type QuerySetDescriptor struct {
  422. Label string
  423. Type QueryType
  424. Count uint32
  425. PipelineStatistics []PipelineStatisticName
  426. }
  427. func (p *Device) CreateQuerySet(descriptor *QuerySetDescriptor) (*QuerySet, error) {
  428. var desc C.WGPUQuerySetDescriptor
  429. if descriptor != nil {
  430. if descriptor.Label != "" {
  431. label := C.CString(descriptor.Label)
  432. defer C.free(unsafe.Pointer(label))
  433. desc.label = label
  434. }
  435. desc._type = C.WGPUQueryType(descriptor.Type)
  436. desc.count = C.uint32_t(descriptor.Count)
  437. // TODO: no longer present in C API
  438. // pipelineStatisticCount := len(descriptor.PipelineStatistics)
  439. // if pipelineStatisticCount > 0 {
  440. // pipelineStatistics := C.malloc(C.size_t(pipelineStatisticCount) * C.size_t(unsafe.Sizeof(C.WGPUPipelineStatisticName(0))))
  441. // defer C.free(pipelineStatistics)
  442. // pipelineStatisticsSlice := unsafe.Slice((*PipelineStatisticName)(pipelineStatistics), pipelineStatisticCount)
  443. // copy(pipelineStatisticsSlice, descriptor.PipelineStatistics)
  444. // desc.pipelineStatisticCount = C.size_t(pipelineStatisticCount)
  445. // desc.pipelineStatistics = (*C.WGPUPipelineStatisticName)(pipelineStatistics)
  446. // }
  447. }
  448. var err error = nil
  449. var cb errorCallback = func(_ ErrorType, message string) {
  450. err = errors.New("wgpu.(*Device).CreateQuerySet(): " + message)
  451. }
  452. errorCallbackHandle := cgo.NewHandle(cb)
  453. defer errorCallbackHandle.Delete()
  454. ref := C.gowebgpu_device_create_query_set(
  455. p.ref,
  456. &desc,
  457. unsafe.Pointer(&errorCallbackHandle),
  458. )
  459. if err != nil {
  460. C.wgpuQuerySetRelease(ref)
  461. return nil, err
  462. }
  463. return &QuerySet{ref: ref}, nil
  464. }
  465. type RenderBundleEncoderDescriptor struct {
  466. Label string
  467. ColorFormats []TextureFormat
  468. DepthStencilFormat TextureFormat
  469. SampleCount uint32
  470. DepthReadOnly bool
  471. StencilReadOnly bool
  472. }
  473. func (p *Device) CreateRenderBundleEncoder(descriptor *RenderBundleEncoderDescriptor) (*RenderBundleEncoder, error) {
  474. var desc C.WGPURenderBundleEncoderDescriptor
  475. if descriptor != nil {
  476. if descriptor.Label != "" {
  477. label := C.CString(descriptor.Label)
  478. defer C.free(unsafe.Pointer(label))
  479. desc.label = label
  480. }
  481. colorFormatCount := len(descriptor.ColorFormats)
  482. if colorFormatCount > 0 {
  483. colorFormats := C.malloc(C.size_t(colorFormatCount) * C.size_t(unsafe.Sizeof(C.WGPUTextureFormat(0))))
  484. defer C.free(colorFormats)
  485. colorFormatsSlice := unsafe.Slice((*TextureFormat)(colorFormats), colorFormatCount)
  486. copy(colorFormatsSlice, descriptor.ColorFormats)
  487. desc.colorFormatCount = C.size_t(colorFormatCount)
  488. desc.colorFormats = (*C.WGPUTextureFormat)(colorFormats)
  489. }
  490. desc.depthStencilFormat = C.WGPUTextureFormat(descriptor.DepthStencilFormat)
  491. desc.sampleCount = C.uint32_t(descriptor.SampleCount)
  492. desc.depthReadOnly = cBool(descriptor.DepthReadOnly)
  493. desc.stencilReadOnly = cBool(descriptor.StencilReadOnly)
  494. }
  495. ref := C.wgpuDeviceCreateRenderBundleEncoder(p.ref, &desc)
  496. return &RenderBundleEncoder{ref}, nil
  497. }
  498. type BlendComponent struct {
  499. Operation BlendOperation
  500. SrcFactor BlendFactor
  501. DstFactor BlendFactor
  502. }
  503. type BlendState struct {
  504. Color BlendComponent
  505. Alpha BlendComponent
  506. }
  507. type ColorTargetState struct {
  508. Format TextureFormat
  509. Blend *BlendState
  510. WriteMask ColorWriteMask
  511. }
  512. type FragmentState struct {
  513. Module *ShaderModule
  514. EntryPoint string
  515. Targets []ColorTargetState
  516. // unused in wgpu
  517. // Constants []ConstantEntry
  518. }
  519. type VertexAttribute struct {
  520. Format VertexFormat
  521. Offset uint64
  522. ShaderLocation uint32
  523. }
  524. type VertexBufferLayout struct {
  525. ArrayStride uint64
  526. StepMode VertexStepMode
  527. Attributes []VertexAttribute
  528. }
  529. type VertexState struct {
  530. Module *ShaderModule
  531. EntryPoint string
  532. Buffers []VertexBufferLayout
  533. // unused in wgpu
  534. // Constants []ConstantEntry
  535. }
  536. type PrimitiveState struct {
  537. Topology PrimitiveTopology
  538. StripIndexFormat IndexFormat
  539. FrontFace FrontFace
  540. CullMode CullMode
  541. }
  542. type StencilFaceState struct {
  543. Compare CompareFunction
  544. FailOp StencilOperation
  545. DepthFailOp StencilOperation
  546. PassOp StencilOperation
  547. }
  548. type DepthStencilState struct {
  549. Format TextureFormat
  550. DepthWriteEnabled bool
  551. DepthCompare CompareFunction
  552. StencilFront StencilFaceState
  553. StencilBack StencilFaceState
  554. StencilReadMask uint32
  555. StencilWriteMask uint32
  556. DepthBias int32
  557. DepthBiasSlopeScale float32
  558. DepthBiasClamp float32
  559. }
  560. type MultisampleState struct {
  561. Count uint32
  562. Mask uint32
  563. AlphaToCoverageEnabled bool
  564. }
  565. func (p *Device) CreateRenderPipeline(descriptor *RenderPipelineDescriptor) (*RenderPipeline, error) {
  566. var desc C.WGPURenderPipelineDescriptor
  567. if descriptor != nil {
  568. if descriptor.Label != "" {
  569. label := C.CString(descriptor.Label)
  570. defer C.free(unsafe.Pointer(label))
  571. desc.label = label
  572. }
  573. if descriptor.Layout != nil {
  574. desc.layout = descriptor.Layout.ref
  575. }
  576. // vertex
  577. {
  578. vertex := descriptor.Vertex
  579. var vert C.WGPUVertexState
  580. if vertex.Module != nil {
  581. vert.module = vertex.Module.ref
  582. }
  583. if vertex.EntryPoint != "" {
  584. entryPoint := C.CString(vertex.EntryPoint)
  585. defer C.free(unsafe.Pointer(entryPoint))
  586. vert.entryPoint = entryPoint
  587. }
  588. bufferCount := len(vertex.Buffers)
  589. if bufferCount > 0 {
  590. buffers := C.malloc(C.size_t(bufferCount) * C.size_t(unsafe.Sizeof(C.WGPUVertexBufferLayout{})))
  591. defer C.free(buffers)
  592. buffersSlice := unsafe.Slice((*C.WGPUVertexBufferLayout)(buffers), bufferCount)
  593. for i, v := range vertex.Buffers {
  594. buffer := C.WGPUVertexBufferLayout{
  595. arrayStride: C.uint64_t(v.ArrayStride),
  596. stepMode: C.WGPUVertexStepMode(v.StepMode),
  597. }
  598. attributeCount := len(v.Attributes)
  599. if attributeCount > 0 {
  600. attributes := C.malloc(C.size_t(attributeCount) * C.size_t(unsafe.Sizeof(C.WGPUVertexAttribute{})))
  601. defer C.free(attributes)
  602. attributesSlice := unsafe.Slice((*C.WGPUVertexAttribute)(attributes), attributeCount)
  603. for j, attribute := range v.Attributes {
  604. attributesSlice[j] = C.WGPUVertexAttribute{
  605. format: C.WGPUVertexFormat(attribute.Format),
  606. offset: C.uint64_t(attribute.Offset),
  607. shaderLocation: C.uint32_t(attribute.ShaderLocation),
  608. }
  609. }
  610. buffer.attributeCount = C.size_t(attributeCount)
  611. buffer.attributes = (*C.WGPUVertexAttribute)(attributes)
  612. }
  613. buffersSlice[i] = buffer
  614. }
  615. vert.bufferCount = C.size_t(bufferCount)
  616. vert.buffers = (*C.WGPUVertexBufferLayout)(buffers)
  617. }
  618. desc.vertex = vert
  619. }
  620. desc.primitive = C.WGPUPrimitiveState{
  621. topology: C.WGPUPrimitiveTopology(descriptor.Primitive.Topology),
  622. stripIndexFormat: C.WGPUIndexFormat(descriptor.Primitive.StripIndexFormat),
  623. frontFace: C.WGPUFrontFace(descriptor.Primitive.FrontFace),
  624. cullMode: C.WGPUCullMode(descriptor.Primitive.CullMode),
  625. }
  626. if descriptor.DepthStencil != nil {
  627. depthStencil := descriptor.DepthStencil
  628. ds := (*C.WGPUDepthStencilState)(C.malloc(C.size_t(unsafe.Sizeof(C.WGPUDepthStencilState{}))))
  629. defer C.free(unsafe.Pointer(ds))
  630. ds.nextInChain = nil
  631. ds.format = C.WGPUTextureFormat(depthStencil.Format)
  632. ds.depthWriteEnabled = cBool(depthStencil.DepthWriteEnabled)
  633. ds.depthCompare = C.WGPUCompareFunction(depthStencil.DepthCompare)
  634. ds.stencilFront = C.WGPUStencilFaceState{
  635. compare: C.WGPUCompareFunction(depthStencil.StencilFront.Compare),
  636. failOp: C.WGPUStencilOperation(depthStencil.StencilFront.FailOp),
  637. depthFailOp: C.WGPUStencilOperation(depthStencil.StencilFront.DepthFailOp),
  638. passOp: C.WGPUStencilOperation(depthStencil.StencilFront.PassOp),
  639. }
  640. ds.stencilBack = C.WGPUStencilFaceState{
  641. compare: C.WGPUCompareFunction(depthStencil.StencilBack.Compare),
  642. failOp: C.WGPUStencilOperation(depthStencil.StencilBack.FailOp),
  643. depthFailOp: C.WGPUStencilOperation(depthStencil.StencilBack.DepthFailOp),
  644. passOp: C.WGPUStencilOperation(depthStencil.StencilBack.PassOp),
  645. }
  646. ds.stencilReadMask = C.uint32_t(depthStencil.StencilReadMask)
  647. ds.stencilWriteMask = C.uint32_t(depthStencil.StencilWriteMask)
  648. ds.depthBias = C.int32_t(depthStencil.DepthBias)
  649. ds.depthBiasSlopeScale = C.float(depthStencil.DepthBiasSlopeScale)
  650. ds.depthBiasClamp = C.float(depthStencil.DepthBiasClamp)
  651. desc.depthStencil = ds
  652. }
  653. desc.multisample = C.WGPUMultisampleState{
  654. count: C.uint32_t(descriptor.Multisample.Count),
  655. mask: C.uint32_t(descriptor.Multisample.Mask),
  656. alphaToCoverageEnabled: cBool(descriptor.Multisample.AlphaToCoverageEnabled),
  657. }
  658. if descriptor.Fragment != nil {
  659. fragment := descriptor.Fragment
  660. frag := (*C.WGPUFragmentState)(C.malloc(C.size_t(unsafe.Sizeof(C.WGPUFragmentState{}))))
  661. defer C.free(unsafe.Pointer(frag))
  662. frag.nextInChain = nil
  663. if fragment.EntryPoint != "" {
  664. entryPoint := C.CString(fragment.EntryPoint)
  665. defer C.free(unsafe.Pointer(entryPoint))
  666. frag.entryPoint = entryPoint
  667. }
  668. if fragment.Module != nil {
  669. frag.module = fragment.Module.ref
  670. }
  671. targetCount := len(fragment.Targets)
  672. if targetCount > 0 {
  673. targets := C.malloc(C.size_t(targetCount) * C.size_t(unsafe.Sizeof(C.WGPUColorTargetState{})))
  674. defer C.free(targets)
  675. targetsSlice := unsafe.Slice((*C.WGPUColorTargetState)(targets), targetCount)
  676. for i, v := range fragment.Targets {
  677. target := C.WGPUColorTargetState{
  678. format: C.WGPUTextureFormat(v.Format),
  679. writeMask: C.WGPUColorWriteMaskFlags(v.WriteMask),
  680. }
  681. if v.Blend != nil {
  682. blend := (*C.WGPUBlendState)(C.malloc(C.size_t(unsafe.Sizeof(C.WGPUBlendState{}))))
  683. defer C.free(unsafe.Pointer(blend))
  684. blend.color = C.WGPUBlendComponent{
  685. operation: C.WGPUBlendOperation(v.Blend.Color.Operation),
  686. srcFactor: C.WGPUBlendFactor(v.Blend.Color.SrcFactor),
  687. dstFactor: C.WGPUBlendFactor(v.Blend.Color.DstFactor),
  688. }
  689. blend.alpha = C.WGPUBlendComponent{
  690. operation: C.WGPUBlendOperation(v.Blend.Alpha.Operation),
  691. srcFactor: C.WGPUBlendFactor(v.Blend.Alpha.SrcFactor),
  692. dstFactor: C.WGPUBlendFactor(v.Blend.Alpha.DstFactor),
  693. }
  694. target.blend = blend
  695. }
  696. targetsSlice[i] = target
  697. }
  698. frag.targetCount = C.size_t(targetCount)
  699. frag.targets = (*C.WGPUColorTargetState)(targets)
  700. } else {
  701. frag.targetCount = 0
  702. frag.targets = nil
  703. }
  704. frag.constantCount = 0 // note: crashes on linux arm64 without setting this to 0
  705. frag.constants = nil // even though wgpu doesn't even support it.
  706. desc.fragment = frag
  707. }
  708. }
  709. var err error = nil
  710. var cb errorCallback = func(_ ErrorType, message string) {
  711. err = errors.New("wgpu.(*Device).CreateRenderPipeline(): " + message)
  712. }
  713. errorCallbackHandle := cgo.NewHandle(cb)
  714. defer errorCallbackHandle.Delete()
  715. ref := C.gowebgpu_device_create_render_pipeline(
  716. p.ref,
  717. &desc,
  718. unsafe.Pointer(&errorCallbackHandle),
  719. )
  720. if err != nil {
  721. C.wgpuRenderPipelineRelease(ref)
  722. return nil, err
  723. }
  724. return &RenderPipeline{ref}, nil
  725. }
  726. func (p *Device) CreateSampler(descriptor *SamplerDescriptor) (*Sampler, error) {
  727. var desc *C.WGPUSamplerDescriptor
  728. if descriptor != nil {
  729. desc = &C.WGPUSamplerDescriptor{
  730. addressModeU: C.WGPUAddressMode(descriptor.AddressModeU),
  731. addressModeV: C.WGPUAddressMode(descriptor.AddressModeV),
  732. addressModeW: C.WGPUAddressMode(descriptor.AddressModeW),
  733. magFilter: C.WGPUFilterMode(descriptor.MagFilter),
  734. minFilter: C.WGPUFilterMode(descriptor.MinFilter),
  735. mipmapFilter: C.WGPUMipmapFilterMode(descriptor.MipmapFilter),
  736. lodMinClamp: C.float(descriptor.LodMinClamp),
  737. lodMaxClamp: C.float(descriptor.LodMaxClamp),
  738. compare: C.WGPUCompareFunction(descriptor.Compare),
  739. maxAnisotropy: C.uint16_t(descriptor.MaxAnisotropy),
  740. }
  741. if descriptor.Label != "" {
  742. label := C.CString(descriptor.Label)
  743. defer C.free(unsafe.Pointer(label))
  744. desc.label = label
  745. }
  746. }
  747. var err error = nil
  748. var cb errorCallback = func(_ ErrorType, message string) {
  749. err = errors.New("wgpu.(*Device).CreateSampler(): " + message)
  750. }
  751. errorCallbackHandle := cgo.NewHandle(cb)
  752. defer errorCallbackHandle.Delete()
  753. ref := C.gowebgpu_device_create_sampler(
  754. p.ref,
  755. desc,
  756. unsafe.Pointer(&errorCallbackHandle),
  757. )
  758. if err != nil {
  759. C.wgpuSamplerRelease(ref)
  760. return nil, err
  761. }
  762. return &Sampler{ref}, nil
  763. }
  764. type ShaderModuleSPIRVDescriptor struct {
  765. Code []byte
  766. }
  767. type ShaderModuleGLSLDescriptor struct {
  768. Code string
  769. Defines map[string]string
  770. ShaderStage ShaderStage
  771. }
  772. type ShaderModuleDescriptor struct {
  773. Label string
  774. SPIRVDescriptor *ShaderModuleSPIRVDescriptor
  775. WGSLDescriptor *ShaderModuleWGSLDescriptor
  776. GLSLDescriptor *ShaderModuleGLSLDescriptor
  777. }
  778. func (p *Device) CreateShaderModule(descriptor *ShaderModuleDescriptor) (*ShaderModule, error) {
  779. var desc C.WGPUShaderModuleDescriptor
  780. if descriptor != nil {
  781. if descriptor.Label != "" {
  782. label := C.CString(descriptor.Label)
  783. defer C.free(unsafe.Pointer(label))
  784. desc.label = label
  785. }
  786. switch {
  787. case descriptor.SPIRVDescriptor != nil:
  788. spirv := (*C.WGPUShaderModuleSPIRVDescriptor)(C.malloc(C.size_t(unsafe.Sizeof(C.WGPUShaderModuleSPIRVDescriptor{}))))
  789. defer C.free(unsafe.Pointer(spirv))
  790. codeSize := len(descriptor.SPIRVDescriptor.Code)
  791. if codeSize > 0 {
  792. code := C.CBytes(descriptor.SPIRVDescriptor.Code)
  793. defer C.free(code)
  794. spirv.codeSize = C.uint32_t(codeSize)
  795. spirv.code = (*C.uint32_t)(code)
  796. } else {
  797. spirv.code = nil
  798. spirv.codeSize = 0
  799. }
  800. spirv.chain.next = nil
  801. spirv.chain.sType = C.WGPUSType_ShaderModuleSPIRVDescriptor
  802. desc.nextInChain = (*C.WGPUChainedStruct)(unsafe.Pointer(spirv))
  803. case descriptor.WGSLDescriptor != nil:
  804. wgsl := (*C.WGPUShaderModuleWGSLDescriptor)(C.malloc(C.size_t(unsafe.Sizeof(C.WGPUShaderModuleWGSLDescriptor{}))))
  805. defer C.free(unsafe.Pointer(wgsl))
  806. if descriptor.WGSLDescriptor.Code != "" {
  807. code := C.CString(descriptor.WGSLDescriptor.Code)
  808. defer C.free(unsafe.Pointer(code))
  809. wgsl.code = code
  810. } else {
  811. wgsl.code = nil
  812. }
  813. wgsl.chain.next = nil
  814. wgsl.chain.sType = C.WGPUSType_ShaderModuleWGSLDescriptor
  815. desc.nextInChain = (*C.WGPUChainedStruct)(unsafe.Pointer(wgsl))
  816. case descriptor.GLSLDescriptor != nil:
  817. glsl := (*C.WGPUShaderModuleGLSLDescriptor)(C.malloc(C.size_t(unsafe.Sizeof(C.WGPUShaderModuleGLSLDescriptor{}))))
  818. defer C.free(unsafe.Pointer(glsl))
  819. if descriptor.GLSLDescriptor.Code != "" {
  820. code := C.CString(descriptor.GLSLDescriptor.Code)
  821. defer C.free(unsafe.Pointer(code))
  822. glsl.code = code
  823. } else {
  824. glsl.code = nil
  825. }
  826. defineCount := len(descriptor.GLSLDescriptor.Defines)
  827. if defineCount > 0 {
  828. shaderDefines := C.malloc(C.size_t(unsafe.Sizeof(C.WGPUShaderDefine{})) * C.size_t(defineCount))
  829. defer C.free(shaderDefines)
  830. shaderDefinesSlice := unsafe.Slice((*C.WGPUShaderDefine)(shaderDefines), defineCount)
  831. index := 0
  832. for name, value := range descriptor.GLSLDescriptor.Defines {
  833. namePtr := C.CString(name)
  834. defer C.free(unsafe.Pointer(namePtr))
  835. valuePtr := C.CString(value)
  836. defer C.free(unsafe.Pointer(valuePtr))
  837. shaderDefinesSlice[index] = C.WGPUShaderDefine{
  838. name: namePtr,
  839. value: valuePtr,
  840. }
  841. index++
  842. }
  843. glsl.defineCount = C.uint32_t(defineCount)
  844. glsl.defines = (*C.WGPUShaderDefine)(shaderDefines)
  845. } else {
  846. glsl.defineCount = 0
  847. glsl.defines = nil
  848. }
  849. glsl.stage = C.WGPUShaderStage(descriptor.GLSLDescriptor.ShaderStage)
  850. glsl.chain.next = nil
  851. glsl.chain.sType = C.WGPUSType_ShaderModuleGLSLDescriptor
  852. desc.nextInChain = (*C.WGPUChainedStruct)(unsafe.Pointer(glsl))
  853. }
  854. }
  855. var err error = nil
  856. var cb errorCallback = func(_ ErrorType, message string) {
  857. err = errors.New("wgpu.(*Device).CreateShaderModule(): " + message)
  858. }
  859. errorCallbackHandle := cgo.NewHandle(cb)
  860. defer errorCallbackHandle.Delete()
  861. ref := C.gowebgpu_device_create_shader_module(
  862. p.ref,
  863. &desc,
  864. unsafe.Pointer(&errorCallbackHandle),
  865. )
  866. if err != nil {
  867. C.wgpuShaderModuleRelease(ref)
  868. return nil, err
  869. }
  870. return &ShaderModule{ref}, nil
  871. }
  872. func (p *Device) CreateTexture(descriptor *TextureDescriptor) (*Texture, error) {
  873. var desc C.WGPUTextureDescriptor
  874. if descriptor != nil {
  875. desc = C.WGPUTextureDescriptor{
  876. usage: C.WGPUTextureUsageFlags(descriptor.Usage),
  877. dimension: C.WGPUTextureDimension(descriptor.Dimension),
  878. size: C.WGPUExtent3D{
  879. width: C.uint32_t(descriptor.Size.Width),
  880. height: C.uint32_t(descriptor.Size.Height),
  881. depthOrArrayLayers: C.uint32_t(descriptor.Size.DepthOrArrayLayers),
  882. },
  883. format: C.WGPUTextureFormat(descriptor.Format),
  884. mipLevelCount: C.uint32_t(descriptor.MipLevelCount),
  885. sampleCount: C.uint32_t(descriptor.SampleCount),
  886. }
  887. if descriptor.Label != "" {
  888. label := C.CString(descriptor.Label)
  889. defer C.free(unsafe.Pointer(label))
  890. desc.label = label
  891. }
  892. }
  893. var err error = nil
  894. var cb errorCallback = func(_ ErrorType, message string) {
  895. err = errors.New("wgpu.(*Device).CreateTexture(): " + message)
  896. }
  897. errorCallbackHandle := cgo.NewHandle(cb)
  898. defer errorCallbackHandle.Delete()
  899. ref := C.gowebgpu_device_create_texture(
  900. p.ref,
  901. &desc,
  902. unsafe.Pointer(&errorCallbackHandle),
  903. )
  904. if err != nil {
  905. C.wgpuTextureRelease(ref)
  906. return nil, err
  907. }
  908. C.wgpuDeviceReference(p.ref)
  909. return &Texture{deviceRef: p.ref, ref: ref}, nil
  910. }
  911. func (p *Device) EnumerateFeatures() []FeatureName {
  912. size := C.wgpuDeviceEnumerateFeatures(p.ref, nil)
  913. if size == 0 {
  914. return nil
  915. }
  916. features := make([]FeatureName, size)
  917. C.wgpuDeviceEnumerateFeatures(p.ref, (*C.WGPUFeatureName)(unsafe.Pointer(&features[0])))
  918. return features
  919. }
  920. func (p *Device) GetLimits() SupportedLimits {
  921. var supportedLimits C.WGPUSupportedLimits
  922. extras := (*C.WGPUSupportedLimitsExtras)(C.malloc(C.size_t(unsafe.Sizeof(C.WGPUSupportedLimitsExtras{}))))
  923. defer C.free(unsafe.Pointer(extras))
  924. supportedLimits.nextInChain = (*C.WGPUChainedStructOut)(unsafe.Pointer(extras))
  925. C.wgpuDeviceGetLimits(p.ref, &supportedLimits)
  926. limits := supportedLimits.limits
  927. return SupportedLimits{
  928. Limits{
  929. MaxTextureDimension1D: uint32(limits.maxTextureDimension1D),
  930. MaxTextureDimension2D: uint32(limits.maxTextureDimension2D),
  931. MaxTextureDimension3D: uint32(limits.maxTextureDimension3D),
  932. MaxTextureArrayLayers: uint32(limits.maxTextureArrayLayers),
  933. MaxBindGroups: uint32(limits.maxBindGroups),
  934. MaxBindingsPerBindGroup: uint32(limits.maxBindingsPerBindGroup),
  935. MaxDynamicUniformBuffersPerPipelineLayout: uint32(limits.maxDynamicUniformBuffersPerPipelineLayout),
  936. MaxDynamicStorageBuffersPerPipelineLayout: uint32(limits.maxDynamicStorageBuffersPerPipelineLayout),
  937. MaxSampledTexturesPerShaderStage: uint32(limits.maxSampledTexturesPerShaderStage),
  938. MaxSamplersPerShaderStage: uint32(limits.maxSamplersPerShaderStage),
  939. MaxStorageBuffersPerShaderStage: uint32(limits.maxStorageBuffersPerShaderStage),
  940. MaxStorageTexturesPerShaderStage: uint32(limits.maxStorageTexturesPerShaderStage),
  941. MaxUniformBuffersPerShaderStage: uint32(limits.maxUniformBuffersPerShaderStage),
  942. MaxUniformBufferBindingSize: uint64(limits.maxUniformBufferBindingSize),
  943. MaxStorageBufferBindingSize: uint64(limits.maxStorageBufferBindingSize),
  944. MinUniformBufferOffsetAlignment: uint32(limits.minUniformBufferOffsetAlignment),
  945. MinStorageBufferOffsetAlignment: uint32(limits.minStorageBufferOffsetAlignment),
  946. MaxVertexBuffers: uint32(limits.maxVertexBuffers),
  947. MaxBufferSize: uint64(limits.maxBufferSize),
  948. MaxVertexAttributes: uint32(limits.maxVertexAttributes),
  949. MaxVertexBufferArrayStride: uint32(limits.maxVertexBufferArrayStride),
  950. MaxInterStageShaderComponents: uint32(limits.maxInterStageShaderComponents),
  951. MaxInterStageShaderVariables: uint32(limits.maxInterStageShaderVariables),
  952. MaxColorAttachments: uint32(limits.maxColorAttachments),
  953. MaxComputeWorkgroupStorageSize: uint32(limits.maxComputeWorkgroupStorageSize),
  954. MaxComputeInvocationsPerWorkgroup: uint32(limits.maxComputeInvocationsPerWorkgroup),
  955. MaxComputeWorkgroupSizeX: uint32(limits.maxComputeWorkgroupSizeX),
  956. MaxComputeWorkgroupSizeY: uint32(limits.maxComputeWorkgroupSizeY),
  957. MaxComputeWorkgroupSizeZ: uint32(limits.maxComputeWorkgroupSizeZ),
  958. MaxComputeWorkgroupsPerDimension: uint32(limits.maxComputeWorkgroupsPerDimension),
  959. MaxPushConstantSize: uint32(extras.limits.maxPushConstantSize),
  960. },
  961. }
  962. }
  963. func (p *Device) GetQueue() *Queue {
  964. ref := C.wgpuDeviceGetQueue(p.ref)
  965. C.wgpuDeviceReference(p.ref)
  966. return &Queue{deviceRef: p.ref, ref: ref}
  967. }
  968. func (p *Device) HasFeature(feature FeatureName) bool {
  969. hasFeature := C.wgpuDeviceHasFeature(p.ref, C.WGPUFeatureName(feature))
  970. return goBool(hasFeature)
  971. }
  972. func (p *Device) Poll(wait bool, wrappedSubmissionIndex *WrappedSubmissionIndex) (queueEmpty bool) {
  973. var index *C.WGPUWrappedSubmissionIndex
  974. if wrappedSubmissionIndex != nil {
  975. index = &C.WGPUWrappedSubmissionIndex{
  976. queue: wrappedSubmissionIndex.Queue.ref,
  977. submissionIndex: C.WGPUSubmissionIndex(wrappedSubmissionIndex.SubmissionIndex),
  978. }
  979. }
  980. return goBool(C.wgpuDevicePoll(p.ref, cBool(wait), index))
  981. }