/* * Copyright 2019 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef GrDawnProgramBuilder_DEFINED #define GrDawnProgramBuilder_DEFINED #include "src/gpu/dawn/GrDawnProgramDataManager.h" #include "src/gpu/dawn/GrDawnUniformHandler.h" #include "src/gpu/dawn/GrDawnVaryingHandler.h" #include "src/sksl/SkSLCompiler.h" #include "dawn/dawncpp.h" #include "src/gpu/glsl/GrGLSLProgramBuilder.h" class GrPipeline; struct GrDawnProgram : public SkRefCnt { struct RenderTargetState { SkISize fRenderTargetSize; GrSurfaceOrigin fRenderTargetOrigin; RenderTargetState() { this->invalidate(); } void invalidate() { fRenderTargetSize.fWidth = -1; fRenderTargetSize.fHeight = -1; fRenderTargetOrigin = (GrSurfaceOrigin) -1; } /** * Gets a float4 that adjusts the position from Skia device coords to GL's normalized device * coords. Assuming the transformed position, pos, is a homogeneous float3, the vec, v, is * applied as such: * pos.x = dot(v.xy, pos.xz) * pos.y = dot(v.zw, pos.yz) */ void getRTAdjustmentVec(float* destVec) { destVec[0] = 2.f / fRenderTargetSize.fWidth; destVec[1] = -1.f; if (kBottomLeft_GrSurfaceOrigin == fRenderTargetOrigin) { destVec[2] = -2.f / fRenderTargetSize.fHeight; destVec[3] = 1.f; } else { destVec[2] = 2.f / fRenderTargetSize.fHeight; destVec[3] = -1.f; } } }; typedef GrGLSLBuiltinUniformHandles BuiltinUniformHandles; GrDawnProgram(const GrDawnUniformHandler::UniformInfoArray& uniforms, uint32_t geometryUniformSize, uint32_t fragmentUniformSize) : fDataManager(uniforms, geometryUniformSize, fragmentUniformSize) { } dawn::ShaderModule fVSModule; dawn::ShaderModule fFSModule; std::unique_ptr fGeometryProcessor; std::unique_ptr fXferProcessor; std::unique_ptr[]> fFragmentProcessors; int fFragmentProcessorCnt; dawn::Buffer fGeometryUniformBuffer; dawn::Buffer fFragmentUniformBuffer; dawn::PipelineLayout fPipelineLayout; dawn::BindGroup fBindGroup; dawn::ColorStateDescriptor fColorState; dawn::DepthStencilStateDescriptor fDepthStencilState; GrDawnProgramDataManager fDataManager; RenderTargetState fRenderTargetState; BuiltinUniformHandles fBuiltinUniformHandles; void setRenderTargetState(const GrRenderTarget*, GrSurfaceOrigin); void setData(const GrPrimitiveProcessor&, const GrRenderTarget*, GrSurfaceOrigin, const GrPipeline&); }; class GrDawnProgramBuilder : public GrGLSLProgramBuilder { public: static sk_sp Build(GrDawnGpu*, GrRenderTarget* renderTarget, GrSurfaceOrigin origin, const GrPipeline&, const GrPrimitiveProcessor&, const GrTextureProxy* const primProcProxies[], dawn::TextureFormat colorFormat, bool hasDepthStencil, dawn::TextureFormat depthStencilFormat, GrProgramDesc* desc); const GrCaps* caps() const override; GrGLSLUniformHandler* uniformHandler() override { return &fUniformHandler; } const GrGLSLUniformHandler* uniformHandler() const override { return &fUniformHandler; } GrGLSLVaryingHandler* varyingHandler() override { return &fVaryingHandler; } GrDawnGpu* gpu() const { return fGpu; } private: GrDawnProgramBuilder(GrDawnGpu*, GrRenderTarget*, GrSurfaceOrigin, const GrPrimitiveProcessor&, const GrTextureProxy* const primProcProxies[], const GrPipeline&, GrProgramDesc*); dawn::ShaderModule createShaderModule(const GrGLSLShaderBuilder&, SkSL::Program::Kind, SkSL::Program::Inputs* inputs); GrDawnGpu* fGpu; GrDawnVaryingHandler fVaryingHandler; GrDawnUniformHandler fUniformHandler; typedef GrGLSLProgramBuilder INHERITED; }; #endif