diff options
author | BoredGuy <osome3717@gmail.com> | 2025-09-22 10:02:53 +0300 |
---|---|---|
committer | BoredGuy <osome3717@gmail.com> | 2025-09-22 10:02:53 +0300 |
commit | 141287e361f45f47cdf93aecf0b2d93620c01020 (patch) | |
tree | 439d43f17b6eed02abfbed49b56cfe46748e18db |
Initial Commit
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | CMakeLists.txt | 20 | ||||
-rw-r--r-- | src/main.c | 217 |
3 files changed, 238 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..378eac2 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +build diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..4eae662 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 3.15) +project("Hole In 321" VERSION 1.0.0 LANGUAGES C CXX) + +set(CMAKE_C_STANDARD 11) +set(CMAKE_C_STANDARD_REQUIRED ON) + +find_package(Threads REQUIRED) +find_package(SDL3 REQUIRED) +find_package(Dawn REQUIRED) + +add_executable(game + "src/main.c" +) + +target_link_libraries(game SDL3::SDL3 dawn::webgpu_dawn) + +if (UNIX) + target_compile_options(game PRIVATE "-g") + target_link_libraries(game m) +endif() diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..dd0876f --- /dev/null +++ b/src/main.c @@ -0,0 +1,217 @@ +#include <webgpu/webgpu.h> +#include <SDL3/SDL.h> +#include <stdbool.h> +#include <string.h> +#include <stdlib.h> +#include <inttypes.h> + +#include <X11/Xlib.h> + +typedef struct { + SDL_Window* window; + + WGPUInstance instance; + WGPUSurface surface; + WGPUAdapter adapter; + WGPUDevice device; + WGPUQueue queue; +} demo; + +void init_demo(demo* demo); +void free_demo(demo* demo); + +int main() { + demo demo = {0}; + init_demo(&demo); + + SDL_Event e; + bool running = true; + + while (running) { + while (SDL_PollEvent(&e)) { + if (e.type == SDL_EVENT_QUIT) { + running = false; + } + } + + WGPUSurfaceTexture screenTexture; + wgpuSurfaceGetCurrentTexture(demo.surface, &screenTexture); + + WGPUTextureView screenView = + wgpuTextureCreateView(screenTexture.texture, NULL); + + WGPUCommandEncoder encoder = + wgpuDeviceCreateCommandEncoder(demo.device, &(const WGPUCommandEncoderDescriptor){ + .label = {NULL, WGPU_STRLEN} + }); + + WGPURenderPassEncoder renderPass = + wgpuCommandEncoderBeginRenderPass(encoder, &(const WGPURenderPassDescriptor){ + .label = {NULL, WGPU_STRLEN}, + .colorAttachmentCount = 1, + .colorAttachments = &(const WGPURenderPassColorAttachment) { + .view = screenView, + .resolveTarget = NULL, + .depthSlice = WGPU_DEPTH_SLICE_UNDEFINED, + + .loadOp = WGPULoadOp_Clear, + .storeOp = WGPUStoreOp_Store, + .clearValue = (WGPUColor) { + .r = 0.1, + .g = 0.2, + .b = 0.3, + .a = 1.0 + } + } + }); + + wgpuRenderPassEncoderEnd(renderPass); + wgpuRenderPassEncoderRelease(renderPass); + + WGPUCommandBuffer drawCommands = wgpuCommandEncoderFinish(encoder, NULL); + wgpuQueueSubmit(demo.queue, 1, &drawCommands); + wgpuSurfacePresent(demo.surface); + + wgpuCommandBufferRelease(drawCommands); + wgpuCommandEncoderRelease(encoder); + wgpuTextureViewRelease(screenView); + wgpuTextureRelease(screenTexture.texture); + } + + free_demo(&demo); + SDL_Quit(); + return 0; +} + +void handle_adapter_request +( + WGPURequestAdapterStatus status, + WGPUAdapter adapter, + WGPUStringView message, + void* userdata, + void* + ) { + demo* demo = userdata; + + if (status != WGPURequestAdapterStatus_Success) { + SDL_Log("Failed to retreive wgpu adapter, error: %s, exitting!", message.data); + exit(EXIT_FAILURE); + } + + demo->adapter = adapter; +} + +void handle_device_request +( + WGPURequestDeviceStatus status, + WGPUDevice device, + WGPUStringView message, + void* userdata, + void* + ) { + demo* demo = userdata; + + if (status != WGPURequestDeviceStatus_Success) { + SDL_Log("Failed to retreive wgpu device, error: %s, exitting!", message.data); + exit(EXIT_FAILURE); + } + + demo->device = device; +} + +void uncaptured_error_callback +( + WGPUDevice const*, + WGPUErrorType, + WGPUStringView message, + void*, void* +) { + SDL_Log("Graphics Error: %s\n", message.data); +} + +void init_demo(demo* demo) { + demo->window = + SDL_CreateWindow("WGPU Test", 800, 600, 0); + + demo->instance = wgpuCreateInstance(&(const WGPUInstanceDescriptor){ + .requiredFeatureCount = 1, + .requiredFeatures = (WGPUInstanceFeatureName[]){ + WGPUInstanceFeatureName_TimedWaitAny + } + }); + SDL_assert(demo->instance); + +#if defined(SDL_PLATFORM_LINUX) + if (strcmp(SDL_GetCurrentVideoDriver(), "x11") == 0) { + Display* xdisplay = + (Display*)SDL_GetPointerProperty(SDL_GetWindowProperties(demo->window), SDL_PROP_WINDOW_X11_DISPLAY_POINTER, NULL); + Window xwindow = + (Window)SDL_GetNumberProperty(SDL_GetWindowProperties(demo->window), SDL_PROP_WINDOW_X11_WINDOW_NUMBER, 0); + + if (xdisplay && xwindow) { + demo->surface = + wgpuInstanceCreateSurface(demo->instance, &(const WGPUSurfaceDescriptor){ + .nextInChain = (WGPUChainedStruct*)&(WGPUSurfaceSourceXlibWindow) { + .chain = (WGPUChainedStruct) { + .next = NULL, + .sType = WGPUSType_SurfaceSourceXlibWindow + }, + + .display = xdisplay, + .window = xwindow + } + }); + } + } +#endif + SDL_assert(demo->surface); + + WGPUFuture adapterFuture = + wgpuInstanceRequestAdapter(demo->instance, &(const WGPURequestAdapterOptions){ + .compatibleSurface = demo->surface, + .powerPreference = WGPUPowerPreference_LowPower + }, (WGPURequestAdapterCallbackInfo){ + .callback = handle_adapter_request, + .mode = WGPUCallbackMode_WaitAnyOnly, + .userdata1 = demo + }); + + wgpuInstanceWaitAny(demo->instance, 1, &(WGPUFutureWaitInfo){adapterFuture, false}, INT64_MAX); + SDL_assert(demo->adapter); + + WGPUFuture deviceFuture = + wgpuAdapterRequestDevice(demo->adapter, &(const WGPUDeviceDescriptor){ + .label = {"RTX 2070", WGPU_STRLEN}, + .uncapturedErrorCallbackInfo = { .callback = uncaptured_error_callback } + }, (WGPURequestDeviceCallbackInfo){ + .callback = handle_device_request, + .mode = WGPUCallbackMode_WaitAnyOnly, + .userdata1 = demo + }); + + wgpuInstanceWaitAny(demo->instance, 1, &(WGPUFutureWaitInfo){deviceFuture, false}, INT64_MAX); + SDL_assert(demo->device); + + WGPUSurfaceCapabilities caps; + wgpuSurfaceGetCapabilities(demo->surface, demo->adapter, &caps); + + WGPUSurfaceConfiguration config = (WGPUSurfaceConfiguration) { + .device = demo->device, + .format = caps.formats[0], + .usage = WGPUTextureUsage_RenderAttachment, + .width = 800, + .height = 600, + .presentMode = WGPUPresentMode_Fifo, + .alphaMode = caps.alphaModes[0] + }; + wgpuSurfaceConfigure(demo->surface, &config); + + demo->queue = wgpuDeviceGetQueue(demo->device); +} + +void free_demo(demo* demo) { + wgpuAdapterRelease(demo->adapter); + wgpuSurfaceRelease(demo->surface); + wgpuInstanceRelease(demo->instance); + SDL_DestroyWindow(demo->window); +} |