blob: 6e6ab3e63e6fcefde6fae6fdf730326a0491b05f [file] [log] [blame]
// 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();
}