Implement type generation for user uniforms in vertex shader.

This commit is contained in:
Jason Sams
2010-01-12 12:12:28 -08:00
parent 917cd4fcda
commit ea87e96959
8 changed files with 137 additions and 38 deletions

View File

@@ -39,6 +39,10 @@ public class Allocation extends BaseObj {
mType = t;
}
public Type getType() {
return mType;
}
public void uploadToTexture(int baseMipLevel) {
mRS.validate();
mRS.validateSurface();

View File

@@ -111,12 +111,13 @@ public class Program extends BaseObj {
mOutputs[mOutputCount++] = e;
}
public void addConstant(Type t) throws IllegalStateException {
public int addConstant(Type t) throws IllegalStateException {
// Should check for consistant and non-conflicting names...
if(mConstantCount >= MAX_CONSTANT) {
throw new IllegalArgumentException("Max input count exceeded.");
}
mConstants[mConstantCount++] = t;
mConstants[mConstantCount] = t;
return mConstantCount++;
}
public void setTextureCount(int count) throws IllegalArgumentException {

View File

@@ -95,7 +95,9 @@ Program::Program(Context *rsc, const char * shaderText, uint32_t shaderLength,
Program::~Program()
{
bindAllocation(NULL);
for (uint32_t ct=0; ct < MAX_UNIFORMS; ct++) {
bindAllocation(NULL, ct);
}
delete[] mInputElements;
delete[] mOutputElements;
@@ -106,15 +108,16 @@ Program::~Program()
}
void Program::bindAllocation(Allocation *alloc)
void Program::bindAllocation(Allocation *alloc, uint32_t slot)
{
if (mConstants.get() == alloc) {
LOGE("bind alloc %p %i", alloc, slot);
if (mConstants[slot].get() == alloc) {
return;
}
if (mConstants.get()) {
mConstants.get()->removeProgramToDirty(this);
if (mConstants[slot].get()) {
mConstants[slot].get()->removeProgramToDirty(this);
}
mConstants.set(alloc);
mConstants[slot].set(alloc);
if (alloc) {
alloc->addProgramToDirty(this);
}
@@ -239,7 +242,7 @@ namespace renderscript {
void rsi_ProgramBindConstants(Context *rsc, RsProgram vp, uint32_t slot, RsAllocation constants)
{
Program *p = static_cast<Program *>(vp);
p->bindAllocation(static_cast<Allocation *>(constants));
p->bindAllocation(static_cast<Allocation *>(constants), slot);
}
void rsi_ProgramBindTexture(Context *rsc, RsProgram vpf, uint32_t slot, RsAllocation a)

View File

@@ -39,7 +39,7 @@ public:
const uint32_t * params, uint32_t paramLength);
virtual ~Program();
void bindAllocation(Allocation *);
void bindAllocation(Allocation *, uint32_t slot);
virtual void createShader();
bool isUserProgram() const {return mUserShader.size() > 0;}
@@ -69,7 +69,7 @@ protected:
uint32_t mOutputCount;
uint32_t mConstantCount;
ObjectBaseRef<Allocation> mConstants;
ObjectBaseRef<Allocation> mConstants[MAX_UNIFORMS];
mutable bool mDirty;
String8 mShader;

View File

@@ -69,7 +69,7 @@ void ProgramVertex::setupGL(const Context *rsc, ProgramVertexState *state)
}
state->mLast.set(this);
const float *f = static_cast<const float *>(mConstants->getPtr());
const float *f = static_cast<const float *>(mConstants[0]->getPtr());
glMatrixMode(GL_TEXTURE);
if (mTextureMatrixEnable) {
@@ -116,16 +116,37 @@ void ProgramVertex::createShader()
{
mShader.setTo("");
for (uint32_t ct=0; ct < mUniformCount; ct++) {
mShader.append("uniform mat4 ");
mShader.append(mUniformNames[ct]);
mShader.append(";\n");
}
mShader.append("varying vec4 varColor;\n");
mShader.append("varying vec4 varTex0;\n");
if (mUserShader.length() > 1) {
mShader.append("uniform mat4 ");
mShader.append(mUniformNames[0]);
mShader.append(";\n");
LOGE("constant %i ", mConstantCount);
for (uint32_t ct=0; ct < mConstantCount; ct++) {
const Element *e = mConstantTypes[ct]->getElement();
for (uint32_t field=0; field < e->getFieldCount(); field++) {
const Element *f = e->getField(field);
// Cannot be complex
rsAssert(!f->getFieldCount());
switch(f->getComponent().getVectorSize()) {
case 1: mShader.append("uniform float UNI_"); break;
case 2: mShader.append("uniform vec2 UNI_"); break;
case 3: mShader.append("uniform vec3 UNI_"); break;
case 4: mShader.append("uniform vec4 UNI_"); break;
default:
rsAssert(0);
}
mShader.append(e->getFieldName(field));
mShader.append(";\n");
}
}
for (uint32_t ct=0; ct < mInputCount; ct++) {
const Element *e = mInputElements[ct].get();
for (uint32_t field=0; field < e->getFieldCount(); field++) {
@@ -148,6 +169,12 @@ void ProgramVertex::createShader()
}
mShader.append(mUserShader);
} else {
for (uint32_t ct=0; ct < mUniformCount; ct++) {
mShader.append("uniform mat4 ");
mShader.append(mUniformNames[ct]);
mShader.append(";\n");
}
for (uint32_t ct=VertexArray::POSITION; ct < mAttribCount; ct++) {
mShader.append("attribute vec4 ");
mShader.append(mAttribNames[ct]);
@@ -155,12 +182,12 @@ void ProgramVertex::createShader()
}
mShader.append("void main() {\n");
mShader.append(" gl_Position = uni_MVP * ATTRIB_Position;\n");
mShader.append(" gl_Position = UNI_MVP * ATTRIB_Position;\n");
mShader.append(" gl_PointSize = ATTRIB_PointSize.x;\n");
mShader.append(" varColor = ATTRIB_Color;\n");
if (mTextureMatrixEnable) {
mShader.append(" varTex0 = uni_TexMatrix * ATTRIB_Texture;\n");
mShader.append(" varTex0 = UNI_TexMatrix * ATTRIB_Texture;\n");
} else {
mShader.append(" varTex0 = ATTRIB_Texture;\n");
}
@@ -180,7 +207,7 @@ void ProgramVertex::setupGL2(const Context *rsc, ProgramVertexState *state, Shad
glVertexAttrib4f(1, state->color[0], state->color[1], state->color[2], state->color[3]);
const float *f = static_cast<const float *>(mConstants->getPtr());
const float *f = static_cast<const float *>(mConstants[0]->getPtr());
Matrix mvp;
mvp.load(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET]);
@@ -194,6 +221,54 @@ void ProgramVertex::setupGL2(const Context *rsc, ProgramVertexState *state, Shad
&f[RS_PROGRAM_VERTEX_TEXTURE_OFFSET]);
}
uint32_t uidx = 1;
for (uint32_t ct=0; ct < mConstantCount; ct++) {
Allocation *alloc = mConstants[ct+1].get();
if (!alloc) {
continue;
}
const uint8_t *data = static_cast<const uint8_t *>(alloc->getPtr());
const Element *e = mConstantTypes[ct]->getElement();
for (uint32_t field=0; field < e->getFieldCount(); field++) {
const Element *f = e->getField(field);
uint32_t offset = e->getFieldOffsetBytes(field);
int32_t slot = sc->vtxUniformSlot(uidx);
const float *fd = reinterpret_cast<const float *>(&data[offset]);
//LOGE("Uniform slot=%i, offset=%i, constant=%i, field=%i, uidx=%i", slot, offset, ct, field, uidx);
if (slot >= 0) {
switch(f->getComponent().getVectorSize()) {
case 1:
//LOGE("Uniform 1 = %f", fd[0]);
glUniform1fv(slot, 1, fd);
break;
case 2:
//LOGE("Uniform 2 = %f %f", fd[0], fd[1]);
glUniform2fv(slot, 1, fd);
break;
case 3:
//LOGE("Uniform 3 = %f %f %f", fd[0], fd[1], fd[2]);
glUniform3fv(slot, 1, fd);
break;
case 4:
//LOGE("Uniform 4 = %f %f %f %f", fd[0], fd[1], fd[2], fd[3]);
glUniform4fv(slot, 1, fd);
break;
default:
rsAssert(0);
}
}
uidx ++;
}
}
for (uint32_t ct=0; ct < mConstantCount; ct++) {
uint32_t glSlot = sc->vtxUniformSlot(ct + 1);
}
state->mLast.set(this);
rsc->checkError("ProgramVertex::setupGL2");
}
@@ -208,46 +283,46 @@ void ProgramVertex::addLight(const Light *l)
void ProgramVertex::setProjectionMatrix(const rsc_Matrix *m) const
{
float *f = static_cast<float *>(mConstants->getPtr());
float *f = static_cast<float *>(mConstants[0]->getPtr());
memcpy(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET], m, sizeof(rsc_Matrix));
mDirty = true;
}
void ProgramVertex::setModelviewMatrix(const rsc_Matrix *m) const
{
float *f = static_cast<float *>(mConstants->getPtr());
float *f = static_cast<float *>(mConstants[0]->getPtr());
memcpy(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET], m, sizeof(rsc_Matrix));
mDirty = true;
}
void ProgramVertex::setTextureMatrix(const rsc_Matrix *m) const
{
float *f = static_cast<float *>(mConstants->getPtr());
float *f = static_cast<float *>(mConstants[0]->getPtr());
memcpy(&f[RS_PROGRAM_VERTEX_TEXTURE_OFFSET], m, sizeof(rsc_Matrix));
mDirty = true;
}
void ProgramVertex::transformToScreen(const Context *rsc, float *v4out, const float *v3in) const
{
float *f = static_cast<float *>(mConstants->getPtr());
float *f = static_cast<float *>(mConstants[0]->getPtr());
Matrix mvp;
mvp.loadMultiply((Matrix *)&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET],
(Matrix *)&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET]);
mvp.vectorMultiply(v4out, v3in);
}
void ProgramVertex::initAddUserAttrib(const Element *e)
void ProgramVertex::initAddUserElement(const Element *e, String8 *names, uint32_t *count, const char *prefix)
{
rsAssert(e->getFieldCount());
for (uint32_t ct=0; ct < e->getFieldCount(); ct++) {
const Element *ce = e->getField(ct);
if (ce->getFieldCount()) {
initAddUserAttrib(ce);
initAddUserElement(ce, names, count, prefix);
} else {
String8 tmp("ATTRIB_");
String8 tmp(prefix);
tmp.append(e->getFieldName(ct));
mAttribNames[mAttribCount].setTo(tmp.string());
mAttribCount++;
names[*count].setTo(tmp.string());
(*count)++;
}
}
}
@@ -257,7 +332,13 @@ void ProgramVertex::init(Context *rsc)
if (mUserShader.size() > 0) {
mAttribCount = 0;
for (uint32_t ct=0; ct < mInputCount; ct++) {
initAddUserAttrib(mInputElements[ct].get());
initAddUserElement(mInputElements[ct].get(), mAttribNames, &mAttribCount, "ATTRIB_");
}
mUniformCount = 1;
mUniformNames[0].setTo("UNI_MVP");
for (uint32_t ct=0; ct < mInputCount; ct++) {
initAddUserElement(mConstantTypes[ct]->getElement(), mUniformNames, &mUniformCount, "UNI_");
}
} else {
mAttribCount = 5;
@@ -266,11 +347,11 @@ void ProgramVertex::init(Context *rsc)
mAttribNames[2].setTo("ATTRIB_Normal");
mAttribNames[3].setTo("ATTRIB_PointSize");
mAttribNames[4].setTo("ATTRIB_Texture");
}
mUniformCount = 2;
mUniformNames[0].setTo("uni_MVP");
mUniformNames[1].setTo("uni_TexMatrix");
mUniformCount = 2;
mUniformNames[0].setTo("UNI_MVP");
mUniformNames[1].setTo("UNI_TexMatrix");
}
createShader();
}
@@ -299,7 +380,7 @@ void ProgramVertexState::init(Context *rsc, int32_t w, int32_t h)
mDefaultAlloc.set(alloc);
mDefault.set(pv);
pv->init(rsc);
pv->bindAllocation(alloc);
pv->bindAllocation(alloc, 0);
color[0] = 1.f;
color[1] = 1.f;

View File

@@ -61,7 +61,7 @@ protected:
bool mTextureMatrixEnable;
private:
void initAddUserAttrib(const Element *e);
void initAddUserElement(const Element *e, String8 *names, uint32_t *count, const char *prefix);
};

View File

@@ -973,6 +973,13 @@ static void SC_uploadToBufferObject(RsAllocation va)
rsi_AllocationUploadToBufferObject(rsc, va);
}
static void SC_syncToGL(RsAllocation va)
{
GET_TLS();
Allocation *a = static_cast<Allocation *>(va);
}
static void SC_ClearColor(float r, float g, float b, float a)
{
//LOGE("c %f %f %f %f", r, g, b, a);
@@ -1321,6 +1328,9 @@ ScriptCState::SymbolTable_t ScriptCState::gSyms[] = {
{ "uploadToBufferObject", (void *)&SC_uploadToBufferObject,
"void", "(int)" },
{ "syncToGL", (void *)&SC_syncToGL,
"void", "(int)" },
{ "colorFloatRGBAtoUNorm8", (void *)&SC_colorFloatRGBAtoUNorm8,
"int", "(float, float, float, float)" },
{ "colorFloatRGBto565", (void *)&SC_colorFloatRGBAto565,

View File

@@ -132,7 +132,7 @@ bool ShaderCache::lookup(Context *rsc, ProgramVertex *vtx, ProgramFragment *frag
LOGV("vtx U, %s = %d\n", vtx->getUniformName(ct).string(), e->mVtxUniformSlots[ct]);
}
}
for (uint32_t ct=0; ct < vtx->getUniformCount(); ct++) {
for (uint32_t ct=0; ct < frag->getUniformCount(); ct++) {
e->mFragUniformSlots[ct] = glGetUniformLocation(pgm, frag->getUniformName(ct));
if (rsc->props.mLogShaders) {
LOGV("frag U, %s = %d\n", frag->getUniformName(ct).string(), e->mFragUniformSlots[ct]);