summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/i965/brw_wm_constant_buffer.c
diff options
context:
space:
mode:
authorKeith Whitwell <keithw@vmware.com>2009-11-01 14:32:50 +0000
committerKeith Whitwell <keithw@vmware.com>2009-11-01 14:33:01 +0000
commit15e7a3b8bb6771d24e5bde7805ea394f9ce0a3ec (patch)
tree799656b83f902dd40895ac859d12dba5e50d4341 /src/gallium/drivers/i965/brw_wm_constant_buffer.c
parent39448a9aa061291f4253ee2a1a42e2488e14233c (diff)
i965g: more files compiling
Diffstat (limited to 'src/gallium/drivers/i965/brw_wm_constant_buffer.c')
-rw-r--r--src/gallium/drivers/i965/brw_wm_constant_buffer.c151
1 files changed, 151 insertions, 0 deletions
diff --git a/src/gallium/drivers/i965/brw_wm_constant_buffer.c b/src/gallium/drivers/i965/brw_wm_constant_buffer.c
new file mode 100644
index 0000000000..7d2533b104
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_wm_constant_buffer.c
@@ -0,0 +1,151 @@
+/* XXX: Constant buffers disabled
+ */
+
+
+/**
+ * Create the constant buffer surface. Vertex/fragment shader constants will be
+ * read from this buffer with Data Port Read instructions/messages.
+ */
+struct brw_winsys_buffer *
+brw_create_constant_surface( struct brw_context *brw,
+ struct brw_surface_key *key )
+{
+ const GLint w = key->width - 1;
+ struct brw_winsys_buffer *bo;
+
+ memset(&surf, 0, sizeof(surf));
+
+ surf.ss0.mipmap_layout_mode = BRW_SURFACE_MIPMAPLAYOUT_BELOW;
+ surf.ss0.surface_type = BRW_SURFACE_BUFFER;
+ surf.ss0.surface_format = BRW_SURFACEFORMAT_R32G32B32A32_FLOAT;
+
+ assert(key->bo);
+ surf.ss1.base_addr = key->bo->offset; /* reloc */
+
+ surf.ss2.width = w & 0x7f; /* bits 6:0 of size or width */
+ surf.ss2.height = (w >> 7) & 0x1fff; /* bits 19:7 of size or width */
+ surf.ss3.depth = (w >> 20) & 0x7f; /* bits 26:20 of size or width */
+ surf.ss3.pitch = (key->pitch * key->cpp) - 1; /* ignored?? */
+ brw_set_surface_tiling(&surf, key->tiling); /* tiling now allowed */
+
+ bo = brw_upload_cache(&brw->surface_cache, BRW_SS_SURFACE,
+ key, sizeof(*key),
+ &key->bo, key->bo ? 1 : 0,
+ &surf, sizeof(surf),
+ NULL, NULL);
+
+ if (key->bo) {
+ /* Emit relocation to surface contents */
+ brw->sws->bo_emit_reloc(bo,
+ I915_GEM_DOMAIN_SAMPLER, 0,
+ 0,
+ offsetof(struct brw_surface_state, ss1),
+ key->bo);
+ }
+
+ return bo;
+}
+
+
+
+/**
+ * Update the surface state for a WM constant buffer.
+ * The constant buffer will be (re)allocated here if needed.
+ */
+static void
+brw_update_wm_constant_surface( struct brw_context *brw,
+ GLuint surf)
+{
+ struct brw_surface_key key;
+ struct brw_fragment_shader *fp = brw->curr.fragment_shader;
+ struct pipe_buffer *cbuf = brw->curr.fragment_constants;
+ int pitch = cbuf->size / (4 * sizeof(float));
+
+ /* If we're in this state update atom, we need to update WM constants, so
+ * free the old buffer and create a new one for the new contents.
+ */
+ brw->sws->bo_unreference(fp->const_buffer);
+ fp->const_buffer = brw_wm_update_constant_buffer(brw);
+
+ /* If there's no constant buffer, then no surface BO is needed to point at
+ * it.
+ */
+ if (cbuf == NULL) {
+ drm_intel_bo_unreference(brw->wm.surf_bo[surf]);
+ brw->wm.surf_bo[surf] = NULL;
+ return;
+ }
+
+ memset(&key, 0, sizeof(key));
+
+ key.ss0.mipmap_layout_mode = BRW_SURFACE_MIPMAPLAYOUT_BELOW;
+ key.ss0.surface_type = BRW_SURFACE_BUFFER;
+ key.ss0.surface_format = BRW_SURFACEFORMAT_R32G32B32A32_FLOAT;
+
+ key.bo = brw_buffer(cbuf)->bo;
+
+ key.ss2.width = (pitch-1) & 0x7f; /* bits 6:0 of size or width */
+ key.ss2.height = ((pitch-1) >> 7) & 0x1fff; /* bits 19:7 of size or width */
+ key.ss3.depth = ((pitch-1) >> 20) & 0x7f; /* bits 26:20 of size or width */
+ key.ss3.pitch = (pitch * 4 * sizeof(float)) - 1; /* ignored?? */
+ brw_set_surface_tiling(&surf, key->tiling); /* tiling now allowed */
+
+
+ /*
+ printf("%s:\n", __FUNCTION__);
+ printf(" width %d height %d depth %d cpp %d pitch %d\n",
+ key.width, key.height, key.depth, key.cpp, key.pitch);
+ */
+
+ brw->sws->bo_unreference(brw->wm.surf_bo[surf]);
+ brw->wm.surf_bo[surf] = brw_search_cache(&brw->surface_cache,
+ BRW_SS_SURFACE,
+ &key, sizeof(key),
+ &key.bo, 1,
+ NULL);
+ if (brw->wm.surf_bo[surf] == NULL) {
+ brw->wm.surf_bo[surf] = brw_create_constant_surface(brw, &key);
+ }
+ brw->state.dirty.brw |= BRW_NEW_WM_SURFACES;
+}
+
+/**
+ * Updates surface / buffer for fragment shader constant buffer, if
+ * one is required.
+ *
+ * This consumes the state updates for the constant buffer, and produces
+ * BRW_NEW_WM_SURFACES to get picked up by brw_prepare_wm_surfaces for
+ * inclusion in the binding table.
+ */
+static void prepare_wm_constant_surface(struct brw_context *brw )
+{
+ struct brw_fragment_program *fp =
+ (struct brw_fragment_program *) brw->fragment_program;
+ GLuint surf = SURF_INDEX_FRAG_CONST_BUFFER;
+
+ drm_intel_bo_unreference(fp->const_buffer);
+ fp->const_buffer = brw_wm_update_constant_buffer(brw);
+
+ /* If there's no constant buffer, then no surface BO is needed to point at
+ * it.
+ */
+ if (fp->const_buffer == 0) {
+ if (brw->wm.surf_bo[surf] != NULL) {
+ drm_intel_bo_unreference(brw->wm.surf_bo[surf]);
+ brw->wm.surf_bo[surf] = NULL;
+ brw->state.dirty.brw |= BRW_NEW_WM_SURFACES;
+ }
+ return;
+ }
+
+ brw_update_wm_constant_surface(ctx, surf);
+}
+
+const struct brw_tracked_state brw_wm_constant_surface = {
+ .dirty = {
+ .mesa = (_NEW_PROGRAM_CONSTANTS),
+ .brw = (BRW_NEW_FRAGMENT_PROGRAM),
+ .cache = 0
+ },
+ .prepare = prepare_wm_constant_surface,
+};