blob: bcb62b2269edd7f90011b403fec10aff52dcc21c [file] [log] [blame]
Timothy Liang7ac582e2018-08-06 09:47:23 -04001/*
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
Timothy Liang057c3902018-08-08 10:48:45 -040011#include "GrMtlBuffer.h"
Timothy Liang6ed63962018-08-10 09:49:44 -040012#include "GrMtlPipelineStateDataManager.h"
Ethan Nicholas01063512018-10-08 16:58:25 -040013#include "GrStencilSettings.h"
Timothy Liangde0be802018-08-10 13:48:08 -040014#include "GrTypesPriv.h"
Timothy Liang6ed63962018-08-10 09:49:44 -040015#include "glsl/GrGLSLProgramBuilder.h"
Timothy Liang057c3902018-08-08 10:48:45 -040016
Timothy Liang7ac582e2018-08-06 09:47:23 -040017#import <metal/metal.h>
18
19class GrMtlGpu;
Timothy Liang6ed63962018-08-10 09:49:44 -040020class GrMtlPipelineStateDataManager;
21class GrMtlSampler;
22class GrMtlTexture;
23class GrPipeline;
Timothy Liang7ac582e2018-08-06 09:47:23 -040024
Timothy Liang057c3902018-08-08 10:48:45 -040025/**
26 * Wraps a MTLRenderPipelineState object and also contains more info about the pipeline as needed
27 * by Ganesh
28 */
Timothy Liang7ac582e2018-08-06 09:47:23 -040029class GrMtlPipelineState {
30public:
Timothy Liang6ed63962018-08-10 09:49:44 -040031 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,
Brian Salomon12d22642019-01-29 14:38:50 -050040 sk_sp<GrMtlBuffer> geometryUniformBuffer,
41 sk_sp<GrMtlBuffer> fragmentUniformBuffer,
Timothy Liang6ed63962018-08-10 09:49:44 -040042 uint32_t numSamplers,
43 std::unique_ptr<GrGLSLPrimitiveProcessor> geometryProcessor,
44 std::unique_ptr<GrGLSLXferProcessor> xferPRocessor,
45 std::unique_ptr<std::unique_ptr<GrGLSLFragmentProcessor>[]> fragmentProcessors,
46 int fFragmentProcessorCnt);
Timothy Liang7ac582e2018-08-06 09:47:23 -040047
48 id<MTLRenderPipelineState> mtlPipelineState() { return fPipelineState; }
49
Robert Phillipsd0fe8752019-01-31 14:13:59 -050050 void setData(const GrRenderTarget*, GrSurfaceOrigin,
51 const GrPrimitiveProcessor& primPRoc, const GrPipeline& pipeline,
Timothy Liang6ed63962018-08-10 09:49:44 -040052 const GrTextureProxy* const primProcTextures[]);
Timothy Liang057c3902018-08-08 10:48:45 -040053
Timothy Liang6ed63962018-08-10 09:49:44 -040054 void bind(id<MTLRenderCommandEncoder>);
55
Timothy Liangde0be802018-08-10 13:48:08 -040056 void setBlendConstants(id<MTLRenderCommandEncoder>, GrPixelConfig, const GrXferProcessor&);
57
Ethan Nicholas01063512018-10-08 16:58:25 -040058 void setDepthStencilState(id<MTLRenderCommandEncoder> renderCmdEncoder);
59
Timothy Liang6ed63962018-08-10 09:49:44 -040060private:
61 /**
62 * We use the RT's size and origin to adjust from Skia device space to Metal normalized device
63 * space and to make device space positions have the correct origin for processors that require
64 * them.
65 */
66 struct RenderTargetState {
67 SkISize fRenderTargetSize;
68 GrSurfaceOrigin fRenderTargetOrigin;
69
70 RenderTargetState() { this->invalidate(); }
71 void invalidate() {
72 fRenderTargetSize.fWidth = -1;
73 fRenderTargetSize.fHeight = -1;
74 fRenderTargetOrigin = (GrSurfaceOrigin)-1;
75 }
76
77 /**
78 * Gets a float4 that adjusts the position from Skia device coords to Metals normalized
79 * device coords. Assuming the transformed position, pos, is a homogeneous float3, the vec,
80 * v, is applied as such:
81 * pos.x = dot(v.xy, pos.xz)
82 * pos.y = dot(v.zw, pos.yz)
83 */
84 void getRTAdjustmentVec(float* destVec) {
85 destVec[0] = 2.f / fRenderTargetSize.fWidth;
86 destVec[1] = -1.f;
87 if (kBottomLeft_GrSurfaceOrigin == fRenderTargetOrigin) {
88 destVec[2] = -2.f / fRenderTargetSize.fHeight;
89 destVec[3] = 1.f;
90 } else {
91 destVec[2] = 2.f / fRenderTargetSize.fHeight;
92 destVec[3] = -1.f;
93 }
94 }
95 };
96
Robert Phillipsd0fe8752019-01-31 14:13:59 -050097 void setRenderTargetState(const GrRenderTarget*, GrSurfaceOrigin);
Timothy Liang6ed63962018-08-10 09:49:44 -040098
99 struct SamplerBindings {
100 id<MTLSamplerState> fSampler;
101 id<MTLTexture> fTexture;
Timothy Liang6ed63962018-08-10 09:49:44 -0400102
Greg Daniel0f70be82018-10-08 17:35:08 +0000103 SamplerBindings(const GrSamplerState& state, GrTexture* texture, GrMtlGpu*);
Timothy Liang6ed63962018-08-10 09:49:44 -0400104 };
105
106 GrMtlGpu* fGpu;
Timothy Liang7ac582e2018-08-06 09:47:23 -0400107 id<MTLRenderPipelineState> fPipelineState;
Timothy Liang057c3902018-08-08 10:48:45 -0400108 MTLPixelFormat fPixelFormat;
Timothy Liang6ed63962018-08-10 09:49:44 -0400109
110 RenderTargetState fRenderTargetState;
111 GrGLSLBuiltinUniformHandles fBuiltinUniformHandles;
112
Ethan Nicholas01063512018-10-08 16:58:25 -0400113 GrStencilSettings fStencil;
114
Timothy Liang6ed63962018-08-10 09:49:44 -0400115 sk_sp<GrMtlBuffer> fGeometryUniformBuffer;
116 sk_sp<GrMtlBuffer> fFragmentUniformBuffer;
117
118 int fNumSamplers;
119 SkTArray<SamplerBindings> fSamplerBindings;
120
121 std::unique_ptr<GrGLSLPrimitiveProcessor> fGeometryProcessor;
122 std::unique_ptr<GrGLSLXferProcessor> fXferProcessor;
123 std::unique_ptr<std::unique_ptr<GrGLSLFragmentProcessor>[]> fFragmentProcessors;
124 int fFragmentProcessorCnt;
125
126 GrMtlPipelineStateDataManager fDataManager;
Timothy Liang7ac582e2018-08-06 09:47:23 -0400127};
128
129#endif