1 /* 2 * Copyright 2020 Google LLC 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 GrD3DPipelineState_DEFINED 9 #define GrD3DPipelineState_DEFINED 10 11 #include "include/core/SkRefCnt.h" 12 #include "include/gpu/GrTypes.h" 13 #include "include/gpu/d3d/GrD3DTypes.h" 14 #include "src/gpu/GrManagedResource.h" 15 #include "src/gpu/d3d/GrD3DPipelineStateDataManager.h" 16 #include "src/gpu/glsl/GrGLSLProgramBuilder.h" 17 18 class GrD3DDirectCommandList; 19 class GrD3DGpu; 20 class GrD3DRootSignature; 21 class GrProgramInfo; 22 23 class GrD3DPipelineState : public GrManagedResource { 24 public: 25 using UniformInfoArray = GrD3DPipelineStateDataManager::UniformInfoArray; 26 27 GrD3DPipelineState(gr_cp<ID3D12PipelineState> pipelineState, 28 sk_sp<GrD3DRootSignature> rootSignature, 29 const GrGLSLBuiltinUniformHandles& builtinUniformHandles, 30 const UniformInfoArray& uniforms, 31 uint32_t uniformSize, 32 uint32_t numSamplers, 33 std::unique_ptr<GrGLSLPrimitiveProcessor> geometryProcessor, 34 std::unique_ptr<GrGLSLXferProcessor> xferProcessor, 35 std::unique_ptr<std::unique_ptr<GrGLSLFragmentProcessor>[]> fragProcessors, 36 size_t vertexStride, 37 size_t instanceStride); 38 39 #ifdef SK_TRACE_MANAGED_RESOURCES 40 /** Output a human-readable dump of this resource's information 41 */ dumpInfo()42 void dumpInfo() const override { 43 SkDebugf("GrD3DPipelineState: %p (%d refs)\n", fPipelineState.get(), this->getRefCnt()); 44 } 45 #endif 46 47 // This will be called right before this class is destroyed and there is no reason to explicitly 48 // release the fPipelineState cause the gr_cp will handle that in the dtor. freeGPUData()49 void freeGPUData() const override {} 50 pipelineState()51 ID3D12PipelineState* pipelineState() const { return fPipelineState.get(); } rootSignature()52 const sk_sp<GrD3DRootSignature>& rootSignature() const { return fRootSignature; } 53 54 void setAndBindConstants(GrD3DGpu*, const GrRenderTarget*, const GrProgramInfo&); 55 56 void setAndBindTextures(GrD3DGpu*, const GrPrimitiveProcessor& primProc, 57 const GrSurfaceProxy* const primProcTextures[], 58 const GrPipeline& pipeline); 59 60 void bindBuffers(GrD3DGpu*, sk_sp<const GrBuffer> indexBuffer, 61 sk_sp<const GrBuffer> instanceBuffer, sk_sp<const GrBuffer> vertexBuffer, 62 GrD3DDirectCommandList* commandList); 63 64 // We can only cache non dirty uniform values until we submit a command list. After that, the 65 // next frame will get a completely different uniform buffer and/or offset into the buffer. Thus 66 // we need a way to mark them all as dirty during submit. markUniformsDirty()67 void markUniformsDirty() { fDataManager.markDirty(); } 68 69 private: 70 /** 71 * We use the RT's size and origin to adjust from Skia device space to d3d normalized device 72 * space and to make device space positions have the correct origin for processors that require 73 * them. 74 */ 75 struct RenderTargetState { 76 SkISize fRenderTargetSize; 77 GrSurfaceOrigin fRenderTargetOrigin; 78 RenderTargetStateRenderTargetState79 RenderTargetState() { this->invalidate(); } invalidateRenderTargetState80 void invalidate() { 81 fRenderTargetSize.fWidth = -1; 82 fRenderTargetSize.fHeight = -1; 83 fRenderTargetOrigin = (GrSurfaceOrigin)-1; 84 } 85 86 /** 87 * Gets a float4 that adjusts the position from Skia device coords to D3D's normalized device 88 * coords. Assuming the transformed position, pos, is a homogeneous float3, the vec, v, is 89 * applied as such: 90 * pos.x = dot(v.xy, pos.xz) 91 * pos.y = dot(v.zw, pos.yz) 92 */ getRTAdjustmentVecRenderTargetState93 void getRTAdjustmentVec(float* destVec) { 94 destVec[0] = 2.f / fRenderTargetSize.fWidth; 95 destVec[1] = -1.f; 96 // D3D's NDC space is flipped from Vulkan and Metal 97 if (kTopLeft_GrSurfaceOrigin == fRenderTargetOrigin) { 98 destVec[2] = -2.f / fRenderTargetSize.fHeight; 99 destVec[3] = 1.f; 100 } else { 101 destVec[2] = 2.f / fRenderTargetSize.fHeight; 102 destVec[3] = -1.f; 103 } 104 } 105 }; 106 107 // Helper for setData() that sets the view matrix and loads the render target height uniform 108 void setRenderTargetState(const GrRenderTarget*, GrSurfaceOrigin); 109 110 gr_cp<ID3D12PipelineState> fPipelineState; 111 sk_sp<GrD3DRootSignature> fRootSignature; 112 113 // Tracks the current render target uniforms stored in the vertex buffer. 114 RenderTargetState fRenderTargetState; 115 GrGLSLBuiltinUniformHandles fBuiltinUniformHandles; 116 117 // Processors in the GrD3DPipelineState 118 std::unique_ptr<GrGLSLPrimitiveProcessor> fGeometryProcessor; 119 std::unique_ptr<GrGLSLXferProcessor> fXferProcessor; 120 std::unique_ptr<std::unique_ptr<GrGLSLFragmentProcessor>[]> fFragmentProcessors; 121 122 GrD3DPipelineStateDataManager fDataManager; 123 124 unsigned int fNumSamplers; 125 size_t fVertexStride; 126 size_t fInstanceStride; 127 }; 128 129 #endif 130