Series looks good AFAICT. Jose
----- Original Message ----- > From: Dave Airlie <airl...@redhat.com> > > this adds UBO support to the state tracker, it works with softpipe > as-is. > > It uses UARL + CONST[x][ADDR[0].x] type constructs. > > Signed-off-by: Dave Airlie <airl...@redhat.com> > --- > src/mesa/state_tracker/st_atom.c | 2 + > src/mesa/state_tracker/st_atom.h | 2 + > src/mesa/state_tracker/st_atom_constbuf.c | 70 > +++++++++++++++++++++++++++- > src/mesa/state_tracker/st_cb_bufferobjects.c | 3 ++ > src/mesa/state_tracker/st_extensions.c | 13 ++++++ > src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 63 > ++++++++++++++++++++++--- > 6 files changed, 146 insertions(+), 7 deletions(-) > > diff --git a/src/mesa/state_tracker/st_atom.c > b/src/mesa/state_tracker/st_atom.c > index 102fee9..091bd55 100644 > --- a/src/mesa/state_tracker/st_atom.c > +++ b/src/mesa/state_tracker/st_atom.c > @@ -64,6 +64,8 @@ static const struct st_tracked_state *atoms[] = > &st_update_vs_constants, > &st_update_gs_constants, > &st_update_fs_constants, > + &st_upload_vs_ubos, > + &st_upload_fs_ubos, > &st_update_pixel_transfer, > > /* this must be done after the vertex program update */ > diff --git a/src/mesa/state_tracker/st_atom.h > b/src/mesa/state_tracker/st_atom.h > index 6c7d09f..ca79b44 100644 > --- a/src/mesa/state_tracker/st_atom.h > +++ b/src/mesa/state_tracker/st_atom.h > @@ -67,6 +67,8 @@ extern const struct st_tracked_state > st_finalize_textures; > extern const struct st_tracked_state st_update_fs_constants; > extern const struct st_tracked_state st_update_gs_constants; > extern const struct st_tracked_state st_update_vs_constants; > +extern const struct st_tracked_state st_upload_fs_ubos; > +extern const struct st_tracked_state st_upload_vs_ubos; > extern const struct st_tracked_state st_update_pixel_transfer; > > > diff --git a/src/mesa/state_tracker/st_atom_constbuf.c > b/src/mesa/state_tracker/st_atom_constbuf.c > index 580393e..ea0cf0e 100644 > --- a/src/mesa/state_tracker/st_atom_constbuf.c > +++ b/src/mesa/state_tracker/st_atom_constbuf.c > @@ -45,7 +45,7 @@ > #include "st_atom.h" > #include "st_atom_constbuf.h" > #include "st_program.h" > - > +#include "st_cb_bufferobjects.h" > > /** > * Pass the given program parameters to the graphics pipe as a > @@ -175,3 +175,71 @@ const struct st_tracked_state > st_update_gs_constants = { > }, > update_gs_constants /* update */ > }; > + > +static void st_upload_ubos(struct st_context *st, > + struct gl_shader *shader, > + unsigned shader_type) > +{ > + int i; > + struct pipe_constant_buffer cb = { 0 }; > + assert(shader_type == PIPE_SHADER_VERTEX || > + shader_type == PIPE_SHADER_FRAGMENT); > + > + if (!shader) > + return; > + > + for (i = 0; i < shader->NumUniformBlocks; i++) { > + struct gl_uniform_buffer_binding *binding; > + struct st_buffer_object *st_obj; > + > + binding = > &st->ctx->UniformBufferBindings[shader->UniformBlocks[i].Binding]; > + st_obj = st_buffer_object(binding->BufferObject); > + pipe_resource_reference(&cb.buffer, st_obj->buffer); > + > + cb.buffer_size = st_obj->buffer->width0 - binding->Offset; > + > + st->pipe->set_constant_buffer(st->pipe, shader_type, 1 + i, > &cb); > + pipe_resource_reference(&cb.buffer, NULL); > + } > +} > + > +static void upload_vs_ubos(struct st_context *st) > +{ > + struct gl_shader_program *prog = > st->ctx->Shader.CurrentVertexProgram; > + > + if (!prog) > + return; > + > + st_upload_ubos(st, prog->_LinkedShaders[MESA_SHADER_VERTEX], > PIPE_SHADER_VERTEX); > +} > + > +const struct st_tracked_state st_upload_vs_ubos = { > + "st_upload_vs_ubos", > + { > + (_NEW_PROGRAM | _NEW_BUFFER_OBJECT), > + ST_NEW_VERTEX_PROGRAM, > + }, > + upload_vs_ubos > +}; > + > +static void upload_fs_ubos(struct st_context *st) > +{ > + struct gl_shader_program *prog = > st->ctx->Shader.CurrentFragmentProgram; > + > + if (!prog) > + return; > + > + st_upload_ubos(st, prog->_LinkedShaders[MESA_SHADER_FRAGMENT], > PIPE_SHADER_FRAGMENT); > + > +} > + > +const struct st_tracked_state st_upload_fs_ubos = { > + "st_upload_fs_ubos", > + { > + (_NEW_PROGRAM | _NEW_BUFFER_OBJECT), > + ST_NEW_FRAGMENT_PROGRAM, > + }, > + upload_fs_ubos > +}; > + > + > diff --git a/src/mesa/state_tracker/st_cb_bufferobjects.c > b/src/mesa/state_tracker/st_cb_bufferobjects.c > index ac38128..7d1c05a 100644 > --- a/src/mesa/state_tracker/st_cb_bufferobjects.c > +++ b/src/mesa/state_tracker/st_cb_bufferobjects.c > @@ -198,6 +198,9 @@ st_bufferobj_data(struct gl_context *ctx, > case GL_TRANSFORM_FEEDBACK_BUFFER: > bind = PIPE_BIND_STREAM_OUTPUT; > break; > + case GL_UNIFORM_BUFFER: > + bind = PIPE_BIND_CONSTANT_BUFFER; > + break; > default: > bind = 0; > } > diff --git a/src/mesa/state_tracker/st_extensions.c > b/src/mesa/state_tracker/st_extensions.c > index ccb1f36..d76cfdb 100644 > --- a/src/mesa/state_tracker/st_extensions.c > +++ b/src/mesa/state_tracker/st_extensions.c > @@ -70,6 +70,8 @@ void st_init_limits(struct st_context *st) > struct pipe_screen *screen = st->pipe->screen; > struct gl_constants *c = &st->ctx->Const; > gl_shader_type sh; > + boolean can_ubo = TRUE; > + int max_const_buffers; > > c->MaxTextureLevels > = _min(screen->get_param(screen, > PIPE_CAP_MAX_TEXTURE_2D_LEVELS), > @@ -218,6 +220,14 @@ void st_init_limits(struct st_context *st) > options->EmitNoIndirectUniform = > !screen->get_shader_param(screen, sh, > PIPE_SHADER_CAP_INDIRECT_CONST_ADDR); > > + if (options->EmitNoIndirectUniform) > + can_ubo = FALSE; > + > + max_const_buffers = screen->get_shader_param(screen, sh, > + > > PIPE_SHADER_CAP_MAX_CONST_BUFFERS); > + if (max_const_buffers < 12) > + can_ubo = FALSE; > + > if (options->EmitNoLoops) > options->MaxUnrollIterations = > MIN2(screen->get_shader_param(screen, sh, > PIPE_SHADER_CAP_MAX_INSTRUCTIONS), 65536); > else > @@ -251,6 +261,9 @@ void st_init_limits(struct st_context *st) > > c->GLSLSkipStrictMaxVaryingLimitCheck = > screen->get_param(screen, PIPE_CAP_TGSI_CAN_COMPACT_VARYINGS); > + > + if (can_ubo) > + st->ctx->Extensions.ARB_uniform_buffer_object = GL_TRUE; > } > > > diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp > b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp > index ae3b8b2..e8a174c 100644 > --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp > +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp > @@ -107,6 +107,7 @@ public: > else > this->swizzle = SWIZZLE_XYZW; > this->negate = 0; > + this->index2D = 0; > this->type = type ? type->base_type : GLSL_TYPE_ERROR; > this->reladdr = NULL; > } > @@ -116,6 +117,18 @@ public: > this->type = type; > this->file = file; > this->index = index; > + this->index2D = 0; > + this->swizzle = SWIZZLE_XYZW; > + this->negate = 0; > + this->reladdr = NULL; > + } > + > + st_src_reg(gl_register_file file, int index, int type, int > index2D) > + { > + this->type = type; > + this->file = file; > + this->index = index; > + this->index2D = index2D; > this->swizzle = SWIZZLE_XYZW; > this->negate = 0; > this->reladdr = NULL; > @@ -126,6 +139,7 @@ public: > this->type = GLSL_TYPE_ERROR; > this->file = PROGRAM_UNDEFINED; > this->index = 0; > + this->index2D = 0; > this->swizzle = 0; > this->negate = 0; > this->reladdr = NULL; > @@ -135,6 +149,7 @@ public: > > gl_register_file file; /**< PROGRAM_* from Mesa */ > int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, > etc. */ > + int index2D; > GLuint swizzle; /**< SWIZZLE_XYZWONEZERO swizzles from Mesa. */ > int negate; /**< NEGATE_XYZW mask from mesa */ > int type; /** GLSL_TYPE_* from GLSL IR (enum glsl_base_type) */ > @@ -183,6 +198,7 @@ st_src_reg::st_src_reg(st_dst_reg reg) > this->swizzle = SWIZZLE_XYZW; > this->negate = 0; > this->reladdr = reg.reladdr; > + this->index2D = 0; > } > > st_dst_reg::st_dst_reg(st_src_reg reg) > @@ -1873,10 +1889,29 @@ glsl_to_tgsi_visitor::visit(ir_expression > *ir) > assert(!"GLSL 1.30 features unsupported"); > break; > > - case ir_binop_ubo_load: > - assert(!"not yet supported"); > - break; > + case ir_binop_ubo_load: { > + ir_constant *uniform_block = ir->operands[0]->as_constant(); > + st_src_reg index_reg = get_temp(glsl_type::uint_type); > + st_src_reg cbuf; > + > + cbuf.type = glsl_type::vec4_type->base_type; > + cbuf.file = PROGRAM_CONSTANT; > + cbuf.index = 0; > + cbuf.index2D = uniform_block->value.u[0] + 1; > + cbuf.reladdr = NULL; > + cbuf.negate = 0; > + > + assert(ir->type->is_vector() || ir->type->is_scalar()); > > + emit(ir, TGSI_OPCODE_USHR, st_dst_reg(index_reg), op[1], > st_src_reg_for_int(4)); > + > + cbuf.swizzle = swizzle_for_size(ir->type->vector_elements); > + cbuf.reladdr = ralloc(mem_ctx, st_src_reg); > + memcpy(cbuf.reladdr, &index_reg, sizeof(index_reg)); > + > + emit(ir, TGSI_OPCODE_MOV, result_dst, cbuf); > + break; > + } > case ir_quadop_vector: > /* This operation should have already been handled. > */ > @@ -4061,7 +4096,7 @@ dst_register(struct st_translate *t, > static struct ureg_src > src_register(struct st_translate *t, > gl_register_file file, > - GLint index) > + GLint index, GLint index2D) > { > switch(file) { > case PROGRAM_UNDEFINED: > @@ -4081,7 +4116,13 @@ src_register(struct st_translate *t, > return t->constants[index]; > case PROGRAM_STATE_VAR: > case PROGRAM_CONSTANT: /* ie, immediate */ > - if (index < 0) > + if (index2D) { > + struct ureg_src src; > + src = ureg_src_register(TGSI_FILE_CONSTANT, 0); > + src.Dimension = 1; > + src.DimensionIndex = index2D; > + return src; > + } else if (index < 0) > return ureg_DECL_constant(t->ureg, 0); > else > return t->constants[index]; > @@ -4160,7 +4201,7 @@ translate_dst(struct st_translate *t, > static struct ureg_src > translate_src(struct st_translate *t, const st_src_reg *src_reg) > { > - struct ureg_src src = src_register(t, src_reg->file, > src_reg->index); > + struct ureg_src src = src_register(t, src_reg->file, > src_reg->index, src_reg->index2D); > > src = ureg_swizzle(src, > GET_SWZ(src_reg->swizzle, 0) & 0x3, > @@ -4754,6 +4795,14 @@ st_translate_program( > } > } > } > + > + if (program->shader_program) { > + unsigned num_ubos = program->shader_program->NumUniformBlocks; > + > + for (i = 0; i < num_ubos; i++) { > + ureg_DECL_constant2D(t->ureg, 0, > program->shader_program->UniformBlocks[i].UniformBufferSize / 4, i + > 1); > + } > + } > > /* Emit immediate values. > */ > @@ -5090,6 +5139,8 @@ st_link_shader(struct gl_context *ctx, struct > gl_shader_program *prog) > || progress; > > progress = do_vec_index_to_cond_assign(ir) || progress; > + > + lower_ubo_reference(prog->_LinkedShaders[i], ir); > } while (progress); > > validate_ir_tree(ir); > -- > 1.8.0.1 > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev > _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev