aboutsummaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri/i965/brw_ff_gs.c
diff options
context:
space:
mode:
authorKenneth Graunke <[email protected]>2014-10-28 17:18:55 -0700
committerKenneth Graunke <[email protected]>2014-10-29 12:38:42 -0700
commit02f8f90cc2261167ea025cbb69f8856c33444007 (patch)
treecc9ccf9916710708c7b1fceee2f970eecbc6635e /src/mesa/drivers/dri/i965/brw_ff_gs.c
parent1480814173f940a1a24c7242e31662e73efb064f (diff)
i965: Rename brw_gs{,_emit}.[ch] to brw_ff_gs{,_emit}.[ch].
The brw_gs.[ch] and brw_gs_emit.c source files contain code for emulating fixed-function unit functionality (VF primitive decomposition or SOL) using the GS unit. They do not contain code to support proper geometry shaders. We've taken to calling that code "ff_gs" (see brw_ff_gs_prog_key, brw_ff_gs_prog_data, brw_context::ff_gs, brw_ff_gs_compile, brw_ff_gs_prog). So it makes sense to make the filenames match. Signed-off-by: Kenneth Graunke <[email protected]> Acked-by: Matt Turner <[email protected]> Acked-by: Jason Ekstrand <[email protected]> Acked-by: Iago Toral Quiroga <[email protected]>
Diffstat (limited to 'src/mesa/drivers/dri/i965/brw_ff_gs.c')
-rw-r--r--src/mesa/drivers/dri/i965/brw_ff_gs.c259
1 files changed, 259 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_ff_gs.c b/src/mesa/drivers/dri/i965/brw_ff_gs.c
new file mode 100644
index 00000000000..6ca9e7f51e9
--- /dev/null
+++ b/src/mesa/drivers/dri/i965/brw_ff_gs.c
@@ -0,0 +1,259 @@
+/*
+ Copyright (C) Intel Corp. 2006. All Rights Reserved.
+ Intel funded Tungsten Graphics to
+ develop this 3D driver.
+
+ 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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.
+
+ **********************************************************************/
+ /*
+ * Authors:
+ * Keith Whitwell <[email protected]>
+ */
+
+#include "main/glheader.h"
+#include "main/macros.h"
+#include "main/enums.h"
+#include "main/transformfeedback.h"
+
+#include "intel_batchbuffer.h"
+
+#include "brw_defines.h"
+#include "brw_context.h"
+#include "brw_eu.h"
+#include "brw_util.h"
+#include "brw_state.h"
+#include "brw_ff_gs.h"
+
+#include "util/ralloc.h"
+
+static void compile_ff_gs_prog(struct brw_context *brw,
+ struct brw_ff_gs_prog_key *key)
+{
+ struct brw_ff_gs_compile c;
+ const GLuint *program;
+ void *mem_ctx;
+ GLuint program_size;
+
+ memset(&c, 0, sizeof(c));
+
+ c.key = *key;
+ c.vue_map = brw->vs.prog_data->base.vue_map;
+ c.nr_regs = (c.vue_map.num_slots + 1)/2;
+
+ mem_ctx = ralloc_context(NULL);
+
+ /* Begin the compilation:
+ */
+ brw_init_compile(brw, &c.func, mem_ctx);
+
+ c.func.single_program_flow = 1;
+
+ /* For some reason the thread is spawned with only 4 channels
+ * unmasked.
+ */
+ brw_set_default_mask_control(&c.func, BRW_MASK_DISABLE);
+
+ if (brw->gen >= 6) {
+ unsigned num_verts;
+ bool check_edge_flag;
+ /* On Sandybridge, we use the GS for implementing transform feedback
+ * (called "Stream Out" in the PRM).
+ */
+ switch (key->primitive) {
+ case _3DPRIM_POINTLIST:
+ num_verts = 1;
+ check_edge_flag = false;
+ break;
+ case _3DPRIM_LINELIST:
+ case _3DPRIM_LINESTRIP:
+ case _3DPRIM_LINELOOP:
+ num_verts = 2;
+ check_edge_flag = false;
+ break;
+ case _3DPRIM_TRILIST:
+ case _3DPRIM_TRIFAN:
+ case _3DPRIM_TRISTRIP:
+ case _3DPRIM_RECTLIST:
+ num_verts = 3;
+ check_edge_flag = false;
+ break;
+ case _3DPRIM_QUADLIST:
+ case _3DPRIM_QUADSTRIP:
+ case _3DPRIM_POLYGON:
+ num_verts = 3;
+ check_edge_flag = true;
+ break;
+ default:
+ unreachable("Unexpected primitive type in Gen6 SOL program.");
+ }
+ gen6_sol_program(&c, key, num_verts, check_edge_flag);
+ } else {
+ /* On Gen4-5, we use the GS to decompose certain types of primitives.
+ * Note that primitives which don't require a GS program have already
+ * been weeded out by now.
+ */
+ switch (key->primitive) {
+ case _3DPRIM_QUADLIST:
+ brw_ff_gs_quads( &c, key );
+ break;
+ case _3DPRIM_QUADSTRIP:
+ brw_ff_gs_quad_strip( &c, key );
+ break;
+ case _3DPRIM_LINELOOP:
+ brw_ff_gs_lines( &c );
+ break;
+ default:
+ ralloc_free(mem_ctx);
+ return;
+ }
+ }
+
+ brw_compact_instructions(&c.func, 0, 0, NULL);
+
+ /* get the program
+ */
+ program = brw_get_program(&c.func, &program_size);
+
+ if (unlikely(INTEL_DEBUG & DEBUG_GS)) {
+ fprintf(stderr, "gs:\n");
+ brw_disassemble(brw, c.func.store, 0, program_size, stderr);
+ fprintf(stderr, "\n");
+ }
+
+ brw_upload_cache(&brw->cache, BRW_FF_GS_PROG,
+ &c.key, sizeof(c.key),
+ program, program_size,
+ &c.prog_data, sizeof(c.prog_data),
+ &brw->ff_gs.prog_offset, &brw->ff_gs.prog_data);
+ ralloc_free(mem_ctx);
+}
+
+static void populate_key(struct brw_context *brw,
+ struct brw_ff_gs_prog_key *key)
+{
+ static const unsigned swizzle_for_offset[4] = {
+ BRW_SWIZZLE4(0, 1, 2, 3),
+ BRW_SWIZZLE4(1, 2, 3, 3),
+ BRW_SWIZZLE4(2, 3, 3, 3),
+ BRW_SWIZZLE4(3, 3, 3, 3)
+ };
+
+ struct gl_context *ctx = &brw->ctx;
+
+ memset(key, 0, sizeof(*key));
+
+ /* CACHE_NEW_VS_PROG (part of VUE map) */
+ key->attrs = brw->vs.prog_data->base.vue_map.slots_valid;
+
+ /* BRW_NEW_PRIMITIVE */
+ key->primitive = brw->primitive;
+
+ /* _NEW_LIGHT */
+ key->pv_first = (ctx->Light.ProvokingVertex == GL_FIRST_VERTEX_CONVENTION);
+ if (key->primitive == _3DPRIM_QUADLIST && ctx->Light.ShadeModel != GL_FLAT) {
+ /* Provide consistent primitive order with brw_set_prim's
+ * optimization of single quads to trifans.
+ */
+ key->pv_first = true;
+ }
+
+ if (brw->gen >= 7) {
+ /* On Gen7 and later, we don't use GS (yet). */
+ key->need_gs_prog = false;
+ } else if (brw->gen == 6) {
+ /* On Gen6, GS is used for transform feedback. */
+ /* BRW_NEW_TRANSFORM_FEEDBACK */
+ if (_mesa_is_xfb_active_and_unpaused(ctx)) {
+ const struct gl_shader_program *shaderprog =
+ ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX];
+ const struct gl_transform_feedback_info *linked_xfb_info =
+ &shaderprog->LinkedTransformFeedback;
+ int i;
+
+ /* Make sure that the VUE slots won't overflow the unsigned chars in
+ * key->transform_feedback_bindings[].
+ */
+ STATIC_ASSERT(BRW_VARYING_SLOT_COUNT <= 256);
+
+ /* Make sure that we don't need more binding table entries than we've
+ * set aside for use in transform feedback. (We shouldn't, since we
+ * set aside enough binding table entries to have one per component).
+ */
+ assert(linked_xfb_info->NumOutputs <= BRW_MAX_SOL_BINDINGS);
+
+ key->need_gs_prog = true;
+ key->num_transform_feedback_bindings = linked_xfb_info->NumOutputs;
+ for (i = 0; i < key->num_transform_feedback_bindings; ++i) {
+ key->transform_feedback_bindings[i] =
+ linked_xfb_info->Outputs[i].OutputRegister;
+ key->transform_feedback_swizzles[i] =
+ swizzle_for_offset[linked_xfb_info->Outputs[i].ComponentOffset];
+ }
+ }
+ } else {
+ /* Pre-gen6, GS is used to transform QUADLIST, QUADSTRIP, and LINELOOP
+ * into simpler primitives.
+ */
+ key->need_gs_prog = (brw->primitive == _3DPRIM_QUADLIST ||
+ brw->primitive == _3DPRIM_QUADSTRIP ||
+ brw->primitive == _3DPRIM_LINELOOP);
+ }
+}
+
+/* Calculate interpolants for triangle and line rasterization.
+ */
+static void
+brw_upload_ff_gs_prog(struct brw_context *brw)
+{
+ struct brw_ff_gs_prog_key key;
+ /* Populate the key:
+ */
+ populate_key(brw, &key);
+
+ if (brw->ff_gs.prog_active != key.need_gs_prog) {
+ brw->state.dirty.cache |= CACHE_NEW_FF_GS_PROG;
+ brw->ff_gs.prog_active = key.need_gs_prog;
+ }
+
+ if (brw->ff_gs.prog_active) {
+ if (!brw_search_cache(&brw->cache, BRW_FF_GS_PROG,
+ &key, sizeof(key),
+ &brw->ff_gs.prog_offset, &brw->ff_gs.prog_data)) {
+ compile_ff_gs_prog( brw, &key );
+ }
+ }
+}
+
+void gen6_brw_upload_ff_gs_prog(struct brw_context *brw)
+{
+ brw_upload_ff_gs_prog(brw);
+}
+
+const struct brw_tracked_state brw_ff_gs_prog = {
+ .dirty = {
+ .mesa = (_NEW_LIGHT),
+ .brw = (BRW_NEW_PRIMITIVE |
+ BRW_NEW_TRANSFORM_FEEDBACK),
+ .cache = CACHE_NEW_VS_PROG
+ },
+ .emit = brw_upload_ff_gs_prog
+};