summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Li <davidxli@google.com>2011-01-27 16:28:32 -0800
committerDavid Li <davidxli@google.com>2011-01-27 16:28:32 -0800
commit36ffccf19c02a54a6dc9952dc9c181d4fda2a020 (patch)
tree4cf048e2284e20da12efe9b282105f86df831fad
parent13fea0fc797fa0d4c236db5aa2e6a23fc0e450db (diff)
Checkpoint on implementing texture sampling
Fixed sampler uniform location assigning. Signed-off-by: David Li <davidxli@google.com>
-rw-r--r--include/pixelflinger2/pixelflinger2_interface.h6
-rw-r--r--src/glsl/ast_to_hir.cpp1
-rw-r--r--src/glsl/ir_to_llvm.cpp54
-rw-r--r--src/glsl/ir_to_llvm_helper.cpp10
-rw-r--r--src/glsl/linker.cpp29
-rw-r--r--src/glsl/main.cpp48
-rw-r--r--src/pixelflinger2/pixelflinger2.h4
-rw-r--r--src/pixelflinger2/shader.cpp2
8 files changed, 114 insertions, 40 deletions
diff --git a/include/pixelflinger2/pixelflinger2_interface.h b/include/pixelflinger2/pixelflinger2_interface.h
index ee4cdca..47a78e0 100644
--- a/include/pixelflinger2/pixelflinger2_interface.h
+++ b/include/pixelflinger2/pixelflinger2_interface.h
@@ -67,10 +67,8 @@ typedef struct GGLTexture {
// data layout is level 0 of first surface (cubemap +x), level 0 of second surface (for cube map, -x),
// level 0 of 3rd surface (cubemap +y), cubemap level 0 -y, cubemap level 0 +z,
// cubemap level 0 -z, level 1 of first surface,
- // levels[1] is level 1 of 1st surface, level 1 of 2nd surface ....
- // levels[n] is max level of first surface...
- // levels[n] + 5 * width * height is last level of last cube map face
- void ** levels;
+ // then level 1 of 1st surface, level 1 of 2nd surface ....
+ void * levels;
// the following affects vs/fs jit; must fit in byte; size used in GetShaderKey
unsigned wrapS :
diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index 1e67d61..e56c5cf 100644
--- a/src/glsl/ast_to_hir.cpp
+++ b/src/glsl/ast_to_hir.cpp
@@ -1564,6 +1564,7 @@ ast_expression::hir(exec_list *instructions,
ir_variable *v = array->whole_variable_referenced();
if (v != NULL)
v->max_array_access = array->type->array_size();
+ // TODO: should this be array->type->array_size() - 1
}
}
diff --git a/src/glsl/ir_to_llvm.cpp b/src/glsl/ir_to_llvm.cpp
index e09e3d4..482d898 100644
--- a/src/glsl/ir_to_llvm.cpp
+++ b/src/glsl/ir_to_llvm.cpp
@@ -86,7 +86,8 @@ public:
const GGLContext * gglCtx;
ir_to_llvm_visitor(llvm::LLVMContext& p_ctx, llvm::Module* p_mod, const GGLContext * GGLCtx)
- : ctx(p_ctx), mod(p_mod), fun(0), loop(std::make_pair((llvm::BasicBlock*)0, (llvm::BasicBlock*)0)), bb(0), bld(ctx), gglCtx(GGLCtx)
+ : ctx(p_ctx), mod(p_mod), fun(0), loop(std::make_pair((llvm::BasicBlock*)0,
+ (llvm::BasicBlock*)0)), bb(0), bld(ctx), gglCtx(GGLCtx)
{
}
@@ -819,10 +820,55 @@ public:
virtual void visit(class ir_texture * ir)
{
- assert(ir_tex == ir->op);
llvm::Value * coordinate = llvm_value(ir->coordinate);
- result = tex2D(bld, coordinate, 0, gglCtx);
- assert(result);
+ if (ir->projector)
+ {
+ llvm::Value * proj = llvm_value(ir->projector);
+ unsigned width = ((llvm::VectorType*)coordinate->getType())->getNumElements();
+ llvm::Value * div = llvm::Constant::getNullValue(coordinate->getType());
+ for (unsigned i = 0; i < width; i++)
+ div = bld.CreateInsertElement(div, proj, bld.getInt32(i), "texProjDup");
+ coordinate = bld.CreateFDiv(coordinate, div, "texProj");
+ }
+
+ ir_variable * sampler = NULL;
+ if(ir_dereference_variable* deref = ir->sampler->as_dereference_variable())
+ sampler = deref->variable_referenced();
+ else if(ir_dereference_array* deref = ir->sampler->as_dereference_array())
+ {
+ result = llvm::Constant::getNullValue(llvm::VectorType::get(bld.getFloatTy(), 4));
+ return;
+ assert(0);
+ deref->array_index;
+ deref->array;
+ }
+ else if(ir->sampler->as_dereference())
+ {
+ assert(0);
+ ir_dereference_record* deref = (ir_dereference_record*)ir->sampler;
+ int idx = deref->record->type->field_index(deref->field);
+ assert(idx >= 0);
+ //return bld.CreateConstInBoundsGEP2_32(llvm_pointer(deref->record), 0, idx);
+ }
+ else
+ assert(0);
+
+ assert(sampler->location >= 0 && sampler->location < 64); // TODO: proper limit
+
+ // ESSL texture LOD is only for 2D texture in vert shader, and it's explicit
+ // bias used only in frag shader, and added to computed LOD
+ assert(ir_tex == ir->op);
+
+ assert(GLSL_TYPE_FLOAT == sampler->type->sampler_type);
+ printf("sampler '%s' location=%d dim=%d type=%d proj=%d lod=%d \n", sampler->name, sampler->location,
+ sampler->type->sampler_dimensionality, sampler->type->sampler_type,
+ ir->projector ? 1 : 0, ir->lod_info.lod ? 1 : 0);
+ if (GLSL_SAMPLER_DIM_CUBE == sampler->type->sampler_dimensionality)
+ result = texCube(bld, coordinate, sampler->location, gglCtx);
+ else if (GLSL_SAMPLER_DIM_2D == sampler->type->sampler_dimensionality)
+ result = tex2D(bld, coordinate, sampler->location, gglCtx);
+ else
+ assert(0);
}
virtual void visit(class ir_discard * ir)
diff --git a/src/glsl/ir_to_llvm_helper.cpp b/src/glsl/ir_to_llvm_helper.cpp
index 5fd4045..9794240 100644
--- a/src/glsl/ir_to_llvm_helper.cpp
+++ b/src/glsl/ir_to_llvm_helper.cpp
@@ -408,14 +408,12 @@ Value * tex2D(IRBuilder<> & builder, Value * in1, const unsigned sampler,
0 == gglCtx->textureState.textures[sampler].magFilter) { // GL_NEAREST
Value * ret = pointSample(builder, textureData, index,
gglCtx->textureState.textures[sampler].format/*, dstDesc*/);
- ret->dump();
return intColorVecToFloatColorVec(builder, ret);
} else if (1 == gglCtx->textureState.textures[sampler].minFilter &&
1 == gglCtx->textureState.textures[sampler].magFilter) { // GL_LINEAR
Value * ret = linearSample(builder, textureData, builder.getInt32(0), x, y, xLerp, yLerp,
textureW, textureH, textureWidth, textureHeight,
gglCtx->textureState.textures[sampler].format/*, dstDesc*/);
- ret->dump();
return intColorVecToFloatColorVec(builder, ret);
} else
assert(!"unsupported texture filter");
@@ -466,11 +464,11 @@ Value * texCube(IRBuilder<> & builder, Value * in1, const unsigned sampler,
Module * module = builder.GetInsertBlock()->getParent()->getParent();
std::vector<Value * > texcoords = extractVector(builder, in1);
- Value * textureDimensions = module->getGlobalVariable("textureDimensions");
+ Value * textureDimensions = module->getGlobalVariable(_PF2_TEXTURE_DIMENSIONS_NAME_);
if (!textureDimensions)
textureDimensions = new GlobalVariable(*module, intType, true,
GlobalValue::ExternalLinkage,
- NULL, "textureDimensions");
+ NULL, _PF2_TEXTURE_DIMENSIONS_NAME_);
Value * textureWidth = builder.CreateConstInBoundsGEP1_32(textureDimensions,
sampler * 2);
textureWidth = builder.CreateLoad(textureWidth, name("textureWidth"));
@@ -592,11 +590,11 @@ Value * texCube(IRBuilder<> & builder, Value * in1, const unsigned sampler,
Value * indexOffset = builder.CreateMul(builder.CreateMul(textureHeight, textureWidth), face);
Value * index = builder.CreateAdd(builder.CreateMul(y, textureWidth), x);
- Value * textureData = module->getGlobalVariable("textureData");
+ Value * textureData = module->getGlobalVariable(_PF2_TEXTURE_DATA_NAME_);
if (!textureData)
textureData = new GlobalVariable(*module, intPointerType,
true, GlobalValue::ExternalLinkage,
- NULL, "textureData");
+ NULL, _PF2_TEXTURE_DATA_NAME_);
textureData = builder.CreateConstInBoundsGEP1_32(textureData, sampler);
textureData = builder.CreateLoad(textureData);
diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
index 10b6f04..ac216e6 100644
--- a/src/glsl/linker.cpp
+++ b/src/glsl/linker.cpp
@@ -986,7 +986,7 @@ update_array_sizes(struct gl_shader_program *prog)
static void
add_uniform(void *mem_ctx, exec_list *uniforms, struct hash_table *ht,
const char *name, const glsl_type *type, GLenum shader_type,
- unsigned *next_shader_pos, unsigned *total_uniforms)
+ unsigned *next_shader_pos, unsigned *total_uniforms, unsigned *next_sampler_pos)
{
if (type->is_record()) {
for (unsigned int i = 0; i < type->length; i++) {
@@ -995,7 +995,7 @@ add_uniform(void *mem_ctx, exec_list *uniforms, struct hash_table *ht,
type->fields.structure[i].name);
add_uniform(mem_ctx, uniforms, ht, field_name, field_type,
- shader_type, next_shader_pos, total_uniforms);
+ shader_type, next_shader_pos, total_uniforms, next_sampler_pos);
}
} else {
uniform_node *n = (uniform_node *) hash_table_find(ht, name);
@@ -1009,7 +1009,7 @@ add_uniform(void *mem_ctx, exec_list *uniforms, struct hash_table *ht,
for (unsigned int i = 0; i < type->length; i++) {
char *elem_name = hieralloc_asprintf(mem_ctx, "%s[%d]", name, i);
add_uniform(mem_ctx, uniforms, ht, elem_name, array_elem_type,
- shader_type, next_shader_pos, total_uniforms);
+ shader_type, next_shader_pos, total_uniforms, next_sampler_pos);
}
return;
}
@@ -1040,11 +1040,18 @@ add_uniform(void *mem_ctx, exec_list *uniforms, struct hash_table *ht,
n->u->FragPos = -1;
n->u->GeomPos = -1;
(*total_uniforms)++;
-
+
+ if (type->is_sampler() || (array_elem_type && array_elem_type->is_sampler()))
+ {
+ n->u->VertPos = n->u->FragPos = n->u->GeomPos = *next_sampler_pos;
+ *next_sampler_pos += vec4_slots;
+ }
hash_table_insert(ht, n, name);
uniforms->push_tail(& n->link);
}
-
+
+ if (!(type->is_sampler() || (array_elem_type && array_elem_type->is_sampler())))
+ {
switch (shader_type) {
case GL_VERTEX_SHADER:
n->u->VertPos = *next_shader_pos;
@@ -1056,8 +1063,8 @@ add_uniform(void *mem_ctx, exec_list *uniforms, struct hash_table *ht,
n->u->GeomPos = *next_shader_pos;
break;
}
-
(*next_shader_pos) += vec4_slots;
+ }
}
}
@@ -1067,6 +1074,7 @@ assign_uniform_locations(struct gl_shader_program *prog)
/* */
exec_list uniforms;
unsigned total_uniforms = 0;
+ unsigned next_sampler_pos = 0; // all shaders in prog share same sampler location
hash_table *ht = hash_table_ctor(32, hash_table_string_hash,
hash_table_string_compare);
void *mem_ctx = hieralloc_new(NULL);
@@ -1075,7 +1083,7 @@ assign_uniform_locations(struct gl_shader_program *prog)
if (prog->_LinkedShaders[i] == NULL)
continue;
- unsigned next_position = 0;
+ unsigned next_position = 0; // TODO: shouldn't shaders of same prog share uniform location?
foreach_list(node, prog->_LinkedShaders[i]->ir) {
ir_variable *const var = ((ir_instruction *) node)->as_variable();
@@ -1091,10 +1099,13 @@ assign_uniform_locations(struct gl_shader_program *prog)
continue;
}
- var->location = next_position;
+ if (var->type->is_sampler() || (var->type->is_array() && var->type->fields.array->is_sampler()))
+ var->location = next_sampler_pos;
+ else
+ var->location = next_position;
add_uniform(mem_ctx, &uniforms, ht, var->name, var->type,
prog->_LinkedShaders[i]->Type,
- &next_position, &total_uniforms);
+ &next_position, &total_uniforms, &next_sampler_pos);
}
}
diff --git a/src/glsl/main.cpp b/src/glsl/main.cpp
index 175719d..3364ee1 100644
--- a/src/glsl/main.cpp
+++ b/src/glsl/main.cpp
@@ -561,19 +561,21 @@ void jit(llvm::Module * mod, gl_shader * shader)
int
main(int argc, char **argv)
{
+ static char basePath [256] = {0};
static char texturePath [256] = {0};
static char shaderPath [256] = {0};
+ static char cubeTexturePath [256] = {0};
static const char shaderFile[] = "fs.frag";
static const char textureFile[] = "android.tga";
+ static const char cubeTextureFile[] = "cube.tga";
- memcpy(texturePath, argv[0], strlen(argv[0]));
- char * slash = texturePath + strlen(texturePath);
- while (*slash != '/' && slash >= texturePath)
- slash--;
- memcpy(slash + 1, textureFile, strlen(textureFile));
- memcpy(shaderPath, texturePath, slash - texturePath + 1);
- memcpy(shaderPath + (slash - texturePath) + 1, shaderFile, strlen(shaderFile));
-
+ strncpy(basePath, argv[0], strrchr(argv[0], '/') - argv[0] + 1);
+ strcpy(shaderPath, basePath);
+ strcat(shaderPath, shaderFile);
+ strcpy(texturePath, basePath);
+ strcat(texturePath, textureFile);
+ strcpy(cubeTexturePath, basePath);
+ strcat(cubeTexturePath, cubeTextureFile);
//*
if (1 == argc) {
argc = 6;
@@ -653,29 +655,51 @@ main(int argc, char **argv)
ggl = CreateGGLInterface();
GGLTexture texture = {0};
- LoadTGA(texturePath, &texture.width, &texture.height, reinterpret_cast<void **>(&texture.levels));
+ LoadTGA(texturePath, &texture.width, &texture.height, &texture.levels);
texture.format = GGL_PIXEL_FORMAT_RGBA_8888;
texture.type = GL_TEXTURE_2D;
texture.levelCount = 1;
texture.wrapS = texture.wrapT = 0; // repeat = 0 fastest, clamp = 1, mirrored = 2
- texture.minFilter = texture.magFilter = 0; // nearest = 0, linear = 1
+ texture.minFilter = texture.magFilter = 1; // nearest = 0, linear = 1
ggl->SetSampler(ggl, 0, &texture);
+ static unsigned cubeTextureSurface [6] = {0xff0000ff, 0xff00ff00, 0xffff0000,
+ 0xff00ffff, 0xffffff00, 0xffff00ff};
+ GGLTexture cubeTexture = {GL_TEXTURE_CUBE_MAP, GGL_PIXEL_FORMAT_RGBA_8888, 1, 1, 1, cubeTextureSurface, 1, 2, 1, 1};
+
for (unsigned i = 0; do_jit && i < MESA_SHADER_TYPES; i++) {
struct gl_shader *shader = whole_program->_LinkedShaders[i];
if (!shader)
continue;
+ // TODO: fix add_uniform for sampler location
+ for (unsigned i = 0; i < whole_program->Uniforms->NumUniforms; i++)
+ {
+ const gl_uniform & uniform = whole_program->Uniforms->Uniforms[i];
+ ir_variable * var = NULL;
+ if (!(var = shader->symbols->get_variable(uniform.Name)))
+ continue;
+ assert(var->location >= 0);
+ printf("uniform '%s': location=%d type=%s \n", uniform.Name, uniform.FragPos, uniform.Type->name);
+ }
+ ir_variable * sampler = NULL;
+ if ((sampler = shader->symbols->get_variable("samp2D")) && sampler->location >= 0)
+ ggl->SetSampler(ggl, sampler->location, &texture);
+ if ((sampler = shader->symbols->get_variable("samp2DA")) && sampler->location >= 0)
+ ggl->SetSampler(ggl, sampler->location, &texture);
+ if ((sampler = shader->symbols->get_variable("sampCube")) && sampler->location >= 0)
+ ggl->SetSampler(ggl, sampler->location, &cubeTexture);
+
exec_list * ir = shader->ir;
do_mat_op_to_vec(ir);
puts("\n *** IR for JIT *** \n");
- _mesa_print_ir(ir, NULL);
+ //_mesa_print_ir(ir, NULL);
llvm::Module * module = glsl_ir_to_llvm_module(ir, (GGLContext *)ggl);
assert(module);
puts("\n *** Module for JIT *** \n");
- module->dump();
+ //module->dump();
jit(module, shader);
puts("jitted");
}
diff --git a/src/pixelflinger2/pixelflinger2.h b/src/pixelflinger2/pixelflinger2.h
index c1259a2..5b9aa1d 100644
--- a/src/pixelflinger2/pixelflinger2.h
+++ b/src/pixelflinger2/pixelflinger2.h
@@ -49,7 +49,7 @@ struct GGLContext
{
GGLInterface interface; // must be first member so that GGLContext * == GGLInterface *
- GGLSurface frameSurface;
+ GGLSurface frameSurface;
GGLSurface depthSurface;
GGLSurface stencilSurface;
@@ -155,6 +155,4 @@ void DestroyShaderFunctions(GGLInterface * iface); // destroy needed objects
// actual gl_shader and gl_shader_program is created and destroyed by ShaderCreate/Free,
// and ShaderProgramCreate/Free.
-
-
#endif // #ifndef _PIXELFLINGER2_H_
diff --git a/src/pixelflinger2/shader.cpp b/src/pixelflinger2/shader.cpp
index f3ae1c5..e201096 100644
--- a/src/pixelflinger2/shader.cpp
+++ b/src/pixelflinger2/shader.cpp
@@ -404,9 +404,7 @@ void SetShaderVerifyFunctions(struct GGLInterface * iface)
void InitializeShaderFunctions(struct GGLInterface * iface)
{
GGL_GET_CONTEXT(ctx, iface);
- puts("ctx->llvmCtx = new llvm::LLVMContext");
ctx->llvmCtx = new llvm::LLVMContext();
- printf("ctx->llvmCtx=%p \n", ctx->llvmCtx);
iface->ShaderCreate = ShaderCreate;
iface->ShaderCompile = ShaderCompile;