xref: /aosp_15_r20/external/skia/src/gpu/ganesh/mtl/GrMtlPipelineStateDataManager.mm (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker/*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2018 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker *
4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker */
7*c8dee2aaSAndroid Build Coastguard Worker
8*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/ganesh/mtl/GrMtlPipelineStateDataManager.h"
9*c8dee2aaSAndroid Build Coastguard Worker
10*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/ganesh/mtl/GrMtlBuffer.h"
11*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/ganesh/mtl/GrMtlGpu.h"
12*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/ganesh/mtl/GrMtlRenderCommandEncoder.h"
13*c8dee2aaSAndroid Build Coastguard Worker
14*c8dee2aaSAndroid Build Coastguard Worker#if !__has_feature(objc_arc)
15*c8dee2aaSAndroid Build Coastguard Worker#error This file must be compiled with Arc. Use -fobjc-arc flag
16*c8dee2aaSAndroid Build Coastguard Worker#endif
17*c8dee2aaSAndroid Build Coastguard Worker
18*c8dee2aaSAndroid Build Coastguard WorkerGR_NORETAIN_BEGIN
19*c8dee2aaSAndroid Build Coastguard Worker
20*c8dee2aaSAndroid Build Coastguard WorkerGrMtlPipelineStateDataManager::GrMtlPipelineStateDataManager(const UniformInfoArray& uniforms,
21*c8dee2aaSAndroid Build Coastguard Worker                                                             uint32_t uniformSize)
22*c8dee2aaSAndroid Build Coastguard Worker        : INHERITED(uniforms.count(), uniformSize) {
23*c8dee2aaSAndroid Build Coastguard Worker    // We must add uniforms in same order is the UniformInfoArray so that UniformHandles already
24*c8dee2aaSAndroid Build Coastguard Worker    // owned by other objects will still match up here.
25*c8dee2aaSAndroid Build Coastguard Worker    int i = 0;
26*c8dee2aaSAndroid Build Coastguard Worker    for (const auto& uniformInfo : uniforms.items()) {
27*c8dee2aaSAndroid Build Coastguard Worker        Uniform& uniform = fUniforms[i];
28*c8dee2aaSAndroid Build Coastguard Worker        SkASSERT(GrShaderVar::kNonArray == uniformInfo.fVariable.getArrayCount() ||
29*c8dee2aaSAndroid Build Coastguard Worker                 uniformInfo.fVariable.getArrayCount() > 0);
30*c8dee2aaSAndroid Build Coastguard Worker        SkDEBUGCODE(
31*c8dee2aaSAndroid Build Coastguard Worker            uniform.fArrayCount = uniformInfo.fVariable.getArrayCount();
32*c8dee2aaSAndroid Build Coastguard Worker        )
33*c8dee2aaSAndroid Build Coastguard Worker        uniform.fOffset = uniformInfo.fUBOffset;
34*c8dee2aaSAndroid Build Coastguard Worker        uniform.fType = uniformInfo.fVariable.getType();
35*c8dee2aaSAndroid Build Coastguard Worker        ++i;
36*c8dee2aaSAndroid Build Coastguard Worker    }
37*c8dee2aaSAndroid Build Coastguard Worker
38*c8dee2aaSAndroid Build Coastguard Worker    fWrite16BitUniforms = true;
39*c8dee2aaSAndroid Build Coastguard Worker}
40*c8dee2aaSAndroid Build Coastguard Worker
41*c8dee2aaSAndroid Build Coastguard Workervoid GrMtlPipelineStateDataManager::set1iv(UniformHandle u,
42*c8dee2aaSAndroid Build Coastguard Worker                                           int arrayCount,
43*c8dee2aaSAndroid Build Coastguard Worker                                           const int32_t v[]) const {
44*c8dee2aaSAndroid Build Coastguard Worker    const Uniform& uni = fUniforms[u.toIndex()];
45*c8dee2aaSAndroid Build Coastguard Worker    SkASSERT(uni.fType == SkSLType::kInt || uni.fType == SkSLType::kShort);
46*c8dee2aaSAndroid Build Coastguard Worker    SkASSERT(arrayCount > 0);
47*c8dee2aaSAndroid Build Coastguard Worker    SkASSERT(arrayCount <= uni.fArrayCount ||
48*c8dee2aaSAndroid Build Coastguard Worker             (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
49*c8dee2aaSAndroid Build Coastguard Worker
50*c8dee2aaSAndroid Build Coastguard Worker    void* buffer = this->getBufferPtrAndMarkDirty(uni);
51*c8dee2aaSAndroid Build Coastguard Worker    this->copyUniforms(buffer, v, arrayCount, uni.fType);
52*c8dee2aaSAndroid Build Coastguard Worker}
53*c8dee2aaSAndroid Build Coastguard Worker
54*c8dee2aaSAndroid Build Coastguard Workervoid GrMtlPipelineStateDataManager::set1fv(UniformHandle u,
55*c8dee2aaSAndroid Build Coastguard Worker                                           int arrayCount,
56*c8dee2aaSAndroid Build Coastguard Worker                                           const float v[]) const {
57*c8dee2aaSAndroid Build Coastguard Worker    const Uniform& uni = fUniforms[u.toIndex()];
58*c8dee2aaSAndroid Build Coastguard Worker    SkASSERT(uni.fType == SkSLType::kFloat || uni.fType == SkSLType::kHalf);
59*c8dee2aaSAndroid Build Coastguard Worker    SkASSERT(arrayCount > 0);
60*c8dee2aaSAndroid Build Coastguard Worker    SkASSERT(arrayCount <= uni.fArrayCount ||
61*c8dee2aaSAndroid Build Coastguard Worker             (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
62*c8dee2aaSAndroid Build Coastguard Worker
63*c8dee2aaSAndroid Build Coastguard Worker    void* buffer = this->getBufferPtrAndMarkDirty(uni);
64*c8dee2aaSAndroid Build Coastguard Worker    this->copyUniforms(buffer, v, arrayCount, uni.fType);
65*c8dee2aaSAndroid Build Coastguard Worker}
66*c8dee2aaSAndroid Build Coastguard Worker
67*c8dee2aaSAndroid Build Coastguard Workervoid GrMtlPipelineStateDataManager::set2iv(UniformHandle u,
68*c8dee2aaSAndroid Build Coastguard Worker                                           int arrayCount,
69*c8dee2aaSAndroid Build Coastguard Worker                                           const int32_t v[]) const {
70*c8dee2aaSAndroid Build Coastguard Worker    const Uniform& uni = fUniforms[u.toIndex()];
71*c8dee2aaSAndroid Build Coastguard Worker    SkASSERT(uni.fType == SkSLType::kInt2 || uni.fType == SkSLType::kShort2);
72*c8dee2aaSAndroid Build Coastguard Worker    SkASSERT(arrayCount > 0);
73*c8dee2aaSAndroid Build Coastguard Worker    SkASSERT(arrayCount <= uni.fArrayCount ||
74*c8dee2aaSAndroid Build Coastguard Worker             (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
75*c8dee2aaSAndroid Build Coastguard Worker
76*c8dee2aaSAndroid Build Coastguard Worker    void* buffer = this->getBufferPtrAndMarkDirty(uni);
77*c8dee2aaSAndroid Build Coastguard Worker    this->copyUniforms(buffer, v, arrayCount * 2, uni.fType);
78*c8dee2aaSAndroid Build Coastguard Worker}
79*c8dee2aaSAndroid Build Coastguard Worker
80*c8dee2aaSAndroid Build Coastguard Workervoid GrMtlPipelineStateDataManager::set2fv(UniformHandle u,
81*c8dee2aaSAndroid Build Coastguard Worker                                           int arrayCount,
82*c8dee2aaSAndroid Build Coastguard Worker                                           const float v[]) const {
83*c8dee2aaSAndroid Build Coastguard Worker    const Uniform& uni = fUniforms[u.toIndex()];
84*c8dee2aaSAndroid Build Coastguard Worker    SkASSERT(uni.fType == SkSLType::kFloat2 || uni.fType == SkSLType::kHalf2);
85*c8dee2aaSAndroid Build Coastguard Worker    SkASSERT(arrayCount > 0);
86*c8dee2aaSAndroid Build Coastguard Worker    SkASSERT(arrayCount <= uni.fArrayCount ||
87*c8dee2aaSAndroid Build Coastguard Worker             (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
88*c8dee2aaSAndroid Build Coastguard Worker
89*c8dee2aaSAndroid Build Coastguard Worker    void* buffer = this->getBufferPtrAndMarkDirty(uni);
90*c8dee2aaSAndroid Build Coastguard Worker    this->copyUniforms(buffer, v, arrayCount * 2, uni.fType);
91*c8dee2aaSAndroid Build Coastguard Worker}
92*c8dee2aaSAndroid Build Coastguard Worker
93*c8dee2aaSAndroid Build Coastguard Workervoid GrMtlPipelineStateDataManager::setMatrix2f(UniformHandle u, const float matrix[]) const {
94*c8dee2aaSAndroid Build Coastguard Worker    this->setMatrix2fv(u, 1, matrix);
95*c8dee2aaSAndroid Build Coastguard Worker}
96*c8dee2aaSAndroid Build Coastguard Worker
97*c8dee2aaSAndroid Build Coastguard Workervoid GrMtlPipelineStateDataManager::setMatrix2fv(UniformHandle u,
98*c8dee2aaSAndroid Build Coastguard Worker                                                 int arrayCount,
99*c8dee2aaSAndroid Build Coastguard Worker                                                 const float m[]) const {
100*c8dee2aaSAndroid Build Coastguard Worker    const Uniform& uni = fUniforms[u.toIndex()];
101*c8dee2aaSAndroid Build Coastguard Worker    SkASSERT(uni.fType == SkSLType::kFloat2x2 || uni.fType == SkSLType::kHalf2x2);
102*c8dee2aaSAndroid Build Coastguard Worker    SkASSERT(arrayCount > 0);
103*c8dee2aaSAndroid Build Coastguard Worker    SkASSERT(arrayCount <= uni.fArrayCount ||
104*c8dee2aaSAndroid Build Coastguard Worker             (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
105*c8dee2aaSAndroid Build Coastguard Worker
106*c8dee2aaSAndroid Build Coastguard Worker    void* buffer = this->getBufferPtrAndMarkDirty(uni);
107*c8dee2aaSAndroid Build Coastguard Worker    this->copyUniforms(buffer, m, arrayCount * 4, uni.fType);
108*c8dee2aaSAndroid Build Coastguard Worker}
109*c8dee2aaSAndroid Build Coastguard Worker
110*c8dee2aaSAndroid Build Coastguard Workervoid GrMtlPipelineStateDataManager::uploadAndBindUniformBuffers(
111*c8dee2aaSAndroid Build Coastguard Worker        GrMtlGpu* gpu,
112*c8dee2aaSAndroid Build Coastguard Worker        GrMtlRenderCommandEncoder* renderCmdEncoder) const {
113*c8dee2aaSAndroid Build Coastguard Worker    if (fUniformSize && fUniformsDirty) {
114*c8dee2aaSAndroid Build Coastguard Worker        fUniformsDirty = false;
115*c8dee2aaSAndroid Build Coastguard Worker        if (@available(macOS 10.11, iOS 8.3, tvOS 9.0, *)) {
116*c8dee2aaSAndroid Build Coastguard Worker            if (fUniformSize <= gpu->caps()->maxPushConstantsSize()) {
117*c8dee2aaSAndroid Build Coastguard Worker                renderCmdEncoder->setVertexBytes(fUniformData.get(), fUniformSize,
118*c8dee2aaSAndroid Build Coastguard Worker                                                 GrMtlUniformHandler::kUniformBinding);
119*c8dee2aaSAndroid Build Coastguard Worker                renderCmdEncoder->setFragmentBytes(fUniformData.get(), fUniformSize,
120*c8dee2aaSAndroid Build Coastguard Worker                                                   GrMtlUniformHandler::kUniformBinding);
121*c8dee2aaSAndroid Build Coastguard Worker                return;
122*c8dee2aaSAndroid Build Coastguard Worker            }
123*c8dee2aaSAndroid Build Coastguard Worker        }
124*c8dee2aaSAndroid Build Coastguard Worker
125*c8dee2aaSAndroid Build Coastguard Worker        // upload the data
126*c8dee2aaSAndroid Build Coastguard Worker        GrRingBuffer::Slice slice = gpu->uniformsRingBuffer()->suballocate(fUniformSize);
127*c8dee2aaSAndroid Build Coastguard Worker        GrMtlBuffer* buffer = (GrMtlBuffer*) slice.fBuffer;
128*c8dee2aaSAndroid Build Coastguard Worker        char* destPtr = static_cast<char*>(slice.fBuffer->map()) + slice.fOffset;
129*c8dee2aaSAndroid Build Coastguard Worker        memcpy(destPtr, fUniformData.get(), fUniformSize);
130*c8dee2aaSAndroid Build Coastguard Worker
131*c8dee2aaSAndroid Build Coastguard Worker        renderCmdEncoder->setVertexBuffer(buffer->mtlBuffer(), slice.fOffset,
132*c8dee2aaSAndroid Build Coastguard Worker                                          GrMtlUniformHandler::kUniformBinding);
133*c8dee2aaSAndroid Build Coastguard Worker        renderCmdEncoder->setFragmentBuffer(buffer->mtlBuffer(), slice.fOffset,
134*c8dee2aaSAndroid Build Coastguard Worker                                            GrMtlUniformHandler::kUniformBinding);
135*c8dee2aaSAndroid Build Coastguard Worker    }
136*c8dee2aaSAndroid Build Coastguard Worker}
137*c8dee2aaSAndroid Build Coastguard Worker
138*c8dee2aaSAndroid Build Coastguard Workervoid GrMtlPipelineStateDataManager::resetDirtyBits() {
139*c8dee2aaSAndroid Build Coastguard Worker    fUniformsDirty = true;
140*c8dee2aaSAndroid Build Coastguard Worker}
141*c8dee2aaSAndroid Build Coastguard Worker
142*c8dee2aaSAndroid Build Coastguard WorkerGR_NORETAIN_END
143