diff --git a/CMakeLists.txt b/CMakeLists.txt index 8ca2f08..7c267a0 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -84,7 +84,6 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL "Emscripten") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g3 -O0") set(ENABLE_WEB TRUE) - set(ENABLE_WEBGPU TRUE) set(NEEDS_HOSTED_SHADER_COMPILER TRUE) endif() @@ -103,10 +102,6 @@ if(ENABLE_DX12) list(APPEND SHADER_LANGUAGES "hlsl") endif() -if(ENABLE_WEBGPU) - list(APPEND SHADER_LANGUAGES "wgsl") -endif() - if(ENABLE_METAL) list(APPEND SHADER_LANGUAGES "msl") endif() diff --git a/engine/gfx/CMakeLists.txt b/engine/gfx/CMakeLists.txt index 4ab028d..37ad782 100755 --- a/engine/gfx/CMakeLists.txt +++ b/engine/gfx/CMakeLists.txt @@ -29,8 +29,4 @@ endif() if(ENABLE_VULKAN) add_subdirectory(vulkan) -endif() - -if(ENABLE_WEBGPU) - add_subdirectory(webgpu) endif() \ No newline at end of file diff --git a/engine/gfx/webgpu/CMakeLists.txt b/engine/gfx/webgpu/CMakeLists.txt deleted file mode 100755 index 8e15c3e..0000000 --- a/engine/gfx/webgpu/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -set(HEADERS - include/gfx_webgpu.hpp - src/gfx_webgpu_buffer.hpp - src/gfx_webgpu_pipeline.hpp - src/gfx_webgpu_texture.hpp - src/gfx_webgpu_framebuffer.hpp - src/gfx_webgpu_renderpass.hpp - src/gfx_webgpu_commandbuffer.hpp) - -add_library(GFXWebGPU STATIC - src/gfx_webgpu.cpp - ${HEADERS}) -target_include_directories(GFXWebGPU PUBLIC include PRIVATE src) -target_link_libraries(GFXWebGPU PUBLIC GFX) \ No newline at end of file diff --git a/engine/gfx/webgpu/include/gfx_webgpu.hpp b/engine/gfx/webgpu/include/gfx_webgpu.hpp deleted file mode 100755 index 7a5a9ee..0000000 --- a/engine/gfx/webgpu/include/gfx_webgpu.hpp +++ /dev/null @@ -1,66 +0,0 @@ -#pragma once - -#include - -#include "gfx.hpp" - -class GFXWebGPUPipeline; - -class GFXWebGPU : public GFX { -public: - bool initialize(const GFXCreateInfo& createInfo) override; - - ShaderLanguage accepted_shader_language() override; - const char* get_name() override; - - // buffer - GFXBuffer* create_buffer(void* data, GFXSize size, bool is_dynamic, GFXBufferUsage usage) override; - void copy_buffer(GFXBuffer* buffer, void* data, GFXSize offset, GFXSize size) override; - - void* get_buffer_contents(GFXBuffer* buffer) override; - void release_buffer_contents(GFXBuffer* buffer, void* handle) override; - - // texture - GFXTexture* create_texture(const GFXTextureCreateInfo& info) override; - void copy_texture(GFXTexture* texture, void* data, GFXSize size) override; - void copy_texture(GFXTexture* from, GFXTexture* to) override; - void copy_texture(GFXTexture* from, GFXBuffer* to) override; - - // sampler - GFXSampler* create_sampler(const GFXSamplerCreateInfo& info) override; - - // framebuffer - GFXFramebuffer* create_framebuffer(const GFXFramebufferCreateInfo& info) override; - - // render pass - GFXRenderPass* create_render_pass(const GFXRenderPassCreateInfo& info) override; - - // pipeline - GFXPipeline* create_graphics_pipeline(const GFXGraphicsPipelineCreateInfo& info) override; - GFXPipeline* create_compute_pipeline(const GFXComputePipelineCreateInfo& info) override; - - GFXCommandBuffer* acquire_command_buffer(bool for_presentation_use) override; - - void submit(GFXCommandBuffer* command_buffer, platform::window_ptr window) override; - -private: - WGPUSwapChain create_swapchain(); - WGPUShaderModule create_shader(const uint32_t* code, uint32_t size, std::string_view label); - - uint64_t get_bind_group_hash(GFXWebGPUPipeline* pipeline); - void cache_bind_group_state(GFXWebGPUPipeline* pipeline, WGPUBindGroupLayout group_layout); - void reset_bind_state(); - - WGPUDevice device; - WGPUQueue queue; - WGPUSwapChain swapchain; - - struct BoundShaderBuffer { - GFXBuffer* buffer = nullptr; - uint32_t size = 0, offset = 0; - }; - - std::array boundShaderBuffers; - std::array boundTextures; - std::array boundSamplers; -}; diff --git a/engine/gfx/webgpu/src/gfx_webgpu.cpp b/engine/gfx/webgpu/src/gfx_webgpu.cpp deleted file mode 100755 index f24d269..0000000 --- a/engine/gfx/webgpu/src/gfx_webgpu.cpp +++ /dev/null @@ -1,894 +0,0 @@ -#include "gfx_webgpu.hpp" - -#include "gfx_commandbuffer.hpp" -#include "gfx_webgpu_buffer.hpp" -#include "gfx_webgpu_commandbuffer.hpp" -#include "gfx_webgpu_framebuffer.hpp" -#include "gfx_webgpu_pipeline.hpp" -#include "gfx_webgpu_renderpass.hpp" -#include "gfx_webgpu_sampler.hpp" -#include "gfx_webgpu_texture.hpp" -#include "utility.hpp" - -WGPUTextureFormat toPixFormat(GFXPixelFormat format) { - switch (format) { - case GFXPixelFormat::R_32F: - return WGPUTextureFormat_R32Float; - - case GFXPixelFormat::R_16F: - return WGPUTextureFormat_R16Float; - - case GFXPixelFormat::RGBA_32F: - return WGPUTextureFormat_RGBA32Float; - - case GFXPixelFormat::RGBA8_UNORM: - return WGPUTextureFormat_RGBA8Unorm; - - case GFXPixelFormat::R8_UNORM: - return WGPUTextureFormat_R8Unorm; - - case GFXPixelFormat::R8G8_UNORM: - return WGPUTextureFormat_RG8Unorm; - - case GFXPixelFormat::R8G8_SFLOAT: - return WGPUTextureFormat_RG16Float; - - case GFXPixelFormat::R8G8B8A8_UNORM: - return WGPUTextureFormat_RGBA8Unorm; - - case GFXPixelFormat::R16G16B16A16_SFLOAT: - return WGPUTextureFormat_RGBA16Float; - - case GFXPixelFormat::DEPTH_32F: - return WGPUTextureFormat_Depth32Float; - } - - return WGPUTextureFormat_Undefined; -} - -WGPUVertexFormat toVertFormat(GFXVertexFormat format) { - switch (format) { - case GFXVertexFormat::FLOAT2: - return WGPUVertexFormat_Float32x2; - case GFXVertexFormat::FLOAT3: - return WGPUVertexFormat_Float32x3; - case GFXVertexFormat::FLOAT4: - return WGPUVertexFormat_Float32x4; - case GFXVertexFormat::INT: - return WGPUVertexFormat_Sint32; - case GFXVertexFormat::INT4: - return WGPUVertexFormat_Sint32x4; - case GFXVertexFormat::UNORM4: - return WGPUVertexFormat_Unorm8x4; - } - - return WGPUVertexFormat_Undefined; -} - -WGPUBlendFactor toFactor(GFXBlendFactor factor) { - switch (factor) { - case GFXBlendFactor::Zero: - return WGPUBlendFactor_Zero; - case GFXBlendFactor::One: - return WGPUBlendFactor_One; - case GFXBlendFactor::OneMinusSrcAlpha: - return WGPUBlendFactor_OneMinusSrcAlpha; - case GFXBlendFactor::OneMinusSrcColor: - return WGPUBlendFactor_OneMinusSrc; - case GFXBlendFactor::SrcAlpha: - return WGPUBlendFactor_SrcAlpha; - case GFXBlendFactor::DstAlpha: - return WGPUBlendFactor_DstAlpha; - case GFXBlendFactor::SrcColor: - return WGPUBlendFactor_Src; - case GFXBlendFactor::DstColor: - return WGPUBlendFactor_Dst; - } - - return WGPUBlendFactor_One; -} - -WGPUAddressMode toSamplerMode(SamplingMode mode) { - switch (mode) { - case SamplingMode::Repeat: - return WGPUAddressMode_Repeat; - case SamplingMode::ClampToEdge: - return WGPUAddressMode_ClampToEdge; - } - - return WGPUAddressMode_Repeat; -} - -WGPUFilterMode toFilter(GFXFilter filter) { - switch (filter) { - case GFXFilter::Nearest: - return WGPUFilterMode_Nearest; - case GFXFilter::Linear: - return WGPUFilterMode_Linear; - } - - return WGPUFilterMode_Linear; -} - -WGPUCompareFunction toCompareFunc(GFXCompareFunction func) { - switch (func) { - case GFXCompareFunction::Never: - return WGPUCompareFunction_Never; - case GFXCompareFunction::Less: - return WGPUCompareFunction_Less; - case GFXCompareFunction::Equal: - return WGPUCompareFunction_Equal; - case GFXCompareFunction::LessOrEqual: - return WGPUCompareFunction_LessEqual; - case GFXCompareFunction::Greater: - return WGPUCompareFunction_Greater; - case GFXCompareFunction::NotEqual: - return WGPUCompareFunction_NotEqual; - case GFXCompareFunction::GreaterOrEqual: - return WGPUCompareFunction_GreaterEqual; - case GFXCompareFunction::Always: - return WGPUCompareFunction_Always; - } -} - -WGPUShaderModule GFXWebGPU::create_shader(const uint32_t* code, const uint32_t size, std::string_view label) { - WGPUShaderModuleSPIRVDescriptor spirv = {}; - spirv.chain.sType = WGPUSType_ShaderModuleSPIRVDescriptor; - spirv.codeSize = size / sizeof(uint32_t); - spirv.code = code; - - WGPUShaderModuleDescriptor desc = {}; - desc.nextInChain = reinterpret_cast(&spirv); - desc.label = label.data(); - - return wgpuDeviceCreateShaderModule(device, &desc); -} - -WGPUSwapChain GFXWebGPU::create_swapchain() { - WGPUSurfaceDescriptorFromCanvasHTMLSelector canvDesc = {}; - canvDesc.chain.sType = WGPUSType_SurfaceDescriptorFromCanvasHTMLSelector; - canvDesc.selector = "canvas"; - - WGPUSurfaceDescriptor surfDesc = {}; - surfDesc.nextInChain = reinterpret_cast(&canvDesc); - - WGPUSurface surface = wgpuInstanceCreateSurface(nullptr, &surfDesc); - - WGPUSwapChainDescriptor swapDesc = {}; - swapDesc.usage = WGPUTextureUsage_RenderAttachment; - swapDesc.format = WGPUTextureFormat_BGRA8Unorm; - swapDesc.width = 800; // TODO: configurable - swapDesc.height = 450; - swapDesc.presentMode = WGPUPresentMode_Fifo; - - return wgpuDeviceCreateSwapChain(device, surface, &swapDesc); -} - -bool GFXWebGPU::initialize(const GFXCreateInfo& createInfo) { - device = emscripten_webgpu_get_device(); - if(device == nullptr) { - prism::log("Failed to get WebGPU device!"); - } - - queue = wgpuDeviceGetQueue(device); - swapchain = create_swapchain(); - - prism::log("Initialized WebGPU!"); - - return true; -} - -ShaderLanguage GFXWebGPU::accepted_shader_language() { - return ShaderLanguage::WGSL; -} - -const char* GFXWebGPU::get_name() { - return "WebGPU"; -} - -GFXCommandBuffer* GFXWebGPU::acquire_command_buffer(bool for_presentation_use) { - return new GFXCommandBuffer(); -} - -GFXBuffer* GFXWebGPU::create_buffer(void* data, const GFXSize size, const bool is_dynamic, const GFXBufferUsage usage) { - auto buffer = new GFXWebGPUBuffer(); - - buffer->size = size; - - WGPUBufferDescriptor desc = {}; - desc.usage = WGPUBufferUsage_CopyDst; - desc.size = size; - desc.mappedAtCreation = true; - - buffer->handle = wgpuDeviceCreateBuffer(device, &desc); - - wgpuQueueWriteBuffer(queue, buffer->handle, 0, data, size); - - return buffer; -} - -void GFXWebGPU::copy_buffer(GFXBuffer* buffer, void* data, const GFXSize offset, const GFXSize size) { - auto wgpu_buffer = (GFXWebGPUBuffer*)buffer; - - wgpuQueueWriteBuffer(queue, wgpu_buffer->handle, offset, data, size); -} - -void* GFXWebGPU::get_buffer_contents(GFXBuffer* buffer) { - auto wgpu_buffer = (GFXWebGPUBuffer*)buffer; - - return wgpuBufferGetMappedRange(wgpu_buffer->handle, 0, wgpu_buffer->size); -} - -void GFXWebGPU::release_buffer_contents(GFXBuffer* buffer, void* handle) { - auto wgpu_buffer = (GFXWebGPUBuffer*)buffer; - - wgpuBufferUnmap(wgpu_buffer->handle); -} - -GFXTexture* GFXWebGPU::create_texture(const GFXTextureCreateInfo& info) { - auto texture = new GFXWebGPUTexture(); - - WGPUTextureDescriptor descriptor = {}; - descriptor.size.width = info.width; - descriptor.size.height = info.height; - descriptor.size.depthOrArrayLayers = info.array_length; - - descriptor.dimension = WGPUTextureDimension_2D; - - descriptor.format = WGPUTextureFormat_BGRA8Unorm; - - descriptor.label = info.label.c_str(); - - descriptor.mipLevelCount = info.mip_count; - - descriptor.usage = WGPUTextureUsage_None; - - if((info.usage & GFXTextureUsage::Sampled) == GFXTextureUsage::Sampled) - descriptor.usage |= WGPUTextureUsage_TextureBinding; - - if((info.usage & GFXTextureUsage::Sampled) == GFXTextureUsage::Attachment) - descriptor.usage |= WGPUTextureUsage_RenderAttachment; - - if((info.usage & GFXTextureUsage::Sampled) == GFXTextureUsage::TransferDst) - descriptor.usage |= WGPUTextureUsage_CopyDst; - - if((info.usage & GFXTextureUsage::Sampled) == GFXTextureUsage::TransferSrc) - descriptor.usage |= WGPUTextureUsage_CopySrc; - - if((info.usage & GFXTextureUsage::Storage) == GFXTextureUsage::Storage) - descriptor.usage |= WGPUTextureUsage_StorageBinding; - - texture->handle = wgpuDeviceCreateTexture(device, &descriptor); - - return texture; -} - -void GFXWebGPU::copy_texture(GFXTexture* texture, void* data, GFXSize size) { - GFX::copy_texture(texture, data, size); -} - -void GFXWebGPU::copy_texture(GFXTexture* from, GFXTexture* to) { - GFX::copy_texture(from, to); -} - -void GFXWebGPU::copy_texture(GFXTexture* from, GFXBuffer* to) { - GFX::copy_texture(from, to); -} - -GFXSampler* GFXWebGPU::create_sampler(const GFXSamplerCreateInfo& info) { - auto sampler = new GFXWebGPUSampler(); - - return sampler; -} - -GFXFramebuffer* GFXWebGPU::create_framebuffer(const GFXFramebufferCreateInfo& info) { - auto framebuffer = new GFXWebGPUFramebuffer(); - - return framebuffer; -} - -GFXRenderPass* GFXWebGPU::create_render_pass(const GFXRenderPassCreateInfo& info) { - auto render_pass = new GFXWebGPURenderPass(); - - return render_pass; -} - -GFXPipeline* GFXWebGPU::create_graphics_pipeline(const GFXGraphicsPipelineCreateInfo& info) { - auto pipeline = new GFXWebGPUPipeline(); - - WGPURenderPipelineDescriptor descriptor = {}; - descriptor.label = info.label.c_str(); - - const bool has_vertex_stage = !info.shaders.vertex_src.empty(); - if (has_vertex_stage) { - const bool vertex_use_shader_source = !info.shaders.vertex_src.is_path(); - - if (vertex_use_shader_source) { - auto vertex_shader_vector = info.shaders.vertex_src.as_bytecode(); - - descriptor.vertex.module = create_shader(vertex_shader_vector.data(), vertex_shader_vector.size() * sizeof(uint32_t), std::string(info.label + " vertex stage").c_str()); - } - else { - auto vertex_shader = prism::open_file(prism::internal_domain / (info.shaders.vertex_src.as_path().string() + ".wgsl.spv"), true); - vertex_shader->read_all(); - - descriptor.vertex.module = create_shader(vertex_shader->cast_data(), vertex_shader->size(), info.shaders.vertex_src.as_path().string().c_str()); - } - } - - WGPUFragmentState fragment = {}; - - const bool has_fragment_stage = !info.shaders.fragment_src.empty(); - if (has_fragment_stage) { - descriptor.fragment = &fragment; - - const bool fragment_use_shader_source = !info.shaders.fragment_src.is_path(); - - if (fragment_use_shader_source) { - auto fragment_shader_vector = info.shaders.fragment_src.as_bytecode(); - - fragment.module = create_shader(fragment_shader_vector.data(), fragment_shader_vector.size() * sizeof(uint32_t), std::string(info.label + " fragment stage").c_str()); - } - else { - auto fragment_shader = prism::open_file(prism::internal_domain / (info.shaders.fragment_src.as_path().string() + ".wgsl.spv"), true); - fragment_shader->read_all(); - - fragment.module = create_shader(fragment_shader->cast_data(), fragment_shader->size(), info.shaders.fragment_src.as_path().string().c_str()); - } - } - - prism::log("building pipeline {}", info.label); - prism::log("--------"); - - // alright, webgpu in their infinite wisdom does not allow arbitrary binding locations - // so, to be consistent with what vulkan, metal and virtually every other API allows, - // we will create dummy buffers with no attributes attached. congrats webgpu devs. - int dummy_buffer_count = 0; - for (auto& binding : info.vertex_input.inputs) { - dummy_buffer_count = std::max(binding.location, dummy_buffer_count); - } - dummy_buffer_count += 1; - - std::vector> attributes; - attributes.resize(dummy_buffer_count); - - prism::log("dummy buffer count: {}", dummy_buffer_count); - - for (auto& attribute : info.vertex_input.attributes) { - WGPUVertexAttribute description; - description.shaderLocation = attribute.location; - description.format = toVertFormat(attribute.format); - description.offset = attribute.offset; - - attributes[attribute.binding].push_back(description); - } - - std::vector inputs; - inputs.resize(dummy_buffer_count); - for (auto& binding : info.vertex_input.inputs) { - prism::log("binding loc {}", binding.location); - - WGPUVertexBufferLayout b; - b.attributes = attributes[binding.location].data(); - b.attributeCount = attributes[binding.location].size(); - b.arrayStride = binding.stride; - b.stepMode = WGPUVertexStepMode_Vertex; - - inputs[binding.location] = b; - } - - descriptor.vertex.buffers = inputs.data(); - descriptor.vertex.bufferCount = inputs.size(); - - switch (info.rasterization.culling_mode) { - case GFXCullingMode::Backface: - descriptor.primitive.cullMode = WGPUCullMode_Back; - break; - case GFXCullingMode::Frontface: - descriptor.primitive.cullMode = WGPUCullMode_Front; - break; - case GFXCullingMode::None: - descriptor.primitive.cullMode = WGPUCullMode_None; - } - - switch (info.rasterization.winding_mode) { - case GFXWindingMode::Clockwise: - descriptor.primitive.frontFace = WGPUFrontFace_CW; - break; - case GFXWindingMode::CounterClockwise: - descriptor.primitive.frontFace = WGPUFrontFace_CCW; - break; - } - - descriptor.primitive.stripIndexFormat = WGPUIndexFormat_Uint16; - descriptor.primitive.topology = WGPUPrimitiveTopology_TriangleList; - - // create bind group layout - std::vector group_entries = {}; - for (auto& binding : info.shader_input.bindings) { - // ignore push constants - if (binding.type == GFXBindingType::PushConstant) - continue; - - WGPUBindGroupLayoutEntry entry = {}; - entry.binding = binding.binding; - entry.visibility = WGPUShaderStage_Vertex | WGPUShaderStage_Fragment; - - switch (binding.type) { - case GFXBindingType::StorageBuffer: - { - entry.buffer.type = WGPUBufferBindingType_Uniform; - } - break; - case GFXBindingType::StorageImage: - { - entry.storageTexture.access = WGPUStorageTextureAccess_WriteOnly; - } - break; - case GFXBindingType::SampledImage: - { - entry.texture.sampleType = WGPUTextureSampleType_Force32; - } - break; - case GFXBindingType::Sampler: { - entry.sampler.type = WGPUSamplerBindingType_Comparison; - } - break; - } - - group_entries.push_back(entry); - } - - WGPUBindGroupLayoutDescriptor bind_group_layout_descriptor = {}; - bind_group_layout_descriptor.entryCount = group_entries.size(); - bind_group_layout_descriptor.entries = group_entries.data(); - - pipeline->bind_group_layout = wgpuDeviceCreateBindGroupLayout(device, &bind_group_layout_descriptor); - - pipeline->render_handle = wgpuDeviceCreateRenderPipeline(device, &descriptor); - - return pipeline; -} - -GFXPipeline* GFXWebGPU::create_compute_pipeline(const GFXComputePipelineCreateInfo& info) { - auto pipeline = new GFXWebGPUPipeline(); - - WGPUComputePipelineDescriptor descriptor = {}; - descriptor.label = info.label.c_str(); - - { - const bool use_shader_source = !info.compute_src.is_path(); - - if (use_shader_source) { - auto compute_shader_vector = info.compute_src.as_bytecode(); - - descriptor.compute.module = create_shader(compute_shader_vector.data(), compute_shader_vector.size() * sizeof(uint32_t), info.label.c_str()); - } - else { - auto compute_shader = prism::open_file(prism::internal_domain / (info.compute_src.as_path().string() + ".wgsl.spv"), true); - compute_shader->read_all(); - - descriptor.compute.module = create_shader(compute_shader->cast_data(), compute_shader->size(), info.compute_src.as_path().string().c_str()); - } - } - - pipeline->compute_handle = wgpuDeviceCreateComputePipeline(device, &descriptor); - - return pipeline; -} - -void GFXWebGPU::submit(GFXCommandBuffer* command_buffer, const platform::window_ptr window) { - WGPUTextureView backBufView = wgpuSwapChainGetCurrentTextureView(swapchain); - - WGPUCommandEncoder command_encoder = wgpuDeviceCreateCommandEncoder(device, nullptr); - - GFXWebGPUPipeline* current_pipeline = nullptr; - WGPURenderPassEncoder render_encoder = nullptr; - WGPUComputePassEncoder compute_encoder = nullptr; - GFXWebGPURenderPass* current_render_pass = nullptr; - GFXWebGPUFramebuffer* current_framebuffer = nullptr; - WGPUColor current_clear_color = {}; - Viewport current_viewport {}; // lol webgpu doesn't even have a viewport type?? - - enum class CurrentEncoder { - None, - Render, - Compute, - } current_encoder = CurrentEncoder::None; - - const auto need_encoder = [&](CurrentEncoder encoder, bool needs_reset = false) { - if(encoder != current_encoder || needs_reset) { - if(render_encoder != nullptr) - wgpuRenderPassEncoderEndPass(render_encoder); - - if(compute_encoder != nullptr) - wgpuComputePassEncoderEndPass(compute_encoder); - - render_encoder = nullptr; - compute_encoder = nullptr; - } - - if(current_encoder == encoder && !needs_reset) - return; - - switch(encoder) { - case CurrentEncoder::None: - break; - case CurrentEncoder::Render: - { - WGPURenderPassDescriptor render_pass_descriptor = {}; - - std::vector color_attachments; - - if(current_framebuffer != nullptr) { - unsigned int i = 0; - for(const auto& attachment : current_framebuffer->attachments) { - if(attachment->format == WGPUTextureFormat_Depth32Float) { - // TODO: lol what - auto depth_attachment = new WGPURenderPassDepthStencilAttachment(); - depth_attachment->view = attachment->view; - depth_attachment->depthLoadOp = WGPULoadOp_Clear; - depth_attachment->depthStoreOp = WGPUStoreOp_Store; - - render_pass_descriptor.depthStencilAttachment = depth_attachment; - } else { - WGPURenderPassColorAttachment color_attachment = {}; - color_attachment.view = attachment->view; - color_attachment.loadOp = WGPULoadOp_Clear; - color_attachment.storeOp = WGPUStoreOp_Store; - color_attachment.clearColor = current_clear_color; - - color_attachments.push_back(color_attachment); - } - } - } else { - // we are rendering to the screen - WGPURenderPassColorAttachment color_attachment = {}; - color_attachment.view = backBufView; - color_attachment.loadOp = WGPULoadOp_Clear; - color_attachment.storeOp = WGPUStoreOp_Store; - color_attachment.clearColor = current_clear_color; - - color_attachments.push_back(color_attachment); - } - - render_pass_descriptor.colorAttachmentCount = color_attachments.size(); - render_pass_descriptor.colorAttachments = color_attachments.data(); - - render_encoder = wgpuCommandEncoderBeginRenderPass(command_encoder, &render_pass_descriptor); - - //if(currentViewport.width != 0.0f && currentViewport.height != 0.0f) - // renderEncoder->setViewport(currentViewport); - } - break; - case CurrentEncoder::Compute: - { - WGPUComputePassDescriptor compute_pass_descriptor = {}; - - compute_encoder = wgpuCommandEncoderBeginComputePass(command_encoder, &compute_pass_descriptor); - } - break; - } - - current_encoder = encoder; - }; - - uint64_t last_bind_group_hash = 0; - - const auto try_bind_group = [&]() -> bool { - if(current_pipeline == nullptr) - return false; - - if(last_bind_group_hash != get_bind_group_hash(current_pipeline)) { - if(!current_pipeline->cached_bind_groups.count(get_bind_group_hash(current_pipeline))) - cache_bind_group_state(current_pipeline, current_pipeline->bind_group_layout); - - auto& bind_group = current_pipeline->cached_bind_groups[get_bind_group_hash(current_pipeline)]; - if(bind_group == nullptr) - return false; - - wgpuRenderPassEncoderSetBindGroup(render_encoder, 0, bind_group, 0, nullptr); - - last_bind_group_hash = get_bind_group_hash(current_pipeline); - } - - return true; - }; - - for(auto command : command_buffer->commands) { - switch (command.type) { - case GFXCommandType::Invalid: - break; - case GFXCommandType::SetRenderPass: - { - current_clear_color = {}; - current_clear_color.r = command.data.set_render_pass.clear_color.r; - current_clear_color.g = command.data.set_render_pass.clear_color.g; - current_clear_color.b = command.data.set_render_pass.clear_color.b; - current_clear_color.a = command.data.set_render_pass.clear_color.a; - - current_framebuffer = (GFXWebGPUFramebuffer*)command.data.set_render_pass.framebuffer; - current_render_pass = (GFXWebGPURenderPass*)command.data.set_render_pass.render_pass; - current_viewport = {}; - - need_encoder(CurrentEncoder::Render, true); - } - break; - case GFXCommandType::EndRenderPass: - { - current_render_pass = nullptr; - - if(current_encoder == CurrentEncoder::Render) - wgpuRenderPassEncoderEndPass(render_encoder); - } - case GFXCommandType::SetGraphicsPipeline: - { - need_encoder(CurrentEncoder::Render); - - current_pipeline = (GFXWebGPUPipeline*)command.data.set_graphics_pipeline.pipeline; - if(current_pipeline != nullptr) { - wgpuRenderPassEncoderSetPipeline(render_encoder, current_pipeline->render_handle); - - reset_bind_state(); - last_bind_group_hash = 0; - } - } - break; - case GFXCommandType::SetComputePipeline: - { - need_encoder(CurrentEncoder::Compute); - - current_pipeline = (GFXWebGPUPipeline*)command.data.set_compute_pipeline.pipeline; - if(current_pipeline != nullptr) { - wgpuComputePassEncoderSetPipeline(compute_encoder, current_pipeline->compute_handle); - - reset_bind_state(); - last_bind_group_hash = 0; - } - } - break; - case GFXCommandType::SetVertexBuffer: - { - need_encoder(CurrentEncoder::Render); - - wgpuRenderPassEncoderSetVertexBuffer(render_encoder, - command.data.set_vertex_buffer.index, - ((GFXWebGPUBuffer*)command.data.set_vertex_buffer.buffer)->handle, - command.data.set_vertex_buffer.offset, - ((GFXWebGPUBuffer*)command.data.set_vertex_buffer.buffer)->size); - } - break; - case GFXCommandType::SetIndexBuffer: - { - need_encoder(CurrentEncoder::Render); - - wgpuRenderPassEncoderSetIndexBuffer(render_encoder, - ((GFXWebGPUBuffer*)command.data.set_index_buffer.buffer)->handle, - command.data.set_index_buffer.index_type == IndexType::UINT32 ? WGPUIndexFormat_Uint32 : WGPUIndexFormat_Uint16, - 0, - ((GFXWebGPUBuffer*)command.data.set_index_buffer.buffer)->size); - } - break; - case GFXCommandType::BindShaderBuffer: - { - BoundShaderBuffer bsb; - bsb.buffer = command.data.bind_shader_buffer.buffer; - bsb.offset = command.data.bind_shader_buffer.offset; - bsb.size = command.data.bind_shader_buffer.size; - - boundShaderBuffers[command.data.bind_shader_buffer.index] = bsb; - } - break; - case GFXCommandType::BindTexture: - { - boundTextures[command.data.bind_texture.index] = command.data.bind_texture.texture; - } - break; - case GFXCommandType::BindSampler: - { - boundSamplers[command.data.bind_sampler.index] = command.data.bind_sampler.sampler; - } - break; - case GFXCommandType::Draw: - { - if(current_pipeline == nullptr) - continue; - - if(try_bind_group()) { - wgpuRenderPassEncoderDraw(render_encoder, - command.data.draw.vertex_count, - command.data.draw.instance_count, - command.data.draw.vertex_offset, - command.data.draw.base_instance); - } - } - break; - case GFXCommandType::DrawIndexed: - { - if(current_pipeline == nullptr) - continue; - - if(try_bind_group()) { - wgpuRenderPassEncoderDrawIndexed(render_encoder, - command.data.draw_indexed.index_count, - 1, - command.data.draw_indexed.vertex_offset, - command.data.draw_indexed.vertex_offset, - command.data.draw_indexed.base_instance); - } - } - break; - case GFXCommandType::MemoryBarrier: - // not supported - break; - case GFXCommandType::CopyTexture: - { - // TODO: blit op - } - break; - case GFXCommandType::SetViewport: - { - need_encoder(CurrentEncoder::Render); - - current_viewport = command.data.set_viewport.viewport; - - wgpuRenderPassEncoderSetViewport(render_encoder, - current_viewport.x, - current_viewport.y, - current_viewport.width, - current_viewport.height, - current_viewport.min_depth, - current_viewport.max_depth); - } - break; - case GFXCommandType::SetScissor: - { - need_encoder(CurrentEncoder::Render); - - wgpuRenderPassEncoderSetScissorRect(render_encoder, - command.data.set_scissor.rect.offset.x, - command.data.set_scissor.rect.offset.y, - command.data.set_scissor.rect.extent.width, - command.data.set_scissor.rect.extent.height); - } - break; - case GFXCommandType::GenerateMipmaps: - { - // TODO: not supported by webgpu? - } - break; - case GFXCommandType::SetDepthBias: { - need_encoder(CurrentEncoder::Render); - - // TODO: not supported by webgpu? - } - break; - case GFXCommandType::PushGroup: - { - // TOOD: stub - } - break; - case GFXCommandType::PopGroup: - { - // TOOD: stub - } - break; - case GFXCommandType::InsertLabel: - { - // TOOD: stub - } - break; - case GFXCommandType::Dispatch: - { - need_encoder(CurrentEncoder::Compute); - - if(try_bind_group()) { - wgpuComputePassEncoderDispatch(compute_encoder, - command.data.dispatch.group_count_x, - command.data.dispatch.group_count_y, - command.data.dispatch.group_count_z); - } - } - break; - default: - prism::log("Unhandled GFX command {}", utility::enum_to_string(command.type)); - } - } - - if(render_encoder != nullptr) - wgpuRenderPassEncoderEndPass(render_encoder); - - if(compute_encoder != nullptr) - wgpuComputePassEncoderEndPass(compute_encoder); - - WGPUCommandBuffer commands = wgpuCommandEncoderFinish(command_encoder, nullptr); - - wgpuQueueSubmit(queue, 1, &commands); - wgpuCommandBufferRelease(commands); - - wgpuTextureViewRelease(backBufView); -} - -uint64_t GFXWebGPU::get_bind_group_hash(GFXWebGPUPipeline *pipeline) { - uint64_t hash = 0; - hash += (int64_t)pipeline; - - int i = 0; - for (auto& buffer : boundShaderBuffers) { - if (buffer.buffer != nullptr) { - hash += (uint64_t)buffer.buffer * (i + 1); - } - } - - i = 0; - for (auto& texture : boundTextures) { - if (texture != nullptr) { - hash += (uint64_t)texture * (i + 1); - } - } - - return hash; -} - -void GFXWebGPU::cache_bind_group_state(GFXWebGPUPipeline* pipeline, WGPUBindGroupLayout group_layout) { - uint64_t hash = get_bind_group_hash(pipeline); - - std::vector group_entries; - - for (auto [i, buffer] : utility::enumerate(boundShaderBuffers)) { - if (buffer.buffer != nullptr) { - auto wgpu_buffer = (GFXWebGPUBuffer*)buffer.buffer; - - WGPUBindGroupEntry entry = {}; - entry.buffer = wgpu_buffer->handle; - entry.size = buffer.size; - entry.offset = buffer.offset; - entry.binding = i; - - group_entries.push_back(entry); - } - } - - for (auto [i, texture] : utility::enumerate(boundTextures)) { - if (texture != nullptr) { - auto wgpu_texture = (GFXWebGPUTexture*) texture; - - WGPUBindGroupEntry entry = {}; - entry.textureView = wgpu_texture->view; - entry.sampler = wgpu_texture->sampler; - entry.binding = i; - - group_entries.push_back(entry); - } - } - - for (auto [i, sampler] : utility::enumerate(boundSamplers)) { - if (sampler != nullptr) { - auto wgpu_sampler = (GFXWebGPUSampler*) sampler; - - WGPUBindGroupEntry entry = {}; - entry.sampler = wgpu_sampler->handle; - entry.binding = i; - - group_entries.push_back(entry); - } - } - - WGPUBindGroupDescriptor group_descriptor = {}; - group_descriptor.layout = group_layout; - group_descriptor.entryCount = group_entries.size(); - group_descriptor.entries = group_entries.data(); - - pipeline->cached_bind_groups[hash] = wgpuDeviceCreateBindGroup(device, &group_descriptor); -} - -void GFXWebGPU::reset_bind_state() { - for (auto& buffer : boundShaderBuffers) - buffer.buffer = nullptr; - - for (auto& texture : boundTextures) - texture = nullptr; - - for (auto& sampler : boundSamplers) - sampler = nullptr; -} diff --git a/engine/gfx/webgpu/src/gfx_webgpu_buffer.hpp b/engine/gfx/webgpu/src/gfx_webgpu_buffer.hpp deleted file mode 100644 index 9132295..0000000 --- a/engine/gfx/webgpu/src/gfx_webgpu_buffer.hpp +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include "gfx_buffer.hpp" - -class GFXWebGPUBuffer : public GFXBuffer { -public: - WGPUBuffer handle = nullptr; - size_t size = 0; -}; diff --git a/engine/gfx/webgpu/src/gfx_webgpu_commandbuffer.hpp b/engine/gfx/webgpu/src/gfx_webgpu_commandbuffer.hpp deleted file mode 100644 index 085ea5b..0000000 --- a/engine/gfx/webgpu/src/gfx_webgpu_commandbuffer.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include "gfx_commandbuffer.hpp" - -class GFXWebGPUCommandBuffer : public GFXCommandBuffer { -public: - -}; diff --git a/engine/gfx/webgpu/src/gfx_webgpu_framebuffer.hpp b/engine/gfx/webgpu/src/gfx_webgpu_framebuffer.hpp deleted file mode 100644 index 60babb1..0000000 --- a/engine/gfx/webgpu/src/gfx_webgpu_framebuffer.hpp +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -#include "gfx_framebuffer.hpp" - -class GFXWebGPUTexture; - -class GFXWebGPUFramebuffer : public GFXFramebuffer { -public: - std::vector attachments; -}; diff --git a/engine/gfx/webgpu/src/gfx_webgpu_pipeline.hpp b/engine/gfx/webgpu/src/gfx_webgpu_pipeline.hpp deleted file mode 100644 index 6519867..0000000 --- a/engine/gfx/webgpu/src/gfx_webgpu_pipeline.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include - -#include "gfx_pipeline.hpp" - -class GFXWebGPUPipeline : public GFXPipeline { -public: - WGPURenderPipeline render_handle = nullptr; - WGPUComputePipeline compute_handle = nullptr; - - WGPUBindGroupLayout bind_group_layout = nullptr; - - std::map cached_bind_groups; -}; diff --git a/engine/gfx/webgpu/src/gfx_webgpu_renderpass.hpp b/engine/gfx/webgpu/src/gfx_webgpu_renderpass.hpp deleted file mode 100644 index fb9c7e5..0000000 --- a/engine/gfx/webgpu/src/gfx_webgpu_renderpass.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include "gfx_renderpass.hpp" - -class GFXWebGPURenderPass : public GFXRenderPass { -public: - -}; diff --git a/engine/gfx/webgpu/src/gfx_webgpu_sampler.hpp b/engine/gfx/webgpu/src/gfx_webgpu_sampler.hpp deleted file mode 100644 index 8f22f4d..0000000 --- a/engine/gfx/webgpu/src/gfx_webgpu_sampler.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include "gfx_sampler.hpp" - -class GFXWebGPUSampler : public GFXSampler { -public: - WGPUSampler handle = nullptr; -}; diff --git a/engine/gfx/webgpu/src/gfx_webgpu_texture.hpp b/engine/gfx/webgpu/src/gfx_webgpu_texture.hpp deleted file mode 100644 index 5c9dfc0..0000000 --- a/engine/gfx/webgpu/src/gfx_webgpu_texture.hpp +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include "gfx_texture.hpp" - -class GFXWebGPUTexture : public GFXTexture { -public: - WGPUTexture handle = nullptr; - WGPUTextureFormat format = WGPUTextureFormat_Undefined; - WGPUTextureView view = nullptr; - WGPUSampler sampler = nullptr; -}; diff --git a/engine/shadercompiler/include/shadercompiler.hpp b/engine/shadercompiler/include/shadercompiler.hpp index e8dea63..df54bd5 100755 --- a/engine/shadercompiler/include/shadercompiler.hpp +++ b/engine/shadercompiler/include/shadercompiler.hpp @@ -20,8 +20,7 @@ enum class ShaderLanguage { GLSL, SPIRV, MSL, - HLSL, - WGSL // lol how do we even convert to this + HLSL }; /// Compilation options when compiling shaders. @@ -36,8 +35,6 @@ public: /// When compiling MSL, the result may differ whether or not we're targetting non-Mac Metal platforms. bool is_apple_mobile = false; - - bool enable_wgpu_compat = false; }; /// Represents the source code of a shader either in plaintext (GLSL, MSL) or bytecode (SPIR-V). diff --git a/engine/shadercompiler/src/shadercompiler.cpp b/engine/shadercompiler/src/shadercompiler.cpp index 0c5a6be..eb9ef83 100755 --- a/engine/shadercompiler/src/shadercompiler.cpp +++ b/engine/shadercompiler/src/shadercompiler.cpp @@ -32,14 +32,6 @@ std::vector compile_glsl_to_spv(const std::string_view source_string, newString += source_string; - if(options.enable_wgpu_compat) { - // in some wacky world the webgpu devs live in, push constants do not exist. - - // alright, so to make webgpu happy we are going to hand-waive all of our push constant blocks - // away into UBOs. let's start by rewriting our GLSL. yay... - newString = replace_substring(newString, "push_constant", "binding = 10"); - } - const char* InputCString = newString.c_str(); glslang::TShader shader(shader_language); @@ -104,8 +96,6 @@ std::optional ShaderCompiler::compile(const ShaderLanguage from_la break; } - options.enable_wgpu_compat = to_language == ShaderLanguage::WGSL; - auto spirv = compile_glsl_to_spv(shader_source.as_string(), lang, options); if(spirv.empty()) { prism::log("SPIRV generation failed!"); @@ -115,7 +105,6 @@ std::optional ShaderCompiler::compile(const ShaderLanguage from_la switch(to_language) { case ShaderLanguage::GLSL: return ShaderSource(shader_source); - case ShaderLanguage::WGSL: case ShaderLanguage::SPIRV: return ShaderSource(spirv); case ShaderLanguage::MSL: { diff --git a/tools/shadercompiler/main.cpp b/tools/shadercompiler/main.cpp index 63f5dd7..20bf05d 100755 --- a/tools/shadercompiler/main.cpp +++ b/tools/shadercompiler/main.cpp @@ -26,8 +26,6 @@ int main(int argc, char* argv[]) { language = ShaderLanguage::SPIRV; } else if(shader_language_string == "msl") { language = ShaderLanguage::MSL; - } else if(shader_language_string == "wgsl") { - language = ShaderLanguage::WGSL; } else if(shader_language_string == "glsl") { language = ShaderLanguage::GLSL; } else if(shader_language_string == "hlsl") { @@ -66,7 +64,6 @@ int main(int argc, char* argv[]) { switch(language) { // right now, WGSL is outputted as SPIR-V with some WGSL compatibility stuff included - case ShaderLanguage::WGSL: case ShaderLanguage::SPIRV: { const auto spirv = compiled_source->as_bytecode();