diff options
author | Paul Berry <[email protected]> | 2011-11-28 06:55:01 -0800 |
---|---|---|
committer | Paul Berry <[email protected]> | 2011-12-20 15:00:23 -0800 |
commit | 9308f298300beaa757194a0db8ed50924754c011 (patch) | |
tree | db6ca76fa610b6e1102bb39f438830ad441569ae /src/mesa/drivers/dri/i965/gen6_sol.c | |
parent | 1413f955ebe213037a9d893e0b7391cac4ba3a57 (diff) |
i965 gen6: Initial implementation of transform feedback.
This patch adds basic transform feedback capability for Gen6 hardware.
This consists of several related pieces of functionality:
(1) In gen6_sol.c, we set up binding table entries for use by
transform feedback. We use one binding table entry per transform
feedback varying (this allows us to avoid doing pointer arithmetic in
the shader, since we can set up the binding table entries with the
appropriate offsets and surface pitches to place each varying at the
correct address).
(2) In brw_context.c, we advertise the hardware capabilities, which
are as follows:
MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 64
MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 4
MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 16
OpenGL 3.0 requires these values to be at least 64, 4, and 4,
respectively. The reason we advertise a larger value than required
for MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS is that we have already
set aside 64 binding table entries, so we might as well make them all
available in both separate attribs and interleaved modes.
(3) We set aside a single SVBI ("streamed vertex buffer index") for
use by transform feedback. The hardware supports four independent
SVBI's, but we only need one, since vertices are added to all
transform feedback buffers at the same rate. Note: at the moment this
index is reset to 0 only when the driver is initialized. It needs to
be reset to 0 whenever BeginTransformFeedback() is called, and
otherwise preserved.
(4) In brw_gs_emit.c and brw_gs.c, we modify the geometry shader
program to output transform feedback data as a side effect.
(5) In gen6_gs_state.c, we configure the geometry shader stage to
handle the SVBI pointer correctly.
Note: ordering of vertices is not yet correct for triangle strips
(alternate triangles are improperly oriented). This will be addressed
in a future patch.
Reviewed-by: Kenneth Graunke <[email protected]>
Reviewed-by: Eric Anholt <[email protected]>
Diffstat (limited to 'src/mesa/drivers/dri/i965/gen6_sol.c')
-rw-r--r-- | src/mesa/drivers/dri/i965/gen6_sol.c | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i965/gen6_sol.c b/src/mesa/drivers/dri/i965/gen6_sol.c new file mode 100644 index 00000000000..491b39cce12 --- /dev/null +++ b/src/mesa/drivers/dri/i965/gen6_sol.c @@ -0,0 +1,71 @@ +/* + * Copyright © 2011 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/** \file gen6_sol.c + * + * Code to initialize the binding table entries used by transform feedback. + */ + +#include "brw_context.h" +#include "brw_defines.h" + +static void +gen6_update_sol_surfaces(struct brw_context *brw) +{ + struct gl_context *ctx = &brw->intel.ctx; + /* _NEW_TRANSFORM_FEEDBACK */ + struct gl_transform_feedback_object *xfb_obj = + ctx->TransformFeedback.CurrentObject; + /* BRW_NEW_VERTEX_PROGRAM */ + const struct gl_shader_program *shaderprog = + ctx->Shader.CurrentVertexProgram; + const struct gl_transform_feedback_info *linked_xfb_info = + &shaderprog->LinkedTransformFeedback; + int i; + + for (i = 0; i < BRW_MAX_SOL_BINDINGS; ++i) { + const int surf_index = SURF_INDEX_SOL_BINDING(i); + if (xfb_obj->Active && i < linked_xfb_info->NumOutputs) { + unsigned buffer = linked_xfb_info->Outputs[i].OutputBuffer; + unsigned buffer_offset = + xfb_obj->Offset[buffer] / 4 + + linked_xfb_info->Outputs[i].DstOffset; + brw_update_sol_surface( + brw, xfb_obj->Buffers[buffer], &brw->bind.surf_offset[surf_index], + linked_xfb_info->Outputs[i].NumComponents, + linked_xfb_info->BufferStride[buffer], buffer_offset); + } else { + brw->bind.surf_offset[surf_index] = 0; + } + } +} + +const struct brw_tracked_state gen6_sol_surface = { + .dirty = { + .mesa = _NEW_TRANSFORM_FEEDBACK, + .brw = (BRW_NEW_BATCH | + BRW_NEW_VERTEX_PROGRAM), + .cache = 0 + }, + .emit = gen6_update_sol_surfaces, +}; |