diff options
author | Kenneth Graunke <[email protected]> | 2014-10-28 17:18:55 -0700 |
---|---|---|
committer | Kenneth Graunke <[email protected]> | 2014-10-29 12:38:42 -0700 |
commit | 02f8f90cc2261167ea025cbb69f8856c33444007 (patch) | |
tree | cc9ccf9916710708c7b1fceee2f970eecbc6635e /src/mesa/drivers/dri/i965/brw_ff_gs.c | |
parent | 1480814173f940a1a24c7242e31662e73efb064f (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.c | 259 |
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 +}; |