diff options
author | David Li <davidxli@google.com> | 2011-01-27 16:28:32 -0800 |
---|---|---|
committer | David Li <davidxli@google.com> | 2011-01-27 16:28:32 -0800 |
commit | 36ffccf19c02a54a6dc9952dc9c181d4fda2a020 (patch) | |
tree | 4cf048e2284e20da12efe9b282105f86df831fad | |
parent | 13fea0fc797fa0d4c236db5aa2e6a23fc0e450db (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.h | 6 | ||||
-rw-r--r-- | src/glsl/ast_to_hir.cpp | 1 | ||||
-rw-r--r-- | src/glsl/ir_to_llvm.cpp | 54 | ||||
-rw-r--r-- | src/glsl/ir_to_llvm_helper.cpp | 10 | ||||
-rw-r--r-- | src/glsl/linker.cpp | 29 | ||||
-rw-r--r-- | src/glsl/main.cpp | 48 | ||||
-rw-r--r-- | src/pixelflinger2/pixelflinger2.h | 4 | ||||
-rw-r--r-- | src/pixelflinger2/shader.cpp | 2 |
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; |