In preparation for supporting external image textures consisting of multiple planes (YUV). One now reserves entries in the sampling engine surface state table only for those samplers that are really used in the current program using a binding table associating a sampler with a slot in the state table. Previously the slot in the state table was determined using the sampler id as the state table index directly. This arrangement allows one to reserve continuous ranges in the state table instead of fixed single entries. Note that one does not have zero pointers in the state table anymore as one only uses as many slots from the beginning that are really needed by the program.
Signed-off-by: Topi Pohjolainen <topi.pohjolai...@intel.com> --- src/mesa/drivers/dri/i965/brw_context.h | 29 +++++++++++++++++++--- src/mesa/drivers/dri/i965/brw_fs.h | 1 + src/mesa/drivers/dri/i965/brw_fs_emit.cpp | 3 ++- src/mesa/drivers/dri/i965/brw_wm.c | 15 +++++++++++ src/mesa/drivers/dri/i965/brw_wm_surface_state.c | 7 +++--- 5 files changed, 48 insertions(+), 7 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index c173e49..531fc26 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -266,12 +266,38 @@ struct brw_vertex_program { }; +/** Number of texture sampler units */ +#define BRW_MAX_TEX_UNIT 16 + /** Subclass of Mesa fragment program */ struct brw_fragment_program { struct gl_fragment_program program; GLuint id; /**< serial no. to identify frag progs, never re-used */ + + /** + * Relation assigning shader samplers with a region in the HW surface state + * binding table. This used to be explicit one-sampler-one-surface-relation. + * However, in order to support image-external-textures a sampler + * representing, for example, multi-planar YUV texture may require up to + * three HW surfaces, one for each of the components/planes (Y, U and V). The + * actual number of HW surfaces associated with a sampler can be deduced from + * the format/layout of the texture image - here one simply stores the + * starting index. + * This relation can be set after linking but must in place before WM FS + * emission (one needs to know the surface state indices when generating the + * sampling commands). In addition, this relation must be accessible just + * before the actual execution of the shader is kicked off. (The contents of + * the surface state binding table itself are updated at that point). + */ + uint32_t sampler_to_surf_state_start[BRW_MAX_TEX_UNIT]; }; +static inline uint32_t brw_surf_index_texture( + const struct brw_fragment_program *fp, unsigned sampler) +{ + return fp->sampler_to_surf_state_start[sampler]; +} + struct brw_shader { struct gl_shader base; @@ -456,9 +482,6 @@ struct brw_vs_prog_data { const float **pull_param; }; -/** Number of texture sampler units */ -#define BRW_MAX_TEX_UNIT 16 - /** Max number of render targets in a shader */ #define BRW_MAX_DRAW_BUFFERS 8 diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h index d1bb111..ac6e631 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.h +++ b/src/mesa/drivers/dri/i965/brw_fs.h @@ -195,6 +195,7 @@ public: int base_mrf; /**< First MRF in the SEND message, if mlen is nonzero. */ uint32_t texture_offset; /**< Texture offset bitfield */ int sampler; + int surf_index_offset; int target; /**< MRT target. */ bool eot; bool header_present; diff --git a/src/mesa/drivers/dri/i965/brw_fs_emit.cpp b/src/mesa/drivers/dri/i965/brw_fs_emit.cpp index 3d1f3b3..b5caace 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_emit.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_emit.cpp @@ -489,7 +489,8 @@ fs_generator::generate_tex(fs_inst *inst, struct brw_reg dst, struct brw_reg src retype(dst, BRW_REGISTER_TYPE_UW), inst->base_mrf, src, - SURF_INDEX_TEXTURE(inst->sampler), + brw_surf_index_texture((const struct brw_fragment_program*)fp, + inst->sampler) + inst->surf_index_offset, inst->sampler, msg_type, rlen, diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c index 4b04465..05b4e68 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.c +++ b/src/mesa/drivers/dri/i965/brw_wm.c @@ -130,6 +130,18 @@ brw_wm_prog_data_free(const void *in_prog_data) ralloc_free((void *)prog_data->pull_param); } +static void brw_wm_fs_surf_setup(GLbitfield samplers, + uint32_t *sampler_to_surf_state_start) +{ + unsigned num_samplers = _mesa_fls(samplers); + unsigned surf_index = 0; + + for (unsigned s = 0; s < num_samplers; s++) { + if (samplers & (1 << s)) + sampler_to_surf_state_start[s] = SURF_INDEX_TEXTURE(surf_index++); + } +} + /** * All Mesa program -> GPU code generation goes through this function. * Depending on the instructions used (i.e. flow control instructions) @@ -172,6 +184,9 @@ bool do_wm_prog(struct brw_context *brw, brw_compute_barycentric_interp_modes(brw, c->key.flat_shade, &fp->program); + brw_wm_fs_surf_setup(fp->program.Base.SamplersUsed, + fp->sampler_to_surf_state_start); + program = brw_wm_fs_emit(brw, c, &fp->program, prog, &program_size); if (program == NULL) return false; diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c index 587ad05..7e17e5d 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c @@ -1374,7 +1374,6 @@ brw_update_texture_surfaces(struct brw_context *brw) for (unsigned s = 0; s < num_samplers; s++) { brw->vs.surf_offset[SURF_INDEX_VS_TEXTURE(s)] = 0; - brw->wm.surf_offset[SURF_INDEX_TEXTURE(s)] = 0; if (vs->SamplersUsed & (1 << s)) { const unsigned unit = vs->SamplerUnits[s]; @@ -1393,8 +1392,10 @@ brw_update_texture_surfaces(struct brw_context *brw) /* _NEW_TEXTURE */ if (ctx->Texture.Unit[unit]._ReallyEnabled) { intel->vtbl.update_texture_surface(ctx, unit, - brw->wm.surf_offset, - SURF_INDEX_TEXTURE(s)); + brw->wm.surf_offset, + brw_surf_index_texture( + (const struct brw_fragment_program *)brw->fragment_program, + s)); } } } -- 1.7.9.5 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev