From d759da409fc28d50751bb07fde604998a846633e Mon Sep 17 00:00:00 2001 From: Timo de Kort Date: Wed, 24 Jul 2019 21:22:00 +0200 Subject: [PATCH 1/2] add compute example --- Makefile | 15 +- README.md | 28 ++- .../CMakeLists.txt | 8 +- examples/compute/main.c | 180 ++++++++++++++++++ .../{hello_triangle.frag => triangle.frag} | 0 ...lo_triangle.frag.spv => triangle.frag.spv} | Bin .../{hello_triangle.vert => triangle.vert} | 0 ...lo_triangle.vert.spv => triangle.vert.spv} | Bin .../{hello_remote_c => remote}/CMakeLists.txt | 6 +- examples/{hello_remote_c => remote}/main.c | 0 examples/triangle/CMakeLists.txt | 51 +++++ .../{hello_triangle_c => triangle}/main.c | 4 +- 12 files changed, 268 insertions(+), 24 deletions(-) rename examples/{hello_triangle_c => compute}/CMakeLists.txt (93%) create mode 100644 examples/compute/main.c rename examples/data/{hello_triangle.frag => triangle.frag} (100%) rename examples/data/{hello_triangle.frag.spv => triangle.frag.spv} (100%) rename examples/data/{hello_triangle.vert => triangle.vert} (100%) rename examples/data/{hello_triangle.vert.spv => triangle.vert.spv} (100%) rename examples/{hello_remote_c => remote}/CMakeLists.txt (71%) rename examples/{hello_remote_c => remote}/main.c (100%) create mode 100644 examples/triangle/CMakeLists.txt rename examples/{hello_triangle_c => triangle}/main.c (98%) diff --git a/Makefile b/Makefile index 008824a61e..b30f453d75 100644 --- a/Makefile +++ b/Makefile @@ -70,11 +70,14 @@ lib-remote: Cargo.lock wgpu-remote/Cargo.toml $(wildcard wgpu-native/**/*.rs wgp ffi/wgpu.h: wgpu-native/cbindgen.toml $(wildcard wgpu-native/**/*.rs) rustup run nightly cbindgen wgpu-native > $(FFI_DIR)/wgpu.h -ffi/wgpu-remote.h: wgpu-remote/cbindgen.toml $(wildcard wgpu-native/**/*.rs wgpu-remote/**/*.rs) - rustup run nightly cbindgen wgpu-remote >$(FFI_DIR)/wgpu-remote.h +ffi/wgpu-remote.h: wgpu-remote/cbindgen.toml $(wildcard wgpu-native/**/*.rs wgpu-remote/**/*.rs) + rustup run nightly cbindgen wgpu-remote > $(FFI_DIR)/wgpu-remote.h -examples-native: lib-native $(FFI_DIR)/wgpu.h examples/hello_triangle_c/main.c - cd examples/hello_triangle_c && $(CREATE_BUILD_DIR) && cd build && cmake .. -DBACKEND=$(FEATURE_RUST) $(GENERATOR_PLATFORM) && cmake --build . +example-compute: lib-native $(FFI_DIR)/wgpu.h examples/compute/main.c + cd examples/compute && $(CREATE_BUILD_DIR) && cd build && cmake .. -DBACKEND=$(FEATURE_RUST) $(GENERATOR_PLATFORM) && cmake --build . -examples-remote: lib-remote $(FFI_DIR)/wgpu-remote.h examples/hello_remote_c/main.c - cd examples/hello_remote_c && $(CREATE_BUILD_DIR) && cd build && cmake .. && cmake --build . +example-triangle: lib-native $(FFI_DIR)/wgpu.h examples/triangle/main.c + cd examples/triangle && $(CREATE_BUILD_DIR) && cd build && cmake .. -DBACKEND=$(FEATURE_RUST) $(GENERATOR_PLATFORM) && cmake --build . + +example-remote: lib-remote $(FFI_DIR)/wgpu-remote.h examples/remote/main.c + cd examples/remote && $(CREATE_BUILD_DIR) && cd build && cmake .. && cmake --build . \ No newline at end of file diff --git a/README.md b/README.md index 024a1eef9a..e4aa84259c 100644 --- a/README.md +++ b/README.md @@ -20,14 +20,24 @@ Supported platforms: ## Usage -This repository contains C-language examples that link to the native library targets and perform basic rendering and computation. -To run the C triangle example, install a C compiler + glfw 3, then run these commands at the root of the repo: -``` -rustup toolchain install nightly -cargo install cbindgen -make examples-native -cd examples/hello_triangle_c/build -./hello_triangle +This repository contains C-language examples that link to the native library targets and perform basic rendering and computation. The prerequisites are a C compiler and GLFW 3 for running the examples. + +### Running an example +The examples are located under the [examples](examples) directory. We are using a [Makefile](Makefile) for running the examples. + +#### Triangle +```bash +make example-triangle ``` -The idiomatic Rust wrapper lives in https://github.com/gfx-rs/wgpu-rs and provides a number of more complex examples to get a feel of the API. +#### Compute +```bash +make example-compute +``` + +#### Remote +```bash +make example-remote +``` + +The idiomatic Rust wrapper lives in https://github.com/gfx-rs/wgpu-rs and provides a number of more [complex examples](https://github.com/gfx-rs/wgpu-rs/tree/master/examples) to get a feel of the API. \ No newline at end of file diff --git a/examples/hello_triangle_c/CMakeLists.txt b/examples/compute/CMakeLists.txt similarity index 93% rename from examples/hello_triangle_c/CMakeLists.txt rename to examples/compute/CMakeLists.txt index 950f90beaf..2a64186e6c 100644 --- a/examples/hello_triangle_c/CMakeLists.txt +++ b/examples/compute/CMakeLists.txt @@ -14,11 +14,11 @@ if(NOT DEFINED BACKEND OR NOT "${BACKEND}" IN_LIST AVAILABLE_BACKENDS) message(FATAL_ERROR "BACKEND invalid or undefined, available backends: ${AVAILABLE_BACKENDS}") endif() -project(hello_triangle) +project(compute) -set(TARGET_NAME hello_triangle) +set(TARGET_NAME compute) -add_executable(hello_triangle main.c) +add_executable(compute main.c) if(MSVC) add_definitions(-DWGPU_TARGET=WGPU_TARGET_WINDOWS) @@ -48,4 +48,4 @@ find_library(WGPU_LIBRARY wgpu_native target_include_directories(${TARGET_NAME} PUBLIC $ENV{GLFW3_INCLUDE_DIR}) -target_link_libraries(${TARGET_NAME} glfw ${WGPU_LIBRARY} ${OS_LIBRARIES}) +target_link_libraries(${TARGET_NAME} glfw ${WGPU_LIBRARY} ${OS_LIBRARIES}) \ No newline at end of file diff --git a/examples/compute/main.c b/examples/compute/main.c new file mode 100644 index 0000000000..c1023ddb73 --- /dev/null +++ b/examples/compute/main.c @@ -0,0 +1,180 @@ +#include "./../../ffi/wgpu.h" +#include +#include + +#define BINDINGS_LENGTH (1) +#define BIND_GROUP_LAYOUTS_LENGTH (1) + +WGPUByteArray read_file(const char *name) { + FILE *file = fopen(name, "rb"); + fseek(file, 0, SEEK_END); + long length = ftell(file); + unsigned char *bytes = malloc(length); + fseek(file, 0, SEEK_SET); + fread(bytes, 1, length, file); + fclose(file); + return (WGPUByteArray){ + .bytes = bytes, + .length = length, + }; +} + +void read_buffer_map( + WGPUBufferMapAsyncStatus status, + const uint8_t *data, + uint8_t *userdata) { + if (status == WGPUBufferMapAsyncStatus_Success) { + uint32_t *times = (uint32_t *) data; + printf("Times: [%d, %d, %d, %d]", + times[0], + times[1], + times[2], + times[3]); + } +} + +int main( + int argc, + char *argv[]) { + + if (argc != 5) { + return 0; + } + + uint32_t numbers[] = { + strtoul(argv[1], NULL, 0), + strtoul(argv[2], NULL, 0), + strtoul(argv[3], NULL, 0), + strtoul(argv[4], NULL, 0), + }; + + uint32_t size = sizeof(numbers); + + uint32_t numbers_length = size / sizeof(uint32_t); + + WGPUInstanceId instance = wgpu_create_instance(); + + WGPUAdapterId adapter = wgpu_instance_get_adapter(instance, + &(WGPUAdapterDescriptor){ + .power_preference = WGPUPowerPreference_LowPower, + }); + + WGPUDeviceId device = wgpu_adapter_request_device(adapter, + &(WGPUDeviceDescriptor){ + .extensions = { + .anisotropic_filtering = false, + }, + }); + + uint8_t *staging_memory; + + WGPUBufferId staging_buffer = wgpu_device_create_buffer_mapped(device, + &(WGPUBufferDescriptor){ + .size = size, + .usage = WGPUBufferUsage_MAP_READ | WGPUBufferUsage_TRANSFER_DST | + WGPUBufferUsage_TRANSFER_SRC}, + &staging_memory); + + memcpy((uint32_t *) staging_memory, numbers, size); + + wgpu_buffer_unmap(staging_buffer); + + WGPUBufferId storage_buffer = wgpu_device_create_buffer(device, + &(WGPUBufferDescriptor){ + .size = size, + .usage = WGPUBufferUsage_STORAGE | WGPUBufferUsage_TRANSFER_DST | + WGPUBufferUsage_TRANSFER_SRC}); + + WGPUBindGroupLayoutId bind_group_layout = + wgpu_device_create_bind_group_layout(device, + &(WGPUBindGroupLayoutDescriptor){ + .bindings = &(WGPUBindGroupLayoutBinding){ + .binding = 0, + .visibility = WGPUShaderStage_COMPUTE, + .ty = WGPUBindingType_StorageBuffer + }, + .bindings_length = BINDINGS_LENGTH + } + ); + + WGPUBindingResource resource = { + .tag = WGPUBindingResource_Buffer, + .buffer = (WGPUBufferBinding){ + .buffer = storage_buffer, + .size = size, + .offset = 0 + } + }; + + WGPUBindGroupId bind_group = wgpu_device_create_bind_group(device, + &(WGPUBindGroupDescriptor){ + .layout = bind_group_layout, + .bindings = + &(WGPUBindGroupBinding){ + .binding = 0, + .resource = resource + }, + .bindings_length = BINDINGS_LENGTH + } + ); + + WGPUBindGroupLayoutId bind_group_layouts[BIND_GROUP_LAYOUTS_LENGTH] = { + bind_group_layout + }; + + WGPUPipelineLayoutId pipeline_layout = + wgpu_device_create_pipeline_layout(device, + &(WGPUPipelineLayoutDescriptor){ + .bind_group_layouts = bind_group_layouts, + .bind_group_layouts_length = BIND_GROUP_LAYOUTS_LENGTH + }); + + WGPUShaderModuleId shader_module = wgpu_device_create_shader_module(device, + &(WGPUShaderModuleDescriptor){ + .code = read_file("./../../data/collatz.comp.spv") + } + ); + + WGPUComputePipelineId compute_pipeline = + wgpu_device_create_compute_pipeline(device, + &(WGPUComputePipelineDescriptor){ + .layout = pipeline_layout, + .compute_stage = (WGPUPipelineStageDescriptor){ + .module = shader_module, + .entry_point = "main" + } + } + ); + + WGPUCommandEncoderId encoder = wgpu_device_create_command_encoder( + device, &(WGPUCommandEncoderDescriptor){ + .todo = 0 + } + ); + + wgpu_command_buffer_copy_buffer_to_buffer( + encoder, staging_buffer, 0, storage_buffer, 0, size); + + WGPUComputePassId command_pass = + wgpu_command_encoder_begin_compute_pass(encoder); + wgpu_compute_pass_set_pipeline(command_pass, compute_pipeline); + + wgpu_compute_pass_set_bind_group(command_pass, 0, bind_group, NULL, 0); + wgpu_compute_pass_dispatch(command_pass, numbers_length, 1, 1); + wgpu_compute_pass_end_pass(command_pass); + + wgpu_command_buffer_copy_buffer_to_buffer( + encoder, storage_buffer, 0, staging_buffer, 0, size); + + WGPUQueueId queue = wgpu_device_get_queue(device); + + WGPUCommandBufferId command_buffer = wgpu_command_encoder_finish(encoder); + + wgpu_queue_submit(queue, &command_buffer, 1); + + wgpu_buffer_map_read_async(staging_buffer, 0, size, read_buffer_map, NULL); + + wgpu_device_poll(device, true); + + return 0; +} \ No newline at end of file diff --git a/examples/data/hello_triangle.frag b/examples/data/triangle.frag similarity index 100% rename from examples/data/hello_triangle.frag rename to examples/data/triangle.frag diff --git a/examples/data/hello_triangle.frag.spv b/examples/data/triangle.frag.spv similarity index 100% rename from examples/data/hello_triangle.frag.spv rename to examples/data/triangle.frag.spv diff --git a/examples/data/hello_triangle.vert b/examples/data/triangle.vert similarity index 100% rename from examples/data/hello_triangle.vert rename to examples/data/triangle.vert diff --git a/examples/data/hello_triangle.vert.spv b/examples/data/triangle.vert.spv similarity index 100% rename from examples/data/hello_triangle.vert.spv rename to examples/data/triangle.vert.spv diff --git a/examples/hello_remote_c/CMakeLists.txt b/examples/remote/CMakeLists.txt similarity index 71% rename from examples/hello_remote_c/CMakeLists.txt rename to examples/remote/CMakeLists.txt index 035845275b..39c57a043a 100644 --- a/examples/hello_remote_c/CMakeLists.txt +++ b/examples/remote/CMakeLists.txt @@ -1,10 +1,10 @@ cmake_minimum_required(VERSION 3.11b) -project(hello_remote) +project(remote) -set(TARGET_NAME hello_remote) +set(TARGET_NAME remote) -add_executable(hello_remote main.c) +add_executable(remote main.c) find_package(glfw3) diff --git a/examples/hello_remote_c/main.c b/examples/remote/main.c similarity index 100% rename from examples/hello_remote_c/main.c rename to examples/remote/main.c diff --git a/examples/triangle/CMakeLists.txt b/examples/triangle/CMakeLists.txt new file mode 100644 index 0000000000..44b211b426 --- /dev/null +++ b/examples/triangle/CMakeLists.txt @@ -0,0 +1,51 @@ +cmake_minimum_required(VERSION 3.11b) + +set(BACKEND_VULKAN "vulkan") +set(BACKEND_METAL "metal") +set(BACKEND_DX11 "dx11") +set(BACKEND_DX12 "dx12") +set(AVAILABLE_BACKENDS + ${BACKEND_VULKAN} + ${BACKEND_METAL} + ${BACKEND_DX11} + ${BACKEND_DX12}) + +if(NOT DEFINED BACKEND OR NOT "${BACKEND}" IN_LIST AVAILABLE_BACKENDS) + message(FATAL_ERROR "BACKEND invalid or undefined, available backends: ${AVAILABLE_BACKENDS}") +endif() + +project(triangle) + +set(TARGET_NAME triangle) + +add_executable(triangle main.c) + +if(MSVC) + add_definitions(-DWGPU_TARGET=WGPU_TARGET_WINDOWS) + target_compile_options(${TARGET_NAME} PRIVATE /W4) + set(OS_LIBRARIES "userenv" "ws2_32" "Dwmapi" "dbghelp") + if("${BACKEND}" STREQUAL "${BACKEND_DX11}") + list(APPEND OS_LIBRARIES "d3dcompiler" "D3D11" "DXGI") + elseif("${BACKEND}" STREQUAL "${BACKEND_DX12}") + list(APPEND OS_LIBRARIES "d3dcompiler" "D3D12" "DXGI") + endif() +elseif(APPLE) + add_definitions(-DWGPU_TARGET=WGPU_TARGET_MACOS) + set(OS_LIBRARIES "-framework Cocoa" "-framework CoreVideo" "-framework IOKit" "-framework QuartzCore") + target_compile_options(${TARGET_NAME} PRIVATE -x objective-c) +else(MSVC) + add_definitions(-DWGPU_TARGET=WGPU_TARGET_LINUX) + target_compile_options(${TARGET_NAME} PRIVATE -Wall -Wextra -pedantic) +endif(MSVC) + +find_package(glfw3 3.3 REQUIRED + HINTS "$ENV{GLFW3_INSTALL_DIR}" +) + +find_library(WGPU_LIBRARY wgpu_native + HINTS "${CMAKE_CURRENT_SOURCE_DIR}/../../target/debug" +) + +target_include_directories(${TARGET_NAME} PUBLIC $ENV{GLFW3_INCLUDE_DIR}) + +target_link_libraries(${TARGET_NAME} glfw ${WGPU_LIBRARY} ${OS_LIBRARIES}) \ No newline at end of file diff --git a/examples/hello_triangle_c/main.c b/examples/triangle/main.c similarity index 98% rename from examples/hello_triangle_c/main.c rename to examples/triangle/main.c index 32f0e06bf5..de9ac8075d 100644 --- a/examples/hello_triangle_c/main.c +++ b/examples/triangle/main.c @@ -59,13 +59,13 @@ int main() { WGPUShaderModuleId vertex_shader = wgpu_device_create_shader_module(device, &(WGPUShaderModuleDescriptor){ - .code = read_file("./../../data/hello_triangle.vert.spv"), + .code = read_file("./../../data/triangle.vert.spv"), }); WGPUShaderModuleId fragment_shader = wgpu_device_create_shader_module(device, &(WGPUShaderModuleDescriptor){ - .code = read_file("./../../data/hello_triangle.frag.spv"), + .code = read_file("./../../data/triangle.frag.spv"), }); WGPUBindGroupLayoutId bind_group_layout = From 842809bc0bf594aac1d56ac8bec1170852e327bb Mon Sep 17 00:00:00 2001 From: Timo de Kort Date: Sat, 27 Jul 2019 12:54:31 +0200 Subject: [PATCH 2/2] add framework files --- README.md | 15 ++++- examples/compute/CMakeLists.txt | 6 +- examples/compute/main.c | 104 +++++++++---------------------- examples/framework.c | 35 +++++++++++ examples/framework.h | 11 ++++ examples/triangle/CMakeLists.txt | 6 +- examples/triangle/main.c | 21 ++----- 7 files changed, 105 insertions(+), 93 deletions(-) create mode 100644 examples/framework.c create mode 100644 examples/framework.h diff --git a/README.md b/README.md index e4aa84259c..768c6c05ce 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,20 @@ Supported platforms: ## Usage -This repository contains C-language examples that link to the native library targets and perform basic rendering and computation. The prerequisites are a C compiler and GLFW 3 for running the examples. +This repository contains C-language examples that link to the native library targets and perform basic rendering and computation. + +### Prerequisites + - C compiler + - GLFW 3 + - Rust nightly toolchain + ```bash + rustup toolchain install nightly + ``` + - [Cbindgen](https://github.com/eqrion/cbindgen) + ```bash + cargo install cbindgen + ``` + ### Running an example The examples are located under the [examples](examples) directory. We are using a [Makefile](Makefile) for running the examples. diff --git a/examples/compute/CMakeLists.txt b/examples/compute/CMakeLists.txt index 2a64186e6c..e8558c7747 100644 --- a/examples/compute/CMakeLists.txt +++ b/examples/compute/CMakeLists.txt @@ -18,7 +18,7 @@ project(compute) set(TARGET_NAME compute) -add_executable(compute main.c) +add_executable(compute main.c ../framework.c) if(MSVC) add_definitions(-DWGPU_TARGET=WGPU_TARGET_WINDOWS) @@ -47,5 +47,7 @@ find_library(WGPU_LIBRARY wgpu_native ) target_include_directories(${TARGET_NAME} PUBLIC $ENV{GLFW3_INCLUDE_DIR}) +target_include_directories(${TARGET_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../ffi) +target_include_directories(${TARGET_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../) -target_link_libraries(${TARGET_NAME} glfw ${WGPU_LIBRARY} ${OS_LIBRARIES}) \ No newline at end of file +target_link_libraries(${TARGET_NAME} glfw ${WGPU_LIBRARY} ${OS_LIBRARIES}) diff --git a/examples/compute/main.c b/examples/compute/main.c index c1023ddb73..09740c47b7 100644 --- a/examples/compute/main.c +++ b/examples/compute/main.c @@ -1,43 +1,22 @@ -#include "./../../ffi/wgpu.h" +#ifndef WGPU_H +#define WGPU_H +#include "wgpu.h" +#endif + +#include "framework.h" + #include #include #define BINDINGS_LENGTH (1) #define BIND_GROUP_LAYOUTS_LENGTH (1) -WGPUByteArray read_file(const char *name) { - FILE *file = fopen(name, "rb"); - fseek(file, 0, SEEK_END); - long length = ftell(file); - unsigned char *bytes = malloc(length); - fseek(file, 0, SEEK_SET); - fread(bytes, 1, length, file); - fclose(file); - return (WGPUByteArray){ - .bytes = bytes, - .length = length, - }; -} - -void read_buffer_map( - WGPUBufferMapAsyncStatus status, - const uint8_t *data, - uint8_t *userdata) { - if (status == WGPUBufferMapAsyncStatus_Success) { - uint32_t *times = (uint32_t *) data; - printf("Times: [%d, %d, %d, %d]", - times[0], - times[1], - times[2], - times[3]); - } -} - int main( int argc, char *argv[]) { if (argc != 5) { + printf("You must pass 4 positive integers!"); return 0; } @@ -61,18 +40,15 @@ int main( WGPUDeviceId device = wgpu_adapter_request_device(adapter, &(WGPUDeviceDescriptor){ - .extensions = { - .anisotropic_filtering = false, - }, + .extensions = NULL }); uint8_t *staging_memory; WGPUBufferId staging_buffer = wgpu_device_create_buffer_mapped(device, - &(WGPUBufferDescriptor){ - .size = size, - .usage = WGPUBufferUsage_MAP_READ | WGPUBufferUsage_TRANSFER_DST | - WGPUBufferUsage_TRANSFER_SRC}, + &(WGPUBufferDescriptor){ + .size = size, + .usage = WGPUBufferUsage_MAP_READ}, &staging_memory); memcpy((uint32_t *) staging_memory, numbers, size); @@ -82,8 +58,7 @@ int main( WGPUBufferId storage_buffer = wgpu_device_create_buffer(device, &(WGPUBufferDescriptor){ .size = size, - .usage = WGPUBufferUsage_STORAGE | WGPUBufferUsage_TRANSFER_DST | - WGPUBufferUsage_TRANSFER_SRC}); + .usage = WGPUBufferUsage_STORAGE}); WGPUBindGroupLayoutId bind_group_layout = wgpu_device_create_bind_group_layout(device, @@ -91,49 +66,35 @@ int main( .bindings = &(WGPUBindGroupLayoutBinding){ .binding = 0, .visibility = WGPUShaderStage_COMPUTE, - .ty = WGPUBindingType_StorageBuffer - }, - .bindings_length = BINDINGS_LENGTH - } - ); + .ty = WGPUBindingType_StorageBuffer}, + .bindings_length = BINDINGS_LENGTH}); WGPUBindingResource resource = { - .tag = WGPUBindingResource_Buffer, + .tag = WGPUBindingResource_Buffer, .buffer = (WGPUBufferBinding){ - .buffer = storage_buffer, + .buffer = storage_buffer, .size = size, - .offset = 0 - } - }; + .offset = 0}}; WGPUBindGroupId bind_group = wgpu_device_create_bind_group(device, - &(WGPUBindGroupDescriptor){ - .layout = bind_group_layout, - .bindings = - &(WGPUBindGroupBinding){ - .binding = 0, - .resource = resource - }, - .bindings_length = BINDINGS_LENGTH - } - ); + &(WGPUBindGroupDescriptor){.layout = bind_group_layout, + .bindings = &(WGPUBindGroupBinding){ + .binding = 0, + .resource = resource}, + .bindings_length = BINDINGS_LENGTH}); WGPUBindGroupLayoutId bind_group_layouts[BIND_GROUP_LAYOUTS_LENGTH] = { - bind_group_layout - }; + bind_group_layout}; WGPUPipelineLayoutId pipeline_layout = - wgpu_device_create_pipeline_layout(device, - &(WGPUPipelineLayoutDescriptor){ - .bind_group_layouts = bind_group_layouts, - .bind_group_layouts_length = BIND_GROUP_LAYOUTS_LENGTH - }); + wgpu_device_create_pipeline_layout(device, + &(WGPUPipelineLayoutDescriptor){ + .bind_group_layouts = bind_group_layouts, + .bind_group_layouts_length = BIND_GROUP_LAYOUTS_LENGTH}); WGPUShaderModuleId shader_module = wgpu_device_create_shader_module(device, &(WGPUShaderModuleDescriptor){ - .code = read_file("./../../data/collatz.comp.spv") - } - ); + .code = read_file("./../../data/collatz.comp.spv")}); WGPUComputePipelineId compute_pipeline = wgpu_device_create_compute_pipeline(device, @@ -142,15 +103,12 @@ int main( .compute_stage = (WGPUPipelineStageDescriptor){ .module = shader_module, .entry_point = "main" - } - } - ); + }}); WGPUCommandEncoderId encoder = wgpu_device_create_command_encoder( device, &(WGPUCommandEncoderDescriptor){ .todo = 0 - } - ); + }); wgpu_command_buffer_copy_buffer_to_buffer( encoder, staging_buffer, 0, storage_buffer, 0, size); diff --git a/examples/framework.c b/examples/framework.c new file mode 100644 index 0000000000..58096b3059 --- /dev/null +++ b/examples/framework.c @@ -0,0 +1,35 @@ +#ifndef WGPU_H +#define WGPU_H +#include "wgpu.h" +#endif + +#include +#include + +WGPUByteArray read_file(const char *name) { + FILE *file = fopen(name, "rb"); + fseek(file, 0, SEEK_END); + long length = ftell(file); + unsigned char *bytes = malloc(length); + fseek(file, 0, SEEK_SET); + fread(bytes, 1, length, file); + fclose(file); + return (WGPUByteArray){ + .bytes = bytes, + .length = length, + }; +} + +void read_buffer_map( + WGPUBufferMapAsyncStatus status, + const uint8_t *data, + uint8_t *userdata) { + if (status == WGPUBufferMapAsyncStatus_Success) { + uint32_t *times = (uint32_t *) data; + printf("Times: [%d, %d, %d, %d]", + times[0], + times[1], + times[2], + times[3]); + } +} diff --git a/examples/framework.h b/examples/framework.h new file mode 100644 index 0000000000..6130df3109 --- /dev/null +++ b/examples/framework.h @@ -0,0 +1,11 @@ +#ifndef WGPU_H +#define WGPU_H +#include "wgpu.h" +#endif + +WGPUByteArray read_file(const char *name); + +void read_buffer_map( + WGPUBufferMapAsyncStatus status, + const uint8_t *data, + uint8_t *userdata); diff --git a/examples/triangle/CMakeLists.txt b/examples/triangle/CMakeLists.txt index 44b211b426..0cc07c3707 100644 --- a/examples/triangle/CMakeLists.txt +++ b/examples/triangle/CMakeLists.txt @@ -18,7 +18,7 @@ project(triangle) set(TARGET_NAME triangle) -add_executable(triangle main.c) +add_executable(triangle main.c ../framework.c) if(MSVC) add_definitions(-DWGPU_TARGET=WGPU_TARGET_WINDOWS) @@ -47,5 +47,7 @@ find_library(WGPU_LIBRARY wgpu_native ) target_include_directories(${TARGET_NAME} PUBLIC $ENV{GLFW3_INCLUDE_DIR}) +target_include_directories(${TARGET_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../ffi) +target_include_directories(${TARGET_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../) -target_link_libraries(${TARGET_NAME} glfw ${WGPU_LIBRARY} ${OS_LIBRARIES}) \ No newline at end of file +target_link_libraries(${TARGET_NAME} glfw ${WGPU_LIBRARY} ${OS_LIBRARIES}) diff --git a/examples/triangle/main.c b/examples/triangle/main.c index de9ac8075d..2b7eea6e1b 100644 --- a/examples/triangle/main.c +++ b/examples/triangle/main.c @@ -1,4 +1,9 @@ -#include "./../../ffi/wgpu.h" +#ifndef WGPU_H +#define WGPU_H +#include "wgpu.h" +#endif + +#include "framework.h" #include #include @@ -27,20 +32,6 @@ #define RENDER_PASS_ATTACHMENTS_LENGTH (1) #define BIND_GROUP_LAYOUTS_LENGTH (1) -WGPUByteArray read_file(const char *name) { - FILE *file = fopen(name, "rb"); - fseek(file, 0, SEEK_END); - long length = ftell(file); - unsigned char *bytes = malloc(length); - fseek(file, 0, SEEK_SET); - fread(bytes, 1, length, file); - fclose(file); - return (WGPUByteArray){ - .bytes = bytes, - .length = length, - }; -} - int main() { WGPUInstanceId instance = wgpu_create_instance();