aboutsummaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri/i965
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2012-06-20 12:29:29 -0700
committerEric Anholt <[email protected]>2012-08-07 13:54:51 -0700
commit25d2bf3845e9a6faaef8d808c1255ec57dc71dba (patch)
tree838ba2d32ec6b35ad7df8de587282b5b3d8bc55f /src/mesa/drivers/dri/i965
parent5bffbd7ba2ba2ff21469b2a69a0ed67f0802fec7 (diff)
i965: Bind UBOs as surfaces like we do for pull constants.
v2: Comment fix, drop extraneous parens (review by Kenneth) Reviewed-by: Kenneth Graunke <[email protected]>
Diffstat (limited to 'src/mesa/drivers/dri/i965')
-rw-r--r--src/mesa/drivers/dri/i965/brw_context.h22
-rw-r--r--src/mesa/drivers/dri/i965/brw_state.h2
-rw-r--r--src/mesa/drivers/dri/i965/brw_state_upload.c4
-rw-r--r--src/mesa/drivers/dri/i965/brw_vs.c2
-rw-r--r--src/mesa/drivers/dri/i965/brw_vs_surface_state.c24
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_surface_state.c59
6 files changed, 110 insertions, 3 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
index 8a082abce7a..1548f81ec4f 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -493,6 +493,9 @@ struct brw_vs_ouput_sizes {
/** Maximum number of actual buffers used for stream output */
#define BRW_MAX_SOL_BUFFERS 4
+#define BRW_MAX_WM_UBOS 12
+#define BRW_MAX_VS_UBOS 12
+
/**
* Helpers to create Surface Binding Table indexes for draw buffers,
* textures, and constant buffers.
@@ -518,6 +521,11 @@ struct brw_vs_ouput_sizes {
* | . | . |
* | : | : |
* | 24 | Texture 15 |
+ * |-----|-------------------------|
+ * | 25 | UBO 0 |
+ * | . | . |
+ * | : | : |
+ * | 36 | UBO 11 |
* +-------------------------------+
*
* Our VS binding tables are programmed as follows:
@@ -529,6 +537,11 @@ struct brw_vs_ouput_sizes {
* | . | . |
* | : | : |
* | 16 | Texture 15 |
+ * +-----+-------------------------+
+ * | 17 | UBO 0 |
+ * | . | . |
+ * | : | : |
+ * | 28 | UBO 11 |
* +-------------------------------+
*
* Our (gen6) GS binding tables are programmed as follows:
@@ -547,13 +560,15 @@ struct brw_vs_ouput_sizes {
#define SURF_INDEX_DRAW(d) (d)
#define SURF_INDEX_FRAG_CONST_BUFFER (BRW_MAX_DRAW_BUFFERS + 1)
#define SURF_INDEX_TEXTURE(t) (BRW_MAX_DRAW_BUFFERS + 2 + (t))
+#define SURF_INDEX_WM_UBO(u) (SURF_INDEX_TEXTURE(BRW_MAX_TEX_UNIT) + u)
/** Maximum size of the binding table. */
-#define BRW_MAX_WM_SURFACES SURF_INDEX_TEXTURE(BRW_MAX_TEX_UNIT)
+#define BRW_MAX_WM_SURFACES SURF_INDEX_WM_UBO(BRW_MAX_WM_UBOS)
#define SURF_INDEX_VERT_CONST_BUFFER (0)
#define SURF_INDEX_VS_TEXTURE(t) (SURF_INDEX_VERT_CONST_BUFFER + 1 + (t))
-#define BRW_MAX_VS_SURFACES SURF_INDEX_VS_TEXTURE(BRW_MAX_TEX_UNIT)
+#define SURF_INDEX_VS_UBO(u) (SURF_INDEX_VS_TEXTURE(BRW_MAX_TEX_UNIT) + u)
+#define BRW_MAX_VS_SURFACES SURF_INDEX_VS_UBO(BRW_MAX_VS_UBOS)
#define SURF_INDEX_SOL_BINDING(t) ((t))
#define BRW_MAX_GS_SURFACES SURF_INDEX_SOL_BINDING(BRW_MAX_SOL_BINDINGS)
@@ -1135,6 +1150,9 @@ brw_update_sol_surface(struct brw_context *brw,
struct gl_buffer_object *buffer_obj,
uint32_t *out_offset, unsigned num_vector_components,
unsigned stride_dwords, unsigned offset_dwords);
+void brw_upload_ubo_surfaces(struct brw_context *brw,
+ struct gl_shader *shader,
+ uint32_t *surf_offsets);
/* gen6_sol.c */
void
diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h
index 8b99c521b78..2540cd574b2 100644
--- a/src/mesa/drivers/dri/i965/brw_state.h
+++ b/src/mesa/drivers/dri/i965/brw_state.h
@@ -71,6 +71,7 @@ extern const struct brw_tracked_state brw_state_base_address;
extern const struct brw_tracked_state brw_urb_fence;
extern const struct brw_tracked_state brw_vertex_state;
extern const struct brw_tracked_state brw_vs_prog;
+extern const struct brw_tracked_state brw_vs_ubo_surfaces;
extern const struct brw_tracked_state brw_vs_unit;
extern const struct brw_tracked_state brw_wm_input_sizes;
extern const struct brw_tracked_state brw_wm_prog;
@@ -78,6 +79,7 @@ extern const struct brw_tracked_state brw_renderbuffer_surfaces;
extern const struct brw_tracked_state brw_texture_surfaces;
extern const struct brw_tracked_state brw_wm_binding_table;
extern const struct brw_tracked_state brw_vs_binding_table;
+extern const struct brw_tracked_state brw_wm_ubo_surfaces;
extern const struct brw_tracked_state brw_wm_unit;
extern const struct brw_tracked_state brw_psp_urb_cbs;
diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c
index 12535ed01cd..c3e6de49779 100644
--- a/src/mesa/drivers/dri/i965/brw_state_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_state_upload.c
@@ -143,7 +143,9 @@ static const struct brw_tracked_state *gen6_atoms[] =
* table upload must be last.
*/
&brw_vs_pull_constants,
+ &brw_vs_ubo_surfaces,
&brw_wm_pull_constants,
+ &brw_wm_ubo_surfaces,
&gen6_renderbuffer_surfaces,
&brw_texture_surfaces,
&gen6_sol_surface,
@@ -215,7 +217,9 @@ const struct brw_tracked_state *gen7_atoms[] =
* table upload must be last.
*/
&brw_vs_pull_constants,
+ &brw_vs_ubo_surfaces,
&brw_wm_pull_constants,
+ &brw_wm_ubo_surfaces,
&gen6_renderbuffer_surfaces,
&brw_texture_surfaces,
&brw_vs_binding_table,
diff --git a/src/mesa/drivers/dri/i965/brw_vs.c b/src/mesa/drivers/dri/i965/brw_vs.c
index b1b073e9bde..feec4558762 100644
--- a/src/mesa/drivers/dri/i965/brw_vs.c
+++ b/src/mesa/drivers/dri/i965/brw_vs.c
@@ -250,7 +250,7 @@ do_vs_prog(struct brw_context *brw,
if (c.prog_data.nr_pull_params)
c.prog_data.num_surfaces = 1;
if (c.vp->program.Base.SamplersUsed)
- c.prog_data.num_surfaces = BRW_MAX_VS_SURFACES;
+ c.prog_data.num_surfaces = SURF_INDEX_VS_TEXTURE(BRW_MAX_TEX_UNIT);
/* Scratch space is used for register spilling */
if (c.last_scratch) {
diff --git a/src/mesa/drivers/dri/i965/brw_vs_surface_state.c b/src/mesa/drivers/dri/i965/brw_vs_surface_state.c
index 202614551a5..e29797e92fa 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_surface_state.c
@@ -111,6 +111,30 @@ const struct brw_tracked_state brw_vs_pull_constants = {
.emit = brw_upload_vs_pull_constants,
};
+static void
+brw_upload_vs_ubo_surfaces(struct brw_context *brw)
+{
+ struct gl_context *ctx = &brw->intel.ctx;
+ /* _NEW_PROGRAM */
+ struct gl_shader_program *prog = ctx->Shader.CurrentVertexProgram;
+
+ if (!prog)
+ return;
+
+ brw_upload_ubo_surfaces(brw, prog->_LinkedShaders[MESA_SHADER_VERTEX],
+ &brw->vs.surf_offset[SURF_INDEX_VS_UBO(0)]);
+}
+
+const struct brw_tracked_state brw_vs_ubo_surfaces = {
+ .dirty = {
+ .mesa = (_NEW_PROGRAM |
+ _NEW_BUFFER_OBJECT),
+ .brw = BRW_NEW_BATCH,
+ .cache = 0,
+ },
+ .emit = brw_upload_vs_ubo_surfaces,
+};
+
/**
* Constructs the binding table for the WM surface state, which maps unit
* numbers to surface state objects.
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 33c21982a47..4d3d265d40c 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
@@ -1263,6 +1263,65 @@ const struct brw_tracked_state brw_texture_surfaces = {
.emit = brw_update_texture_surfaces,
};
+void
+brw_upload_ubo_surfaces(struct brw_context *brw,
+ struct gl_shader *shader,
+ uint32_t *surf_offsets)
+{
+ struct gl_context *ctx = &brw->intel.ctx;
+ struct intel_context *intel = &brw->intel;
+
+ if (!shader)
+ return;
+
+ for (int i = 0; i < shader->NumUniformBlocks; i++) {
+ struct gl_uniform_buffer_binding *binding;
+ struct intel_buffer_object *intel_bo;
+
+ binding = &ctx->UniformBufferBindings[shader->UniformBlocks[i].Binding];
+ intel_bo = intel_buffer_object(binding->BufferObject);
+ drm_intel_bo *bo = intel_bufferobj_buffer(intel, intel_bo, INTEL_READ);
+
+ /* Because behavior for referencing outside of the binding's size in the
+ * glBindBufferRange case is undefined, we can just bind the whole buffer
+ * glBindBufferBase wants and be a correct implementation.
+ */
+ int size = bo->size - binding->Offset;
+ size = ALIGN(size, 16) / 16; /* The interface takes a number of vec4s */
+
+ intel->vtbl.create_constant_surface(brw, bo, binding->Offset,
+ size,
+ &surf_offsets[i]);
+ }
+
+ if (shader->NumUniformBlocks)
+ brw->state.dirty.brw |= BRW_NEW_SURFACES;
+}
+
+static void
+brw_upload_wm_ubo_surfaces(struct brw_context *brw)
+{
+ struct gl_context *ctx = &brw->intel.ctx;
+ /* _NEW_PROGRAM */
+ struct gl_shader_program *prog = ctx->Shader._CurrentFragmentProgram;
+
+ if (!prog)
+ return;
+
+ brw_upload_ubo_surfaces(brw, prog->_LinkedShaders[MESA_SHADER_FRAGMENT],
+ &brw->wm.surf_offset[SURF_INDEX_WM_UBO(0)]);
+}
+
+const struct brw_tracked_state brw_wm_ubo_surfaces = {
+ .dirty = {
+ .mesa = (_NEW_PROGRAM |
+ _NEW_BUFFER_OBJECT),
+ .brw = BRW_NEW_BATCH,
+ .cache = 0,
+ },
+ .emit = brw_upload_wm_ubo_surfaces,
+};
+
/**
* Constructs the binding table for the WM surface state, which maps unit
* numbers to surface state objects.