xref: /aosp_15_r20/frameworks/rs/rsProgram.cpp (revision e1eccf28f96817838ad6867f7f39d2351ec11f56)
1*e1eccf28SAndroid Build Coastguard Worker /*
2*e1eccf28SAndroid Build Coastguard Worker  * Copyright (C) 2011 The Android Open Source Project
3*e1eccf28SAndroid Build Coastguard Worker  *
4*e1eccf28SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*e1eccf28SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*e1eccf28SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*e1eccf28SAndroid Build Coastguard Worker  *
8*e1eccf28SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*e1eccf28SAndroid Build Coastguard Worker  *
10*e1eccf28SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*e1eccf28SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*e1eccf28SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*e1eccf28SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*e1eccf28SAndroid Build Coastguard Worker  * limitations under the License.
15*e1eccf28SAndroid Build Coastguard Worker  */
16*e1eccf28SAndroid Build Coastguard Worker 
17*e1eccf28SAndroid Build Coastguard Worker #include "rsContext.h"
18*e1eccf28SAndroid Build Coastguard Worker #include "rsProgram.h"
19*e1eccf28SAndroid Build Coastguard Worker 
20*e1eccf28SAndroid Build Coastguard Worker #include <inttypes.h>
21*e1eccf28SAndroid Build Coastguard Worker 
22*e1eccf28SAndroid Build Coastguard Worker namespace android {
23*e1eccf28SAndroid Build Coastguard Worker namespace renderscript {
24*e1eccf28SAndroid Build Coastguard Worker 
Program(Context * rsc,const char * shaderText,size_t shaderLength,const uintptr_t * params,size_t paramLength)25*e1eccf28SAndroid Build Coastguard Worker Program::Program(Context *rsc, const char * shaderText, size_t shaderLength,
26*e1eccf28SAndroid Build Coastguard Worker                  const uintptr_t * params, size_t paramLength)
27*e1eccf28SAndroid Build Coastguard Worker     : ProgramBase(rsc) {
28*e1eccf28SAndroid Build Coastguard Worker 
29*e1eccf28SAndroid Build Coastguard Worker     initMemberVars();
30*e1eccf28SAndroid Build Coastguard Worker     for (uint32_t ct=0; ct < paramLength; ct+=2) {
31*e1eccf28SAndroid Build Coastguard Worker         if (params[ct] == RS_PROGRAM_PARAM_INPUT) {
32*e1eccf28SAndroid Build Coastguard Worker             mHal.state.inputElementsCount++;
33*e1eccf28SAndroid Build Coastguard Worker         }
34*e1eccf28SAndroid Build Coastguard Worker         if (params[ct] == RS_PROGRAM_PARAM_CONSTANT) {
35*e1eccf28SAndroid Build Coastguard Worker             mHal.state.constantsCount++;
36*e1eccf28SAndroid Build Coastguard Worker         }
37*e1eccf28SAndroid Build Coastguard Worker         if (params[ct] == RS_PROGRAM_PARAM_TEXTURE_TYPE) {
38*e1eccf28SAndroid Build Coastguard Worker             mHal.state.texturesCount++;
39*e1eccf28SAndroid Build Coastguard Worker         }
40*e1eccf28SAndroid Build Coastguard Worker     }
41*e1eccf28SAndroid Build Coastguard Worker 
42*e1eccf28SAndroid Build Coastguard Worker     mTextures = new ObjectBaseRef<Allocation>[mHal.state.texturesCount];
43*e1eccf28SAndroid Build Coastguard Worker     mSamplers = new ObjectBaseRef<Sampler>[mHal.state.texturesCount];
44*e1eccf28SAndroid Build Coastguard Worker     mInputElements = new ObjectBaseRef<Element>[mHal.state.inputElementsCount];
45*e1eccf28SAndroid Build Coastguard Worker     mConstantTypes = new ObjectBaseRef<Type>[mHal.state.constantsCount];
46*e1eccf28SAndroid Build Coastguard Worker     mConstants = new ObjectBaseRef<Allocation>[mHal.state.constantsCount];
47*e1eccf28SAndroid Build Coastguard Worker 
48*e1eccf28SAndroid Build Coastguard Worker     mHal.state.textures = new Allocation*[mHal.state.texturesCount];
49*e1eccf28SAndroid Build Coastguard Worker     mHal.state.samplers = new Sampler*[mHal.state.texturesCount];
50*e1eccf28SAndroid Build Coastguard Worker     mHal.state.textureTargets = new RsTextureTarget[mHal.state.texturesCount];
51*e1eccf28SAndroid Build Coastguard Worker     mHal.state.inputElements = new Element*[mHal.state.inputElementsCount];
52*e1eccf28SAndroid Build Coastguard Worker     mHal.state.constantTypes = new Type*[mHal.state.constantsCount];
53*e1eccf28SAndroid Build Coastguard Worker     mHal.state.constants = new Allocation*[mHal.state.constantsCount];
54*e1eccf28SAndroid Build Coastguard Worker 
55*e1eccf28SAndroid Build Coastguard Worker     // Will initialize everything
56*e1eccf28SAndroid Build Coastguard Worker     freeChildren();
57*e1eccf28SAndroid Build Coastguard Worker 
58*e1eccf28SAndroid Build Coastguard Worker     uint32_t input = 0;
59*e1eccf28SAndroid Build Coastguard Worker     uint32_t constant = 0;
60*e1eccf28SAndroid Build Coastguard Worker     uint32_t texture = 0;
61*e1eccf28SAndroid Build Coastguard Worker     for (uint32_t ct=0; ct < paramLength; ct+=2) {
62*e1eccf28SAndroid Build Coastguard Worker         if (params[ct] == RS_PROGRAM_PARAM_INPUT) {
63*e1eccf28SAndroid Build Coastguard Worker             mInputElements[input].set(reinterpret_cast<Element *>(params[ct+1]));
64*e1eccf28SAndroid Build Coastguard Worker             mHal.state.inputElements[input++] = reinterpret_cast<Element *>(params[ct+1]);
65*e1eccf28SAndroid Build Coastguard Worker         }
66*e1eccf28SAndroid Build Coastguard Worker         if (params[ct] == RS_PROGRAM_PARAM_CONSTANT) {
67*e1eccf28SAndroid Build Coastguard Worker             mConstantTypes[constant].set(reinterpret_cast<Type *>(params[ct+1]));
68*e1eccf28SAndroid Build Coastguard Worker             mHal.state.constantTypes[constant++] = reinterpret_cast<Type *>(params[ct+1]);
69*e1eccf28SAndroid Build Coastguard Worker         }
70*e1eccf28SAndroid Build Coastguard Worker         if (params[ct] == RS_PROGRAM_PARAM_TEXTURE_TYPE) {
71*e1eccf28SAndroid Build Coastguard Worker             mHal.state.textureTargets[texture++] = (RsTextureTarget)params[ct+1];
72*e1eccf28SAndroid Build Coastguard Worker         }
73*e1eccf28SAndroid Build Coastguard Worker     }
74*e1eccf28SAndroid Build Coastguard Worker     mIsInternal = false;
75*e1eccf28SAndroid Build Coastguard Worker     uint32_t internalTokenLen = strlen(RS_SHADER_INTERNAL);
76*e1eccf28SAndroid Build Coastguard Worker     if (shaderLength > internalTokenLen &&
77*e1eccf28SAndroid Build Coastguard Worker        strncmp(RS_SHADER_INTERNAL, shaderText, internalTokenLen) == 0) {
78*e1eccf28SAndroid Build Coastguard Worker         mIsInternal = true;
79*e1eccf28SAndroid Build Coastguard Worker         shaderText += internalTokenLen;
80*e1eccf28SAndroid Build Coastguard Worker         shaderLength -= internalTokenLen;
81*e1eccf28SAndroid Build Coastguard Worker     }
82*e1eccf28SAndroid Build Coastguard Worker 
83*e1eccf28SAndroid Build Coastguard Worker     mUserShader = rsuCopyString(shaderText, shaderLength);
84*e1eccf28SAndroid Build Coastguard Worker     mUserShaderLen = shaderLength;
85*e1eccf28SAndroid Build Coastguard Worker }
86*e1eccf28SAndroid Build Coastguard Worker 
~Program()87*e1eccf28SAndroid Build Coastguard Worker Program::~Program() {
88*e1eccf28SAndroid Build Coastguard Worker     freeChildren();
89*e1eccf28SAndroid Build Coastguard Worker 
90*e1eccf28SAndroid Build Coastguard Worker     delete[] mTextures;
91*e1eccf28SAndroid Build Coastguard Worker     delete[] mSamplers;
92*e1eccf28SAndroid Build Coastguard Worker     delete[] mInputElements;
93*e1eccf28SAndroid Build Coastguard Worker     delete[] mConstantTypes;
94*e1eccf28SAndroid Build Coastguard Worker     delete[] mConstants;
95*e1eccf28SAndroid Build Coastguard Worker 
96*e1eccf28SAndroid Build Coastguard Worker     delete[] mHal.state.textures;
97*e1eccf28SAndroid Build Coastguard Worker     delete[] mHal.state.samplers;
98*e1eccf28SAndroid Build Coastguard Worker     delete[] mHal.state.textureTargets;
99*e1eccf28SAndroid Build Coastguard Worker     delete[] mHal.state.inputElements;
100*e1eccf28SAndroid Build Coastguard Worker     delete[] mHal.state.constantTypes;
101*e1eccf28SAndroid Build Coastguard Worker     delete[] mHal.state.constants;
102*e1eccf28SAndroid Build Coastguard Worker     mHal.state.inputElementsCount = 0;
103*e1eccf28SAndroid Build Coastguard Worker     mHal.state.constantsCount = 0;
104*e1eccf28SAndroid Build Coastguard Worker     mHal.state.texturesCount = 0;
105*e1eccf28SAndroid Build Coastguard Worker 
106*e1eccf28SAndroid Build Coastguard Worker     if (mUserShader != nullptr) {
107*e1eccf28SAndroid Build Coastguard Worker         delete[] mUserShader;
108*e1eccf28SAndroid Build Coastguard Worker         mUserShader = nullptr;
109*e1eccf28SAndroid Build Coastguard Worker     }
110*e1eccf28SAndroid Build Coastguard Worker     mUserShaderLen = 0;
111*e1eccf28SAndroid Build Coastguard Worker }
112*e1eccf28SAndroid Build Coastguard Worker 
freeChildren()113*e1eccf28SAndroid Build Coastguard Worker bool Program::freeChildren() {
114*e1eccf28SAndroid Build Coastguard Worker     for (uint32_t ct=0; ct < mHal.state.constantsCount; ct++) {
115*e1eccf28SAndroid Build Coastguard Worker         bindAllocation(nullptr, nullptr, ct);
116*e1eccf28SAndroid Build Coastguard Worker     }
117*e1eccf28SAndroid Build Coastguard Worker 
118*e1eccf28SAndroid Build Coastguard Worker     for (uint32_t ct=0; ct < mHal.state.texturesCount; ct++) {
119*e1eccf28SAndroid Build Coastguard Worker         bindTexture(nullptr, ct, nullptr);
120*e1eccf28SAndroid Build Coastguard Worker         bindSampler(nullptr, ct, nullptr);
121*e1eccf28SAndroid Build Coastguard Worker     }
122*e1eccf28SAndroid Build Coastguard Worker     return false;
123*e1eccf28SAndroid Build Coastguard Worker }
124*e1eccf28SAndroid Build Coastguard Worker 
initMemberVars()125*e1eccf28SAndroid Build Coastguard Worker void Program::initMemberVars() {
126*e1eccf28SAndroid Build Coastguard Worker     mDirty = true;
127*e1eccf28SAndroid Build Coastguard Worker 
128*e1eccf28SAndroid Build Coastguard Worker     mHal.drv = nullptr;
129*e1eccf28SAndroid Build Coastguard Worker     mHal.state.textures = nullptr;
130*e1eccf28SAndroid Build Coastguard Worker     mHal.state.samplers = nullptr;
131*e1eccf28SAndroid Build Coastguard Worker     mHal.state.textureTargets = nullptr;
132*e1eccf28SAndroid Build Coastguard Worker     mHal.state.inputElements = nullptr;
133*e1eccf28SAndroid Build Coastguard Worker     mHal.state.constantTypes = nullptr;
134*e1eccf28SAndroid Build Coastguard Worker     mHal.state.constants = nullptr;
135*e1eccf28SAndroid Build Coastguard Worker 
136*e1eccf28SAndroid Build Coastguard Worker     mHal.state.inputElementsCount = 0;
137*e1eccf28SAndroid Build Coastguard Worker     mHal.state.constantsCount = 0;
138*e1eccf28SAndroid Build Coastguard Worker     mHal.state.texturesCount = 0;
139*e1eccf28SAndroid Build Coastguard Worker 
140*e1eccf28SAndroid Build Coastguard Worker     mTextures = nullptr;
141*e1eccf28SAndroid Build Coastguard Worker     mSamplers = nullptr;
142*e1eccf28SAndroid Build Coastguard Worker     mInputElements = nullptr;
143*e1eccf28SAndroid Build Coastguard Worker     mConstantTypes = nullptr;
144*e1eccf28SAndroid Build Coastguard Worker     mConstants = nullptr;
145*e1eccf28SAndroid Build Coastguard Worker 
146*e1eccf28SAndroid Build Coastguard Worker     mIsInternal = false;
147*e1eccf28SAndroid Build Coastguard Worker 
148*e1eccf28SAndroid Build Coastguard Worker     mUserShader = nullptr;
149*e1eccf28SAndroid Build Coastguard Worker     mUserShaderLen = 0;
150*e1eccf28SAndroid Build Coastguard Worker }
151*e1eccf28SAndroid Build Coastguard Worker 
bindAllocation(Context * rsc,Allocation * alloc,uint32_t slot)152*e1eccf28SAndroid Build Coastguard Worker void Program::bindAllocation(Context *rsc, Allocation *alloc, uint32_t slot) {
153*e1eccf28SAndroid Build Coastguard Worker     if (alloc != nullptr) {
154*e1eccf28SAndroid Build Coastguard Worker         if (slot >= mHal.state.constantsCount) {
155*e1eccf28SAndroid Build Coastguard Worker             ALOGE("Attempt to bind alloc at slot %u, on shader id %" PRIuPTR ", but const count is %u",
156*e1eccf28SAndroid Build Coastguard Worker                  slot, (uintptr_t)this, mHal.state.constantsCount);
157*e1eccf28SAndroid Build Coastguard Worker             rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind allocation");
158*e1eccf28SAndroid Build Coastguard Worker             return;
159*e1eccf28SAndroid Build Coastguard Worker         }
160*e1eccf28SAndroid Build Coastguard Worker         if (alloc->getType() != mConstantTypes[slot].get()) {
161*e1eccf28SAndroid Build Coastguard Worker             ALOGE("Attempt to bind alloc at slot %u, on shader id %" PRIuPTR ", but types mismatch",
162*e1eccf28SAndroid Build Coastguard Worker                  slot, (uintptr_t)this);
163*e1eccf28SAndroid Build Coastguard Worker             rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind allocation");
164*e1eccf28SAndroid Build Coastguard Worker             return;
165*e1eccf28SAndroid Build Coastguard Worker         }
166*e1eccf28SAndroid Build Coastguard Worker     }
167*e1eccf28SAndroid Build Coastguard Worker     if (mConstants[slot].get() == alloc) {
168*e1eccf28SAndroid Build Coastguard Worker         return;
169*e1eccf28SAndroid Build Coastguard Worker     }
170*e1eccf28SAndroid Build Coastguard Worker     if (mConstants[slot].get()) {
171*e1eccf28SAndroid Build Coastguard Worker         mConstants[slot]->removeProgramToDirty(this);
172*e1eccf28SAndroid Build Coastguard Worker     }
173*e1eccf28SAndroid Build Coastguard Worker     mConstants[slot].set(alloc);
174*e1eccf28SAndroid Build Coastguard Worker     mHal.state.constants[slot] = alloc;
175*e1eccf28SAndroid Build Coastguard Worker     if (alloc) {
176*e1eccf28SAndroid Build Coastguard Worker         alloc->addProgramToDirty(this);
177*e1eccf28SAndroid Build Coastguard Worker     }
178*e1eccf28SAndroid Build Coastguard Worker     mDirty = true;
179*e1eccf28SAndroid Build Coastguard Worker }
180*e1eccf28SAndroid Build Coastguard Worker 
bindTexture(Context * rsc,uint32_t slot,Allocation * a)181*e1eccf28SAndroid Build Coastguard Worker void Program::bindTexture(Context *rsc, uint32_t slot, Allocation *a) {
182*e1eccf28SAndroid Build Coastguard Worker     if (slot >= mHal.state.texturesCount) {
183*e1eccf28SAndroid Build Coastguard Worker         ALOGE("Attempt to bind texture to slot %u but tex count is %u", slot, mHal.state.texturesCount);
184*e1eccf28SAndroid Build Coastguard Worker         rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind texture");
185*e1eccf28SAndroid Build Coastguard Worker         return;
186*e1eccf28SAndroid Build Coastguard Worker     }
187*e1eccf28SAndroid Build Coastguard Worker 
188*e1eccf28SAndroid Build Coastguard Worker     if (a && a->getType()->getDimFaces() && mHal.state.textureTargets[slot] != RS_TEXTURE_CUBE) {
189*e1eccf28SAndroid Build Coastguard Worker         ALOGE("Attempt to bind cubemap to slot %u but 2d texture needed", slot);
190*e1eccf28SAndroid Build Coastguard Worker         rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind cubemap to 2d texture slot");
191*e1eccf28SAndroid Build Coastguard Worker         return;
192*e1eccf28SAndroid Build Coastguard Worker     }
193*e1eccf28SAndroid Build Coastguard Worker 
194*e1eccf28SAndroid Build Coastguard Worker     mTextures[slot].set(a);
195*e1eccf28SAndroid Build Coastguard Worker     mHal.state.textures[slot] = a;
196*e1eccf28SAndroid Build Coastguard Worker 
197*e1eccf28SAndroid Build Coastguard Worker     mDirty = true;
198*e1eccf28SAndroid Build Coastguard Worker }
199*e1eccf28SAndroid Build Coastguard Worker 
bindSampler(Context * rsc,uint32_t slot,Sampler * s)200*e1eccf28SAndroid Build Coastguard Worker void Program::bindSampler(Context *rsc, uint32_t slot, Sampler *s) {
201*e1eccf28SAndroid Build Coastguard Worker     if (slot >= mHal.state.texturesCount) {
202*e1eccf28SAndroid Build Coastguard Worker         ALOGE("Attempt to bind sampler to slot %u but tex count is %u", slot, mHal.state.texturesCount);
203*e1eccf28SAndroid Build Coastguard Worker         rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind sampler");
204*e1eccf28SAndroid Build Coastguard Worker         return;
205*e1eccf28SAndroid Build Coastguard Worker     }
206*e1eccf28SAndroid Build Coastguard Worker 
207*e1eccf28SAndroid Build Coastguard Worker     mSamplers[slot].set(s);
208*e1eccf28SAndroid Build Coastguard Worker     mHal.state.samplers[slot] = s;
209*e1eccf28SAndroid Build Coastguard Worker     mDirty = true;
210*e1eccf28SAndroid Build Coastguard Worker }
211*e1eccf28SAndroid Build Coastguard Worker 
rsi_ProgramBindConstants(Context * rsc,RsProgram vp,uint32_t slot,RsAllocation constants)212*e1eccf28SAndroid Build Coastguard Worker void rsi_ProgramBindConstants(Context *rsc, RsProgram vp, uint32_t slot, RsAllocation constants) {
213*e1eccf28SAndroid Build Coastguard Worker     Program *p = static_cast<Program *>(vp);
214*e1eccf28SAndroid Build Coastguard Worker     p->bindAllocation(rsc, static_cast<Allocation *>(constants), slot);
215*e1eccf28SAndroid Build Coastguard Worker }
216*e1eccf28SAndroid Build Coastguard Worker 
rsi_ProgramBindTexture(Context * rsc,RsProgram vpf,uint32_t slot,RsAllocation a)217*e1eccf28SAndroid Build Coastguard Worker void rsi_ProgramBindTexture(Context *rsc, RsProgram vpf, uint32_t slot, RsAllocation a) {
218*e1eccf28SAndroid Build Coastguard Worker     Program *p = static_cast<Program *>(vpf);
219*e1eccf28SAndroid Build Coastguard Worker     p->bindTexture(rsc, slot, static_cast<Allocation *>(a));
220*e1eccf28SAndroid Build Coastguard Worker }
221*e1eccf28SAndroid Build Coastguard Worker 
rsi_ProgramBindSampler(Context * rsc,RsProgram vpf,uint32_t slot,RsSampler s)222*e1eccf28SAndroid Build Coastguard Worker void rsi_ProgramBindSampler(Context *rsc, RsProgram vpf, uint32_t slot, RsSampler s) {
223*e1eccf28SAndroid Build Coastguard Worker     Program *p = static_cast<Program *>(vpf);
224*e1eccf28SAndroid Build Coastguard Worker     p->bindSampler(rsc, slot, static_cast<Sampler *>(s));
225*e1eccf28SAndroid Build Coastguard Worker }
226*e1eccf28SAndroid Build Coastguard Worker 
227*e1eccf28SAndroid Build Coastguard Worker } // namespace renderscript
228*e1eccf28SAndroid Build Coastguard Worker } // namespace android
229