├── .gitattributes ├── .gitignore ├── .gitmodules ├── LICENSE ├── Makefile ├── README.md ├── examples ├── quad │ ├── quad.odin │ └── quad.wgsl ├── textured_quad │ ├── textured_quad.odin │ ├── textured_quad.png │ └── textured_quad.wgsl └── window │ └── window.odin └── wgpu ├── wgpu-ext.odin ├── wgpu-native.odin └── wgpu-rs.odin /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | vsession 3 | ols.json 4 | ***/*.o 5 | ***/*-gen.odin 6 | ***/.DS_Store 7 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "thirdparty/wgpu-native"] 2 | path = thirdparty/wgpu-native 3 | url = https://github.com/gfx-rs/wgpu-native 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # --- General --- # 2 | 3 | ## https://stackoverflow.com/a/14777895 4 | ifeq ($(OS),Windows_NT) # is Windows_NT on XP, 2000, 7, Vista, 10... 5 | detected_OS := Windows 6 | else 7 | detected_OS := $(shell uname) 8 | endif 9 | 10 | ifeq ($(detected_OS),Darwin) 11 | else ifeq ($(detected_OS),Windows) 12 | else 13 | $(error [ERROR][OS] Unsupported platform : '$(detected_OS)') 14 | endif 15 | 16 | ifeq ($(profile),) 17 | Profile := release 18 | else 19 | Profile := $(profile) 20 | endif 21 | 22 | ## -- Target Triple -- ## 23 | TARGET_ARCH:=x86_64 24 | ifeq ($(detected_OS),Windows) 25 | TARGET_PLATFORM :=pc 26 | TARGET_OS :=windows 27 | else ifeq ($(detected_OS),Darwin) 28 | TARGET_PLATFORM :=apple 29 | TARGET_OS :=darwin 30 | endif 31 | 32 | # --- Rust --- # 33 | 34 | CARGO_TARGET_OS :=$(TARGET_OS) 35 | ifeq ($(detected_OS),Windows) 36 | CARGO_TARGET_OS := $(TARGET_OS)-msvc 37 | endif 38 | 39 | CARGO_TARGET := $(TARGET_ARCH)-$(TARGET_PLATFORM)-$(CARGO_TARGET_OS) 40 | ifeq ($(Profile),release) 41 | CARGO_PROFILE := release 42 | else 43 | CARGO_PROFILE := 44 | endif 45 | 46 | CARGO_BUILD := cargo build --target=$(CARGO_TARGET) --$(CARGO_PROFILE) 47 | 48 | ## Rust -- WGPU-Native -- ## 49 | 50 | CARGO_WGPU_NATIVE_PATH := thirdparty/wgpu-native 51 | 52 | ifeq ($(detected_OS),Windows) 53 | CARGO_BUILD_WGPU_NATIVE_POST := && cp -u \ 54 | $(CARGO_WGPU_NATIVE_PATH)/target/$(CARGO_TARGET)/$(CARGO_PROFILE)/wgpu_native.lib \ 55 | wgpu/wgpu_native.lib 56 | endif 57 | 58 | CARGO_BUILD_WGPU_NATIVE := pushd $(CARGO_WGPU_NATIVE_PATH) && $(CARGO_BUILD) && popd $(CARGO_BUILD_WGPU_NATIVE_POST) 59 | CARGO_CLEAN_WGPU_NATIVE := pushd $(CARGO_WGPU_NATIVE_PATH)/ && cargo clean && popd && rm -rf wgpu_native/wgpu_native.lib 60 | 61 | # --- Odin --- # 62 | 63 | ifeq ($(TARGET_ARCH),x86_64) 64 | ODIN_TARGET_ARCH := amd64 65 | else ifeq ($(TARGET_ARCH),aarch64) 66 | ODIN_TARGET_ARCH := arm64 67 | endif 68 | 69 | ifeq ($(detected_OS),Darwin) 70 | 71 | ifeq ($(TARGET_ARCH),x86_64) 72 | ODIN_HOMEBREW_PATH := /usr/local/homebrew 73 | else ifeq ($(TARGET_ARCH),aarch64) 74 | ODIN_HOMEBREW_PATH := /opt/homebrew 75 | endif 76 | 77 | ODIN_EXTRA_LINKER_FLAGS := -L$(CARGO_WGPU_NATIVE_PATH)/target/$(CARGO_TARGET)/$(CARGO_PROFILE)/ \ 78 | -L$(ODIN_HOMEBREW_PATH)/opt/sdl2/lib/ 79 | else ifeq ($(detected_OS),Windows) 80 | ODIN_DEFAULT_WIN32_LIBS := Ws2_32.lib AdvAPI32.lib Userenv.lib Bcrypt.lib User32.lib 81 | ODIN_EXTRA_LINKER_FLAGS := $(ODIN_DEFAULT_WIN32_LIBS) d3dcompiler.lib 82 | endif 83 | 84 | ifeq ($(example_name),) 85 | ODIN_EXAMPLE_BIN_NAME :=quad 86 | else 87 | ODIN_EXAMPLE_BIN_NAME :=$(example_name) 88 | endif 89 | 90 | ifeq ($(Profile),release) 91 | ODIN_PROFILE := -o:speed 92 | else 93 | ODIN_PROFILE := -debug 94 | endif 95 | 96 | ODIN_EXAMPLE_BIN_PATH := bin/examples/$(CARGO_PROFILE)/$(ODIN_EXAMPLE_BIN_NAME) 97 | ODIN_RUN_EXAMPLE_CMD_PRE := mkdir -p $(ODIN_EXAMPLE_BIN_PATH) 98 | ODIN_RUN_EXAMPLE_CMD := $(ODIN_RUN_EXAMPLE_CMD_PRE) && \ 99 | odin run \ 100 | examples/$(ODIN_EXAMPLE_BIN_NAME)/$(ODIN_EXAMPLE_BIN_NAME).odin -file \ 101 | $(ODIN_PROFILE) \ 102 | -target=$(TARGET_OS)_$(ODIN_TARGET_ARCH) \ 103 | -extra-linker-flags="$(ODIN_EXTRA_LINKER_FLAGS)" \ 104 | -out="$(ODIN_EXAMPLE_BIN_PATH)/$(ODIN_EXAMPLE_BIN_NAME)" 105 | 106 | ODIN_BUILD_SHARED_LIB_CMD := mkdir -p bin/shared/$(CARGO_PROFILE)/ && \ 107 | odin build \ 108 | wgpu/ \ 109 | -no-entry-point \ 110 | -build-mode=shared \ 111 | $(ODIN_PROFILE) \ 112 | -target=$(TARGET_OS)_$(ODIN_TARGET_ARCH) \ 113 | -extra-linker-flags="$(ODIN_EXTRA_LINKER_FLAGS)" \ 114 | -out="bin/shared/$(CARGO_PROFILE)/wgpu" 115 | 116 | setup: 117 | git config --global pull.rebase true 118 | git config --global fetch.prune true 119 | git config --global diff.colorMoved zebra 120 | git pull 121 | git submodule update --init --recursive 122 | $(CARGO_BUILD_WGPU_NATIVE) 123 | 124 | shared: setup 125 | $(ODIN_BUILD_SHARED_LIB_CMD) 126 | 127 | run: setup 128 | $(ODIN_RUN_EXAMPLE_CMD) 129 | 130 | clean: 131 | $(CARGO_CLEAN_WGPU_NATIVE) 132 | rm -rf bin/* 133 | 134 | .PHONY: build run clean 135 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # wgpu-odin 2 | 3 | WGPU bindings for Odin. 4 | 5 | ## Platforms ( WIP ). 6 | Windows x86_64 : ⚠ (Makefile is kinda broken, working on it). 7 | 8 | MacOS x86_64 : ✅ (For M1, use Rosetta for now) 9 | 10 | Linux : ❌ (Coming Soon) 11 | 12 | ## Build : 13 | 14 | #### 1 - Building wgpu_native : 15 | Clone this repository : 16 | ``` 17 | git clone https://github.com/UsiTarek/wgpu-odin 18 | ``` 19 | Run 'make' or 'make setup' : 20 | ``` 21 | make 22 | ``` 23 | 24 | #### 2 - Running examples : 25 | Test the library with an example : (Requires SDL2) 26 | ``` 27 | make run 28 | ``` 29 | You can choose which example to run with the 'example_name' argument : 30 | ``` 31 | make run example_name=textured_quad 32 | ``` 33 | 34 | #### 3 - Enjoy ! 35 | You can include the package using 'import'. 36 | -------------------------------------------------------------------------------- /examples/quad/quad.odin: -------------------------------------------------------------------------------- 1 | package examples 2 | 3 | import "core:fmt" 4 | import "core:os" 5 | import SDL "vendor:sdl2" 6 | import WGPU "../../wgpu" 7 | 8 | when ODIN_OS == "windows" { 9 | import "core:sys/win32" 10 | } 11 | 12 | Vertex :: struct { 13 | pos: [2]f32, 14 | color: [4]f32, 15 | } 16 | 17 | VERTICES :: [6]Vertex { 18 | { pos = {-1.0, -1.0}, color = { 1.0, 0.0, 0.0, 1.0 } }, 19 | { pos = {-1.0, 1.0}, color = { 0.0, 1.0, 0.0, 1.0 } }, 20 | { pos = { 1.0, 1.0}, color = { 0.0, 0.0, 1.0, 1.0 } }, 21 | 22 | { pos = {-1.0, -1.0}, color = { 1.0, 0.0, 0.0, 1.0 } }, 23 | { pos = { 1.0, -1.0}, color = { 0.0, 1.0, 0.0, 1.0 } }, 24 | { pos = { 1.0, 1.0}, color = { 0.0, 0.0, 1.0, 1.0 } }, 25 | } 26 | 27 | request_adapter_callback :: proc ( 28 | status: WGPU.RequestAdapterStatus, 29 | adapter: WGPU.Adapter, 30 | message: cstring, 31 | userdata: rawptr, 32 | ) { 33 | adapter_props : WGPU.AdapterProperties 34 | WGPU.AdapterGetProperties(adapter, &adapter_props) 35 | 36 | if status == WGPU.RequestAdapterStatus.Success { 37 | user_adapter := cast(^WGPU.Adapter)userdata 38 | user_adapter^ = adapter 39 | } 40 | } 41 | 42 | request_device_callback :: proc ( 43 | status: WGPU.RequestDeviceStatus, 44 | device : WGPU.Device, 45 | message : cstring, 46 | userdata : rawptr, 47 | ) { 48 | if status == WGPU.RequestDeviceStatus.Success { 49 | user_device := cast(^WGPU.Device)userdata 50 | user_device^ = device 51 | } 52 | } 53 | 54 | error_callback :: proc( 55 | level : WGPU.LogLevel, 56 | msg : cstring, 57 | ) { 58 | fmt.println(msg) 59 | } 60 | 61 | main :: proc () { 62 | err := SDL.Init({.VIDEO}) 63 | assert(err == 0) 64 | 65 | window_flags : SDL.WindowFlags 66 | when ODIN_OS == "darwin" { 67 | window_flags = SDL.WindowFlags{.METAL} 68 | } 69 | 70 | window := SDL.CreateWindow( 71 | "WebGPU Example Quad", 72 | SDL.WINDOWPOS_CENTERED, 73 | SDL.WINDOWPOS_CENTERED, 74 | 800, 75 | 600, 76 | window_flags, 77 | ) 78 | defer SDL.DestroyWindow(window) 79 | 80 | WGPU.SetLogCallback(error_callback) 81 | WGPU.SetLogLevel(WGPU.LogLevel.Warn) 82 | 83 | when ODIN_OS == "darwin" { 84 | metalView := SDL.Metal_CreateView(window) 85 | defer SDL.Metal_DestroyView(metalView) 86 | 87 | surface := WGPU.InstanceCreateSurface(nil, &WGPU.SurfaceDescriptor{ 88 | label = "Metal Surface", 89 | nextInChain = auto_cast &WGPU.SurfaceDescriptorFromMetalLayer{ 90 | layer = SDL.Metal_GetLayer(metalView), 91 | chain = { 92 | sType = WGPU.SType.SurfaceDescriptorFromMetalLayer, 93 | }, 94 | }, 95 | }) 96 | } else when ODIN_OS == "windows" { 97 | wmInfo: SDL.SysWMinfo = --- 98 | SDL.GetWindowWMInfo(window, &wmInfo); 99 | hwnd := wmInfo.info.win.window; 100 | hinstance := win32.get_module_handle_a(nil) 101 | 102 | surface := WGPU.InstanceCreateSurface(nil, &(WGPU.SurfaceDescriptor) { 103 | label = "Windows Surface", 104 | nextInChain = auto_cast &WGPU.SurfaceDescriptorFromWindowsHWND{ 105 | chain = (WGPU.ChainedStruct) { 106 | sType = WGPU.SType.SurfaceDescriptorFromWindowsHWND, 107 | }, 108 | hinstance = hinstance, 109 | hwnd = hwnd, 110 | }, 111 | }); 112 | } 113 | 114 | assert(surface != nil) 115 | 116 | adapter : WGPU.Adapter = nil 117 | WGPU.InstanceRequestAdapter(nil, 118 | &(WGPU.RequestAdapterOptions{ 119 | compatibleSurface = surface, 120 | powerPreference = WGPU.PowerPreference.LowPower, 121 | forceFallbackAdapter = false, 122 | }), 123 | request_adapter_callback, 124 | &adapter) 125 | assert(adapter != nil) 126 | 127 | device : WGPU.Device = nil 128 | WGPU.AdapterRequestDevice(adapter, 129 | &WGPU.DeviceDescriptor { 130 | nextInChain = auto_cast &WGPU.DeviceExtras{ 131 | chain = WGPU.ChainedStruct{ 132 | sType = auto_cast WGPU.NativeSType.DeviceExtras, 133 | }, 134 | label = "Device", 135 | }, 136 | requiredLimits = &WGPU.RequiredLimits{ 137 | limits = (WGPU.Limits) { 138 | maxBindGroups = 1, 139 | }, 140 | }, 141 | }, 142 | request_device_callback, 143 | &device) 144 | assert(device != nil) 145 | 146 | queue := WGPU.DeviceGetQueue(device) 147 | 148 | pipeline_layout := WGPU.DeviceCreatePipelineLayout( 149 | device, 150 | &WGPU.PipelineLayoutDescriptor{ 151 | label = "Empty Pipeline Layout", 152 | bindGroupLayouts = {}, 153 | }, 154 | ) 155 | 156 | read_content, read_ok := os.read_entire_file_from_filename("examples/quad/quad.wgsl"); 157 | if !read_ok { 158 | panic("Could not open or read file.") 159 | } 160 | defer delete(read_content) 161 | 162 | shader_module := WGPU.DeviceCreateShaderModule(device, &WGPU.ShaderModuleDescriptor{ 163 | nextInChain = auto_cast &WGPU.ShaderModuleWGSLDescriptor{ 164 | chain = WGPU.ChainedStruct { 165 | sType = WGPU.SType.ShaderModuleWGSLDescriptor, 166 | }, 167 | source = cstring(&read_content[0]), 168 | }, 169 | label = "Quad Shader Module", 170 | }) 171 | defer WGPU.ShaderModuleDrop(shader_module) 172 | 173 | render_pipeline := WGPU.DeviceCreateRenderPipeline(device, &WGPU.RenderPipelineDescriptor{ 174 | label = "Quad Render Pipeline", 175 | layout = pipeline_layout, 176 | vertex = WGPU.VertexState{ 177 | module = shader_module, 178 | entryPoint = "vs_main", 179 | buffers = { 180 | { 181 | arrayStride = size_of(Vertex), 182 | stepMode = WGPU.VertexStepMode.Vertex, 183 | attributes = { 184 | { 185 | format = WGPU.VertexFormat.Float32x2, 186 | offset = auto_cast offset_of(Vertex, pos), 187 | shaderLocation = 0, 188 | }, 189 | { 190 | format = WGPU.VertexFormat.Float32x4, 191 | offset = auto_cast offset_of(Vertex, color), 192 | shaderLocation = 1, 193 | }, 194 | }, 195 | }, 196 | }, 197 | }, 198 | fragment = &{ 199 | module = shader_module, 200 | entryPoint = "fs_main", 201 | targets = { 202 | { 203 | format = WGPU.TextureFormat.BGRA8UnormSrgb, 204 | writeMask = WGPU.ColorWriteMaskFlagsAll, 205 | }, 206 | }, 207 | }, 208 | primitive = { 209 | topology = WGPU.PrimitiveTopology.TriangleList, 210 | cullMode = WGPU.CullMode.None, 211 | }, 212 | multisample = { 213 | count = 1, 214 | mask = 1, 215 | alphaToCoverageEnabled = false, 216 | }, 217 | }) 218 | defer WGPU.RenderPipelineDrop(render_pipeline) 219 | 220 | w, h : i32 = 0, 0 221 | SDL.GetWindowSize(window, &w, &h) 222 | swapchain := WGPU.DeviceCreateSwapChain(device, surface, &WGPU.SwapChainDescriptor{ 223 | label = "Swapchain", 224 | usage = WGPU.TextureUsageFlags{.RenderAttachment}, 225 | format = WGPU.TextureFormat.BGRA8UnormSrgb, 226 | width = auto_cast w, 227 | height = auto_cast h, 228 | presentMode = WGPU.PresentMode.Fifo, 229 | }) 230 | 231 | vert_buffer := WGPU.DeviceCreateBuffer(device, &WGPU.BufferDescriptor{ 232 | label = "", 233 | usage = WGPU.BufferUsageFlags{.Vertex, .CopyDst}, 234 | size = size_of(Vertex) * 6, 235 | }) 236 | defer WGPU.BufferDrop(vert_buffer) 237 | 238 | vertices := VERTICES 239 | WGPU.QueueWriteBuffer(queue, vert_buffer, 0, &vertices, size_of(vertices)) 240 | WGPU.QueueSubmit(queue, []WGPU.CommandBuffer{}) 241 | 242 | main_loop: for { 243 | for e: SDL.Event; SDL.PollEvent(&e) != 0; { 244 | #partial switch(e.type) { 245 | case .QUIT: 246 | break main_loop; 247 | } 248 | } 249 | 250 | current_view := WGPU.SwapChainGetCurrentTextureView(swapchain) 251 | 252 | cmd_encoder := WGPU.DeviceCreateCommandEncoder( 253 | device, 254 | &WGPU.CommandEncoderDescriptor{ 255 | label = "Main Command Encoder", 256 | }, 257 | ) 258 | 259 | render_pass := WGPU.CommandEncoderBeginRenderPass( 260 | cmd_encoder, 261 | &WGPU.RenderPassDescriptor{ 262 | label = "Main Render Pass", 263 | colorAttachments = { 264 | { 265 | view = current_view, 266 | loadOp = WGPU.LoadOp.Clear, 267 | storeOp = WGPU.StoreOp.Store, 268 | clearColor = WGPU.Color{ 0.1, 0.1, 0.25, 1.0 }, 269 | }, 270 | }, 271 | }, 272 | ) 273 | WGPU.RenderPassEncoderSetPipeline(render_pass, render_pipeline) 274 | WGPU.RenderPassEncoderSetVertexBuffer(render_pass, 0, vert_buffer, 0, 0) 275 | WGPU.RenderPassEncoderDraw(render_pass, len(VERTICES), 1, 0, 0) 276 | WGPU.RenderPassEncoderEndPass(render_pass) 277 | 278 | cmd_buffer := WGPU.CommandEncoderFinish(cmd_encoder, &WGPU.CommandBufferDescriptor{ 279 | label = "Main Command Buffer", 280 | }) 281 | WGPU.QueueSubmit(queue, []WGPU.CommandBuffer{cmd_buffer}); 282 | 283 | WGPU.SwapChainPresent(swapchain) 284 | } 285 | } -------------------------------------------------------------------------------- /examples/quad/quad.wgsl: -------------------------------------------------------------------------------- 1 | struct OutVertex { 2 | [[builtin(position)]] pos: vec4; 3 | [[location(0)]] color: vec4; 4 | }; 5 | 6 | [[stage(vertex)]] 7 | fn vs_main([[location(0)]] in_pos: vec2, 8 | [[location(1)]] in_color: vec4 9 | ) -> OutVertex 10 | { 11 | var out: OutVertex; 12 | out.pos = vec4(in_pos.x, in_pos.y, 0.0, 1.0); 13 | out.color = in_color; 14 | return out; 15 | } 16 | 17 | [[stage(fragment)]] 18 | fn fs_main([[location(0)]] in_color: vec4) -> [[location(0)]] vec4 19 | { 20 | return in_color; 21 | } -------------------------------------------------------------------------------- /examples/textured_quad/textured_quad.odin: -------------------------------------------------------------------------------- 1 | package examples 2 | 3 | import "core:fmt" 4 | import "core:os" 5 | import "core:c" 6 | 7 | import sdl "vendor:sdl2" 8 | import stbi "vendor:stb/image" 9 | import wgpu "../../wgpu" 10 | 11 | when ODIN_OS == .Windows { 12 | import win32 "core:sys/windows" 13 | } 14 | 15 | Vertex :: struct { 16 | pos: [2]f32, 17 | uv: [2]f32, 18 | } 19 | 20 | main :: proc () { 21 | err := sdl.Init({.VIDEO}) 22 | assert(err == 0) 23 | 24 | window_flags : sdl.WindowFlags 25 | when ODIN_OS == .Darwin { 26 | window_flags = sdl.WindowFlags{.METAL} 27 | } 28 | 29 | window := sdl.CreateWindow( 30 | "WebGPU Example Quad", 31 | sdl.WINDOWPOS_CENTERED, 32 | sdl.WINDOWPOS_CENTERED, 33 | 800, 34 | 600, 35 | window_flags, 36 | ) 37 | defer sdl.DestroyWindow(window) 38 | 39 | wgpu.SetLogCallback( 40 | proc( 41 | level : wgpu.LogLevel, 42 | msg : cstring, 43 | ) { 44 | fmt.println(msg) 45 | }, 46 | ) 47 | wgpu.SetLogLevel(wgpu.LogLevel.Warn) 48 | 49 | when ODIN_OS == .Darwin { 50 | metalView := sdl.Metal_CreateView(window) 51 | defer sdl.Metal_DestroyView(metalView) 52 | 53 | surface := wgpu.InstanceCreateSurface(nil, &wgpu.SurfaceDescriptor{ 54 | label = "Metal Surface", 55 | nextInChain = auto_cast &wgpu.SurfaceDescriptorFromMetalLayer{ 56 | layer = sdl.Metal_GetLayer(metalView), 57 | chain = { 58 | sType = wgpu.SType.SurfaceDescriptorFromMetalLayer, 59 | }, 60 | }, 61 | }) 62 | } 63 | when ODIN_OS == .Windows { 64 | wmInfo: sdl.SysWMinfo = --- 65 | sdl.GetWindowWMInfo(window, &wmInfo); 66 | hwnd := wmInfo.info.win.window; 67 | hinstance := win32.GetModuleHandleA(nil) 68 | 69 | surface := wgpu.InstanceCreateSurface(nil, &(wgpu.SurfaceDescriptor) { 70 | label = "Windows Surface", 71 | nextInChain = auto_cast &wgpu.SurfaceDescriptorFromWindowsHWND{ 72 | chain = (wgpu.ChainedStruct) { 73 | sType = wgpu.SType.SurfaceDescriptorFromWindowsHWND, 74 | }, 75 | hinstance = hinstance, 76 | hwnd = hwnd, 77 | }, 78 | }); 79 | } 80 | 81 | assert(surface != nil) 82 | 83 | adapter : wgpu.Adapter = nil 84 | wgpu.InstanceRequestAdapter(nil, 85 | &(wgpu.RequestAdapterOptions{ 86 | compatibleSurface = surface, 87 | powerPreference = wgpu.PowerPreference.LowPower, 88 | forceFallbackAdapter = false, 89 | }), 90 | proc ( 91 | status: wgpu.RequestAdapterStatus, 92 | adapter: wgpu.Adapter, 93 | message: cstring, 94 | userdata: rawptr, 95 | ) { 96 | adapter_props : wgpu.AdapterProperties 97 | wgpu.AdapterGetProperties(adapter, &adapter_props) 98 | 99 | if status == wgpu.RequestAdapterStatus.Success { 100 | user_adapter := cast(^wgpu.Adapter)userdata 101 | user_adapter^ = adapter 102 | } 103 | }, 104 | &adapter) 105 | assert(adapter != nil) 106 | 107 | device : wgpu.Device = nil 108 | wgpu.AdapterRequestDevice(adapter, 109 | &wgpu.DeviceDescriptor { 110 | nextInChain = auto_cast &wgpu.DeviceExtras{ 111 | chain = wgpu.ChainedStruct{ 112 | sType = auto_cast wgpu.NativeSType.DeviceExtras, 113 | }, 114 | label = "Device", 115 | }, 116 | requiredLimits = &wgpu.RequiredLimits{ 117 | limits = (wgpu.Limits) { 118 | maxBindGroups = 1, 119 | }, 120 | }, 121 | }, 122 | proc ( 123 | status: wgpu.RequestDeviceStatus, 124 | device : wgpu.Device, 125 | message : cstring, 126 | userdata : rawptr, 127 | ) { 128 | if status == wgpu.RequestDeviceStatus.Success { 129 | user_device := cast(^wgpu.Device)userdata 130 | user_device^ = device 131 | } 132 | }, 133 | &device) 134 | assert(device != nil) 135 | 136 | queue := wgpu.DeviceGetQueue(device) 137 | 138 | bind_group_layout_0 := wgpu.DeviceCreateBindGroupLayout( 139 | device, 140 | &wgpu.BindGroupLayoutDescriptor { 141 | label = "Texture Bind Group Layout", 142 | entries = { 143 | { 144 | binding = 0, 145 | visibility = wgpu.ShaderStageFlags{ .Fragment }, 146 | texture = { 147 | sampleType = wgpu.TextureSampleType.Float, 148 | viewDimension = wgpu.TextureViewDimension.TwoDimensional, 149 | }, 150 | }, 151 | { 152 | binding = 1, 153 | visibility = wgpu.ShaderStageFlags{ .Fragment }, 154 | sampler = { 155 | type = wgpu.SamplerBindingType.Filtering, 156 | }, 157 | }, 158 | }, 159 | }, 160 | ) 161 | defer wgpu.BindGroupLayoutDrop(bind_group_layout_0) 162 | 163 | pipeline_layout := wgpu.DeviceCreatePipelineLayout( 164 | device, 165 | &wgpu.PipelineLayoutDescriptor{ 166 | label = "Empty Pipeline Layout", 167 | bindGroupLayouts = { 168 | bind_group_layout_0, 169 | }, 170 | }, 171 | ) 172 | 173 | read_content, read_ok := os.read_entire_file_from_filename("examples/textured_quad/textured_quad.wgsl"); 174 | if !read_ok { 175 | panic("Could not open or read file.") 176 | } 177 | defer delete(read_content) 178 | 179 | shader_module := wgpu.DeviceCreateShaderModule(device, &wgpu.ShaderModuleDescriptor{ 180 | nextInChain = auto_cast &wgpu.ShaderModuleWGSLDescriptor{ 181 | chain = wgpu.ChainedStruct { 182 | sType = wgpu.SType.ShaderModuleWGSLDescriptor, 183 | }, 184 | source = cstring(&read_content[0]), 185 | }, 186 | label = "Quad Shader Module", 187 | }) 188 | defer wgpu.ShaderModuleDrop(shader_module) 189 | 190 | render_pipeline := wgpu.DeviceCreateRenderPipeline( 191 | device, 192 | &wgpu.RenderPipelineDescriptor{ 193 | label = "Quad Render Pipeline", 194 | layout = pipeline_layout, 195 | vertex = wgpu.VertexState{ 196 | module = shader_module, 197 | entryPoint = "vs_main", 198 | buffers = { 199 | { 200 | arrayStride = size_of(Vertex), 201 | stepMode = wgpu.VertexStepMode.Vertex, 202 | attributes = { 203 | { 204 | format = wgpu.VertexFormat.Float32x2, 205 | offset = auto_cast offset_of(Vertex, pos), 206 | shaderLocation = 0, 207 | }, 208 | { 209 | format = wgpu.VertexFormat.Float32x2, 210 | offset = auto_cast offset_of(Vertex, uv), 211 | shaderLocation = 1, 212 | }, 213 | }, 214 | }, 215 | }, 216 | }, 217 | fragment = &{ 218 | module = shader_module, 219 | entryPoint = "fs_main", 220 | targets = { 221 | { 222 | format = wgpu.TextureFormat.BGRA8UnormSrgb, 223 | writeMask = wgpu.ColorWriteMaskFlagsAll, 224 | }, 225 | }, 226 | }, 227 | primitive = { 228 | topology = wgpu.PrimitiveTopology.TriangleList, 229 | cullMode = wgpu.CullMode.None, 230 | }, 231 | multisample = { 232 | count = 1, 233 | mask = 1, 234 | alphaToCoverageEnabled = false, 235 | }, 236 | }) 237 | defer wgpu.RenderPipelineDrop(render_pipeline) 238 | 239 | w, h : i32 = 0, 0 240 | sdl.GetWindowSize(window, &w, &h) 241 | swapchain := wgpu.DeviceCreateSwapChain( 242 | device, 243 | surface, 244 | &(wgpu.SwapChainDescriptor){ 245 | label = "Swapchain", 246 | usage = wgpu.TextureUsageFlags{.RenderAttachment}, 247 | format = wgpu.TextureFormat.BGRA8UnormSrgb, 248 | width = auto_cast w, 249 | height = auto_cast h, 250 | presentMode = wgpu.PresentMode.Fifo, 251 | }, 252 | ) 253 | 254 | vertices := [6]Vertex { 255 | { pos = {-1.0, -1.0}, uv = { 0.0, 0.0 } }, 256 | { pos = {-1.0, 1.0}, uv = { 0.0, 1.0 } }, 257 | { pos = { 1.0, 1.0}, uv = { 1.0, 1.0 } }, 258 | 259 | { pos = {-1.0, -1.0}, uv = { 0.0, 0.0 } }, 260 | { pos = { 1.0, -1.0}, uv = { 1.0, 0.0 } }, 261 | { pos = { 1.0, 1.0}, uv = { 1.0, 1.0 } }, 262 | } 263 | 264 | vert_buffer := wgpu.DeviceCreateBuffer( 265 | device, 266 | &wgpu.BufferDescriptor{ 267 | label = "", 268 | usage = wgpu.BufferUsageFlags{ .Vertex, .CopyDst }, 269 | size = size_of(Vertex) * 6, 270 | }, 271 | ) 272 | defer wgpu.BufferDrop(vert_buffer) 273 | 274 | wgpu.QueueWriteBuffer(queue, vert_buffer, 0, &vertices, size_of(vertices)) 275 | wgpu.QueueSubmit(queue, []wgpu.CommandBuffer{}) 276 | 277 | texture_width, texture_height, texture_channels_count : i32 278 | texture_filename : cstring = "examples/textured_quad/textured_quad.png" 279 | stbi.set_flip_vertically_on_load(1) 280 | assert(stbi.is_16_bit(texture_filename) == false) 281 | texture_data := stbi.load(texture_filename, &texture_width, &texture_height, &texture_channels_count, 4) 282 | 283 | texture := wgpu.DeviceCreateTexture( 284 | device, 285 | &wgpu.TextureDescriptor{ 286 | label = "Example Texture", 287 | usage = wgpu.TextureUsageFlags{ .CopyDst, .TextureBinding }, 288 | dimension = wgpu.TextureDimension.TwoDimensional, 289 | size = wgpu.Extent3D{ 290 | width = auto_cast texture_width, 291 | height = auto_cast texture_height, 292 | depthOrArrayLayers = 1, 293 | }, 294 | format = wgpu.TextureFormat.RGBA8Unorm, 295 | mipLevelCount = 1, 296 | sampleCount = 1, 297 | }, 298 | ) 299 | defer wgpu.TextureDrop(texture) 300 | 301 | wgpu.QueueWriteTexture( 302 | queue = queue, 303 | destination = &{ 304 | texture = texture, 305 | mipLevel = 0, 306 | aspect = wgpu.TextureAspect.All, 307 | }, 308 | data = auto_cast &texture_data[0], 309 | dataSize = auto_cast (texture_width * texture_height * texture_channels_count), 310 | dataLayout = &{ 311 | offset = 0, 312 | bytesPerRow = auto_cast ( texture_channels_count * texture_width ), 313 | rowsPerImage = auto_cast texture_height, 314 | }, 315 | writeSize = &{ 316 | width = auto_cast texture_width, 317 | height = auto_cast texture_height, 318 | depthOrArrayLayers = 1, 319 | }, 320 | ) 321 | wgpu.QueueSubmit(queue, []wgpu.CommandBuffer{}) 322 | 323 | texture_view := wgpu.TextureCreateView( 324 | texture, 325 | &wgpu.TextureViewDescriptor{ 326 | format = wgpu.TextureFormat.RGBA8Unorm, 327 | dimension = wgpu.TextureViewDimension.TwoDimensional, 328 | mipLevelCount = 1, 329 | arrayLayerCount = 1, 330 | aspect = wgpu.TextureAspect.All, 331 | }, 332 | ) 333 | defer wgpu.TextureViewDrop(texture_view) 334 | 335 | sampler := wgpu.DeviceCreateSampler( 336 | device, 337 | &wgpu.SamplerDescriptor{ 338 | magFilter = wgpu.FilterMode.Linear, 339 | minFilter = wgpu.FilterMode.Linear, 340 | }, 341 | ) 342 | defer wgpu.SamplerDrop(sampler) 343 | 344 | texture_bind_group := wgpu.DeviceCreateBindGroup( 345 | device, 346 | &wgpu.BindGroupDescriptor{ 347 | layout = bind_group_layout_0, 348 | entries = { 349 | { 350 | binding = 0, 351 | textureView = texture_view, 352 | }, 353 | { 354 | binding = 1, 355 | sampler = sampler, 356 | }, 357 | }, 358 | }, 359 | ) 360 | defer wgpu.BindGroupDrop(texture_bind_group) 361 | 362 | main_loop: for { 363 | for e: sdl.Event; sdl.PollEvent(&e); { 364 | #partial switch(e.type) { 365 | case .QUIT: 366 | break main_loop; 367 | } 368 | } 369 | 370 | current_view := wgpu.SwapChainGetCurrentTextureView(swapchain) 371 | 372 | cmd_encoder := wgpu.DeviceCreateCommandEncoder( 373 | device, 374 | &wgpu.CommandEncoderDescriptor{ 375 | label = "Main Command Encoder", 376 | }, 377 | ) 378 | 379 | render_pass := wgpu.CommandEncoderBeginRenderPass( 380 | cmd_encoder, 381 | &wgpu.RenderPassDescriptor{ 382 | label = "Main Render Pass", 383 | colorAttachments = { 384 | { 385 | view = current_view, 386 | loadOp = wgpu.LoadOp.Clear, 387 | storeOp = wgpu.StoreOp.Store, 388 | clearColor = wgpu.Color{ 0.1, 0.1, 0.25, 1.0 }, 389 | }, 390 | }, 391 | }, 392 | ) 393 | wgpu.RenderPassEncoderSetPipeline(render_pass, render_pipeline) 394 | wgpu.RenderPassEncoderSetBindGroup(render_pass, 0, texture_bind_group, 0, nil) 395 | wgpu.RenderPassEncoderSetVertexBuffer(render_pass, 0, vert_buffer, 0, 0) 396 | wgpu.RenderPassEncoderDraw(render_pass, len(vertices), 1, 0, 0) 397 | wgpu.RenderPassEncoderEndPass(render_pass) 398 | 399 | cmd_buffer := wgpu.CommandEncoderFinish(cmd_encoder, &wgpu.CommandBufferDescriptor{ 400 | label = "Main Command Buffer", 401 | }) 402 | wgpu.QueueSubmit(queue, []wgpu.CommandBuffer{cmd_buffer}); 403 | 404 | wgpu.SwapChainPresent(swapchain) 405 | } 406 | } -------------------------------------------------------------------------------- /examples/textured_quad/textured_quad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UsiTarek/wgpu-odin/0bc17ecdfb36a12e7c39ec0a3a89a142afa1a915/examples/textured_quad/textured_quad.png -------------------------------------------------------------------------------- /examples/textured_quad/textured_quad.wgsl: -------------------------------------------------------------------------------- 1 | struct OutVertex { 2 | [[builtin(position)]] pos: vec4; 3 | [[location(0)]] uv: vec2; 4 | }; 5 | 6 | [[stage(vertex)]] 7 | fn vs_main([[location(0)]] in_pos: vec2, 8 | [[location(1)]] in_uv: vec2 9 | ) -> OutVertex 10 | { 11 | var out: OutVertex; 12 | out.pos = vec4(in_pos.x, in_pos.y, 0.0, 1.0); 13 | out.uv = vec2(in_uv.x, in_uv.y); 14 | return out; 15 | } 16 | 17 | [[group(0), binding(0)]] var texture: texture_2d; 18 | [[group(0), binding(1)]] var texture_sampler: sampler; 19 | 20 | [[stage(fragment)]] 21 | fn fs_main([[location(0)]] in_uv: vec2) -> [[location(0)]] vec4 22 | { 23 | return textureSample(texture, texture_sampler, in_uv); 24 | } -------------------------------------------------------------------------------- /examples/window/window.odin: -------------------------------------------------------------------------------- 1 | package examples 2 | 3 | import "core:fmt" 4 | import SDL "vendor:sdl2" 5 | import WGPU "../../wgpu" 6 | 7 | when ODIN_OS == "windows" { 8 | import "core:sys/win32" 9 | } 10 | 11 | request_adapter_callback :: proc ( 12 | status: WGPU.RequestAdapterStatus, 13 | adapter: WGPU.Adapter, 14 | message: cstring, 15 | userdata: rawptr, 16 | ) { 17 | adapter_props : WGPU.AdapterProperties 18 | WGPU.AdapterGetProperties(adapter, &adapter_props) 19 | 20 | if status == WGPU.RequestAdapterStatus.Success { 21 | user_adapter := cast(^WGPU.Adapter)userdata 22 | user_adapter^ = adapter 23 | } 24 | } 25 | 26 | request_device_callback :: proc ( 27 | status: WGPU.RequestDeviceStatus, 28 | device : WGPU.Device, 29 | message : cstring, 30 | userdata : rawptr, 31 | ) { 32 | if status == WGPU.RequestDeviceStatus.Success { 33 | user_device := cast(^WGPU.Device)userdata 34 | user_device^ = device 35 | } 36 | } 37 | 38 | error_callback :: proc( 39 | level : WGPU.LogLevel, 40 | msg : cstring, 41 | ) { 42 | fmt.println(msg) 43 | } 44 | 45 | main :: proc () { 46 | err := SDL.Init({.VIDEO}) 47 | assert(err == 0) 48 | 49 | window_flags : SDL.WindowFlags 50 | when ODIN_OS == "darwin" { 51 | window_flags = SDL.WindowFlags{.METAL} 52 | } 53 | 54 | window := SDL.CreateWindow( 55 | "WebGPU Example Quad", 56 | SDL.WINDOWPOS_CENTERED, 57 | SDL.WINDOWPOS_CENTERED, 58 | 800, 59 | 600, 60 | window_flags, 61 | ) 62 | defer SDL.DestroyWindow(window) 63 | 64 | WGPU.SetLogCallback(error_callback) 65 | WGPU.SetLogLevel(WGPU.LogLevel.Warn) 66 | 67 | when ODIN_OS == "darwin" { 68 | metalView := SDL.Metal_CreateView(window) 69 | defer SDL.Metal_DestroyView(metalView) 70 | 71 | surface := WGPU.InstanceCreateSurface(nil, &WGPU.SurfaceDescriptor{ 72 | label = "Metal Surface", 73 | nextInChain = auto_cast &WGPU.SurfaceDescriptorFromMetalLayer{ 74 | layer = SDL.Metal_GetLayer(metalView), 75 | chain = { 76 | sType = WGPU.SType.SurfaceDescriptorFromMetalLayer, 77 | }, 78 | }, 79 | }) 80 | } else when ODIN_OS == "windows" { 81 | wmInfo: SDL.SysWMinfo = --- 82 | SDL.GetWindowWMInfo(window, &wmInfo); 83 | hwnd := wmInfo.info.win.window; 84 | hinstance := win32.get_module_handle_a(nil) 85 | 86 | surface := WGPU.InstanceCreateSurface(nil, &(WGPU.SurfaceDescriptor) { 87 | label = "Windows Surface", 88 | nextInChain = auto_cast &WGPU.SurfaceDescriptorFromWindowsHWND{ 89 | chain = (WGPU.ChainedStruct) { 90 | sType = WGPU.SType.SurfaceDescriptorFromWindowsHWND, 91 | }, 92 | hinstance = hinstance, 93 | hwnd = hwnd, 94 | }, 95 | }); 96 | } 97 | 98 | assert(surface != nil) 99 | 100 | adapter : WGPU.Adapter = nil 101 | WGPU.InstanceRequestAdapter(nil, 102 | &(WGPU.RequestAdapterOptions{ 103 | compatibleSurface = surface, 104 | powerPreference = WGPU.PowerPreference.LowPower, 105 | forceFallbackAdapter = false, 106 | }), 107 | request_adapter_callback, 108 | &adapter) 109 | assert(adapter != nil) 110 | 111 | device : WGPU.Device = nil 112 | WGPU.AdapterRequestDevice(adapter, 113 | &WGPU.DeviceDescriptor { 114 | nextInChain = auto_cast &WGPU.DeviceExtras{ 115 | chain = WGPU.ChainedStruct{ 116 | sType = auto_cast WGPU.NativeSType.DeviceExtras, 117 | }, 118 | label = "Device", 119 | }, 120 | requiredLimits = &WGPU.RequiredLimits{ 121 | limits = (WGPU.Limits) { 122 | maxBindGroups = 1, 123 | }, 124 | }, 125 | }, 126 | request_device_callback, 127 | &device) 128 | assert(device != nil) 129 | 130 | queue := WGPU.DeviceGetQueue(device) 131 | 132 | w, h : i32 = 0, 0 133 | SDL.GetWindowSize(window, &w, &h) 134 | swapchain := WGPU.DeviceCreateSwapChain(device, surface, &(WGPU.SwapChainDescriptor){ 135 | label = "Swapchain", 136 | usage = WGPU.TextureUsageFlags{.RenderAttachment}, 137 | format = WGPU.TextureFormat.BGRA8UnormSrgb, 138 | width = auto_cast w, 139 | height = auto_cast h, 140 | presentMode = WGPU.PresentMode.Fifo, 141 | }) 142 | 143 | main_loop: for { 144 | for e: SDL.Event; SDL.PollEvent(&e) != 0; { 145 | #partial switch(e.type) { 146 | case .QUIT: 147 | break main_loop; 148 | } 149 | } 150 | 151 | current_view := WGPU.SwapChainGetCurrentTextureView(swapchain) 152 | 153 | cmd_encoder := WGPU.DeviceCreateCommandEncoder( 154 | device, 155 | &WGPU.CommandEncoderDescriptor{ 156 | label = "Main Command Encoder", 157 | }, 158 | ) 159 | 160 | render_pass := WGPU.CommandEncoderBeginRenderPass( 161 | cmd_encoder, 162 | &WGPU.RenderPassDescriptor{ 163 | label = "Main Render Pass", 164 | colorAttachments = { 165 | { 166 | view = current_view, 167 | loadOp = WGPU.LoadOp.Clear, 168 | storeOp = WGPU.StoreOp.Store, 169 | clearColor = WGPU.Color{ 0.1, 0.1, 0.25, 1.0 }, 170 | }, 171 | }, 172 | }, 173 | ) 174 | WGPU.RenderPassEncoderEndPass(render_pass) 175 | 176 | cmd_buffer := WGPU.CommandEncoderFinish(cmd_encoder, &WGPU.CommandBufferDescriptor{ 177 | label = "Main Command Buffer", 178 | }) 179 | WGPU.QueueSubmit(queue, []WGPU.CommandBuffer{cmd_buffer}); 180 | 181 | WGPU.SwapChainPresent(swapchain) 182 | } 183 | } -------------------------------------------------------------------------------- /wgpu/wgpu-ext.odin: -------------------------------------------------------------------------------- 1 | package wgpu 2 | 3 | import "core:mem" 4 | 5 | slice_to_ptr :: proc ( 6 | slice: []$T, 7 | ) -> (^T, uint) { 8 | if (len(slice) != 0) { 9 | return &slice[0], len(slice) 10 | } 11 | return nil, 0 12 | } 13 | 14 | DeviceDescriptor :: struct { 15 | nextInChain : ^ChainedStruct, 16 | requiredFeatures : []FeatureName, 17 | requiredLimits : ^RequiredLimits, 18 | } 19 | 20 | RenderPassDescriptor :: struct { 21 | nextInChain : ^ChainedStruct, 22 | label : cstring, 23 | colorAttachments : []RenderPassColorAttachment, 24 | depthStencilAttachment : ^RenderPassDepthStencilAttachment, 25 | occlusionQuerySet : QuerySet, 26 | } 27 | 28 | PipelineLayoutDescriptor :: struct { 29 | nextInChain : ^ChainedStruct, 30 | label : cstring, 31 | bindGroupLayouts : []BindGroupLayout, 32 | } 33 | 34 | QuerySetDescriptor :: struct { 35 | nextInChain : ^ChainedStruct, 36 | label : cstring, 37 | type : QueryType, 38 | count : u32, 39 | pipelineStatistics : []PipelineStatisticName, 40 | } 41 | 42 | RenderBundleEncoderDescriptor :: struct { 43 | nextInChain : ^ChainedStruct, 44 | label : cstring, 45 | colorFormats : []TextureFormat, 46 | depthStencilFormat : TextureFormat, 47 | sampleCount : u32, 48 | } 49 | 50 | BindGroupDescriptor :: struct { 51 | nextInChain : ^ChainedStruct, 52 | label : cstring, 53 | layout : BindGroupLayout, 54 | entries : []BindGroupEntry, 55 | } 56 | 57 | BindGroupLayoutDescriptor :: struct { 58 | nextInChain : ^ChainedStruct, 59 | label : cstring, 60 | entries : []BindGroupLayoutEntry, 61 | } 62 | 63 | ProgrammableStageDescriptor :: struct { 64 | nextInChain : ^ChainedStruct, 65 | module : ShaderModule, 66 | entryPoint : cstring, 67 | constantCount : u32, 68 | constants : []ConstantEntry, 69 | } 70 | 71 | ComputePipelineDescriptor :: struct { 72 | nextInChain : ^ChainedStruct, 73 | label : cstring, 74 | layout : PipelineLayout, 75 | compute : ProgrammableStageDescriptor, 76 | } 77 | 78 | VertexBufferLayout :: struct { 79 | arrayStride : u64, 80 | stepMode : VertexStepMode, 81 | attributes : []VertexAttribute, 82 | } 83 | 84 | VertexState :: struct { 85 | nextInChain : ^ChainedStruct, 86 | module : ShaderModule, 87 | entryPoint : cstring, 88 | constants : []ConstantEntry, 89 | buffers : []VertexBufferLayout, 90 | } 91 | 92 | FragmentState :: struct { 93 | nextInChain : ^ChainedStruct, 94 | module : ShaderModule, 95 | entryPoint : cstring, 96 | constants : []ConstantEntry, 97 | targets : []ColorTargetState, 98 | } 99 | 100 | RenderPipelineDescriptor :: struct { 101 | nextInChain : ^ChainedStruct, 102 | label : cstring, 103 | layout : PipelineLayout, 104 | vertex : VertexState, 105 | primitive : PrimitiveState, 106 | depthStencil : ^DepthStencilState, 107 | multisample : MultisampleState, 108 | fragment : ^FragmentState, 109 | } 110 | 111 | DeviceCreateRenderPipelineSlice :: proc( 112 | device : Device, 113 | descriptor : ^RenderPipelineDescriptor, 114 | ) -> RenderPipeline { 115 | fragment: ^FragmentStateC = nil 116 | if descriptor.fragment != nil { 117 | fragmentSlice := descriptor.fragment 118 | constants, constantCount := slice_to_ptr(descriptor.fragment.constants) 119 | targets, targetCount := slice_to_ptr(descriptor.fragment.targets) 120 | 121 | fragment = &FragmentStateC { 122 | nextInChain = fragmentSlice.nextInChain, 123 | module = fragmentSlice.module, 124 | entryPoint = fragmentSlice.entryPoint, 125 | constantCount = auto_cast constantCount, 126 | constants = constants, 127 | targetCount = auto_cast targetCount, 128 | targets = targets, 129 | } 130 | } 131 | 132 | // Vertex State 133 | vertex: VertexStateC = {} 134 | { 135 | constants, constantCount := slice_to_ptr(descriptor.vertex.constants) 136 | 137 | bufferCount := cast(u32)len(descriptor.vertex.buffers) 138 | buffersSlice := make([]VertexBufferLayoutC, bufferCount) 139 | if bufferCount != 0 { 140 | for bufferLayout, i in descriptor.vertex.buffers { 141 | attributes, attributeCount := slice_to_ptr(descriptor.vertex.buffers[i].attributes) 142 | buffersSlice[i] = VertexBufferLayoutC{ 143 | arrayStride = descriptor.vertex.buffers[i].arrayStride, 144 | stepMode = descriptor.vertex.buffers[i].stepMode, 145 | attributeCount = auto_cast attributeCount, 146 | attributes = attributes, 147 | } 148 | } 149 | } 150 | 151 | buffers, _ := slice_to_ptr(buffersSlice) 152 | vertex = VertexStateC{ 153 | nextInChain = descriptor.vertex.nextInChain, 154 | module = descriptor.vertex.module, 155 | entryPoint = descriptor.vertex.entryPoint, 156 | constantCount = auto_cast constantCount, 157 | constants = constants, 158 | bufferCount = bufferCount, 159 | buffers = buffers, 160 | } 161 | } 162 | 163 | return DeviceCreateRenderPipeline( 164 | device, 165 | &RenderPipelineDescriptorC{ 166 | nextInChain = descriptor.nextInChain, 167 | label = descriptor.label, 168 | layout = descriptor.layout, 169 | vertex = vertex, 170 | primitive = descriptor.primitive, 171 | depthStencil = descriptor.depthStencil, 172 | multisample = descriptor.multisample, 173 | fragment = fragment, 174 | }, 175 | ) 176 | } 177 | 178 | DeviceCreateRenderPipelineAsyncSlice :: proc( 179 | device : Device, 180 | descriptor : ^RenderPipelineDescriptor, 181 | callback : CreateRenderPipelineAsyncCallback, 182 | userdata : rawptr, 183 | ) { 184 | fragment: ^FragmentStateC = nil 185 | if descriptor.fragment != nil { 186 | fragmentSlice := descriptor.fragment 187 | constants, constantCount := slice_to_ptr(descriptor.fragment.constants) 188 | targets, targetCount := slice_to_ptr(descriptor.fragment.targets) 189 | 190 | fragment = &FragmentStateC{ 191 | nextInChain = fragmentSlice.nextInChain, 192 | module = fragmentSlice.module, 193 | entryPoint = fragmentSlice.entryPoint, 194 | constantCount = auto_cast constantCount, 195 | constants = constants, 196 | targetCount = auto_cast targetCount, 197 | targets = targets, 198 | } 199 | } 200 | 201 | // Vertex State 202 | vertex: VertexStateC = {} 203 | { 204 | constants, constantCount := slice_to_ptr(descriptor.vertex.constants) 205 | 206 | bufferCount := cast(u32)len(descriptor.vertex.buffers) 207 | buffersSlice := make([]VertexBufferLayoutC, bufferCount) 208 | if bufferCount != 0 { 209 | for bufferLayout, i in descriptor.vertex.buffers { 210 | attributes, attributeCount := slice_to_ptr(descriptor.vertex.buffers[i].attributes) 211 | buffersSlice [i] = VertexBufferLayoutC{ 212 | arrayStride = descriptor.vertex.buffers[i].arrayStride, 213 | stepMode = descriptor.vertex.buffers[i].stepMode, 214 | attributeCount = auto_cast attributeCount, 215 | attributes = attributes, 216 | } 217 | } 218 | } 219 | 220 | buffers, _ := slice_to_ptr(buffersSlice) 221 | vertex = VertexStateC{ 222 | nextInChain = descriptor.vertex.nextInChain, 223 | module = descriptor.vertex.module, 224 | entryPoint = descriptor.vertex.entryPoint, 225 | constantCount = auto_cast constantCount, 226 | constants = constants, 227 | bufferCount = bufferCount, 228 | buffers = buffers, 229 | } 230 | } 231 | 232 | DeviceCreateRenderPipelineAsync( 233 | device, 234 | &RenderPipelineDescriptorC{ 235 | nextInChain = descriptor.nextInChain, 236 | label = descriptor.label, 237 | layout = descriptor.layout, 238 | vertex = vertex, 239 | primitive = descriptor.primitive, 240 | depthStencil = descriptor.depthStencil, 241 | multisample = descriptor.multisample, 242 | fragment = fragment, 243 | }, 244 | callback, 245 | userdata, 246 | ) 247 | } 248 | 249 | DeviceCreateBindGroupSlice :: proc( 250 | device : Device, 251 | descriptor : ^BindGroupDescriptor, 252 | ) -> BindGroup { 253 | entries, entriesCount := slice_to_ptr(descriptor.entries) 254 | 255 | return DeviceCreateBindGroupC( 256 | device, 257 | &BindGroupDescriptorC{ 258 | nextInChain = descriptor.nextInChain, 259 | label = descriptor.label, 260 | layout = descriptor.layout, 261 | entryCount = auto_cast entriesCount, 262 | entries = entries, 263 | }, 264 | ) 265 | } 266 | 267 | DeviceCreateRenderBundleEncoderSlice :: proc( 268 | device : Device, 269 | descriptor : ^RenderBundleEncoderDescriptor, 270 | ) -> RenderBundleEncoder { 271 | colorFormats, colorFormatsCount := slice_to_ptr(descriptor.colorFormats) 272 | 273 | return DeviceCreateRenderBundleEncoderC( 274 | device = device, 275 | descriptor = &RenderBundleEncoderDescriptorC{ 276 | nextInChain = descriptor.nextInChain, 277 | label = descriptor.label, 278 | colorFormatsCount = auto_cast colorFormatsCount, 279 | colorFormats = colorFormats, 280 | depthStencilFormat = descriptor.depthStencilFormat, 281 | sampleCount = descriptor.sampleCount, 282 | }, 283 | ) 284 | 285 | } 286 | 287 | DeviceCreateQuerySetSlice :: proc( 288 | device : Device, 289 | descriptor : ^QuerySetDescriptor, 290 | ) -> QuerySet { 291 | pipStats, pipStatCount := slice_to_ptr(descriptor.pipelineStatistics) 292 | 293 | return DeviceCreateQuerySetC( 294 | device, 295 | &QuerySetDescriptorC{ 296 | nextInChain = descriptor.nextInChain, 297 | label = descriptor.label, 298 | type = descriptor.type, 299 | count = descriptor.count, 300 | pipelineStatisticsCount = auto_cast pipStatCount, 301 | pipelineStatistics = pipStats, 302 | }, 303 | ) 304 | } 305 | 306 | QueueSubmitSlice :: proc( 307 | queue : Queue, 308 | commands : []CommandBuffer, 309 | ) { 310 | cmds, cmdCount := slice_to_ptr(commands) 311 | 312 | QueueSubmit( 313 | queue, 314 | auto_cast cmdCount, 315 | cmds, 316 | ) 317 | } 318 | 319 | ComputePassEncoderSetBindGroupSlice :: proc( 320 | computePassEncoder : ComputePassEncoder, 321 | groupIndex : u32, 322 | group : BindGroup, 323 | dynamicOffsets : []u32, 324 | ) { 325 | dynOffsets, dynOffsetCount := slice_to_ptr(dynamicOffsets) 326 | 327 | ComputePassEncoderSetBindGroup( 328 | computePassEncoder, 329 | groupIndex, 330 | group, 331 | auto_cast dynOffsetCount, 332 | dynOffsets, 333 | ) 334 | } 335 | 336 | DeviceCreatePipelineLayoutSlice :: proc( 337 | device : Device, 338 | descriptor : ^PipelineLayoutDescriptor, 339 | ) -> PipelineLayout { 340 | 341 | bindGroupLayouts, bindGroupLayoutCount := slice_to_ptr(descriptor.bindGroupLayouts) 342 | 343 | return DeviceCreatePipelineLayoutC( 344 | device, 345 | &PipelineLayoutDescriptorC{ 346 | nextInChain = descriptor.nextInChain, 347 | label = descriptor.label, 348 | bindGroupLayoutCount = auto_cast bindGroupLayoutCount, 349 | bindGroupLayouts = bindGroupLayouts, 350 | }, 351 | ) 352 | } 353 | 354 | DeviceCreateBindGroupLayoutSlice :: proc( 355 | device : Device, 356 | descriptor : ^BindGroupLayoutDescriptor, 357 | ) -> BindGroupLayout { 358 | entries, entriesCount := slice_to_ptr(descriptor.entries) 359 | 360 | return DeviceCreateBindGroupLayoutC( 361 | device, 362 | &BindGroupLayoutDescriptorC{ 363 | nextInChain = descriptor.nextInChain, 364 | label = descriptor.label, 365 | entryCount = auto_cast entriesCount, 366 | entries = entries, 367 | }, 368 | ) 369 | } 370 | 371 | 372 | DeviceCreateComputePipelineSlice :: proc( 373 | device : Device, 374 | descriptor : ^ComputePipelineDescriptor, 375 | ) -> ComputePipeline { 376 | constants, constantCount := slice_to_ptr(descriptor.compute.constants) 377 | 378 | return DeviceCreateComputePipelineC( 379 | device, 380 | &ComputePipelineDescriptorC{ 381 | nextInChain = descriptor.nextInChain, 382 | label = descriptor.label, 383 | layout = descriptor.layout, 384 | compute = ProgrammableStageDescriptorC{ 385 | nextInChain = descriptor.compute.nextInChain, 386 | module = descriptor.compute.module, 387 | entryPoint = descriptor.compute.entryPoint, 388 | constantCount = auto_cast constantCount, 389 | constants = constants, 390 | }, 391 | }, 392 | ) 393 | } 394 | 395 | DeviceCreateComputePipelineAsyncSlice :: proc( 396 | device : Device, 397 | descriptor : ^ComputePipelineDescriptor, 398 | callback : CreateComputePipelineAsyncCallback, 399 | userdata : rawptr, 400 | ) { 401 | constants, constantCount := slice_to_ptr(descriptor.compute.constants) 402 | 403 | DeviceCreateComputePipelineAsyncC( 404 | device, 405 | &ComputePipelineDescriptorC{ 406 | nextInChain = descriptor.nextInChain, 407 | label = descriptor.label, 408 | layout = descriptor.layout, 409 | compute = ProgrammableStageDescriptorC{ 410 | nextInChain = descriptor.compute.nextInChain, 411 | module = descriptor.compute.module, 412 | entryPoint = descriptor.compute.entryPoint, 413 | constantCount = auto_cast constantCount, 414 | constants = constants, 415 | }, 416 | }, 417 | callback, 418 | userdata, 419 | ) 420 | } 421 | 422 | AdapterRequestDeviceSlice :: proc( 423 | adapter : Adapter, 424 | descriptor : ^DeviceDescriptor, 425 | callback : RequestDeviceCallback, 426 | userdata : rawptr, 427 | ) { 428 | requiredFeatures, requiredFeaturesCount := slice_to_ptr(descriptor.requiredFeatures) 429 | 430 | AdapterRequestDeviceC( 431 | adapter, 432 | &DeviceDescriptorC{ 433 | nextInChain = descriptor.nextInChain, 434 | requiredFeaturesCount = auto_cast requiredFeaturesCount, 435 | requiredFeatures = requiredFeatures, 436 | requiredLimits = descriptor.requiredLimits, 437 | }, 438 | callback, 439 | userdata, 440 | ) 441 | } 442 | 443 | 444 | CommandEncoderBeginRenderPassSlice :: proc( 445 | commandEncoder : CommandEncoder, 446 | descriptor : ^RenderPassDescriptor, 447 | ) -> RenderPassEncoder { 448 | colorAttachments, colorAttachmentCount := slice_to_ptr(descriptor.colorAttachments) 449 | 450 | return CommandEncoderBeginRenderPassC( 451 | commandEncoder, 452 | &RenderPassDescriptorC{ 453 | nextInChain = descriptor.nextInChain, 454 | label = descriptor.label, 455 | colorAttachmentCount = auto_cast colorAttachmentCount, 456 | colorAttachments = colorAttachments, 457 | depthStencilAttachment = descriptor.depthStencilAttachment, 458 | occlusionQuerySet = descriptor.occlusionQuerySet, 459 | }, 460 | ) 461 | } 462 | 463 | 464 | AdapterRequestDevice :: proc { 465 | AdapterRequestDeviceSlice, 466 | AdapterRequestDeviceC, 467 | } 468 | 469 | DeviceCreateRenderPipeline :: proc { 470 | DeviceCreateRenderPipelineSlice, 471 | DeviceCreateRenderPipelineC, 472 | } 473 | 474 | DeviceCreateRenderPipelineAsync :: proc { 475 | DeviceCreateRenderPipelineAsyncSlice, 476 | DeviceCreateRenderPipelineAsyncC, 477 | } 478 | 479 | DeviceCreateBindGroup :: proc { 480 | DeviceCreateBindGroupSlice, 481 | DeviceCreateBindGroupC, 482 | } 483 | 484 | DeviceCreateRenderBundleEncoder :: proc { 485 | DeviceCreateRenderBundleEncoderSlice, 486 | DeviceCreateRenderBundleEncoderC, 487 | } 488 | 489 | DeviceCreateQuerySet :: proc { 490 | DeviceCreateQuerySetSlice, 491 | DeviceCreateQuerySetC, 492 | } 493 | 494 | DeviceCreateBindGroupLayout :: proc { 495 | DeviceCreateBindGroupLayoutSlice, 496 | DeviceCreateBindGroupLayoutC, 497 | } 498 | 499 | QueueSubmit :: proc { 500 | QueueSubmitSlice, 501 | QueueSubmitC, 502 | } 503 | 504 | ComputePassEncoderSetBindGroup :: proc { 505 | ComputePassEncoderSetBindGroupSlice, 506 | ComputePassEncoderSetBindGroupC, 507 | } 508 | 509 | CommandEncoderBeginRenderPass :: proc { 510 | CommandEncoderBeginRenderPassSlice, 511 | CommandEncoderBeginRenderPassC, 512 | } 513 | 514 | DeviceCreatePipelineLayout :: proc { 515 | DeviceCreatePipelineLayoutSlice, 516 | DeviceCreatePipelineLayoutC, 517 | } 518 | 519 | DeviceCreateComputePipeline :: proc { 520 | DeviceCreateComputePipelineSlice, 521 | DeviceCreateComputePipelineC, 522 | } 523 | 524 | DeviceCreateComputePipelineAsync :: proc { 525 | DeviceCreateComputePipelineAsyncSlice, 526 | DeviceCreateComputePipelineAsyncC, 527 | } 528 | 529 | //DeviceDescriptorSlice :: struct {} -------------------------------------------------------------------------------- /wgpu/wgpu-native.odin: -------------------------------------------------------------------------------- 1 | package wgpu 2 | 3 | // -lwgpu_native 4 | when ODIN_OS == .Windows { 5 | foreign import lib "wgpu_native.lib" 6 | }else { 7 | foreign import lib "system:wgpu_native" 8 | } 9 | 10 | import _c "core:c" 11 | 12 | Handle :: rawptr 13 | Adapter :: Handle 14 | BindGroup :: Handle 15 | BindGroupLayout :: Handle 16 | Buffer :: Handle 17 | CommandBuffer :: Handle 18 | CommandEncoder :: Handle 19 | ComputePassEncoder :: Handle 20 | ComputePipeline :: Handle 21 | Device :: Handle 22 | Instance :: Handle 23 | PipelineLayout :: Handle 24 | QuerySet :: Handle 25 | Queue :: Handle 26 | RenderBundle :: Handle 27 | RenderBundleEncoder :: Handle 28 | RenderPassEncoder :: Handle 29 | RenderPipeline :: Handle 30 | Sampler :: Handle 31 | ShaderModule :: Handle 32 | Surface :: Handle 33 | SwapChain :: Handle 34 | Texture :: Handle 35 | TextureView :: Handle 36 | 37 | BufferMapCallback :: #type proc( 38 | status : BufferMapAsyncStatus, 39 | userdata : rawptr, 40 | ) 41 | 42 | CreateComputePipelineAsyncCallback :: #type proc( 43 | status : CreatePipelineAsyncStatus, 44 | pipeline : ComputePipeline, 45 | message : cstring, 46 | userdata : rawptr, 47 | ) 48 | 49 | CreateRenderPipelineAsyncCallback :: #type proc( 50 | status : CreatePipelineAsyncStatus, 51 | pipeline : RenderPipeline, 52 | message : cstring, 53 | userdata : rawptr, 54 | ) 55 | 56 | DeviceLostCallback :: #type proc( 57 | reason : DeviceLostReason, 58 | message : cstring, 59 | userdata : rawptr, 60 | ) 61 | 62 | ErrorCallback :: #type proc( 63 | type : ErrorType, 64 | message : cstring, 65 | userdata : rawptr, 66 | ) 67 | 68 | QueueWorkDoneCallback :: #type proc( 69 | status : QueueWorkDoneStatus, 70 | userdata : rawptr, 71 | ) 72 | 73 | RequestAdapterCallback :: #type proc( 74 | status : RequestAdapterStatus, 75 | adapter : Adapter, 76 | message : cstring, 77 | userdata : rawptr, 78 | ) 79 | 80 | RequestDeviceCallback :: #type proc( 81 | status : RequestDeviceStatus, 82 | device : Device, 83 | message : cstring, 84 | userdata : rawptr, 85 | ) 86 | 87 | Proc :: #type proc() 88 | 89 | AdapterType :: enum i32 { 90 | DiscreteGPU = 0, 91 | IntegratedGPU = 1, 92 | CPU = 2, 93 | Unknown = 3, 94 | } 95 | 96 | AddressMode :: enum i32 { 97 | Repeat = 0, 98 | MirrorRepeat = 1, 99 | ClampToEdge = 2, 100 | } 101 | 102 | BackendType :: enum i32 { 103 | Null = 0, 104 | WebGPU = 1, 105 | D3D11 = 2, 106 | D3D12 = 3, 107 | Metal = 4, 108 | Vulkan = 5, 109 | OpenGL = 6, 110 | OpenGLES = 7, 111 | } 112 | 113 | BlendFactor :: enum i32 { 114 | Zero = 0, 115 | One = 1, 116 | Src = 2, 117 | OneMinusSrc = 3, 118 | SrcAlpha = 4, 119 | OneMinusSrcAlpha = 5, 120 | Dst = 6, 121 | OneMinusDst = 7, 122 | DstAlpha = 8, 123 | OneMinusDstAlpha = 9, 124 | SrcAlphaSaturated = 10, 125 | Constant = 11, 126 | OneMinusConstant = 12, 127 | } 128 | 129 | BlendOperation :: enum i32 { 130 | Add = 0, 131 | Subtract = 1, 132 | ReverseSubtract = 2, 133 | Min = 3, 134 | Max = 4, 135 | } 136 | 137 | BufferBindingType :: enum i32 { 138 | Undefined = 0, 139 | Uniform = 1, 140 | Storage = 2, 141 | ReadOnlyStorage = 3, 142 | } 143 | 144 | BufferMapAsyncStatus :: enum i32 { 145 | Success = 0, 146 | Error = 1, 147 | Unknown = 2, 148 | DeviceLost = 3, 149 | DestroyedBeforeCallback = 4, 150 | UnmappedBeforeCallback = 5, 151 | } 152 | 153 | CompareFunction :: enum i32 { 154 | Undefined = 0, 155 | Never = 1, 156 | Less = 2, 157 | LessEqual = 3, 158 | Greater = 4, 159 | GreaterEqual = 5, 160 | Equal = 6, 161 | NotEqual = 7, 162 | Always = 8, 163 | } 164 | 165 | CompilationMessageType :: enum i32 { 166 | Error = 0, 167 | Warning = 1, 168 | Info = 2, 169 | } 170 | 171 | CreatePipelineAsyncStatus :: enum i32 { 172 | Success = 0, 173 | Error = 1, 174 | DeviceLost = 2, 175 | DeviceDestroyed = 3, 176 | Unknown = 4, 177 | } 178 | 179 | CullMode :: enum i32 { 180 | None = 0, 181 | Front = 1, 182 | Back = 2, 183 | } 184 | 185 | DeviceLostReason :: enum i32 { 186 | Undefined = 0, 187 | Destroyed = 1, 188 | } 189 | 190 | ErrorFilter :: enum i32 { 191 | None = 0, 192 | Validation = 1, 193 | OutOfMemory = 2, 194 | } 195 | 196 | ErrorType :: enum i32 { 197 | NoError = 0, 198 | Validation = 1, 199 | OutOfMemory = 2, 200 | Unknown = 3, 201 | DeviceLost = 4, 202 | } 203 | 204 | FeatureName :: enum i32 { 205 | Undefined = 0, 206 | DepthClamping = 1, 207 | Depth24UnormStencil8 = 2, 208 | Depth32FloatStencil8 = 3, 209 | TimestampQuery = 4, 210 | PipelineStatisticsQuery = 5, 211 | TextureCompressionBC = 6, 212 | } 213 | 214 | FilterMode :: enum i32 { 215 | Nearest = 0, 216 | Linear = 1, 217 | } 218 | 219 | FrontFace :: enum i32 { 220 | CCW = 0, 221 | CW = 1, 222 | } 223 | 224 | IndexFormat :: enum i32 { 225 | Undefined = 0, 226 | Uint16 = 1, 227 | Uint32 = 2, 228 | } 229 | 230 | LoadOp :: enum i32 { 231 | Clear = 0, 232 | Load = 1, 233 | } 234 | 235 | PipelineStatisticName :: enum i32 { 236 | VertexShaderInvocations = 0, 237 | ClipperInvocations = 1, 238 | ClipperPrimitivesOut = 2, 239 | FragmentShaderInvocations = 3, 240 | ComputeShaderInvocations = 4, 241 | } 242 | 243 | PowerPreference :: enum i32 { 244 | LowPower = 0, 245 | HighPerformance = 1, 246 | } 247 | 248 | PresentMode :: enum i32 { 249 | Immediate = 0, 250 | Mailbox = 1, 251 | Fifo = 2, 252 | } 253 | 254 | PrimitiveTopology :: enum i32 { 255 | PointList = 0, 256 | LineList = 1, 257 | LineStrip = 2, 258 | TriangleList = 3, 259 | TriangleStrip = 4, 260 | } 261 | 262 | QueryType :: enum i32 { 263 | Occlusion = 0, 264 | PipelineStatistics = 1, 265 | Timestamp = 2, 266 | } 267 | 268 | QueueWorkDoneStatus :: enum i32 { 269 | Success = 0, 270 | Error = 1, 271 | Unknown = 2, 272 | DeviceLost = 3, 273 | } 274 | 275 | RequestAdapterStatus :: enum i32 { 276 | Success = 0, 277 | Unavailable = 1, 278 | Error = 2, 279 | Unknown = 3, 280 | } 281 | 282 | RequestDeviceStatus :: enum i32 { 283 | Success = 0, 284 | Error = 1, 285 | Unknown = 2, 286 | } 287 | 288 | SType :: enum i32 { 289 | Invalid = 0, 290 | SurfaceDescriptorFromMetalLayer = 1, 291 | SurfaceDescriptorFromWindowsHWND = 2, 292 | SurfaceDescriptorFromXlib = 3, 293 | SurfaceDescriptorFromCanvasHTMLSelector = 4, 294 | ShaderModuleSPIRVDescriptor = 5, 295 | ShaderModuleWGSLDescriptor = 6, 296 | PrimitiveDepthClampingState = 7, 297 | } 298 | 299 | SamplerBindingType :: enum i32 { 300 | Undefined = 0, 301 | Filtering = 1, 302 | NonFiltering = 2, 303 | Comparison = 3, 304 | } 305 | 306 | StencilOperation :: enum i32 { 307 | Keep = 0, 308 | Zero = 1, 309 | Replace = 2, 310 | Invert = 3, 311 | IncrementClamp = 4, 312 | DecrementClamp = 5, 313 | IncrementWrap = 6, 314 | DecrementWrap = 7, 315 | } 316 | 317 | StorageTextureAccess :: enum i32 { 318 | Undefined = 0, 319 | WriteOnly = 1, 320 | } 321 | 322 | StoreOp :: enum i32 { 323 | Store = 0, 324 | Discard = 1, 325 | } 326 | 327 | TextureAspect :: enum i32 { 328 | All = 0, 329 | StencilOnly = 1, 330 | DepthOnly = 2, 331 | } 332 | 333 | TextureComponentType :: enum i32 { 334 | Float = 0, 335 | Sint = 1, 336 | Uint = 2, 337 | DepthComparison = 3, 338 | } 339 | 340 | TextureDimension :: enum i32 { 341 | OneDimensional = 0, 342 | TwoDimensional = 1, 343 | ThreeDimensional = 2, 344 | } 345 | 346 | TextureFormat :: enum i32 { 347 | Undefined = 0, 348 | R8Unorm = 1, 349 | R8Snorm = 2, 350 | R8Uint = 3, 351 | R8Sint = 4, 352 | R16Uint = 5, 353 | R16Sint = 6, 354 | R16Float = 7, 355 | RG8Unorm = 8, 356 | RG8Snorm = 9, 357 | RG8Uint = 10, 358 | RG8Sint = 11, 359 | R32Float = 12, 360 | R32Uint = 13, 361 | R32Sint = 14, 362 | RG16Uint = 15, 363 | RG16Sint = 16, 364 | RG16Float = 17, 365 | RGBA8Unorm = 18, 366 | RGBA8UnormSrgb = 19, 367 | RGBA8Snorm = 20, 368 | RGBA8Uint = 21, 369 | RGBA8Sint = 22, 370 | BGRA8Unorm = 23, 371 | BGRA8UnormSrgb = 24, 372 | RGB10A2Unorm = 25, 373 | RG11B10Ufloat = 26, 374 | RGB9E5Ufloat = 27, 375 | RG32Float = 28, 376 | RG32Uint = 29, 377 | RG32Sint = 30, 378 | RGBA16Uint = 31, 379 | RGBA16Sint = 32, 380 | RGBA16Float = 33, 381 | RGBA32Float = 34, 382 | RGBA32Uint = 35, 383 | RGBA32Sint = 36, 384 | Stencil8 = 37, 385 | Depth16Unorm = 38, 386 | Depth24Plus = 39, 387 | Depth24PlusStencil8 = 40, 388 | Depth32Float = 41, 389 | BC1RGBAUnorm = 42, 390 | BC1RGBAUnormSrgb = 43, 391 | BC2RGBAUnorm = 44, 392 | BC2RGBAUnormSrgb = 45, 393 | BC3RGBAUnorm = 46, 394 | BC3RGBAUnormSrgb = 47, 395 | BC4RUnorm = 48, 396 | BC4RSnorm = 49, 397 | BC5RGUnorm = 50, 398 | BC5RGSnorm = 51, 399 | BC6HRGBUfloat = 52, 400 | BC6HRGBFloat = 53, 401 | BC7RGBAUnorm = 54, 402 | BC7RGBAUnormSrgb = 55, 403 | } 404 | 405 | TextureSampleType :: enum i32 { 406 | Undefined = 0, 407 | Float = 1, 408 | UnfilterableFloat = 2, 409 | Depth = 3, 410 | Sint = 4, 411 | Uint = 5, 412 | } 413 | 414 | TextureViewDimension :: enum i32 { 415 | Undefined = 0, 416 | OneDimensional = 1, 417 | TwoDimensional = 2, 418 | TwoDimensionalArray = 3, 419 | Cube = 4, 420 | CubeArray = 5, 421 | ThreeDimensional = 6, 422 | } 423 | 424 | VertexFormat :: enum i32 { 425 | Undefined = 0, 426 | Uint8x2 = 1, 427 | Uint8x4 = 2, 428 | Sint8x2 = 3, 429 | Sint8x4 = 4, 430 | Unorm8x2 = 5, 431 | Unorm8x4 = 6, 432 | Snorm8x2 = 7, 433 | Snorm8x4 = 8, 434 | Uint16x2 = 9, 435 | Uint16x4 = 10, 436 | Sint16x2 = 11, 437 | Sint16x4 = 12, 438 | Unorm16x2 = 13, 439 | Unorm16x4 = 14, 440 | Snorm16x2 = 15, 441 | Snorm16x4 = 16, 442 | Float16x2 = 17, 443 | Float16x4 = 18, 444 | Float32 = 19, 445 | Float32x2 = 20, 446 | Float32x3 = 21, 447 | Float32x4 = 22, 448 | Uint32 = 23, 449 | Uint32x2 = 24, 450 | Uint32x3 = 25, 451 | Uint32x4 = 26, 452 | Sint32 = 27, 453 | Sint32x2 = 28, 454 | Sint32x3 = 29, 455 | Sint32x4 = 30, 456 | } 457 | 458 | VertexStepMode :: enum i32 { 459 | Vertex = 0, 460 | Instance = 1, 461 | } 462 | 463 | BufferUsage :: enum i32 { 464 | MapRead = 0, 465 | MapWrite = 1, 466 | CopySrc = 2, 467 | CopyDst = 3, 468 | Index = 4, 469 | Vertex = 5, 470 | Uniform = 6, 471 | Storage = 7, 472 | Indirect = 8, 473 | QueryResolve = 9, 474 | } 475 | BufferUsageFlags :: bit_set[BufferUsage; u32] 476 | BufferUsageFlagsNone :: BufferUsageFlags{} 477 | 478 | ColorWriteMask :: enum u32 { 479 | Red = 0, 480 | Green = 1, 481 | Blue = 2, 482 | Alpha = 3, 483 | } 484 | ColorWriteMaskFlags :: bit_set[ColorWriteMask; u32] 485 | ColorWriteMaskFlagsAll :: ColorWriteMaskFlags{ .Red, .Green, .Blue, .Alpha } 486 | ColorWriteMaskFlagsNone :: ColorWriteMaskFlags{ } 487 | 488 | MapMode :: enum i32 { 489 | Read = 0, 490 | Write = 1, 491 | } 492 | MapModeFlags :: distinct bit_set[MapMode; u32] 493 | MapModeFlagsNone :: MapModeFlags{} 494 | 495 | ShaderStage :: enum i32 { 496 | Vertex = 0, 497 | Fragment = 1, 498 | Compute = 2, 499 | } 500 | ShaderStageFlags :: distinct bit_set[ShaderStage; u32] 501 | ShaderStageFlagsNone :: ShaderStageFlags{} 502 | 503 | TextureUsage :: enum i32 { 504 | CopySrc = 0, 505 | CopyDst = 1, 506 | TextureBinding = 2, 507 | StorageBinding = 3, 508 | RenderAttachment = 4, 509 | } 510 | TextureUsageFlags :: distinct bit_set[TextureUsage; u32] 511 | TextureUsageFlagsNone :: TextureUsageFlags{} 512 | 513 | ChainedStruct :: struct { 514 | next : ^ChainedStruct, 515 | sType : SType, 516 | } 517 | 518 | ChainedStructOut :: struct { 519 | next : ^ChainedStructOut, 520 | sType : SType, 521 | } 522 | 523 | AdapterProperties :: struct { 524 | nextInChain : ^ChainedStructOut, 525 | vendorID : u32, 526 | deviceID : u32, 527 | name : cstring, 528 | driverDescription : cstring, 529 | adapterType : AdapterType, 530 | backendType : BackendType, 531 | } 532 | 533 | BindGroupEntry :: struct { 534 | nextInChain : ^ChainedStruct, 535 | binding : u32, 536 | buffer : Buffer, 537 | offset : u64, 538 | size : u64, 539 | sampler : Sampler, 540 | textureView : TextureView, 541 | } 542 | 543 | BlendComponent :: struct { 544 | operation : BlendOperation, 545 | srcFactor : BlendFactor, 546 | dstFactor : BlendFactor, 547 | } 548 | 549 | BufferBindingLayout :: struct { 550 | nextInChain : ^ChainedStruct, 551 | type : BufferBindingType, 552 | hasDynamicOffset : bool, 553 | minBindingSize : u64, 554 | } 555 | 556 | BufferDescriptor :: struct { 557 | nextInChain : ^ChainedStruct, 558 | label : cstring, 559 | usage : BufferUsageFlags, 560 | size : u64, 561 | mappedAtCreation : bool, 562 | } 563 | 564 | Color :: struct { 565 | r : _c.double, 566 | g : _c.double, 567 | b : _c.double, 568 | a : _c.double, 569 | } 570 | 571 | CommandBufferDescriptor :: struct { 572 | nextInChain : ^ChainedStruct, 573 | label : cstring, 574 | } 575 | 576 | CommandEncoderDescriptor :: struct { 577 | nextInChain : ^ChainedStruct, 578 | label : cstring, 579 | } 580 | 581 | CompilationMessage :: struct { 582 | nextInChain : ^ChainedStruct, 583 | message : cstring, 584 | type : CompilationMessageType, 585 | lineNum : u64, 586 | linePos : u64, 587 | offset : u64, 588 | length : u64, 589 | } 590 | 591 | ComputePassDescriptor :: struct { 592 | nextInChain : ^ChainedStruct, 593 | label : cstring, 594 | } 595 | 596 | ConstantEntry :: struct { 597 | nextInChain : ^ChainedStruct, 598 | key : cstring, 599 | value : _c.double, 600 | } 601 | 602 | Extent3D :: struct { 603 | width : u32, 604 | height : u32, 605 | depthOrArrayLayers : u32, 606 | } 607 | 608 | InstanceDescriptor :: struct { 609 | nextInChain : ^ChainedStruct, 610 | } 611 | 612 | Limits :: struct { 613 | maxTextureDimension1D : u32, 614 | maxTextureDimension2D : u32, 615 | maxTextureDimension3D : u32, 616 | maxTextureArrayLayers : u32, 617 | maxBindGroups : u32, 618 | maxDynamicUniformBuffersPerPipelineLayout : u32, 619 | maxDynamicStorageBuffersPerPipelineLayout : u32, 620 | maxSampledTexturesPerShaderStage : u32, 621 | maxSamplersPerShaderStage : u32, 622 | maxStorageBuffersPerShaderStage : u32, 623 | maxStorageTexturesPerShaderStage : u32, 624 | maxUniformBuffersPerShaderStage : u32, 625 | maxUniformBufferBindingSize : u64, 626 | maxStorageBufferBindingSize : u64, 627 | minUniformBufferOffsetAlignment : u32, 628 | minStorageBufferOffsetAlignment : u32, 629 | maxVertexBuffers : u32, 630 | maxVertexAttributes : u32, 631 | maxVertexBufferArrayStride : u32, 632 | maxInterStageShaderComponents : u32, 633 | maxComputeWorkgroupStorageSize : u32, 634 | maxComputeInvocationsPerWorkgroup : u32, 635 | maxComputeWorkgroupSizeX : u32, 636 | maxComputeWorkgroupSizeY : u32, 637 | maxComputeWorkgroupSizeZ : u32, 638 | maxComputeWorkgroupsPerDimension : u32, 639 | } 640 | 641 | MultisampleState :: struct { 642 | nextInChain : ^ChainedStruct, 643 | count : u32, 644 | mask : u32, 645 | alphaToCoverageEnabled : bool, 646 | } 647 | 648 | Origin3D :: struct { 649 | x : u32, 650 | y : u32, 651 | z : u32, 652 | } 653 | 654 | PipelineLayoutDescriptorC :: struct { 655 | nextInChain : ^ChainedStruct, 656 | label : cstring, 657 | bindGroupLayoutCount : u32, 658 | bindGroupLayouts : [^]BindGroupLayout, 659 | } 660 | 661 | PrimitiveDepthClampingState :: struct { 662 | chain : ChainedStruct, 663 | clampDepth : bool, 664 | } 665 | 666 | PrimitiveState :: struct { 667 | nextInChain : ^ChainedStruct, 668 | topology : PrimitiveTopology, 669 | stripIndexFormat : IndexFormat, 670 | frontFace : FrontFace, 671 | cullMode : CullMode, 672 | } 673 | 674 | QuerySetDescriptorC :: struct { 675 | nextInChain : ^ChainedStruct, 676 | label : cstring, 677 | type : QueryType, 678 | count : u32, 679 | pipelineStatistics : [^]PipelineStatisticName, 680 | pipelineStatisticsCount : u32, 681 | } 682 | 683 | RenderBundleDescriptor :: struct { 684 | nextInChain : ^ChainedStruct, 685 | label : cstring, 686 | } 687 | 688 | RenderBundleEncoderDescriptorC :: struct { 689 | nextInChain : ^ChainedStruct, 690 | label : cstring, 691 | colorFormatsCount : u32, 692 | colorFormats : [^]TextureFormat, 693 | depthStencilFormat : TextureFormat, 694 | sampleCount : u32, 695 | } 696 | 697 | RenderPassDepthStencilAttachment :: struct { 698 | view : TextureView, 699 | depthLoadOp : LoadOp, 700 | depthStoreOp : StoreOp, 701 | clearDepth : _c.float, 702 | depthReadOnly : bool, 703 | stencilLoadOp : LoadOp, 704 | stencilStoreOp : StoreOp, 705 | clearStencil : u32, 706 | stencilReadOnly : bool, 707 | } 708 | 709 | RequestAdapterOptions :: struct { 710 | nextInChain : ^ChainedStruct, 711 | compatibleSurface : Surface, 712 | powerPreference : PowerPreference, 713 | forceFallbackAdapter : bool, 714 | } 715 | 716 | SamplerBindingLayout :: struct { 717 | nextInChain : ^ChainedStruct, 718 | type : SamplerBindingType, 719 | } 720 | 721 | SamplerDescriptor :: struct { 722 | nextInChain : ^ChainedStruct, 723 | label : cstring, 724 | addressModeU : AddressMode, 725 | addressModeV : AddressMode, 726 | addressModeW : AddressMode, 727 | magFilter : FilterMode, 728 | minFilter : FilterMode, 729 | mipmapFilter : FilterMode, 730 | lodMinClamp : _c.float, 731 | lodMaxClamp : _c.float, 732 | compare : CompareFunction, 733 | maxAnisotropy : u16, 734 | } 735 | 736 | ShaderModuleDescriptor :: struct { 737 | nextInChain : ^ChainedStruct, 738 | label : cstring, 739 | } 740 | 741 | ShaderModuleSPIRVDescriptor :: struct { 742 | chain : ChainedStruct, 743 | codeSize : u32, 744 | code : ^u32, 745 | } 746 | 747 | ShaderModuleWGSLDescriptor :: struct { 748 | chain : ChainedStruct, 749 | source : cstring, 750 | } 751 | 752 | StencilFaceState :: struct { 753 | compare : CompareFunction, 754 | failOp : StencilOperation, 755 | depthFailOp : StencilOperation, 756 | passOp : StencilOperation, 757 | } 758 | 759 | StorageTextureBindingLayout :: struct { 760 | nextInChain : ^ChainedStruct, 761 | access : StorageTextureAccess, 762 | format : TextureFormat, 763 | viewDimension : TextureViewDimension, 764 | } 765 | 766 | SurfaceDescriptor :: struct { 767 | nextInChain : ^ChainedStruct, 768 | label : cstring, 769 | } 770 | 771 | SurfaceDescriptorFromCanvasHTMLSelector :: struct { 772 | chain : ChainedStruct, 773 | selector : cstring, 774 | } 775 | 776 | SurfaceDescriptorFromMetalLayer :: struct { 777 | chain : ChainedStruct, 778 | layer : rawptr, 779 | } 780 | 781 | SurfaceDescriptorFromWindowsHWND :: struct { 782 | chain : ChainedStruct, 783 | hinstance : rawptr, 784 | hwnd : rawptr, 785 | } 786 | 787 | SurfaceDescriptorFromXlib :: struct { 788 | chain : ChainedStruct, 789 | display : rawptr, 790 | window : u32, 791 | } 792 | 793 | SwapChainDescriptor :: struct { 794 | nextInChain : ^ChainedStruct, 795 | label : cstring, 796 | usage : TextureUsageFlags, 797 | format : TextureFormat, 798 | width : u32, 799 | height : u32, 800 | presentMode : PresentMode, 801 | } 802 | 803 | TextureBindingLayout :: struct { 804 | nextInChain : ^ChainedStruct, 805 | sampleType : TextureSampleType, 806 | viewDimension : TextureViewDimension, 807 | multisampled : bool, 808 | } 809 | 810 | TextureDataLayout :: struct { 811 | nextInChain : ^ChainedStruct, 812 | offset : u64, 813 | bytesPerRow : u32, 814 | rowsPerImage : u32, 815 | } 816 | 817 | TextureViewDescriptor :: struct { 818 | nextInChain : ^ChainedStruct, 819 | label : cstring, 820 | format : TextureFormat, 821 | dimension : TextureViewDimension, 822 | baseMipLevel : u32, 823 | mipLevelCount : u32, 824 | baseArrayLayer : u32, 825 | arrayLayerCount : u32, 826 | aspect : TextureAspect, 827 | } 828 | 829 | VertexAttribute :: struct { 830 | format : VertexFormat, 831 | offset : u64, 832 | shaderLocation : u32, 833 | } 834 | 835 | BindGroupDescriptorC :: struct { 836 | nextInChain : ^ChainedStruct, 837 | label : cstring, 838 | layout : BindGroupLayout, 839 | entryCount : u32, 840 | entries : [^]BindGroupEntry, 841 | } 842 | 843 | BindGroupLayoutEntry :: struct { 844 | nextInChain : ^ChainedStruct, 845 | binding : u32, 846 | visibility : ShaderStageFlags, 847 | buffer : BufferBindingLayout, 848 | sampler : SamplerBindingLayout, 849 | texture : TextureBindingLayout, 850 | storageTexture : StorageTextureBindingLayout, 851 | } 852 | 853 | BlendState :: struct { 854 | color : BlendComponent, 855 | alpha : BlendComponent, 856 | } 857 | 858 | CompilationInfo :: struct { 859 | nextInChain : ^ChainedStruct, 860 | messageCount : u32, 861 | messages : [^]CompilationMessage, 862 | } 863 | 864 | DepthStencilState :: struct { 865 | nextInChain : ^ChainedStruct, 866 | format : TextureFormat, 867 | depthWriteEnabled : bool, 868 | depthCompare : CompareFunction, 869 | stencilFront : StencilFaceState, 870 | stencilBack : StencilFaceState, 871 | stencilReadMask : u32, 872 | stencilWriteMask : u32, 873 | depthBias : i32, 874 | depthBiasSlopeScale : _c.float, 875 | depthBiasClamp : _c.float, 876 | } 877 | 878 | ImageCopyBuffer :: struct { 879 | nextInChain : ^ChainedStruct, 880 | layout : TextureDataLayout, 881 | buffer : Buffer, 882 | } 883 | 884 | ImageCopyTexture :: struct { 885 | nextInChain : ^ChainedStruct, 886 | texture : Texture, 887 | mipLevel : u32, 888 | origin : Origin3D, 889 | aspect : TextureAspect, 890 | } 891 | 892 | ProgrammableStageDescriptorC :: struct { 893 | nextInChain : ^ChainedStruct, 894 | module : ShaderModule, 895 | entryPoint : cstring, 896 | constantCount : u32, 897 | constants : [^]ConstantEntry, 898 | } 899 | 900 | RenderPassColorAttachment :: struct { 901 | view : TextureView, 902 | resolveTarget : TextureView, 903 | loadOp : LoadOp, 904 | storeOp : StoreOp, 905 | clearColor : Color, 906 | } 907 | 908 | RequiredLimits :: struct { 909 | nextInChain : ^ChainedStruct, 910 | limits : Limits, 911 | } 912 | 913 | SupportedLimits :: struct { 914 | nextInChain : ^ChainedStructOut, 915 | limits : Limits, 916 | } 917 | 918 | TextureDescriptor :: struct { 919 | nextInChain : ^ChainedStruct, 920 | label : cstring, 921 | usage : TextureUsageFlags, 922 | dimension : TextureDimension, 923 | size : Extent3D, 924 | format : TextureFormat, 925 | mipLevelCount : u32, 926 | sampleCount : u32, 927 | } 928 | 929 | VertexBufferLayoutC :: struct { 930 | arrayStride : u64, 931 | stepMode : VertexStepMode, 932 | attributeCount : u32, 933 | attributes : [^]VertexAttribute, 934 | } 935 | 936 | BindGroupLayoutDescriptorC :: struct { 937 | nextInChain : ^ChainedStruct, 938 | label : cstring, 939 | entryCount : u32, 940 | entries : [^]BindGroupLayoutEntry, 941 | } 942 | 943 | ColorTargetState :: struct { 944 | nextInChain : ^ChainedStruct, 945 | format : TextureFormat, 946 | blend : ^BlendState, 947 | writeMask : ColorWriteMaskFlags, 948 | } 949 | 950 | ComputePipelineDescriptorC :: struct { 951 | nextInChain : ^ChainedStruct, 952 | label : cstring, 953 | layout : PipelineLayout, 954 | compute : ProgrammableStageDescriptorC, 955 | } 956 | 957 | DeviceDescriptorC :: struct { 958 | nextInChain : ^ChainedStruct, 959 | requiredFeaturesCount : u32, 960 | requiredFeatures : [^]FeatureName, 961 | requiredLimits : ^RequiredLimits, 962 | } 963 | 964 | RenderPassDescriptorC :: struct { 965 | nextInChain : ^ChainedStruct, 966 | label : cstring, 967 | colorAttachmentCount : u32, 968 | colorAttachments : [^]RenderPassColorAttachment, 969 | depthStencilAttachment : ^RenderPassDepthStencilAttachment, 970 | occlusionQuerySet : QuerySet, 971 | } 972 | 973 | VertexStateC :: struct { 974 | nextInChain : ^ChainedStruct, 975 | module : ShaderModule, 976 | entryPoint : cstring, 977 | constantCount : u32, 978 | constants : [^]ConstantEntry, 979 | bufferCount : u32, 980 | buffers : [^]VertexBufferLayoutC, 981 | } 982 | 983 | FragmentStateC :: struct { 984 | nextInChain : ^ChainedStruct, 985 | module : ShaderModule, 986 | entryPoint : cstring, 987 | constantCount : u32, 988 | constants : ^ConstantEntry, 989 | targetCount : u32, 990 | targets : ^ColorTargetState, 991 | } 992 | 993 | RenderPipelineDescriptorC :: struct { 994 | nextInChain : ^ChainedStruct, 995 | label : cstring, 996 | layout : PipelineLayout, 997 | vertex : VertexStateC, 998 | primitive : PrimitiveState, 999 | depthStencil : ^DepthStencilState, 1000 | multisample : MultisampleState, 1001 | fragment : ^FragmentStateC, 1002 | } 1003 | 1004 | @(default_calling_convention="c", link_prefix="wgpu") 1005 | foreign lib { 1006 | 1007 | CreateInstance :: proc(descriptor : ^InstanceDescriptor) -> Instance --- 1008 | 1009 | GetProcAddress :: proc( 1010 | device : Device, 1011 | procName : cstring, 1012 | ) -> Proc --- 1013 | 1014 | AdapterGetLimits :: proc( 1015 | adapter : Adapter, 1016 | limits : ^SupportedLimits, 1017 | ) -> bool --- 1018 | 1019 | AdapterGetProperties :: proc( 1020 | adapter : Adapter, 1021 | properties : ^AdapterProperties, 1022 | ) --- 1023 | 1024 | AdapterHasFeature :: proc( 1025 | adapter : Adapter, 1026 | feature : FeatureName, 1027 | ) -> bool --- 1028 | 1029 | BufferDestroy :: proc(buffer : Buffer) --- 1030 | 1031 | BufferGetConstMappedRange :: proc( 1032 | buffer : Buffer, 1033 | offset : _c.size_t, 1034 | size : _c.size_t, 1035 | ) -> rawptr --- 1036 | 1037 | BufferGetMappedRange :: proc( 1038 | buffer : Buffer, 1039 | offset : _c.size_t, 1040 | size : _c.size_t, 1041 | ) -> rawptr --- 1042 | 1043 | BufferMapAsync :: proc( 1044 | buffer : Buffer, 1045 | mode : MapModeFlags, 1046 | offset : _c.size_t, 1047 | size : _c.size_t, 1048 | callback : BufferMapCallback, 1049 | userdata : rawptr, 1050 | ) --- 1051 | 1052 | BufferUnmap :: proc(buffer : Buffer) --- 1053 | 1054 | CommandEncoderBeginComputePass :: proc( 1055 | commandEncoder : CommandEncoder, 1056 | descriptor : ^ComputePassDescriptor, 1057 | ) -> ComputePassEncoder --- 1058 | 1059 | CommandEncoderCopyBufferToBuffer :: proc( 1060 | commandEncoder : CommandEncoder, 1061 | source : Buffer, 1062 | sourceOffset : u64, 1063 | destination : Buffer, 1064 | destinationOffset : u64, 1065 | size : u64, 1066 | ) --- 1067 | 1068 | CommandEncoderCopyBufferToTexture :: proc( 1069 | commandEncoder : CommandEncoder, 1070 | source : ^ImageCopyBuffer, 1071 | destination : ^ImageCopyTexture, 1072 | copySize : ^Extent3D, 1073 | ) --- 1074 | 1075 | CommandEncoderCopyTextureToBuffer :: proc( 1076 | commandEncoder : CommandEncoder, 1077 | source : ^ImageCopyTexture, 1078 | destination : ^ImageCopyBuffer, 1079 | copySize : ^Extent3D, 1080 | ) --- 1081 | 1082 | CommandEncoderCopyTextureToTexture :: proc( 1083 | commandEncoder : CommandEncoder, 1084 | source : ^ImageCopyTexture, 1085 | destination : ^ImageCopyTexture, 1086 | copySize : ^Extent3D, 1087 | ) --- 1088 | 1089 | CommandEncoderFinish :: proc( 1090 | commandEncoder : CommandEncoder, 1091 | descriptor : ^CommandBufferDescriptor, 1092 | ) -> CommandBuffer --- 1093 | 1094 | CommandEncoderInsertDebugMarker :: proc( 1095 | commandEncoder : CommandEncoder, 1096 | markerLabel : cstring, 1097 | ) --- 1098 | 1099 | CommandEncoderPopDebugGroup :: proc(commandEncoder : CommandEncoder) --- 1100 | 1101 | CommandEncoderPushDebugGroup :: proc( 1102 | commandEncoder : CommandEncoder, 1103 | groupLabel : cstring, 1104 | ) --- 1105 | 1106 | CommandEncoderResolveQuerySet :: proc( 1107 | commandEncoder : CommandEncoder, 1108 | querySet : QuerySet, 1109 | firstQuery : u32, 1110 | queryCount : u32, 1111 | destination : Buffer, 1112 | destinationOffset : u64, 1113 | ) --- 1114 | 1115 | CommandEncoderWriteTimestamp :: proc( 1116 | commandEncoder : CommandEncoder, 1117 | querySet : QuerySet, 1118 | queryIndex : u32, 1119 | ) --- 1120 | 1121 | ComputePassEncoderBeginPipelineStatisticsQuery :: proc( 1122 | computePassEncoder : ComputePassEncoder, 1123 | querySet : QuerySet, 1124 | queryIndex : u32, 1125 | ) --- 1126 | 1127 | ComputePassEncoderDispatch :: proc( 1128 | computePassEncoder : ComputePassEncoder, 1129 | x : u32, 1130 | y : u32, 1131 | z : u32, 1132 | ) --- 1133 | 1134 | ComputePassEncoderDispatchIndirect :: proc( 1135 | computePassEncoder : ComputePassEncoder, 1136 | indirectBuffer : Buffer, 1137 | indirectOffset : u64, 1138 | ) --- 1139 | 1140 | ComputePassEncoderEndPass :: proc(computePassEncoder : ComputePassEncoder) --- 1141 | 1142 | ComputePassEncoderEndPipelineStatisticsQuery :: proc(computePassEncoder : ComputePassEncoder) --- 1143 | 1144 | ComputePassEncoderInsertDebugMarker :: proc( 1145 | computePassEncoder : ComputePassEncoder, 1146 | markerLabel : cstring, 1147 | ) --- 1148 | 1149 | ComputePassEncoderPopDebugGroup :: proc(computePassEncoder : ComputePassEncoder) --- 1150 | 1151 | ComputePassEncoderPushDebugGroup :: proc( 1152 | computePassEncoder : ComputePassEncoder, 1153 | groupLabel : cstring, 1154 | ) --- 1155 | 1156 | ComputePassEncoderSetPipeline :: proc( 1157 | computePassEncoder : ComputePassEncoder, 1158 | pipeline : ComputePipeline, 1159 | ) --- 1160 | 1161 | ComputePassEncoderWriteTimestamp :: proc( 1162 | computePassEncoder : ComputePassEncoder, 1163 | querySet : QuerySet, 1164 | queryIndex : u32, 1165 | ) --- 1166 | 1167 | ComputePipelineGetBindGroupLayout :: proc( 1168 | computePipeline : ComputePipeline, 1169 | groupIndex : u32, 1170 | ) -> BindGroupLayout --- 1171 | 1172 | ComputePipelineSetLabel :: proc( 1173 | computePipeline : ComputePipeline, 1174 | label : cstring, 1175 | ) --- 1176 | 1177 | DeviceCreateBuffer :: proc( 1178 | device : Device, 1179 | descriptor : ^BufferDescriptor, 1180 | ) -> Buffer --- 1181 | 1182 | DeviceCreateCommandEncoder :: proc( 1183 | device : Device, 1184 | descriptor : ^CommandEncoderDescriptor, 1185 | ) -> CommandEncoder --- 1186 | 1187 | DeviceCreateSampler :: proc( 1188 | device : Device, 1189 | descriptor : ^SamplerDescriptor, 1190 | ) -> Sampler --- 1191 | 1192 | DeviceCreateShaderModule :: proc( 1193 | device : Device, 1194 | descriptor : ^ShaderModuleDescriptor, 1195 | ) -> ShaderModule --- 1196 | 1197 | DeviceCreateSwapChain :: proc( 1198 | device : Device, 1199 | surface : Surface, 1200 | descriptor : ^SwapChainDescriptor, 1201 | ) -> SwapChain --- 1202 | 1203 | DeviceCreateTexture :: proc( 1204 | device : Device, 1205 | descriptor : ^TextureDescriptor, 1206 | ) -> Texture --- 1207 | 1208 | DeviceDestroy :: proc(device : Device) --- 1209 | 1210 | DeviceGetLimits :: proc( 1211 | device : Device, 1212 | limits : ^SupportedLimits, 1213 | ) -> bool --- 1214 | 1215 | DeviceGetQueue :: proc(device : Device) -> Queue --- 1216 | 1217 | DevicePopErrorScope :: proc( 1218 | device : Device, 1219 | callback : ErrorCallback, 1220 | userdata : rawptr, 1221 | ) -> bool --- 1222 | 1223 | DevicePushErrorScope :: proc( 1224 | device : Device, 1225 | filter : ErrorFilter, 1226 | ) --- 1227 | 1228 | DeviceSetDeviceLostCallback :: proc( 1229 | device : Device, 1230 | callback : DeviceLostCallback, 1231 | userdata : rawptr, 1232 | ) --- 1233 | 1234 | DeviceSetUncapturedErrorCallback :: proc( 1235 | device : Device, 1236 | callback : ErrorCallback, 1237 | userdata : rawptr, 1238 | ) --- 1239 | 1240 | InstanceCreateSurface :: proc( 1241 | instance : Instance, 1242 | descriptor : ^SurfaceDescriptor, 1243 | ) -> Surface --- 1244 | 1245 | InstanceProcessEvents :: proc(instance : Instance) --- 1246 | 1247 | InstanceRequestAdapter :: proc( 1248 | instance : Instance, 1249 | options : ^RequestAdapterOptions, 1250 | callback : RequestAdapterCallback, 1251 | userdata : rawptr, 1252 | ) --- 1253 | 1254 | QuerySetDestroy :: proc(querySet : QuerySet) --- 1255 | 1256 | QueueOnSubmittedWorkDone :: proc( 1257 | queue : Queue, 1258 | signalValue : u64, 1259 | callback : QueueWorkDoneCallback, 1260 | userdata : rawptr, 1261 | ) --- 1262 | 1263 | QueueWriteBuffer :: proc( 1264 | queue : Queue, 1265 | buffer : Buffer, 1266 | bufferOffset : u64, 1267 | data : rawptr, 1268 | size : _c.size_t, 1269 | ) --- 1270 | 1271 | QueueWriteTexture :: proc( 1272 | queue : Queue, 1273 | destination : ^ImageCopyTexture, 1274 | data : rawptr, 1275 | dataSize : _c.size_t, 1276 | dataLayout : ^TextureDataLayout, 1277 | writeSize : ^Extent3D, 1278 | ) --- 1279 | 1280 | RenderBundleEncoderDraw :: proc( 1281 | renderBundleEncoder : RenderBundleEncoder, 1282 | vertexCount : u32, 1283 | instanceCount : u32, 1284 | firstVertex : u32, 1285 | firstInstance : u32, 1286 | ) --- 1287 | 1288 | RenderBundleEncoderDrawIndexed :: proc( 1289 | renderBundleEncoder : RenderBundleEncoder, 1290 | indexCount : u32, 1291 | instanceCount : u32, 1292 | firstIndex : u32, 1293 | baseVertex : i32, 1294 | firstInstance : u32, 1295 | ) --- 1296 | 1297 | RenderBundleEncoderDrawIndexedIndirect :: proc( 1298 | renderBundleEncoder : RenderBundleEncoder, 1299 | indirectBuffer : Buffer, 1300 | indirectOffset : u64, 1301 | ) --- 1302 | 1303 | RenderBundleEncoderDrawIndirect :: proc( 1304 | renderBundleEncoder : RenderBundleEncoder, 1305 | indirectBuffer : Buffer, 1306 | indirectOffset : u64, 1307 | ) --- 1308 | 1309 | RenderBundleEncoderFinish :: proc( 1310 | renderBundleEncoder : RenderBundleEncoder, 1311 | descriptor : ^RenderBundleDescriptor, 1312 | ) -> RenderBundle --- 1313 | 1314 | RenderBundleEncoderInsertDebugMarker :: proc( 1315 | renderBundleEncoder : RenderBundleEncoder, 1316 | markerLabel : cstring, 1317 | ) --- 1318 | 1319 | RenderBundleEncoderPopDebugGroup :: proc(renderBundleEncoder : RenderBundleEncoder) --- 1320 | 1321 | RenderBundleEncoderPushDebugGroup :: proc( 1322 | renderBundleEncoder : RenderBundleEncoder, 1323 | groupLabel : cstring, 1324 | ) --- 1325 | 1326 | RenderBundleEncoderSetBindGroup :: proc( 1327 | renderBundleEncoder : RenderBundleEncoder, 1328 | groupIndex : u32, 1329 | group : BindGroup, 1330 | dynamicOffsetCount : u32, 1331 | dynamicOffsets : ^u32, 1332 | ) --- 1333 | 1334 | RenderBundleEncoderSetIndexBuffer :: proc( 1335 | renderBundleEncoder : RenderBundleEncoder, 1336 | buffer : Buffer, 1337 | format : IndexFormat, 1338 | offset : u64, 1339 | size : u64, 1340 | ) --- 1341 | 1342 | RenderBundleEncoderSetPipeline :: proc( 1343 | renderBundleEncoder : RenderBundleEncoder, 1344 | pipeline : RenderPipeline, 1345 | ) --- 1346 | 1347 | RenderBundleEncoderSetVertexBuffer :: proc( 1348 | renderBundleEncoder : RenderBundleEncoder, 1349 | slot : u32, 1350 | buffer : Buffer, 1351 | offset : u64, 1352 | size : u64, 1353 | ) --- 1354 | 1355 | RenderPassEncoderBeginOcclusionQuery :: proc( 1356 | renderPassEncoder : RenderPassEncoder, 1357 | queryIndex : u32, 1358 | ) --- 1359 | 1360 | RenderPassEncoderBeginPipelineStatisticsQuery :: proc( 1361 | renderPassEncoder : RenderPassEncoder, 1362 | querySet : QuerySet, 1363 | queryIndex : u32, 1364 | ) --- 1365 | 1366 | RenderPassEncoderDraw :: proc( 1367 | renderPassEncoder : RenderPassEncoder, 1368 | vertexCount : u32, 1369 | instanceCount : u32, 1370 | firstVertex : u32, 1371 | firstInstance : u32, 1372 | ) --- 1373 | 1374 | RenderPassEncoderDrawIndexed :: proc( 1375 | renderPassEncoder : RenderPassEncoder, 1376 | indexCount : u32, 1377 | instanceCount : u32, 1378 | firstIndex : u32, 1379 | baseVertex : i32, 1380 | firstInstance : u32, 1381 | ) --- 1382 | 1383 | RenderPassEncoderDrawIndexedIndirect :: proc( 1384 | renderPassEncoder : RenderPassEncoder, 1385 | indirectBuffer : Buffer, 1386 | indirectOffset : u64, 1387 | ) --- 1388 | 1389 | RenderPassEncoderDrawIndirect :: proc( 1390 | renderPassEncoder : RenderPassEncoder, 1391 | indirectBuffer : Buffer, 1392 | indirectOffset : u64, 1393 | ) --- 1394 | 1395 | RenderPassEncoderEndOcclusionQuery :: proc(renderPassEncoder : RenderPassEncoder) --- 1396 | 1397 | RenderPassEncoderEndPass :: proc(renderPassEncoder : RenderPassEncoder) --- 1398 | 1399 | RenderPassEncoderEndPipelineStatisticsQuery :: proc(renderPassEncoder : RenderPassEncoder) --- 1400 | 1401 | RenderPassEncoderExecuteBundles :: proc( 1402 | renderPassEncoder : RenderPassEncoder, 1403 | bundlesCount : u32, 1404 | bundles : ^RenderBundle, 1405 | ) --- 1406 | 1407 | RenderPassEncoderInsertDebugMarker :: proc( 1408 | renderPassEncoder : RenderPassEncoder, 1409 | markerLabel : cstring, 1410 | ) --- 1411 | 1412 | RenderPassEncoderPopDebugGroup :: proc(renderPassEncoder : RenderPassEncoder) --- 1413 | 1414 | RenderPassEncoderPushDebugGroup :: proc( 1415 | renderPassEncoder : RenderPassEncoder, 1416 | groupLabel : cstring, 1417 | ) --- 1418 | 1419 | RenderPassEncoderSetBindGroup :: proc( 1420 | renderPassEncoder : RenderPassEncoder, 1421 | groupIndex : u32, 1422 | group : BindGroup, 1423 | dynamicOffsetCount : u32, 1424 | dynamicOffsets : ^u32, 1425 | ) --- 1426 | 1427 | RenderPassEncoderSetBlendConstant :: proc( 1428 | renderPassEncoder : RenderPassEncoder, 1429 | color : ^Color, 1430 | ) --- 1431 | 1432 | RenderPassEncoderSetIndexBuffer :: proc( 1433 | renderPassEncoder : RenderPassEncoder, 1434 | buffer : Buffer, 1435 | format : IndexFormat, 1436 | offset : u64, 1437 | size : u64, 1438 | ) --- 1439 | 1440 | RenderPassEncoderSetPipeline :: proc( 1441 | renderPassEncoder : RenderPassEncoder, 1442 | pipeline : RenderPipeline, 1443 | ) --- 1444 | 1445 | RenderPassEncoderSetScissorRect :: proc( 1446 | renderPassEncoder : RenderPassEncoder, 1447 | x : u32, 1448 | y : u32, 1449 | width : u32, 1450 | height : u32, 1451 | ) --- 1452 | 1453 | RenderPassEncoderSetStencilReference :: proc( 1454 | renderPassEncoder : RenderPassEncoder, 1455 | reference : u32, 1456 | ) --- 1457 | 1458 | RenderPassEncoderSetVertexBuffer :: proc( 1459 | renderPassEncoder : RenderPassEncoder, 1460 | slot : u32, 1461 | buffer : Buffer, 1462 | offset : u64, 1463 | size : u64, 1464 | ) --- 1465 | 1466 | RenderPassEncoderSetViewport :: proc( 1467 | renderPassEncoder : RenderPassEncoder, 1468 | x : _c.float, 1469 | y : _c.float, 1470 | width : _c.float, 1471 | height : _c.float, 1472 | minDepth : _c.float, 1473 | maxDepth : _c.float, 1474 | ) --- 1475 | 1476 | RenderPassEncoderWriteTimestamp :: proc( 1477 | renderPassEncoder : RenderPassEncoder, 1478 | querySet : QuerySet, 1479 | queryIndex : u32, 1480 | ) --- 1481 | 1482 | RenderPipelineGetBindGroupLayout :: proc( 1483 | renderPipeline : RenderPipeline, 1484 | groupIndex : u32, 1485 | ) -> BindGroupLayout --- 1486 | 1487 | RenderPipelineSetLabel :: proc( 1488 | renderPipeline : RenderPipeline, 1489 | label : cstring, 1490 | ) --- 1491 | 1492 | ShaderModuleSetLabel :: proc( 1493 | shaderModule : ShaderModule, 1494 | label : cstring, 1495 | ) --- 1496 | 1497 | SurfaceGetPreferredFormat :: proc( 1498 | surface : Surface, 1499 | adapter : Adapter, 1500 | ) -> TextureFormat --- 1501 | 1502 | SwapChainGetCurrentTextureView :: proc(swapChain : SwapChain) -> TextureView --- 1503 | 1504 | SwapChainPresent :: proc(swapChain : SwapChain) --- 1505 | 1506 | TextureCreateView :: proc( 1507 | texture : Texture, 1508 | descriptor : ^TextureViewDescriptor, 1509 | ) -> TextureView --- 1510 | 1511 | TextureDestroy :: proc(texture : Texture) --- 1512 | 1513 | } 1514 | 1515 | @(default_calling_convention="c") 1516 | foreign lib { 1517 | @(link_name="wgpuDeviceCreatePipelineLayout") 1518 | DeviceCreatePipelineLayoutC :: proc( 1519 | device : Device, 1520 | descriptor : ^PipelineLayoutDescriptorC, 1521 | ) -> PipelineLayout --- 1522 | 1523 | @(link_name="wgpuDeviceCreateQuerySet") 1524 | DeviceCreateQuerySetC :: proc( 1525 | device : Device, 1526 | descriptor : ^QuerySetDescriptorC, 1527 | ) -> QuerySet --- 1528 | 1529 | @(link_name="wgpuComputePassEncoderSetBindGroup") 1530 | ComputePassEncoderSetBindGroupC :: proc( 1531 | computePassEncoder : ComputePassEncoder, 1532 | groupIndex : u32, 1533 | group : BindGroup, 1534 | dynamicOffsetCount : u32, 1535 | dynamicOffsets : ^u32, 1536 | ) --- 1537 | 1538 | @(link_name="wgpuQueueSubmit") 1539 | QueueSubmitC :: proc( 1540 | queue : Queue, 1541 | commandCount : u32, 1542 | commands : ^CommandBuffer, 1543 | ) --- 1544 | 1545 | @(link_name="wgpuDeviceCreateRenderBundleEncoder") 1546 | DeviceCreateRenderBundleEncoderC :: proc( 1547 | device : Device, 1548 | descriptor : ^RenderBundleEncoderDescriptorC, 1549 | ) -> RenderBundleEncoder --- 1550 | 1551 | 1552 | @(link_name="wgpuDeviceCreateComputePipeline") 1553 | DeviceCreateComputePipelineC :: proc( 1554 | device : Device, 1555 | descriptor : ^ComputePipelineDescriptorC, 1556 | ) -> ComputePipeline --- 1557 | 1558 | @(link_name="wgpuDeviceCreateComputePipelineAsync") 1559 | DeviceCreateComputePipelineAsyncC :: proc( 1560 | device : Device, 1561 | descriptor : ^ComputePipelineDescriptorC, 1562 | callback : CreateComputePipelineAsyncCallback, 1563 | userdata : rawptr, 1564 | ) --- 1565 | 1566 | @(link_name="wgpuDeviceCreateBindGroup") 1567 | DeviceCreateBindGroupC :: proc( 1568 | device : Device, 1569 | descriptor : ^BindGroupDescriptorC, 1570 | ) -> BindGroup --- 1571 | 1572 | @(link_name="wgpuDeviceCreateBindGroupLayout") 1573 | DeviceCreateBindGroupLayoutC :: proc( 1574 | device : Device, 1575 | descriptor : ^BindGroupLayoutDescriptorC, 1576 | ) -> BindGroupLayout --- 1577 | 1578 | @(link_name="wgpuDeviceCreateRenderPipeline") 1579 | DeviceCreateRenderPipelineC :: proc( 1580 | device : Device, 1581 | descriptor : ^RenderPipelineDescriptorC, 1582 | ) -> RenderPipeline --- 1583 | 1584 | @(link_name="wgpuDeviceCreateRenderPipelineAsync") 1585 | DeviceCreateRenderPipelineAsyncC :: proc( 1586 | device : Device, 1587 | descriptor : ^RenderPipelineDescriptorC, 1588 | callback : CreateRenderPipelineAsyncCallback, 1589 | userdata : rawptr, 1590 | ) --- 1591 | 1592 | @(link_name="wgpuAdapterRequestDevice") 1593 | AdapterRequestDeviceC :: proc( 1594 | adapter : Adapter, 1595 | descriptor : ^DeviceDescriptorC, 1596 | callback : RequestDeviceCallback, 1597 | userdata : rawptr, 1598 | ) --- 1599 | 1600 | @(link_name="wgpuCommandEncoderBeginRenderPass") 1601 | CommandEncoderBeginRenderPassC :: proc( 1602 | commandEncoder : CommandEncoder, 1603 | descriptor : ^RenderPassDescriptorC, 1604 | ) -> RenderPassEncoder --- 1605 | 1606 | } 1607 | -------------------------------------------------------------------------------- /wgpu/wgpu-rs.odin: -------------------------------------------------------------------------------- 1 | package wgpu 2 | 3 | when ODIN_OS == .Windows { 4 | foreign import lib "wgpu_native.lib" 5 | }else { 6 | foreign import lib "system:wgpu_native" 7 | } 8 | 9 | import _c "core:c" 10 | 11 | _H_ :: 1 12 | 13 | LogCallback :: #type proc( 14 | level : LogLevel, 15 | msg : cstring, 16 | ) 17 | 18 | NativeSType :: enum i32 { 19 | DeviceExtras = 1610612737, 20 | AdapterExtras = 1610612738, 21 | } 22 | 23 | NativeFeature :: enum i32 { 24 | TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES = 268435456, 25 | } 26 | 27 | LogLevel :: enum i32 { 28 | Off = 0, 29 | Error = 1, 30 | Warn = 2, 31 | Info = 3, 32 | Debug = 4, 33 | Trace = 5, 34 | } 35 | 36 | AdapterExtras :: struct { 37 | chain : ChainedStruct, 38 | backend : BackendType, 39 | } 40 | 41 | DeviceExtras :: struct { 42 | chain : ChainedStruct, 43 | nativeFeatures : NativeFeature, 44 | label : cstring, 45 | tracePath : cstring, 46 | } 47 | 48 | @(default_calling_convention="c", link_prefix="wgpu") 49 | foreign lib { 50 | 51 | DevicePoll :: proc( 52 | device : Device, 53 | force_wait : bool, 54 | ) --- 55 | 56 | SetLogCallback :: proc(callback : LogCallback) --- 57 | 58 | SetLogLevel :: proc(level : LogLevel) --- 59 | 60 | GetVersion :: proc() -> u32 --- 61 | 62 | RenderPassEncoderSetPushConstants :: proc( 63 | encoder : RenderPassEncoder, 64 | stages : ShaderStage, 65 | offset : u32, 66 | sizeBytes : u32, 67 | data : rawptr, 68 | ) --- 69 | 70 | BufferDrop :: proc(buffer : Buffer) --- 71 | 72 | CommandEncoderDrop :: proc(commandEncoder : CommandEncoder) --- 73 | 74 | DeviceDrop :: proc(device : Device) --- 75 | 76 | QuerySetDrop :: proc(querySet : QuerySet) --- 77 | 78 | RenderPipelineDrop :: proc(renderPipeline : RenderPipeline) --- 79 | 80 | TextureDrop :: proc(texture : Texture) --- 81 | 82 | TextureViewDrop :: proc(textureView : TextureView) --- 83 | 84 | SamplerDrop :: proc(sampler : Sampler) --- 85 | 86 | BindGroupLayoutDrop :: proc(bindGroupLayout : BindGroupLayout) --- 87 | 88 | PipelineLayoutDrop :: proc(pipelineLayout : PipelineLayout) --- 89 | 90 | BindGroupDrop :: proc(bindGroup : BindGroup) --- 91 | 92 | ShaderModuleDrop :: proc(shaderModule : ShaderModule) --- 93 | 94 | CommandBufferDrop :: proc(commandBuffer : CommandBuffer) --- 95 | 96 | RenderBundleDrop :: proc(renderBundle : RenderBundle) --- 97 | 98 | ComputePipelineDrop :: proc(computePipeline : ComputePipeline) --- 99 | } 100 | --------------------------------------------------------------------------------