blob: 656a3c33952980a01d69faebb380942de89185ea [file] [log] [blame]
Jason Samsd19f10d2009-05-22 14:03:28 -07001/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "rsContext.h"
18#include "rsProgram.h"
19
Jason Samsbb51c402009-11-25 13:22:07 -080020#include <GLES2/gl2.h>
21#include <GLES2/gl2ext.h>
22
Jason Samsd19f10d2009-05-22 14:03:28 -070023using namespace android;
24using namespace android::renderscript;
25
26
Jason Sams0011bcf2009-12-15 12:58:36 -080027Program::Program(Context *rsc) : ObjectBase(rsc)
Jason Samsd19f10d2009-05-22 14:03:28 -070028{
Jason Sams61f08d62009-09-25 16:37:33 -070029 mAllocFile = __FILE__;
30 mAllocLine = __LINE__;
Jason Samsbb51c402009-11-25 13:22:07 -080031 mDirty = true;
32 mShaderID = 0;
33 mAttribCount = 0;
34 mUniformCount = 0;
Jason Sams61f08d62009-09-25 16:37:33 -070035
Jason Sams0011bcf2009-12-15 12:58:36 -080036 mInputElements = NULL;
37 mOutputElements = NULL;
38 mConstantTypes = NULL;
39 mInputCount = 0;
40 mOutputCount = 0;
41 mConstantCount = 0;
42}
43
44Program::Program(Context *rsc, const char * shaderText, uint32_t shaderLength,
45 const uint32_t * params, uint32_t paramLength) :
46 ObjectBase(rsc)
47{
48 mAllocFile = __FILE__;
49 mAllocLine = __LINE__;
50 mDirty = true;
51 mShaderID = 0;
52 mAttribCount = 0;
53 mUniformCount = 0;
Jason Sams7e5ab3b2009-12-15 13:27:04 -080054 mTextureCount = 0;
Jason Sams0011bcf2009-12-15 12:58:36 -080055
56 mInputCount = 0;
57 mOutputCount = 0;
58 mConstantCount = 0;
59
60 for (uint32_t ct=0; ct < paramLength; ct+=2) {
61 if (params[ct] == RS_PROGRAM_PARAM_INPUT) {
62 mInputCount++;
63 }
64 if (params[ct] == RS_PROGRAM_PARAM_OUTPUT) {
65 mOutputCount++;
66 }
67 if (params[ct] == RS_PROGRAM_PARAM_CONSTANT) {
68 mConstantCount++;
69 }
Jason Sams7e5ab3b2009-12-15 13:27:04 -080070 if (params[ct] == RS_PROGRAM_PARAM_TEXTURE_COUNT) {
71 mTextureCount = params[ct+1];
72 }
Jason Sams0011bcf2009-12-15 12:58:36 -080073 }
74
75 mInputElements = new ObjectBaseRef<Element>[mInputCount];
76 mOutputElements = new ObjectBaseRef<Element>[mOutputCount];
77 mConstantTypes = new ObjectBaseRef<Type>[mConstantCount];
78
79 uint32_t input = 0;
80 uint32_t output = 0;
81 uint32_t constant = 0;
82 for (uint32_t ct=0; ct < paramLength; ct+=2) {
83 if (params[ct] == RS_PROGRAM_PARAM_INPUT) {
84 mInputElements[input++].set(reinterpret_cast<Element *>(params[ct+1]));
85 }
86 if (params[ct] == RS_PROGRAM_PARAM_OUTPUT) {
87 mOutputElements[output++].set(reinterpret_cast<Element *>(params[ct+1]));
88 }
89 if (params[ct] == RS_PROGRAM_PARAM_CONSTANT) {
90 mConstantTypes[constant++].set(reinterpret_cast<Type *>(params[ct+1]));
91 }
92 }
93 mUserShader.setTo(shaderText, shaderLength);
Jason Samsd19f10d2009-05-22 14:03:28 -070094}
95
96Program::~Program()
97{
Jason Samsea87e962010-01-12 12:12:28 -080098 for (uint32_t ct=0; ct < MAX_UNIFORMS; ct++) {
99 bindAllocation(NULL, ct);
100 }
Jason Sams0011bcf2009-12-15 12:58:36 -0800101
102 delete[] mInputElements;
103 delete[] mOutputElements;
104 delete[] mConstantTypes;
105 mInputCount = 0;
106 mOutputCount = 0;
107 mConstantCount = 0;
Jason Samsd19f10d2009-05-22 14:03:28 -0700108}
109
110
Jason Samsea87e962010-01-12 12:12:28 -0800111void Program::bindAllocation(Allocation *alloc, uint32_t slot)
Jason Samsd19f10d2009-05-22 14:03:28 -0700112{
Jason Samsea87e962010-01-12 12:12:28 -0800113 if (mConstants[slot].get() == alloc) {
Jason Sams83f1c632009-10-26 15:19:28 -0700114 return;
115 }
Jason Samsea87e962010-01-12 12:12:28 -0800116 if (mConstants[slot].get()) {
117 mConstants[slot].get()->removeProgramToDirty(this);
Jason Sams83f1c632009-10-26 15:19:28 -0700118 }
Jason Samsea87e962010-01-12 12:12:28 -0800119 mConstants[slot].set(alloc);
Jason Sams83f1c632009-10-26 15:19:28 -0700120 if (alloc) {
121 alloc->addProgramToDirty(this);
122 }
Jason Samsd19f10d2009-05-22 14:03:28 -0700123 mDirty = true;
124}
125
Jason Sams68afd012009-12-17 16:55:08 -0800126void Program::bindTexture(uint32_t slot, Allocation *a)
127{
128 if (slot >= MAX_TEXTURE) {
129 LOGE("Attempt to bind a texture to a slot > MAX_TEXTURE");
130 return;
131 }
132
133 //LOGE("bindtex %i %p", slot, a);
134 mTextures[slot].set(a);
135 mDirty = true;
136}
137
138void Program::bindSampler(uint32_t slot, Sampler *s)
139{
140 if (slot >= MAX_TEXTURE) {
141 LOGE("Attempt to bind a Sampler to a slot > MAX_TEXTURE");
142 return;
143 }
144
145 mSamplers[slot].set(s);
146 mDirty = true;
147}
148
Jason Samse17964e2010-01-04 16:52:27 -0800149String8 Program::getGLSLInputString() const
150{
151 String8 s;
152 for (uint32_t ct=0; ct < mInputCount; ct++) {
153 const Element *e = mInputElements[ct].get();
154 for (uint32_t field=0; field < e->getFieldCount(); field++) {
155 const Element *f = e->getField(field);
156
157 // Cannot be complex
158 rsAssert(!f->getFieldCount());
159 switch(f->getComponent().getVectorSize()) {
160 case 1: s.append("attribute float ATTRIB_"); break;
161 case 2: s.append("attribute vec2 ATTRIB_"); break;
162 case 3: s.append("attribute vec3 ATTRIB_"); break;
163 case 4: s.append("attribute vec4 ATTRIB_"); break;
164 default:
165 rsAssert(0);
166 }
167
168 s.append(e->getFieldName(field));
169 s.append(";\n");
170 }
171 }
172 return s;
173}
174
175String8 Program::getGLSLOutputString() const
176{
177 return String8();
178}
179
180String8 Program::getGLSLConstantString() const
181{
182 return String8();
183}
184
Jason Sams68afd012009-12-17 16:55:08 -0800185
Jason Samsbb51c402009-11-25 13:22:07 -0800186void Program::createShader()
187{
188}
Jason Sams9bee51c2009-08-05 13:57:03 -0700189
Jason Sams5dad8b42009-12-15 19:10:11 -0800190bool Program::loadShader(Context *rsc, uint32_t type)
Jason Samsbb51c402009-11-25 13:22:07 -0800191{
192 mShaderID = glCreateShader(type);
193 rsAssert(mShaderID);
194
Jason Sams5dad8b42009-12-15 19:10:11 -0800195 if (rsc->props.mLogShaders) {
196 LOGV("Loading shader type %x, ID %i", type, mShaderID);
197 LOGV(mShader.string());
198 }
Jason Samsbb51c402009-11-25 13:22:07 -0800199
200 if (mShaderID) {
201 const char * ss = mShader.string();
202 glShaderSource(mShaderID, 1, &ss, NULL);
203 glCompileShader(mShaderID);
204
205 GLint compiled = 0;
206 glGetShaderiv(mShaderID, GL_COMPILE_STATUS, &compiled);
207 if (!compiled) {
208 GLint infoLen = 0;
209 glGetShaderiv(mShaderID, GL_INFO_LOG_LENGTH, &infoLen);
210 if (infoLen) {
211 char* buf = (char*) malloc(infoLen);
212 if (buf) {
213 glGetShaderInfoLog(mShaderID, infoLen, NULL, buf);
214 LOGE("Could not compile shader \n%s\n", buf);
215 free(buf);
216 }
217 glDeleteShader(mShaderID);
218 mShaderID = 0;
219 return false;
220 }
221 }
222 }
Jason Sams5dad8b42009-12-15 19:10:11 -0800223
224 if (rsc->props.mLogShaders) {
225 LOGV("--Shader load result %x ", glGetError());
226 }
Jason Samsbb51c402009-11-25 13:22:07 -0800227 return true;
228}
Jason Sams54c0ec12009-11-30 14:49:55 -0800229
230void Program::setShader(const char *txt, uint32_t len)
231{
232 mUserShader.setTo(txt, len);
233}
234
Jason Sams0011bcf2009-12-15 12:58:36 -0800235
236
237namespace android {
238namespace renderscript {
239
240
241void rsi_ProgramBindConstants(Context *rsc, RsProgram vp, uint32_t slot, RsAllocation constants)
242{
243 Program *p = static_cast<Program *>(vp);
Jason Samsea87e962010-01-12 12:12:28 -0800244 p->bindAllocation(static_cast<Allocation *>(constants), slot);
Jason Sams0011bcf2009-12-15 12:58:36 -0800245}
246
Jason Sams68afd012009-12-17 16:55:08 -0800247void rsi_ProgramBindTexture(Context *rsc, RsProgram vpf, uint32_t slot, RsAllocation a)
248{
249 Program *p = static_cast<Program *>(vpf);
250 p->bindTexture(slot, static_cast<Allocation *>(a));
251}
252
253void rsi_ProgramBindSampler(Context *rsc, RsProgram vpf, uint32_t slot, RsSampler s)
254{
255 Program *p = static_cast<Program *>(vpf);
256 p->bindSampler(slot, static_cast<Sampler *>(s));
257}
Jason Sams0011bcf2009-12-15 12:58:36 -0800258
259}
260}
261