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