Merge branch 'upstream-gallium-0.1' into darktama-gallium-0.1

This commit is contained in:
Ben Skeggs
2007-12-15 09:48:11 +11:00
62 changed files with 2313 additions and 3917 deletions
+3 -3
View File
@@ -90,7 +90,9 @@ static void Init( void )
}
fprintf(stderr, "%.*s\n", sz, buf);
glEnable(GL_VERTEX_PROGRAM_NV);
glGenProgramsARB(1, &prognum);
glBindProgramARB(GL_VERTEX_PROGRAM_ARB, prognum);
@@ -168,8 +170,6 @@ static void Display( void )
glClearColor(0.3, 0.3, 0.3, 1);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glEnable(GL_VERTEX_PROGRAM_NV);
glBegin(GL_TRIANGLES);
+7 -1
View File
@@ -936,10 +936,16 @@ static void load_texture( struct texenv_fragment_program *p, GLuint unit )
/* TODO: Use D0_MASK_XY where possible.
*/
if (p->state->unit[unit].enabled)
if (p->state->unit[unit].enabled) {
p->src_texture[unit] = emit_texld( p, OPCODE_TXP,
tmp, WRITEMASK_XYZW,
unit, dim, texcoord );
p->program->Base.SamplersUsed |= (1 << unit);
/* This identity mapping should already be in place
* (see _mesa_init_program_struct()) but let's be safe.
*/
p->program->Base.SamplerUnits[unit] = unit;
}
else
p->src_texture[unit] = get_zero(p);
}
@@ -928,8 +928,9 @@ i915_translate_instructions(struct i915_fp_compile *p,
break;
case TGSI_TOKEN_TYPE_IMMEDIATE:
/* XXX no-op? */
assert(0);
/* This is a no-op. We'll get immediates from the usual constant/
* uniform buffer.
*/
break;
case TGSI_TOKEN_TYPE_INSTRUCTION:
-4
View File
@@ -47,10 +47,6 @@ static unsigned minify( unsigned d )
return MAX2(1, d>>1);
}
static int align(int value, int alignment)
{
return (value + alignment - 1) & ~(alignment - 1);
}
static void
+2 -2
View File
@@ -31,6 +31,7 @@ DRIVER_SOURCES = \
brw_sf.c \
brw_sf_emit.c \
brw_sf_state.c \
brw_shader_info.c \
brw_state.c \
brw_state_batch.c \
brw_state_cache.c \
@@ -40,12 +41,11 @@ DRIVER_SOURCES = \
brw_urb.c \
brw_util.c \
brw_vs.c \
brw_vs_constval.c \
brw_vs_emit.c \
brw_vs_state.c \
brw_vtbl.c \
brw_wm.c \
brw_wm_iz.c \
brw_wm_decl.c \
brw_wm_glsl.c \
brw_wm_sampler_state.c \
brw_wm_state.c \
+1 -2
View File
@@ -36,7 +36,7 @@
#define INTEL_BATCH_CLIPRECTS 0x2
#define BEGIN_BATCH( dwords, relocs ) \
(brw->batch_start = brw->winsys->batch_start(brw->winsys, dwords, relocs))
brw->winsys->batch_start(brw->winsys, dwords, relocs)
#define OUT_BATCH( dword ) \
brw->winsys->batch_dword(brw->winsys, dword)
@@ -50,7 +50,6 @@
*/
#define FLUSH_BATCH(fence) do { \
brw->winsys->batch_flush(brw->winsys, fence); \
brw->batch_start = NULL; \
brw->hardware_dirty = ~0; \
} while (0)
+1 -1
View File
@@ -142,7 +142,7 @@ static void upload_cc_vp( struct brw_context *brw )
const struct brw_tracked_state brw_cc_vp = {
.dirty = {
.brw = BRW_NEW_CONTEXT,
.brw = BRW_NEW_SCENE,
.cache = 0
},
.update = upload_cc_vp
+2 -2
View File
@@ -32,7 +32,7 @@
#include "brw_context.h"
#include "brw_state.h"
#include "brw_defines.h"
#include "pipe/p_util.h"
static void upload_clip_unit( struct brw_context *brw )
@@ -43,7 +43,7 @@ static void upload_clip_unit( struct brw_context *brw )
/* CACHE_NEW_CLIP_PROG */
clip.thread0.grf_reg_count =
ALIGN(brw->clip.prog_data->total_grf, 16) / 16 - 1;
align(brw->clip.prog_data->total_grf, 16) / 16 - 1;
clip.thread0.kernel_start_pointer = brw->clip.prog_gs_offset >> 6;
clip.thread3.urb_entry_read_length = brw->clip.prog_data->urb_read_length;
clip.thread3.const_urb_entry_read_length = brw->clip.prog_data->curb_read_length;
-1
View File
@@ -237,7 +237,6 @@ struct pipe_context *brw_create(struct pipe_winsys *pipe_winsys,
brw->pci_id = pci_id;
brw->dirty = ~0;
brw->hardware_dirty = ~0;
brw->batch_start = NULL;
memset(&brw->wm.bind, ~0, sizeof(brw->wm.bind));
+50 -51
View File
@@ -119,7 +119,6 @@
* Handles blending and (presumably) depth and stencil testing.
*/
#define BRW_FALLBACK_TEXTURE 0x1
#define BRW_MAX_CURBE (32*16)
struct brw_context;
@@ -147,16 +146,13 @@ struct brw_winsys;
/* Raised for other internal events:
*/
#define BRW_NEW_URB_FENCE 0x10000
#define BRW_NEW_INPUT_DIMENSIONS 0x20000
#define BRW_NEW_PSP 0x20000
#define BRW_NEW_CURBE_OFFSETS 0x40000
#define BRW_NEW_REDUCED_PRIMITIVE 0x80000
#define BRW_NEW_PRIMITIVE 0x100000
#define BRW_NEW_CONTEXT 0x200000
#define BRW_NEW_WM_INPUT_DIMENSIONS 0x400000
#define BRW_NEW_INPUT_VARYING 0x800000
#define BRW_NEW_PSP 0x1000000
#define BRW_NEW_SCENE 0x200000
#define BRW_NEW_SF_LINKAGE 0x400000
#define ALIGN(value, alignment) ((value + alignment - 1) & ~(alignment - 1))
extern int BRW_DEBUG;
#define DEBUG_TEXTURE 0x1
@@ -198,23 +194,47 @@ struct brw_state_flags {
unsigned brw;
};
struct brw_shader_info {
int nr_regs[8]; /* TGSI_FILE_* */
};
struct brw_vertex_program {
struct pipe_shader_state program;
unsigned id;
unsigned param_state; /* flags indicating state tracked by params */
struct brw_shader_info info;
int id;
};
struct brw_fragment_program {
struct pipe_shader_state program;
unsigned id;
unsigned param_state; /* flags indicating state tracked by params */
struct brw_shader_info info;
boolean UsesDepth;
boolean UsesKill;
boolean ComputesDepth;
int id;
};
struct pipe_setup_linkage {
struct {
unsigned vp_output:5;
unsigned interp_mode:4;
unsigned bf_vp_output:5;
} fp_input[PIPE_MAX_SHADER_INPUTS];
unsigned fp_input_count:5;
unsigned max_vp_output:5;
};
struct brw_texture {
struct pipe_texture base;
@@ -248,6 +268,12 @@ struct brw_texture {
* corresponding to a different brw_wm_prog_key struct, with different
* compiled programs:
*/
/* Data about a particular attempt to compile a program. Note that
* there can be many of these, each in a different GL state
* corresponding to a different brw_wm_prog_key struct, with different
* compiled programs:
*/
struct brw_wm_prog_data {
unsigned curb_read_length;
unsigned urb_read_length;
@@ -256,13 +282,14 @@ struct brw_wm_prog_data {
unsigned total_grf;
unsigned total_scratch;
unsigned nr_params;
boolean error;
/* Pointer to tracked values (only valid once
* _mesa_load_state_parameters has been called at runtime).
/* Internally generated constants for the CURBE. These are loaded
* ahead of the data from the constant buffer.
*/
const float *param[BRW_MAX_CURBE];
const float internal_const[8];
unsigned nr_internal_consts;
unsigned max_const;
boolean error;
};
struct brw_sf_prog_data {
@@ -298,19 +325,14 @@ struct brw_vs_prog_data {
unsigned inputs_read;
unsigned max_const;
/* Used for calculating urb partitions:
*/
unsigned urb_entry_size;
};
/* Size == 0 if output either not written, or always [0,0,0,1]
*/
struct brw_vs_ouput_sizes {
ubyte output_size[PIPE_MAX_SHADER_OUTPUTS];
};
#define BRW_MAX_TEX_UNIT 8
#define BRW_WM_MAX_SURF BRW_MAX_TEX_UNIT + 1
@@ -374,8 +396,6 @@ struct brw_cache {
struct brw_tracked_state {
struct brw_state_flags dirty;
void (*update)( struct brw_context *brw );
void (*emit_reloc)( struct brw_context *brw );
boolean always_update;
};
@@ -455,8 +475,6 @@ struct brw_context
struct {
struct brw_state_flags dirty;
struct brw_tracked_state **atoms;
unsigned nr_atoms;
} state;
@@ -489,34 +507,23 @@ struct brw_context
/* Arrays with buffer objects to copy non-bufferobj arrays into
* for upload:
*/
struct pipe_vertex_buffer vbo_array[PIPE_ATTRIB_MAX];
struct pipe_vertex_buffer *vbo_array[PIPE_ATTRIB_MAX];
struct brw_vertex_element inputs[PIPE_ATTRIB_MAX];
#define BRW_NR_UPLOAD_BUFS 17
#define BRW_UPLOAD_INIT_SIZE (128*1024)
struct {
struct pipe_buffer_handle *vbo[BRW_NR_UPLOAD_BUFS];
unsigned buf;
unsigned offset;
unsigned size;
unsigned wrap;
} upload;
/* Summary of size and varying of active arrays, so we can check
* for changes to this state:
*/
struct brw_vertex_info info;
int last_vb;
} vb;
unsigned *batch_start;
unsigned hardware_dirty;
unsigned dirty;
unsigned pci_id;
/* BRW_NEW_URB_ALLOCATIONS:
*/
struct {
@@ -557,11 +564,6 @@ struct brw_context
unsigned vs_size;
unsigned total_size;
/* Dynamic tracker which changes to reflect the state referenced
* by active fp and vp program parameters:
*/
struct brw_tracked_state tracked_state;
unsigned gs_offset;
float *last_buf;
@@ -595,6 +597,8 @@ struct brw_context
struct {
struct brw_sf_prog_data *prog_data;
struct pipe_setup_linkage linkage;
unsigned prog_gs_offset;
unsigned vp_gs_offset;
unsigned state_gs_offset;
@@ -602,11 +606,8 @@ struct brw_context
struct {
struct brw_wm_prog_data *prog_data;
struct brw_wm_compile *compile_data;
/* Input sizes, calculated from active vertex program:
*/
unsigned input_size_masks[4];
// struct brw_wm_compiler *compile_data;
/**
@@ -667,8 +668,6 @@ void brw_destroy_state(struct brw_context *brw);
* brw_tex.c
*/
void brwUpdateTextureState( struct brw_context *brw );
void brw_FrameBufferTexInit( struct brw_context *brw );
void brw_FrameBufferTexDestroy( struct brw_context *brw );
/* brw_urb.c
+35 -44
View File
@@ -35,6 +35,9 @@
#include "brw_defines.h"
#include "brw_state.h"
#include "brw_util.h"
#include "brw_wm.h"
#include "pipe/p_state.h"
#include "pipe/p_util.h"
#define FILE_DEBUG_FLAG DEBUG_FALLBACKS
@@ -43,11 +46,10 @@
static void calculate_curbe_offsets( struct brw_context *brw )
{
/* CACHE_NEW_WM_PROG */
unsigned nr_fp_regs = (brw->wm.prog_data->nr_params + 15) / 16;
unsigned nr_fp_regs = align(brw->wm.prog_data->max_const, 16);
/* BRW_NEW_VERTEX_PROGRAM */
struct brw_vertex_program *vp = (struct brw_vertex_program *)brw->attribs.VertexProgram;
unsigned nr_vp_regs = (vp->program.num_inputs * 4 + 15) / 16;
unsigned nr_vp_regs = align(brw->vs.prog_data->max_const, 16);
unsigned nr_clip_regs = 0;
unsigned total_regs;
@@ -55,7 +57,7 @@ static void calculate_curbe_offsets( struct brw_context *brw )
/* BRW_NEW_CLIP ? */
if (brw->attribs.Transform->ClipPlanesEnabled) {
unsigned nr_planes = 6 + brw_count_bits(brw->attribs.Transform->ClipPlanesEnabled);
nr_clip_regs = (nr_planes * 4 + 15) / 16;
nr_clip_regs = align(nr_planes * 4, 16);
}
#endif
@@ -172,28 +174,18 @@ static float fixed_plane[6][4] = {
{ 1, 0, 0, 1 }
};
#if 0
/* Upload a new set of constants. Too much variability to go into the
* cache mechanism, but maybe would benefit from a comparison against
* the current uploaded set of constants.
*/
static void upload_constant_buffer(struct brw_context *brw)
{
GLcontext *ctx = &brw->intel.ctx;
struct brw_vertex_program *vp = (struct brw_vertex_program *)brw->vertex_program;
struct brw_fragment_program *fp = (struct brw_fragment_program *)brw->fragment_program;
struct brw_mem_pool *pool = &brw->pool[BRW_GS_POOL];
unsigned sz = brw->curbe.total_size;
unsigned bufsz = sz * 16 * sizeof(float);
float *buf;
unsigned i;
/* Update our own dependency flags. This works because this
* function will also be called whenever fp or vp changes.
*/
brw->curbe.tracked_state.dirty.mesa = (_NEW_TRANSFORM|_NEW_PROJECTION);
brw->curbe.tracked_state.dirty.mesa |= vp->param_state;
brw->curbe.tracked_state.dirty.mesa |= fp->param_state;
if (sz == 0) {
struct brw_constant_buffer cb;
@@ -220,10 +212,16 @@ static void upload_constant_buffer(struct brw_context *brw)
if (brw->curbe.wm_size) {
unsigned offset = brw->curbe.wm_start * 16;
_mesa_load_state_parameters(ctx, fp->program.Base.Parameters);
/* First the constant buffer constants:
*/
/* Then any internally generated constants:
*/
for (i = 0; i < brw->wm.prog_data->nr_internal_consts; i++)
buf[offset + i] = brw->wm.prog_data->internal_const[i];
for (i = 0; i < brw->wm.prog_data->nr_params; i++)
buf[offset + i] = brw->wm.prog_data->param[i][0];
assert(brw->wm.prog_data->max_const ==
brw->wm.prog_data->nr_internal_consts);
}
@@ -243,34 +241,26 @@ static void upload_constant_buffer(struct brw_context *brw)
buf[offset + i * 4 + 3] = fixed_plane[i][3];
}
/* Clip planes: _NEW_TRANSFORM plus _NEW_PROJECTION to get to
* clip-space:
/* Clip planes: BRW_NEW_CLIP:
*/
assert(MAX_CLIP_PLANES == 6);
for (j = 0; j < MAX_CLIP_PLANES; j++) {
if (brw->attribs.Transform->ClipPlanesEnabled & (1<<j)) {
buf[offset + i * 4 + 0] = brw->attribs.Transform->_ClipUserPlane[j][0];
buf[offset + i * 4 + 1] = brw->attribs.Transform->_ClipUserPlane[j][1];
buf[offset + i * 4 + 2] = brw->attribs.Transform->_ClipUserPlane[j][2];
buf[offset + i * 4 + 3] = brw->attribs.Transform->_ClipUserPlane[j][3];
i++;
}
for (j = 0; j < brw->attribs.Clip.nr; j++) {
buf[offset + i * 4 + 0] = brw->attribs.Clip.ucp[j][0];
buf[offset + i * 4 + 1] = brw->attribs.Clip.ucp[j][1];
buf[offset + i * 4 + 2] = brw->attribs.Clip.ucp[j][2];
buf[offset + i * 4 + 3] = brw->attribs.Clip.ucp[j][3];
i++;
}
}
if (brw->curbe.vs_size) {
unsigned offset = brw->curbe.vs_start * 16;
unsigned nr = vp->program.Base.Parameters->NumParameters;
// unsigned offset = brw->curbe.vs_start * 16;
// unsigned nr = vp->max_const;
_mesa_load_state_parameters(ctx, vp->program.Base.Parameters);
/* map the vertex constant buffer and copy to curbe: */
for (i = 0; i < nr; i++) {
buf[offset + i * 4 + 0] = vp->program.Base.Parameters->ParameterValues[i][0];
buf[offset + i * 4 + 1] = vp->program.Base.Parameters->ParameterValues[i][1];
buf[offset + i * 4 + 2] = vp->program.Base.Parameters->ParameterValues[i][2];
buf[offset + i * 4 + 3] = vp->program.Base.Parameters->ParameterValues[i][3];
}
// assert(nr == 0);
assert(0);
}
if (0) {
@@ -309,7 +299,12 @@ static void upload_constant_buffer(struct brw_context *brw)
/* Copy data to the buffer:
*/
dri_bo_subdata(pool->buffer, brw->curbe.gs_offset, bufsz, buf);
brw->winsys->buffer_subdata_typed(brw->winsys,
pool->buffer,
brw->curbe.gs_offset,
bufsz,
buf,
BRW_CONSTANT_BUFFER );
}
/* TODO: only emit the constant_buffer packet when necessary, ie:
@@ -341,9 +336,7 @@ static void upload_constant_buffer(struct brw_context *brw)
* flushes as necessary when doublebuffering of CURBEs isn't
* possible.
*/
/* intel_batchbuffer_align(brw->intel.batch, 64, sizeof(cb)); */
BRW_BATCH_STRUCT(brw, &cb);
/* intel_batchbuffer_align(brw->intel.batch, 64, 0); */
}
}
@@ -355,9 +348,8 @@ static void upload_constant_buffer(struct brw_context *brw)
*/
const struct brw_tracked_state brw_constant_buffer = {
.dirty = {
.mesa = (_NEW_TRANSFORM|_NEW_PROJECTION), /* plus fp and vp flags */
.brw = (BRW_NEW_FRAGMENT_PROGRAM |
BRW_NEW_VERTEX_PROGRAM |
.brw = (BRW_NEW_CLIP |
BRW_NEW_CONSTANTS |
BRW_NEW_URB_FENCE | /* Implicit - hardware requires this, not used above */
BRW_NEW_PSP | /* Implicit - hardware requires this, not used above */
BRW_NEW_CURBE_OFFSETS),
@@ -366,4 +358,3 @@ const struct brw_tracked_state brw_constant_buffer = {
.update = upload_constant_buffer
};
#endif
-1
View File
@@ -151,7 +151,6 @@ static boolean brw_try_draw_elements( struct pipe_context *pipe,
unsigned count )
{
struct brw_context *brw = brw_context(pipe);
boolean retval = FALSE;
/* Set the first primitive ahead of validate_state:
*/
+12 -9
View File
@@ -207,25 +207,28 @@ static unsigned get_index_type(int type)
boolean brw_upload_vertex_buffers( struct brw_context *brw )
{
struct brw_array_state vbp;
unsigned nr_enabled = 0;
unsigned i;
int nr_enabled = brw->vb.last_vb + 1;
memset(&vbp, 0, sizeof(vbp));
/* This is a hardware limit:
*/
if (nr_enabled >= BRW_VEP_MAX)
return FALSE;
for (i = 0; i < nr_enabled; i++)
for (i = 0; i < BRW_VEP_MAX; i++)
{
vbp.vb[i].vb0.bits.pitch = brw->vb.vbo_array[i].pitch;
if (brw->vb.vbo_array[i]->buffer == NULL) {
nr_enabled = i;
break;
}
vbp.vb[i].vb0.bits.pitch = brw->vb.vbo_array[i]->pitch;
vbp.vb[i].vb0.bits.pad = 0;
vbp.vb[i].vb0.bits.access_type = BRW_VERTEXBUFFER_ACCESS_VERTEXDATA;
vbp.vb[i].vb0.bits.vb_index = i;
vbp.vb[i].offset = brw->vb.vbo_array[i].buffer_offset;
vbp.vb[i].buffer = brw->vb.vbo_array[i].buffer;
vbp.vb[i].max_index = brw->vb.vbo_array[i].max_index;
vbp.vb[i].offset = brw->vb.vbo_array[i]->buffer_offset;
vbp.vb[i].buffer = brw->vb.vbo_array[i]->buffer;
vbp.vb[i].max_index = brw->vb.vbo_array[i]->max_index;
}
@@ -260,7 +263,7 @@ boolean brw_upload_vertex_elements( struct brw_context *brw )
for (i = 0; i < nr_enabled; i++) {
struct brw_vertex_element *input = &brw->vb.inputs[i];
switch (brw->vb.vbo_array[input->vep.ve0.vertex_buffer_index].pitch) {
switch (brw->vb.vbo_array[input->vep.ve0.vertex_buffer_index]->pitch) {
case 0: input->vep.ve1.vfcomponent0 = BRW_VFCOMPONENT_STORE_0;
case 1: input->vep.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_0;
case 2: input->vep.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_0;
+11
View File
@@ -694,6 +694,17 @@ void brw_init_compile( struct brw_compile *p );
const unsigned *brw_get_program( struct brw_compile *p, unsigned *sz );
struct brw_instruction *brw_alu1( struct brw_compile *p,
unsigned opcode,
struct brw_reg dest,
struct brw_reg src );
struct brw_instruction *brw_alu2(struct brw_compile *p,
unsigned opcode,
struct brw_reg dest,
struct brw_reg src0,
struct brw_reg src1 );
/* Helpers for regular instructions:
*/
#define ALU1(OP) \
+9 -9
View File
@@ -363,10 +363,10 @@ static struct brw_instruction *next_insn( struct brw_compile *p,
}
static struct brw_instruction *brw_alu1( struct brw_compile *p,
unsigned opcode,
struct brw_reg dest,
struct brw_reg src )
struct brw_instruction *brw_alu1( struct brw_compile *p,
unsigned opcode,
struct brw_reg dest,
struct brw_reg src )
{
struct brw_instruction *insn = next_insn(p, opcode);
brw_set_dest(insn, dest);
@@ -374,11 +374,11 @@ static struct brw_instruction *brw_alu1( struct brw_compile *p,
return insn;
}
static struct brw_instruction *brw_alu2(struct brw_compile *p,
unsigned opcode,
struct brw_reg dest,
struct brw_reg src0,
struct brw_reg src1 )
struct brw_instruction *brw_alu2(struct brw_compile *p,
unsigned opcode,
struct brw_reg dest,
struct brw_reg src0,
struct brw_reg src1 )
{
struct brw_instruction *insn = next_insn(p, opcode);
brw_set_dest(insn, dest);
+2 -1
View File
@@ -34,6 +34,7 @@
#include "brw_context.h"
#include "brw_state.h"
#include "brw_defines.h"
#include "pipe/p_util.h"
@@ -46,7 +47,7 @@ static void upload_gs_unit( struct brw_context *brw )
/* CACHE_NEW_GS_PROG */
if (brw->gs.prog_active) {
gs.thread0.grf_reg_count =
ALIGN(brw->gs.prog_data->total_grf, 16) / 16 - 1;
align(brw->gs.prog_data->total_grf, 16) / 16 - 1;
gs.thread0.kernel_start_pointer = brw->gs.prog_gs_offset >> 6;
gs.thread3.urb_entry_read_length = brw->gs.prog_data->urb_read_length;
}
+4 -6
View File
@@ -202,9 +202,7 @@ static void upload_depthbuffer(struct brw_context *brw)
OUT_BATCH(((depth_surface->pitch * depth_surface->cpp) - 1) |
(format << 18) |
(BRW_TILEWALK_YMAJOR << 26) |
#if 0
(depth_surface->region->tiled << 27) |
#endif
// (depth_surface->region->tiled << 27) |
(BRW_SURFACE_2D << 29));
OUT_RELOC(depth_surface->buffer,
PIPE_BUFFER_FLAG_READ | PIPE_BUFFER_FLAG_WRITE, 0);
@@ -317,7 +315,7 @@ static void upload_pipe_control(struct brw_context *brw)
const struct brw_tracked_state brw_pipe_control = {
.dirty = {
.brw = BRW_NEW_CONTEXT,
.brw = BRW_NEW_SCENE,
.cache = 0
},
.update = upload_pipe_control
@@ -382,7 +380,7 @@ static void upload_invarient_state( struct brw_context *brw )
const struct brw_tracked_state brw_invarient_state = {
.dirty = {
.brw = BRW_NEW_CONTEXT,
.brw = BRW_NEW_SCENE,
.cache = 0
},
.update = upload_invarient_state
@@ -418,7 +416,7 @@ static void upload_state_base_address( struct brw_context *brw )
const struct brw_tracked_state brw_state_base_address = {
.dirty = {
.brw = BRW_NEW_CONTEXT,
.brw = BRW_NEW_SCENE,
.cache = 0
},
.update = upload_state_base_address
+165 -48
View File
@@ -36,9 +36,8 @@
#include "brw_util.h"
#include "brw_sf.h"
#include "brw_state.h"
#include "tgsi/util/tgsi_parse.h"
#if 0
#define DO_SETUP_BITS ((1<<(FRAG_ATTRIB_MAX)) - 1)
static void compile_sf_prog( struct brw_context *brw,
struct brw_sf_prog_key *key )
@@ -46,7 +45,6 @@ static void compile_sf_prog( struct brw_context *brw,
struct brw_sf_compile c;
const unsigned *program;
unsigned program_size;
unsigned i, idx;
memset(&c, 0, sizeof(c));
@@ -55,27 +53,17 @@ static void compile_sf_prog( struct brw_context *brw,
brw_init_compile(&c.func);
c.key = *key;
c.nr_attrs = brw_count_bits(c.key.attrs);
c.nr_attrs = c.key.vp_output_count;
c.nr_attr_regs = (c.nr_attrs+1)/2;
c.nr_setup_attrs = brw_count_bits(c.key.attrs & DO_SETUP_BITS);
c.nr_setup_attrs = c.key.fp_input_count;
c.nr_setup_regs = (c.nr_setup_attrs+1)/2;
c.prog_data.urb_read_length = c.nr_attr_regs;
c.prog_data.urb_entry_size = c.nr_setup_regs * 2;
/* Construct map from attribute number to position in the vertex.
*/
for (i = idx = 0; i < VERT_RESULT_MAX; i++)
if (c.key.attrs & (1<<i)) {
c.attr_to_idx[i] = idx;
c.idx_to_attr[idx] = i;
if (i >= VERT_RESULT_TEX0 && i <= VERT_RESULT_TEX7) {
c.point_attrs[i].CoordReplace =
brw->attribs.Point->CoordReplace[i - VERT_RESULT_TEX0];
} else
c.point_attrs[i].CoordReplace = FALSE;
idx++;
}
/* Which primitive? Or all three?
*/
@@ -90,21 +78,17 @@ static void compile_sf_prog( struct brw_context *brw,
break;
case SF_POINTS:
c.nr_verts = 1;
if (key->do_point_sprite)
brw_emit_point_sprite_setup( &c );
else
brw_emit_point_setup( &c );
brw_emit_point_setup( &c );
break;
case SF_UNFILLED_TRIS:
c.nr_verts = 3;
brw_emit_anyprim_setup( &c );
break;
default:
assert(0);
return;
}
/* get the program
*/
program = brw_get_program(&c.func, &program_size);
@@ -142,20 +126,15 @@ static void upload_sf_prog( struct brw_context *brw )
/* Populate the key, noting state dependencies:
*/
/* CACHE_NEW_VS_PROG */
key.attrs = brw->vs.prog_data->outputs_written;
key.vp_output_count = brw->vs.prog_data->outputs_written;
/* BRW_NEW_REDUCED_PRIMITIVE */
switch (brw->reduced_primitive) {
case PIPE_PRIM_TRIANGLES:
/* NOTE: We just use the edgeflag attribute as an indicator that
* unfilled triangles are active. We don't actually do the
* edgeflag testing here, it is already done in the clip
* program.
*/
if (key.attrs & (1<<VERT_RESULT_EDGE))
key.primitive = SF_UNFILLED_TRIS;
else
key.primitive = SF_TRIANGLES;
// if (key.attrs & (1<<VERT_RESULT_EDGE))
// key.primitive = SF_UNFILLED_TRIS;
// else
key.primitive = SF_TRIANGLES;
break;
case PIPE_PRIM_LINES:
key.primitive = SF_LINES;
@@ -165,16 +144,15 @@ static void upload_sf_prog( struct brw_context *brw )
break;
}
/* BRW_NEW_POINT */
key.do_point_sprite = brw->attribs.Point->PointSprite;
key.SpriteOrigin = brw->attribs.Point->SpriteOrigin;
/* BRW_NEW_RASTER */
key.do_flat_shading = (brw->attribs.Raster->flatshade);
key.do_twoside_color = (brw->attribs.Light->Enabled && brw->attribs.Light->Model.TwoSide);
/* _NEW_POLYGON */
if (key.do_twoside_color)
key.frontface_ccw = (brw->attribs.Polygon->FrontFace == GL_CCW);
// key.do_point_sprite = brw->attribs.Point->PointSprite;
// key.SpriteOrigin = brw->attribs.Point->SpriteOrigin;
// key.do_flat_shading = (brw->attribs.Raster->flatshade);
// key.do_twoside_color = (brw->attribs.Light->Enabled && brw->attribs.Light->Model.TwoSide);
// if (key.do_twoside_color)
// key.frontface_ccw = (brw->attribs.Polygon->FrontFace == GL_CCW);
if (!search_cache(brw, &key))
@@ -184,11 +162,150 @@ static void upload_sf_prog( struct brw_context *brw )
const struct brw_tracked_state brw_sf_prog = {
.dirty = {
.brw = (BRW_NEW_RASTER |
BRW_NEW_REDUCED_PRIMITIVE),
.cache = CACHE_NEW_VS_PROG
.brw = (BRW_NEW_RASTERIZER |
BRW_NEW_REDUCED_PRIMITIVE |
BRW_NEW_VS |
BRW_NEW_FS),
.cache = 0,
},
.update = upload_sf_prog
};
#endif
/* Build a struct like the one we'd like the state tracker to pass to
* us.
*/
static void update_sf_linkage( struct brw_context *brw )
{
const struct brw_vertex_program *vs = brw->attribs.VertexProgram;
const struct brw_fragment_program *fs = brw->attribs.FragmentProgram;
struct pipe_setup_linkage state;
struct tgsi_parse_context parse;
int i, j;
int nr_vp_outputs = 0;
int done = 0;
struct {
unsigned semantic:8;
unsigned semantic_index:16;
} fp_semantic[32], vp_semantic[32];
memset(&state, 0, sizeof(state));
state.fp_input_count = 0;
/* First scan fp inputs
*/
tgsi_parse_init( &parse, fs->program.tokens );
while( !done &&
!tgsi_parse_end_of_tokens( &parse ) )
{
tgsi_parse_token( &parse );
switch( parse.FullToken.Token.Type ) {
case TGSI_TOKEN_TYPE_DECLARATION:
if (parse.FullToken.FullDeclaration.Declaration.File == TGSI_FILE_INPUT)
{
int first = parse.FullToken.FullDeclaration.u.DeclarationRange.First;
int last = parse.FullToken.FullDeclaration.u.DeclarationRange.Last;
for (i = first; i < last; i++) {
state.fp_input[i].vp_output = ~0;
state.fp_input[i].bf_vp_output = ~0;
state.fp_input[i].interp_mode =
parse.FullToken.FullDeclaration.Interpolation.Interpolate;
fp_semantic[i].semantic =
parse.FullToken.FullDeclaration.Semantic.SemanticName;
fp_semantic[i].semantic_index =
parse.FullToken.FullDeclaration.Semantic.SemanticIndex;
}
assert(last > state.fp_input_count);
state.fp_input_count = last;
}
break;
default:
done = 1;
break;
}
}
assert(state.fp_input_count == fs->program.num_inputs);
/* Then scan vp outputs
*/
done = 0;
tgsi_parse_init( &parse, vs->program.tokens );
while( !done &&
!tgsi_parse_end_of_tokens( &parse ) )
{
tgsi_parse_token( &parse );
switch( parse.FullToken.Token.Type ) {
case TGSI_TOKEN_TYPE_DECLARATION:
if (parse.FullToken.FullDeclaration.Declaration.File == TGSI_FILE_INPUT)
{
int first = parse.FullToken.FullDeclaration.u.DeclarationRange.First;
int last = parse.FullToken.FullDeclaration.u.DeclarationRange.Last;
for (i = first; i < last; i++) {
vp_semantic[i].semantic =
parse.FullToken.FullDeclaration.Semantic.SemanticName;
vp_semantic[i].semantic_index =
parse.FullToken.FullDeclaration.Semantic.SemanticIndex;
}
assert(last > nr_vp_outputs);
nr_vp_outputs = last;
}
break;
default:
done = 1;
break;
}
}
/* Now match based on semantic information.
*/
for (i = 0; i< state.fp_input_count; i++) {
for (j = 0; j < nr_vp_outputs; j++) {
if (fp_semantic[i].semantic == vp_semantic[j].semantic &&
fp_semantic[i].semantic_index == vp_semantic[j].semantic_index) {
state.fp_input[i].vp_output = j;
}
}
if (fp_semantic[i].semantic == TGSI_SEMANTIC_COLOR) {
for (j = 0; j < nr_vp_outputs; j++) {
if (TGSI_SEMANTIC_BCOLOR == vp_semantic[j].semantic &&
fp_semantic[i].semantic_index == vp_semantic[j].semantic_index) {
state.fp_input[i].bf_vp_output = j;
}
}
}
}
if (memcmp(&brw->sf.linkage, &state, sizeof(state)) != 0) {
brw->sf.linkage = state;
brw->state.dirty.brw |= BRW_NEW_SF_LINKAGE;
}
}
const struct brw_tracked_state brw_sf_linkage = {
.dirty = {
.brw = (BRW_NEW_VS |
BRW_NEW_FS),
.cache = 0,
},
.update = update_sf_linkage
};
+14 -3
View File
@@ -42,15 +42,26 @@
#define SF_TRIANGLES 2
#define SF_UNFILLED_TRIS 3
struct brw_sf_prog_key {
unsigned attrs:32;
unsigned vp_output_count:5;
unsigned fp_input_count:5;
unsigned primitive:2;
unsigned do_twoside_color:1;
unsigned do_flat_shading:1;
unsigned frontface_ccw:1;
unsigned do_point_sprite:1;
unsigned pad:10;
int SpriteOrigin;
/* Interpolation masks;
*/
unsigned linear_mask;
unsigned persp_mask;
unsigned const_mask;
// int SpriteOrigin;
};
struct brw_sf_point_tex {
+6 -334
View File
@@ -36,171 +36,6 @@
#include "brw_util.h"
#include "brw_sf.h"
#if 0
static struct brw_reg get_vert_attr(struct brw_sf_compile *c,
struct brw_reg vert,
unsigned attr)
{
unsigned off = c->attr_to_idx[attr] / 2;
unsigned sub = c->attr_to_idx[attr] % 2;
return brw_vec4_grf(vert.nr + off, sub * 4);
}
static boolean have_attr(struct brw_sf_compile *c,
unsigned attr)
{
return (c->key.attrs & (1<<attr)) ? 1 : 0;
}
/***********************************************************************
* Twoside lighting
*/
static void copy_bfc( struct brw_sf_compile *c,
struct brw_reg vert )
{
struct brw_compile *p = &c->func;
unsigned i;
for (i = 0; i < 2; i++) {
if (have_attr(c, VERT_RESULT_COL0+i) &&
have_attr(c, VERT_RESULT_BFC0+i))
brw_MOV(p,
get_vert_attr(c, vert, VERT_RESULT_COL0+i),
get_vert_attr(c, vert, VERT_RESULT_BFC0+i));
}
}
static void do_twoside_color( struct brw_sf_compile *c )
{
struct brw_compile *p = &c->func;
struct brw_instruction *if_insn;
unsigned backface_conditional = c->key.frontface_ccw ? BRW_CONDITIONAL_G : BRW_CONDITIONAL_L;
/* Already done in clip program:
*/
if (c->key.primitive == SF_UNFILLED_TRIS)
return;
/* XXX: What happens if BFC isn't present? This could only happen
* for user-supplied vertex programs, as t_vp_build.c always does
* the right thing.
*/
if (!(have_attr(c, VERT_RESULT_COL0) && have_attr(c, VERT_RESULT_BFC0)) &&
!(have_attr(c, VERT_RESULT_COL1) && have_attr(c, VERT_RESULT_BFC1)))
return;
/* Need to use BRW_EXECUTE_4 and also do an 4-wide compare in order
* to get all channels active inside the IF. In the clipping code
* we run with NoMask, so it's not an option and we can use
* BRW_EXECUTE_1 for all comparisions.
*/
brw_push_insn_state(p);
brw_CMP(p, vec4(brw_null_reg()), backface_conditional, c->det, brw_imm_f(0));
if_insn = brw_IF(p, BRW_EXECUTE_4);
{
switch (c->nr_verts) {
case 3: copy_bfc(c, c->vert[2]);
case 2: copy_bfc(c, c->vert[1]);
case 1: copy_bfc(c, c->vert[0]);
}
}
brw_ENDIF(p, if_insn);
brw_pop_insn_state(p);
}
/***********************************************************************
* Flat shading
*/
#define VERT_RESULT_COLOR_BITS ((1<<VERT_RESULT_COL0) | \
(1<<VERT_RESULT_COL1))
static void copy_colors( struct brw_sf_compile *c,
struct brw_reg dst,
struct brw_reg src)
{
struct brw_compile *p = &c->func;
unsigned i;
for (i = VERT_RESULT_COL0; i <= VERT_RESULT_COL1; i++) {
if (have_attr(c,i))
brw_MOV(p,
get_vert_attr(c, dst, i),
get_vert_attr(c, src, i));
}
}
/* Need to use a computed jump to copy flatshaded attributes as the
* vertices are ordered according to y-coordinate before reaching this
* point, so the PV could be anywhere.
*/
static void do_flatshade_triangle( struct brw_sf_compile *c )
{
struct brw_compile *p = &c->func;
struct brw_reg ip = brw_ip_reg();
unsigned nr = brw_count_bits(c->key.attrs & VERT_RESULT_COLOR_BITS);
if (!nr)
return;
/* Already done in clip program:
*/
if (c->key.primitive == SF_UNFILLED_TRIS)
return;
brw_push_insn_state(p);
brw_MUL(p, c->pv, c->pv, brw_imm_ud(nr*2+1));
brw_JMPI(p, ip, ip, c->pv);
copy_colors(c, c->vert[1], c->vert[0]);
copy_colors(c, c->vert[2], c->vert[0]);
brw_JMPI(p, ip, ip, brw_imm_ud(nr*4+1));
copy_colors(c, c->vert[0], c->vert[1]);
copy_colors(c, c->vert[2], c->vert[1]);
brw_JMPI(p, ip, ip, brw_imm_ud(nr*2));
copy_colors(c, c->vert[0], c->vert[2]);
copy_colors(c, c->vert[1], c->vert[2]);
brw_pop_insn_state(p);
}
static void do_flatshade_line( struct brw_sf_compile *c )
{
struct brw_compile *p = &c->func;
struct brw_reg ip = brw_ip_reg();
unsigned nr = brw_count_bits(c->key.attrs & VERT_RESULT_COLOR_BITS);
if (!nr)
return;
/* Already done in clip program:
*/
if (c->key.primitive == SF_UNFILLED_TRIS)
return;
brw_push_insn_state(p);
brw_MUL(p, c->pv, c->pv, brw_imm_ud(nr+1));
brw_JMPI(p, ip, ip, c->pv);
copy_colors(c, c->vert[1], c->vert[0]);
brw_JMPI(p, ip, ip, brw_imm_ud(nr));
copy_colors(c, c->vert[0], c->vert[1]);
brw_pop_insn_state(p);
}
/***********************************************************************
@@ -277,9 +112,6 @@ static void copy_z_inv_w( struct brw_sf_compile *c )
static void invert_det( struct brw_sf_compile *c)
{
/* Looks like we invert all 8 elements just to get 1/det in
* position 2 !?!
*/
brw_math(&c->func,
c->inv_det,
BRW_MATH_FUNCTION_INV,
@@ -302,22 +134,16 @@ static boolean calculate_masks( struct brw_sf_compile *c,
ushort *pc_linear)
{
boolean is_last_attr = (reg == c->nr_setup_regs - 1);
unsigned persp_mask = c->key.attrs & ~NON_PERPECTIVE_ATTRS;
unsigned linear_mask;
if (c->key.do_flat_shading)
linear_mask = c->key.attrs & ~(FRAG_BIT_COL0|FRAG_BIT_COL1);
else
linear_mask = c->key.attrs;
*pc_persp = 0;
*pc_linear = 0;
*pc = 0xf;
if (persp_mask & (1 << c->idx_to_attr[reg*2]))
*pc_persp = 0xf;
// if (persp_mask & (1 << c->idx_to_attr[reg*2]))
// *pc_persp = 0xf;
if (linear_mask & (1 << c->idx_to_attr[reg*2]))
// if (linear_mask & (1 << c->idx_to_attr[reg*2]))
*pc_linear = 0xf;
/* Maybe only processs one attribute on the final round:
@@ -325,10 +151,10 @@ static boolean calculate_masks( struct brw_sf_compile *c,
if (reg*2+1 < c->nr_setup_attrs) {
*pc |= 0xf0;
if (persp_mask & (1 << c->idx_to_attr[reg*2+1]))
*pc_persp |= 0xf0;
// if (persp_mask & (1 << c->idx_to_attr[reg*2+1]))
// *pc_persp |= 0xf0;
if (linear_mask & (1 << c->idx_to_attr[reg*2+1]))
// if (linear_mask & (1 << c->idx_to_attr[reg*2+1]))
*pc_linear |= 0xf0;
}
@@ -347,12 +173,6 @@ void brw_emit_tri_setup( struct brw_sf_compile *c )
invert_det(c);
copy_z_inv_w(c);
if (c->key.do_twoside_color)
do_twoside_color(c);
if (c->key.do_flat_shading)
do_flatshade_triangle(c);
for (i = 0; i < c->nr_setup_regs; i++)
{
@@ -433,9 +253,6 @@ void brw_emit_line_setup( struct brw_sf_compile *c )
invert_det(c);
copy_z_inv_w(c);
if (c->key.do_flat_shading)
do_flatshade_line(c);
for (i = 0; i < c->nr_setup_regs; i++)
{
/* Pair of incoming attributes:
@@ -491,86 +308,6 @@ void brw_emit_line_setup( struct brw_sf_compile *c )
}
}
void brw_emit_point_sprite_setup( struct brw_sf_compile *c )
{
struct brw_compile *p = &c->func;
unsigned i;
c->nr_verts = 1;
alloc_regs(c);
copy_z_inv_w(c);
for (i = 0; i < c->nr_setup_regs; i++)
{
struct brw_sf_point_tex *tex = &c->point_attrs[c->idx_to_attr[2*i]];
struct brw_reg a0 = offset(c->vert[0], i);
ushort pc, pc_persp, pc_linear;
boolean last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear);
if (pc_persp)
{
if (!tex->CoordReplace) {
brw_set_predicate_control_flag_value(p, pc_persp);
brw_MUL(p, a0, a0, c->inv_w[0]);
}
}
if (tex->CoordReplace) {
/* Caculate 1.0/PointWidth */
brw_math(&c->func,
c->tmp,
BRW_MATH_FUNCTION_INV,
BRW_MATH_SATURATE_NONE,
0,
c->dx0,
BRW_MATH_DATA_SCALAR,
BRW_MATH_PRECISION_FULL);
if (c->key.SpriteOrigin == GL_UPPER_LEFT) {
brw_MUL(p, c->m1Cx, c->tmp, c->inv_w[0]);
brw_MOV(p, vec1(suboffset(c->m1Cx, 1)), brw_imm_f(0.0));
brw_MUL(p, c->m2Cy, c->tmp, negate(c->inv_w[0]));
brw_MOV(p, vec1(suboffset(c->m2Cy, 0)), brw_imm_f(0.0));
} else {
brw_MUL(p, c->m1Cx, c->tmp, c->inv_w[0]);
brw_MOV(p, vec1(suboffset(c->m1Cx, 1)), brw_imm_f(0.0));
brw_MUL(p, c->m2Cy, c->tmp, c->inv_w[0]);
brw_MOV(p, vec1(suboffset(c->m2Cy, 0)), brw_imm_f(0.0));
}
} else {
brw_MOV(p, c->m1Cx, brw_imm_ud(0));
brw_MOV(p, c->m2Cy, brw_imm_ud(0));
}
{
brw_set_predicate_control_flag_value(p, pc);
if (tex->CoordReplace) {
if (c->key.SpriteOrigin == GL_UPPER_LEFT) {
brw_MUL(p, c->m3C0, c->inv_w[0], brw_imm_f(1.0));
brw_MOV(p, vec1(suboffset(c->m3C0, 0)), brw_imm_f(0.0));
}
else
brw_MOV(p, c->m3C0, brw_imm_f(0.0));
} else {
brw_MOV(p, c->m3C0, a0); /* constant value */
}
/* Copy m0..m3 to URB.
*/
brw_urb_WRITE(p,
brw_null_reg(),
0,
brw_vec8_grf(0, 0),
0, /* allocate */
1, /* used */
4, /* msg len */
0, /* response len */
last, /* eot */
last, /* writes complete */
i*4, /* urb destination offset */
BRW_URB_SWIZZLE_TRANSPOSE);
}
}
}
/* Points setup - several simplifications as all attributes are
* constant across the face of the point (point sprites excluded!)
@@ -629,68 +366,3 @@ void brw_emit_point_setup( struct brw_sf_compile *c )
}
}
}
void brw_emit_anyprim_setup( struct brw_sf_compile *c )
{
struct brw_compile *p = &c->func;
struct brw_reg ip = brw_ip_reg();
struct brw_reg payload_prim = brw_uw1_reg(BRW_GENERAL_REGISTER_FILE, 1, 0);
struct brw_reg payload_attr = get_element_ud(brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, 1, 0), 0);
struct brw_reg primmask;
struct brw_instruction *jmp;
struct brw_reg v1_null_ud = vec1(retype(brw_null_reg(), BRW_REGISTER_TYPE_UD));
alloc_regs(c);
primmask = retype(get_element(c->tmp, 0), BRW_REGISTER_TYPE_UD);
brw_MOV(p, primmask, brw_imm_ud(1));
brw_SHL(p, primmask, primmask, payload_prim);
brw_set_conditionalmod(p, BRW_CONDITIONAL_Z);
brw_AND(p, v1_null_ud, primmask, brw_imm_ud((1<<_3DPRIM_TRILIST) |
(1<<_3DPRIM_TRISTRIP) |
(1<<_3DPRIM_TRIFAN) |
(1<<_3DPRIM_TRISTRIP_REVERSE) |
(1<<_3DPRIM_POLYGON) |
(1<<_3DPRIM_RECTLIST) |
(1<<_3DPRIM_TRIFAN_NOSTIPPLE)));
jmp = brw_JMPI(p, ip, ip, brw_imm_w(0));
{
brw_push_insn_state(p);
brw_emit_tri_setup( c );
brw_pop_insn_state(p);
/* note - thread killed in subroutine */
}
brw_land_fwd_jump(p, jmp);
brw_set_conditionalmod(p, BRW_CONDITIONAL_Z);
brw_AND(p, v1_null_ud, primmask, brw_imm_ud((1<<_3DPRIM_LINELIST) |
(1<<_3DPRIM_LINESTRIP) |
(1<<_3DPRIM_LINELOOP) |
(1<<_3DPRIM_LINESTRIP_CONT) |
(1<<_3DPRIM_LINESTRIP_BF) |
(1<<_3DPRIM_LINESTRIP_CONT_BF)));
jmp = brw_JMPI(p, ip, ip, brw_imm_w(0));
{
brw_push_insn_state(p);
brw_emit_line_setup( c );
brw_pop_insn_state(p);
/* note - thread killed in subroutine */
}
brw_land_fwd_jump(p, jmp);
brw_set_conditionalmod(p, BRW_CONDITIONAL_Z);
brw_AND(p, v1_null_ud, payload_attr, brw_imm_ud(1<<BRW_SPRITE_POINT_ENABLE));
jmp = brw_JMPI(p, ip, ip, brw_imm_w(0));
{
brw_push_insn_state(p);
brw_emit_point_sprite_setup( c );
brw_pop_insn_state(p);
}
brw_land_fwd_jump(p, jmp);
brw_emit_point_setup( c );
}
#endif
+33 -89
View File
@@ -34,91 +34,41 @@
#include "brw_context.h"
#include "brw_state.h"
#include "brw_defines.h"
#include "pipe/p_util.h"
#if 0
static void upload_sf_vp(struct brw_context *brw)
{
GLcontext *ctx = &brw->intel.ctx;
struct brw_sf_viewport sfv;
struct intel_renderbuffer *irb =
intel_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0][0]);
float y_scale, y_bias;
int x, y, w, h, x1, x2, y1, y2;
int draw_h = ctx->DrawBuffer->Height;
memset(&sfv, 0, sizeof(sfv));
if (ctx->DrawBuffer->Name) {
/* User-created FBO */
if (irb && !irb->RenderToTexture) {
y_scale = -1.0;
y_bias = draw_h;
} else {
y_scale = 1.0;
y_bias = 0;
}
} else {
if (brw->intel.driDrawable != NULL) {
y_scale = -1.0;
y_bias = draw_h;
} else {
y_scale = 1.0;
y_bias = 0;
}
}
/* _NEW_VIEWPORT, BRW_NEW_METAOPS */
/* BRW_NEW_VIEWPORT */
{
const float *scale = brw->attribs.Viewport.scale;
const float *trans = brw->attribs.Viewport.translate;
if (!brw->metaops.active) {
const float *v = brw->intel.ctx.Viewport._WindowMap.m;
sfv.viewport.m00 = v[MAT_SX];
sfv.viewport.m11 = v[MAT_SY] * y_scale;
sfv.viewport.m22 = v[MAT_SZ] * brw->intel.depth_scale;
sfv.viewport.m30 = v[MAT_TX];
sfv.viewport.m31 = v[MAT_TY] * y_scale + y_bias;
sfv.viewport.m32 = v[MAT_TZ] * brw->intel.depth_scale;
} else {
sfv.viewport.m00 = 1;
sfv.viewport.m11 = - 1;
sfv.viewport.m22 = 1;
sfv.viewport.m30 = 0;
sfv.viewport.m31 = brw->intel.driDrawable->h;
sfv.viewport.m32 = 0;
sfv.viewport.m00 = scale[0];
sfv.viewport.m11 = scale[1];
sfv.viewport.m22 = scale[2];
sfv.viewport.m30 = trans[0];
sfv.viewport.m31 = trans[1];
sfv.viewport.m32 = trans[2];
}
/* _NEW_SCISSOR */
x = brw->attribs.Scissor->X;
y = brw->attribs.Scissor->Y;
w = brw->attribs.Scissor->Width;
h = brw->attribs.Scissor->Height;
if (ctx->DrawBuffer->Name == 0) {
x1 = x;
y1 = draw_h - (y + h);
x2 = x + w - 1;
y2 = y1 + h - 1;
} else {
/* FBO has non-inverted coords. */
x1 = x;
y1 = y;
x2 = x + w - 1;
y2 = y + h - 1;
}
sfv.scissor.xmin = CLAMP(x1, 0, ctx->DrawBuffer->Width - 1);
sfv.scissor.xmax = CLAMP(y1, 0, ctx->DrawBuffer->Height - 1);
sfv.scissor.ymin = CLAMP(x2, 0, ctx->DrawBuffer->Width - 1);
sfv.scissor.ymax = CLAMP(y2, 0, ctx->DrawBuffer->Height - 1);
sfv.scissor.xmin = brw->attribs.Scissor.minx;
sfv.scissor.xmax = brw->attribs.Scissor.maxx;
sfv.scissor.ymin = brw->attribs.Scissor.miny;
sfv.scissor.ymax = brw->attribs.Scissor.maxy;
brw->sf.vp_gs_offset = brw_cache_data( &brw->cache[BRW_SF_VP], &sfv );
}
const struct brw_tracked_state brw_sf_vp = {
.dirty = {
.mesa = (_NEW_VIEWPORT |
_NEW_SCISSOR),
.brw = BRW_NEW_METAOPS,
.brw = (BRW_NEW_SCISSOR |
BRW_NEW_VIEWPORT),
.cache = 0
},
.update = upload_sf_vp
@@ -130,7 +80,7 @@ static void upload_sf_unit( struct brw_context *brw )
memset(&sf, 0, sizeof(sf));
/* CACHE_NEW_SF_PROG */
sf.thread0.grf_reg_count = ALIGN(brw->sf.prog_data->total_grf, 16) / 16 - 1;
sf.thread0.grf_reg_count = align(brw->sf.prog_data->total_grf, 16) / 16 - 1;
sf.thread0.kernel_start_pointer = brw->sf.prog_gs_offset >> 6;
sf.thread3.urb_entry_read_length = brw->sf.prog_data->urb_read_length;
@@ -151,19 +101,19 @@ static void upload_sf_unit( struct brw_context *brw )
/* CACHE_NEW_SF_VP */
sf.sf5.sf_viewport_state_offset = brw->sf.vp_gs_offset >> 5;
sf.sf5.viewport_transform = 1;
/* _NEW_SCISSOR */
if (brw->attribs.Scissor->Enabled)
/* BRW_NEW_RASTER */
if (brw->attribs.Raster->scissor)
sf.sf6.scissor = 1;
/* _NEW_POLYGON */
#if 0
if (brw->attribs.Polygon->FrontFace == GL_CCW)
sf.sf5.front_winding = BRW_FRONTWINDING_CCW;
else
sf.sf5.front_winding = BRW_FRONTWINDING_CW;
if (brw->attribs.Polygon->CullFlag) {
switch (brw->attribs.Polygon->CullFaceMode) {
case GL_FRONT:
@@ -182,25 +132,24 @@ static void upload_sf_unit( struct brw_context *brw )
}
else
sf.sf6.cull_mode = BRW_CULLMODE_NONE;
#else
sf.sf5.front_winding = BRW_FRONTWINDING_CW;
sf.sf6.cull_mode = BRW_CULLMODE_NONE;
#endif
/* _NEW_LINE */
/* XXX use ctx->Const.Min/MaxLineWidth here */
sf.sf6.line_width = CLAMP(brw->attribs.Line->Width, 1.0, 5.0) * (1<<1);
sf.sf6.line_width = CLAMP(brw->attribs.Raster->line_width, 1.0, 5.0) * (1<<1);
sf.sf6.line_endcap_aa_region_width = 1;
if (brw->attribs.Line->SmoothFlag)
if (brw->attribs.Raster->line_smooth)
sf.sf6.aa_enable = 1;
else if (sf.sf6.line_width <= 0x2)
sf.sf6.line_width = 0;
/* _NEW_POINT */
sf.sf6.point_rast_rule = 1; /* opengl conventions */
/* XXX clamp max depends on AA vs. non-AA */
sf.sf7.sprite_point = brw->attribs.Point->PointSprite;
sf.sf7.point_size = CLAMP(brw->attribs.Point->Size, 1.0, 255.0) * (1<<3);
sf.sf7.use_point_size_state = !brw->attribs.Point->_Attenuated;
sf.sf7.sprite_point = brw->attribs.Raster->point_sprite;
sf.sf7.point_size = CLAMP(brw->attribs.Raster->line_width, 1.0, 255.0) * (1<<3);
sf.sf7.use_point_size_state = brw->attribs.Raster->point_size_per_vertex;
/* might be BRW_NEW_PRIMITIVE if we have to adjust pv for polygons:
*/
@@ -220,12 +169,8 @@ static void upload_sf_unit( struct brw_context *brw )
const struct brw_tracked_state brw_sf_unit = {
.dirty = {
.mesa = (_NEW_POLYGON |
_NEW_LINE |
_NEW_POINT |
_NEW_SCISSOR),
.brw = (BRW_NEW_URB_FENCE |
BRW_NEW_METAOPS),
.brw = (BRW_NEW_RASTERIZER |
BRW_NEW_URB_FENCE),
.cache = (CACHE_NEW_SF_VP |
CACHE_NEW_SF_PROG)
},
@@ -233,4 +178,3 @@ const struct brw_tracked_state brw_sf_unit = {
};
#endif
@@ -0,0 +1,49 @@
#include "brw_context.h"
#include "brw_state.h"
#include "pipe/p_util.h"
#include "pipe/p_shader_tokens.h"
#include "pipe/tgsi/util/tgsi_parse.h"
void brw_shader_info(const struct tgsi_token *tokens,
struct brw_shader_info *info )
{
struct tgsi_parse_context parse;
int done = 0;
tgsi_parse_init( &parse, tokens );
while( !done &&
!tgsi_parse_end_of_tokens( &parse ) )
{
tgsi_parse_token( &parse );
switch( parse.FullToken.Token.Type ) {
case TGSI_TOKEN_TYPE_DECLARATION:
{
const struct tgsi_full_declaration *decl = &parse.FullToken.FullDeclaration;
unsigned last = decl->u.DeclarationRange.Last;
assert( decl->Declaration.Declare == TGSI_DECLARE_RANGE );
// Broken by crazy wpos init:
//assert( info->nr_regs[decl->Declaration.File] <= last);
info->nr_regs[decl->Declaration.File] = MAX2(info->nr_regs[decl->Declaration.File],
last+1);
break;
}
case TGSI_TOKEN_TYPE_IMMEDIATE:
case TGSI_TOKEN_TYPE_INSTRUCTION:
default:
done = 1;
break;
}
}
tgsi_parse_free (&parse);
}
+13 -6
View File
@@ -198,6 +198,13 @@ static void * brw_create_fs_state(struct pipe_context *pipe,
/* XXX: Do I have to duplicate the tokens as well??
*/
brw_fp->program = *shader;
brw_fp->id = brw_context(pipe)->program_id++;
brw_shader_info(shader->tokens,
&brw_fp->info);
tgsi_dump(shader->tokens, 0);
return (void *)brw_fp;
}
@@ -228,6 +235,9 @@ static void *brw_create_vs_state(struct pipe_context *pipe,
/* XXX: Do I have to duplicate the tokens as well??
*/
brw_vp->program = *shader;
brw_vp->id = brw_context(pipe)->program_id++;
brw_shader_info(shader->tokens,
&brw_vp->info);
tgsi_dump(shader->tokens, 0);
@@ -273,14 +283,11 @@ static void brw_set_viewport_state( struct pipe_context *pipe,
static void brw_set_vertex_buffer( struct pipe_context *pipe,
unsigned index,
const struct pipe_vertex_buffer *buffer )
unsigned index,
const struct pipe_vertex_buffer *buffer )
{
struct brw_context *brw = brw_context(pipe);
brw->vb.vbo_array[index] = *buffer;
if (index > brw->vb.last_vb)
brw->vb.last_vb = index;
assert(brw->vb.last_vb < BRW_VEP_MAX);
brw->vb.vbo_array[index] = buffer;
}
static void brw_set_vertex_element(struct pipe_context *pipe,
+7
View File
@@ -154,4 +154,11 @@ void brw_upload_clip_prog(struct brw_context *brw);
void brw_upload_blend_constant_color(struct brw_context *brw);
void brw_upload_wm_samplers(struct brw_context *brw);
/* brw_shader_info.c
*/
void brw_shader_info(const struct tgsi_token *tokens,
struct brw_shader_info *info );
#endif
+3 -2
View File
@@ -178,8 +178,9 @@ unsigned brw_upload_cache( struct brw_cache *cache,
if (BRW_DEBUG & DEBUG_STATE)
printf("upload %s: %d bytes to pool buffer %p offset %x\n",
cache->name, data_size,
cache->pool->buffer,
cache->name,
data_size,
(void*)cache->pool->buffer,
offset);
/* Copy data to the buffer:
+5 -4
View File
@@ -43,17 +43,18 @@
*/
#include "pipe/p_winsys.h"
#include "pipe/p_util.h"
#include "brw_context.h"
#include "brw_state.h"
boolean brw_pool_alloc( struct brw_mem_pool *pool,
unsigned size,
unsigned align,
unsigned alignment,
unsigned *offset_return)
{
unsigned fixup = ALIGN(pool->offset, align) - pool->offset;
unsigned fixup = align(pool->offset, alignment) - pool->offset;
size = ALIGN(size, 4);
size = align(size, 4);
if (pool->offset + fixup + size >= pool->size) {
printf("%s failed\n", __FUNCTION__);
@@ -114,7 +115,7 @@ void brw_pool_check_wrap( struct brw_context *brw,
struct brw_mem_pool *pool )
{
if (pool->offset > (pool->size * 3) / 4) {
brw->state.dirty.brw |= BRW_NEW_CONTEXT;
brw->state.dirty.brw |= BRW_NEW_SCENE;
}
}
+6 -35
View File
@@ -97,39 +97,16 @@ const struct brw_tracked_state *atoms[] =
void brw_init_state( struct brw_context *brw )
{
unsigned i;
brw_init_pools(brw);
brw_init_caches(brw);
brw->state.atoms = MALLOC(sizeof(atoms));
brw->state.nr_atoms = sizeof(atoms)/sizeof(*atoms);
memcpy(brw->state.atoms, atoms, sizeof(atoms));
/* Patch in a pointer to the dynamic state atom:
*/
for (i = 0; i < brw->state.nr_atoms; i++)
if (brw->state.atoms[i] == NULL)
brw->state.atoms[i] = &brw->curbe.tracked_state;
memcpy(&brw->curbe.tracked_state,
&brw_constant_buffer,
sizeof(brw_constant_buffer));
brw->state.dirty.brw = ~0;
brw->emit_state_always = 0;
}
void brw_destroy_state( struct brw_context *brw )
{
if (brw->state.atoms) {
FREE(brw->state.atoms);
brw->state.atoms = NULL;
}
brw_destroy_caches(brw);
brw_destroy_batch_cache(brw);
brw_destroy_pools(brw);
@@ -177,7 +154,7 @@ void brw_validate_state( struct brw_context *brw )
state->brw == 0)
return;
if (brw->state.dirty.brw & BRW_NEW_CONTEXT)
if (brw->state.dirty.brw & BRW_NEW_SCENE)
brw_clear_batch_cache_flush(brw);
if (BRW_DEBUG) {
@@ -189,21 +166,17 @@ void brw_validate_state( struct brw_context *brw )
memset(&examined, 0, sizeof(examined));
prev = *state;
for (i = 0; i < brw->state.nr_atoms; i++) {
const struct brw_tracked_state *atom = brw->state.atoms[i];
for (i = 0; i < Elements(atoms); i++) {
const struct brw_tracked_state *atom = atoms[i];
struct brw_state_flags generated;
assert(atom->dirty.brw ||
atom->dirty.cache);
assert(atom->update);
if (check_state(state, &atom->dirty) || atom->always_update) {
if (check_state(state, &atom->dirty)) {
atom->update( brw );
/* emit_foo(brw); */
}
if (atom->emit_reloc != NULL)
atom->emit_reloc(brw);
accumulate_state(&examined, &atom->dirty);
@@ -218,12 +191,10 @@ void brw_validate_state( struct brw_context *brw )
}
else {
for (i = 0; i < Elements(atoms); i++) {
const struct brw_tracked_state *atom = brw->state.atoms[i];
const struct brw_tracked_state *atom = atoms[i];
if (check_state(state, &atom->dirty) || atom->always_update)
if (check_state(state, &atom->dirty))
atom->update( brw );
if (atom->emit_reloc != NULL)
atom->emit_reloc(brw);
}
}
+12 -14
View File
@@ -149,10 +149,10 @@ static void i945_miptree_layout_2d(struct brw_texture *tex)
unsigned mip1_width;
if (pt->compressed) {
mip1_width = ALIGN(minify(pt->width[0]), align_w)
+ ALIGN(minify(minify(pt->width[0])), align_w);
mip1_width = align(minify(pt->width[0]), align_w)
+ align(minify(minify(pt->width[0])), align_w);
} else {
mip1_width = ALIGN(minify(pt->width[0]), align_w)
mip1_width = align(minify(pt->width[0]), align_w)
+ minify(minify(pt->width[0]));
}
@@ -164,7 +164,7 @@ static void i945_miptree_layout_2d(struct brw_texture *tex)
/* Pitch must be a whole number of dwords, even though we
* express it in texels.
*/
tex->pitch = ALIGN(tex->pitch * pt->cpp, 4) / pt->cpp;
tex->pitch = align(tex->pitch * pt->cpp, 4) / pt->cpp;
tex->total_height = 0;
for ( level = pt->first_level ; level <= pt->last_level ; level++ ) {
@@ -176,7 +176,7 @@ static void i945_miptree_layout_2d(struct brw_texture *tex)
if (pt->compressed)
img_height = MAX2(1, height/4);
else
img_height = ALIGN(height, align_h);
img_height = align(height, align_h);
/* Because the images are packed better, the final offset
@@ -187,7 +187,7 @@ static void i945_miptree_layout_2d(struct brw_texture *tex)
/* Layout_below: step right after second mipmap.
*/
if (level == pt->first_level + 1) {
x += ALIGN(width, align_w);
x += align(width, align_w);
}
else {
y += img_height;
@@ -221,13 +221,13 @@ static boolean brw_miptree_layout(struct pipe_context *pipe, struct brw_texture
#if 0
if (pt->compressed) {
align_w = intel_compressed_alignment(pt->internal_format);
pt->pitch = ALIGN(width, align_w);
pt->pitch = align(width, align_w);
pack_y_pitch = (height + 3) / 4;
} else
#endif
{
tex->pitch = ALIGN(pt->width[0] * pt->cpp, 4) / pt->cpp;
pack_y_pitch = ALIGN(pt->height[0], align_h);
tex->pitch = align(pt->width[0] * pt->cpp, 4) / pt->cpp;
pack_y_pitch = align(pt->height[0], align_h);
}
pack_x_pitch = tex->pitch;
@@ -262,8 +262,8 @@ static boolean brw_miptree_layout(struct pipe_context *pipe, struct brw_texture
if (pt->compressed) {
pack_y_pitch = (height + 3) / 4;
if (pack_x_pitch > ALIGN(width, align_w)) {
pack_x_pitch = ALIGN(width, align_w);
if (pack_x_pitch > align(width, align_w)) {
pack_x_pitch = align(width, align_w);
pack_x_nr <<= 1;
}
} else {
@@ -275,7 +275,7 @@ static boolean brw_miptree_layout(struct pipe_context *pipe, struct brw_texture
if (pack_y_pitch > 2) {
pack_y_pitch >>= 1;
pack_y_pitch = ALIGN(pack_y_pitch, align_h);
pack_y_pitch = align(pack_y_pitch, align_h);
}
}
@@ -305,8 +305,6 @@ brw_texture_create(struct pipe_context *pipe, struct pipe_texture **pt)
sizeof(struct brw_texture));
if (tex) {
struct brw_context *brw = brw_context(pipe);
memset(&tex->base + 1, 0,
sizeof(struct brw_texture) - sizeof(struct pipe_texture));
-10
View File
@@ -97,13 +97,6 @@ static void brw_upload_vs_prog( struct brw_context *brw )
key.copy_edgeflag = (brw->attribs.Raster->fill_cw != PIPE_POLYGON_MODE_FILL ||
brw->attribs.Raster->fill_ccw != PIPE_POLYGON_MODE_FILL);
#if 0
/* BRW_NEW_METAOPS
*/
if (brw->metaops.active)
key.know_w_is_one = 1;
#endif
/* Make an early check for the key.
*/
if (brw_search_cache(&brw->cache[BRW_VS_PROG],
@@ -120,9 +113,6 @@ static void brw_upload_vs_prog( struct brw_context *brw )
*/
const struct brw_tracked_state brw_vs_prog = {
.dirty = {
#if 0
.brw = BRW_NEW_VS | BRW_NEW_METAOPS,
#endif
.brw = BRW_NEW_VS,
.cache = 0
},
-223
View File
@@ -1,223 +0,0 @@
/*
Copyright (C) Intel Corp. 2006. All Rights Reserved.
Intel funded Tungsten Graphics (http://www.tungstengraphics.com) 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 <keith@tungstengraphics.com>
*/
#include "brw_context.h"
#include "brw_vs.h"
#if 0
/* Component is active if it may diverge from [0,0,0,1]. Undef values
* are promoted to [0,0,0,1] for the purposes of this analysis.
*/
struct tracker {
boolean twoside;
ubyte active[PROGRAM_OUTPUT+1][128];
unsigned size_masks[4];
};
static void set_active_component( struct tracker *t,
unsigned file,
unsigned index,
ubyte active )
{
switch (file) {
case PROGRAM_TEMPORARY:
case PROGRAM_INPUT:
case PROGRAM_OUTPUT:
t->active[file][index] |= active;
default:
break;
}
}
static void set_active( struct tracker *t,
struct prog_dst_register dst,
unsigned active )
{
set_active_component( t, dst.File, dst.Index, active & dst.WriteMask );
}
static ubyte get_active_component( struct tracker *t,
unsigned file,
unsigned index,
unsigned component,
ubyte swz )
{
switch (swz) {
case SWIZZLE_ZERO:
return component < 3 ? 0 : (1<<component);
case SWIZZLE_ONE:
return component == 3 ? 0 : (1<<component);
default:
switch (file) {
case PROGRAM_TEMPORARY:
case PROGRAM_INPUT:
case PROGRAM_OUTPUT:
return t->active[file][index] & (1<<component);
default:
return 1 << component;
}
}
}
static ubyte get_active( struct tracker *t,
struct prog_src_register src )
{
unsigned i;
ubyte active = src.NegateBase; /* NOTE! */
if (src.RelAddr)
return 0xf;
for (i = 0; i < 4; i++)
active |= get_active_component(t, src.File, src.Index, i,
GET_SWZ(src.Swizzle, i));
return active;
}
static ubyte get_output_size( struct tracker *t,
unsigned idx )
{
ubyte active = t->active[PROGRAM_OUTPUT][idx];
if (active & (1<<3)) return 4;
if (active & (1<<2)) return 3;
if (active & (1<<1)) return 2;
if (active & (1<<0)) return 1;
return 0;
}
/* Note the potential copying that occurs in the setup program:
*/
static void calc_sizes( struct tracker *t )
{
unsigned i;
if (t->twoside) {
t->active[PROGRAM_OUTPUT][VERT_RESULT_COL0] |=
t->active[PROGRAM_OUTPUT][VERT_RESULT_BFC0];
t->active[PROGRAM_OUTPUT][VERT_RESULT_COL1] |=
t->active[PROGRAM_OUTPUT][VERT_RESULT_BFC1];
}
for (i = 0; i < FRAG_ATTRIB_MAX; i++) {
switch (get_output_size(t, i)) {
case 4: t->size_masks[4-1] |= 1<<i;
case 3: t->size_masks[3-1] |= 1<<i;
case 2: t->size_masks[2-1] |= 1<<i;
case 1: t->size_masks[1-1] |= 1<<i;
break;
}
}
}
static ubyte szflag[4+1] = {
0,
0x1,
0x3,
0x7,
0xf
};
/* Pull a size out of the packed array:
*/
static unsigned get_input_size(struct brw_context *brw,
unsigned attr)
{
unsigned sizes_dword = brw->vb.info.sizes[attr/16];
unsigned sizes_bits = (sizes_dword>>((attr%16)*2)) & 0x3;
return sizes_bits + 1;
/* return brw->vb.inputs[attr].glarray->Size; */
}
/* Calculate sizes of vertex program outputs. Size is the largest
* component index which might vary from [0,0,0,1]
*/
static void calc_wm_input_sizes( struct brw_context *brw )
{
/* BRW_NEW_VERTEX_PROGRAM */
struct brw_vertex_program *vp =
(struct brw_vertex_program *)brw->vertex_program;
/* BRW_NEW_INPUT_DIMENSIONS */
struct tracker t;
unsigned insn;
unsigned i;
memset(&t, 0, sizeof(t));
/* _NEW_LIGHT */
if (brw->attribs.Light->Model.TwoSide)
t.twoside = 1;
for (i = 0; i < PIPE_ATTRIB_MAX; i++)
if (vp->program.Base.InputsRead & (1<<i))
set_active_component(&t, PROGRAM_INPUT, i,
szflag[get_input_size(brw, i)]);
for (insn = 0; insn < vp->program.Base.NumInstructions; insn++) {
struct prog_instruction *inst = &vp->program.Base.Instructions[insn];
switch (inst->Opcode) {
case OPCODE_ARL:
break;
case OPCODE_MOV:
set_active(&t, inst->DstReg, get_active(&t, inst->SrcReg[0]));
break;
default:
set_active(&t, inst->DstReg, 0xf);
break;
}
}
calc_sizes(&t);
if (memcmp(brw->wm.input_size_masks, t.size_masks, sizeof(t.size_masks)) != 0) {
memcpy(brw->wm.input_size_masks, t.size_masks, sizeof(t.size_masks));
brw->state.dirty.brw |= BRW_NEW_WM_INPUT_DIMENSIONS;
}
}
const struct brw_tracked_state brw_wm_input_sizes = {
.dirty = {
.mesa = _NEW_LIGHT,
.brw = BRW_NEW_VERTEX_PROGRAM | BRW_NEW_INPUT_DIMENSIONS,
.cache = 0
},
.update = calc_wm_input_sizes
};
#endif
+17 -21
View File
@@ -103,28 +103,26 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c,
c->first_output = reg;
mrf = 4;
for (i = 0; i < c->vp->program.num_outputs; i++) {
if (c->prog_data.outputs_written & (1<<i)) {
c->nr_outputs++;
c->nr_outputs++;
#if 0
if (i == VERT_RESULT_HPOS) {
c->regs[TGSI_FILE_OUTPUT][i] = brw_vec8_grf(reg, 0);
reg++;
}
else if (i == VERT_RESULT_PSIZ) {
c->regs[TGSI_FILE_OUTPUT][i] = brw_vec8_grf(reg, 0);
reg++;
mrf++; /* just a placeholder? XXX fix later stages & remove this */
}
else {
c->regs[TGSI_FILE_OUTPUT][i] = brw_message_reg(mrf);
mrf++;
}
#else
/* for now stuff everything in grf */
if (i == VERT_RESULT_HPOS) {
c->regs[TGSI_FILE_OUTPUT][i] = brw_vec8_grf(reg, 0);
reg++;
#endif
}
else if (i == VERT_RESULT_PSIZ) {
c->regs[TGSI_FILE_OUTPUT][i] = brw_vec8_grf(reg, 0);
reg++;
mrf++; /* just a placeholder? XXX fix later stages & remove this */
}
else {
c->regs[TGSI_FILE_OUTPUT][i] = brw_message_reg(mrf);
mrf++;
}
#else
/* for now stuff everything in grf */
c->regs[TGSI_FILE_OUTPUT][i] = brw_vec8_grf(reg, 0);
reg++;
#endif
}
/* Allocate program temporaries:
@@ -627,11 +625,9 @@ static struct brw_reg get_reg( struct brw_vs_compile *c,
case TGSI_FILE_TEMPORARY:
case TGSI_FILE_INPUT:
case TGSI_FILE_OUTPUT:
case TGSI_FILE_CONSTANT:
assert(c->regs[file][index].nr != 0);
return c->regs[file][index];
case TGSI_FILE_CONSTANT:
assert(c->regs[TGSI_FILE_CONSTANT][index].nr != 0);
return c->regs[TGSI_FILE_CONSTANT][index];
case TGSI_FILE_ADDRESS:
assert(index == 0);
return c->regs[file][index];
+1 -1
View File
@@ -44,7 +44,7 @@ static void upload_vs_unit( struct brw_context *brw )
/* CACHE_NEW_VS_PROG */
vs.thread0.kernel_start_pointer = brw->vs.prog_gs_offset >> 6;
vs.thread0.grf_reg_count = ALIGN(brw->vs.prog_data->total_grf, 16) / 16 - 1;
vs.thread0.grf_reg_count = align(brw->vs.prog_data->total_grf, 16) / 16 - 1;
vs.thread3.urb_entry_read_length = brw->vs.prog_data->urb_read_length;
vs.thread3.const_urb_entry_read_length = brw->vs.prog_data->curb_read_length;
vs.thread3.dispatch_grf_start_reg = 1;
-149
View File
@@ -1,149 +0,0 @@
/*
Copyright (C) Intel Corp. 2006. All Rights Reserved.
Intel funded Tungsten Graphics (http://www.tungstengraphics.com) 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 <keith@tungstengraphics.com>
*/
#include "brw_context.h"
#include "brw_defines.h"
#include "brw_state.h"
#include "brw_draw.h"
#include "brw_state.h"
#include "brw_vs.h"
#include <stdarg.h>
#if 0
/* called from intelDestroyContext()
*/
static void brw_destroy_context( struct intel_context *intel )
{
GLcontext *ctx = &intel->ctx;
struct brw_context *brw = brw_context(&intel->ctx);
brw_destroy_metaops(brw);
brw_destroy_state(brw);
brw_draw_destroy( brw );
brw_ProgramCacheDestroy( ctx );
brw_FrameBufferTexDestroy( brw );
}
/* called from intelDrawBuffer()
*/
static void brw_set_draw_region( struct intel_context *intel,
struct intel_region *draw_region,
struct intel_region *depth_region)
{
struct brw_context *brw = brw_context(&intel->ctx);
intel_region_release(&brw->state.draw_region);
intel_region_release(&brw->state.depth_region);
intel_region_reference(&brw->state.draw_region, draw_region);
intel_region_reference(&brw->state.depth_region, depth_region);
}
/* called from intelFlushBatchLocked
*/
static void brw_lost_hardware( struct intel_context *intel )
{
struct brw_context *brw = brw_context(&intel->ctx);
/* Note that we effectively lose the context after this.
*
* Setting this flag provokes a state buffer wrap and also flushes
* the hardware caches.
*/
brw->state.dirty.brw |= BRW_NEW_CONTEXT;
/* Which means there shouldn't be any commands already queued:
*/
assert(intel->batch->ptr == intel->batch->map);
brw->state.dirty.mesa |= ~0;
brw->state.dirty.brw |= ~0;
brw->state.dirty.cache |= ~0;
}
static void brw_note_fence( struct intel_context *intel,
unsigned fence )
{
brw_context(&intel->ctx)->state.dirty.brw |= BRW_NEW_FENCE;
}
static void brw_note_unlock( struct intel_context *intel )
{
struct brw_context *brw = brw_context(&intel->ctx);
brw_pool_check_wrap(brw, &brw->pool[BRW_GS_POOL]);
brw_pool_check_wrap(brw, &brw->pool[BRW_SS_POOL]);
brw_context(&intel->ctx)->state.dirty.brw |= BRW_NEW_LOCK;
}
void brw_do_flush( struct brw_context *brw,
unsigned flags )
{
struct brw_mi_flush flush;
memset(&flush, 0, sizeof(flush));
flush.opcode = CMD_MI_FLUSH;
flush.flags = flags;
BRW_BATCH_STRUCT(brw, &flush);
}
static void brw_emit_flush( struct intel_context *intel,
unsigned unused )
{
brw_do_flush(brw_context(&intel->ctx),
BRW_FLUSH_STATE_CACHE|BRW_FLUSH_READ_CACHE);
}
/* called from intelWaitForIdle() and intelFlush()
*
* For now, just flush everything. Could be smarter later.
*/
static unsigned brw_flush_cmd( void )
{
struct brw_mi_flush flush;
flush.opcode = CMD_MI_FLUSH;
flush.pad = 0;
flush.flags = BRW_FLUSH_READ_CACHE | BRW_FLUSH_STATE_CACHE;
return *(unsigned *)&flush;
}
static void brw_invalidate_state( struct intel_context *intel, unsigned new_state )
{
/* nothing */
}
#endif
+9
View File
@@ -95,6 +95,8 @@ enum brw_cache_id {
BRW_MAX_CACHE
};
#define BRW_CONSTANT_BUFFER BRW_MAX_CACHE
/**
* Additional winsys interface for i965simple.
*
@@ -164,6 +166,13 @@ struct brw_winsys {
unsigned data_type);
/* A cheat so we don't have to think about relocations in a couple
* of places yet:
*/
unsigned (*get_buffer_offset)( struct brw_winsys *sws,
struct pipe_buffer_handle *buf,
unsigned flags );
};
#define BRW_BUFFER_ACCESS_WRITE 0x1
+21 -146
View File
@@ -33,153 +33,34 @@
#include "brw_context.h"
#include "brw_util.h"
#include "brw_wm.h"
#include "brw_eu.h"
#include "brw_state.h"
#include "pipe/p_util.h"
unsigned brw_wm_nr_args( unsigned opcode )
{
switch (opcode) {
case WM_PIXELXY:
case TGSI_OPCODE_ABS:
case TGSI_OPCODE_FLR:
case TGSI_OPCODE_FRC:
case TGSI_OPCODE_MOV:
case TGSI_OPCODE_COS:
case TGSI_OPCODE_EX2:
case TGSI_OPCODE_LG2:
case TGSI_OPCODE_RCP:
case TGSI_OPCODE_RSQ:
case TGSI_OPCODE_SIN:
case TGSI_OPCODE_SCS:
case TGSI_OPCODE_TEX:
case TGSI_OPCODE_TXB:
case TGSI_OPCODE_TXD:
case TGSI_OPCODE_KIL:
case TGSI_OPCODE_LIT:
case WM_CINTERP:
case WM_WPOSXY:
return 1;
case TGSI_OPCODE_POW:
case TGSI_OPCODE_SUB:
case TGSI_OPCODE_SGE:
case TGSI_OPCODE_SGT:
case TGSI_OPCODE_SLE:
case TGSI_OPCODE_SLT:
case TGSI_OPCODE_SEQ:
case TGSI_OPCODE_SNE:
case TGSI_OPCODE_ADD:
case TGSI_OPCODE_MAX:
case TGSI_OPCODE_MIN:
case TGSI_OPCODE_MUL:
case TGSI_OPCODE_XPD:
case TGSI_OPCODE_DP3:
case TGSI_OPCODE_DP4:
case TGSI_OPCODE_DPH:
case TGSI_OPCODE_DST:
case WM_LINTERP:
case WM_DELTAXY:
case WM_PIXELW:
return 2;
case WM_FB_WRITE:
case WM_PINTERP:
case TGSI_OPCODE_MAD:
case TGSI_OPCODE_CMP:
case TGSI_OPCODE_LRP:
return 3;
default:
return 0;
}
}
unsigned brw_wm_is_scalar_result( unsigned opcode )
{
switch (opcode) {
case TGSI_OPCODE_COS:
case TGSI_OPCODE_EX2:
case TGSI_OPCODE_LG2:
case TGSI_OPCODE_POW:
case TGSI_OPCODE_RCP:
case TGSI_OPCODE_RSQ:
case TGSI_OPCODE_SIN:
case TGSI_OPCODE_DP3:
case TGSI_OPCODE_DP4:
case TGSI_OPCODE_DPH:
case TGSI_OPCODE_DST:
return 1;
default:
return 0;
}
}
static void do_wm_prog( struct brw_context *brw,
struct brw_fragment_program *fp,
struct brw_wm_prog_key *key)
{
struct brw_wm_compile *c;
struct brw_wm_compile *c = CALLOC_STRUCT(brw_wm_compile);
const unsigned *program;
unsigned program_size;
c = brw->wm.compile_data;
if (c == NULL) {
brw->wm.compile_data = calloc(1, sizeof(*brw->wm.compile_data));
c = brw->wm.compile_data;
} else {
memset(c, 0, sizeof(*brw->wm.compile_data));
}
memcpy(&c->key, key, sizeof(*key));
c->key = *key;
c->fp = fp;
c->delta_xy[0] = brw_null_reg();
c->delta_xy[1] = brw_null_reg();
c->pixel_xy[0] = brw_null_reg();
c->pixel_xy[1] = brw_null_reg();
c->pixel_w = brw_null_reg();
fprintf(stderr, "XXXXXXXX FP\n");
#if 0
c->env_param = brw->intel.ctx.FragmentProgram.Parameters;
brw_wm_glsl_emit(c);
if (brw_wm_is_glsl(&c->fp->program)) {
brw_wm_glsl_emit(c);
} else
{
/* Augment fragment program. Add instructions for pre- and
* post-fragment-program tasks such as interpolation and fogging.
*/
brw_wm_pass_fp(c);
/* Translate to intermediate representation. Build register usage
* chains.
*/
brw_wm_pass0(c);
/* Dead code removal.
*/
brw_wm_pass1(c);
/* Register allocation.
*/
c->grf_limit = BRW_WM_MAX_GRF/2;
/* This is where we start emitting gen4 code:
*/
brw_init_compile(&c->func);
brw_wm_pass2(c);
c->prog_data.total_grf = c->max_wm_grf;
if (c->last_scratch) {
c->prog_data.total_scratch =
c->last_scratch + 0x40;
} else {
c->prog_data.total_scratch = 0;
}
/* Emit GEN4 code.
*/
brw_wm_emit(c);
}
/* get the program
*/
program = brw_get_program(&c->func, &program_size);
@@ -193,7 +74,8 @@ static void do_wm_prog( struct brw_context *brw,
program_size,
&c->prog_data,
&brw->wm.prog_data );
#endif
FREE(c);
}
@@ -206,8 +88,7 @@ static void brw_wm_populate_key( struct brw_context *brw,
(struct brw_fragment_program *)brw->attribs.FragmentProgram;
unsigned lookup = 0;
unsigned line_aa;
unsigned i;
memset(key, 0, sizeof(*key));
/* Build the index for table lookup
@@ -274,14 +155,10 @@ static void brw_wm_populate_key( struct brw_context *brw,
#if 0
/* BRW_NEW_WM_INPUT_DIMENSIONS */
key->projtex_mask = brw->wm.input_size_masks[4-1] >> (FRAG_ATTRIB_TEX0 - FRAG_ATTRIB_WPOS);
#endif
/* _NEW_LIGHT */
key->flat_shade = (brw->attribs.Raster->flatshade);
/* _NEW_TEXTURE */
/* BRW_NEW_SAMPLER
*
* Not doing any of this at the moment:
*/
for (i = 0; i < BRW_MAX_TEX_UNIT; i++) {
const struct pipe_sampler_state *unit = brw->attribs.Samplers[i];
@@ -291,12 +168,11 @@ static void brw_wm_populate_key( struct brw_context *brw,
unit->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
key->shadowtex_mask |= 1<<i;
}
#if 0
if (t->Image[0][t->BaseLevel]->InternalFormat == GL_YCBCR_MESA)
key->yuvtex_mask |= 1<<i;
#endif
}
}
#endif
/* Extra info:
@@ -329,7 +205,6 @@ static void brw_upload_wm_prog( struct brw_context *brw )
const struct brw_tracked_state brw_wm_prog = {
.dirty = {
.brw = (BRW_NEW_FS |
BRW_NEW_WM_INPUT_DIMENSIONS |
BRW_NEW_REDUCED_PRIMITIVE),
.cache = 0
},
+33 -165
View File
@@ -60,87 +60,20 @@ struct brw_wm_prog_key {
unsigned aa_dest_stencil_reg:3;
unsigned dest_depth_reg:3;
unsigned nr_depth_regs:3;
unsigned projtex_mask:8;
unsigned shadowtex_mask:8;
unsigned computes_depth:1; /* could be derived from program string */
unsigned source_depth_to_render_target:1;
unsigned flat_shade:1;
unsigned runtime_check_aads_emit:1;
unsigned yuvtex_mask:8;
unsigned pad1:24;
unsigned program_string_id:32;
unsigned program_string_id;
};
/* A bit of a glossary:
*
* brw_wm_value: A computed value or program input. Values are
* constant, they are created once and are never modified. When a
* fragment program register is written or overwritten, new values are
* created fresh, preserving the rule that values are constant.
*
* brw_wm_ref: A reference to a value. Wherever a value used is by an
* instruction or as a program output, that is tracked with an
* instance of this struct. All references to a value occur after it
* is created. After the last reference, a value is dead and can be
* discarded.
*
* brw_wm_grf: Represents a physical hardware register. May be either
* empty or hold a value. Register allocation is the process of
* assigning values to grf registers. This occurs in pass2 and the
* brw_wm_grf struct is not used before that.
*
* Fragment program registers: These are time-varying constructs that
* are hard to reason about and which we translate away in pass0. A
* single fragment program register element (eg. temp[0].x) will be
* translated to one or more brw_wm_value structs, one for each time
* that temp[0].x is written to during the program.
*/
/* Used in pass2 to track register allocation.
*/
struct brw_wm_grf {
struct brw_wm_value *value;
unsigned nextuse;
};
struct brw_wm_value {
struct brw_reg hw_reg; /* emitted to this reg, may not always be there */
struct brw_wm_ref *lastuse;
struct brw_wm_grf *resident;
unsigned contributes_to_output:1;
unsigned spill_slot:16; /* if non-zero, spill immediately after calculation */
};
struct brw_wm_ref {
struct brw_reg hw_reg; /* nr filled in in pass2, everything else, pass0 */
struct brw_wm_value *value;
struct brw_wm_ref *prevuse;
unsigned unspill_reg:7; /* unspill to reg */
unsigned emitted:1;
unsigned insn:24;
};
struct brw_wm_constref {
const struct brw_wm_ref *ref;
float constval;
};
struct brw_wm_instruction {
struct brw_wm_value *dst[4];
struct brw_wm_ref *src[3][4];
unsigned opcode:8;
unsigned saturate:1;
unsigned writemask:4;
unsigned tex_unit:4; /* texture unit for TEX, TXD, TXP instructions */
unsigned tex_idx:3; /* TEXTURE_1D,2D,3D,CUBE,RECT_INDEX source target */
};
#define PROGRAM_INTERNAL_PARAM
#define MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS 1024 /* 72 for GL_ARB_f_p */
#define BRW_WM_MAX_INSN (MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS*3 + PIPE_ATTRIB_MAX + 3)
@@ -151,124 +84,59 @@ struct brw_wm_instruction {
#define BRW_WM_MAX_CONST 256
#define BRW_WM_MAX_KILLS MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS
/* New opcodes to track internal operations required for WM unit.
* These are added early so that the registers used can be tracked,
* freed and reused like those of other instructions.
*/
#define WM_PIXELXY (TGSI_OPCODE_LAST)
#define WM_DELTAXY (TGSI_OPCODE_LAST + 1)
#define WM_PIXELW (TGSI_OPCODE_LAST + 2)
#define WM_LINTERP (TGSI_OPCODE_LAST + 3)
#define WM_PINTERP (TGSI_OPCODE_LAST + 4)
#define WM_CINTERP (TGSI_OPCODE_LAST + 5)
#define WM_WPOSXY (TGSI_OPCODE_LAST + 6)
#define WM_FB_WRITE (TGSI_OPCODE_LAST + 7)
#define MAX_WM_OPCODE (TGSI_OPCODE_LAST + 8)
#define PAYLOAD_DEPTH (PIPE_ATTRIB_MAX)
#define MAX_IFSN 32
#define MAX_LOOP_DEPTH 32
struct brw_wm_compile {
struct brw_compile func;
struct brw_wm_prog_key key;
struct brw_wm_prog_data prog_data;
struct brw_wm_prog_data prog_data; /* result */
struct brw_fragment_program *fp;
float (*env_param)[4];
enum {
START,
PASS2_DONE
} state;
/* Initial pass - translate fp instructions to fp instructions,
* simplifying and adding instructions for interpolation and
* framebuffer writes.
*/
const struct pipe_shader_state *prog_instructions;
unsigned nr_fp_insns;
unsigned fp_temp;
unsigned fp_interp_emitted;
unsigned fp_deriv_emitted;
struct tgsi_src_register pixel_xy;
struct tgsi_src_register delta_xy;
struct tgsi_src_register pixel_w;
struct brw_wm_value vreg[BRW_WM_MAX_VREG];
unsigned nr_vreg;
struct brw_wm_value creg[BRW_WM_MAX_PARAM];
unsigned nr_creg;
struct {
struct brw_wm_value depth[4]; /* includes r0/r1 */
struct brw_wm_value input_interp[PIPE_ATTRIB_MAX];
} payload;
const struct brw_wm_ref *pass0_fp_reg[16][256][4];
struct brw_wm_ref undef_ref;
struct brw_wm_value undef_value;
struct brw_wm_ref refs[BRW_WM_MAX_REF];
unsigned nr_refs;
struct brw_wm_instruction instruction[BRW_WM_MAX_INSN];
unsigned nr_insns;
struct brw_wm_constref constref[BRW_WM_MAX_CONST];
unsigned nr_constrefs;
struct brw_wm_grf pass2_grf[BRW_WM_MAX_GRF/2];
unsigned grf_limit;
unsigned max_wm_grf;
unsigned last_scratch;
struct {
boolean inited;
struct brw_reg reg;
} wm_regs[16][256][4];
struct brw_reg stack;
struct brw_reg pixel_xy[2];
struct brw_reg delta_xy[2];
struct brw_reg pixel_w;
struct brw_reg wm_regs[8][32][4];
struct brw_reg payload_depth[4];
struct brw_reg payload_coef[16];
struct brw_reg emit_mask_reg;
struct brw_instruction *if_inst[MAX_IFSN];
int if_insn;
struct brw_instruction *loop_inst[MAX_LOOP_DEPTH];
int loop_insn;
struct brw_instruction *inst0;
struct brw_instruction *inst1;
struct brw_reg stack;
struct brw_indirect stack_index;
unsigned reg_index;
unsigned tmp_start;
unsigned tmp_index;
};
unsigned brw_wm_nr_args( unsigned opcode );
unsigned brw_wm_is_scalar_result( unsigned opcode );
void brw_wm_pass_fp( struct brw_wm_compile *c );
void brw_wm_pass0( struct brw_wm_compile *c );
void brw_wm_pass1( struct brw_wm_compile *c );
void brw_wm_pass2( struct brw_wm_compile *c );
void brw_wm_emit( struct brw_wm_compile *c );
void brw_wm_print_value( struct brw_wm_compile *c,
struct brw_wm_value *value );
void brw_wm_print_ref( struct brw_wm_compile *c,
struct brw_wm_ref *ref );
void brw_wm_print_insn( struct brw_wm_compile *c,
struct brw_wm_instruction *inst );
void brw_wm_print_program( struct brw_wm_compile *c,
const char *stage );
void brw_wm_lookup_iz( unsigned line_aa,
unsigned lookup,
struct brw_wm_prog_key *key );
#if 0
boolean brw_wm_is_glsl(struct gl_fragment_program *fp);
void brw_wm_glsl_emit(struct brw_wm_compile *c);
#endif
void brw_wm_emit_decls(struct brw_wm_compile *c);
#endif
+377
View File
@@ -0,0 +1,377 @@
#include "brw_context.h"
#include "brw_eu.h"
#include "brw_wm.h"
#include "pipe/p_util.h"
#include "pipe/p_shader_tokens.h"
#include "pipe/tgsi/util/tgsi_parse.h"
static struct brw_reg alloc_tmp(struct brw_wm_compile *c)
{
c->tmp_index++;
c->reg_index = MAX2(c->reg_index, c->tmp_index);
return brw_vec8_grf(c->tmp_start + c->tmp_index, 0);
}
static void release_tmps(struct brw_wm_compile *c)
{
c->tmp_index = 0;
}
static int is_null( struct brw_reg reg )
{
return (reg.file == BRW_ARCHITECTURE_REGISTER_FILE &&
reg.nr == BRW_ARF_NULL);
}
static void emit_pixel_xy( struct brw_wm_compile *c )
{
if (is_null(c->pixel_xy[0])) {
struct brw_compile *p = &c->func;
struct brw_reg r1_uw = retype(brw_vec1_grf(1, 0), BRW_REGISTER_TYPE_UW);
c->pixel_xy[0] = vec8(retype(alloc_tmp(c), BRW_REGISTER_TYPE_UW));
c->pixel_xy[1] = vec8(retype(alloc_tmp(c), BRW_REGISTER_TYPE_UW));
/* Calculate pixel centers by adding 1 or 0 to each of the
* micro-tile coordinates passed in r1.
*/
brw_ADD(p,
c->pixel_xy[0],
stride(suboffset(r1_uw, 4), 2, 4, 0),
brw_imm_v(0x10101010));
brw_ADD(p,
c->pixel_xy[1],
stride(suboffset(r1_uw, 5), 2, 4, 0),
brw_imm_v(0x11001100));
}
}
static void emit_delta_xy( struct brw_wm_compile *c )
{
if (is_null(c->delta_xy[0])) {
struct brw_compile *p = &c->func;
struct brw_reg r1 = brw_vec1_grf(1, 0);
emit_pixel_xy(c);
c->delta_xy[0] = alloc_tmp(c);
c->delta_xy[1] = alloc_tmp(c);
/* Calc delta X,Y by subtracting origin in r1 from the pixel
* centers.
*/
brw_ADD(p,
c->delta_xy[0],
retype(c->pixel_xy[0], BRW_REGISTER_TYPE_UW),
negate(r1));
brw_ADD(p,
c->delta_xy[1],
retype(c->pixel_xy[1], BRW_REGISTER_TYPE_UW),
negate(suboffset(r1,1)));
}
}
#if 0
static void emit_pixel_w( struct brw_wm_compile *c )
{
if (is_null(c->pixel_w)) {
struct brw_compile *p = &c->func;
struct brw_reg interp_wpos = c->coef_wpos;
c->pixel_w = alloc_tmp(c);
emit_delta_xy(c);
/* Calc 1/w - just linterp wpos[3] optimized by putting the
* result straight into a message reg.
*/
struct brw_reg interp3 = brw_vec1_grf(interp_wpos.nr+1, 4);
brw_LINE(p, brw_null_reg(), interp3, c->delta_xy[0]);
brw_MAC(p, brw_message_reg(2), suboffset(interp3, 1), c->delta_xy[1]);
/* Calc w */
brw_math_16( p,
c->pixel_w,
BRW_MATH_FUNCTION_INV,
BRW_MATH_SATURATE_NONE,
2,
brw_null_reg(),
BRW_MATH_PRECISION_FULL);
}
}
#endif
static void emit_cinterp(struct brw_wm_compile *c,
int idx,
int mask )
{
struct brw_compile *p = &c->func;
struct brw_reg interp[4];
struct brw_reg coef = c->payload_coef[idx];
int i;
interp[0] = brw_vec1_grf(coef.nr, 0);
interp[1] = brw_vec1_grf(coef.nr, 4);
interp[2] = brw_vec1_grf(coef.nr+1, 0);
interp[3] = brw_vec1_grf(coef.nr+1, 4);
for(i = 0; i < 4; i++ ) {
if (mask & (1<<i)) {
struct brw_reg dst = c->wm_regs[TGSI_FILE_INPUT][idx][i];
brw_MOV(p, dst, suboffset(interp[i],3));
}
}
}
static void emit_linterp(struct brw_wm_compile *c,
int idx,
int mask )
{
struct brw_compile *p = &c->func;
struct brw_reg interp[4];
struct brw_reg coef = c->payload_coef[idx];
int i;
emit_delta_xy(c);
interp[0] = brw_vec1_grf(coef.nr, 0);
interp[1] = brw_vec1_grf(coef.nr, 4);
interp[2] = brw_vec1_grf(coef.nr+1, 0);
interp[3] = brw_vec1_grf(coef.nr+1, 4);
for(i = 0; i < 4; i++ ) {
if (mask & (1<<i)) {
struct brw_reg dst = c->wm_regs[TGSI_FILE_INPUT][idx][i];
brw_LINE(p, brw_null_reg(), interp[i], c->delta_xy[0]);
brw_MAC(p, dst, suboffset(interp[i],1), c->delta_xy[1]);
}
}
}
#if 0
static void emit_pinterp(struct brw_wm_compile *c,
int idx,
int mask )
{
struct brw_compile *p = &c->func;
struct brw_reg interp[4];
struct brw_reg coef = c->payload_coef[idx];
int i;
get_delta_xy(c);
get_pixel_w(c);
interp[0] = brw_vec1_grf(coef.nr, 0);
interp[1] = brw_vec1_grf(coef.nr, 4);
interp[2] = brw_vec1_grf(coef.nr+1, 0);
interp[3] = brw_vec1_grf(coef.nr+1, 4);
for(i = 0; i < 4; i++ ) {
if (mask & (1<<i)) {
struct brw_reg dst = allocate_reg(c, TGSI_FILE_INPUT, idx, i);
brw_LINE(p, brw_null_reg(), interp[i], c->delta_xy[0]);
brw_MAC(p, dst, suboffset(interp[i],1), c->delta_xy[1]);
brw_MUL(p, dst, dst, c->pixel_w);
}
}
}
#endif
#if 0
static void emit_wpos( )
{
struct prog_dst_register dst = dst_reg(PROGRAM_INPUT, idx);
struct tgsi_full_src_register interp = src_reg(PROGRAM_PAYLOAD, idx);
struct tgsi_full_src_register deltas = get_delta_xy(c);
struct tgsi_full_src_register arg2;
unsigned opcode;
opcode = WM_LINTERP;
arg2 = src_undef();
/* Have to treat wpos.xy specially:
*/
emit_op(c,
WM_WPOSXY,
dst_mask(dst, WRITEMASK_XY),
0, 0, 0,
get_pixel_xy(c),
src_undef(),
src_undef());
dst = dst_mask(dst, WRITEMASK_ZW);
/* PROGRAM_INPUT.attr.xyzw = INTERP payload.interp[attr].x, deltas.xyw
*/
emit_op(c,
WM_LINTERP,
dst,
0, 0, 0,
interp,
deltas,
arg2);
}
#endif
/* Perform register allocation:
*
* -- r0???
* -- passthrough depth regs (and stencil/aa??)
* -- curbe ??
* -- inputs (coefficients)
*
* Use a totally static register allocation. This will perform poorly
* but is an easy way to get started (again).
*/
static void prealloc_reg(struct brw_wm_compile *c)
{
int i, j;
int nr_curbe_regs = 0;
/* R0, then some depth related regs:
*/
for (i = 0; i < c->key.nr_depth_regs; i++) {
c->payload_depth[i] = brw_vec8_grf(i*2, 0);
c->reg_index += 2;
}
/* Then a copy of our part of the CURBE entry:
*/
{
int nr_constants = c->fp->info.nr_regs[TGSI_FILE_CONSTANT];
int index = 0;
c->prog_data.max_const = 4*nr_constants;
for (i = 0; i < nr_constants; i++) {
for (j = 0; j < 4; j++, index++)
c->wm_regs[TGSI_FILE_CONSTANT][i][j] = brw_vec1_grf(c->reg_index + index/8,
index%8);
}
nr_curbe_regs = 2*((4*nr_constants+15)/16);
c->reg_index += nr_curbe_regs;
}
/* Next we receive the plane coefficients for parameter
* interpolation:
*/
for (i = 0; i < c->fp->info.nr_regs[TGSI_FILE_INPUT]; i++) {
c->payload_coef[i] = brw_vec8_grf(c->reg_index, 0);
c->reg_index += 2;
}
c->prog_data.first_curbe_grf = c->key.nr_depth_regs * 2;
c->prog_data.urb_read_length = c->fp->program.num_inputs * 2;
c->prog_data.curb_read_length = nr_curbe_regs;
/* That's the end of the payload, now we can start allocating registers.
*/
c->emit_mask_reg = brw_uw1_reg(BRW_GENERAL_REGISTER_FILE, c->reg_index, 0);
c->reg_index++;
c->stack = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, c->reg_index, 0);
c->reg_index += 2;
/* Now allocate room for the interpolated inputs and staging
* registers for the outputs:
*/
for (i = 0; i < c->fp->info.nr_regs[TGSI_FILE_INPUT]; i++)
for (j = 0; j < 4; j++)
c->wm_regs[TGSI_FILE_INPUT][i][j] = brw_vec8_grf( c->reg_index++, 0 );
for (i = 0; i < c->fp->info.nr_regs[TGSI_FILE_OUTPUT]; i++)
for (j = 0; j < 4; j++)
c->wm_regs[TGSI_FILE_OUTPUT][i][j] = brw_vec8_grf( c->reg_index++, 0 );
/* Beyond this we should only need registers for internal temporaries:
*/
c->tmp_start = c->reg_index;
}
/* Need to interpolate fragment program inputs in as a preamble to the
* shader. A more sophisticated compiler would do this on demand, but
* we'll do it up front:
*/
void brw_wm_emit_decls(struct brw_wm_compile *c)
{
struct tgsi_parse_context parse;
int done = 0;
prealloc_reg(c);
tgsi_parse_init( &parse, c->fp->program.tokens );
while( !done &&
!tgsi_parse_end_of_tokens( &parse ) )
{
tgsi_parse_token( &parse );
switch( parse.FullToken.Token.Type ) {
case TGSI_TOKEN_TYPE_DECLARATION:
{
const struct tgsi_full_declaration *decl = &parse.FullToken.FullDeclaration;
unsigned first = decl->u.DeclarationRange.First;
unsigned last = decl->u.DeclarationRange.Last;
unsigned mask = decl->Declaration.UsageMask; /* ? */
unsigned i;
if (decl->Declaration.File != TGSI_FILE_INPUT)
break;
assert(decl->Declaration.Interpolate);
for( i = first; i <= last; i++ ) {
switch (decl->Interpolation.Interpolate) {
case TGSI_INTERPOLATE_CONSTANT:
emit_cinterp(c, i, mask);
break;
case TGSI_INTERPOLATE_LINEAR:
emit_linterp(c, i, mask);
break;
case TGSI_INTERPOLATE_PERSPECTIVE:
//emit_pinterp(c, i, mask);
emit_linterp(c, i, mask);
break;
}
}
break;
}
case TGSI_TOKEN_TYPE_IMMEDIATE:
case TGSI_TOKEN_TYPE_INSTRUCTION:
default:
done = 1;
break;
}
}
tgsi_parse_free (&parse);
release_tmps(c);
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -229,12 +229,12 @@ static void brw_update_sampler_state( const struct pipe_sampler_state *pipe_samp
* complicates various things. However, this is still too confusing -
* FIXME: simplify all the different new texture state flags.
*/
void brw_upload_wm_samplers(struct brw_context *brw)
static void upload_wm_samplers(struct brw_context *brw)
{
unsigned unit;
unsigned sampler_count = 0;
/* _NEW_TEXTURE */
/* BRW_NEW_SAMPLER */
for (unit = 0; unit < BRW_MAX_TEX_UNIT; unit++) {
if (brw->attribs.Samplers[unit]) { /* FIXME: correctly detect enabled ones */
const struct pipe_sampler_state *sampler = brw->attribs.Samplers[unit];
@@ -262,14 +262,11 @@ void brw_upload_wm_samplers(struct brw_context *brw)
sizeof(struct brw_sampler_state) * brw->wm.sampler_count);
}
#if 0
const struct brw_tracked_state brw_wm_samplers = {
.dirty = {
.mesa = _NEW_TEXTURE,
.brw = 0,
.brw = BRW_NEW_SAMPLER,
.cache = 0
},
.update = upload_wm_samplers
};
#endif
+21 -29
View File
@@ -34,15 +34,13 @@
#include "brw_state.h"
#include "brw_defines.h"
#include "brw_wm.h"
#include "pipe/p_util.h"
/***********************************************************************
* WM unit - fragment programs and rasterization
*/
#if 0
static void upload_wm_unit(struct brw_context *brw )
{
struct intel_context *intel = &brw->intel;
struct brw_wm_unit_state wm;
unsigned max_threads;
unsigned per_thread;
@@ -56,7 +54,7 @@ static void upload_wm_unit(struct brw_context *brw )
memset(&wm, 0, sizeof(wm));
/* CACHE_NEW_WM_PROG */
wm.thread0.grf_reg_count = ALIGN(brw->wm.prog_data->total_grf, 16) / 16 - 1;
wm.thread0.grf_reg_count = align(brw->wm.prog_data->total_grf, 16) / 16 - 1;
wm.thread0.kernel_start_pointer = brw->wm.prog_gs_offset >> 6;
wm.thread3.dispatch_grf_start_reg = brw->wm.prog_data->first_curbe_grf;
wm.thread3.urb_entry_read_length = brw->wm.prog_data->urb_read_length;
@@ -64,9 +62,10 @@ static void upload_wm_unit(struct brw_context *brw )
wm.wm5.max_threads = max_threads;
per_thread = ALIGN(brw->wm.prog_data->total_scratch, 1024);
per_thread = align(brw->wm.prog_data->total_scratch, 1024);
assert(per_thread <= 12 * 1024);
#if 0
if (brw->wm.prog_data->total_scratch) {
unsigned total = per_thread * (max_threads + 1);
@@ -95,6 +94,7 @@ static void upload_wm_unit(struct brw_context *brw )
* so just fail for now if we hit that path.
*/
assert(brw->wm.prog_data->total_scratch == 0);
#endif
/* CACHE_NEW_SURFACE */
wm.thread1.binding_table_entry_count = brw->wm.nr_surfaces;
@@ -112,23 +112,20 @@ static void upload_wm_unit(struct brw_context *brw )
/* BRW_NEW_FRAGMENT_PROGRAM */
{
const struct gl_fragment_program *fp = brw->fragment_program;
const struct brw_fragment_program *fp = brw->attribs.FragmentProgram;
if (fp->Base.InputsRead & (1<<FRAG_ATTRIB_WPOS))
if (fp->UsesDepth)
wm.wm5.program_uses_depth = 1; /* as far as we can tell */
if (fp->Base.OutputsWritten & (1<<FRAG_RESULT_DEPR))
if (fp->ComputesDepth)
wm.wm5.program_computes_depth = 1;
/* _NEW_COLOR */
/* BRW_NEW_ALPHA_TEST */
if (fp->UsesKill ||
brw->attribs.Color->AlphaEnabled)
brw->attribs.AlphaTest->enabled)
wm.wm5.program_uses_killpixel = 1;
if (brw_wm_is_glsl(fp))
wm.wm5.enable_8_pix = 1;
else
wm.wm5.enable_16_pix = 1;
wm.wm5.enable_8_pix = 1;
}
wm.wm5.thread_dispatch_enable = 1; /* AKA: color_write */
@@ -138,11 +135,11 @@ static void upload_wm_unit(struct brw_context *brw )
wm.wm5.line_aa_region_width = 0;
wm.wm5.line_endcap_aa_region_width = 1;
/* _NEW_POLYGONSTIPPLE */
if (brw->attribs.Polygon->StippleFlag)
/* BRW_NEW_RASTERIZER */
if (brw->attribs.Raster->poly_stipple_enable)
wm.wm5.polygon_stipple = 1;
/* _NEW_POLYGON */
#if 0
if (brw->attribs.Polygon->OffsetFill) {
wm.wm5.depth_offset = 1;
/* Something wierd going on with legacy_global_depth_bias,
@@ -156,13 +153,13 @@ static void upload_wm_unit(struct brw_context *brw )
*/
wm.global_depth_offset_scale = brw->attribs.Polygon->OffsetFactor;
}
#endif
/* _NEW_LINE */
if (brw->attribs.Line->StippleFlag) {
if (brw->attribs.Raster->line_stipple_enable) {
wm.wm5.line_stipple = 1;
}
if (BRW_DEBUG & DEBUG_STATS || intel->stats_wm)
if (BRW_DEBUG & DEBUG_STATS)
wm.wm4.stats_enable = 1;
brw->wm.state_gs_offset = brw_cache_data( &brw->cache[BRW_WM_UNIT], &wm );
@@ -183,14 +180,10 @@ static void upload_wm_unit(struct brw_context *brw )
const struct brw_tracked_state brw_wm_unit = {
.dirty = {
.mesa = (_NEW_POLYGON |
_NEW_POLYGONSTIPPLE |
_NEW_LINE |
_NEW_COLOR),
.brw = (BRW_NEW_FRAGMENT_PROGRAM |
BRW_NEW_CURBE_OFFSETS |
BRW_NEW_LOCK),
.brw = (BRW_NEW_RASTERIZER |
BRW_NEW_ALPHA_TEST |
BRW_NEW_FS |
BRW_NEW_CURBE_OFFSETS),
.cache = (CACHE_NEW_SURFACE |
CACHE_NEW_WM_PROG |
@@ -199,4 +192,3 @@ const struct brw_tracked_state brw_wm_unit = {
.update = upload_wm_unit
};
#endif
+53 -48
View File
@@ -33,8 +33,6 @@
#include "brw_state.h"
#include "brw_defines.h"
#if 0
static unsigned translate_tex_target( int target )
{
switch (target) {
@@ -75,13 +73,13 @@ static unsigned translate_tex_format( unsigned mesa_format )
assert(0); /* not supported for sampling */
return BRW_SURFACEFORMAT_R8G8B8_UNORM;
case PIPE_FORMAT_U_A8_R8_G8_B8:
case PIPE_FORMAT_B8G8R8A8_UNORM:
return BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
case PIPE_FORMAT_RGBA8888_REV:
case PIPE_FORMAT_R8G8B8A8_UNORM:
return BRW_SURFACEFORMAT_R8G8B8A8_UNORM;
case PIPE_FORMAT_U_R5_G6_B5:
case PIPE_FORMAT_R5G6B5_UNORM:
return BRW_SURFACEFORMAT_B5G6R5_UNORM;
case PIPE_FORMAT_A1R5G5B5_UNORM:
@@ -95,14 +93,15 @@ static unsigned translate_tex_format( unsigned mesa_format )
case PIPE_FORMAT_YCBCR:
return BRW_SURFACEFORMAT_YCRCB_SWAPUVY;
#if 0
case PIPE_FORMAT_RGB_FXT1:
case PIPE_FORMAT_RGBA_FXT1:
return BRW_SURFACEFORMAT_FXT1;
#endif
case PIPE_FORMAT_Z16_UNORM:
return BRW_SURFACEFORMAT_I16_UNORM;
#if 0
case PIPE_FORMAT_RGB_DXT1:
return BRW_SURFACEFORMAT_DXT1_RGB;
@@ -119,6 +118,7 @@ static unsigned translate_tex_format( unsigned mesa_format )
return BRW_SURFACEFORMAT_R8G8B8A8_UNORM_SRGB;
case PIPE_FORMAT_SRGB_DXT1:
return BRW_SURFACEFORMAT_BC1_UNORM_SRGB;
#endif
default:
assert(0);
@@ -126,41 +126,46 @@ static unsigned translate_tex_format( unsigned mesa_format )
}
}
static unsigned brw_buffer_offset(struct brw_context *brw,
struct pipe_buffer_handle *buffer)
{
return brw->winsys->get_buffer_offset(brw->winsys,
buffer,
0);
}
static
void brw_update_texture_surface( GLcontext *ctx,
void brw_update_texture_surface( struct brw_context *brw,
unsigned unit )
{
struct brw_context *brw = brw_context(ctx);
struct gl_texture_object *tObj = brw->attribs.Texture->Unit[unit]._Current;
struct intel_texture_object *intelObj = intel_texture_object(tObj);
struct gl_texture_image *firstImage = tObj->Image[0][intelObj->firstLevel];
const struct brw_texture *tObj = brw->attribs.Texture[unit];
struct brw_surface_state surf;
memset(&surf, 0, sizeof(surf));
surf.ss0.mipmap_layout_mode = BRW_SURFACE_MIPMAPLAYOUT_BELOW;
surf.ss0.surface_type = translate_tex_target(tObj->Target);
surf.ss0.surface_format = translate_tex_format(firstImage->TexFormat->MesaFormat);
surf.ss0.surface_type = translate_tex_target(tObj->base.target);
surf.ss0.surface_format = translate_tex_format(tObj->base.format);
/* This is ok for all textures with channel width 8bit or less:
*/
/* surf.ss0.data_return_format = BRW_SURFACERETURNFORMAT_S1; */
/* Updated in emit_reloc */
surf.ss1.base_addr = brw_buffer_offset( intelObj->mt->region->buffer );
surf.ss1.base_addr = brw_buffer_offset( brw, tObj->buffer );
surf.ss2.mip_count = intelObj->lastLevel - intelObj->firstLevel;
surf.ss2.width = firstImage->Width - 1;
surf.ss2.height = firstImage->Height - 1;
surf.ss2.mip_count = tObj->base.last_level - tObj->base.first_level;
surf.ss2.width = tObj->base.width[0];
surf.ss2.height = tObj->base.height[0];
surf.ss3.tile_walk = BRW_TILEWALK_XMAJOR;
surf.ss3.tiled_surface = intelObj->mt->region->tiled; /* always zero */
surf.ss3.pitch = (intelObj->mt->pitch * intelObj->mt->cpp) - 1;
surf.ss3.depth = firstImage->Depth - 1;
surf.ss3.tiled_surface = 0; /* always zero */
surf.ss3.pitch = tObj->pitch;
surf.ss3.depth = tObj->base.depth[0];
surf.ss4.min_lod = 0;
if (tObj->Target == GL_TEXTURE_CUBE_MAP) {
if (tObj->base.target == PIPE_TEXTURE_CUBE) {
surf.ss0.cube_pos_x = 1;
surf.ss0.cube_pos_y = 1;
surf.ss0.cube_pos_z = 1;
@@ -180,13 +185,14 @@ void brw_update_texture_surface( GLcontext *ctx,
static void upload_wm_surfaces(struct brw_context *brw )
{
GLcontext *ctx = &brw->intel.ctx;
struct intel_context *intel = &brw->intel;
unsigned i;
{
struct brw_surface_state surf;
struct intel_region *region = brw->state.draw_region;
/* BRW_NEW_FRAMEBUFFER
*/
struct pipe_surface *region = brw->attribs.FrameBuffer.cbufs[0];/*fixme*/
memset(&surf, 0, sizeof(surf));
@@ -198,27 +204,27 @@ static void upload_wm_surfaces(struct brw_context *brw )
surf.ss0.surface_type = BRW_SURFACE_2D;
surf.ss1.base_addr = brw_buffer_offset( region->buffer );
surf.ss1.base_addr = brw_buffer_offset( brw, region->buffer );
surf.ss2.width = region->pitch - 1; /* XXX: not really! */
surf.ss2.height = region->height - 1;
surf.ss2.width = region->width;
surf.ss2.height = region->height;
surf.ss3.tile_walk = BRW_TILEWALK_XMAJOR;
surf.ss3.tiled_surface = region->tiled;
surf.ss3.pitch = (region->pitch * region->cpp) - 1;
surf.ss3.tiled_surface = 0;
surf.ss3.pitch = region->pitch;
} else {
surf.ss0.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
surf.ss0.surface_type = BRW_SURFACE_NULL;
}
/* _NEW_COLOR */
surf.ss0.color_blend = (!brw->attribs.Color->_LogicOpEnabled &&
brw->attribs.Color->BlendEnabled);
/* BRW_NEW_BLEND */
surf.ss0.color_blend = (!brw->attribs.Blend->logicop_enable &&
brw->attribs.Blend->blend_enable);
surf.ss0.writedisable_red = !brw->attribs.Color->ColorMask[0];
surf.ss0.writedisable_green = !brw->attribs.Color->ColorMask[1];
surf.ss0.writedisable_blue = !brw->attribs.Color->ColorMask[2];
surf.ss0.writedisable_alpha = !brw->attribs.Color->ColorMask[3];
surf.ss0.writedisable_red = !brw->attribs.BlendColor.color[0];
surf.ss0.writedisable_green = !brw->attribs.BlendColor.color[1];
surf.ss0.writedisable_blue = !brw->attribs.BlendColor.color[2];
surf.ss0.writedisable_alpha = !brw->attribs.BlendColor.color[3];
@@ -230,23 +236,24 @@ static void upload_wm_surfaces(struct brw_context *brw )
for (i = 0; i < BRW_MAX_TEX_UNIT; i++) {
struct gl_texture_unit *texUnit = &brw->attribs.Texture->Unit[i];
const struct brw_texture *texUnit = brw->attribs.Texture[i];
/* _NEW_TEXTURE, BRW_NEW_TEXDATA
/* BRW_NEW_TEXTURE
*/
if (texUnit->_ReallyEnabled &&
intel_finalize_mipmap_tree(intel, i)) {
if (texUnit->base.refcount/*(texUnit->refcount > 0) == really used */) {
brw_update_texture_surface(ctx, i);
brw_update_texture_surface(brw, i);
brw->wm.nr_surfaces = i+2;
}
else if( texUnit->_ReallyEnabled &&
#if 0
else if( texUnit->refcount &&
texUnit->_Current == intel->frame_buffer_texobj )
{
brw->wm.bind.surf_ss_offset[i+1] = brw->wm.bind.surf_ss_offset[0];
brw->wm.nr_surfaces = i+2;
}
#endif
else {
brw->wm.bind.surf_ss_offset[i+1] = 0;
}
@@ -293,14 +300,12 @@ static void emit_reloc_wm_surfaces(struct brw_context *brw)
}
#endif
const struct brw_tracked_state brw_wm_surfaces = {
.dirty = {
.mesa = _NEW_COLOR | _NEW_TEXTURE | _NEW_BUFFERS,
.brw = BRW_NEW_CONTEXT,
.brw = (BRW_NEW_FRAMEBUFFER |
BRW_NEW_BLEND |
BRW_NEW_TEXTURE),
.cache = 0
},
.update = upload_wm_surfaces,
};
#endif
+2
View File
@@ -94,6 +94,7 @@ struct pipe_rasterizer_state
unsigned line_stipple_factor:8; /**< [1..256] actually */
unsigned line_stipple_pattern:16;
unsigned bypass_clipping:1;
unsigned origin_lower_left:1; /**< Is (0,0) the lower-left corner? */
float line_width;
float point_size; /**< used when no per-vertex size */
@@ -139,6 +140,7 @@ struct pipe_shader_state {
const struct tgsi_token *tokens;
ubyte num_inputs;
ubyte num_outputs;
ubyte input_map[PIPE_MAX_SHADER_INPUTS]; /* XXX this may be temporary */
ubyte input_semantic_name[PIPE_MAX_SHADER_INPUTS]; /**< TGSI_SEMANTIC_x */
ubyte input_semantic_index[PIPE_MAX_SHADER_INPUTS];
ubyte output_semantic_name[PIPE_MAX_SHADER_OUTPUTS]; /**< TGSI_SEMANTIC_x */
+5
View File
@@ -360,6 +360,11 @@ static INLINE float LOG2(float val)
#define CEILF(x) ((float) ceil(x))
#endif
static INLINE int align(int value, int alignment)
{
return (value + alignment - 1) & ~(alignment - 1);
}
/* Convenient...
*/
extern void _mesa_printf(const char *str, ...);
-2
View File
@@ -55,8 +55,6 @@ static boolean
softpipe_is_format_supported( struct pipe_context *pipe,
enum pipe_format format, uint type )
{
struct softpipe_context *softpipe = softpipe_context( pipe );
switch (type) {
case PIPE_TEXTURE:
/* softpipe supports all texture formats */
-2
View File
@@ -110,8 +110,6 @@ struct softpipe_context {
struct vertex_info vertex_info;
unsigned attr_mask;
unsigned nr_frag_attrs; /**< number of active fragment attribs */
boolean need_z; /**< produce quad/fragment Z values? */
boolean need_w; /**< produce quad/fragment W values? */
int psize_slot;
#if 0
+1
View File
@@ -73,6 +73,7 @@ struct quad_header {
float coverage[QUAD_SIZE]; /** fragment coverage for antialiasing */
const struct tgsi_interp_coef *coef;
const struct tgsi_interp_coef *posCoef;
unsigned nr_attrs;
};
+224 -121
View File
@@ -36,10 +36,12 @@
#include "sp_context.h"
#include "sp_headers.h"
#include "sp_quad.h"
#include "sp_state.h"
#include "sp_prim_setup.h"
#include "pipe/draw/draw_private.h"
#include "pipe/draw/draw_vertex.h"
#include "pipe/p_util.h"
#include "pipe/p_shader_tokens.h"
#define DEBUG_VERTS 0
@@ -80,8 +82,11 @@ struct setup_stage {
float oneoverarea;
struct tgsi_interp_coef coef[PIPE_MAX_SHADER_INPUTS];
struct tgsi_interp_coef posCoef; /* For Z, W */
struct quad_header quad;
uint firstFpInput; /** Semantic type of first frag input */
struct {
int left[2]; /**< [0] = row0, [1] = row1 */
int right[2];
@@ -365,18 +370,17 @@ static boolean setup_sort_vertices( struct setup_stage *setup,
* \param i which component of the slot (0..3)
*/
static void const_coeff( struct setup_stage *setup,
unsigned slot,
unsigned i )
struct tgsi_interp_coef *coef,
uint vertSlot, uint i)
{
assert(slot < PIPE_MAX_SHADER_INPUTS);
assert(i <= 3);
setup->coef[slot].dadx[i] = 0;
setup->coef[slot].dady[i] = 0;
coef->dadx[i] = 0;
coef->dady[i] = 0;
/* need provoking vertex info!
*/
setup->coef[slot].a0[i] = setup->vprovoke->data[slot][i];
coef->a0[i] = setup->vprovoke->data[vertSlot][i];
}
@@ -385,19 +389,20 @@ static void const_coeff( struct setup_stage *setup,
* for a triangle.
*/
static void tri_linear_coeff( struct setup_stage *setup,
unsigned slot,
unsigned i)
struct tgsi_interp_coef *coef,
uint vertSlot, uint i)
{
float botda = setup->vmid->data[slot][i] - setup->vmin->data[slot][i];
float majda = setup->vmax->data[slot][i] - setup->vmin->data[slot][i];
float botda = setup->vmid->data[vertSlot][i] - setup->vmin->data[vertSlot][i];
float majda = setup->vmax->data[vertSlot][i] - setup->vmin->data[vertSlot][i];
float a = setup->ebot.dy * majda - botda * setup->emaj.dy;
float b = setup->emaj.dx * botda - majda * setup->ebot.dx;
assert(slot < PIPE_MAX_SHADER_INPUTS);
float dadx = a * setup->oneoverarea;
float dady = b * setup->oneoverarea;
assert(i <= 3);
setup->coef[slot].dadx[i] = a * setup->oneoverarea;
setup->coef[slot].dady[i] = b * setup->oneoverarea;
coef->dadx[i] = dadx;
coef->dady[i] = dady;
/* calculate a0 as the value which would be sampled for the
* fragment at (0,0), taking into account that we want to sample at
@@ -411,9 +416,9 @@ static void tri_linear_coeff( struct setup_stage *setup,
* to define a0 as the sample at a pixel center somewhere near vmin
* instead - i'll switch to this later.
*/
setup->coef[slot].a0[i] = (setup->vmin->data[slot][i] -
(setup->coef[slot].dadx[i] * (setup->vmin->data[0][0] - 0.5f) +
setup->coef[slot].dady[i] * (setup->vmin->data[0][1] - 0.5f)));
coef->a0[i] = (setup->vmin->data[vertSlot][i] -
(dadx * (setup->vmin->data[0][0] - 0.5f) +
dady * (setup->vmin->data[0][1] - 0.5f)));
/*
_mesa_printf("attr[%d].%c: %f dx:%f dy:%f\n",
@@ -434,39 +439,76 @@ static void tri_linear_coeff( struct setup_stage *setup,
* divide the interpolated value by the interpolated W at that fragment.
*/
static void tri_persp_coeff( struct setup_stage *setup,
unsigned slot,
unsigned i )
struct tgsi_interp_coef *coef,
uint vertSlot, uint i)
{
/* premultiply by 1/w:
/* premultiply by 1/w (v->data[0][3] is always W):
*/
float mina = setup->vmin->data[slot][i] * setup->vmin->data[0][3];
float mida = setup->vmid->data[slot][i] * setup->vmid->data[0][3];
float maxa = setup->vmax->data[slot][i] * setup->vmax->data[0][3];
float mina = setup->vmin->data[vertSlot][i] * setup->vmin->data[0][3];
float mida = setup->vmid->data[vertSlot][i] * setup->vmid->data[0][3];
float maxa = setup->vmax->data[vertSlot][i] * setup->vmax->data[0][3];
float botda = mida - mina;
float majda = maxa - mina;
float a = setup->ebot.dy * majda - botda * setup->emaj.dy;
float b = setup->emaj.dx * botda - majda * setup->ebot.dx;
float dadx = a * setup->oneoverarea;
float dady = b * setup->oneoverarea;
/*
printf("tri persp %d,%d: %f %f %f\n", slot, i,
setup->vmin->data[slot][i],
setup->vmid->data[slot][i],
setup->vmax->data[slot][i]
printf("tri persp %d,%d: %f %f %f\n", vertSlot, i,
setup->vmin->data[vertSlot][i],
setup->vmid->data[vertSlot][i],
setup->vmax->data[vertSlot][i]
);
*/
assert(slot < PIPE_MAX_SHADER_INPUTS);
assert(i <= 3);
setup->coef[slot].dadx[i] = a * setup->oneoverarea;
setup->coef[slot].dady[i] = b * setup->oneoverarea;
setup->coef[slot].a0[i] = (mina -
(setup->coef[slot].dadx[i] * (setup->vmin->data[0][0] - 0.5f) +
setup->coef[slot].dady[i] * (setup->vmin->data[0][1] - 0.5f)));
coef->dadx[i] = dadx;
coef->dady[i] = dady;
coef->a0[i] = (mina -
(dadx * (setup->vmin->data[0][0] - 0.5f) +
dady * (setup->vmin->data[0][1] - 0.5f)));
}
/**
* Special coefficient setup for gl_FragCoord.
* X and Y are trivial, though Y has to be inverted for OpenGL.
* Z and W are copied from posCoef which should have already been computed.
* We could do a bit less work if we'd examine gl_FragCoord's swizzle mask.
*/
static void
setup_fragcoord_coeff(struct setup_stage *setup)
{
/*X*/
setup->coef[0].a0[0] = 0;
setup->coef[0].dadx[0] = 1.0;
setup->coef[0].dady[0] = 0.0;
/*Y*/
if (setup->softpipe->rasterizer->origin_lower_left) {
/* y=0=bottom */
const int winHeight = setup->softpipe->framebuffer.cbufs[0]->height;
setup->coef[0].a0[1] = winHeight - 1;
setup->coef[0].dady[1] = -1.0;
}
else {
/* y=0=top */
setup->coef[0].a0[1] = 0.0;
setup->coef[0].dady[1] = 1.0;
}
setup->coef[0].dadx[1] = 0.0;
/*Z*/
setup->coef[0].a0[2] = setup->posCoef.a0[2];
setup->coef[0].dadx[2] = setup->posCoef.dadx[2];
setup->coef[0].dady[2] = setup->posCoef.dady[2];
/*w*/
setup->coef[0].a0[3] = setup->posCoef.a0[3];
setup->coef[0].dadx[3] = setup->posCoef.dadx[3];
setup->coef[0].dady[3] = setup->posCoef.dady[3];
}
/**
* Compute the setup->coef[] array dadx, dady, a0 values.
* Must be called after setup->vmin,vmid,vmax,vprovoke are initialized.
@@ -474,36 +516,67 @@ static void tri_persp_coeff( struct setup_stage *setup,
static void setup_tri_coefficients( struct setup_stage *setup )
{
const enum interp_mode *interp = setup->softpipe->vertex_info.interp_mode;
unsigned slot, j;
#define USE_INPUT_MAP 0
#if USE_INPUT_MAP
const struct pipe_shader_state *fs = &setup->softpipe->fs->shader;
#endif
uint fragSlot;
/* z and w are done by linear interpolation:
*/
tri_linear_coeff(setup, 0, 2);
tri_linear_coeff(setup, 0, 3);
tri_linear_coeff(setup, &setup->posCoef, 0, 2);
tri_linear_coeff(setup, &setup->posCoef, 0, 3);
/* setup interpolation for all the remaining attributes:
*/
for (slot = 1; slot < setup->quad.nr_attrs; slot++) {
switch (interp[slot]) {
case INTERP_CONSTANT:
for (j = 0; j < NUM_CHANNELS; j++)
const_coeff(setup, slot, j);
break;
case INTERP_LINEAR:
for (j = 0; j < NUM_CHANNELS; j++)
tri_linear_coeff(setup, slot, j);
break;
case INTERP_PERSPECTIVE:
for (j = 0; j < NUM_CHANNELS; j++)
tri_persp_coeff(setup, slot, j);
break;
default:
/* invalid interp mode */
assert(0);
for (fragSlot = 0; fragSlot < setup->quad.nr_attrs; fragSlot++) {
/* which vertex output maps to this fragment input: */
#if !USE_INPUT_MAP
uint vertSlot;
if (setup->firstFpInput == TGSI_SEMANTIC_POSITION) {
if (fragSlot == 0) {
setup_fragcoord_coeff(setup);
continue;
}
vertSlot = fragSlot;
}
else {
vertSlot = fragSlot + 1;
}
#else
uint vertSlot = fs->input_map[fragSlot];
if (vertSlot == 0) {
/* special case: shader is reading gl_FragCoord */
/* XXX with a new INTERP_POSITION token, we could just add a
* new case to the switch below.
*/
setup_fragcoord_coeff(setup);
}
else {
#endif
uint j;
switch (interp[vertSlot]) {
case INTERP_CONSTANT:
for (j = 0; j < NUM_CHANNELS; j++)
const_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
break;
case INTERP_LINEAR:
for (j = 0; j < NUM_CHANNELS; j++)
tri_linear_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
break;
case INTERP_PERSPECTIVE:
for (j = 0; j < NUM_CHANNELS; j++)
tri_persp_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
break;
default:
/* invalid interp mode */
assert(0);
}
#if USE_INPUT_MAP
}
#endif
}
}
@@ -660,17 +733,18 @@ static void setup_tri( struct draw_stage *stage,
* for a line.
*/
static void
line_linear_coeff(struct setup_stage *setup, unsigned slot, unsigned i)
line_linear_coeff(struct setup_stage *setup,
struct tgsi_interp_coef *coef,
uint vertSlot, uint i)
{
const float da = setup->vmax->data[slot][i] - setup->vmin->data[slot][i];
const float da = setup->vmax->data[vertSlot][i] - setup->vmin->data[vertSlot][i];
const float dadx = da * setup->emaj.dx * setup->oneoverarea;
const float dady = da * setup->emaj.dy * setup->oneoverarea;
setup->coef[slot].dadx[i] = dadx;
setup->coef[slot].dady[i] = dady;
setup->coef[slot].a0[i]
= (setup->vmin->data[slot][i] -
(dadx * (setup->vmin->data[0][0] - 0.5f) +
dady * (setup->vmin->data[0][1] - 0.5f)));
coef->dadx[i] = dadx;
coef->dady[i] = dady;
coef->a0[i] = (setup->vmin->data[vertSlot][i] -
(dadx * (setup->vmin->data[0][0] - 0.5f) +
dady * (setup->vmin->data[0][1] - 0.5f)));
}
@@ -679,21 +753,21 @@ line_linear_coeff(struct setup_stage *setup, unsigned slot, unsigned i)
* for a line.
*/
static void
line_persp_coeff(struct setup_stage *setup, unsigned slot, unsigned i)
line_persp_coeff(struct setup_stage *setup,
struct tgsi_interp_coef *coef,
uint vertSlot, uint i)
{
/* XXX double-check/verify this arithmetic */
const float a0 = setup->vmin->data[slot][i] * setup->vmin->data[0][3];
const float a1 = setup->vmax->data[slot][i] * setup->vmin->data[0][3];
const float a0 = setup->vmin->data[vertSlot][i] * setup->vmin->data[0][3];
const float a1 = setup->vmax->data[vertSlot][i] * setup->vmin->data[0][3];
const float da = a1 - a0;
const float dadx = da * setup->emaj.dx * setup->oneoverarea;
const float dady = da * setup->emaj.dy * setup->oneoverarea;
setup->coef[slot].dadx[i] = dadx;
setup->coef[slot].dady[i] = dady;
setup->coef[slot].a0[i]
= (setup->vmin->data[slot][i] -
(dadx * (setup->vmin->data[0][0] - 0.5f) +
dady * (setup->vmin->data[0][1] - 0.5f)));
coef->dadx[i] = dadx;
coef->dady[i] = dady;
coef->a0[i] = (setup->vmin->data[vertSlot][i] -
(dadx * (setup->vmin->data[0][0] - 0.5f) +
dady * (setup->vmin->data[0][1] - 0.5f)));
}
@@ -705,7 +779,8 @@ static INLINE void
setup_line_coefficients(struct setup_stage *setup, struct prim_header *prim)
{
const enum interp_mode *interp = setup->softpipe->vertex_info.interp_mode;
unsigned slot, j;
const struct pipe_shader_state *fs = &setup->softpipe->fs->shader;
unsigned fragSlot;
/* use setup->vmin, vmax to point to vertices */
setup->vprovoke = prim->v[1];
@@ -720,31 +795,39 @@ setup_line_coefficients(struct setup_stage *setup, struct prim_header *prim)
/* z and w are done by linear interpolation:
*/
line_linear_coeff(setup, 0, 2);
line_linear_coeff(setup, 0, 3);
line_linear_coeff(setup, &setup->posCoef, 0, 2);
line_linear_coeff(setup, &setup->posCoef, 0, 3);
/* setup interpolation for all the remaining attributes:
*/
for (slot = 1; slot < setup->quad.nr_attrs; slot++) {
switch (interp[slot]) {
case INTERP_CONSTANT:
for (j = 0; j < NUM_CHANNELS; j++)
const_coeff(setup, slot, j);
break;
case INTERP_LINEAR:
for (j = 0; j < NUM_CHANNELS; j++)
line_linear_coeff(setup, slot, j);
break;
for (fragSlot = 0; fragSlot < setup->quad.nr_attrs; fragSlot++) {
/* which vertex output maps to this fragment input: */
uint vertSlot = fs->input_map[fragSlot];
case INTERP_PERSPECTIVE:
for (j = 0; j < NUM_CHANNELS; j++)
line_persp_coeff(setup, slot, j);
break;
default:
/* invalid interp mode */
assert(0);
if (vertSlot == 0) {
/* special case: shader is reading gl_FragCoord */
setup_fragcoord_coeff(setup);
}
else {
uint j;
switch (interp[vertSlot]) {
case INTERP_CONSTANT:
for (j = 0; j < NUM_CHANNELS; j++)
const_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
break;
case INTERP_LINEAR:
for (j = 0; j < NUM_CHANNELS; j++)
line_linear_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
break;
case INTERP_PERSPECTIVE:
for (j = 0; j < NUM_CHANNELS; j++)
line_persp_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
break;
default:
/* invalid interp mode */
assert(0);
}
}
}
}
@@ -910,14 +993,15 @@ setup_line(struct draw_stage *stage, struct prim_header *prim)
static void
point_persp_coeff(struct setup_stage *setup, const struct vertex_header *vert,
uint slot, uint i)
point_persp_coeff(struct setup_stage *setup,
const struct vertex_header *vert,
struct tgsi_interp_coef *coef,
uint vertSlot, uint i)
{
assert(slot < PIPE_MAX_SHADER_INPUTS);
assert(i <= 3);
setup->coef[slot].dadx[i] = 0.0F;
setup->coef[slot].dady[i] = 0.0F;
setup->coef[slot].a0[i] = vert->data[slot][i] * vert->data[0][3];
coef->dadx[i] = 0.0F;
coef->dady[i] = 0.0F;
coef->a0[i] = vert->data[vertSlot][i] * vert->data[0][3];
}
@@ -930,6 +1014,7 @@ static void
setup_point(struct draw_stage *stage, struct prim_header *prim)
{
struct setup_stage *setup = setup_stage( stage );
const struct pipe_shader_state *fs = &setup->softpipe->fs->shader;
const enum interp_mode *interp = setup->softpipe->vertex_info.interp_mode;
const struct vertex_header *v0 = prim->v[0];
const int sizeAttr = setup->softpipe->psize_slot;
@@ -940,7 +1025,7 @@ setup_point(struct draw_stage *stage, struct prim_header *prim)
const boolean round = (boolean) setup->softpipe->rasterizer->point_smooth;
const float x = v0->data[0][0]; /* Note: data[0] is always position */
const float y = v0->data[0][1];
unsigned slot, j;
uint fragSlot;
/* For points, all interpolants are constant-valued.
* However, for point sprites, we'll need to setup texcoords appropriately.
@@ -959,22 +1044,36 @@ setup_point(struct draw_stage *stage, struct prim_header *prim)
* probably should be ruled out on that basis.
*/
setup->vprovoke = prim->v[0];
const_coeff(setup, 0, 2);
const_coeff(setup, 0, 3);
for (slot = 1; slot < setup->quad.nr_attrs; slot++) {
switch (interp[slot]) {
case INTERP_CONSTANT:
/* fall-through */
case INTERP_LINEAR:
for (j = 0; j < NUM_CHANNELS; j++)
const_coeff(setup, slot, j);
break;
case INTERP_PERSPECTIVE:
for (j = 0; j < NUM_CHANNELS; j++)
point_persp_coeff(setup, v0, slot, j);
break;
default:
assert(0);
/* setup Z, W */
const_coeff(setup, &setup->posCoef, 0, 2);
const_coeff(setup, &setup->posCoef, 0, 3);
for (fragSlot = 0; fragSlot < setup->quad.nr_attrs; fragSlot++) {
/* which vertex output maps to this fragment input: */
uint vertSlot = fs->input_map[fragSlot];
if (vertSlot == 0) {
/* special case: shader is reading gl_FragCoord */
setup_fragcoord_coeff(setup);
}
else {
uint j;
switch (interp[vertSlot]) {
case INTERP_CONSTANT:
/* fall-through */
case INTERP_LINEAR:
for (j = 0; j < NUM_CHANNELS; j++)
const_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
break;
case INTERP_PERSPECTIVE:
for (j = 0; j < NUM_CHANNELS; j++)
point_persp_coeff(setup, setup->vprovoke,
&setup->coef[fragSlot], vertSlot, j);
break;
default:
assert(0);
}
}
}
@@ -1108,9 +1207,12 @@ static void setup_begin( struct draw_stage *stage )
{
struct setup_stage *setup = setup_stage(stage);
struct softpipe_context *sp = setup->softpipe;
const struct pipe_shader_state *fs = &setup->softpipe->fs->shader;
setup->quad.nr_attrs = setup->softpipe->nr_frag_attrs;
setup->firstFpInput = fs->input_semantic_name[0];
sp->quad.first->begin(sp->quad.first);
}
@@ -1151,6 +1253,7 @@ struct draw_stage *sp_draw_render_stage( struct softpipe_context *softpipe )
setup->stage.destroy = render_destroy;
setup->quad.coef = setup->coef;
setup->quad.posCoef = &setup->posCoef;
return &setup->stage;
}
+3 -3
View File
@@ -47,9 +47,9 @@ earlyz_quad(
{
const float fx = (float) quad->x0;
const float fy = (float) quad->y0;
const float dzdx = quad->coef[0].dadx[2];
const float dzdy = quad->coef[0].dady[2];
const float z0 = quad->coef[0].a0[2] + dzdx * fx + dzdy * fy;
const float dzdx = quad->posCoef->dadx[2];
const float dzdy = quad->posCoef->dady[2];
const float z0 = quad->posCoef->a0[2] + dzdx * fx + dzdy * fy;
quad->outputs.depth[0] = z0;
quad->outputs.depth[1] = z0 + dzdx;
+45 -20
View File
@@ -74,15 +74,49 @@ quad_shade_stage(struct quad_stage *qs)
}
/**
* Compute quad X,Y,Z,W for the four fragments in a quad.
* Note that we only need to "compute" X and Y for the upper-left fragment.
* We could do less work if we're not depth testing, or there's no
* perspective-corrected attributes, but that's seldom.
*/
static void
setup_pos_vector(const struct tgsi_interp_coef *coef,
float x, float y,
struct tgsi_exec_vector *quadpos)
{
uint chan;
/* do X */
quadpos->xyzw[0].f[0] = x;
/* do Y */
quadpos->xyzw[1].f[0] = y;
/* do Z and W for all fragments in the quad */
for (chan = 2; chan < 4; chan++) {
const float dadx = coef->dadx[chan];
const float dady = coef->dady[chan];
const float a0 = coef->a0[chan] + dadx * x + dady * y;
quadpos->xyzw[chan].f[0] = a0;
quadpos->xyzw[chan].f[1] = a0 + dadx;
quadpos->xyzw[chan].f[2] = a0 + dady;
quadpos->xyzw[chan].f[3] = a0 + dadx + dady;
}
}
typedef void (XSTDCALL *codegen_function)(
const struct tgsi_exec_vector *input,
struct tgsi_exec_vector *output,
float (*constant)[4],
struct tgsi_exec_vector *temporary,
const struct tgsi_interp_coef *coef );
const struct tgsi_interp_coef *coef
#if 0
,const struct tgsi_exec_vector *quadPos
#endif
);
/* This should be done by the fragment shader execution unit (code
* generated from the decl instructions). Do it here for now.
/**
* Execute fragment shader for the four fragments in the quad.
*/
static void
shade_quad(
@@ -91,28 +125,15 @@ shade_quad(
{
struct quad_shade_stage *qss = quad_shade_stage( qs );
struct softpipe_context *softpipe = qs->softpipe;
const float fx = (float) quad->x0;
const float fy = (float) quad->y0;
struct tgsi_exec_machine *machine = &qss->machine;
/* Consts does not require 16 byte alignment. */
/* Consts do not require 16 byte alignment. */
machine->Consts = softpipe->mapped_constants[PIPE_SHADER_FRAGMENT];
machine->InterpCoefs = quad->coef;
machine->Inputs[0].xyzw[0].f[0] = fx;
machine->Inputs[0].xyzw[0].f[1] = fx + 1.0f;
machine->Inputs[0].xyzw[0].f[2] = fx;
machine->Inputs[0].xyzw[0].f[3] = fx + 1.0f;
/* XXX for OpenGL we need to invert the Y pos here (y=0=top).
* but that'll mess up linear/perspective interpolation of other
* attributes...
*/
machine->Inputs[0].xyzw[1].f[0] = fy;
machine->Inputs[0].xyzw[1].f[1] = fy;
machine->Inputs[0].xyzw[1].f[2] = fy + 1.0f;
machine->Inputs[0].xyzw[1].f[3] = fy + 1.0f;
/* Compute X, Y, Z, W vals for this quad */
setup_pos_vector(quad->posCoef, quad->x0, quad->y0, &machine->QuadPos);
/* run shader */
#if defined(__i386__) || defined(__386__)
@@ -123,7 +144,11 @@ shade_quad(
machine->Outputs,
machine->Consts,
machine->Temps,
machine->InterpCoefs );
machine->InterpCoefs
#if 0
,machine->QuadPos
#endif
);
quad->mask &= ~(machine->Temps[TGSI_EXEC_TEMP_KILMASK_I].xyzw[TGSI_EXEC_TEMP_KILMASK_C].u[0]);
}
else
+12 -4
View File
@@ -22,10 +22,18 @@ stipple_quad(struct quad_stage *qs, struct quad_header *quad)
if (quad->prim == PRIM_TRI) {
struct softpipe_context *softpipe = qs->softpipe;
/* need to invert Y to index into OpenGL's stipple pattern */
const int y0 = softpipe->framebuffer.cbufs[0]->height - 1 - quad->y0;
const int y1 = y0 - 1;
const unsigned stipple0 = softpipe->poly_stipple.stipple[y0 % 32];
const unsigned stipple1 = softpipe->poly_stipple.stipple[y1 % 32];
int y0, y1;
uint stipple0, stipple1;
if (softpipe->rasterizer->origin_lower_left) {
y0 = softpipe->framebuffer.cbufs[0]->height - 1 - quad->y0;
y1 = y0 - 1;
}
else {
y0 = quad->y0;
y1 = y0 + 1;
}
stipple0 = softpipe->poly_stipple.stipple[y0 % 32];
stipple1 = softpipe->poly_stipple.stipple[y1 % 32];
#if 1
const int col0 = quad->x0 % 32;
+4 -8
View File
@@ -51,18 +51,11 @@ static void calculate_vertex_layout( struct softpipe_context *softpipe )
memset(vinfo, 0, sizeof(*vinfo));
if (softpipe->depth_stencil->depth.enabled)
softpipe->need_z = TRUE;
else
softpipe->need_z = FALSE;
softpipe->need_w = FALSE;
if (fs->input_semantic_name[0] == TGSI_SEMANTIC_POSITION) {
/* Need Z if depth test is enabled or the fragment program uses the
* fragment position (XYZW).
*/
softpipe->need_z = TRUE;
softpipe->need_w = TRUE;
}
softpipe->psize_slot = -1;
@@ -121,7 +114,6 @@ static void calculate_vertex_layout( struct softpipe_context *softpipe )
case TGSI_SEMANTIC_GENERIC:
/* this includes texcoords and varying vars */
draw_emit_vertex_attr(vinfo, FORMAT_4F, INTERP_PERSPECTIVE);
softpipe->need_w = TRUE;
break;
default:
@@ -129,7 +121,11 @@ static void calculate_vertex_layout( struct softpipe_context *softpipe )
}
}
#if 00
softpipe->nr_frag_attrs = vinfo->num_attribs;
#else
softpipe->nr_frag_attrs = fs->num_inputs;
#endif
/* We want these after all other attribs since they won't get passed
* to the fragment shader. All prior vertex output attribs should match
-4
View File
@@ -52,10 +52,6 @@ static unsigned minify( unsigned d )
return MAX2(1, d>>1);
}
static int align(int value, int alignment)
{
return (value + alignment - 1) & ~(alignment - 1);
}
static void
+10 -19
View File
@@ -1352,8 +1352,8 @@ linear_interpolation(
unsigned attrib,
unsigned chan )
{
const float x = mach->Inputs[0].xyzw[0].f[0];
const float y = mach->Inputs[0].xyzw[1].f[0];
const float x = mach->QuadPos.xyzw[0].f[0];
const float y = mach->QuadPos.xyzw[1].f[0];
const float dadx = mach->InterpCoefs[attrib].dadx[chan];
const float dady = mach->InterpCoefs[attrib].dady[chan];
const float a0 = mach->InterpCoefs[attrib].a0[chan] + dadx * x + dady * y;
@@ -1369,15 +1369,17 @@ perspective_interpolation(
unsigned attrib,
unsigned chan )
{
const float x = mach->Inputs[0].xyzw[0].f[0];
const float y = mach->Inputs[0].xyzw[1].f[0];
const float x = mach->QuadPos.xyzw[0].f[0];
const float y = mach->QuadPos.xyzw[1].f[0];
const float dadx = mach->InterpCoefs[attrib].dadx[chan];
const float dady = mach->InterpCoefs[attrib].dady[chan];
const float a0 = mach->InterpCoefs[attrib].a0[chan] + dadx * x + dady * y;
mach->Inputs[attrib].xyzw[chan].f[0] = a0 / mach->Inputs[0].xyzw[3].f[0];
mach->Inputs[attrib].xyzw[chan].f[1] = (a0 + dadx) / mach->Inputs[0].xyzw[3].f[1];
mach->Inputs[attrib].xyzw[chan].f[2] = (a0 + dady) / mach->Inputs[0].xyzw[3].f[2];
mach->Inputs[attrib].xyzw[chan].f[3] = (a0 + dadx + dady) / mach->Inputs[0].xyzw[3].f[3];
const float *w = mach->QuadPos.xyzw[3].f;
/* divide by W here */
mach->Inputs[attrib].xyzw[chan].f[0] = a0 / w[0];
mach->Inputs[attrib].xyzw[chan].f[1] = (a0 + dadx) / w[1];
mach->Inputs[attrib].xyzw[chan].f[2] = (a0 + dady) / w[2];
mach->Inputs[attrib].xyzw[chan].f[3] = (a0 + dadx + dady) / w[3];
}
@@ -1402,17 +1404,6 @@ exec_declaration(
last = decl->u.DeclarationRange.Last;
mask = decl->Declaration.UsageMask;
/* Do not touch WPOS.xy */
if( first == 0 ) {
mask &= ~TGSI_WRITEMASK_XY;
if( mask == TGSI_WRITEMASK_NONE ) {
first++;
if( first > last ) {
return;
}
}
}
switch( decl->Interpolation.Interpolate ) {
case TGSI_INTERPOLATE_CONSTANT:
interp = constant_interpolation;
+1
View File
@@ -177,6 +177,7 @@ struct tgsi_exec_machine
/* FRAGMENT processor only. */
const struct tgsi_interp_coef *InterpCoefs;
struct tgsi_exec_vector QuadPos;
/* Conditional execution masks */
uint CondMask; /**< For IF/ELSE/ENDIF */
+8
View File
@@ -493,6 +493,13 @@ static void aub_i965_batch_reloc( struct brw_winsys *sws,
iws->data[iws->nr++] = aub_bo(buf)->offset + delta;
}
static unsigned aub_i965_get_buffer_offset( struct brw_winsys *sws,
struct pipe_buffer_handle *buf,
unsigned access_flags )
{
return aub_bo(buf)->offset;
}
static void aub_i965_batch_flush( struct brw_winsys *sws,
@@ -605,6 +612,7 @@ xmesa_create_i965simple( struct pipe_winsys *winsys )
iws->winsys.batch_reloc = aub_i965_batch_reloc;
iws->winsys.batch_flush = aub_i965_batch_flush;
iws->winsys.buffer_subdata_typed = aub_i965_buffer_subdata_typed;
iws->winsys.get_buffer_offset = aub_i965_get_buffer_offset;
iws->pipe_winsys = winsys;
@@ -77,6 +77,8 @@ static void update_raster_state( struct st_context *st )
uint i;
memset(&raster, 0, sizeof(raster));
raster.origin_lower_left = 1; /* Always true for OpenGL */
/* _NEW_POLYGON, _NEW_BUFFERS
*/
+16 -9
View File
@@ -35,6 +35,7 @@
#include "st_context.h"
#include "st_cache.h"
#include "st_atom.h"
#include "st_program.h"
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
@@ -116,17 +117,23 @@ gl_filter_to_img_filter(GLenum filter)
static void
update_samplers(struct st_context *st)
{
GLuint u;
const struct st_fragment_program *fs = st->fp;
GLuint su;
for (u = 0; u < st->ctx->Const.MaxTextureImageUnits; u++) {
const struct gl_texture_object *texobj
= st->ctx->Texture.Unit[u]._Current;
/* loop over sampler units (aka tex image units) */
for (su = 0; su < st->ctx->Const.MaxTextureImageUnits; su++) {
struct pipe_sampler_state sampler;
const struct cso_sampler *cso;
memset(&sampler, 0, sizeof(sampler));
if (texobj) {
if (fs->Base.Base.SamplersUsed & (1 << su)) {
GLuint texUnit = fs->Base.Base.SamplerUnits[su];
const struct gl_texture_object *texobj
= st->ctx->Texture.Unit[texUnit]._Current;
assert(texobj);
sampler.wrap_s = gl_wrap_to_sp(texobj->WrapS);
sampler.wrap_t = gl_wrap_to_sp(texobj->WrapT);
sampler.wrap_r = gl_wrap_to_sp(texobj->WrapR);
@@ -138,7 +145,7 @@ update_samplers(struct st_context *st)
if (texobj->Target != GL_TEXTURE_RECTANGLE_ARB)
sampler.normalized_coords = 1;
sampler.lod_bias = st->ctx->Texture.Unit[u].LodBias;
sampler.lod_bias = st->ctx->Texture.Unit[su].LodBias;
#if 1
sampler.min_lod = texobj->MinLod;
sampler.max_lod = texobj->MaxLod;
@@ -166,10 +173,10 @@ update_samplers(struct st_context *st)
cso = st_cached_sampler_state(st, &sampler);
if (cso != st->state.sampler[u]) {
if (cso != st->state.sampler[su]) {
/* state has changed */
st->state.sampler[u] = cso;
st->pipe->bind_sampler_state(st->pipe, u, cso->data);
st->state.sampler[su] = cso;
st->pipe->bind_sampler_state(st->pipe, su, cso->data);
}
}
}
+19 -6
View File
@@ -151,8 +151,7 @@ find_translated_vp(struct st_context *st,
{
static const GLuint UNUSED = ~0;
struct translated_vertex_program *xvp;
const GLbitfield fragInputsRead
= stfp->Base.Base.InputsRead | FRAG_BIT_WPOS;
const GLbitfield fragInputsRead = stfp->Base.Base.InputsRead;
/*
* Translate fragment program if needed.
@@ -206,6 +205,7 @@ find_translated_vp(struct st_context *st,
if (xvp->serialNo != stvp->serialNo) {
GLuint outAttr, dummySlot;
const GLbitfield outputsWritten = stvp->Base.Base.OutputsWritten;
GLuint numVpOuts = 0;
/* Compute mapping of vertex program outputs to slots, which depends
* on the fragment program's input->slot mapping.
@@ -214,11 +214,24 @@ find_translated_vp(struct st_context *st,
/* set default: */
xvp->output_to_slot[outAttr] = UNUSED;
if (outputsWritten & (1 << outAttr)) {
if (outAttr == VERT_RESULT_HPOS) {
/* always put xformed position into slot zero */
xvp->output_to_slot[VERT_RESULT_HPOS] = 0;
numVpOuts++;
}
else if (outputsWritten & (1 << outAttr)) {
/* see if the frag prog wants this vert output */
GLint fpIn = vp_out_to_fp_in(outAttr);
if (fpIn >= 0) {
xvp->output_to_slot[outAttr] = stfp->input_to_slot[fpIn];
GLint fpInAttrib = vp_out_to_fp_in(outAttr);
if (fpInAttrib >= 0) {
GLuint fpInSlot = stfp->input_to_slot[fpInAttrib];
GLuint vpOutSlot = stfp->fs->state.input_map[fpInSlot];
xvp->output_to_slot[outAttr] = vpOutSlot;
numVpOuts++;
}
else if (outAttr == VERT_RESULT_BFC0 ||
outAttr == VERT_RESULT_BFC1) {
/* backface colors go into last slots */
xvp->output_to_slot[outAttr] = numVpOuts++;
}
}
}
+4
View File
@@ -243,6 +243,10 @@ st_new_renderbuffer_fb(enum pipe_format format)
strb->Base.InternalFormat = GL_DEPTH24_STENCIL8_EXT;
strb->Base._BaseFormat = GL_DEPTH_STENCIL_EXT;
break;
case PIPE_FORMAT_S8_UNORM:
strb->Base.InternalFormat = GL_STENCIL_INDEX8_EXT;
strb->Base._BaseFormat = GL_STENCIL_INDEX;
break;
case PIPE_FORMAT_R16G16B16A16_SNORM:
strb->Base.InternalFormat = GL_RGBA16;
strb->Base._BaseFormat = GL_RGBA;
+39 -34
View File
@@ -585,6 +585,20 @@ make_temp_decl(
}
static struct tgsi_full_declaration
make_sampler_decl(GLuint index)
{
struct tgsi_full_declaration decl;
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_SAMPLER;
decl.Declaration.Declare = TGSI_DECLARE_RANGE;
decl.u.DeclarationRange.First = index;
decl.u.DeclarationRange.Last = index;
return decl;
}
/**
* Find the temporaries which are used in the given program.
*/
@@ -675,44 +689,22 @@ tgsi_translate_mesa_program(
if (procType == TGSI_PROCESSOR_FRAGMENT) {
for (i = 0; i < numInputs; i++) {
struct tgsi_full_declaration fulldecl;
switch (inputSemanticName[i]) {
case TGSI_SEMANTIC_POSITION:
/* Fragment XY pos */
fulldecl = make_input_decl(i,
GL_TRUE, TGSI_INTERPOLATE_CONSTANT,
TGSI_WRITEMASK_XY,
GL_TRUE, TGSI_SEMANTIC_POSITION, 0 );
ti += tgsi_build_full_declaration(
&fulldecl,
&tokens[ti],
header,
maxTokens - ti );
/* Fragment ZW pos */
fulldecl = make_input_decl(i,
GL_TRUE, TGSI_INTERPOLATE_LINEAR,
TGSI_WRITEMASK_ZW,
GL_TRUE, TGSI_SEMANTIC_POSITION, 0 );
ti += tgsi_build_full_declaration(&fulldecl,
&tokens[ti],
header,
maxTokens - ti );
break;
default:
fulldecl = make_input_decl(i,
GL_TRUE, interpMode[i],
TGSI_WRITEMASK_XYZW,
GL_TRUE, inputSemanticName[i],
inputSemanticIndex[i]);
ti += tgsi_build_full_declaration(&fulldecl,
&tokens[ti],
header,
maxTokens - ti );
break;
}
fulldecl = make_input_decl(i,
GL_TRUE, interpMode[i],
TGSI_WRITEMASK_XYZW,
GL_TRUE, inputSemanticName[i],
inputSemanticIndex[i]);
ti += tgsi_build_full_declaration(&fulldecl,
&tokens[ti],
header,
maxTokens - ti );
}
}
else {
/* vertex prog */
/* XXX: this could probaby be merged with the clause above.
* the only difference is the semantic tags.
*/
for (i = 0; i < numInputs; i++) {
struct tgsi_full_declaration fulldecl;
fulldecl = make_input_decl(i,
@@ -810,6 +802,19 @@ tgsi_translate_mesa_program(
}
}
/* texture samplers */
for (i = 0; i < 8; i++) {
if (program->SamplersUsed & (1 << i)) {
struct tgsi_full_declaration fulldecl;
fulldecl = make_sampler_decl( i );
ti += tgsi_build_full_declaration(&fulldecl,
&tokens[ti],
header,
maxTokens - ti );
}
}
for( i = 0; i < program->NumInstructions; i++ ) {
compile_instruction(
&program->Instructions[i],
+14 -11
View File
@@ -47,7 +47,7 @@
#include "st_mesa_to_tgsi.h"
#define TGSI_DEBUG 0
#define TGSI_DEBUG 01
/**
@@ -283,16 +283,17 @@ st_translate_fragment_program(struct st_context *st,
const struct cso_fragment_shader *cso;
GLuint interpMode[16]; /* XXX size? */
GLuint attr;
GLbitfield inputsRead = stfp->Base.Base.InputsRead;
/* For software rendering, we always need the fragment input position
* in order to calculate interpolated values.
* For i915, we always want to emit the semantic info for position.
*/
inputsRead |= FRAG_BIT_WPOS;
const GLbitfield inputsRead = stfp->Base.Base.InputsRead;
GLuint vslot = 0;
memset(&fs, 0, sizeof(fs));
/* which vertex output goes to the first fragment input: */
if (inputsRead & FRAG_BIT_WPOS)
vslot = 0;
else
vslot = 1;
/*
* Convert Mesa program inputs to TGSI input register semantics.
*/
@@ -300,15 +301,17 @@ st_translate_fragment_program(struct st_context *st,
if (inputsRead & (1 << attr)) {
const GLuint slot = fs.num_inputs;
fs.num_inputs++;
defaultInputMapping[attr] = slot;
fs.input_map[slot] = vslot++;
fs.num_inputs++;
switch (attr) {
case FRAG_ATTRIB_WPOS:
fs.input_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
fs.input_semantic_index[slot] = 0;
interpMode[slot] = TGSI_INTERPOLATE_CONSTANT;
interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
break;
case FRAG_ATTRIB_COL0:
fs.input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;