1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2019 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "src/gpu/dawn/GrDawnProgramBuilder.h" 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_ci#include "src/gpu/GrAutoLocaleSetter.h" 11cb93a386Sopenharmony_ci#include "src/gpu/GrRenderTarget.h" 12cb93a386Sopenharmony_ci#include "src/gpu/GrShaderUtils.h" 13cb93a386Sopenharmony_ci#include "src/gpu/GrStencilSettings.h" 14cb93a386Sopenharmony_ci#include "src/gpu/dawn/GrDawnGpu.h" 15cb93a386Sopenharmony_ci#include "src/gpu/dawn/GrDawnTexture.h" 16cb93a386Sopenharmony_ci#include "src/gpu/effects/GrTextureEffect.h" 17cb93a386Sopenharmony_ci 18cb93a386Sopenharmony_cistatic wgpu::BlendFactor to_dawn_blend_factor(GrBlendCoeff coeff) { 19cb93a386Sopenharmony_ci switch (coeff) { 20cb93a386Sopenharmony_ci case kZero_GrBlendCoeff: 21cb93a386Sopenharmony_ci return wgpu::BlendFactor::Zero; 22cb93a386Sopenharmony_ci case kOne_GrBlendCoeff: 23cb93a386Sopenharmony_ci return wgpu::BlendFactor::One; 24cb93a386Sopenharmony_ci case kSC_GrBlendCoeff: 25cb93a386Sopenharmony_ci return wgpu::BlendFactor::Src; 26cb93a386Sopenharmony_ci case kISC_GrBlendCoeff: 27cb93a386Sopenharmony_ci return wgpu::BlendFactor::OneMinusSrc; 28cb93a386Sopenharmony_ci case kDC_GrBlendCoeff: 29cb93a386Sopenharmony_ci return wgpu::BlendFactor::Dst; 30cb93a386Sopenharmony_ci case kIDC_GrBlendCoeff: 31cb93a386Sopenharmony_ci return wgpu::BlendFactor::OneMinusDst; 32cb93a386Sopenharmony_ci case kSA_GrBlendCoeff: 33cb93a386Sopenharmony_ci return wgpu::BlendFactor::SrcAlpha; 34cb93a386Sopenharmony_ci case kISA_GrBlendCoeff: 35cb93a386Sopenharmony_ci return wgpu::BlendFactor::OneMinusSrcAlpha; 36cb93a386Sopenharmony_ci case kDA_GrBlendCoeff: 37cb93a386Sopenharmony_ci return wgpu::BlendFactor::DstAlpha; 38cb93a386Sopenharmony_ci case kIDA_GrBlendCoeff: 39cb93a386Sopenharmony_ci return wgpu::BlendFactor::OneMinusDstAlpha; 40cb93a386Sopenharmony_ci case kConstC_GrBlendCoeff: 41cb93a386Sopenharmony_ci return wgpu::BlendFactor::Constant; 42cb93a386Sopenharmony_ci case kIConstC_GrBlendCoeff: 43cb93a386Sopenharmony_ci return wgpu::BlendFactor::OneMinusConstant; 44cb93a386Sopenharmony_ci case kS2C_GrBlendCoeff: 45cb93a386Sopenharmony_ci case kIS2C_GrBlendCoeff: 46cb93a386Sopenharmony_ci case kS2A_GrBlendCoeff: 47cb93a386Sopenharmony_ci case kIS2A_GrBlendCoeff: 48cb93a386Sopenharmony_ci default: 49cb93a386Sopenharmony_ci SkASSERT(!"unsupported blend coefficient"); 50cb93a386Sopenharmony_ci return wgpu::BlendFactor::One; 51cb93a386Sopenharmony_ci } 52cb93a386Sopenharmony_ci} 53cb93a386Sopenharmony_ci 54cb93a386Sopenharmony_cistatic wgpu::BlendFactor to_dawn_blend_factor_for_alpha(GrBlendCoeff coeff) { 55cb93a386Sopenharmony_ci switch (coeff) { 56cb93a386Sopenharmony_ci // Force all srcColor used in alpha slot to alpha version. 57cb93a386Sopenharmony_ci case kSC_GrBlendCoeff: 58cb93a386Sopenharmony_ci return wgpu::BlendFactor::SrcAlpha; 59cb93a386Sopenharmony_ci case kISC_GrBlendCoeff: 60cb93a386Sopenharmony_ci return wgpu::BlendFactor::OneMinusSrcAlpha; 61cb93a386Sopenharmony_ci case kDC_GrBlendCoeff: 62cb93a386Sopenharmony_ci return wgpu::BlendFactor::DstAlpha; 63cb93a386Sopenharmony_ci case kIDC_GrBlendCoeff: 64cb93a386Sopenharmony_ci return wgpu::BlendFactor::OneMinusDstAlpha; 65cb93a386Sopenharmony_ci default: 66cb93a386Sopenharmony_ci return to_dawn_blend_factor(coeff); 67cb93a386Sopenharmony_ci } 68cb93a386Sopenharmony_ci} 69cb93a386Sopenharmony_ci 70cb93a386Sopenharmony_cistatic wgpu::BlendOperation to_dawn_blend_operation(GrBlendEquation equation) { 71cb93a386Sopenharmony_ci switch (equation) { 72cb93a386Sopenharmony_ci case kAdd_GrBlendEquation: 73cb93a386Sopenharmony_ci return wgpu::BlendOperation::Add; 74cb93a386Sopenharmony_ci case kSubtract_GrBlendEquation: 75cb93a386Sopenharmony_ci return wgpu::BlendOperation::Subtract; 76cb93a386Sopenharmony_ci case kReverseSubtract_GrBlendEquation: 77cb93a386Sopenharmony_ci return wgpu::BlendOperation::ReverseSubtract; 78cb93a386Sopenharmony_ci default: 79cb93a386Sopenharmony_ci SkASSERT(!"unsupported blend equation"); 80cb93a386Sopenharmony_ci return wgpu::BlendOperation::Add; 81cb93a386Sopenharmony_ci } 82cb93a386Sopenharmony_ci} 83cb93a386Sopenharmony_ci 84cb93a386Sopenharmony_cistatic wgpu::CompareFunction to_dawn_compare_function(GrStencilTest test) { 85cb93a386Sopenharmony_ci switch (test) { 86cb93a386Sopenharmony_ci case GrStencilTest::kAlways: 87cb93a386Sopenharmony_ci return wgpu::CompareFunction::Always; 88cb93a386Sopenharmony_ci case GrStencilTest::kNever: 89cb93a386Sopenharmony_ci return wgpu::CompareFunction::Never; 90cb93a386Sopenharmony_ci case GrStencilTest::kGreater: 91cb93a386Sopenharmony_ci return wgpu::CompareFunction::Greater; 92cb93a386Sopenharmony_ci case GrStencilTest::kGEqual: 93cb93a386Sopenharmony_ci return wgpu::CompareFunction::GreaterEqual; 94cb93a386Sopenharmony_ci case GrStencilTest::kLess: 95cb93a386Sopenharmony_ci return wgpu::CompareFunction::Less; 96cb93a386Sopenharmony_ci case GrStencilTest::kLEqual: 97cb93a386Sopenharmony_ci return wgpu::CompareFunction::LessEqual; 98cb93a386Sopenharmony_ci case GrStencilTest::kEqual: 99cb93a386Sopenharmony_ci return wgpu::CompareFunction::Equal; 100cb93a386Sopenharmony_ci case GrStencilTest::kNotEqual: 101cb93a386Sopenharmony_ci return wgpu::CompareFunction::NotEqual; 102cb93a386Sopenharmony_ci default: 103cb93a386Sopenharmony_ci SkASSERT(!"unsupported stencil test"); 104cb93a386Sopenharmony_ci return wgpu::CompareFunction::Always; 105cb93a386Sopenharmony_ci } 106cb93a386Sopenharmony_ci} 107cb93a386Sopenharmony_ci 108cb93a386Sopenharmony_cistatic wgpu::StencilOperation to_dawn_stencil_operation(GrStencilOp op) { 109cb93a386Sopenharmony_ci switch (op) { 110cb93a386Sopenharmony_ci case GrStencilOp::kKeep: 111cb93a386Sopenharmony_ci return wgpu::StencilOperation::Keep; 112cb93a386Sopenharmony_ci case GrStencilOp::kZero: 113cb93a386Sopenharmony_ci return wgpu::StencilOperation::Zero; 114cb93a386Sopenharmony_ci case GrStencilOp::kReplace: 115cb93a386Sopenharmony_ci return wgpu::StencilOperation::Replace; 116cb93a386Sopenharmony_ci case GrStencilOp::kInvert: 117cb93a386Sopenharmony_ci return wgpu::StencilOperation::Invert; 118cb93a386Sopenharmony_ci case GrStencilOp::kIncClamp: 119cb93a386Sopenharmony_ci return wgpu::StencilOperation::IncrementClamp; 120cb93a386Sopenharmony_ci case GrStencilOp::kDecClamp: 121cb93a386Sopenharmony_ci return wgpu::StencilOperation::DecrementClamp; 122cb93a386Sopenharmony_ci case GrStencilOp::kIncWrap: 123cb93a386Sopenharmony_ci return wgpu::StencilOperation::IncrementWrap; 124cb93a386Sopenharmony_ci case GrStencilOp::kDecWrap: 125cb93a386Sopenharmony_ci return wgpu::StencilOperation::DecrementWrap; 126cb93a386Sopenharmony_ci default: 127cb93a386Sopenharmony_ci SkASSERT(!"unsupported stencil function"); 128cb93a386Sopenharmony_ci return wgpu::StencilOperation::Keep; 129cb93a386Sopenharmony_ci } 130cb93a386Sopenharmony_ci} 131cb93a386Sopenharmony_ci 132cb93a386Sopenharmony_cistatic wgpu::PrimitiveTopology to_dawn_primitive_topology(GrPrimitiveType primitiveType) { 133cb93a386Sopenharmony_ci switch (primitiveType) { 134cb93a386Sopenharmony_ci case GrPrimitiveType::kTriangles: 135cb93a386Sopenharmony_ci return wgpu::PrimitiveTopology::TriangleList; 136cb93a386Sopenharmony_ci case GrPrimitiveType::kTriangleStrip: 137cb93a386Sopenharmony_ci return wgpu::PrimitiveTopology::TriangleStrip; 138cb93a386Sopenharmony_ci case GrPrimitiveType::kPoints: 139cb93a386Sopenharmony_ci return wgpu::PrimitiveTopology::PointList; 140cb93a386Sopenharmony_ci case GrPrimitiveType::kLines: 141cb93a386Sopenharmony_ci return wgpu::PrimitiveTopology::LineList; 142cb93a386Sopenharmony_ci case GrPrimitiveType::kLineStrip: 143cb93a386Sopenharmony_ci return wgpu::PrimitiveTopology::LineStrip; 144cb93a386Sopenharmony_ci case GrPrimitiveType::kPath: 145cb93a386Sopenharmony_ci default: 146cb93a386Sopenharmony_ci SkASSERT(!"unsupported primitive topology"); 147cb93a386Sopenharmony_ci return wgpu::PrimitiveTopology::TriangleList; 148cb93a386Sopenharmony_ci } 149cb93a386Sopenharmony_ci} 150cb93a386Sopenharmony_ci 151cb93a386Sopenharmony_cistatic wgpu::VertexFormat to_dawn_vertex_format(GrVertexAttribType type) { 152cb93a386Sopenharmony_ci switch (type) { 153cb93a386Sopenharmony_ci case kFloat_GrVertexAttribType: 154cb93a386Sopenharmony_ci case kHalf_GrVertexAttribType: 155cb93a386Sopenharmony_ci return wgpu::VertexFormat::Float32; 156cb93a386Sopenharmony_ci case kFloat2_GrVertexAttribType: 157cb93a386Sopenharmony_ci case kHalf2_GrVertexAttribType: 158cb93a386Sopenharmony_ci return wgpu::VertexFormat::Float32x2; 159cb93a386Sopenharmony_ci case kFloat3_GrVertexAttribType: 160cb93a386Sopenharmony_ci return wgpu::VertexFormat::Float32x3; 161cb93a386Sopenharmony_ci case kFloat4_GrVertexAttribType: 162cb93a386Sopenharmony_ci case kHalf4_GrVertexAttribType: 163cb93a386Sopenharmony_ci return wgpu::VertexFormat::Float32x4; 164cb93a386Sopenharmony_ci case kUShort2_GrVertexAttribType: 165cb93a386Sopenharmony_ci return wgpu::VertexFormat::Uint16x2; 166cb93a386Sopenharmony_ci case kInt_GrVertexAttribType: 167cb93a386Sopenharmony_ci return wgpu::VertexFormat::Sint32; 168cb93a386Sopenharmony_ci case kUByte4_norm_GrVertexAttribType: 169cb93a386Sopenharmony_ci return wgpu::VertexFormat::Unorm8x4; 170cb93a386Sopenharmony_ci default: 171cb93a386Sopenharmony_ci SkASSERT(!"unsupported vertex format"); 172cb93a386Sopenharmony_ci return wgpu::VertexFormat::Float32x4; 173cb93a386Sopenharmony_ci } 174cb93a386Sopenharmony_ci} 175cb93a386Sopenharmony_ci 176cb93a386Sopenharmony_cistatic wgpu::BlendState create_blend_state(const GrDawnGpu* gpu, const GrPipeline& pipeline) { 177cb93a386Sopenharmony_ci GrXferProcessor::BlendInfo blendInfo = pipeline.getXferProcessor().getBlendInfo(); 178cb93a386Sopenharmony_ci GrBlendEquation equation = blendInfo.fEquation; 179cb93a386Sopenharmony_ci GrBlendCoeff srcCoeff = blendInfo.fSrcBlend; 180cb93a386Sopenharmony_ci GrBlendCoeff dstCoeff = blendInfo.fDstBlend; 181cb93a386Sopenharmony_ci 182cb93a386Sopenharmony_ci wgpu::BlendFactor srcFactor = to_dawn_blend_factor(srcCoeff); 183cb93a386Sopenharmony_ci wgpu::BlendFactor dstFactor = to_dawn_blend_factor(dstCoeff); 184cb93a386Sopenharmony_ci wgpu::BlendFactor srcFactorAlpha = to_dawn_blend_factor_for_alpha(srcCoeff); 185cb93a386Sopenharmony_ci wgpu::BlendFactor dstFactorAlpha = to_dawn_blend_factor_for_alpha(dstCoeff); 186cb93a386Sopenharmony_ci wgpu::BlendOperation operation = to_dawn_blend_operation(equation); 187cb93a386Sopenharmony_ci 188cb93a386Sopenharmony_ci wgpu::BlendState blendState; 189cb93a386Sopenharmony_ci blendState.color = {operation, srcFactor, dstFactor}; 190cb93a386Sopenharmony_ci blendState.alpha = {operation, srcFactorAlpha, dstFactorAlpha}; 191cb93a386Sopenharmony_ci 192cb93a386Sopenharmony_ci return blendState; 193cb93a386Sopenharmony_ci} 194cb93a386Sopenharmony_ci 195cb93a386Sopenharmony_cistatic wgpu::StencilFaceState to_stencil_state_face(const GrStencilSettings::Face& face) { 196cb93a386Sopenharmony_ci wgpu::StencilFaceState desc; 197cb93a386Sopenharmony_ci desc.compare = to_dawn_compare_function(face.fTest); 198cb93a386Sopenharmony_ci desc.failOp = desc.depthFailOp = to_dawn_stencil_operation(face.fFailOp); 199cb93a386Sopenharmony_ci desc.passOp = to_dawn_stencil_operation(face.fPassOp); 200cb93a386Sopenharmony_ci return desc; 201cb93a386Sopenharmony_ci} 202cb93a386Sopenharmony_ci 203cb93a386Sopenharmony_cistatic wgpu::DepthStencilState create_depth_stencil_state( 204cb93a386Sopenharmony_ci const GrProgramInfo& programInfo, 205cb93a386Sopenharmony_ci wgpu::TextureFormat depthStencilFormat) { 206cb93a386Sopenharmony_ci GrStencilSettings stencilSettings = programInfo.nonGLStencilSettings(); 207cb93a386Sopenharmony_ci GrSurfaceOrigin origin = programInfo.origin(); 208cb93a386Sopenharmony_ci 209cb93a386Sopenharmony_ci wgpu::DepthStencilState state; 210cb93a386Sopenharmony_ci state.format = depthStencilFormat; 211cb93a386Sopenharmony_ci if (!stencilSettings.isDisabled()) { 212cb93a386Sopenharmony_ci if (stencilSettings.isTwoSided()) { 213cb93a386Sopenharmony_ci auto front = stencilSettings.postOriginCCWFace(origin); 214cb93a386Sopenharmony_ci auto back = stencilSettings.postOriginCWFace(origin); 215cb93a386Sopenharmony_ci state.stencilFront = to_stencil_state_face(front); 216cb93a386Sopenharmony_ci state.stencilBack = to_stencil_state_face(back); 217cb93a386Sopenharmony_ci state.stencilReadMask = front.fTestMask; 218cb93a386Sopenharmony_ci state.stencilWriteMask = front.fWriteMask; 219cb93a386Sopenharmony_ci } else { 220cb93a386Sopenharmony_ci auto frontAndBack = stencilSettings.singleSidedFace(); 221cb93a386Sopenharmony_ci state.stencilBack = state.stencilFront = to_stencil_state_face(frontAndBack); 222cb93a386Sopenharmony_ci state.stencilReadMask = frontAndBack.fTestMask; 223cb93a386Sopenharmony_ci state.stencilWriteMask = frontAndBack.fWriteMask; 224cb93a386Sopenharmony_ci } 225cb93a386Sopenharmony_ci } 226cb93a386Sopenharmony_ci return state; 227cb93a386Sopenharmony_ci} 228cb93a386Sopenharmony_ci 229cb93a386Sopenharmony_cistatic wgpu::BindGroupEntry make_bind_group_entry(uint32_t binding, 230cb93a386Sopenharmony_ci const wgpu::Sampler& sampler, 231cb93a386Sopenharmony_ci const wgpu::TextureView& textureView) { 232cb93a386Sopenharmony_ci wgpu::BindGroupEntry result; 233cb93a386Sopenharmony_ci result.binding = binding; 234cb93a386Sopenharmony_ci result.buffer = nullptr; 235cb93a386Sopenharmony_ci result.offset = 0; 236cb93a386Sopenharmony_ci result.size = 0; 237cb93a386Sopenharmony_ci result.sampler = sampler; 238cb93a386Sopenharmony_ci result.textureView = textureView; 239cb93a386Sopenharmony_ci return result; 240cb93a386Sopenharmony_ci} 241cb93a386Sopenharmony_ci 242cb93a386Sopenharmony_cistatic wgpu::BindGroupEntry make_bind_group_entry(uint32_t binding, 243cb93a386Sopenharmony_ci const wgpu::Sampler& sampler) { 244cb93a386Sopenharmony_ci return make_bind_group_entry(binding, sampler, nullptr); 245cb93a386Sopenharmony_ci} 246cb93a386Sopenharmony_ci 247cb93a386Sopenharmony_cistatic wgpu::BindGroupEntry make_bind_group_entry(uint32_t binding, 248cb93a386Sopenharmony_ci const wgpu::TextureView& textureView) { 249cb93a386Sopenharmony_ci return make_bind_group_entry(binding, nullptr, textureView); 250cb93a386Sopenharmony_ci} 251cb93a386Sopenharmony_ci 252cb93a386Sopenharmony_cisk_sp<GrDawnProgram> GrDawnProgramBuilder::Build(GrDawnGpu* gpu, 253cb93a386Sopenharmony_ci GrRenderTarget* renderTarget, 254cb93a386Sopenharmony_ci const GrProgramInfo& programInfo, 255cb93a386Sopenharmony_ci wgpu::TextureFormat colorFormat, 256cb93a386Sopenharmony_ci bool hasDepthStencil, 257cb93a386Sopenharmony_ci wgpu::TextureFormat depthStencilFormat, 258cb93a386Sopenharmony_ci GrProgramDesc* desc) { 259cb93a386Sopenharmony_ci GrAutoLocaleSetter als("C"); 260cb93a386Sopenharmony_ci 261cb93a386Sopenharmony_ci GrDawnProgramBuilder builder(gpu, programInfo, desc); 262cb93a386Sopenharmony_ci if (!builder.emitAndInstallProcs()) { 263cb93a386Sopenharmony_ci return nullptr; 264cb93a386Sopenharmony_ci } 265cb93a386Sopenharmony_ci 266cb93a386Sopenharmony_ci builder.finalizeShaders(); 267cb93a386Sopenharmony_ci 268cb93a386Sopenharmony_ci SkSL::Program::Inputs vertInputs, fragInputs; 269cb93a386Sopenharmony_ci bool flipY = programInfo.origin() != kTopLeft_GrSurfaceOrigin; 270cb93a386Sopenharmony_ci auto vsModule = builder.createShaderModule(builder.fVS, SkSL::ProgramKind::kVertex, flipY, 271cb93a386Sopenharmony_ci &vertInputs); 272cb93a386Sopenharmony_ci auto fsModule = builder.createShaderModule(builder.fFS, SkSL::ProgramKind::kFragment, flipY, 273cb93a386Sopenharmony_ci &fragInputs); 274cb93a386Sopenharmony_ci GrSPIRVUniformHandler::UniformInfoArray& uniforms = builder.fUniformHandler.fUniforms; 275cb93a386Sopenharmony_ci uint32_t uniformBufferSize = builder.fUniformHandler.fCurrentUBOOffset; 276cb93a386Sopenharmony_ci sk_sp<GrDawnProgram> result(new GrDawnProgram(uniforms, uniformBufferSize)); 277cb93a386Sopenharmony_ci result->fGPImpl = std::move(builder.fGPImpl); 278cb93a386Sopenharmony_ci result->fXPImpl = std::move(builder.fXPImpl); 279cb93a386Sopenharmony_ci result->fFPImpls = std::move(builder.fFPImpls); 280cb93a386Sopenharmony_ci std::vector<wgpu::BindGroupLayoutEntry> uniformLayoutEntries; 281cb93a386Sopenharmony_ci if (0 != uniformBufferSize) { 282cb93a386Sopenharmony_ci wgpu::BindGroupLayoutEntry entry; 283cb93a386Sopenharmony_ci entry.binding = GrSPIRVUniformHandler::kUniformBinding; 284cb93a386Sopenharmony_ci entry.visibility = wgpu::ShaderStage::Vertex | wgpu::ShaderStage::Fragment; 285cb93a386Sopenharmony_ci entry.buffer.type = wgpu::BufferBindingType::Uniform; 286cb93a386Sopenharmony_ci uniformLayoutEntries.push_back(std::move(entry)); 287cb93a386Sopenharmony_ci } 288cb93a386Sopenharmony_ci wgpu::BindGroupLayoutDescriptor uniformBindGroupLayoutDesc; 289cb93a386Sopenharmony_ci uniformBindGroupLayoutDesc.entryCount = uniformLayoutEntries.size(); 290cb93a386Sopenharmony_ci uniformBindGroupLayoutDesc.entries = uniformLayoutEntries.data(); 291cb93a386Sopenharmony_ci result->fBindGroupLayouts.push_back( 292cb93a386Sopenharmony_ci gpu->device().CreateBindGroupLayout(&uniformBindGroupLayoutDesc)); 293cb93a386Sopenharmony_ci uint32_t binding = 0; 294cb93a386Sopenharmony_ci std::vector<wgpu::BindGroupLayoutEntry> textureLayoutEntries; 295cb93a386Sopenharmony_ci int textureCount = builder.fUniformHandler.fSamplers.count(); 296cb93a386Sopenharmony_ci if (textureCount > 0) { 297cb93a386Sopenharmony_ci for (int i = 0; i < textureCount; ++i) { 298cb93a386Sopenharmony_ci { 299cb93a386Sopenharmony_ci wgpu::BindGroupLayoutEntry entry; 300cb93a386Sopenharmony_ci entry.binding = binding++; 301cb93a386Sopenharmony_ci entry.visibility = wgpu::ShaderStage::Fragment; 302cb93a386Sopenharmony_ci entry.sampler.type = wgpu::SamplerBindingType::Filtering; 303cb93a386Sopenharmony_ci textureLayoutEntries.push_back(std::move(entry)); 304cb93a386Sopenharmony_ci } 305cb93a386Sopenharmony_ci { 306cb93a386Sopenharmony_ci wgpu::BindGroupLayoutEntry entry; 307cb93a386Sopenharmony_ci entry.binding = binding++; 308cb93a386Sopenharmony_ci entry.visibility = wgpu::ShaderStage::Fragment; 309cb93a386Sopenharmony_ci entry.texture.sampleType = wgpu::TextureSampleType::Float; 310cb93a386Sopenharmony_ci entry.texture.viewDimension = wgpu::TextureViewDimension::e2D; 311cb93a386Sopenharmony_ci textureLayoutEntries.push_back(std::move(entry)); 312cb93a386Sopenharmony_ci } 313cb93a386Sopenharmony_ci } 314cb93a386Sopenharmony_ci wgpu::BindGroupLayoutDescriptor textureBindGroupLayoutDesc; 315cb93a386Sopenharmony_ci textureBindGroupLayoutDesc.entryCount = textureLayoutEntries.size(); 316cb93a386Sopenharmony_ci textureBindGroupLayoutDesc.entries = textureLayoutEntries.data(); 317cb93a386Sopenharmony_ci result->fBindGroupLayouts.push_back( 318cb93a386Sopenharmony_ci gpu->device().CreateBindGroupLayout(&textureBindGroupLayoutDesc)); 319cb93a386Sopenharmony_ci } 320cb93a386Sopenharmony_ci wgpu::PipelineLayoutDescriptor pipelineLayoutDesc; 321cb93a386Sopenharmony_ci pipelineLayoutDesc.bindGroupLayoutCount = result->fBindGroupLayouts.size(); 322cb93a386Sopenharmony_ci pipelineLayoutDesc.bindGroupLayouts = result->fBindGroupLayouts.data(); 323cb93a386Sopenharmony_ci auto pipelineLayout = gpu->device().CreatePipelineLayout(&pipelineLayoutDesc); 324cb93a386Sopenharmony_ci result->fBuiltinUniformHandles = builder.fUniformHandles; 325cb93a386Sopenharmony_ci const GrPipeline& pipeline = programInfo.pipeline(); 326cb93a386Sopenharmony_ci wgpu::DepthStencilState depthStencilState; 327cb93a386Sopenharmony_ci 328cb93a386Sopenharmony_ci#ifdef SK_DEBUG 329cb93a386Sopenharmony_ci if (programInfo.isStencilEnabled()) { 330cb93a386Sopenharmony_ci SkASSERT(renderTarget->numStencilBits(renderTarget->numSamples() > 1) == 8); 331cb93a386Sopenharmony_ci } 332cb93a386Sopenharmony_ci#endif 333cb93a386Sopenharmony_ci depthStencilState = create_depth_stencil_state(programInfo, depthStencilFormat); 334cb93a386Sopenharmony_ci 335cb93a386Sopenharmony_ci std::vector<wgpu::VertexBufferLayout> inputs; 336cb93a386Sopenharmony_ci 337cb93a386Sopenharmony_ci std::vector<wgpu::VertexAttribute> vertexAttributes; 338cb93a386Sopenharmony_ci const GrGeometryProcessor& geomProc = programInfo.geomProc(); 339cb93a386Sopenharmony_ci int i = 0; 340cb93a386Sopenharmony_ci if (geomProc.numVertexAttributes() > 0) { 341cb93a386Sopenharmony_ci size_t offset = 0; 342cb93a386Sopenharmony_ci for (const auto& attrib : geomProc.vertexAttributes()) { 343cb93a386Sopenharmony_ci wgpu::VertexAttribute attribute; 344cb93a386Sopenharmony_ci attribute.shaderLocation = i; 345cb93a386Sopenharmony_ci attribute.offset = offset; 346cb93a386Sopenharmony_ci attribute.format = to_dawn_vertex_format(attrib.cpuType()); 347cb93a386Sopenharmony_ci vertexAttributes.push_back(attribute); 348cb93a386Sopenharmony_ci offset += attrib.sizeAlign4(); 349cb93a386Sopenharmony_ci i++; 350cb93a386Sopenharmony_ci } 351cb93a386Sopenharmony_ci wgpu::VertexBufferLayout input; 352cb93a386Sopenharmony_ci input.arrayStride = offset; 353cb93a386Sopenharmony_ci input.stepMode = wgpu::VertexStepMode::Vertex; 354cb93a386Sopenharmony_ci input.attributeCount = vertexAttributes.size(); 355cb93a386Sopenharmony_ci input.attributes = &vertexAttributes.front(); 356cb93a386Sopenharmony_ci inputs.push_back(input); 357cb93a386Sopenharmony_ci } 358cb93a386Sopenharmony_ci std::vector<wgpu::VertexAttribute> instanceAttributes; 359cb93a386Sopenharmony_ci if (geomProc.numInstanceAttributes() > 0) { 360cb93a386Sopenharmony_ci size_t offset = 0; 361cb93a386Sopenharmony_ci for (const auto& attrib : geomProc.instanceAttributes()) { 362cb93a386Sopenharmony_ci wgpu::VertexAttribute attribute; 363cb93a386Sopenharmony_ci attribute.shaderLocation = i; 364cb93a386Sopenharmony_ci attribute.offset = offset; 365cb93a386Sopenharmony_ci attribute.format = to_dawn_vertex_format(attrib.cpuType()); 366cb93a386Sopenharmony_ci instanceAttributes.push_back(attribute); 367cb93a386Sopenharmony_ci offset += attrib.sizeAlign4(); 368cb93a386Sopenharmony_ci i++; 369cb93a386Sopenharmony_ci } 370cb93a386Sopenharmony_ci wgpu::VertexBufferLayout input; 371cb93a386Sopenharmony_ci input.arrayStride = offset; 372cb93a386Sopenharmony_ci input.stepMode = wgpu::VertexStepMode::Instance; 373cb93a386Sopenharmony_ci input.attributeCount = instanceAttributes.size(); 374cb93a386Sopenharmony_ci input.attributes = &instanceAttributes.front(); 375cb93a386Sopenharmony_ci inputs.push_back(input); 376cb93a386Sopenharmony_ci } 377cb93a386Sopenharmony_ci wgpu::VertexState vertexState; 378cb93a386Sopenharmony_ci vertexState.module = vsModule; 379cb93a386Sopenharmony_ci vertexState.entryPoint = "main"; 380cb93a386Sopenharmony_ci vertexState.bufferCount = inputs.size(); 381cb93a386Sopenharmony_ci vertexState.buffers = &inputs.front(); 382cb93a386Sopenharmony_ci 383cb93a386Sopenharmony_ci wgpu::BlendState blendState = create_blend_state(gpu, pipeline); 384cb93a386Sopenharmony_ci 385cb93a386Sopenharmony_ci wgpu::ColorTargetState colorTargetState; 386cb93a386Sopenharmony_ci colorTargetState.format = colorFormat; 387cb93a386Sopenharmony_ci colorTargetState.blend = &blendState; 388cb93a386Sopenharmony_ci 389cb93a386Sopenharmony_ci bool writeColor = pipeline.getXferProcessor().getBlendInfo().fWriteColor; 390cb93a386Sopenharmony_ci colorTargetState.writeMask = writeColor ? wgpu::ColorWriteMask::All 391cb93a386Sopenharmony_ci : wgpu::ColorWriteMask::None; 392cb93a386Sopenharmony_ci 393cb93a386Sopenharmony_ci wgpu::FragmentState fragmentState; 394cb93a386Sopenharmony_ci fragmentState.module = fsModule; 395cb93a386Sopenharmony_ci fragmentState.entryPoint = "main"; 396cb93a386Sopenharmony_ci fragmentState.targetCount = 1; 397cb93a386Sopenharmony_ci fragmentState.targets = &colorTargetState; 398cb93a386Sopenharmony_ci 399cb93a386Sopenharmony_ci wgpu::RenderPipelineDescriptor rpDesc; 400cb93a386Sopenharmony_ci rpDesc.layout = pipelineLayout; 401cb93a386Sopenharmony_ci rpDesc.vertex = vertexState; 402cb93a386Sopenharmony_ci rpDesc.primitive.topology = to_dawn_primitive_topology(programInfo.primitiveType()); 403cb93a386Sopenharmony_ci GrPrimitiveType primitiveType = programInfo.primitiveType(); 404cb93a386Sopenharmony_ci if (primitiveType == GrPrimitiveType::kTriangleStrip || 405cb93a386Sopenharmony_ci primitiveType == GrPrimitiveType::kLineStrip) { 406cb93a386Sopenharmony_ci rpDesc.primitive.stripIndexFormat = wgpu::IndexFormat::Uint16; 407cb93a386Sopenharmony_ci } 408cb93a386Sopenharmony_ci if (hasDepthStencil) { 409cb93a386Sopenharmony_ci rpDesc.depthStencil = &depthStencilState; 410cb93a386Sopenharmony_ci } 411cb93a386Sopenharmony_ci rpDesc.fragment = &fragmentState; 412cb93a386Sopenharmony_ci result->fRenderPipeline = gpu->device().CreateRenderPipeline(&rpDesc); 413cb93a386Sopenharmony_ci return result; 414cb93a386Sopenharmony_ci} 415cb93a386Sopenharmony_ci 416cb93a386Sopenharmony_ciGrDawnProgramBuilder::GrDawnProgramBuilder(GrDawnGpu* gpu, 417cb93a386Sopenharmony_ci const GrProgramInfo& programInfo, 418cb93a386Sopenharmony_ci GrProgramDesc* desc) 419cb93a386Sopenharmony_ci : INHERITED(*desc, programInfo) 420cb93a386Sopenharmony_ci , fGpu(gpu) 421cb93a386Sopenharmony_ci , fVaryingHandler(this) 422cb93a386Sopenharmony_ci , fUniformHandler(this) { 423cb93a386Sopenharmony_ci} 424cb93a386Sopenharmony_ci 425cb93a386Sopenharmony_ciwgpu::ShaderModule GrDawnProgramBuilder::createShaderModule(const GrGLSLShaderBuilder& builder, 426cb93a386Sopenharmony_ci SkSL::ProgramKind kind, 427cb93a386Sopenharmony_ci bool flipY, 428cb93a386Sopenharmony_ci SkSL::Program::Inputs* inputs) { 429cb93a386Sopenharmony_ci wgpu::Device device = fGpu->device(); 430cb93a386Sopenharmony_ci SkString source(builder.fCompilerString.c_str()); 431cb93a386Sopenharmony_ci 432cb93a386Sopenharmony_ci#if 0 433cb93a386Sopenharmony_ci SkSL::String sksl = GrShaderUtils::PrettyPrint(builder.fCompilerString); 434cb93a386Sopenharmony_ci printf("converting program:\n%s\n", sksl.c_str()); 435cb93a386Sopenharmony_ci#endif 436cb93a386Sopenharmony_ci 437cb93a386Sopenharmony_ci SkSL::String spirvSource = fGpu->SkSLToSPIRV(source.c_str(), 438cb93a386Sopenharmony_ci kind, 439cb93a386Sopenharmony_ci fUniformHandler.getRTFlipOffset(), 440cb93a386Sopenharmony_ci inputs); 441cb93a386Sopenharmony_ci if (inputs->fUseFlipRTUniform) { 442cb93a386Sopenharmony_ci this->addRTFlipUniform(SKSL_RTFLIP_NAME); 443cb93a386Sopenharmony_ci } 444cb93a386Sopenharmony_ci 445cb93a386Sopenharmony_ci return fGpu->createShaderModule(spirvSource); 446cb93a386Sopenharmony_ci}; 447cb93a386Sopenharmony_ci 448cb93a386Sopenharmony_ciconst GrCaps* GrDawnProgramBuilder::caps() const { 449cb93a386Sopenharmony_ci return fGpu->caps(); 450cb93a386Sopenharmony_ci} 451cb93a386Sopenharmony_ci 452cb93a386Sopenharmony_ciSkSL::Compiler* GrDawnProgramBuilder::shaderCompiler() const { 453cb93a386Sopenharmony_ci return fGpu->shaderCompiler(); 454cb93a386Sopenharmony_ci} 455cb93a386Sopenharmony_ci 456cb93a386Sopenharmony_civoid GrDawnProgram::setRenderTargetState(const GrRenderTarget* rt, GrSurfaceOrigin origin) { 457cb93a386Sopenharmony_ci // Set RT adjustment and RT flip 458cb93a386Sopenharmony_ci SkISize dimensions = rt->dimensions(); 459cb93a386Sopenharmony_ci SkASSERT(fBuiltinUniformHandles.fRTAdjustmentUni.isValid()); 460cb93a386Sopenharmony_ci if (fRenderTargetState.fRenderTargetOrigin != origin || 461cb93a386Sopenharmony_ci fRenderTargetState.fRenderTargetSize != dimensions) { 462cb93a386Sopenharmony_ci fRenderTargetState.fRenderTargetSize = dimensions; 463cb93a386Sopenharmony_ci fRenderTargetState.fRenderTargetOrigin = origin; 464cb93a386Sopenharmony_ci 465cb93a386Sopenharmony_ci // The client will mark a swap buffer as kTopLeft when making a SkSurface because 466cb93a386Sopenharmony_ci // Dawn's framebuffer space has (0, 0) at the top left. This agrees with Skia's device 467cb93a386Sopenharmony_ci // coords. However, in NDC (-1, -1) is the bottom left. So we flip when origin is kTopLeft. 468cb93a386Sopenharmony_ci bool flip = (origin == kTopLeft_GrSurfaceOrigin); 469cb93a386Sopenharmony_ci std::array<float, 4> v = SkSL::Compiler::GetRTAdjustVector(dimensions, flip); 470cb93a386Sopenharmony_ci fDataManager.set4fv(fBuiltinUniformHandles.fRTAdjustmentUni, 1, v.data()); 471cb93a386Sopenharmony_ci if (fBuiltinUniformHandles.fRTFlipUni.isValid()) { 472cb93a386Sopenharmony_ci // Note above that framebuffer space has origin top left. So we need !flip here. 473cb93a386Sopenharmony_ci std::array<float, 2> d = SkSL::Compiler::GetRTFlipVector(rt->height(), !flip); 474cb93a386Sopenharmony_ci fDataManager.set2fv(fBuiltinUniformHandles.fRTFlipUni, 1, d.data()); 475cb93a386Sopenharmony_ci } 476cb93a386Sopenharmony_ci } 477cb93a386Sopenharmony_ci} 478cb93a386Sopenharmony_ci 479cb93a386Sopenharmony_cistatic void set_texture(GrDawnGpu* gpu, GrSamplerState state, GrTexture* texture, 480cb93a386Sopenharmony_ci std::vector<wgpu::BindGroupEntry>* bindings, int* binding) { 481cb93a386Sopenharmony_ci // FIXME: could probably cache samplers in GrDawnProgram 482cb93a386Sopenharmony_ci wgpu::Sampler sampler = gpu->getOrCreateSampler(state); 483cb93a386Sopenharmony_ci bindings->push_back(make_bind_group_entry((*binding)++, sampler)); 484cb93a386Sopenharmony_ci GrDawnTexture* tex = static_cast<GrDawnTexture*>(texture); 485cb93a386Sopenharmony_ci wgpu::TextureViewDescriptor viewDesc; 486cb93a386Sopenharmony_ci // Note that a mipLevelCount == WGPU_MIP_LEVEL_COUNT_UNDEFINED here means to expose all 487cb93a386Sopenharmony_ci // available levels. 488cb93a386Sopenharmony_ci viewDesc.mipLevelCount = GrSamplerState::MipmapMode::kNone == state.mipmapMode() 489cb93a386Sopenharmony_ci ? 1 490cb93a386Sopenharmony_ci : WGPU_MIP_LEVEL_COUNT_UNDEFINED; 491cb93a386Sopenharmony_ci wgpu::TextureView textureView = tex->texture().CreateView(&viewDesc); 492cb93a386Sopenharmony_ci bindings->push_back(make_bind_group_entry((*binding)++, textureView)); 493cb93a386Sopenharmony_ci} 494cb93a386Sopenharmony_ci 495cb93a386Sopenharmony_ciwgpu::BindGroup GrDawnProgram::setUniformData(GrDawnGpu* gpu, const GrRenderTarget* renderTarget, 496cb93a386Sopenharmony_ci const GrProgramInfo& programInfo) { 497cb93a386Sopenharmony_ci if (0 == fDataManager.uniformBufferSize()) { 498cb93a386Sopenharmony_ci return nullptr; 499cb93a386Sopenharmony_ci } 500cb93a386Sopenharmony_ci this->setRenderTargetState(renderTarget, programInfo.origin()); 501cb93a386Sopenharmony_ci const GrPipeline& pipeline = programInfo.pipeline(); 502cb93a386Sopenharmony_ci const GrGeometryProcessor& geomProc = programInfo.geomProc(); 503cb93a386Sopenharmony_ci fGPImpl->setData(fDataManager, *gpu->caps()->shaderCaps(), geomProc); 504cb93a386Sopenharmony_ci 505cb93a386Sopenharmony_ci for (int i = 0; i < programInfo.pipeline().numFragmentProcessors(); ++i) { 506cb93a386Sopenharmony_ci const auto& fp = programInfo.pipeline().getFragmentProcessor(i); 507cb93a386Sopenharmony_ci fp.visitWithImpls([&](const GrFragmentProcessor& fp, 508cb93a386Sopenharmony_ci GrFragmentProcessor::ProgramImpl& impl) { 509cb93a386Sopenharmony_ci impl.setData(fDataManager, fp); 510cb93a386Sopenharmony_ci }, *fFPImpls[i]); 511cb93a386Sopenharmony_ci } 512cb93a386Sopenharmony_ci 513cb93a386Sopenharmony_ci programInfo.pipeline().setDstTextureUniforms(fDataManager, &fBuiltinUniformHandles); 514cb93a386Sopenharmony_ci fXPImpl->setData(fDataManager, pipeline.getXferProcessor()); 515cb93a386Sopenharmony_ci 516cb93a386Sopenharmony_ci return fDataManager.uploadUniformBuffers(gpu, fBindGroupLayouts[0]); 517cb93a386Sopenharmony_ci} 518cb93a386Sopenharmony_ci 519cb93a386Sopenharmony_ciwgpu::BindGroup GrDawnProgram::setTextures(GrDawnGpu* gpu, 520cb93a386Sopenharmony_ci const GrGeometryProcessor& geomProc, 521cb93a386Sopenharmony_ci const GrPipeline& pipeline, 522cb93a386Sopenharmony_ci const GrSurfaceProxy* const geomProcTextures[]) { 523cb93a386Sopenharmony_ci if (fBindGroupLayouts.size() < 2) { 524cb93a386Sopenharmony_ci return nullptr; 525cb93a386Sopenharmony_ci } 526cb93a386Sopenharmony_ci std::vector<wgpu::BindGroupEntry> bindings; 527cb93a386Sopenharmony_ci int binding = 0; 528cb93a386Sopenharmony_ci if (geomProcTextures) { 529cb93a386Sopenharmony_ci for (int i = 0; i < geomProc.numTextureSamplers(); ++i) { 530cb93a386Sopenharmony_ci SkASSERT(geomProcTextures[i]->asTextureProxy()); 531cb93a386Sopenharmony_ci auto& sampler = geomProc.textureSampler(i); 532cb93a386Sopenharmony_ci set_texture(gpu, sampler.samplerState(), geomProcTextures[i]->peekTexture(), &bindings, 533cb93a386Sopenharmony_ci &binding); 534cb93a386Sopenharmony_ci } 535cb93a386Sopenharmony_ci } 536cb93a386Sopenharmony_ci 537cb93a386Sopenharmony_ci if (GrTexture* dstTexture = pipeline.peekDstTexture()) { 538cb93a386Sopenharmony_ci set_texture(gpu, GrSamplerState::Filter::kNearest, dstTexture, &bindings, &binding); 539cb93a386Sopenharmony_ci } 540cb93a386Sopenharmony_ci 541cb93a386Sopenharmony_ci pipeline.visitTextureEffects([&](const GrTextureEffect& te) { 542cb93a386Sopenharmony_ci set_texture(gpu, te.samplerState(), te.texture(), &bindings, &binding); 543cb93a386Sopenharmony_ci }); 544cb93a386Sopenharmony_ci 545cb93a386Sopenharmony_ci wgpu::BindGroupDescriptor descriptor; 546cb93a386Sopenharmony_ci descriptor.layout = fBindGroupLayouts[1]; 547cb93a386Sopenharmony_ci descriptor.entryCount = bindings.size(); 548cb93a386Sopenharmony_ci descriptor.entries = bindings.data(); 549cb93a386Sopenharmony_ci return gpu->device().CreateBindGroup(&descriptor); 550cb93a386Sopenharmony_ci} 551