private static IntPtr CreateShader(UInt32[] byte_code, char *label = null) { IntPtr shader; fixed(uint *code = byte_code) { WGPUShaderModuleSPIRVDescriptor spirv = new WGPUShaderModuleSPIRVDescriptor() { chain = new WGPUChainedStruct() { sType = WGPUSType.WGPUSType_ShaderModuleSPIRVDescriptor }, codeSize = (uint)byte_code.Length, code = code }; WGPUShaderModuleDescriptor desc = new WGPUShaderModuleDescriptor() { nextInChain = (WGPUChainedStruct *)&spirv, label = label }; shader = WebGPUNative.wgpuDeviceCreateShaderModule(Device, &desc); } return(shader); }
unsafe static void Main() { Application.SetHighDpiMode(HighDpiMode.SystemAware); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); var window = new Form1(); var device = Dawn.createDevice(window.Handle); var queue = WebGPUNative.wgpuDeviceGetDefaultQueue(device); var swapChain = Dawn.createSwapChain(device, WGPUTextureUsage.WGPUTextureUsage_OutputAttachment, 800, 450, WGPUPresentMode.WGPUPresentMode_Mailbox); Triangle.Device = device; Triangle.Queue = queue; Triangle.SwapChain = swapChain; TriangleCPP.initialize(device, queue, swapChain); Triangle.CreatePipelineAndBuffers(); //TriangleCPP.initializePipelineAndBuffers(Triangle.pipeline, Triangle.vertBuf, Triangle.indxBuf, Triangle.uRotBuf, Triangle.bindGroup); //TriangleCPP.createPipelineAndBuffers(); window.Show(); while (true) { System.Windows.Forms.Application.DoEvents(); Triangle.redraw(); //TriangleCPP.redraw(); } }
public static WGPUSwapChain CreateSwapChain(WGPUDevice device) { WGPUSurfaceDescriptorFromCanvasHTMLSelector canvDesc = new WGPUSurfaceDescriptorFromCanvasHTMLSelector { chain = new WGPUChainedStruct { sType = WGPUSType.WGPUSType_SurfaceDescriptorFromCanvasHTMLSelector, }, selector = canvas_str }; WGPUSurfaceDescriptor surfDesc = new WGPUSurfaceDescriptor { nextInChain = (WGPUChainedStruct *)&canvDesc }; WGPUSurface surface = WebGPUNative.wgpuInstanceCreateSurface(IntPtr.Zero, &surfDesc); WGPUSwapChainDescriptor swapDesc = new WGPUSwapChainDescriptor { usage = WGPUTextureUsage.WGPUTextureUsage_OutputAttachment, format = WGPUTextureFormat.WGPUTextureFormat_BGRA8Unorm, width = 800, height = 450, presentMode = WGPUPresentMode.WGPUPresentMode_Fifo }; return(WebGPUNative.wgpuDeviceCreateSwapChain(device, surface, &swapDesc));; }
public static bool redraw() { IntPtr backBufView = WebGPUNative.wgpuSwapChainGetCurrentTextureView(SwapChain); // create textureView WGPURenderPassColorAttachmentDescriptor colorDesc = new WGPURenderPassColorAttachmentDescriptor { attachment = backBufView, loadOp = WGPULoadOp.WGPULoadOp_Clear, storeOp = WGPUStoreOp.WGPUStoreOp_Store, clearColor = new WGPUColor { r = 0.3f, g = 0.3f, b = 0.3f, a = 1.0f } }; WGPURenderPassDescriptor renderPass = new WGPURenderPassDescriptor { colorAttachmentCount = 1, colorAttachments = &colorDesc }; IntPtr encoder = WebGPUNative.wgpuDeviceCreateCommandEncoder(Device, null); // create encoder IntPtr pass = WebGPUNative.wgpuCommandEncoderBeginRenderPass(encoder, &renderPass); // update the rotation rotDeg += 0.1f; fixed(void *data = &rotDeg) { WebGPUNative.wgpuQueueWriteBuffer(Queue, uRotBuf, 0, data, sizeof(float)); } // draw the triangle (comment these five lines to simply clear the screen) WebGPUNative.wgpuRenderPassEncoderSetPipeline(pass, pipeline); WebGPUNative.wgpuRenderPassEncoderSetBindGroup(pass, 0, bindGroup, 0, null); WebGPUNative.wgpuRenderPassEncoderSetVertexBuffer(pass, 0, vertBuf, 0, 0); WebGPUNative.wgpuRenderPassEncoderSetIndexBufferWithFormat(pass, indxBuf, WGPUIndexFormat.WGPUIndexFormat_Uint16, 0, 0); WebGPUNative.wgpuRenderPassEncoderDrawIndexed(pass, 3, 1, 0, 0, 0); WebGPUNative.wgpuRenderPassEncoderEndPass(pass); WebGPUNative.wgpuRenderPassEncoderRelease(pass); // release pass IntPtr commands = WebGPUNative.wgpuCommandEncoderFinish(encoder, null); // create commands WebGPUNative.wgpuCommandEncoderRelease(encoder); // release encoder WebGPUNative.wgpuQueueSubmit(Queue, 1, &commands); WebGPUNative.wgpuCommandBufferRelease(commands); // release commands // TODO EMSCRIPTEN: wgpuSwapChainPresent is unsupported in Emscripten, so what do we do? WebGPUNative.wgpuSwapChainPresent(SwapChain); WebGPUNative.wgpuTextureViewRelease(backBufView); // release textureView return(true); }
/** * Helper to create a buffer. * * \param[in] data pointer to the start of the raw data * \param[in] size number of bytes in \a data * \param[in] usage type of buffer */ private static IntPtr CreateBuffer(void *data, ulong size, WGPUBufferUsage usage) { WGPUBufferDescriptor desc = new WGPUBufferDescriptor { usage = WGPUBufferUsage.WGPUBufferUsage_CopyDst | usage, size = size }; IntPtr buffer = WebGPUNative.wgpuDeviceCreateBuffer(Device, ref desc); WebGPUNative.wgpuQueueWriteBuffer(Queue, buffer, 0, data, size); return(buffer); }
public static IntPtr createBindGroupLayout() // ResourceLayout on wave { WGPUBindGroupLayoutEntry bglEntry = new WGPUBindGroupLayoutEntry { binding = 0, visibility = WGPUShaderStage.WGPUShaderStage_Vertex, type = WGPUBindingType.WGPUBindingType_UniformBuffer }; WGPUBindGroupLayoutDescriptor bglDesc = new WGPUBindGroupLayoutDescriptor { entryCount = 1, entries = &bglEntry }; return(WebGPUNative.wgpuDeviceCreateBindGroupLayout(Device, &bglDesc)); }
public static IntPtr CreateBindGroup(IntPtr bindGroupLayout, IntPtr _uRotBuf) // ResourceSet on wave { WGPUBindGroupEntry bgEntry = new WGPUBindGroupEntry { binding = 0, buffer = _uRotBuf, offset = 0, size = sizeof(float) // sizeof(rotDeg) }; WGPUBindGroupDescriptor bgDesc = new WGPUBindGroupDescriptor { layout = bindGroupLayout, entryCount = 1, entries = &bgEntry }; return(WebGPUNative.wgpuDeviceCreateBindGroup(Device, &bgDesc)); }
public static void CreatePipelineAndBuffers() { IntPtr bindGroupLayout = createBindGroupLayout(); //IntPtr bindGroupLayout = TriangleCPP.createBindGroupLayout(); pipeline = CreatePipeline(bindGroupLayout); //pipeline = TriangleCPP.createPipeline(bindGroupLayout); vertBuf = CreateVertBuffer(); //vertBuf = TriangleCPP.createVertBuffer(); indxBuf = CreateIndxBuffer(); //indxBuf = TriangleCPP.createIndxBuffer(); uRotBuf = CreateDataBuffer(); //uRotBuf = TriangleCPP.createDataBuffer(); bindGroup = CreateBindGroup(bindGroupLayout, uRotBuf); //bindGroup = TriangleCPP.createBindGroup(bindGroupLayout, uRotBuf); // last bit of clean-up WebGPUNative.wgpuBindGroupLayoutRelease(bindGroupLayout); }
static void Main() { //Emscripten.wgpu_set_dotnet_entry_point(EntryPoint); //Emscripten.wgpu_run(); var device = Emscripten.CreateDevice(IntPtr.Zero); Console.WriteLine("----> Device: " + device); var queue = WebGPUNative.wgpuDeviceGetDefaultQueue(device); Console.WriteLine("----> Queue: " + device); var swapChain = Emscripten.CreateSwapChain(device); Console.WriteLine("----> SwapChain: " + device); Triangle.Device = device; Triangle.Queue = queue; Triangle.SwapChain = swapChain; Triangle.CreatePipelineAndBuffers(); Console.WriteLine("----> PipelinesAndBuffers!"); Emscripten.MainLoop(Triangle.redraw); }
public static IntPtr CreatePipeline(IntPtr bindGroupLayout) { // Load shaders var vertMod = CreateShader(triangleVert); //var vertMod = TriangleCPP.createVertShader(); var fragMod = CreateShader(triangleFrag); //var fragMod = TriangleCPP.createFragShader(); WGPUPipelineLayoutDescriptor layoutDesc = new WGPUPipelineLayoutDescriptor { bindGroupLayoutCount = 1, bindGroupLayouts = &bindGroupLayout }; IntPtr pipelineLayout = WebGPUNative.wgpuDeviceCreatePipelineLayout(Device, &layoutDesc); // begin pipeline set-up WGPURenderPipelineDescriptor desc = new WGPURenderPipelineDescriptor { layout = pipelineLayout, vertexStage = new WGPUProgrammableStageDescriptor() { module = vertMod, entryPoint = str_entrypoint } }; WGPUProgrammableStageDescriptor fragStage = new WGPUProgrammableStageDescriptor { module = fragMod, entryPoint = str_entrypoint }; desc.fragmentStage = &fragStage; // describe buffer layouts var vertAttrs = stackalloc WGPUVertexAttributeDescriptor[2]; vertAttrs[0] = new WGPUVertexAttributeDescriptor { format = WGPUVertexFormat.WGPUVertexFormat_Float2, offset = 0, shaderLocation = 0 }; vertAttrs[1] = new WGPUVertexAttributeDescriptor { format = WGPUVertexFormat.WGPUVertexFormat_Float3, offset = 2 * sizeof(float), shaderLocation = 1 }; WGPUVertexBufferLayoutDescriptor vertDesc = new WGPUVertexBufferLayoutDescriptor { arrayStride = 5 * sizeof(float), attributeCount = 2, attributes = vertAttrs }; WGPUVertexStateDescriptor vertState = new WGPUVertexStateDescriptor { ////indexFormat = WGPUIndexFormat.WGPUIndexFormat_Uint16, vertexBufferCount = 1, vertexBuffers = &vertDesc }; desc.vertexState = &vertState; desc.primitiveTopology = WGPUPrimitiveTopology.WGPUPrimitiveTopology_TriangleList; desc.sampleCount = 1; // describe blend WGPUBlendDescriptor blendDesc = new WGPUBlendDescriptor { operation = WGPUBlendOperation.WGPUBlendOperation_Add, srcFactor = WGPUBlendFactor.WGPUBlendFactor_SrcAlpha, dstFactor = WGPUBlendFactor.WGPUBlendFactor_OneMinusSrcAlpha }; WGPUColorStateDescriptor colorDesc = new WGPUColorStateDescriptor { format = Dawn.getSwapChainFormat(Device), alphaBlend = blendDesc, colorBlend = blendDesc, writeMask = WGPUColorWriteMask.WGPUColorWriteMask_All }; desc.colorStateCount = 1; desc.colorStates = &colorDesc; desc.sampleMask = 0xFFFFFFFF; // <-- Note: this currently causes Emscripten to fail (sampleMask ends up as -1, which trips an assert) IntPtr _pipeline = WebGPUNative.wgpuDeviceCreateRenderPipeline(Device, ref desc); // partial clean-up (just move to the end, no?) WebGPUNative.wgpuPipelineLayoutRelease(pipelineLayout); WebGPUNative.wgpuShaderModuleRelease(fragMod); WebGPUNative.wgpuShaderModuleRelease(vertMod); return(_pipeline); }