rsProgram.cpp revision 4815c0d121310cfcd6a8aba4eab77a9910af53ac
1326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams/*
2326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * Copyright (C) 2009 The Android Open Source Project
3326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams *
4326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * Licensed under the Apache License, Version 2.0 (the "License");
5326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * you may not use this file except in compliance with the License.
6326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * You may obtain a copy of the License at
7326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams *
8326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams *      http://www.apache.org/licenses/LICENSE-2.0
9326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams *
10326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * Unless required by applicable law or agreed to in writing, software
11326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * distributed under the License is distributed on an "AS IS" BASIS,
12326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * See the License for the specific language governing permissions and
14326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * limitations under the License.
15326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams */
16326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
17326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams#include "rsContext.h"
18326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams#include "rsProgram.h"
19326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
20c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams#include <GLES2/gl2.h>
21c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams#include <GLES2/gl2ext.h>
22c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams
23326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsusing namespace android;
24326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsusing namespace android::renderscript;
25326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
26326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
274815c0d121310cfcd6a8aba4eab77a9910af53acJason SamsProgram::Program(Context *rsc) : ObjectBase(rsc)
28326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams{
29f2649a961db2995e9e24a6c98f8a419f1496c1b7Jason Sams    mAllocFile = __FILE__;
30f2649a961db2995e9e24a6c98f8a419f1496c1b7Jason Sams    mAllocLine = __LINE__;
31c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams    mDirty = true;
32c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams    mShaderID = 0;
33c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams    mAttribCount = 0;
34c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams    mUniformCount = 0;
35f2649a961db2995e9e24a6c98f8a419f1496c1b7Jason Sams
364815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mInputElements = NULL;
374815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mOutputElements = NULL;
384815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mConstantTypes = NULL;
394815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mInputCount = 0;
404815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mOutputCount = 0;
414815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mConstantCount = 0;
424815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams}
434815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams
444815c0d121310cfcd6a8aba4eab77a9910af53acJason SamsProgram::Program(Context *rsc, const char * shaderText, uint32_t shaderLength,
454815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams                 const uint32_t * params, uint32_t paramLength) :
464815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    ObjectBase(rsc)
474815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams{
484815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mAllocFile = __FILE__;
494815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mAllocLine = __LINE__;
504815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mDirty = true;
514815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mShaderID = 0;
524815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mAttribCount = 0;
534815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mUniformCount = 0;
544815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams
554815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mInputCount = 0;
564815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mOutputCount = 0;
574815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mConstantCount = 0;
584815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams
594815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    for (uint32_t ct=0; ct < paramLength; ct+=2) {
604815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams        if (params[ct] == RS_PROGRAM_PARAM_INPUT) {
614815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams            mInputCount++;
624815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams        }
634815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams        if (params[ct] == RS_PROGRAM_PARAM_OUTPUT) {
644815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams            mOutputCount++;
654815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams        }
664815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams        if (params[ct] == RS_PROGRAM_PARAM_CONSTANT) {
674815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams            mConstantCount++;
684815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams        }
694815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    }
704815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams
714815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mInputElements = new ObjectBaseRef<Element>[mInputCount];
724815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mOutputElements = new ObjectBaseRef<Element>[mOutputCount];
734815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mConstantTypes = new ObjectBaseRef<Type>[mConstantCount];
744815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams
754815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    uint32_t input = 0;
764815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    uint32_t output = 0;
774815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    uint32_t constant = 0;
784815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    for (uint32_t ct=0; ct < paramLength; ct+=2) {
794815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams        if (params[ct] == RS_PROGRAM_PARAM_INPUT) {
804815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams            mInputElements[input++].set(reinterpret_cast<Element *>(params[ct+1]));
814815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams        }
824815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams        if (params[ct] == RS_PROGRAM_PARAM_OUTPUT) {
834815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams            mOutputElements[output++].set(reinterpret_cast<Element *>(params[ct+1]));
844815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams        }
854815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams        if (params[ct] == RS_PROGRAM_PARAM_CONSTANT) {
864815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams            mConstantTypes[constant++].set(reinterpret_cast<Type *>(params[ct+1]));
874815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams        }
884815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    }
894815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mUserShader.setTo(shaderText, shaderLength);
90326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
91326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
92326e0ddf89e8df2837752fbfd7a014814b32082cJason SamsProgram::~Program()
93326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams{
945c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    bindAllocation(NULL);
954815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams
964815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    delete[] mInputElements;
974815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    delete[] mOutputElements;
984815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    delete[] mConstantTypes;
994815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mInputCount = 0;
1004815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mOutputCount = 0;
1014815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    mConstantCount = 0;
102326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
103326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
104326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
105cfb1d11ce6826fce7241d316d8b7dcab661f63a6Jason Samsvoid Program::bindAllocation(Allocation *alloc)
106326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams{
1075c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    if (mConstants.get() == alloc) {
1085c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams        return;
1095c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    }
1105c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    if (mConstants.get()) {
1115c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams        mConstants.get()->removeProgramToDirty(this);
1125c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    }
113326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mConstants.set(alloc);
1145c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    if (alloc) {
1155c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams        alloc->addProgramToDirty(this);
1165c3e3bc8af6de6be5e6bd68e1d5168496f99e6cfJason Sams    }
117326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mDirty = true;
118326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
119326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
120c460e55d78cbe8bee95c5c947dfe541218142a5bJason Samsvoid Program::createShader()
121c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams{
122c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams}
123c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams
124c460e55d78cbe8bee95c5c947dfe541218142a5bJason Samsbool Program::loadShader(uint32_t type)
125c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams{
126c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams    mShaderID = glCreateShader(type);
127c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams    rsAssert(mShaderID);
128c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams
129f2a5d7326b38e5a28b6618f9b1e5a021aef7179fJason Sams    LOGV("Loading shader type %x, ID %i", type, mShaderID);
130c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams    LOGE(mShader.string());
131c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams
132c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams    if (mShaderID) {
133c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams        const char * ss = mShader.string();
134c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams        glShaderSource(mShaderID, 1, &ss, NULL);
135c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams        glCompileShader(mShaderID);
136cfb1d11ce6826fce7241d316d8b7dcab661f63a6Jason Sams
137c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams        GLint compiled = 0;
138c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams        glGetShaderiv(mShaderID, GL_COMPILE_STATUS, &compiled);
139c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams        if (!compiled) {
140c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams            GLint infoLen = 0;
141c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams            glGetShaderiv(mShaderID, GL_INFO_LOG_LENGTH, &infoLen);
142c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams            if (infoLen) {
143c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams                char* buf = (char*) malloc(infoLen);
144c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams                if (buf) {
145c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams                    glGetShaderInfoLog(mShaderID, infoLen, NULL, buf);
146c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams                    LOGE("Could not compile shader \n%s\n", buf);
147c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams                    free(buf);
148c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams                }
149c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams                glDeleteShader(mShaderID);
150c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams                mShaderID = 0;
151c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams                return false;
152c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams            }
153c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams        }
154c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams    }
155c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams    LOGV("--Shader load result %x ", glGetError());
156c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams    return true;
157c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams}
158f2a5d7326b38e5a28b6618f9b1e5a021aef7179fJason Sams
159f2a5d7326b38e5a28b6618f9b1e5a021aef7179fJason Samsvoid Program::setShader(const char *txt, uint32_t len)
160f2a5d7326b38e5a28b6618f9b1e5a021aef7179fJason Sams{
161f2a5d7326b38e5a28b6618f9b1e5a021aef7179fJason Sams    mUserShader.setTo(txt, len);
162f2a5d7326b38e5a28b6618f9b1e5a021aef7179fJason Sams}
163f2a5d7326b38e5a28b6618f9b1e5a021aef7179fJason Sams
1644815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams
1654815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams
1664815c0d121310cfcd6a8aba4eab77a9910af53acJason Samsnamespace android {
1674815c0d121310cfcd6a8aba4eab77a9910af53acJason Samsnamespace renderscript {
1684815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams
1694815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams
1704815c0d121310cfcd6a8aba4eab77a9910af53acJason Samsvoid rsi_ProgramBindConstants(Context *rsc, RsProgram vp, uint32_t slot, RsAllocation constants)
1714815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams{
1724815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    Program *p = static_cast<Program *>(vp);
1734815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams    p->bindAllocation(static_cast<Allocation *>(constants));
1744815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams}
1754815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams
1764815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams
1774815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams}
1784815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams}
1794815c0d121310cfcd6a8aba4eab77a9910af53acJason Sams
180