i965: Move clip program compilation to the compiler

Reviewed-by: Topi Pohjolainen <topi.pohjolainen@intel.com>
This commit is contained in:
Jason Ekstrand 2017-03-18 12:02:45 -07:00
parent 9fb8a8775b
commit 18e18a1863
13 changed files with 211 additions and 181 deletions

View File

@ -23,6 +23,13 @@ DECODER_FILES = \
COMPILER_FILES = \
compiler/brw_cfg.cpp \
compiler/brw_cfg.h \
compiler/brw_clip.h \
compiler/brw_clip_line.c \
compiler/brw_clip_point.c \
compiler/brw_clip_tri.c \
compiler/brw_clip_unfilled.c \
compiler/brw_clip_util.c \
compiler/brw_compile_clip.c \
compiler/brw_compile_sf.c \
compiler/brw_compiler.c \
compiler/brw_compiler.h \

View File

@ -32,9 +32,8 @@
#ifndef BRW_CLIP_H
#define BRW_CLIP_H
#include "brw_context.h"
#include "compiler/brw_eu.h"
#include "brw_compiler.h"
#include "brw_eu.h"
/* Initial 3 verts, plus at most 6 additional verts from intersections
* with fixed planes, plus at most 8 additional verts from intersections
@ -42,38 +41,6 @@
*/
#define MAX_VERTS (3+6+8)
/* Note that if unfilled primitives are being emitted, we have to fix
* up polygon offset and flatshading at this point:
*/
struct brw_clip_prog_key {
GLbitfield64 attrs;
bool contains_flat_varying;
bool contains_noperspective_varying;
unsigned char interp_mode[65]; /* BRW_VARYING_SLOT_COUNT */
GLuint primitive:4;
GLuint nr_userclip:4;
GLuint pv_first:1;
GLuint do_unfilled:1;
GLuint fill_cw:2; /* includes cull information */
GLuint fill_ccw:2; /* includes cull information */
GLuint offset_cw:1;
GLuint offset_ccw:1;
GLuint copy_bfc_cw:1;
GLuint copy_bfc_ccw:1;
GLuint clip_mode:3;
GLfloat offset_factor;
GLfloat offset_units;
GLfloat offset_clamp;
};
#define CLIP_LINE 0
#define CLIP_POINT 1
#define CLIP_FILL 2
#define CLIP_CULL 3
#define PRIM_MASK (0x1f)
struct brw_clip_compile {
@ -192,4 +159,5 @@ void brw_clip_project_position(struct brw_clip_compile *c,
struct brw_reg pos );
void brw_clip_ff_sync(struct brw_clip_compile *c);
void brw_clip_init_ff_sync(struct brw_clip_compile *c);
#endif

View File

@ -33,14 +33,8 @@
#include "main/enums.h"
#include "program/program.h"
#include "intel_batchbuffer.h"
#include "brw_defines.h"
#include "brw_context.h"
#include "brw_clip.h"
static void brw_clip_line_alloc_regs( struct brw_clip_compile *c )
{
const struct gen_device_info *devinfo = c->func.devinfo;

View File

@ -33,10 +33,6 @@
#include "main/enums.h"
#include "program/program.h"
#include "intel_batchbuffer.h"
#include "brw_defines.h"
#include "brw_context.h"
#include "brw_clip.h"

View File

@ -33,10 +33,6 @@
#include "main/enums.h"
#include "program/program.h"
#include "intel_batchbuffer.h"
#include "brw_defines.h"
#include "brw_context.h"
#include "brw_clip.h"
static void release_tmps( struct brw_clip_compile *c )
@ -652,8 +648,8 @@ void brw_emit_tri_clip( struct brw_clip_compile *c )
if (c->key.contains_flat_varying)
brw_clip_tri_flat_shade(c);
if ((c->key.clip_mode == BRW_CLIPMODE_NORMAL) ||
(c->key.clip_mode == BRW_CLIPMODE_KERNEL_CLIP))
if ((c->key.clip_mode == BRW_CLIP_MODE_NORMAL) ||
(c->key.clip_mode == BRW_CLIP_MODE_KERNEL_CLIP))
do_clip_tri(c);
else
maybe_do_clip_tri(c);

View File

@ -33,14 +33,9 @@
#include "main/enums.h"
#include "program/program.h"
#include "intel_batchbuffer.h"
#include "brw_defines.h"
#include "brw_context.h"
#include "brw_clip.h"
/* This is performed against the original triangles, so no indirection
* required:
BZZZT!
@ -99,10 +94,10 @@ static void cull_direction( struct brw_clip_compile *c )
struct brw_codegen *p = &c->func;
GLuint conditional;
assert (!(c->key.fill_ccw == CLIP_CULL &&
c->key.fill_cw == CLIP_CULL));
assert (!(c->key.fill_ccw == BRW_CLIP_FILL_MODE_CULL &&
c->key.fill_cw == BRW_CLIP_FILL_MODE_CULL));
if (c->key.fill_ccw == CLIP_CULL)
if (c->key.fill_ccw == BRW_CLIP_FILL_MODE_CULL)
conditional = BRW_CONDITIONAL_GE;
else
conditional = BRW_CONDITIONAL_L;
@ -405,19 +400,19 @@ static void emit_primitives( struct brw_clip_compile *c,
bool do_offset )
{
switch (mode) {
case CLIP_FILL:
case BRW_CLIP_FILL_MODE_FILL:
brw_clip_tri_emit_polygon(c);
break;
case CLIP_LINE:
case BRW_CLIP_FILL_MODE_LINE:
emit_lines(c, do_offset);
break;
case CLIP_POINT:
case BRW_CLIP_FILL_MODE_POINT:
emit_points(c, do_offset);
break;
case CLIP_CULL:
case BRW_CLIP_FILL_MODE_CULL:
unreachable("not reached");
}
}
@ -431,8 +426,8 @@ static void emit_unfilled_primitives( struct brw_clip_compile *c )
/* Direction culling has already been done.
*/
if (c->key.fill_ccw != c->key.fill_cw &&
c->key.fill_ccw != CLIP_CULL &&
c->key.fill_cw != CLIP_CULL)
c->key.fill_ccw != BRW_CLIP_FILL_MODE_CULL &&
c->key.fill_cw != BRW_CLIP_FILL_MODE_CULL)
{
brw_CMP(p,
vec1(brw_null_reg()),
@ -450,10 +445,10 @@ static void emit_unfilled_primitives( struct brw_clip_compile *c )
}
brw_ENDIF(p);
}
else if (c->key.fill_cw != CLIP_CULL) {
else if (c->key.fill_cw != BRW_CLIP_FILL_MODE_CULL) {
emit_primitives(c, c->key.fill_cw, c->key.offset_cw);
}
else if (c->key.fill_ccw != CLIP_CULL) {
else if (c->key.fill_ccw != BRW_CLIP_FILL_MODE_CULL) {
emit_primitives(c, c->key.fill_ccw, c->key.offset_ccw);
}
}
@ -480,8 +475,8 @@ void brw_emit_unfilled_clip( struct brw_clip_compile *c )
c->need_direction = ((c->key.offset_ccw || c->key.offset_cw) ||
(c->key.fill_ccw != c->key.fill_cw) ||
c->key.fill_ccw == CLIP_CULL ||
c->key.fill_cw == CLIP_CULL ||
c->key.fill_ccw == BRW_CLIP_FILL_MODE_CULL ||
c->key.fill_cw == BRW_CLIP_FILL_MODE_CULL ||
c->key.copy_bfc_cw ||
c->key.copy_bfc_ccw);
@ -491,8 +486,8 @@ void brw_emit_unfilled_clip( struct brw_clip_compile *c )
assert(brw_clip_have_varying(c, VARYING_SLOT_EDGE));
if (c->key.fill_ccw == CLIP_CULL &&
c->key.fill_cw == CLIP_CULL) {
if (c->key.fill_ccw == BRW_CLIP_FILL_MODE_CULL &&
c->key.fill_cw == BRW_CLIP_FILL_MODE_CULL) {
brw_clip_kill_thread(c);
return;
}
@ -504,8 +499,8 @@ void brw_emit_unfilled_clip( struct brw_clip_compile *c )
if (c->need_direction)
compute_tri_direction(c);
if (c->key.fill_ccw == CLIP_CULL ||
c->key.fill_cw == CLIP_CULL)
if (c->key.fill_ccw == BRW_CLIP_FILL_MODE_CULL ||
c->key.fill_cw == BRW_CLIP_FILL_MODE_CULL)
cull_direction(c);
if (c->key.offset_ccw ||

View File

@ -34,15 +34,9 @@
#include "main/enums.h"
#include "program/program.h"
#include "intel_batchbuffer.h"
#include "brw_defines.h"
#include "brw_context.h"
#include "brw_clip.h"
struct brw_reg get_tmp( struct brw_clip_compile *c )
{
struct brw_reg tmp = brw_vec4_grf(c->last_tmp, 0);

View File

@ -0,0 +1,96 @@
/*
* Copyright © 2006 - 2017 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.
*/
#include "brw_clip.h"
#include "common/gen_debug.h"
const unsigned *
brw_compile_clip(const struct brw_compiler *compiler,
void *mem_ctx,
const struct brw_clip_prog_key *key,
struct brw_clip_prog_data *prog_data,
struct brw_vue_map *vue_map,
unsigned *final_assembly_size)
{
struct brw_clip_compile c;
memset(&c, 0, sizeof(c));
/* Begin the compilation:
*/
brw_init_codegen(compiler->devinfo, &c.func, mem_ctx);
c.func.single_program_flow = 1;
c.key = *key;
c.vue_map = *vue_map;
/* nr_regs is the number of registers filled by reading data from the VUE.
* This program accesses the entire VUE, so nr_regs needs to be the size of
* the VUE (measured in pairs, since two slots are stored in each
* register).
*/
c.nr_regs = (c.vue_map.num_slots + 1)/2;
c.prog_data.clip_mode = c.key.clip_mode; /* XXX */
/* For some reason the thread is spawned with only 4 channels
* unmasked.
*/
brw_set_default_mask_control(&c.func, BRW_MASK_DISABLE);
/* Would ideally have the option of producing a program which could
* do all three:
*/
switch (key->primitive) {
case GL_TRIANGLES:
if (key->do_unfilled)
brw_emit_unfilled_clip( &c );
else
brw_emit_tri_clip( &c );
break;
case GL_LINES:
brw_emit_line_clip( &c );
break;
case GL_POINTS:
brw_emit_point_clip( &c );
break;
default:
unreachable("not reached");
}
brw_compact_instructions(&c.func, 0, 0, NULL);
*prog_data = c.prog_data;
const unsigned *program = brw_get_program(&c.func, final_assembly_size);
if (unlikely(INTEL_DEBUG & DEBUG_CLIP)) {
fprintf(stderr, "clip:\n");
brw_disassemble(compiler->devinfo,
program, 0, *final_assembly_size, stderr);
fprintf(stderr, "\n");
}
return program;
}

View File

@ -281,6 +281,47 @@ struct brw_sf_prog_key {
bool userclip_active:1;
};
enum brw_clip_mode {
BRW_CLIP_MODE_NORMAL = 0,
BRW_CLIP_MODE_CLIP_ALL = 1,
BRW_CLIP_MODE_CLIP_NON_REJECTED = 2,
BRW_CLIP_MODE_REJECT_ALL = 3,
BRW_CLIP_MODE_ACCEPT_ALL = 4,
BRW_CLIP_MODE_KERNEL_CLIP = 5,
};
enum brw_clip_fill_mode {
BRW_CLIP_FILL_MODE_LINE = 0,
BRW_CLIP_FILL_MODE_POINT = 1,
BRW_CLIP_FILL_MODE_FILL = 2,
BRW_CLIP_FILL_MODE_CULL = 3,
};
/* Note that if unfilled primitives are being emitted, we have to fix
* up polygon offset and flatshading at this point:
*/
struct brw_clip_prog_key {
uint64_t attrs;
bool contains_flat_varying;
bool contains_noperspective_varying;
unsigned char interp_mode[65]; /* BRW_VARYING_SLOT_COUNT */
unsigned primitive:4;
unsigned nr_userclip:4;
bool pv_first:1;
bool do_unfilled:1;
enum brw_clip_fill_mode fill_cw:2; /* includes cull information */
enum brw_clip_fill_mode fill_ccw:2; /* includes cull information */
bool offset_cw:1;
bool offset_ccw:1;
bool copy_bfc_cw:1;
bool copy_bfc_ccw:1;
enum brw_clip_mode clip_mode:3;
float offset_factor;
float offset_units;
float offset_clamp;
};
/* A big lookup table is used to figure out which and how many
* additional regs will inserted before the main payload in the WM
* program execution. These mainly relate to depth and stencil
@ -905,6 +946,13 @@ struct brw_sf_prog_data {
unsigned urb_entry_size;
};
struct brw_clip_prog_data {
uint32_t curb_read_length; /* user planes? */
uint32_t clip_mode;
uint32_t urb_read_length;
uint32_t total_grf;
};
#define DEFINE_PROG_DATA_DOWNCAST(stage) \
static inline struct brw_##stage##_prog_data * \
brw_##stage##_prog_data(struct brw_stage_prog_data *prog_data) \
@ -1010,6 +1058,22 @@ brw_compile_sf(const struct brw_compiler *compiler,
struct brw_vue_map *vue_map,
unsigned *final_assembly_size);
/**
* Compile a clipper shader.
*
* This is a fixed-function shader determined entirely by the shader key and
* a VUE map.
*
* Returns the final assembly and the program's size.
*/
const unsigned *
brw_compile_clip(const struct brw_compiler *compiler,
void *mem_ctx,
const struct brw_clip_prog_key *key,
struct brw_clip_prog_data *prog_data,
struct brw_vue_map *vue_map,
unsigned *final_assembly_size);
/**
* Compile a fragment shader.
*

View File

@ -7,13 +7,7 @@ i965_FILES = \
brw_cc.c \
brw_clear.c \
brw_clip.c \
brw_clip.h \
brw_clip_line.c \
brw_clip_point.c \
brw_clip_state.c \
brw_clip_tri.c \
brw_clip_unfilled.c \
brw_clip_util.c \
brw_compute.c \
brw_conditional_render.c \
brw_context.c \

View File

@ -38,88 +38,28 @@
#include "brw_context.h"
#include "brw_util.h"
#include "brw_state.h"
#include "brw_clip.h"
#include "compiler/brw_eu.h"
#include "util/ralloc.h"
#define FRONT_UNFILLED_BIT 0x1
#define BACK_UNFILLED_BIT 0x2
static void compile_clip_prog( struct brw_context *brw,
struct brw_clip_prog_key *key )
{
struct brw_clip_compile c;
const GLuint *program;
const unsigned *program;
void *mem_ctx;
GLuint program_size;
memset(&c, 0, sizeof(c));
unsigned program_size;
mem_ctx = ralloc_context(NULL);
/* Begin the compilation:
*/
brw_init_codegen(&brw->screen->devinfo, &c.func, mem_ctx);
c.func.single_program_flow = 1;
c.key = *key;
c.vue_map = brw->vue_map_geom_out;
/* nr_regs is the number of registers filled by reading data from the VUE.
* This program accesses the entire VUE, so nr_regs needs to be the size of
* the VUE (measured in pairs, since two slots are stored in each
* register).
*/
c.nr_regs = (c.vue_map.num_slots + 1)/2;
c.prog_data.clip_mode = c.key.clip_mode; /* XXX */
/* For some reason the thread is spawned with only 4 channels
* unmasked.
*/
brw_set_default_mask_control(&c.func, BRW_MASK_DISABLE);
/* Would ideally have the option of producing a program which could
* do all three:
*/
switch (key->primitive) {
case GL_TRIANGLES:
if (key->do_unfilled)
brw_emit_unfilled_clip( &c );
else
brw_emit_tri_clip( &c );
break;
case GL_LINES:
brw_emit_line_clip( &c );
break;
case GL_POINTS:
brw_emit_point_clip( &c );
break;
default:
unreachable("not reached");
}
brw_compact_instructions(&c.func, 0, 0, NULL);
/* get the program
*/
program = brw_get_program(&c.func, &program_size);
if (unlikely(INTEL_DEBUG & DEBUG_CLIP)) {
fprintf(stderr, "clip:\n");
brw_disassemble(&brw->screen->devinfo, c.func.store,
0, program_size, stderr);
fprintf(stderr, "\n");
}
struct brw_clip_prog_data prog_data;
program = brw_compile_clip(brw->screen->compiler, mem_ctx, key, &prog_data,
&brw->vue_map_geom_out, &program_size);
brw_upload_cache(&brw->cache,
BRW_CACHE_CLIP_PROG,
&c.key, sizeof(c.key),
key, sizeof(*key),
program, program_size,
&c.prog_data, sizeof(c.prog_data),
&prog_data, sizeof(prog_data),
&brw->clip.prog_offset, &brw->clip.prog_data);
ralloc_free(mem_ctx);
}
@ -174,18 +114,18 @@ brw_upload_clip_prog(struct brw_context *brw)
key.nr_userclip = _mesa_logbase2(ctx->Transform.ClipPlanesEnabled) + 1;
if (brw->gen == 5)
key.clip_mode = BRW_CLIPMODE_KERNEL_CLIP;
key.clip_mode = BRW_CLIP_MODE_KERNEL_CLIP;
else
key.clip_mode = BRW_CLIPMODE_NORMAL;
key.clip_mode = BRW_CLIP_MODE_NORMAL;
/* _NEW_POLYGON */
if (key.primitive == GL_TRIANGLES) {
if (ctx->Polygon.CullFlag &&
ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK)
key.clip_mode = BRW_CLIPMODE_REJECT_ALL;
key.clip_mode = BRW_CLIP_MODE_REJECT_ALL;
else {
GLuint fill_front = CLIP_CULL;
GLuint fill_back = CLIP_CULL;
GLuint fill_front = BRW_CLIP_FILL_MODE_CULL;
GLuint fill_back = BRW_CLIP_FILL_MODE_CULL;
GLuint offset_front = 0;
GLuint offset_back = 0;
@ -193,15 +133,15 @@ brw_upload_clip_prog(struct brw_context *brw)
ctx->Polygon.CullFaceMode != GL_FRONT) {
switch (ctx->Polygon.FrontMode) {
case GL_FILL:
fill_front = CLIP_FILL;
fill_front = BRW_CLIP_FILL_MODE_FILL;
offset_front = 0;
break;
case GL_LINE:
fill_front = CLIP_LINE;
fill_front = BRW_CLIP_FILL_MODE_LINE;
offset_front = ctx->Polygon.OffsetLine;
break;
case GL_POINT:
fill_front = CLIP_POINT;
fill_front = BRW_CLIP_FILL_MODE_POINT;
offset_front = ctx->Polygon.OffsetPoint;
break;
}
@ -211,15 +151,15 @@ brw_upload_clip_prog(struct brw_context *brw)
ctx->Polygon.CullFaceMode != GL_BACK) {
switch (ctx->Polygon.BackMode) {
case GL_FILL:
fill_back = CLIP_FILL;
fill_back = BRW_CLIP_FILL_MODE_FILL;
offset_back = 0;
break;
case GL_LINE:
fill_back = CLIP_LINE;
fill_back = BRW_CLIP_FILL_MODE_LINE;
offset_back = ctx->Polygon.OffsetLine;
break;
case GL_POINT:
fill_back = CLIP_POINT;
fill_back = BRW_CLIP_FILL_MODE_POINT;
offset_back = ctx->Polygon.OffsetPoint;
break;
}
@ -232,7 +172,7 @@ brw_upload_clip_prog(struct brw_context *brw)
/* Most cases the fixed function units will handle. Cases where
* one or more polygon faces are unfilled will require help:
*/
key.clip_mode = BRW_CLIPMODE_CLIP_NON_REJECTED;
key.clip_mode = BRW_CLIP_MODE_CLIP_NON_REJECTED;
if (offset_back || offset_front) {
/* _NEW_POLYGON, _NEW_BUFFERS */
@ -247,7 +187,7 @@ brw_upload_clip_prog(struct brw_context *brw)
key.offset_ccw = offset_front;
key.offset_cw = offset_back;
if (ctx->Light.Model.TwoSide &&
key.fill_cw != CLIP_CULL)
key.fill_cw != BRW_CLIP_FILL_MODE_CULL)
key.copy_bfc_cw = 1;
} else {
key.fill_cw = fill_front;
@ -255,7 +195,7 @@ brw_upload_clip_prog(struct brw_context *brw)
key.offset_cw = offset_front;
key.offset_ccw = offset_back;
if (ctx->Light.Model.TwoSide &&
key.fill_ccw != CLIP_CULL)
key.fill_ccw != BRW_CLIP_FILL_MODE_CULL)
key.copy_bfc_ccw = 1;
}
}

View File

@ -325,13 +325,6 @@ struct brw_program {
};
struct brw_clip_prog_data {
GLuint curb_read_length; /* user planes? */
GLuint clip_mode;
GLuint urb_read_length;
GLuint total_grf;
};
struct brw_ff_gs_prog_data {
GLuint urb_read_length;
GLuint total_grf;

View File

@ -109,13 +109,6 @@
#define BRW_CLIP_API_OGL 0
#define BRW_CLIP_API_DX 1
#define BRW_CLIPMODE_NORMAL 0
#define BRW_CLIPMODE_CLIP_ALL 1
#define BRW_CLIPMODE_CLIP_NON_REJECTED 2
#define BRW_CLIPMODE_REJECT_ALL 3
#define BRW_CLIPMODE_ACCEPT_ALL 4
#define BRW_CLIPMODE_KERNEL_CLIP 5
#define BRW_CLIP_NDCSPACE 0
#define BRW_CLIP_SCREENSPACE 1