1 /*
2  * Copyright 2018 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #ifndef GrMtlPipelineState_DEFINED
9 #define GrMtlPipelineState_DEFINED
10 
11 #include "include/private/GrTypesPriv.h"
12 #include "src/gpu/GrStencilSettings.h"
13 #include "src/gpu/glsl/GrGLSLProgramBuilder.h"
14 #include "src/gpu/mtl/GrMtlBuffer.h"
15 #include "src/gpu/mtl/GrMtlPipelineStateDataManager.h"
16 
17 #import <Metal/Metal.h>
18 
19 class GrMtlGpu;
20 class GrMtlPipelineStateDataManager;
21 class GrMtlSampler;
22 class GrMtlTexture;
23 class GrPipeline;
24 
25 /**
26  * Wraps a MTLRenderPipelineState object and also contains more info about the pipeline as needed
27  * by Ganesh
28  */
29 class GrMtlPipelineState {
30 public:
31     using UniformInfoArray = GrMtlPipelineStateDataManager::UniformInfoArray;
32     using UniformHandle = GrGLSLProgramDataManager::UniformHandle;
33 
34     GrMtlPipelineState(
35             GrMtlGpu* gpu,
36             id<MTLRenderPipelineState> pipelineState,
37             MTLPixelFormat pixelFormat,
38             const GrGLSLBuiltinUniformHandles& builtinUniformHandles,
39             const UniformInfoArray& uniforms,
40             uint32_t uniformBufferSize,
41             uint32_t numSamplers,
42             std::unique_ptr<GrGLSLPrimitiveProcessor> geometryProcessor,
43             std::unique_ptr<GrGLSLXferProcessor> xferPRocessor,
44             std::unique_ptr<std::unique_ptr<GrGLSLFragmentProcessor>[]> fragmentProcessors,
45             int fFragmentProcessorCnt);
46 
mtlPipelineState()47     id<MTLRenderPipelineState> mtlPipelineState() { return fPipelineState; }
48 
49     void setData(const GrRenderTarget*, const GrProgramInfo&);
50 
51     void setDrawState(id<MTLRenderCommandEncoder>, const GrSwizzle& outputSwizzle,
52                       const GrXferProcessor&);
53 
54     static void SetDynamicScissorRectState(id<MTLRenderCommandEncoder> renderCmdEncoder,
55                                            const GrRenderTarget* renderTarget,
56                                            GrSurfaceOrigin rtOrigin,
57                                            SkIRect scissorRect);
58 
59     bool doesntSampleAttachment(const MTLRenderPassAttachmentDescriptor*) const;
60 
61 private:
62     /**
63     * We use the RT's size and origin to adjust from Skia device space to Metal normalized device
64     * space and to make device space positions have the correct origin for processors that require
65     * them.
66     */
67     struct RenderTargetState {
68         SkISize         fRenderTargetSize;
69         GrSurfaceOrigin fRenderTargetOrigin;
70 
RenderTargetStateRenderTargetState71         RenderTargetState() { this->invalidate(); }
invalidateRenderTargetState72         void invalidate() {
73             fRenderTargetSize.fWidth = -1;
74             fRenderTargetSize.fHeight = -1;
75             fRenderTargetOrigin = (GrSurfaceOrigin)-1;
76         }
77 
78         /**
79         * Gets a float4 that adjusts the position from Skia device coords to Metals normalized
80         * device coords. Assuming the transformed position, pos, is a homogeneous float3, the vec,
81         * v, is applied as such:
82         * pos.x = dot(v.xy, pos.xz)
83         * pos.y = dot(v.zw, pos.yz)
84         */
getRTAdjustmentVecRenderTargetState85         void getRTAdjustmentVec(float* destVec) {
86             destVec[0] = 2.f / fRenderTargetSize.fWidth;
87             destVec[1] = -1.f;
88             if (kBottomLeft_GrSurfaceOrigin == fRenderTargetOrigin) {
89                 destVec[2] = -2.f / fRenderTargetSize.fHeight;
90                 destVec[3] = 1.f;
91             } else {
92                 destVec[2] = 2.f / fRenderTargetSize.fHeight;
93                 destVec[3] = -1.f;
94             }
95         }
96     };
97 
98     void setRenderTargetState(const GrRenderTarget*, GrSurfaceOrigin);
99 
100     void bind(id<MTLRenderCommandEncoder>);
101 
102     void setBlendConstants(id<MTLRenderCommandEncoder>, const GrSwizzle&, const GrXferProcessor&);
103 
104     void setDepthStencilState(id<MTLRenderCommandEncoder> renderCmdEncoder);
105 
106     struct SamplerBindings {
107         GrMtlSampler*  fSampler;
108         id<MTLTexture> fTexture;
109 
110         SamplerBindings(const GrSamplerState& state, GrTexture* texture, GrMtlGpu*);
111     };
112 
113     GrMtlGpu* fGpu;
114     id<MTLRenderPipelineState> fPipelineState;
115     MTLPixelFormat             fPixelFormat;
116 
117     RenderTargetState fRenderTargetState;
118     GrGLSLBuiltinUniformHandles fBuiltinUniformHandles;
119 
120     GrStencilSettings fStencil;
121 
122     int fNumSamplers;
123     SkTArray<SamplerBindings> fSamplerBindings;
124 
125     std::unique_ptr<GrGLSLPrimitiveProcessor> fGeometryProcessor;
126     std::unique_ptr<GrGLSLXferProcessor> fXferProcessor;
127     std::unique_ptr<std::unique_ptr<GrGLSLFragmentProcessor>[]> fFragmentProcessors;
128     int fFragmentProcessorCnt;
129 
130     GrMtlPipelineStateDataManager fDataManager;
131 };
132 
133 #endif
134