blob: b528c4656226f5d2fc1f562eb4ce0578aff6043e [file] [log] [blame]
Jason Sams326e0dd2009-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 Samsc460e552009-11-25 13:22:07 -080020#include <GLES2/gl2.h>
21#include <GLES2/gl2ext.h>
22
Jason Sams326e0dd2009-05-22 14:03:28 -070023using namespace android;
24using namespace android::renderscript;
25
26
Jason Sams4815c0d2009-12-15 12:58:36 -080027Program::Program(Context *rsc) : ObjectBase(rsc)
Jason Sams326e0dd2009-05-22 14:03:28 -070028{
Jason Samsf2649a92009-09-25 16:37:33 -070029 mAllocFile = __FILE__;
30 mAllocLine = __LINE__;
Jason Samsc460e552009-11-25 13:22:07 -080031 mDirty = true;
32 mShaderID = 0;
33 mAttribCount = 0;
34 mUniformCount = 0;
Jason Samsf2649a92009-09-25 16:37:33 -070035
Jason Sams4815c0d2009-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 Samsf2e4fa22009-12-15 13:27:04 -080054 mTextureCount = 0;
Jason Sams4815c0d2009-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 Samsf2e4fa22009-12-15 13:27:04 -080070 if (params[ct] == RS_PROGRAM_PARAM_TEXTURE_COUNT) {
71 mTextureCount = params[ct+1];
72 }
Jason Sams4815c0d2009-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 Sams326e0dd2009-05-22 14:03:28 -070094}
95
96Program::~Program()
97{
Jason Sams9ebb0c42010-01-12 12:12:28 -080098 for (uint32_t ct=0; ct < MAX_UNIFORMS; ct++) {
99 bindAllocation(NULL, ct);
100 }
Jason Sams4815c0d2009-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 Sams326e0dd2009-05-22 14:03:28 -0700108}
109
110
Jason Sams9ebb0c42010-01-12 12:12:28 -0800111void Program::bindAllocation(Allocation *alloc, uint32_t slot)
Jason Sams326e0dd2009-05-22 14:03:28 -0700112{
Jason Sams9ebb0c42010-01-12 12:12:28 -0800113 LOGE("bind alloc %p %i", alloc, slot);
114 if (mConstants[slot].get() == alloc) {
Jason Sams5c3e3bc2009-10-26 15:19:28 -0700115 return;
116 }
Jason Sams9ebb0c42010-01-12 12:12:28 -0800117 if (mConstants[slot].get()) {
118 mConstants[slot].get()->removeProgramToDirty(this);
Jason Sams5c3e3bc2009-10-26 15:19:28 -0700119 }
Jason Sams9ebb0c42010-01-12 12:12:28 -0800120 mConstants[slot].set(alloc);
Jason Sams5c3e3bc2009-10-26 15:19:28 -0700121 if (alloc) {
122 alloc->addProgramToDirty(this);
123 }
Jason Sams326e0dd2009-05-22 14:03:28 -0700124 mDirty = true;
125}
126
Jason Sams7dad9c32009-12-17 16:55:08 -0800127void Program::bindTexture(uint32_t slot, Allocation *a)
128{
129 if (slot >= MAX_TEXTURE) {
130 LOGE("Attempt to bind a texture to a slot > MAX_TEXTURE");
131 return;
132 }
133
134 //LOGE("bindtex %i %p", slot, a);
135 mTextures[slot].set(a);
136 mDirty = true;
137}
138
139void Program::bindSampler(uint32_t slot, Sampler *s)
140{
141 if (slot >= MAX_TEXTURE) {
142 LOGE("Attempt to bind a Sampler to a slot > MAX_TEXTURE");
143 return;
144 }
145
146 mSamplers[slot].set(s);
147 mDirty = true;
148}
149
Jason Samsb4d35682010-01-04 16:52:27 -0800150String8 Program::getGLSLInputString() const
151{
152 String8 s;
153 for (uint32_t ct=0; ct < mInputCount; ct++) {
154 const Element *e = mInputElements[ct].get();
155 for (uint32_t field=0; field < e->getFieldCount(); field++) {
156 const Element *f = e->getField(field);
157
158 // Cannot be complex
159 rsAssert(!f->getFieldCount());
160 switch(f->getComponent().getVectorSize()) {
161 case 1: s.append("attribute float ATTRIB_"); break;
162 case 2: s.append("attribute vec2 ATTRIB_"); break;
163 case 3: s.append("attribute vec3 ATTRIB_"); break;
164 case 4: s.append("attribute vec4 ATTRIB_"); break;
165 default:
166 rsAssert(0);
167 }
168
169 s.append(e->getFieldName(field));
170 s.append(";\n");
171 }
172 }
173 return s;
174}
175
176String8 Program::getGLSLOutputString() const
177{
178 return String8();
179}
180
181String8 Program::getGLSLConstantString() const
182{
183 return String8();
184}
185
Jason Sams7dad9c32009-12-17 16:55:08 -0800186
Jason Samsc460e552009-11-25 13:22:07 -0800187void Program::createShader()
188{
189}
Jason Samscfb1d112009-08-05 13:57:03 -0700190
Jason Samscd506532009-12-15 19:10:11 -0800191bool Program::loadShader(Context *rsc, uint32_t type)
Jason Samsc460e552009-11-25 13:22:07 -0800192{
193 mShaderID = glCreateShader(type);
194 rsAssert(mShaderID);
195
Jason Samscd506532009-12-15 19:10:11 -0800196 if (rsc->props.mLogShaders) {
197 LOGV("Loading shader type %x, ID %i", type, mShaderID);
198 LOGV(mShader.string());
199 }
Jason Samsc460e552009-11-25 13:22:07 -0800200
201 if (mShaderID) {
202 const char * ss = mShader.string();
203 glShaderSource(mShaderID, 1, &ss, NULL);
204 glCompileShader(mShaderID);
205
206 GLint compiled = 0;
207 glGetShaderiv(mShaderID, GL_COMPILE_STATUS, &compiled);
208 if (!compiled) {
209 GLint infoLen = 0;
210 glGetShaderiv(mShaderID, GL_INFO_LOG_LENGTH, &infoLen);
211 if (infoLen) {
212 char* buf = (char*) malloc(infoLen);
213 if (buf) {
214 glGetShaderInfoLog(mShaderID, infoLen, NULL, buf);
215 LOGE("Could not compile shader \n%s\n", buf);
216 free(buf);
217 }
218 glDeleteShader(mShaderID);
219 mShaderID = 0;
220 return false;
221 }
222 }
223 }
Jason Samscd506532009-12-15 19:10:11 -0800224
225 if (rsc->props.mLogShaders) {
226 LOGV("--Shader load result %x ", glGetError());
227 }
Jason Samsc460e552009-11-25 13:22:07 -0800228 return true;
229}
Jason Samsf2a5d732009-11-30 14:49:55 -0800230
231void Program::setShader(const char *txt, uint32_t len)
232{
233 mUserShader.setTo(txt, len);
234}
235
Jason Sams4815c0d2009-12-15 12:58:36 -0800236
237
238namespace android {
239namespace renderscript {
240
241
242void rsi_ProgramBindConstants(Context *rsc, RsProgram vp, uint32_t slot, RsAllocation constants)
243{
244 Program *p = static_cast<Program *>(vp);
Jason Sams9ebb0c42010-01-12 12:12:28 -0800245 p->bindAllocation(static_cast<Allocation *>(constants), slot);
Jason Sams4815c0d2009-12-15 12:58:36 -0800246}
247
Jason Sams7dad9c32009-12-17 16:55:08 -0800248void rsi_ProgramBindTexture(Context *rsc, RsProgram vpf, uint32_t slot, RsAllocation a)
249{
250 Program *p = static_cast<Program *>(vpf);
251 p->bindTexture(slot, static_cast<Allocation *>(a));
252}
253
254void rsi_ProgramBindSampler(Context *rsc, RsProgram vpf, uint32_t slot, RsSampler s)
255{
256 Program *p = static_cast<Program *>(vpf);
257 p->bindSampler(slot, static_cast<Sampler *>(s));
258}
Jason Sams4815c0d2009-12-15 12:58:36 -0800259
260}
261}
262