| // Copyright 2023 The Dawn Authors |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| #include "RendererC.h" // NOLINT |
| #include "dawn/common/Log.h" |
| |
| void RendererC::Init() { |
| device = CreateCppDawnDeviceForAndroid(androidDesc).MoveToCHandle(); |
| queue = wgpuDeviceGetQueue(device); |
| swapChain = GetSwapChain().MoveToCHandle(); |
| |
| const char* shaderSource = R"( |
| @vertex fn vs_main(@builtin(vertex_index) i : u32) -> |
| @builtin(position) vec4f { |
| var p = vec2f(0.0, 0.0); |
| if (i == 0u) { |
| p = vec2f(-0.5, -0.5); |
| } else if (i == 1u) { |
| p = vec2f(0.5, -0.5); |
| } else { |
| p = vec2f(0.0, 0.5); |
| } |
| return vec4f(p, 0.0, 1.0); |
| } |
| |
| @fragment fn fs_main() -> @location(0) vec4f { |
| return vec4f(0.0, 0.4, 1.0, 1.0); |
| } |
| )"; |
| |
| WGPUShaderModuleWGSLDescriptor shaderCodeDesc = {}; |
| shaderCodeDesc.chain.sType = WGPUSType_ShaderModuleWGSLDescriptor; |
| shaderCodeDesc.code = shaderSource; |
| WGPUShaderModuleDescriptor shaderDesc = {}; |
| shaderDesc.nextInChain = &shaderCodeDesc.chain; |
| |
| WGPUShaderModule shaderModule = wgpuDeviceCreateShaderModule(device, &shaderDesc); |
| WGPURenderPipelineDescriptor pipelineDesc = {}; |
| |
| // Vertex shader |
| pipelineDesc.vertex.module = shaderModule; |
| pipelineDesc.vertex.entryPoint = "vs_main"; |
| pipelineDesc.primitive.topology = WGPUPrimitiveTopology_TriangleList; |
| |
| // Fragment shader |
| WGPUFragmentState fragmentState = {}; |
| pipelineDesc.fragment = &fragmentState; |
| fragmentState.module = shaderModule; |
| fragmentState.entryPoint = "fs_main"; |
| |
| |
| WGPUColorTargetState colorTarget = {}; |
| colorTarget.format = static_cast<WGPUTextureFormat>(GetPreferredSwapChainTextureFormat()); |
| colorTarget.writeMask = WGPUColorWriteMask_All; |
| |
| fragmentState.targetCount = 1; |
| fragmentState.targets = &colorTarget; |
| pipelineDesc.multisample.count = 1; |
| pipelineDesc.multisample.mask = ~0u; |
| pipelineDesc.multisample.alphaToCoverageEnabled = false; |
| pipeline = wgpuDeviceCreateRenderPipeline(device, &pipelineDesc); |
| } |
| |
| void RendererC::Frame() { |
| WGPUTextureView nextTexture = wgpuSwapChainGetCurrentTextureView(swapChain); |
| if (!nextTexture) { |
| dawn::ErrorLog() << "Cannot acquire next swap chain texture"; |
| return; |
| } |
| |
| WGPURenderPassColorAttachment renderPassColorAttachment = {}; |
| renderPassColorAttachment.view = nextTexture; |
| renderPassColorAttachment.loadOp = WGPULoadOp_Clear; |
| renderPassColorAttachment.storeOp = WGPUStoreOp_Store; |
| renderPassColorAttachment.clearValue = WGPUColor{0.9, 0.1, 0.2, 1.0}; |
| |
| WGPURenderPassDescriptor renderPassDesc = {}; |
| renderPassDesc.colorAttachmentCount = 1; |
| renderPassDesc.colorAttachments = &renderPassColorAttachment; |
| |
| WGPUCommandEncoderDescriptor commandEncoderDesc = {}; |
| commandEncoderDesc.label = "Command Encoder"; |
| WGPUCommandEncoder encoder = wgpuDeviceCreateCommandEncoder(device, &commandEncoderDesc); |
| WGPURenderPassEncoder renderPass = wgpuCommandEncoderBeginRenderPass(encoder, &renderPassDesc); |
| wgpuRenderPassEncoderSetPipeline(renderPass, pipeline); |
| wgpuRenderPassEncoderDraw(renderPass, 3, 1, 0, 0); |
| wgpuRenderPassEncoderEnd(renderPass); |
| |
| wgpuTextureViewRelease(nextTexture); |
| |
| WGPUCommandBufferDescriptor cmdBufferDescriptor = {}; |
| cmdBufferDescriptor.label = "Command buffer"; |
| |
| WGPUCommandBuffer command = wgpuCommandEncoderFinish(encoder, &cmdBufferDescriptor); |
| wgpuQueueSubmit(queue, 1, &command); |
| wgpuSwapChainPresent(swapChain); |
| } |
| |
| void RendererC::GameLoop() { |
| if (!deviceInitialised) { |
| Init(); |
| deviceInitialised = true; |
| } |
| Frame(); |
| } |