blob: 478a6dcbcc210980579aed2ec6d9dea160befe71 [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;
Jason Samsa2cf7552010-03-03 13:03:18 -080042 mIsValid = false;
Jason Sams4815c0d2009-12-15 12:58:36 -080043}
44
45Program::Program(Context *rsc, const char * shaderText, uint32_t shaderLength,
46 const uint32_t * params, uint32_t paramLength) :
47 ObjectBase(rsc)
48{
49 mAllocFile = __FILE__;
50 mAllocLine = __LINE__;
51 mDirty = true;
52 mShaderID = 0;
53 mAttribCount = 0;
54 mUniformCount = 0;
Jason Samsf2e4fa22009-12-15 13:27:04 -080055 mTextureCount = 0;
Jason Sams4815c0d2009-12-15 12:58:36 -080056
57 mInputCount = 0;
58 mOutputCount = 0;
59 mConstantCount = 0;
60
61 for (uint32_t ct=0; ct < paramLength; ct+=2) {
62 if (params[ct] == RS_PROGRAM_PARAM_INPUT) {
63 mInputCount++;
64 }
65 if (params[ct] == RS_PROGRAM_PARAM_OUTPUT) {
66 mOutputCount++;
67 }
68 if (params[ct] == RS_PROGRAM_PARAM_CONSTANT) {
69 mConstantCount++;
70 }
Jason Samsf2e4fa22009-12-15 13:27:04 -080071 if (params[ct] == RS_PROGRAM_PARAM_TEXTURE_COUNT) {
72 mTextureCount = params[ct+1];
73 }
Jason Sams4815c0d2009-12-15 12:58:36 -080074 }
75
76 mInputElements = new ObjectBaseRef<Element>[mInputCount];
77 mOutputElements = new ObjectBaseRef<Element>[mOutputCount];
78 mConstantTypes = new ObjectBaseRef<Type>[mConstantCount];
79
80 uint32_t input = 0;
81 uint32_t output = 0;
82 uint32_t constant = 0;
83 for (uint32_t ct=0; ct < paramLength; ct+=2) {
84 if (params[ct] == RS_PROGRAM_PARAM_INPUT) {
85 mInputElements[input++].set(reinterpret_cast<Element *>(params[ct+1]));
86 }
87 if (params[ct] == RS_PROGRAM_PARAM_OUTPUT) {
88 mOutputElements[output++].set(reinterpret_cast<Element *>(params[ct+1]));
89 }
90 if (params[ct] == RS_PROGRAM_PARAM_CONSTANT) {
91 mConstantTypes[constant++].set(reinterpret_cast<Type *>(params[ct+1]));
92 }
93 }
94 mUserShader.setTo(shaderText, shaderLength);
Jason Sams326e0dd2009-05-22 14:03:28 -070095}
96
97Program::~Program()
98{
Jason Sams9ebb0c42010-01-12 12:12:28 -080099 for (uint32_t ct=0; ct < MAX_UNIFORMS; ct++) {
100 bindAllocation(NULL, ct);
101 }
Jason Sams4815c0d2009-12-15 12:58:36 -0800102
103 delete[] mInputElements;
104 delete[] mOutputElements;
105 delete[] mConstantTypes;
106 mInputCount = 0;
107 mOutputCount = 0;
108 mConstantCount = 0;
Jason Sams326e0dd2009-05-22 14:03:28 -0700109}
110
111
Jason Sams9ebb0c42010-01-12 12:12:28 -0800112void Program::bindAllocation(Allocation *alloc, uint32_t slot)
Jason Sams326e0dd2009-05-22 14:03:28 -0700113{
Jason Sams9ebb0c42010-01-12 12:12:28 -0800114 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;
Jason Samsa2cf7552010-03-03 13:03:18 -0800220 rsc->setError(RS_ERROR_BAD_SHADER, "Error returned from GL driver loading shader text,");
Jason Samsc460e552009-11-25 13:22:07 -0800221 return false;
222 }
223 }
224 }
Jason Samscd506532009-12-15 19:10:11 -0800225
226 if (rsc->props.mLogShaders) {
227 LOGV("--Shader load result %x ", glGetError());
228 }
Jason Samsa2cf7552010-03-03 13:03:18 -0800229 mIsValid = true;
Jason Samsc460e552009-11-25 13:22:07 -0800230 return true;
231}
Jason Samsf2a5d732009-11-30 14:49:55 -0800232
233void Program::setShader(const char *txt, uint32_t len)
234{
235 mUserShader.setTo(txt, len);
236}
237
Jason Sams4815c0d2009-12-15 12:58:36 -0800238
239
240namespace android {
241namespace renderscript {
242
243
244void rsi_ProgramBindConstants(Context *rsc, RsProgram vp, uint32_t slot, RsAllocation constants)
245{
246 Program *p = static_cast<Program *>(vp);
Jason Sams9ebb0c42010-01-12 12:12:28 -0800247 p->bindAllocation(static_cast<Allocation *>(constants), slot);
Jason Sams4815c0d2009-12-15 12:58:36 -0800248}
249
Jason Sams7dad9c32009-12-17 16:55:08 -0800250void rsi_ProgramBindTexture(Context *rsc, RsProgram vpf, uint32_t slot, RsAllocation a)
251{
252 Program *p = static_cast<Program *>(vpf);
253 p->bindTexture(slot, static_cast<Allocation *>(a));
254}
255
256void rsi_ProgramBindSampler(Context *rsc, RsProgram vpf, uint32_t slot, RsSampler s)
257{
258 Program *p = static_cast<Program *>(vpf);
259 p->bindSampler(slot, static_cast<Sampler *>(s));
260}
Jason Sams4815c0d2009-12-15 12:58:36 -0800261
262}
263}
264