Port i965 driver to Gallium3D.
This is a squashed commit of i965 branch on ssh://people.freedesktop.org/~zack/mesa Because of the porting the branch often didn't compile so squashing it makes more sense. The port is still far from complete.
This commit is contained in:
+5
-3
@@ -11,7 +11,9 @@ GL_MINOR = 5
|
||||
GL_TINY = 0$(MESA_MAJOR)0$(MESA_MINOR)0$(MESA_TINY)
|
||||
|
||||
|
||||
SOFTPIPE_LIB = $(TOP)/src/mesa/pipe/softpipe/libsoftpipe.a
|
||||
PIPE_LIB = \
|
||||
$(TOP)/src/mesa/pipe/softpipe/libsoftpipe.a \
|
||||
$(TOP)/src/mesa/pipe/i965simple/libi965simple.a
|
||||
|
||||
ifeq ($(CONFIG_NAME), linux-cell)
|
||||
CELL_LIB = $(TOP)/src/mesa/pipe/cell/ppu/libcell.a
|
||||
@@ -118,12 +120,12 @@ stand-alone: depend subdirs $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) $(TOP)/$(LIB_DIR)/$
|
||||
osmesa-only: depend subdirs $(TOP)/$(LIB_DIR)/$(OSMESA_LIB_NAME)
|
||||
|
||||
# Make the GL library
|
||||
$(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(STAND_ALONE_OBJECTS) $(SOFTPIPE_LIB) $(CELL_LIB) $(CELL_LIB_SPU)
|
||||
$(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(STAND_ALONE_OBJECTS) $(PIPE_LIB) $(CELL_LIB) $(CELL_LIB_SPU)
|
||||
@ $(TOP)/bin/mklib -o $(GL_LIB) \
|
||||
-major $(GL_MAJOR) -minor $(GL_MINOR) -patch $(GL_TINY) \
|
||||
-install $(TOP)/$(LIB_DIR) \
|
||||
$(MKLIB_OPTIONS) $(STAND_ALONE_OBJECTS) \
|
||||
$(SOFTPIPE_LIB) $(CELL_LIB) $(CELL_LIB_SPU) $(GL_LIB_DEPS)
|
||||
$(PIPE_LIB) $(CELL_LIB) $(CELL_LIB_SPU) $(GL_LIB_DEPS)
|
||||
|
||||
# Make the OSMesa library
|
||||
$(TOP)/$(LIB_DIR)/$(OSMESA_LIB_NAME): $(OSMESA_DRIVER_OBJECTS) $(OSMESA16_OBJECTS)
|
||||
|
||||
@@ -6,7 +6,7 @@ ifeq ($(CONFIG_NAME), linux-cell)
|
||||
CELL_DIR = cell
|
||||
endif
|
||||
|
||||
SUBDIRS = softpipe i915simple failover pipebuffer $(CELL_DIR)
|
||||
SUBDIRS = softpipe i915simple i965simple failover pipebuffer $(CELL_DIR)
|
||||
|
||||
|
||||
default: subdirs
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
|
||||
TOP = ../../../..
|
||||
include $(TOP)/configs/current
|
||||
|
||||
LIBNAME = i965simple
|
||||
|
||||
DRIVER_SOURCES = \
|
||||
brw_blit.c \
|
||||
brw_flush.c \
|
||||
brw_strings.c \
|
||||
brw_surface.c \
|
||||
brw_cc.c \
|
||||
brw_clip.c \
|
||||
brw_clip_line.c \
|
||||
brw_clip_point.c \
|
||||
brw_clip_state.c \
|
||||
brw_clip_tri.c \
|
||||
brw_clip_util.c \
|
||||
brw_context.c \
|
||||
brw_curbe.c \
|
||||
brw_draw.c \
|
||||
brw_draw_upload.c \
|
||||
brw_eu.c \
|
||||
brw_eu_debug.c \
|
||||
brw_eu_emit.c \
|
||||
brw_eu_util.c \
|
||||
brw_gs.c \
|
||||
brw_gs_emit.c \
|
||||
brw_gs_state.c \
|
||||
brw_misc_state.c \
|
||||
brw_program.c \
|
||||
brw_regions.c \
|
||||
brw_sf.c \
|
||||
brw_sf_emit.c \
|
||||
brw_sf_state.c \
|
||||
brw_state.c \
|
||||
brw_state_batch.c \
|
||||
brw_state_cache.c \
|
||||
brw_state_pool.c \
|
||||
brw_state_upload.c \
|
||||
brw_tex.c \
|
||||
brw_tex_layout.c \
|
||||
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_debug.c \
|
||||
brw_wm_emit.c \
|
||||
brw_wm_fp.c \
|
||||
brw_wm_iz.c \
|
||||
brw_wm_glsl.c \
|
||||
brw_wm_pass0.c \
|
||||
brw_wm_pass1.c \
|
||||
brw_wm_pass2.c \
|
||||
brw_wm_sampler_state.c \
|
||||
brw_wm_state.c \
|
||||
brw_wm_surface_state.c
|
||||
|
||||
C_SOURCES = \
|
||||
$(COMMON_SOURCES) \
|
||||
$(COMMON_BM_SOURCES) \
|
||||
$(MINIGLX_SOURCES) \
|
||||
$(DRIVER_SOURCES)
|
||||
|
||||
ASM_SOURCES =
|
||||
|
||||
DRIVER_DEFINES = -I.
|
||||
|
||||
include ../Makefile.template
|
||||
|
||||
symlinks:
|
||||
@@ -0,0 +1,57 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* 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, sub license, 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 NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS 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.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef BRW_BATCH_H
|
||||
#define BRW_BATCH_H
|
||||
|
||||
#include "brw_winsys.h"
|
||||
|
||||
#define BATCH_LOCALS
|
||||
|
||||
#define INTEL_BATCH_NO_CLIPRECTS 0x1
|
||||
#define INTEL_BATCH_CLIPRECTS 0x2
|
||||
|
||||
#define BEGIN_BATCH( dwords, relocs ) \
|
||||
(brw->batch_start = brw->winsys->batch_start(brw->winsys, dwords, relocs))
|
||||
|
||||
#define OUT_BATCH( dword ) \
|
||||
brw->winsys->batch_dword(brw->winsys, dword)
|
||||
|
||||
#define OUT_RELOC( buf, flags, delta ) \
|
||||
brw->winsys->batch_reloc(brw->winsys, buf, flags, delta)
|
||||
|
||||
#define ADVANCE_BATCH()
|
||||
|
||||
/* XXX: this is bogus - need proper handling for out-of-memory in batchbuffer.
|
||||
*/
|
||||
#define FLUSH_BATCH(fence) do { \
|
||||
brw->winsys->batch_flush(brw->winsys, fence); \
|
||||
brw->batch_start = NULL; \
|
||||
brw->hardware_dirty = ~0; \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,217 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* 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, sub license, 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 NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS 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.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "brw_batch.h"
|
||||
#include "brw_blit.h"
|
||||
#include "brw_context.h"
|
||||
#include "brw_reg.h"
|
||||
|
||||
#include "pipe/p_context.h"
|
||||
#include "pipe/p_winsys.h"
|
||||
|
||||
#define FILE_DEBUG_FLAG DEBUG_BLIT
|
||||
|
||||
void brw_fill_blit(struct brw_context *brw,
|
||||
unsigned cpp,
|
||||
short dst_pitch,
|
||||
struct pipe_buffer_handle *dst_buffer,
|
||||
unsigned dst_offset,
|
||||
boolean dst_tiled,
|
||||
short x, short y,
|
||||
short w, short h,
|
||||
unsigned color)
|
||||
{
|
||||
unsigned BR13, CMD;
|
||||
BATCH_LOCALS;
|
||||
|
||||
dst_pitch *= cpp;
|
||||
|
||||
switch(cpp) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
BR13 = (0xF0 << 16) | (1<<24);
|
||||
CMD = XY_COLOR_BLT_CMD;
|
||||
break;
|
||||
case 4:
|
||||
BR13 = (0xF0 << 16) | (1<<24) | (1<<25);
|
||||
CMD = XY_COLOR_BLT_CMD | XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if (dst_tiled) {
|
||||
CMD |= XY_DST_TILED;
|
||||
dst_pitch /= 4;
|
||||
}
|
||||
|
||||
BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS);
|
||||
OUT_BATCH( CMD );
|
||||
OUT_BATCH( dst_pitch | BR13 );
|
||||
OUT_BATCH( (y << 16) | x );
|
||||
OUT_BATCH( ((y+h) << 16) | (x+w) );
|
||||
OUT_RELOC( dst_buffer, BRW_BUFFER_ACCESS_WRITE, dst_offset );
|
||||
OUT_BATCH( color );
|
||||
ADVANCE_BATCH();
|
||||
}
|
||||
|
||||
static unsigned translate_raster_op(unsigned logicop)
|
||||
{
|
||||
switch(logicop) {
|
||||
case PIPE_LOGICOP_CLEAR: return 0x00;
|
||||
case PIPE_LOGICOP_AND: return 0x88;
|
||||
case PIPE_LOGICOP_AND_REVERSE: return 0x44;
|
||||
case PIPE_LOGICOP_COPY: return 0xCC;
|
||||
case PIPE_LOGICOP_AND_INVERTED: return 0x22;
|
||||
case PIPE_LOGICOP_NOOP: return 0xAA;
|
||||
case PIPE_LOGICOP_XOR: return 0x66;
|
||||
case PIPE_LOGICOP_OR: return 0xEE;
|
||||
case PIPE_LOGICOP_NOR: return 0x11;
|
||||
case PIPE_LOGICOP_EQUIV: return 0x99;
|
||||
case PIPE_LOGICOP_INVERT: return 0x55;
|
||||
case PIPE_LOGICOP_OR_REVERSE: return 0xDD;
|
||||
case PIPE_LOGICOP_COPY_INVERTED: return 0x33;
|
||||
case PIPE_LOGICOP_OR_INVERTED: return 0xBB;
|
||||
case PIPE_LOGICOP_NAND: return 0x77;
|
||||
case PIPE_LOGICOP_SET: return 0xFF;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Copy BitBlt
|
||||
*/
|
||||
void brw_copy_blit(struct brw_context *brw,
|
||||
unsigned cpp,
|
||||
short src_pitch,
|
||||
struct pipe_buffer_handle *src_buffer,
|
||||
unsigned src_offset,
|
||||
boolean src_tiled,
|
||||
short dst_pitch,
|
||||
struct pipe_buffer_handle *dst_buffer,
|
||||
unsigned dst_offset,
|
||||
boolean dst_tiled,
|
||||
short src_x, short src_y,
|
||||
short dst_x, short dst_y,
|
||||
short w, short h,
|
||||
unsigned logic_op)
|
||||
{
|
||||
unsigned CMD, BR13;
|
||||
int dst_y2 = dst_y + h;
|
||||
int dst_x2 = dst_x + w;
|
||||
BATCH_LOCALS;
|
||||
|
||||
|
||||
DBG("%s src:buf(%d)/%d %d,%d dst:buf(%d)/%d %d,%d sz:%dx%d op:%d\n",
|
||||
__FUNCTION__,
|
||||
src_buffer, src_pitch, src_x, src_y,
|
||||
dst_buffer, dst_pitch, dst_x, dst_y,
|
||||
w,h,logic_op);
|
||||
|
||||
assert( logic_op - PIPE_LOGICOP_CLEAR >= 0 );
|
||||
assert( logic_op - PIPE_LOGICOP_CLEAR < 0x10 );
|
||||
|
||||
src_pitch *= cpp;
|
||||
dst_pitch *= cpp;
|
||||
|
||||
switch(cpp) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
BR13 = (translate_raster_op(logic_op) << 16) | (1<<24);
|
||||
CMD = XY_SRC_COPY_BLT_CMD;
|
||||
break;
|
||||
case 4:
|
||||
BR13 = (translate_raster_op(logic_op) << 16) | (1<<24) |
|
||||
(1<<25);
|
||||
CMD = XY_SRC_COPY_BLT_CMD | XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if (src_tiled) {
|
||||
CMD |= XY_SRC_TILED;
|
||||
src_pitch /= 4;
|
||||
}
|
||||
|
||||
if (dst_tiled) {
|
||||
CMD |= XY_DST_TILED;
|
||||
dst_pitch /= 4;
|
||||
}
|
||||
|
||||
if (dst_y2 < dst_y ||
|
||||
dst_x2 < dst_x) {
|
||||
return;
|
||||
}
|
||||
|
||||
dst_pitch &= 0xffff;
|
||||
src_pitch &= 0xffff;
|
||||
|
||||
/* Initial y values don't seem to work with negative pitches. If
|
||||
* we adjust the offsets manually (below), it seems to work fine.
|
||||
*
|
||||
* On the other hand, if we always adjust, the hardware doesn't
|
||||
* know which blit directions to use, so overlapping copypixels get
|
||||
* the wrong result.
|
||||
*/
|
||||
if (dst_pitch > 0 && src_pitch > 0) {
|
||||
BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS);
|
||||
OUT_BATCH( CMD );
|
||||
OUT_BATCH( dst_pitch | BR13 );
|
||||
OUT_BATCH( (dst_y << 16) | dst_x );
|
||||
OUT_BATCH( (dst_y2 << 16) | dst_x2 );
|
||||
OUT_RELOC( dst_buffer, BRW_BUFFER_ACCESS_WRITE,
|
||||
dst_offset );
|
||||
OUT_BATCH( (src_y << 16) | src_x );
|
||||
OUT_BATCH( src_pitch );
|
||||
OUT_RELOC( src_buffer, BRW_BUFFER_ACCESS_READ,
|
||||
src_offset );
|
||||
ADVANCE_BATCH();
|
||||
}
|
||||
else {
|
||||
BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS);
|
||||
OUT_BATCH( CMD );
|
||||
OUT_BATCH( (dst_pitch & 0xffff) | BR13 );
|
||||
OUT_BATCH( (0 << 16) | dst_x );
|
||||
OUT_BATCH( (h << 16) | dst_x2 );
|
||||
OUT_RELOC( dst_buffer, BRW_BUFFER_ACCESS_WRITE,
|
||||
dst_offset + dst_y * dst_pitch );
|
||||
OUT_BATCH( (src_pitch & 0xffff) );
|
||||
OUT_RELOC( src_buffer, BRW_BUFFER_ACCESS_READ,
|
||||
src_offset + src_y * src_pitch );
|
||||
ADVANCE_BATCH();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
#ifndef BRW_BLIT_H
|
||||
#define BRW_BLIT_H
|
||||
|
||||
#include "pipe/p_compiler.h"
|
||||
|
||||
struct pipe_buffer_handle;
|
||||
struct brw_context;
|
||||
|
||||
void brw_fill_blit(struct brw_context *intel,
|
||||
unsigned cpp,
|
||||
short dst_pitch,
|
||||
struct pipe_buffer_handle *dst_buffer,
|
||||
unsigned dst_offset,
|
||||
boolean dst_tiled,
|
||||
short x, short y,
|
||||
short w, short h,
|
||||
unsigned color);
|
||||
void brw_copy_blit(struct brw_context *intel,
|
||||
unsigned cpp,
|
||||
short src_pitch,
|
||||
struct pipe_buffer_handle *src_buffer,
|
||||
unsigned src_offset,
|
||||
boolean src_tiled,
|
||||
short dst_pitch,
|
||||
struct pipe_buffer_handle *dst_buffer,
|
||||
unsigned dst_offset,
|
||||
boolean dst_tiled,
|
||||
short src_x, short src_y,
|
||||
short dst_x, short dst_y,
|
||||
short w, short h,
|
||||
unsigned logic_op);
|
||||
#endif
|
||||
@@ -0,0 +1,268 @@
|
||||
/*
|
||||
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 "pipe/p_util.h"
|
||||
|
||||
#include "brw_context.h"
|
||||
#include "brw_state.h"
|
||||
#include "brw_defines.h"
|
||||
#include "brw_util.h"
|
||||
|
||||
|
||||
static int brw_translate_compare_func(int func)
|
||||
{
|
||||
switch(func) {
|
||||
case PIPE_FUNC_NEVER:
|
||||
return BRW_COMPAREFUNCTION_NEVER;
|
||||
case PIPE_FUNC_LESS:
|
||||
return BRW_COMPAREFUNCTION_LESS;
|
||||
case PIPE_FUNC_LEQUAL:
|
||||
return BRW_COMPAREFUNCTION_LEQUAL;
|
||||
case PIPE_FUNC_GREATER:
|
||||
return BRW_COMPAREFUNCTION_GREATER;
|
||||
case PIPE_FUNC_GEQUAL:
|
||||
return BRW_COMPAREFUNCTION_GEQUAL;
|
||||
case PIPE_FUNC_NOTEQUAL:
|
||||
return BRW_COMPAREFUNCTION_NOTEQUAL;
|
||||
case PIPE_FUNC_EQUAL:
|
||||
return BRW_COMPAREFUNCTION_EQUAL;
|
||||
case PIPE_FUNC_ALWAYS:
|
||||
return BRW_COMPAREFUNCTION_ALWAYS;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Unknown value in %s: %x\n", __FUNCTION__, func);
|
||||
return BRW_COMPAREFUNCTION_ALWAYS;
|
||||
}
|
||||
|
||||
static int brw_translate_stencil_op(int op)
|
||||
{
|
||||
switch(op) {
|
||||
case PIPE_STENCIL_OP_KEEP:
|
||||
return BRW_STENCILOP_KEEP;
|
||||
case PIPE_STENCIL_OP_ZERO:
|
||||
return BRW_STENCILOP_ZERO;
|
||||
case PIPE_STENCIL_OP_REPLACE:
|
||||
return BRW_STENCILOP_REPLACE;
|
||||
case PIPE_STENCIL_OP_INCR:
|
||||
return BRW_STENCILOP_INCRSAT;
|
||||
case PIPE_STENCIL_OP_DECR:
|
||||
return BRW_STENCILOP_DECRSAT;
|
||||
case PIPE_STENCIL_OP_INCR_WRAP:
|
||||
return BRW_STENCILOP_INCR;
|
||||
case PIPE_STENCIL_OP_DECR_WRAP:
|
||||
return BRW_STENCILOP_DECR;
|
||||
case PIPE_STENCIL_OP_INVERT:
|
||||
return BRW_STENCILOP_INVERT;
|
||||
default:
|
||||
return BRW_STENCILOP_ZERO;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int brw_translate_logic_op(int opcode)
|
||||
{
|
||||
switch(opcode) {
|
||||
case PIPE_LOGICOP_CLEAR:
|
||||
return BRW_LOGICOPFUNCTION_CLEAR;
|
||||
case PIPE_LOGICOP_AND:
|
||||
return BRW_LOGICOPFUNCTION_AND;
|
||||
case PIPE_LOGICOP_AND_REVERSE:
|
||||
return BRW_LOGICOPFUNCTION_AND_REVERSE;
|
||||
case PIPE_LOGICOP_COPY:
|
||||
return BRW_LOGICOPFUNCTION_COPY;
|
||||
case PIPE_LOGICOP_COPY_INVERTED:
|
||||
return BRW_LOGICOPFUNCTION_COPY_INVERTED;
|
||||
case PIPE_LOGICOP_AND_INVERTED:
|
||||
return BRW_LOGICOPFUNCTION_AND_INVERTED;
|
||||
case PIPE_LOGICOP_NOOP:
|
||||
return BRW_LOGICOPFUNCTION_NOOP;
|
||||
case PIPE_LOGICOP_XOR:
|
||||
return BRW_LOGICOPFUNCTION_XOR;
|
||||
case PIPE_LOGICOP_OR:
|
||||
return BRW_LOGICOPFUNCTION_OR;
|
||||
case PIPE_LOGICOP_OR_INVERTED:
|
||||
return BRW_LOGICOPFUNCTION_OR_INVERTED;
|
||||
case PIPE_LOGICOP_NOR:
|
||||
return BRW_LOGICOPFUNCTION_NOR;
|
||||
case PIPE_LOGICOP_EQUIV:
|
||||
return BRW_LOGICOPFUNCTION_EQUIV;
|
||||
case PIPE_LOGICOP_INVERT:
|
||||
return BRW_LOGICOPFUNCTION_INVERT;
|
||||
case PIPE_LOGICOP_OR_REVERSE:
|
||||
return BRW_LOGICOPFUNCTION_OR_REVERSE;
|
||||
case PIPE_LOGICOP_NAND:
|
||||
return BRW_LOGICOPFUNCTION_NAND;
|
||||
case PIPE_LOGICOP_SET:
|
||||
return BRW_LOGICOPFUNCTION_SET;
|
||||
default:
|
||||
return BRW_LOGICOPFUNCTION_SET;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void upload_cc_vp( struct brw_context *brw )
|
||||
{
|
||||
struct brw_cc_viewport ccv;
|
||||
|
||||
memset(&ccv, 0, sizeof(ccv));
|
||||
|
||||
ccv.min_depth = 0.0;
|
||||
ccv.max_depth = 1.0;
|
||||
|
||||
brw->cc.vp_gs_offset = brw_cache_data( &brw->cache[BRW_CC_VP], &ccv );
|
||||
}
|
||||
|
||||
const struct brw_tracked_state brw_cc_vp = {
|
||||
.dirty = {
|
||||
.brw = BRW_NEW_CONTEXT,
|
||||
.cache = 0
|
||||
},
|
||||
.update = upload_cc_vp
|
||||
};
|
||||
|
||||
|
||||
static void upload_cc_unit( struct brw_context *brw )
|
||||
{
|
||||
struct brw_cc_unit_state cc;
|
||||
|
||||
memset(&cc, 0, sizeof(cc));
|
||||
|
||||
/* BRW_NEW_DEPTH_STENCIL */
|
||||
if (brw->attribs.DepthStencil->stencil.front_enabled) {
|
||||
cc.cc0.stencil_enable = brw->attribs.DepthStencil->stencil.front_enabled;
|
||||
cc.cc0.stencil_func = brw_translate_compare_func(brw->attribs.DepthStencil->stencil.front_func);
|
||||
cc.cc0.stencil_fail_op = brw_translate_stencil_op(brw->attribs.DepthStencil->stencil.front_fail_op);
|
||||
cc.cc0.stencil_pass_depth_fail_op = brw_translate_stencil_op(
|
||||
brw->attribs.DepthStencil->stencil.front_zfail_op);
|
||||
cc.cc0.stencil_pass_depth_pass_op = brw_translate_stencil_op(
|
||||
brw->attribs.DepthStencil->stencil.front_zpass_op);
|
||||
cc.cc1.stencil_ref = brw->attribs.DepthStencil->stencil.ref_value[0];
|
||||
cc.cc1.stencil_write_mask = brw->attribs.DepthStencil->stencil.write_mask[0];
|
||||
cc.cc1.stencil_test_mask = brw->attribs.DepthStencil->stencil.value_mask[0];
|
||||
|
||||
if (brw->attribs.DepthStencil->stencil.back_enabled) {
|
||||
cc.cc0.bf_stencil_enable = brw->attribs.DepthStencil->stencil.back_enabled;
|
||||
cc.cc0.bf_stencil_func = brw_translate_compare_func(
|
||||
brw->attribs.DepthStencil->stencil.back_func);
|
||||
cc.cc0.bf_stencil_fail_op = brw_translate_stencil_op(
|
||||
brw->attribs.DepthStencil->stencil.back_fail_op);
|
||||
cc.cc0.bf_stencil_pass_depth_fail_op = brw_translate_stencil_op(
|
||||
brw->attribs.DepthStencil->stencil.back_zfail_op);
|
||||
cc.cc0.bf_stencil_pass_depth_pass_op = brw_translate_stencil_op(
|
||||
brw->attribs.DepthStencil->stencil.back_zpass_op);
|
||||
cc.cc1.bf_stencil_ref = brw->attribs.DepthStencil->stencil.ref_value[1];
|
||||
cc.cc2.bf_stencil_write_mask = brw->attribs.DepthStencil->stencil.write_mask[1];
|
||||
cc.cc2.bf_stencil_test_mask = brw->attribs.DepthStencil->stencil.value_mask[1];
|
||||
}
|
||||
|
||||
/* Not really sure about this:
|
||||
*/
|
||||
if (brw->attribs.DepthStencil->stencil.write_mask[0] ||
|
||||
(brw->attribs.DepthStencil->stencil.back_enabled &&
|
||||
brw->attribs.DepthStencil->stencil.write_mask[1]))
|
||||
cc.cc0.stencil_write_enable = 1;
|
||||
}
|
||||
|
||||
/* BRW_NEW_BLEND */
|
||||
if (brw->attribs.Blend->logicop_enable) {
|
||||
cc.cc2.logicop_enable = 1;
|
||||
cc.cc5.logicop_func = brw_translate_logic_op( brw->attribs.Blend->logicop_func );
|
||||
}
|
||||
else if (brw->attribs.Blend->blend_enable) {
|
||||
int eqRGB = brw->attribs.Blend->rgb_func;
|
||||
int eqA = brw->attribs.Blend->alpha_func;
|
||||
int srcRGB = brw->attribs.Blend->rgb_src_factor;
|
||||
int dstRGB = brw->attribs.Blend->rgb_dst_factor;
|
||||
int srcA = brw->attribs.Blend->alpha_src_factor;
|
||||
int dstA = brw->attribs.Blend->alpha_dst_factor;
|
||||
|
||||
if (eqRGB == PIPE_BLEND_MIN || eqRGB == PIPE_BLEND_MAX) {
|
||||
srcRGB = dstRGB = PIPE_BLENDFACTOR_ONE;
|
||||
}
|
||||
|
||||
if (eqA == PIPE_BLEND_MIN || eqA == PIPE_BLEND_MAX) {
|
||||
srcA = dstA = PIPE_BLENDFACTOR_ONE;
|
||||
}
|
||||
|
||||
cc.cc6.dest_blend_factor = brw_translate_blend_factor(dstRGB);
|
||||
cc.cc6.src_blend_factor = brw_translate_blend_factor(srcRGB);
|
||||
cc.cc6.blend_function = brw_translate_blend_equation( eqRGB );
|
||||
|
||||
cc.cc5.ia_dest_blend_factor = brw_translate_blend_factor(dstA);
|
||||
cc.cc5.ia_src_blend_factor = brw_translate_blend_factor(srcA);
|
||||
cc.cc5.ia_blend_function = brw_translate_blend_equation( eqA );
|
||||
|
||||
cc.cc3.blend_enable = 1;
|
||||
cc.cc3.ia_blend_enable = (srcA != srcRGB ||
|
||||
dstA != dstRGB ||
|
||||
eqA != eqRGB);
|
||||
}
|
||||
|
||||
/* BRW_NEW_ALPHATEST
|
||||
*/
|
||||
if (brw->attribs.AlphaTest->enabled) {
|
||||
cc.cc3.alpha_test = 1;
|
||||
cc.cc3.alpha_test_func = brw_translate_compare_func(brw->attribs.AlphaTest->func);
|
||||
|
||||
UNCLAMPED_FLOAT_TO_UBYTE(cc.cc7.alpha_ref.ub[0], brw->attribs.AlphaTest->ref);
|
||||
|
||||
cc.cc3.alpha_test_format = BRW_ALPHATEST_FORMAT_UNORM8;
|
||||
}
|
||||
|
||||
if (brw->attribs.Blend->dither) {
|
||||
cc.cc5.dither_enable = 1;
|
||||
cc.cc6.y_dither_offset = 0;
|
||||
cc.cc6.x_dither_offset = 0;
|
||||
}
|
||||
|
||||
if (brw->attribs.DepthStencil->depth.enabled) {
|
||||
cc.cc2.depth_test = brw->attribs.DepthStencil->depth.enabled;
|
||||
cc.cc2.depth_test_function = brw_translate_compare_func(brw->attribs.DepthStencil->depth.func);
|
||||
cc.cc2.depth_write_enable = brw->attribs.DepthStencil->depth.writemask;
|
||||
}
|
||||
|
||||
/* CACHE_NEW_CC_VP */
|
||||
cc.cc4.cc_viewport_state_offset = brw->cc.vp_gs_offset >> 5;
|
||||
|
||||
if (BRW_DEBUG & DEBUG_STATS)
|
||||
cc.cc5.statistics_enable = 1;
|
||||
|
||||
brw->cc.state_gs_offset = brw_cache_data( &brw->cache[BRW_CC_UNIT], &cc );
|
||||
}
|
||||
|
||||
const struct brw_tracked_state brw_cc_unit = {
|
||||
.dirty = {
|
||||
.brw = BRW_NEW_DEPTH_STENCIL | BRW_NEW_BLEND | BRW_NEW_ALPHA_TEST,
|
||||
.cache = CACHE_NEW_CC_VP
|
||||
},
|
||||
.update = upload_cc_unit
|
||||
};
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
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_defines.h"
|
||||
#include "brw_context.h"
|
||||
#include "brw_eu.h"
|
||||
#include "brw_util.h"
|
||||
#include "brw_state.h"
|
||||
#include "brw_clip.h"
|
||||
|
||||
#define FRONT_UNFILLED_BIT 0x1
|
||||
#define BACK_UNFILLED_BIT 0x2
|
||||
|
||||
|
||||
static void compile_clip_prog( struct brw_context *brw,
|
||||
struct brw_clip_prog_key *key )
|
||||
{
|
||||
struct brw_clip_compile c;
|
||||
const unsigned *program;
|
||||
unsigned program_size;
|
||||
unsigned delta;
|
||||
unsigned i;
|
||||
|
||||
memset(&c, 0, sizeof(c));
|
||||
|
||||
/* Begin the compilation:
|
||||
*/
|
||||
brw_init_compile(&c.func);
|
||||
|
||||
c.func.single_program_flow = 1;
|
||||
|
||||
c.key = *key;
|
||||
|
||||
|
||||
/* Need to locate the two positions present in vertex + header.
|
||||
* These are currently hardcoded:
|
||||
*/
|
||||
c.header_position_offset = ATTR_SIZE;
|
||||
|
||||
for (i = 0, delta = REG_SIZE; i < PIPE_MAX_SHADER_OUTPUTS; i++)
|
||||
if (c.key.attrs & (1<<i)) {
|
||||
c.offset[i] = delta;
|
||||
delta += ATTR_SIZE;
|
||||
}
|
||||
|
||||
c.nr_attrs = brw_count_bits(c.key.attrs);
|
||||
c.nr_regs = (c.nr_attrs + 1) / 2 + 1; /* are vertices packed, or reg-aligned? */
|
||||
c.nr_bytes = c.nr_regs * REG_SIZE;
|
||||
|
||||
c.prog_data.clip_mode = c.key.clip_mode; /* XXX */
|
||||
|
||||
/* For some reason the thread is spawned with only 4 channels
|
||||
* unmasked.
|
||||
*/
|
||||
brw_set_mask_control(&c.func, BRW_MASK_DISABLE);
|
||||
|
||||
|
||||
/* Would ideally have the option of producing a program which could
|
||||
* do all three:
|
||||
*/
|
||||
switch (key->primitive) {
|
||||
case PIPE_PRIM_TRIANGLES:
|
||||
#if 0
|
||||
if (key->do_unfilled)
|
||||
brw_emit_unfilled_clip( &c );
|
||||
else
|
||||
#endif
|
||||
brw_emit_tri_clip( &c );
|
||||
break;
|
||||
case PIPE_PRIM_LINES:
|
||||
brw_emit_line_clip( &c );
|
||||
break;
|
||||
case PIPE_PRIM_POINTS:
|
||||
brw_emit_point_clip( &c );
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* get the program
|
||||
*/
|
||||
program = brw_get_program(&c.func, &program_size);
|
||||
|
||||
/* Upload
|
||||
*/
|
||||
brw->clip.prog_gs_offset = brw_upload_cache( &brw->cache[BRW_CLIP_PROG],
|
||||
&c.key,
|
||||
sizeof(c.key),
|
||||
program,
|
||||
program_size,
|
||||
&c.prog_data,
|
||||
&brw->clip.prog_data );
|
||||
}
|
||||
|
||||
|
||||
static boolean search_cache( struct brw_context *brw,
|
||||
struct brw_clip_prog_key *key )
|
||||
{
|
||||
return brw_search_cache(&brw->cache[BRW_CLIP_PROG],
|
||||
key, sizeof(*key),
|
||||
&brw->clip.prog_data,
|
||||
&brw->clip.prog_gs_offset);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Calculate interpolants for triangle and line rasterization.
|
||||
*/
|
||||
static void upload_clip_prog(struct brw_context *brw)
|
||||
{
|
||||
struct brw_clip_prog_key key;
|
||||
|
||||
memset(&key, 0, sizeof(key));
|
||||
|
||||
/* Populate the key:
|
||||
*/
|
||||
/* BRW_NEW_REDUCED_PRIMITIVE */
|
||||
key.primitive = brw->reduced_primitive;
|
||||
/* CACHE_NEW_VS_PROG */
|
||||
key.attrs = brw->vs.prog_data->outputs_written;
|
||||
/* BRW_NEW_RASTER */
|
||||
key.do_flat_shading = (brw->attribs.Raster->flatshade);
|
||||
/* BRW_NEW_CLIP */
|
||||
key.nr_userclip = brw->attribs.Clip.nr; /* XXX */
|
||||
key.clip_mode = BRW_CLIPMODE_NORMAL;
|
||||
|
||||
if (key.primitive == PIPE_PRIM_TRIANGLES) {
|
||||
if (brw->attribs.Raster->cull_mode == PIPE_WINDING_BOTH)
|
||||
key.clip_mode = BRW_CLIPMODE_REJECT_ALL;
|
||||
else {
|
||||
if (brw->attribs.Raster->fill_cw != PIPE_POLYGON_MODE_FILL ||
|
||||
brw->attribs.Raster->fill_ccw != PIPE_POLYGON_MODE_FILL)
|
||||
key.do_unfilled = 1;
|
||||
|
||||
/* Most cases the fixed function units will handle. Cases where
|
||||
* one or more polygon faces are unfilled will require help:
|
||||
*/
|
||||
if (key.do_unfilled) {
|
||||
key.clip_mode = BRW_CLIPMODE_CLIP_NON_REJECTED;
|
||||
|
||||
if (brw->attribs.Raster->offset_cw ||
|
||||
brw->attribs.Raster->offset_ccw) {
|
||||
key.offset_units = brw->attribs.Raster->offset_units;
|
||||
key.offset_factor = brw->attribs.Raster->offset_scale;
|
||||
}
|
||||
key.fill_ccw = brw->attribs.Raster->fill_ccw;
|
||||
key.fill_cw = brw->attribs.Raster->fill_cw;
|
||||
key.offset_ccw = brw->attribs.Raster->offset_ccw;
|
||||
key.offset_cw = brw->attribs.Raster->offset_cw;
|
||||
if (brw->attribs.Raster->light_twoside &&
|
||||
key.fill_cw != CLIP_CULL)
|
||||
key.copy_bfc_cw = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!search_cache(brw, &key))
|
||||
compile_clip_prog( brw, &key );
|
||||
}
|
||||
|
||||
const struct brw_tracked_state brw_clip_prog = {
|
||||
.dirty = {
|
||||
.brw = (BRW_NEW_RASTERIZER |
|
||||
BRW_NEW_CLIP |
|
||||
BRW_NEW_REDUCED_PRIMITIVE),
|
||||
.cache = CACHE_NEW_VS_PROG
|
||||
},
|
||||
.update = upload_clip_prog
|
||||
};
|
||||
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
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>
|
||||
*/
|
||||
|
||||
#ifndef BRW_CLIP_H
|
||||
#define BRW_CLIP_H
|
||||
|
||||
|
||||
#include "brw_context.h"
|
||||
#include "brw_eu.h"
|
||||
|
||||
#define MAX_VERTS (3+6+6)
|
||||
|
||||
/* Note that if unfilled primitives are being emitted, we have to fix
|
||||
* up polygon offset and flatshading at this point:
|
||||
*/
|
||||
struct brw_clip_prog_key {
|
||||
unsigned attrs:32;
|
||||
unsigned primitive:4;
|
||||
unsigned nr_userclip:3;
|
||||
unsigned do_flat_shading:1;
|
||||
unsigned do_unfilled:1;
|
||||
unsigned fill_cw:2; /* includes cull information */
|
||||
unsigned fill_ccw:2; /* includes cull information */
|
||||
unsigned offset_cw:1;
|
||||
unsigned offset_ccw:1;
|
||||
unsigned pad0:17;
|
||||
|
||||
unsigned copy_bfc_cw:1;
|
||||
unsigned copy_bfc_ccw:1;
|
||||
unsigned clip_mode:3;
|
||||
unsigned pad1:27;
|
||||
|
||||
float offset_factor;
|
||||
float offset_units;
|
||||
};
|
||||
|
||||
|
||||
#define CLIP_LINE 0
|
||||
#define CLIP_POINT 1
|
||||
#define CLIP_FILL 2
|
||||
#define CLIP_CULL 3
|
||||
|
||||
|
||||
#define PRIM_MASK (0x1f)
|
||||
|
||||
struct brw_clip_compile {
|
||||
struct brw_compile func;
|
||||
struct brw_clip_prog_key key;
|
||||
struct brw_clip_prog_data prog_data;
|
||||
|
||||
struct {
|
||||
struct brw_reg R0;
|
||||
struct brw_reg vertex[MAX_VERTS];
|
||||
|
||||
struct brw_reg t;
|
||||
struct brw_reg t0, t1;
|
||||
struct brw_reg dp0, dp1;
|
||||
|
||||
struct brw_reg dpPrev;
|
||||
struct brw_reg dp;
|
||||
struct brw_reg loopcount;
|
||||
struct brw_reg nr_verts;
|
||||
struct brw_reg planemask;
|
||||
|
||||
struct brw_reg inlist;
|
||||
struct brw_reg outlist;
|
||||
struct brw_reg freelist;
|
||||
|
||||
struct brw_reg dir;
|
||||
struct brw_reg tmp0, tmp1;
|
||||
struct brw_reg offset;
|
||||
|
||||
struct brw_reg fixed_planes;
|
||||
struct brw_reg plane_equation;
|
||||
} reg;
|
||||
|
||||
/* 3 different ways of expressing vertex size:
|
||||
*/
|
||||
unsigned nr_attrs;
|
||||
unsigned nr_regs;
|
||||
unsigned nr_bytes;
|
||||
|
||||
unsigned first_tmp;
|
||||
unsigned last_tmp;
|
||||
|
||||
boolean need_direction;
|
||||
|
||||
unsigned last_mrf;
|
||||
|
||||
unsigned header_position_offset;
|
||||
unsigned offset[PIPE_ATTRIB_MAX];
|
||||
};
|
||||
|
||||
#define ATTR_SIZE (4*4)
|
||||
|
||||
/* Points are only culled, so no need for a clip routine, however it
|
||||
* works out easier to have a dummy one.
|
||||
*/
|
||||
void brw_emit_unfilled_clip( struct brw_clip_compile *c );
|
||||
void brw_emit_tri_clip( struct brw_clip_compile *c );
|
||||
void brw_emit_line_clip( struct brw_clip_compile *c );
|
||||
void brw_emit_point_clip( struct brw_clip_compile *c );
|
||||
|
||||
/* brw_clip_tri.c, for use by the unfilled clip routine:
|
||||
*/
|
||||
void brw_clip_tri_init_vertices( struct brw_clip_compile *c );
|
||||
void brw_clip_tri_flat_shade( struct brw_clip_compile *c );
|
||||
void brw_clip_tri( struct brw_clip_compile *c );
|
||||
void brw_clip_tri_emit_polygon( struct brw_clip_compile *c );
|
||||
void brw_clip_tri_alloc_regs( struct brw_clip_compile *c,
|
||||
unsigned nr_verts );
|
||||
|
||||
|
||||
/* Utils:
|
||||
*/
|
||||
|
||||
void brw_clip_interp_vertex( struct brw_clip_compile *c,
|
||||
struct brw_indirect dest_ptr,
|
||||
struct brw_indirect v0_ptr, /* from */
|
||||
struct brw_indirect v1_ptr, /* to */
|
||||
struct brw_reg t0,
|
||||
boolean force_edgeflag );
|
||||
|
||||
void brw_clip_init_planes( struct brw_clip_compile *c );
|
||||
|
||||
void brw_clip_emit_vue(struct brw_clip_compile *c,
|
||||
struct brw_indirect vert,
|
||||
boolean allocate,
|
||||
boolean eot,
|
||||
unsigned header);
|
||||
|
||||
void brw_clip_kill_thread(struct brw_clip_compile *c);
|
||||
|
||||
struct brw_reg brw_clip_plane_stride( struct brw_clip_compile *c );
|
||||
struct brw_reg brw_clip_plane0_address( struct brw_clip_compile *c );
|
||||
|
||||
void brw_clip_copy_colors( struct brw_clip_compile *c,
|
||||
unsigned to, unsigned from );
|
||||
|
||||
void brw_clip_init_clipmask( struct brw_clip_compile *c );
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,245 @@
|
||||
/*
|
||||
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_defines.h"
|
||||
#include "brw_context.h"
|
||||
#include "brw_eu.h"
|
||||
#include "brw_util.h"
|
||||
#include "brw_clip.h"
|
||||
|
||||
|
||||
|
||||
static void brw_clip_line_alloc_regs( struct brw_clip_compile *c )
|
||||
{
|
||||
unsigned i = 0,j;
|
||||
|
||||
/* Register usage is static, precompute here:
|
||||
*/
|
||||
c->reg.R0 = retype(brw_vec8_grf(i, 0), BRW_REGISTER_TYPE_UD); i++;
|
||||
|
||||
if (c->key.nr_userclip) {
|
||||
c->reg.fixed_planes = brw_vec4_grf(i, 0);
|
||||
i += (6 + c->key.nr_userclip + 1) / 2;
|
||||
|
||||
c->prog_data.curb_read_length = (6 + c->key.nr_userclip + 1) / 2;
|
||||
}
|
||||
else
|
||||
c->prog_data.curb_read_length = 0;
|
||||
|
||||
|
||||
/* Payload vertices plus space for more generated vertices:
|
||||
*/
|
||||
for (j = 0; j < 4; j++) {
|
||||
c->reg.vertex[j] = brw_vec4_grf(i, 0);
|
||||
i += c->nr_regs;
|
||||
}
|
||||
|
||||
c->reg.t = brw_vec1_grf(i, 0);
|
||||
c->reg.t0 = brw_vec1_grf(i, 1);
|
||||
c->reg.t1 = brw_vec1_grf(i, 2);
|
||||
c->reg.planemask = retype(brw_vec1_grf(i, 3), BRW_REGISTER_TYPE_UD);
|
||||
c->reg.plane_equation = brw_vec4_grf(i, 4);
|
||||
i++;
|
||||
|
||||
c->reg.dp0 = brw_vec1_grf(i, 0); /* fixme - dp4 will clobber r.1,2,3 */
|
||||
c->reg.dp1 = brw_vec1_grf(i, 4);
|
||||
i++;
|
||||
|
||||
if (!c->key.nr_userclip) {
|
||||
c->reg.fixed_planes = brw_vec8_grf(i, 0);
|
||||
i++;
|
||||
}
|
||||
|
||||
|
||||
c->first_tmp = i;
|
||||
c->last_tmp = i;
|
||||
|
||||
c->prog_data.urb_read_length = c->nr_regs; /* ? */
|
||||
c->prog_data.total_grf = i;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Line clipping, more or less following the following algorithm:
|
||||
*
|
||||
* for (p=0;p<MAX_PLANES;p++) {
|
||||
* if (clipmask & (1 << p)) {
|
||||
* float dp0 = DOTPROD( vtx0, plane[p] );
|
||||
* float dp1 = DOTPROD( vtx1, plane[p] );
|
||||
*
|
||||
* if (IS_NEGATIVE(dp1)) {
|
||||
* float t = dp1 / (dp1 - dp0);
|
||||
* if (t > t1) t1 = t;
|
||||
* } else {
|
||||
* float t = dp0 / (dp0 - dp1);
|
||||
* if (t > t0) t0 = t;
|
||||
* }
|
||||
*
|
||||
* if (t0 + t1 >= 1.0)
|
||||
* return;
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* interp( ctx, newvtx0, vtx0, vtx1, t0 );
|
||||
* interp( ctx, newvtx1, vtx1, vtx0, t1 );
|
||||
*
|
||||
*/
|
||||
static void clip_and_emit_line( struct brw_clip_compile *c )
|
||||
{
|
||||
struct brw_compile *p = &c->func;
|
||||
struct brw_indirect vtx0 = brw_indirect(0, 0);
|
||||
struct brw_indirect vtx1 = brw_indirect(1, 0);
|
||||
struct brw_indirect newvtx0 = brw_indirect(2, 0);
|
||||
struct brw_indirect newvtx1 = brw_indirect(3, 0);
|
||||
struct brw_indirect plane_ptr = brw_indirect(4, 0);
|
||||
struct brw_instruction *plane_loop;
|
||||
struct brw_instruction *plane_active;
|
||||
struct brw_instruction *is_negative;
|
||||
struct brw_instruction *is_neg2;
|
||||
struct brw_instruction *not_culled;
|
||||
struct brw_reg v1_null_ud = retype(vec1(brw_null_reg()), BRW_REGISTER_TYPE_UD);
|
||||
|
||||
brw_MOV(p, get_addr_reg(vtx0), brw_address(c->reg.vertex[0]));
|
||||
brw_MOV(p, get_addr_reg(vtx1), brw_address(c->reg.vertex[1]));
|
||||
brw_MOV(p, get_addr_reg(newvtx0), brw_address(c->reg.vertex[2]));
|
||||
brw_MOV(p, get_addr_reg(newvtx1), brw_address(c->reg.vertex[3]));
|
||||
brw_MOV(p, get_addr_reg(plane_ptr), brw_clip_plane0_address(c));
|
||||
|
||||
/* Note: init t0, t1 together:
|
||||
*/
|
||||
brw_MOV(p, vec2(c->reg.t0), brw_imm_f(0));
|
||||
|
||||
brw_clip_init_planes(c);
|
||||
brw_clip_init_clipmask(c);
|
||||
|
||||
/* -ve rhw workaround */
|
||||
brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
|
||||
brw_AND(p, brw_null_reg(), get_element_ud(c->reg.R0, 2),
|
||||
brw_imm_ud(1<<20));
|
||||
brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(0x3f));
|
||||
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
|
||||
|
||||
plane_loop = brw_DO(p, BRW_EXECUTE_1);
|
||||
{
|
||||
/* if (planemask & 1)
|
||||
*/
|
||||
brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
|
||||
brw_AND(p, v1_null_ud, c->reg.planemask, brw_imm_ud(1));
|
||||
|
||||
plane_active = brw_IF(p, BRW_EXECUTE_1);
|
||||
{
|
||||
if (c->key.nr_userclip)
|
||||
brw_MOV(p, c->reg.plane_equation, deref_4f(plane_ptr, 0));
|
||||
else
|
||||
brw_MOV(p, c->reg.plane_equation, deref_4b(plane_ptr, 0));
|
||||
|
||||
#if 0
|
||||
/* dp = DP4(vtx->position, plane)
|
||||
*/
|
||||
brw_DP4(p, vec4(c->reg.dp0), deref_4f(vtx0, c->offset[VERT_RESULT_HPOS]), c->reg.plane_equation);
|
||||
|
||||
/* if (IS_NEGATIVE(dp1))
|
||||
*/
|
||||
brw_set_conditionalmod(p, BRW_CONDITIONAL_L);
|
||||
brw_DP4(p, vec4(c->reg.dp1), deref_4f(vtx1, c->offset[VERT_RESULT_HPOS]), c->reg.plane_equation);
|
||||
#else
|
||||
#warning "disabled"
|
||||
#endif
|
||||
is_negative = brw_IF(p, BRW_EXECUTE_1);
|
||||
{
|
||||
brw_ADD(p, c->reg.t, c->reg.dp1, negate(c->reg.dp0));
|
||||
brw_math_invert(p, c->reg.t, c->reg.t);
|
||||
brw_MUL(p, c->reg.t, c->reg.t, c->reg.dp1);
|
||||
|
||||
brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_G, c->reg.t, c->reg.t1 );
|
||||
brw_MOV(p, c->reg.t1, c->reg.t);
|
||||
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
|
||||
}
|
||||
is_negative = brw_ELSE(p, is_negative);
|
||||
{
|
||||
/* Coming back in. We know that both cannot be negative
|
||||
* because the line would have been culled in that case.
|
||||
*/
|
||||
|
||||
/* If both are positive, do nothing */
|
||||
brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.dp0, brw_imm_f(0.0));
|
||||
is_neg2 = brw_IF(p, BRW_EXECUTE_1);
|
||||
{
|
||||
brw_ADD(p, c->reg.t, c->reg.dp0, negate(c->reg.dp1));
|
||||
brw_math_invert(p, c->reg.t, c->reg.t);
|
||||
brw_MUL(p, c->reg.t, c->reg.t, c->reg.dp0);
|
||||
|
||||
brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_G, c->reg.t, c->reg.t0 );
|
||||
brw_MOV(p, c->reg.t0, c->reg.t);
|
||||
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
|
||||
}
|
||||
brw_ENDIF(p, is_neg2);
|
||||
}
|
||||
brw_ENDIF(p, is_negative);
|
||||
}
|
||||
brw_ENDIF(p, plane_active);
|
||||
|
||||
/* plane_ptr++;
|
||||
*/
|
||||
brw_ADD(p, get_addr_reg(plane_ptr), get_addr_reg(plane_ptr), brw_clip_plane_stride(c));
|
||||
|
||||
/* while (planemask>>=1) != 0
|
||||
*/
|
||||
brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
|
||||
brw_SHR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(1));
|
||||
}
|
||||
brw_WHILE(p, plane_loop);
|
||||
|
||||
brw_ADD(p, c->reg.t, c->reg.t0, c->reg.t1);
|
||||
brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.t, brw_imm_f(1.0));
|
||||
not_culled = brw_IF(p, BRW_EXECUTE_1);
|
||||
{
|
||||
brw_clip_interp_vertex(c, newvtx0, vtx0, vtx1, c->reg.t0, FALSE);
|
||||
brw_clip_interp_vertex(c, newvtx1, vtx1, vtx0, c->reg.t1, FALSE);
|
||||
|
||||
brw_clip_emit_vue(c, newvtx0, 1, 0, (_3DPRIM_LINESTRIP << 2) | R02_PRIM_START);
|
||||
brw_clip_emit_vue(c, newvtx1, 0, 1, (_3DPRIM_LINESTRIP << 2) | R02_PRIM_END);
|
||||
}
|
||||
brw_ENDIF(p, not_culled);
|
||||
brw_clip_kill_thread(c);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void brw_emit_line_clip( struct brw_clip_compile *c )
|
||||
{
|
||||
brw_clip_line_alloc_regs(c);
|
||||
|
||||
if (c->key.do_flat_shading)
|
||||
brw_clip_copy_colors(c, 0, 1);
|
||||
|
||||
clip_and_emit_line(c);
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
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_defines.h"
|
||||
#include "brw_context.h"
|
||||
#include "brw_eu.h"
|
||||
#include "brw_util.h"
|
||||
#include "brw_clip.h"
|
||||
|
||||
|
||||
/* Point clipping, nothing to do?
|
||||
*/
|
||||
void brw_emit_point_clip( struct brw_clip_compile *c )
|
||||
{
|
||||
/* Send an empty message to kill the thread:
|
||||
*/
|
||||
brw_clip_tri_alloc_regs(c, 0);
|
||||
brw_clip_kill_thread(c);
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
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_state.h"
|
||||
#include "brw_defines.h"
|
||||
|
||||
|
||||
|
||||
static void upload_clip_unit( struct brw_context *brw )
|
||||
{
|
||||
struct brw_clip_unit_state clip;
|
||||
|
||||
memset(&clip, 0, sizeof(clip));
|
||||
|
||||
/* CACHE_NEW_CLIP_PROG */
|
||||
clip.thread0.grf_reg_count =
|
||||
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;
|
||||
clip.clip5.clip_mode = brw->clip.prog_data->clip_mode;
|
||||
|
||||
/* BRW_NEW_CURBE_OFFSETS */
|
||||
clip.thread3.const_urb_entry_read_offset = brw->curbe.clip_start * 2;
|
||||
|
||||
/* BRW_NEW_URB_FENCE */
|
||||
clip.thread4.nr_urb_entries = brw->urb.nr_clip_entries;
|
||||
clip.thread4.urb_entry_allocation_size = brw->urb.vsize - 1;
|
||||
clip.thread4.max_threads = 1; /* 2 threads */
|
||||
|
||||
if (BRW_DEBUG & DEBUG_STATS)
|
||||
clip.thread4.stats_enable = 1;
|
||||
|
||||
/* CONSTANT */
|
||||
clip.thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754;
|
||||
clip.thread1.single_program_flow = 1;
|
||||
clip.thread3.dispatch_grf_start_reg = 1;
|
||||
clip.thread3.urb_entry_read_offset = 0;
|
||||
clip.clip5.userclip_enable_flags = 0x7f;
|
||||
clip.clip5.userclip_must_clip = 1;
|
||||
clip.clip5.guard_band_enable = 0;
|
||||
clip.clip5.viewport_z_clip_enable = 1;
|
||||
clip.clip5.viewport_xy_clip_enable = 1;
|
||||
clip.clip5.vertex_position_space = BRW_CLIP_NDCSPACE;
|
||||
clip.clip5.api_mode = BRW_CLIP_API_OGL;
|
||||
clip.clip6.clipper_viewport_state_ptr = 0;
|
||||
clip.viewport_xmin = -1;
|
||||
clip.viewport_xmax = 1;
|
||||
clip.viewport_ymin = -1;
|
||||
clip.viewport_ymax = 1;
|
||||
|
||||
brw->clip.state_gs_offset = brw_cache_data( &brw->cache[BRW_CLIP_UNIT], &clip );
|
||||
}
|
||||
|
||||
|
||||
const struct brw_tracked_state brw_clip_unit = {
|
||||
.dirty = {
|
||||
.brw = (BRW_NEW_CURBE_OFFSETS |
|
||||
BRW_NEW_URB_FENCE),
|
||||
.cache = CACHE_NEW_CLIP_PROG
|
||||
},
|
||||
.update = upload_clip_unit
|
||||
};
|
||||
@@ -0,0 +1,566 @@
|
||||
/*
|
||||
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_defines.h"
|
||||
#include "brw_context.h"
|
||||
#include "brw_eu.h"
|
||||
#include "brw_util.h"
|
||||
#include "brw_clip.h"
|
||||
|
||||
static struct brw_reg get_tmp( struct brw_clip_compile *c )
|
||||
{
|
||||
struct brw_reg tmp = brw_vec4_grf(c->last_tmp, 0);
|
||||
|
||||
if (++c->last_tmp > c->prog_data.total_grf)
|
||||
c->prog_data.total_grf = c->last_tmp;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static void release_tmps( struct brw_clip_compile *c )
|
||||
{
|
||||
c->last_tmp = c->first_tmp;
|
||||
}
|
||||
|
||||
|
||||
void brw_clip_tri_alloc_regs( struct brw_clip_compile *c,
|
||||
unsigned nr_verts )
|
||||
{
|
||||
unsigned i = 0,j;
|
||||
|
||||
/* Register usage is static, precompute here:
|
||||
*/
|
||||
c->reg.R0 = retype(brw_vec8_grf(i, 0), BRW_REGISTER_TYPE_UD); i++;
|
||||
|
||||
if (c->key.nr_userclip) {
|
||||
c->reg.fixed_planes = brw_vec4_grf(i, 0);
|
||||
i += (6 + c->key.nr_userclip + 1) / 2;
|
||||
|
||||
c->prog_data.curb_read_length = (6 + c->key.nr_userclip + 1) / 2;
|
||||
}
|
||||
else
|
||||
c->prog_data.curb_read_length = 0;
|
||||
|
||||
|
||||
/* Payload vertices plus space for more generated vertices:
|
||||
*/
|
||||
for (j = 0; j < nr_verts; j++) {
|
||||
c->reg.vertex[j] = brw_vec4_grf(i, 0);
|
||||
i += c->nr_regs;
|
||||
}
|
||||
|
||||
if (c->nr_attrs & 1) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
unsigned delta = c->nr_attrs*16 + 32;
|
||||
brw_MOV(&c->func, byte_offset(c->reg.vertex[j], delta), brw_imm_f(0));
|
||||
}
|
||||
}
|
||||
|
||||
c->reg.t = brw_vec1_grf(i, 0);
|
||||
c->reg.loopcount = retype(brw_vec1_grf(i, 1), BRW_REGISTER_TYPE_UD);
|
||||
c->reg.nr_verts = retype(brw_vec1_grf(i, 2), BRW_REGISTER_TYPE_UD);
|
||||
c->reg.planemask = retype(brw_vec1_grf(i, 3), BRW_REGISTER_TYPE_UD);
|
||||
c->reg.plane_equation = brw_vec4_grf(i, 4);
|
||||
i++;
|
||||
|
||||
c->reg.dpPrev = brw_vec1_grf(i, 0); /* fixme - dp4 will clobber r.1,2,3 */
|
||||
c->reg.dp = brw_vec1_grf(i, 4);
|
||||
i++;
|
||||
|
||||
c->reg.inlist = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, i, 0);
|
||||
i++;
|
||||
|
||||
c->reg.outlist = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, i, 0);
|
||||
i++;
|
||||
|
||||
c->reg.freelist = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, i, 0);
|
||||
i++;
|
||||
|
||||
if (!c->key.nr_userclip) {
|
||||
c->reg.fixed_planes = brw_vec8_grf(i, 0);
|
||||
i++;
|
||||
}
|
||||
|
||||
if (c->key.do_unfilled) {
|
||||
c->reg.dir = brw_vec4_grf(i, 0);
|
||||
c->reg.offset = brw_vec4_grf(i, 4);
|
||||
i++;
|
||||
c->reg.tmp0 = brw_vec4_grf(i, 0);
|
||||
c->reg.tmp1 = brw_vec4_grf(i, 4);
|
||||
i++;
|
||||
}
|
||||
|
||||
c->first_tmp = i;
|
||||
c->last_tmp = i;
|
||||
|
||||
c->prog_data.urb_read_length = c->nr_regs; /* ? */
|
||||
c->prog_data.total_grf = i;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void brw_clip_tri_init_vertices( struct brw_clip_compile *c )
|
||||
{
|
||||
struct brw_compile *p = &c->func;
|
||||
struct brw_reg tmp0 = c->reg.loopcount; /* handy temporary */
|
||||
struct brw_instruction *is_rev;
|
||||
|
||||
/* Initial list of indices for incoming vertexes:
|
||||
*/
|
||||
brw_AND(p, tmp0, get_element_ud(c->reg.R0, 2), brw_imm_ud(PRIM_MASK));
|
||||
brw_CMP(p,
|
||||
vec1(brw_null_reg()),
|
||||
BRW_CONDITIONAL_EQ,
|
||||
tmp0,
|
||||
brw_imm_ud(_3DPRIM_TRISTRIP_REVERSE));
|
||||
|
||||
/* XXX: Is there an easier way to do this? Need to reverse every
|
||||
* second tristrip element: Can ignore sometimes?
|
||||
*/
|
||||
is_rev = brw_IF(p, BRW_EXECUTE_1);
|
||||
{
|
||||
brw_MOV(p, get_element(c->reg.inlist, 0), brw_address(c->reg.vertex[1]) );
|
||||
brw_MOV(p, get_element(c->reg.inlist, 1), brw_address(c->reg.vertex[0]) );
|
||||
if (c->need_direction)
|
||||
brw_MOV(p, c->reg.dir, brw_imm_f(-1));
|
||||
}
|
||||
is_rev = brw_ELSE(p, is_rev);
|
||||
{
|
||||
brw_MOV(p, get_element(c->reg.inlist, 0), brw_address(c->reg.vertex[0]) );
|
||||
brw_MOV(p, get_element(c->reg.inlist, 1), brw_address(c->reg.vertex[1]) );
|
||||
if (c->need_direction)
|
||||
brw_MOV(p, c->reg.dir, brw_imm_f(1));
|
||||
}
|
||||
brw_ENDIF(p, is_rev);
|
||||
|
||||
brw_MOV(p, get_element(c->reg.inlist, 2), brw_address(c->reg.vertex[2]) );
|
||||
brw_MOV(p, brw_vec8_grf(c->reg.outlist.nr, 0), brw_imm_f(0));
|
||||
brw_MOV(p, c->reg.nr_verts, brw_imm_ud(3));
|
||||
}
|
||||
|
||||
|
||||
|
||||
void brw_clip_tri_flat_shade( struct brw_clip_compile *c )
|
||||
{
|
||||
struct brw_compile *p = &c->func;
|
||||
struct brw_instruction *is_poly;
|
||||
struct brw_reg tmp0 = c->reg.loopcount; /* handy temporary */
|
||||
|
||||
brw_AND(p, tmp0, get_element_ud(c->reg.R0, 2), brw_imm_ud(PRIM_MASK));
|
||||
brw_CMP(p,
|
||||
vec1(brw_null_reg()),
|
||||
BRW_CONDITIONAL_EQ,
|
||||
tmp0,
|
||||
brw_imm_ud(_3DPRIM_POLYGON));
|
||||
|
||||
is_poly = brw_IF(p, BRW_EXECUTE_1);
|
||||
{
|
||||
brw_clip_copy_colors(c, 1, 0);
|
||||
brw_clip_copy_colors(c, 2, 0);
|
||||
}
|
||||
is_poly = brw_ELSE(p, is_poly);
|
||||
{
|
||||
brw_clip_copy_colors(c, 0, 2);
|
||||
brw_clip_copy_colors(c, 1, 2);
|
||||
}
|
||||
brw_ENDIF(p, is_poly);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Use mesa's clipping algorithms, translated to GEN4 assembly.
|
||||
*/
|
||||
void brw_clip_tri( struct brw_clip_compile *c )
|
||||
{
|
||||
#if 0
|
||||
struct brw_compile *p = &c->func;
|
||||
struct brw_indirect vtx = brw_indirect(0, 0);
|
||||
struct brw_indirect vtxPrev = brw_indirect(1, 0);
|
||||
struct brw_indirect vtxOut = brw_indirect(2, 0);
|
||||
struct brw_indirect plane_ptr = brw_indirect(3, 0);
|
||||
struct brw_indirect inlist_ptr = brw_indirect(4, 0);
|
||||
struct brw_indirect outlist_ptr = brw_indirect(5, 0);
|
||||
struct brw_indirect freelist_ptr = brw_indirect(6, 0);
|
||||
struct brw_instruction *plane_loop;
|
||||
struct brw_instruction *plane_active;
|
||||
struct brw_instruction *vertex_loop;
|
||||
struct brw_instruction *next_test;
|
||||
struct brw_instruction *prev_test;
|
||||
|
||||
brw_MOV(p, get_addr_reg(vtxPrev), brw_address(c->reg.vertex[2]) );
|
||||
brw_MOV(p, get_addr_reg(plane_ptr), brw_clip_plane0_address(c));
|
||||
brw_MOV(p, get_addr_reg(inlist_ptr), brw_address(c->reg.inlist));
|
||||
brw_MOV(p, get_addr_reg(outlist_ptr), brw_address(c->reg.outlist));
|
||||
|
||||
brw_MOV(p, get_addr_reg(freelist_ptr), brw_address(c->reg.vertex[3]) );
|
||||
|
||||
plane_loop = brw_DO(p, BRW_EXECUTE_1);
|
||||
{
|
||||
/* if (planemask & 1)
|
||||
*/
|
||||
brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
|
||||
brw_AND(p, vec1(brw_null_reg()), c->reg.planemask, brw_imm_ud(1));
|
||||
|
||||
plane_active = brw_IF(p, BRW_EXECUTE_1);
|
||||
{
|
||||
/* vtxOut = freelist_ptr++
|
||||
*/
|
||||
brw_MOV(p, get_addr_reg(vtxOut), get_addr_reg(freelist_ptr) );
|
||||
brw_ADD(p, get_addr_reg(freelist_ptr), get_addr_reg(freelist_ptr), brw_imm_uw(c->nr_regs * REG_SIZE));
|
||||
|
||||
if (c->key.nr_userclip)
|
||||
brw_MOV(p, c->reg.plane_equation, deref_4f(plane_ptr, 0));
|
||||
else
|
||||
brw_MOV(p, c->reg.plane_equation, deref_4b(plane_ptr, 0));
|
||||
|
||||
brw_MOV(p, c->reg.loopcount, c->reg.nr_verts);
|
||||
brw_MOV(p, c->reg.nr_verts, brw_imm_ud(0));
|
||||
|
||||
vertex_loop = brw_DO(p, BRW_EXECUTE_1);
|
||||
{
|
||||
/* vtx = *input_ptr;
|
||||
*/
|
||||
brw_MOV(p, get_addr_reg(vtx), deref_1uw(inlist_ptr, 0));
|
||||
|
||||
/* IS_NEGATIVE(prev) */
|
||||
brw_set_conditionalmod(p, BRW_CONDITIONAL_L);
|
||||
brw_DP4(p, vec4(c->reg.dpPrev), deref_4f(vtxPrev, c->offset[VERT_RESULT_HPOS]), c->reg.plane_equation);
|
||||
prev_test = brw_IF(p, BRW_EXECUTE_1);
|
||||
{
|
||||
/* IS_POSITIVE(next)
|
||||
*/
|
||||
brw_set_conditionalmod(p, BRW_CONDITIONAL_GE);
|
||||
brw_DP4(p, vec4(c->reg.dp), deref_4f(vtx, c->offset[VERT_RESULT_HPOS]), c->reg.plane_equation);
|
||||
next_test = brw_IF(p, BRW_EXECUTE_1);
|
||||
{
|
||||
|
||||
/* Coming back in.
|
||||
*/
|
||||
brw_ADD(p, c->reg.t, c->reg.dpPrev, negate(c->reg.dp));
|
||||
brw_math_invert(p, c->reg.t, c->reg.t);
|
||||
brw_MUL(p, c->reg.t, c->reg.t, c->reg.dpPrev);
|
||||
|
||||
/* If (vtxOut == 0) vtxOut = vtxPrev
|
||||
*/
|
||||
brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_EQ, get_addr_reg(vtxOut), brw_imm_uw(0) );
|
||||
brw_MOV(p, get_addr_reg(vtxOut), get_addr_reg(vtxPrev) );
|
||||
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
|
||||
|
||||
brw_clip_interp_vertex(c, vtxOut, vtxPrev, vtx, c->reg.t, FALSE);
|
||||
|
||||
/* *outlist_ptr++ = vtxOut;
|
||||
* nr_verts++;
|
||||
* vtxOut = 0;
|
||||
*/
|
||||
brw_MOV(p, deref_1uw(outlist_ptr, 0), get_addr_reg(vtxOut));
|
||||
brw_ADD(p, get_addr_reg(outlist_ptr), get_addr_reg(outlist_ptr), brw_imm_uw(sizeof(short)));
|
||||
brw_ADD(p, c->reg.nr_verts, c->reg.nr_verts, brw_imm_ud(1));
|
||||
brw_MOV(p, get_addr_reg(vtxOut), brw_imm_uw(0) );
|
||||
}
|
||||
brw_ENDIF(p, next_test);
|
||||
|
||||
}
|
||||
prev_test = brw_ELSE(p, prev_test);
|
||||
{
|
||||
/* *outlist_ptr++ = vtxPrev;
|
||||
* nr_verts++;
|
||||
*/
|
||||
brw_MOV(p, deref_1uw(outlist_ptr, 0), get_addr_reg(vtxPrev));
|
||||
brw_ADD(p, get_addr_reg(outlist_ptr), get_addr_reg(outlist_ptr), brw_imm_uw(sizeof(short)));
|
||||
brw_ADD(p, c->reg.nr_verts, c->reg.nr_verts, brw_imm_ud(1));
|
||||
|
||||
/* IS_NEGATIVE(next)
|
||||
*/
|
||||
brw_set_conditionalmod(p, BRW_CONDITIONAL_L);
|
||||
brw_DP4(p, vec4(c->reg.dp), deref_4f(vtx, c->offset[VERT_RESULT_HPOS]), c->reg.plane_equation);
|
||||
next_test = brw_IF(p, BRW_EXECUTE_1);
|
||||
{
|
||||
/* Going out of bounds. Avoid division by zero as we
|
||||
* know dp != dpPrev from DIFFERENT_SIGNS, above.
|
||||
*/
|
||||
brw_ADD(p, c->reg.t, c->reg.dp, negate(c->reg.dpPrev));
|
||||
brw_math_invert(p, c->reg.t, c->reg.t);
|
||||
brw_MUL(p, c->reg.t, c->reg.t, c->reg.dp);
|
||||
|
||||
/* If (vtxOut == 0) vtxOut = vtx
|
||||
*/
|
||||
brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_EQ, get_addr_reg(vtxOut), brw_imm_uw(0) );
|
||||
brw_MOV(p, get_addr_reg(vtxOut), get_addr_reg(vtx) );
|
||||
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
|
||||
|
||||
brw_clip_interp_vertex(c, vtxOut, vtx, vtxPrev, c->reg.t, TRUE);
|
||||
|
||||
/* *outlist_ptr++ = vtxOut;
|
||||
* nr_verts++;
|
||||
* vtxOut = 0;
|
||||
*/
|
||||
brw_MOV(p, deref_1uw(outlist_ptr, 0), get_addr_reg(vtxOut));
|
||||
brw_ADD(p, get_addr_reg(outlist_ptr), get_addr_reg(outlist_ptr), brw_imm_uw(sizeof(short)));
|
||||
brw_ADD(p, c->reg.nr_verts, c->reg.nr_verts, brw_imm_ud(1));
|
||||
brw_MOV(p, get_addr_reg(vtxOut), brw_imm_uw(0) );
|
||||
}
|
||||
brw_ENDIF(p, next_test);
|
||||
}
|
||||
brw_ENDIF(p, prev_test);
|
||||
|
||||
/* vtxPrev = vtx;
|
||||
* inlist_ptr++;
|
||||
*/
|
||||
brw_MOV(p, get_addr_reg(vtxPrev), get_addr_reg(vtx));
|
||||
brw_ADD(p, get_addr_reg(inlist_ptr), get_addr_reg(inlist_ptr), brw_imm_uw(sizeof(short)));
|
||||
|
||||
/* while (--loopcount != 0)
|
||||
*/
|
||||
brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
|
||||
brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1));
|
||||
}
|
||||
brw_WHILE(p, vertex_loop);
|
||||
|
||||
/* vtxPrev = *(outlist_ptr-1) OR: outlist[nr_verts-1]
|
||||
* inlist = outlist
|
||||
* inlist_ptr = &inlist[0]
|
||||
* outlist_ptr = &outlist[0]
|
||||
*/
|
||||
brw_ADD(p, get_addr_reg(outlist_ptr), get_addr_reg(outlist_ptr), brw_imm_w(-2));
|
||||
brw_MOV(p, get_addr_reg(vtxPrev), deref_1uw(outlist_ptr, 0));
|
||||
brw_MOV(p, brw_vec8_grf(c->reg.inlist.nr, 0), brw_vec8_grf(c->reg.outlist.nr, 0));
|
||||
brw_MOV(p, get_addr_reg(inlist_ptr), brw_address(c->reg.inlist));
|
||||
brw_MOV(p, get_addr_reg(outlist_ptr), brw_address(c->reg.outlist));
|
||||
}
|
||||
brw_ENDIF(p, plane_active);
|
||||
|
||||
/* plane_ptr++;
|
||||
*/
|
||||
brw_ADD(p, get_addr_reg(plane_ptr), get_addr_reg(plane_ptr), brw_clip_plane_stride(c));
|
||||
|
||||
/* nr_verts >= 3
|
||||
*/
|
||||
brw_CMP(p,
|
||||
vec1(brw_null_reg()),
|
||||
BRW_CONDITIONAL_GE,
|
||||
c->reg.nr_verts,
|
||||
brw_imm_ud(3));
|
||||
|
||||
/* && (planemask>>=1) != 0
|
||||
*/
|
||||
brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
|
||||
brw_SHR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(1));
|
||||
}
|
||||
brw_WHILE(p, plane_loop);
|
||||
#else
|
||||
#warning "disabled"
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
void brw_clip_tri_emit_polygon(struct brw_clip_compile *c)
|
||||
{
|
||||
struct brw_compile *p = &c->func;
|
||||
struct brw_instruction *loop, *if_insn;
|
||||
|
||||
/* for (loopcount = nr_verts-2; loopcount > 0; loopcount--)
|
||||
*/
|
||||
brw_set_conditionalmod(p, BRW_CONDITIONAL_G);
|
||||
brw_ADD(p,
|
||||
c->reg.loopcount,
|
||||
c->reg.nr_verts,
|
||||
brw_imm_d(-2));
|
||||
|
||||
if_insn = brw_IF(p, BRW_EXECUTE_1);
|
||||
{
|
||||
struct brw_indirect v0 = brw_indirect(0, 0);
|
||||
struct brw_indirect vptr = brw_indirect(1, 0);
|
||||
|
||||
brw_MOV(p, get_addr_reg(vptr), brw_address(c->reg.inlist));
|
||||
brw_MOV(p, get_addr_reg(v0), deref_1uw(vptr, 0));
|
||||
|
||||
brw_clip_emit_vue(c, v0, 1, 0, ((_3DPRIM_TRIFAN << 2) | R02_PRIM_START));
|
||||
|
||||
brw_ADD(p, get_addr_reg(vptr), get_addr_reg(vptr), brw_imm_uw(2));
|
||||
brw_MOV(p, get_addr_reg(v0), deref_1uw(vptr, 0));
|
||||
|
||||
loop = brw_DO(p, BRW_EXECUTE_1);
|
||||
{
|
||||
brw_clip_emit_vue(c, v0, 1, 0, (_3DPRIM_TRIFAN << 2));
|
||||
|
||||
brw_ADD(p, get_addr_reg(vptr), get_addr_reg(vptr), brw_imm_uw(2));
|
||||
brw_MOV(p, get_addr_reg(v0), deref_1uw(vptr, 0));
|
||||
|
||||
brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
|
||||
brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1));
|
||||
}
|
||||
brw_WHILE(p, loop);
|
||||
|
||||
brw_clip_emit_vue(c, v0, 0, 1, ((_3DPRIM_TRIFAN << 2) | R02_PRIM_END));
|
||||
}
|
||||
brw_ENDIF(p, if_insn);
|
||||
}
|
||||
|
||||
static void do_clip_tri( struct brw_clip_compile *c )
|
||||
{
|
||||
brw_clip_init_planes(c);
|
||||
|
||||
brw_clip_tri(c);
|
||||
}
|
||||
|
||||
|
||||
static void maybe_do_clip_tri( struct brw_clip_compile *c )
|
||||
{
|
||||
struct brw_compile *p = &c->func;
|
||||
struct brw_instruction *do_clip;
|
||||
|
||||
brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_NZ, c->reg.planemask, brw_imm_ud(0));
|
||||
do_clip = brw_IF(p, BRW_EXECUTE_1);
|
||||
{
|
||||
do_clip_tri(c);
|
||||
}
|
||||
brw_ENDIF(p, do_clip);
|
||||
}
|
||||
|
||||
static void brw_clip_test( struct brw_clip_compile *c )
|
||||
{
|
||||
#if 0
|
||||
struct brw_reg t = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
|
||||
struct brw_reg t1 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
|
||||
struct brw_reg t2 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
|
||||
struct brw_reg t3 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
|
||||
|
||||
struct brw_reg v0 = get_tmp(c);
|
||||
struct brw_reg v1 = get_tmp(c);
|
||||
struct brw_reg v2 = get_tmp(c);
|
||||
|
||||
struct brw_indirect vt0 = brw_indirect(0, 0);
|
||||
struct brw_indirect vt1 = brw_indirect(1, 0);
|
||||
struct brw_indirect vt2 = brw_indirect(2, 0);
|
||||
|
||||
struct brw_compile *p = &c->func;
|
||||
|
||||
brw_MOV(p, get_addr_reg(vt0), brw_address(c->reg.vertex[0]));
|
||||
brw_MOV(p, get_addr_reg(vt1), brw_address(c->reg.vertex[1]));
|
||||
brw_MOV(p, get_addr_reg(vt2), brw_address(c->reg.vertex[2]));
|
||||
brw_MOV(p, v0, deref_4f(vt0, c->offset[VERT_RESULT_HPOS]));
|
||||
brw_MOV(p, v1, deref_4f(vt1, c->offset[VERT_RESULT_HPOS]));
|
||||
brw_MOV(p, v2, deref_4f(vt2, c->offset[VERT_RESULT_HPOS]));
|
||||
|
||||
/* test nearz, xmin, ymin plane */
|
||||
brw_CMP(p, t1, BRW_CONDITIONAL_LE, negate(v0), get_element(v0, 3));
|
||||
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
|
||||
brw_CMP(p, t2, BRW_CONDITIONAL_LE, negate(v1), get_element(v1, 3));
|
||||
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
|
||||
brw_CMP(p, t3, BRW_CONDITIONAL_LE, negate(v2), get_element(v2, 3));
|
||||
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
|
||||
brw_XOR(p, t, t1, t2);
|
||||
brw_XOR(p, t1, t2, t3);
|
||||
brw_OR(p, t, t, t1);
|
||||
|
||||
brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
|
||||
get_element(t, 0), brw_imm_ud(0));
|
||||
brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<5)));
|
||||
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
|
||||
brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
|
||||
get_element(t, 1), brw_imm_ud(0));
|
||||
brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<3)));
|
||||
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
|
||||
brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
|
||||
get_element(t, 2), brw_imm_ud(0));
|
||||
brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<1)));
|
||||
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
|
||||
|
||||
/* test farz, xmax, ymax plane */
|
||||
brw_CMP(p, t1, BRW_CONDITIONAL_L, v0, get_element(v0, 3));
|
||||
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
|
||||
brw_CMP(p, t2, BRW_CONDITIONAL_L, v1, get_element(v1, 3));
|
||||
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
|
||||
brw_CMP(p, t3, BRW_CONDITIONAL_L, v2, get_element(v2, 3));
|
||||
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
|
||||
|
||||
brw_XOR(p, t, t1, t2);
|
||||
brw_XOR(p, t1, t2, t3);
|
||||
brw_OR(p, t, t, t1);
|
||||
|
||||
brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
|
||||
get_element(t, 0), brw_imm_ud(0));
|
||||
brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<4)));
|
||||
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
|
||||
brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
|
||||
get_element(t, 1), brw_imm_ud(0));
|
||||
brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<2)));
|
||||
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
|
||||
brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
|
||||
get_element(t, 2), brw_imm_ud(0));
|
||||
brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<0)));
|
||||
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
|
||||
|
||||
release_tmps(c);
|
||||
#else
|
||||
#warning "disabled"
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void brw_emit_tri_clip( struct brw_clip_compile *c )
|
||||
{
|
||||
struct brw_instruction *neg_rhw;
|
||||
struct brw_compile *p = &c->func;
|
||||
brw_clip_tri_alloc_regs(c, 3 + c->key.nr_userclip + 6);
|
||||
brw_clip_tri_init_vertices(c);
|
||||
brw_clip_init_clipmask(c);
|
||||
|
||||
/* if -ve rhw workaround bit is set,
|
||||
do cliptest */
|
||||
brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
|
||||
brw_AND(p, brw_null_reg(), get_element_ud(c->reg.R0, 2),
|
||||
brw_imm_ud(1<<20));
|
||||
neg_rhw = brw_IF(p, BRW_EXECUTE_1);
|
||||
{
|
||||
brw_clip_test(c);
|
||||
}
|
||||
brw_ENDIF(p, neg_rhw);
|
||||
|
||||
/* Can't push into do_clip_tri because with polygon (or quad)
|
||||
* flatshading, need to apply the flatshade here because we don't
|
||||
* respect the PV when converting to trifan for emit:
|
||||
*/
|
||||
if (c->key.do_flat_shading)
|
||||
brw_clip_tri_flat_shade(c);
|
||||
|
||||
if (c->key.clip_mode == BRW_CLIPMODE_NORMAL)
|
||||
do_clip_tri(c);
|
||||
else
|
||||
maybe_do_clip_tri(c);
|
||||
|
||||
brw_clip_tri_emit_polygon(c);
|
||||
|
||||
/* Send an empty message to kill the thread:
|
||||
*/
|
||||
brw_clip_kill_thread(c);
|
||||
}
|
||||
@@ -0,0 +1,477 @@
|
||||
/*
|
||||
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_defines.h"
|
||||
#include "brw_context.h"
|
||||
#include "brw_eu.h"
|
||||
#include "brw_util.h"
|
||||
#include "brw_clip.h"
|
||||
|
||||
|
||||
|
||||
/* This is performed against the original triangles, so no indirection
|
||||
* required:
|
||||
BZZZT!
|
||||
*/
|
||||
static void compute_tri_direction( struct brw_clip_compile *c )
|
||||
{
|
||||
struct brw_compile *p = &c->func;
|
||||
struct brw_reg e = c->reg.tmp0;
|
||||
struct brw_reg f = c->reg.tmp1;
|
||||
struct brw_reg v0 = byte_offset(c->reg.vertex[0], c->offset[VERT_RESULT_HPOS]);
|
||||
struct brw_reg v1 = byte_offset(c->reg.vertex[1], c->offset[VERT_RESULT_HPOS]);
|
||||
struct brw_reg v2 = byte_offset(c->reg.vertex[2], c->offset[VERT_RESULT_HPOS]);
|
||||
|
||||
|
||||
/* Calculate the vectors of two edges of the triangle:
|
||||
*/
|
||||
brw_ADD(p, e, v0, negate(v2));
|
||||
brw_ADD(p, f, v1, negate(v2));
|
||||
|
||||
/* Take their crossproduct:
|
||||
*/
|
||||
brw_set_access_mode(p, BRW_ALIGN_16);
|
||||
brw_MUL(p, vec4(brw_null_reg()), brw_swizzle(e, 1,2,0,3), brw_swizzle(f,2,0,1,3));
|
||||
brw_MAC(p, vec4(e), negate(brw_swizzle(e, 2,0,1,3)), brw_swizzle(f,1,2,0,3));
|
||||
brw_set_access_mode(p, BRW_ALIGN_1);
|
||||
|
||||
brw_MUL(p, c->reg.dir, c->reg.dir, vec4(e));
|
||||
}
|
||||
|
||||
|
||||
static void cull_direction( struct brw_clip_compile *c )
|
||||
{
|
||||
struct brw_compile *p = &c->func;
|
||||
struct brw_instruction *ccw;
|
||||
unsigned conditional;
|
||||
|
||||
assert (!(c->key.fill_ccw == CLIP_CULL &&
|
||||
c->key.fill_cw == CLIP_CULL));
|
||||
|
||||
if (c->key.fill_ccw == CLIP_CULL)
|
||||
conditional = BRW_CONDITIONAL_GE;
|
||||
else
|
||||
conditional = BRW_CONDITIONAL_L;
|
||||
|
||||
brw_CMP(p,
|
||||
vec1(brw_null_reg()),
|
||||
conditional,
|
||||
get_element(c->reg.dir, 2),
|
||||
brw_imm_f(0));
|
||||
|
||||
ccw = brw_IF(p, BRW_EXECUTE_1);
|
||||
{
|
||||
brw_clip_kill_thread(c);
|
||||
}
|
||||
brw_ENDIF(p, ccw);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void copy_bfc( struct brw_clip_compile *c )
|
||||
{
|
||||
struct brw_compile *p = &c->func;
|
||||
struct brw_instruction *ccw;
|
||||
unsigned conditional;
|
||||
|
||||
/* Do we have any colors to copy?
|
||||
*/
|
||||
if (!(c->offset[VERT_RESULT_COL0] && c->offset[VERT_RESULT_BFC0]) &&
|
||||
!(c->offset[VERT_RESULT_COL1] && c->offset[VERT_RESULT_BFC1]))
|
||||
return;
|
||||
|
||||
/* In some wierd degnerate cases we can end up testing the
|
||||
* direction twice, once for culling and once for bfc copying. Oh
|
||||
* well, that's what you get for setting wierd GL state.
|
||||
*/
|
||||
if (c->key.copy_bfc_ccw)
|
||||
conditional = BRW_CONDITIONAL_GE;
|
||||
else
|
||||
conditional = BRW_CONDITIONAL_L;
|
||||
|
||||
brw_CMP(p,
|
||||
vec1(brw_null_reg()),
|
||||
conditional,
|
||||
get_element(c->reg.dir, 2),
|
||||
brw_imm_f(0));
|
||||
|
||||
ccw = brw_IF(p, BRW_EXECUTE_1);
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (c->offset[VERT_RESULT_COL0] && c->offset[VERT_RESULT_BFC0])
|
||||
brw_MOV(p,
|
||||
byte_offset(c->reg.vertex[i], c->offset[VERT_RESULT_COL0]),
|
||||
byte_offset(c->reg.vertex[i], c->offset[VERT_RESULT_BFC0]));
|
||||
|
||||
if (c->offset[VERT_RESULT_COL1] && c->offset[VERT_RESULT_BFC1])
|
||||
brw_MOV(p,
|
||||
byte_offset(c->reg.vertex[i], c->offset[VERT_RESULT_COL1]),
|
||||
byte_offset(c->reg.vertex[i], c->offset[VERT_RESULT_BFC1]));
|
||||
}
|
||||
}
|
||||
brw_ENDIF(p, ccw);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
float iz = 1.0 / dir.z;
|
||||
float ac = dir.x * iz;
|
||||
float bc = dir.y * iz;
|
||||
offset = ctx->Polygon.OffsetUnits * DEPTH_SCALE;
|
||||
offset += MAX2( abs(ac), abs(bc) ) * ctx->Polygon.OffsetFactor;
|
||||
offset *= MRD;
|
||||
*/
|
||||
static void compute_offset( struct brw_clip_compile *c )
|
||||
{
|
||||
struct brw_compile *p = &c->func;
|
||||
struct brw_reg off = c->reg.offset;
|
||||
struct brw_reg dir = c->reg.dir;
|
||||
|
||||
brw_math_invert(p, get_element(off, 2), get_element(dir, 2));
|
||||
brw_MUL(p, vec2(off), dir, get_element(off, 2));
|
||||
|
||||
brw_CMP(p,
|
||||
vec1(brw_null_reg()),
|
||||
BRW_CONDITIONAL_GE,
|
||||
brw_abs(get_element(off, 0)),
|
||||
brw_abs(get_element(off, 1)));
|
||||
|
||||
brw_SEL(p, vec1(off), brw_abs(get_element(off, 0)), brw_abs(get_element(off, 1)));
|
||||
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
|
||||
|
||||
brw_MUL(p, vec1(off), off, brw_imm_f(c->key.offset_factor));
|
||||
brw_ADD(p, vec1(off), off, brw_imm_f(c->key.offset_units));
|
||||
}
|
||||
|
||||
|
||||
static void merge_edgeflags( struct brw_clip_compile *c )
|
||||
{
|
||||
struct brw_compile *p = &c->func;
|
||||
struct brw_instruction *is_poly;
|
||||
struct brw_reg tmp0 = get_element_ud(c->reg.tmp0, 0);
|
||||
|
||||
brw_AND(p, tmp0, get_element_ud(c->reg.R0, 2), brw_imm_ud(PRIM_MASK));
|
||||
brw_CMP(p,
|
||||
vec1(brw_null_reg()),
|
||||
BRW_CONDITIONAL_EQ,
|
||||
tmp0,
|
||||
brw_imm_ud(_3DPRIM_POLYGON));
|
||||
|
||||
/* Get away with using reg.vertex because we know that this is not
|
||||
* a _3DPRIM_TRISTRIP_REVERSE:
|
||||
*/
|
||||
is_poly = brw_IF(p, BRW_EXECUTE_1);
|
||||
{
|
||||
brw_set_conditionalmod(p, BRW_CONDITIONAL_EQ);
|
||||
brw_AND(p, vec1(brw_null_reg()), get_element_ud(c->reg.R0, 2), brw_imm_ud(1<<8));
|
||||
brw_MOV(p, byte_offset(c->reg.vertex[0], c->offset[VERT_RESULT_EDGE]), brw_imm_f(0));
|
||||
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
|
||||
|
||||
brw_set_conditionalmod(p, BRW_CONDITIONAL_EQ);
|
||||
brw_AND(p, vec1(brw_null_reg()), get_element_ud(c->reg.R0, 2), brw_imm_ud(1<<9));
|
||||
brw_MOV(p, byte_offset(c->reg.vertex[2], c->offset[VERT_RESULT_EDGE]), brw_imm_f(0));
|
||||
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
|
||||
}
|
||||
brw_ENDIF(p, is_poly);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void apply_one_offset( struct brw_clip_compile *c,
|
||||
struct brw_indirect vert )
|
||||
{
|
||||
struct brw_compile *p = &c->func;
|
||||
struct brw_reg pos = deref_4f(vert, c->offset[VERT_RESULT_HPOS]);
|
||||
struct brw_reg z = get_element(pos, 2);
|
||||
|
||||
brw_ADD(p, z, z, vec1(c->reg.offset));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Output clipped polygon as an unfilled primitive:
|
||||
*/
|
||||
static void emit_lines(struct brw_clip_compile *c,
|
||||
boolean do_offset)
|
||||
{
|
||||
struct brw_compile *p = &c->func;
|
||||
struct brw_instruction *loop;
|
||||
struct brw_instruction *draw_edge;
|
||||
struct brw_indirect v0 = brw_indirect(0, 0);
|
||||
struct brw_indirect v1 = brw_indirect(1, 0);
|
||||
struct brw_indirect v0ptr = brw_indirect(2, 0);
|
||||
struct brw_indirect v1ptr = brw_indirect(3, 0);
|
||||
|
||||
/* Need a seperate loop for offset:
|
||||
*/
|
||||
if (do_offset) {
|
||||
brw_MOV(p, c->reg.loopcount, c->reg.nr_verts);
|
||||
brw_MOV(p, get_addr_reg(v0ptr), brw_address(c->reg.inlist));
|
||||
|
||||
loop = brw_DO(p, BRW_EXECUTE_1);
|
||||
{
|
||||
brw_MOV(p, get_addr_reg(v0), deref_1uw(v0ptr, 0));
|
||||
brw_ADD(p, get_addr_reg(v0ptr), get_addr_reg(v0ptr), brw_imm_uw(2));
|
||||
|
||||
apply_one_offset(c, v0);
|
||||
|
||||
brw_set_conditionalmod(p, BRW_CONDITIONAL_G);
|
||||
brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1));
|
||||
}
|
||||
brw_WHILE(p, loop);
|
||||
}
|
||||
|
||||
/* v1ptr = &inlist[nr_verts]
|
||||
* *v1ptr = v0
|
||||
*/
|
||||
brw_MOV(p, c->reg.loopcount, c->reg.nr_verts);
|
||||
brw_MOV(p, get_addr_reg(v0ptr), brw_address(c->reg.inlist));
|
||||
brw_ADD(p, get_addr_reg(v1ptr), get_addr_reg(v0ptr), retype(c->reg.nr_verts, BRW_REGISTER_TYPE_UW));
|
||||
brw_ADD(p, get_addr_reg(v1ptr), get_addr_reg(v1ptr), retype(c->reg.nr_verts, BRW_REGISTER_TYPE_UW));
|
||||
brw_MOV(p, deref_1uw(v1ptr, 0), deref_1uw(v0ptr, 0));
|
||||
|
||||
loop = brw_DO(p, BRW_EXECUTE_1);
|
||||
{
|
||||
brw_MOV(p, get_addr_reg(v0), deref_1uw(v0ptr, 0));
|
||||
brw_MOV(p, get_addr_reg(v1), deref_1uw(v0ptr, 2));
|
||||
brw_ADD(p, get_addr_reg(v0ptr), get_addr_reg(v0ptr), brw_imm_uw(2));
|
||||
|
||||
/* draw edge if edgeflag != 0 */
|
||||
brw_CMP(p,
|
||||
vec1(brw_null_reg()), BRW_CONDITIONAL_NZ,
|
||||
deref_1f(v0, c->offset[VERT_RESULT_EDGE]),
|
||||
brw_imm_f(0));
|
||||
draw_edge = brw_IF(p, BRW_EXECUTE_1);
|
||||
{
|
||||
brw_clip_emit_vue(c, v0, 1, 0, (_3DPRIM_LINESTRIP << 2) | R02_PRIM_START);
|
||||
brw_clip_emit_vue(c, v1, 1, 0, (_3DPRIM_LINESTRIP << 2) | R02_PRIM_END);
|
||||
}
|
||||
brw_ENDIF(p, draw_edge);
|
||||
|
||||
brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
|
||||
brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1));
|
||||
}
|
||||
brw_WHILE(p, loop);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void emit_points(struct brw_clip_compile *c,
|
||||
boolean do_offset )
|
||||
{
|
||||
struct brw_compile *p = &c->func;
|
||||
struct brw_instruction *loop;
|
||||
struct brw_instruction *draw_point;
|
||||
|
||||
struct brw_indirect v0 = brw_indirect(0, 0);
|
||||
struct brw_indirect v0ptr = brw_indirect(2, 0);
|
||||
|
||||
brw_MOV(p, c->reg.loopcount, c->reg.nr_verts);
|
||||
brw_MOV(p, get_addr_reg(v0ptr), brw_address(c->reg.inlist));
|
||||
|
||||
loop = brw_DO(p, BRW_EXECUTE_1);
|
||||
{
|
||||
brw_MOV(p, get_addr_reg(v0), deref_1uw(v0ptr, 0));
|
||||
brw_ADD(p, get_addr_reg(v0ptr), get_addr_reg(v0ptr), brw_imm_uw(2));
|
||||
|
||||
/* draw if edgeflag != 0
|
||||
*/
|
||||
brw_CMP(p,
|
||||
vec1(brw_null_reg()), BRW_CONDITIONAL_NZ,
|
||||
deref_1f(v0, c->offset[VERT_RESULT_EDGE]),
|
||||
brw_imm_f(0));
|
||||
draw_point = brw_IF(p, BRW_EXECUTE_1);
|
||||
{
|
||||
if (do_offset)
|
||||
apply_one_offset(c, v0);
|
||||
|
||||
brw_clip_emit_vue(c, v0, 1, 0, (_3DPRIM_POINTLIST << 2) | R02_PRIM_START | R02_PRIM_END);
|
||||
}
|
||||
brw_ENDIF(p, draw_point);
|
||||
|
||||
brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
|
||||
brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1));
|
||||
}
|
||||
brw_WHILE(p, loop);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void emit_primitives( struct brw_clip_compile *c,
|
||||
unsigned mode,
|
||||
boolean do_offset )
|
||||
{
|
||||
switch (mode) {
|
||||
case CLIP_FILL:
|
||||
brw_clip_tri_emit_polygon(c);
|
||||
break;
|
||||
|
||||
case CLIP_LINE:
|
||||
emit_lines(c, do_offset);
|
||||
break;
|
||||
|
||||
case CLIP_POINT:
|
||||
emit_points(c, do_offset);
|
||||
break;
|
||||
|
||||
case CLIP_CULL:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void emit_unfilled_primitives( struct brw_clip_compile *c )
|
||||
{
|
||||
struct brw_compile *p = &c->func;
|
||||
struct brw_instruction *ccw;
|
||||
|
||||
/* Direction culling has already been done.
|
||||
*/
|
||||
if (c->key.fill_ccw != c->key.fill_cw &&
|
||||
c->key.fill_ccw != CLIP_CULL &&
|
||||
c->key.fill_cw != CLIP_CULL)
|
||||
{
|
||||
brw_CMP(p,
|
||||
vec1(brw_null_reg()),
|
||||
BRW_CONDITIONAL_GE,
|
||||
get_element(c->reg.dir, 2),
|
||||
brw_imm_f(0));
|
||||
|
||||
ccw = brw_IF(p, BRW_EXECUTE_1);
|
||||
{
|
||||
emit_primitives(c, c->key.fill_ccw, c->key.offset_ccw);
|
||||
}
|
||||
ccw = brw_ELSE(p, ccw);
|
||||
{
|
||||
emit_primitives(c, c->key.fill_cw, c->key.offset_cw);
|
||||
}
|
||||
brw_ENDIF(p, ccw);
|
||||
}
|
||||
else if (c->key.fill_cw != CLIP_CULL) {
|
||||
emit_primitives(c, c->key.fill_cw, c->key.offset_cw);
|
||||
}
|
||||
else if (c->key.fill_ccw != CLIP_CULL) {
|
||||
emit_primitives(c, c->key.fill_ccw, c->key.offset_ccw);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void check_nr_verts( struct brw_clip_compile *c )
|
||||
{
|
||||
struct brw_compile *p = &c->func;
|
||||
struct brw_instruction *if_insn;
|
||||
|
||||
brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.nr_verts, brw_imm_d(3));
|
||||
if_insn = brw_IF(p, BRW_EXECUTE_1);
|
||||
{
|
||||
brw_clip_kill_thread(c);
|
||||
}
|
||||
brw_ENDIF(p, if_insn);
|
||||
}
|
||||
|
||||
|
||||
void brw_emit_unfilled_clip( struct brw_clip_compile *c )
|
||||
{
|
||||
struct brw_compile *p = &c->func;
|
||||
struct brw_instruction *do_clip;
|
||||
|
||||
|
||||
c->need_direction = ((c->key.offset_ccw || c->key.offset_cw) ||
|
||||
(c->key.fill_ccw != c->key.fill_cw) ||
|
||||
c->key.fill_ccw == CLIP_CULL ||
|
||||
c->key.fill_cw == CLIP_CULL ||
|
||||
c->key.copy_bfc_cw ||
|
||||
c->key.copy_bfc_ccw);
|
||||
|
||||
brw_clip_tri_alloc_regs(c, 3 + c->key.nr_userclip + 6);
|
||||
brw_clip_tri_init_vertices(c);
|
||||
|
||||
assert(c->offset[VERT_RESULT_EDGE]);
|
||||
|
||||
if (c->key.fill_ccw == CLIP_CULL &&
|
||||
c->key.fill_cw == CLIP_CULL) {
|
||||
brw_clip_kill_thread(c);
|
||||
return;
|
||||
}
|
||||
|
||||
merge_edgeflags(c);
|
||||
|
||||
/* Need to use the inlist indirection here:
|
||||
*/
|
||||
if (c->need_direction)
|
||||
compute_tri_direction(c);
|
||||
|
||||
if (c->key.fill_ccw == CLIP_CULL ||
|
||||
c->key.fill_cw == CLIP_CULL)
|
||||
cull_direction(c);
|
||||
|
||||
if (c->key.offset_ccw ||
|
||||
c->key.offset_cw)
|
||||
compute_offset(c);
|
||||
|
||||
if (c->key.copy_bfc_ccw ||
|
||||
c->key.copy_bfc_cw)
|
||||
copy_bfc(c);
|
||||
|
||||
/* Need to do this whether we clip or not:
|
||||
*/
|
||||
if (c->key.do_flat_shading)
|
||||
brw_clip_tri_flat_shade(c);
|
||||
|
||||
brw_clip_init_clipmask(c);
|
||||
brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_NZ, c->reg.planemask, brw_imm_ud(0));
|
||||
do_clip = brw_IF(p, BRW_EXECUTE_1);
|
||||
{
|
||||
brw_clip_init_planes(c);
|
||||
brw_clip_tri(c);
|
||||
check_nr_verts(c);
|
||||
}
|
||||
brw_ENDIF(p, do_clip);
|
||||
|
||||
emit_unfilled_primitives(c);
|
||||
brw_clip_kill_thread(c);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,351 @@
|
||||
/*
|
||||
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_defines.h"
|
||||
#include "brw_context.h"
|
||||
#include "brw_eu.h"
|
||||
#include "brw_util.h"
|
||||
#include "brw_clip.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static struct brw_reg get_tmp( struct brw_clip_compile *c )
|
||||
{
|
||||
struct brw_reg tmp = brw_vec4_grf(c->last_tmp, 0);
|
||||
|
||||
if (++c->last_tmp > c->prog_data.total_grf)
|
||||
c->prog_data.total_grf = c->last_tmp;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static void release_tmp( struct brw_clip_compile *c, struct brw_reg tmp )
|
||||
{
|
||||
if (tmp.nr == c->last_tmp-1)
|
||||
c->last_tmp--;
|
||||
}
|
||||
|
||||
|
||||
static struct brw_reg make_plane_ud(unsigned x, unsigned y, unsigned z, unsigned w)
|
||||
{
|
||||
return brw_imm_ud((w<<24) | (z<<16) | (y<<8) | x);
|
||||
}
|
||||
|
||||
|
||||
void brw_clip_init_planes( struct brw_clip_compile *c )
|
||||
{
|
||||
struct brw_compile *p = &c->func;
|
||||
|
||||
if (!c->key.nr_userclip) {
|
||||
brw_MOV(p, get_element_ud(c->reg.fixed_planes, 0), make_plane_ud( 0, 0, 0xff, 1));
|
||||
brw_MOV(p, get_element_ud(c->reg.fixed_planes, 1), make_plane_ud( 0, 0, 1, 1));
|
||||
brw_MOV(p, get_element_ud(c->reg.fixed_planes, 2), make_plane_ud( 0, 0xff, 0, 1));
|
||||
brw_MOV(p, get_element_ud(c->reg.fixed_planes, 3), make_plane_ud( 0, 1, 0, 1));
|
||||
brw_MOV(p, get_element_ud(c->reg.fixed_planes, 4), make_plane_ud(0xff, 0, 0, 1));
|
||||
brw_MOV(p, get_element_ud(c->reg.fixed_planes, 5), make_plane_ud( 1, 0, 0, 1));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define W 3
|
||||
|
||||
/* Project 'pos' to screen space (or back again), overwrite with results:
|
||||
*/
|
||||
static void brw_clip_project_position(struct brw_clip_compile *c, struct brw_reg pos )
|
||||
{
|
||||
struct brw_compile *p = &c->func;
|
||||
|
||||
/* calc rhw
|
||||
*/
|
||||
brw_math_invert(p, get_element(pos, W), get_element(pos, W));
|
||||
|
||||
/* value.xyz *= value.rhw
|
||||
*/
|
||||
brw_set_access_mode(p, BRW_ALIGN_16);
|
||||
brw_MUL(p, brw_writemask(pos, TGSI_WRITEMASK_XYZ), pos, brw_swizzle1(pos, W));
|
||||
brw_set_access_mode(p, BRW_ALIGN_1);
|
||||
}
|
||||
|
||||
|
||||
static void brw_clip_project_vertex( struct brw_clip_compile *c,
|
||||
struct brw_indirect vert_addr )
|
||||
{
|
||||
#if 0
|
||||
struct brw_compile *p = &c->func;
|
||||
struct brw_reg tmp = get_tmp(c);
|
||||
|
||||
/* Fixup position. Extract from the original vertex and re-project
|
||||
* to screen space:
|
||||
*/
|
||||
brw_MOV(p, tmp, deref_4f(vert_addr, c->offset[VERT_RESULT_HPOS]));
|
||||
brw_clip_project_position(c, tmp);
|
||||
brw_MOV(p, deref_4f(vert_addr, c->header_position_offset), tmp);
|
||||
|
||||
release_tmp(c, tmp);
|
||||
#else
|
||||
#warning "disabled"
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Interpolate between two vertices and put the result into a0.0.
|
||||
* Increment a0.0 accordingly.
|
||||
*/
|
||||
void brw_clip_interp_vertex( struct brw_clip_compile *c,
|
||||
struct brw_indirect dest_ptr,
|
||||
struct brw_indirect v0_ptr, /* from */
|
||||
struct brw_indirect v1_ptr, /* to */
|
||||
struct brw_reg t0,
|
||||
boolean force_edgeflag)
|
||||
{
|
||||
#if 0
|
||||
struct brw_compile *p = &c->func;
|
||||
struct brw_reg tmp = get_tmp(c);
|
||||
unsigned i;
|
||||
|
||||
/* Just copy the vertex header:
|
||||
*/
|
||||
brw_copy_indirect_to_indirect(p, dest_ptr, v0_ptr, 1);
|
||||
|
||||
/* Iterate over each attribute (could be done in pairs?)
|
||||
*/
|
||||
for (i = 0; i < c->nr_attrs; i++) {
|
||||
unsigned delta = i*16 + 32;
|
||||
|
||||
if (delta == c->offset[VERT_RESULT_EDGE]) {
|
||||
if (force_edgeflag)
|
||||
brw_MOV(p, deref_4f(dest_ptr, delta), brw_imm_f(1));
|
||||
else
|
||||
brw_MOV(p, deref_4f(dest_ptr, delta), deref_4f(v0_ptr, delta));
|
||||
}
|
||||
else {
|
||||
/* Interpolate:
|
||||
*
|
||||
* New = attr0 + t*attr1 - t*attr0
|
||||
*/
|
||||
brw_MUL(p,
|
||||
vec4(brw_null_reg()),
|
||||
deref_4f(v1_ptr, delta),
|
||||
t0);
|
||||
|
||||
brw_MAC(p,
|
||||
tmp,
|
||||
negate(deref_4f(v0_ptr, delta)),
|
||||
t0);
|
||||
|
||||
brw_ADD(p,
|
||||
deref_4f(dest_ptr, delta),
|
||||
deref_4f(v0_ptr, delta),
|
||||
tmp);
|
||||
}
|
||||
}
|
||||
|
||||
if (i & 1) {
|
||||
unsigned delta = i*16 + 32;
|
||||
brw_MOV(p, deref_4f(dest_ptr, delta), brw_imm_f(0));
|
||||
}
|
||||
|
||||
release_tmp(c, tmp);
|
||||
|
||||
/* Recreate the projected (NDC) coordinate in the new vertex
|
||||
* header:
|
||||
*/
|
||||
brw_clip_project_vertex(c, dest_ptr );
|
||||
#else
|
||||
#warning "disabled"
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#define MAX_MRF 16
|
||||
|
||||
void brw_clip_emit_vue(struct brw_clip_compile *c,
|
||||
struct brw_indirect vert,
|
||||
boolean allocate,
|
||||
boolean eot,
|
||||
unsigned header)
|
||||
{
|
||||
struct brw_compile *p = &c->func;
|
||||
unsigned start = c->last_mrf;
|
||||
|
||||
assert(!(allocate && eot));
|
||||
|
||||
/* Cycle through mrf regs - probably futile as we have to wait for
|
||||
* the allocation response anyway. Also, the order this function
|
||||
* is invoked doesn't correspond to the order the instructions will
|
||||
* be executed, so it won't have any effect in many cases.
|
||||
*/
|
||||
#if 0
|
||||
if (start + c->nr_regs + 1 >= MAX_MRF)
|
||||
start = 0;
|
||||
|
||||
c->last_mrf = start + c->nr_regs + 1;
|
||||
#endif
|
||||
|
||||
/* Copy the vertex from vertn into m1..mN+1:
|
||||
*/
|
||||
brw_copy_from_indirect(p, brw_message_reg(start+1), vert, c->nr_regs);
|
||||
|
||||
/* Overwrite PrimType and PrimStart in the message header, for
|
||||
* each vertex in turn:
|
||||
*/
|
||||
brw_MOV(p, get_element_ud(c->reg.R0, 2), brw_imm_ud(header));
|
||||
|
||||
|
||||
/* Send each vertex as a seperate write to the urb. This
|
||||
* is different to the concept in brw_sf_emit.c, where
|
||||
* subsequent writes are used to build up a single urb
|
||||
* entry. Each of these writes instantiates a seperate
|
||||
* urb entry - (I think... what about 'allocate'?)
|
||||
*/
|
||||
brw_urb_WRITE(p,
|
||||
allocate ? c->reg.R0 : retype(brw_null_reg(), BRW_REGISTER_TYPE_UD),
|
||||
start,
|
||||
c->reg.R0,
|
||||
allocate,
|
||||
1, /* used */
|
||||
c->nr_regs + 1, /* msg length */
|
||||
allocate ? 1 : 0, /* response_length */
|
||||
eot, /* eot */
|
||||
1, /* writes_complete */
|
||||
0, /* urb offset */
|
||||
BRW_URB_SWIZZLE_NONE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void brw_clip_kill_thread(struct brw_clip_compile *c)
|
||||
{
|
||||
struct brw_compile *p = &c->func;
|
||||
|
||||
/* Send an empty message to kill the thread and release any
|
||||
* allocated urb entry:
|
||||
*/
|
||||
brw_urb_WRITE(p,
|
||||
retype(brw_null_reg(), BRW_REGISTER_TYPE_UD),
|
||||
0,
|
||||
c->reg.R0,
|
||||
0, /* allocate */
|
||||
0, /* used */
|
||||
0, /* msg len */
|
||||
0, /* response len */
|
||||
1, /* eot */
|
||||
1, /* writes complete */
|
||||
0,
|
||||
BRW_URB_SWIZZLE_NONE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
struct brw_reg brw_clip_plane0_address( struct brw_clip_compile *c )
|
||||
{
|
||||
return brw_address(c->reg.fixed_planes);
|
||||
}
|
||||
|
||||
|
||||
struct brw_reg brw_clip_plane_stride( struct brw_clip_compile *c )
|
||||
{
|
||||
if (c->key.nr_userclip) {
|
||||
return brw_imm_uw(16);
|
||||
}
|
||||
else {
|
||||
return brw_imm_uw(4);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* If flatshading, distribute color from provoking vertex prior to
|
||||
* clipping.
|
||||
*/
|
||||
void brw_clip_copy_colors( struct brw_clip_compile *c,
|
||||
unsigned to, unsigned from )
|
||||
{
|
||||
#if 0
|
||||
struct brw_compile *p = &c->func;
|
||||
|
||||
if (c->offset[VERT_RESULT_COL0])
|
||||
brw_MOV(p,
|
||||
byte_offset(c->reg.vertex[to], c->offset[VERT_RESULT_COL0]),
|
||||
byte_offset(c->reg.vertex[from], c->offset[VERT_RESULT_COL0]));
|
||||
|
||||
if (c->offset[VERT_RESULT_COL1])
|
||||
brw_MOV(p,
|
||||
byte_offset(c->reg.vertex[to], c->offset[VERT_RESULT_COL1]),
|
||||
byte_offset(c->reg.vertex[from], c->offset[VERT_RESULT_COL1]));
|
||||
|
||||
if (c->offset[VERT_RESULT_BFC0])
|
||||
brw_MOV(p,
|
||||
byte_offset(c->reg.vertex[to], c->offset[VERT_RESULT_BFC0]),
|
||||
byte_offset(c->reg.vertex[from], c->offset[VERT_RESULT_BFC0]));
|
||||
|
||||
if (c->offset[VERT_RESULT_BFC1])
|
||||
brw_MOV(p,
|
||||
byte_offset(c->reg.vertex[to], c->offset[VERT_RESULT_BFC1]),
|
||||
byte_offset(c->reg.vertex[from], c->offset[VERT_RESULT_BFC1]));
|
||||
#else
|
||||
#warning "disabled"
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
void brw_clip_init_clipmask( struct brw_clip_compile *c )
|
||||
{
|
||||
struct brw_compile *p = &c->func;
|
||||
struct brw_reg incoming = get_element_ud(c->reg.R0, 2);
|
||||
|
||||
/* Shift so that lowest outcode bit is rightmost:
|
||||
*/
|
||||
brw_SHR(p, c->reg.planemask, incoming, brw_imm_ud(26));
|
||||
|
||||
if (c->key.nr_userclip) {
|
||||
struct brw_reg tmp = retype(vec1(get_tmp(c)), BRW_REGISTER_TYPE_UD);
|
||||
|
||||
/* Rearrange userclip outcodes so that they come directly after
|
||||
* the fixed plane bits.
|
||||
*/
|
||||
brw_AND(p, tmp, incoming, brw_imm_ud(0x3f<<14));
|
||||
brw_SHR(p, tmp, tmp, brw_imm_ud(8));
|
||||
brw_OR(p, c->reg.planemask, c->reg.planemask, tmp);
|
||||
|
||||
release_tmp(c, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,287 @@
|
||||
/*
|
||||
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_draw.h"
|
||||
#include "brw_vs.h"
|
||||
#include "brw_tex_layout.h"
|
||||
#include "brw_winsys.h"
|
||||
|
||||
#include "pipe/p_winsys.h"
|
||||
#include "pipe/p_context.h"
|
||||
#include "pipe/p_util.h"
|
||||
|
||||
/***************************************
|
||||
* Mesa's Driver Functions
|
||||
***************************************/
|
||||
|
||||
#ifndef BRW_DEBUG
|
||||
int BRW_DEBUG = (0);
|
||||
#endif
|
||||
|
||||
static void brw_destroy(struct pipe_context *pipe)
|
||||
{
|
||||
struct brw_context *brw = brw_context(pipe);
|
||||
|
||||
FREE(brw);
|
||||
}
|
||||
|
||||
static void brw_clear(struct pipe_context *pipe, struct pipe_surface *ps,
|
||||
unsigned clearValue)
|
||||
{
|
||||
int x, y, w, h;
|
||||
/* FIXME: corny... */
|
||||
|
||||
x = 0;
|
||||
y = 0;
|
||||
w = ps->width;
|
||||
h = ps->height;
|
||||
|
||||
pipe->surface_fill(pipe, ps, x, y, w, h, clearValue);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
brw_get_param(struct pipe_context *pipe, int param)
|
||||
{
|
||||
switch (param) {
|
||||
case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
|
||||
return 8;
|
||||
case PIPE_CAP_NPOT_TEXTURES:
|
||||
return 1;
|
||||
case PIPE_CAP_TWO_SIDED_STENCIL:
|
||||
return 1;
|
||||
case PIPE_CAP_GLSL:
|
||||
return 0;
|
||||
case PIPE_CAP_S3TC:
|
||||
return 0;
|
||||
case PIPE_CAP_ANISOTROPIC_FILTER:
|
||||
return 0;
|
||||
case PIPE_CAP_POINT_SPRITE:
|
||||
return 0;
|
||||
case PIPE_CAP_MAX_RENDER_TARGETS:
|
||||
return 1;
|
||||
case PIPE_CAP_OCCLUSION_QUERY:
|
||||
return 0;
|
||||
case PIPE_CAP_TEXTURE_SHADOW_MAP:
|
||||
return 1;
|
||||
case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
|
||||
return 11; /* max 1024x1024 */
|
||||
case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
|
||||
return 8; /* max 128x128x128 */
|
||||
case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
|
||||
return 11; /* max 1024x1024 */
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static float
|
||||
brw_get_paramf(struct pipe_context *pipe, int param)
|
||||
{
|
||||
switch (param) {
|
||||
case PIPE_CAP_MAX_LINE_WIDTH:
|
||||
/* fall-through */
|
||||
case PIPE_CAP_MAX_LINE_WIDTH_AA:
|
||||
return 7.5;
|
||||
|
||||
case PIPE_CAP_MAX_POINT_WIDTH:
|
||||
/* fall-through */
|
||||
case PIPE_CAP_MAX_POINT_WIDTH_AA:
|
||||
return 255.0;
|
||||
|
||||
case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
|
||||
return 4.0;
|
||||
|
||||
case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
|
||||
return 16.0;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static boolean
|
||||
brw_is_format_supported( struct pipe_context *pipe,
|
||||
uint format )
|
||||
{
|
||||
#if 0
|
||||
/* XXX: This is broken -- rewrite if still needed. */
|
||||
static const unsigned tex_supported[] = {
|
||||
PIPE_FORMAT_U_R8_G8_B8_A8,
|
||||
PIPE_FORMAT_U_A8_R8_G8_B8,
|
||||
PIPE_FORMAT_U_R5_G6_B5,
|
||||
PIPE_FORMAT_U_L8,
|
||||
PIPE_FORMAT_U_A8,
|
||||
PIPE_FORMAT_U_I8,
|
||||
PIPE_FORMAT_U_L8_A8,
|
||||
PIPE_FORMAT_YCBCR,
|
||||
PIPE_FORMAT_YCBCR_REV,
|
||||
PIPE_FORMAT_S8_Z24,
|
||||
};
|
||||
|
||||
|
||||
/* Actually a lot more than this - add later:
|
||||
*/
|
||||
static const unsigned render_supported[] = {
|
||||
PIPE_FORMAT_U_A8_R8_G8_B8,
|
||||
PIPE_FORMAT_U_R5_G6_B5,
|
||||
};
|
||||
|
||||
/*
|
||||
*/
|
||||
static const unsigned z_stencil_supported[] = {
|
||||
PIPE_FORMAT_U_Z16,
|
||||
PIPE_FORMAT_U_Z32,
|
||||
PIPE_FORMAT_S8_Z24,
|
||||
};
|
||||
|
||||
switch (type) {
|
||||
case PIPE_RENDER_FORMAT:
|
||||
*numFormats = Elements(render_supported);
|
||||
return render_supported;
|
||||
|
||||
case PIPE_TEX_FORMAT:
|
||||
*numFormats = Elements(tex_supported);
|
||||
return render_supported;
|
||||
|
||||
case PIPE_Z_STENCIL_FORMAT:
|
||||
*numFormats = Elements(render_supported);
|
||||
return render_supported;
|
||||
|
||||
default:
|
||||
*numFormats = 0;
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
switch (format) {
|
||||
case PIPE_FORMAT_A8R8G8B8_UNORM:
|
||||
case PIPE_FORMAT_R5G6B5_UNORM:
|
||||
case PIPE_FORMAT_S8Z24_UNORM:
|
||||
return TRUE;
|
||||
};
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
brw_begin_query(struct pipe_context *pipe, struct pipe_query_object *q)
|
||||
{
|
||||
/* should never be called */
|
||||
assert(0);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
brw_end_query(struct pipe_context *pipe, struct pipe_query_object *q)
|
||||
{
|
||||
/* should never be called */
|
||||
assert(0);
|
||||
}
|
||||
|
||||
|
||||
static boolean
|
||||
brw_draw_elements(struct pipe_context *pipe,
|
||||
struct pipe_buffer_handle *indexBuffer,
|
||||
unsigned indexSize,
|
||||
unsigned prim, unsigned start, unsigned count)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static boolean brw_draw_arrays(struct pipe_context *pipe,
|
||||
unsigned prim, unsigned start, unsigned count)
|
||||
{
|
||||
return brw_draw_elements(pipe, NULL, 0, prim, start, count);
|
||||
}
|
||||
|
||||
|
||||
struct pipe_context *brw_create(struct pipe_winsys *pipe_winsys,
|
||||
struct brw_winsys *brw_winsys,
|
||||
unsigned pci_id)
|
||||
{
|
||||
struct brw_context *brw;
|
||||
|
||||
pipe_winsys->printf(pipe_winsys,
|
||||
"%s: creating brw_context with pci id 0x%x\n",
|
||||
__FUNCTION__, pci_id);
|
||||
|
||||
brw = CALLOC_STRUCT(brw_context);
|
||||
if (brw == NULL)
|
||||
return NULL;
|
||||
|
||||
brw->winsys = brw_winsys;
|
||||
brw->pipe.winsys = pipe_winsys;
|
||||
|
||||
brw->pipe.destroy = brw_destroy;
|
||||
brw->pipe.is_format_supported = brw_is_format_supported;
|
||||
brw->pipe.get_param = brw_get_param;
|
||||
brw->pipe.get_paramf = brw_get_paramf;
|
||||
|
||||
brw->pipe.clear = brw_clear;
|
||||
|
||||
brw->pipe.begin_query = brw_begin_query;
|
||||
brw->pipe.end_query = brw_end_query;
|
||||
|
||||
brw->pipe.draw_arrays = brw_draw_arrays;
|
||||
brw->pipe.draw_elements = brw_draw_elements;
|
||||
|
||||
brw_init_surface_functions(brw);
|
||||
brw_init_state_functions(brw);
|
||||
brw_init_flush_functions(brw);
|
||||
brw_init_string_functions(brw);
|
||||
|
||||
brw->pci_id = pci_id;
|
||||
|
||||
brw->pipe.texture_create = brw_texture_create;
|
||||
brw->pipe.texture_release = brw_texture_release;
|
||||
|
||||
brw->dirty = ~0;
|
||||
brw->hardware_dirty = ~0;
|
||||
|
||||
/* Batch stream debugging is a bit hacked up at the moment:
|
||||
*/
|
||||
brw->batch_start = NULL;
|
||||
|
||||
|
||||
brw_init_state( brw );
|
||||
|
||||
memset(&brw->wm.bind, ~0, sizeof(brw->wm.bind));
|
||||
|
||||
brw_draw_init( brw );
|
||||
|
||||
|
||||
return &brw->pipe;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,699 @@
|
||||
/*
|
||||
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>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef BRWCONTEXT_INC
|
||||
#define BRWCONTEXT_INC
|
||||
|
||||
|
||||
#include "pipe/p_context.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_state.h"
|
||||
|
||||
#include "brw_structs.h"
|
||||
#include "brw_winsys.h"
|
||||
|
||||
|
||||
/* Glossary:
|
||||
*
|
||||
* URB - uniform resource buffer. A mid-sized buffer which is
|
||||
* partitioned between the fixed function units and used for passing
|
||||
* values (vertices, primitives, constants) between them.
|
||||
*
|
||||
* CURBE - constant URB entry. An urb region (entry) used to hold
|
||||
* constant values which the fixed function units can be instructed to
|
||||
* preload into the GRF when spawining a thread.
|
||||
*
|
||||
* VUE - vertex URB entry. An urb entry holding a vertex and usually
|
||||
* a vertex header. The header contains control information and
|
||||
* things like primitive type, Begin/end flags and clip codes.
|
||||
*
|
||||
* PUE - primitive URB entry. An urb entry produced by the setup (SF)
|
||||
* unit holding rasterization and interpolation parameters.
|
||||
*
|
||||
* GRF - general register file. One of several register files
|
||||
* addressable by programmed threads. The inputs (r0, payload, curbe,
|
||||
* urb) of the thread are preloaded to this area before the thread is
|
||||
* spawned. The registers are individually 8 dwords wide and suitable
|
||||
* for general usage. Registers holding thread input values are not
|
||||
* special and may be overwritten.
|
||||
*
|
||||
* MRF - message register file. Threads communicate (and terminate)
|
||||
* by sending messages. Message parameters are placed in contigous
|
||||
* MRF registers. All program output is via these messages. URB
|
||||
* entries are populated by sending a message to the shared URB
|
||||
* function containing the new data, together with a control word,
|
||||
* often an unmodified copy of R0.
|
||||
*
|
||||
* R0 - GRF register 0. Typically holds control information used when
|
||||
* sending messages to other threads.
|
||||
*
|
||||
* EU or GEN4 EU: The name of the programmable subsystem of the
|
||||
* i965 hardware. Threads are executed by the EU, the registers
|
||||
* described above are part of the EU architecture.
|
||||
*
|
||||
* Fixed function units:
|
||||
*
|
||||
* CS - Command streamer. Notional first unit, little software
|
||||
* interaction. Holds the URB entries used for constant data, ie the
|
||||
* CURBEs.
|
||||
*
|
||||
* VF/VS - Vertex Fetch / Vertex Shader. The fixed function part of
|
||||
* this unit is responsible for pulling vertices out of vertex buffers
|
||||
* in vram and injecting them into the processing pipe as VUEs. If
|
||||
* enabled, it first passes them to a VS thread which is a good place
|
||||
* for the driver to implement any active vertex shader.
|
||||
*
|
||||
* GS - Geometry Shader. This corresponds to a new DX10 concept. If
|
||||
* enabled, incoming strips etc are passed to GS threads in individual
|
||||
* line/triangle/point units. The GS thread may perform arbitary
|
||||
* computation and emit whatever primtives with whatever vertices it
|
||||
* chooses. This makes GS an excellent place to implement GL's
|
||||
* unfilled polygon modes, though of course it is capable of much
|
||||
* more. Additionally, GS is used to translate away primitives not
|
||||
* handled by latter units, including Quads and Lineloops.
|
||||
*
|
||||
* CS - Clipper. Mesa's clipping algorithms are imported to run on
|
||||
* this unit. The fixed function part performs cliptesting against
|
||||
* the 6 fixed clipplanes and makes descisions on whether or not the
|
||||
* incoming primitive needs to be passed to a thread for clipping.
|
||||
* User clip planes are handled via cooperation with the VS thread.
|
||||
*
|
||||
* SF - Strips Fans or Setup: Triangles are prepared for
|
||||
* rasterization. Interpolation coefficients are calculated.
|
||||
* Flatshading and two-side lighting usually performed here.
|
||||
*
|
||||
* WM - Windower. Interpolation of vertex attributes performed here.
|
||||
* Fragment shader implemented here. SIMD aspects of EU taken full
|
||||
* advantage of, as pixels are processed in blocks of 16.
|
||||
*
|
||||
* CC - Color Calculator. No EU threads associated with this unit.
|
||||
* Handles blending and (presumably) depth and stencil testing.
|
||||
*/
|
||||
|
||||
#define BRW_FALLBACK_TEXTURE 0x1
|
||||
#define BRW_MAX_CURBE (32*16)
|
||||
|
||||
struct brw_context;
|
||||
struct brw_winsys;
|
||||
|
||||
|
||||
/* Raised when we receive new state across the pipe interface:
|
||||
*/
|
||||
#define BRW_NEW_VIEWPORT 0x1
|
||||
#define BRW_NEW_RASTERIZER 0x2
|
||||
#define BRW_NEW_FS 0x4
|
||||
#define BRW_NEW_BLEND 0x8
|
||||
#define BRW_NEW_CLIP 0x10
|
||||
#define BRW_NEW_SCISSOR 0x20
|
||||
#define BRW_NEW_STIPPLE 0x40
|
||||
#define BRW_NEW_FRAMEBUFFER 0x80
|
||||
#define BRW_NEW_ALPHA_TEST 0x100
|
||||
#define BRW_NEW_DEPTH_STENCIL 0x200
|
||||
#define BRW_NEW_SAMPLER 0x400
|
||||
#define BRW_NEW_TEXTURE 0x800
|
||||
#define BRW_NEW_CONSTANTS 0x1000
|
||||
#define BRW_NEW_VBO 0x2000
|
||||
#define BRW_NEW_VS 0x4000
|
||||
|
||||
/* Raised for other internal events:
|
||||
*/
|
||||
#define BRW_NEW_URB_FENCE 0x10000
|
||||
#define BRW_NEW_INPUT_DIMENSIONS 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 ALIGN(value, alignment) ((value + alignment - 1) & ~(alignment - 1))
|
||||
extern int BRW_DEBUG;
|
||||
|
||||
#define DEBUG_TEXTURE 0x1
|
||||
#define DEBUG_STATE 0x2
|
||||
#define DEBUG_IOCTL 0x4
|
||||
#define DEBUG_PRIMS 0x8
|
||||
#define DEBUG_VERTS 0x10
|
||||
#define DEBUG_FALLBACKS 0x20
|
||||
#define DEBUG_VERBOSE 0x40
|
||||
#define DEBUG_DRI 0x80
|
||||
#define DEBUG_DMA 0x100
|
||||
#define DEBUG_SANITY 0x200
|
||||
#define DEBUG_SYNC 0x400
|
||||
#define DEBUG_SLEEP 0x800
|
||||
#define DEBUG_PIXEL 0x1000
|
||||
#define DEBUG_STATS 0x2000
|
||||
#define DEBUG_TILE 0x4000
|
||||
#define DEBUG_SINGLE_THREAD 0x8000
|
||||
#define DEBUG_WM 0x10000
|
||||
#define DEBUG_URB 0x20000
|
||||
#define DEBUG_VS 0x40000
|
||||
#define DEBUG_BATCH 0x80000
|
||||
#define DEBUG_BUFMGR 0x100000
|
||||
#define DEBUG_BLIT 0x200000
|
||||
#define DEBUG_REGION 0x400000
|
||||
#define DEBUG_MIPTREE 0x800000
|
||||
|
||||
#define DBG(...) do { \
|
||||
if (BRW_DEBUG & FILE_DEBUG_FLAG) \
|
||||
brw->pipe.winsys->printf(brw->pipe.winsys, __VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
#define PRINT(...) do { \
|
||||
brw->pipe.winsys->printf(brw->pipe.winsys, __VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
struct brw_state_flags {
|
||||
unsigned cache;
|
||||
unsigned brw;
|
||||
};
|
||||
|
||||
struct brw_vertex_program {
|
||||
struct pipe_shader_state program;
|
||||
unsigned id;
|
||||
unsigned param_state; /* flags indicating state tracked by params */
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct brw_fragment_program {
|
||||
struct pipe_shader_state program;
|
||||
unsigned id;
|
||||
unsigned param_state; /* flags indicating state tracked by params */
|
||||
boolean UsesKill;
|
||||
boolean ComputesDepth;
|
||||
};
|
||||
|
||||
|
||||
struct brw_texture {
|
||||
struct pipe_texture base;
|
||||
|
||||
/* Derived from the above:
|
||||
*/
|
||||
unsigned pitch;
|
||||
unsigned depth_pitch; /* per-image on i945? */
|
||||
unsigned total_height;
|
||||
|
||||
unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS];
|
||||
|
||||
/* Explicitly store the offset of each image for each cube face or
|
||||
* depth value. Pretty much have to accept that hardware formats
|
||||
* are going to be so diverse that there is no unified way to
|
||||
* compute the offsets of depth/cube images within a mipmap level,
|
||||
* so have to store them as a lookup table:
|
||||
*/
|
||||
unsigned *image_offset[PIPE_MAX_TEXTURE_LEVELS]; /**< array [depth] of offsets */
|
||||
|
||||
/* Includes image offset tables:
|
||||
*/
|
||||
unsigned level_offset[PIPE_MAX_TEXTURE_LEVELS];
|
||||
|
||||
/* The data is held here:
|
||||
*/
|
||||
struct pipe_buffer_handle *buffer;
|
||||
};
|
||||
|
||||
/* 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;
|
||||
|
||||
unsigned first_curbe_grf;
|
||||
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).
|
||||
*/
|
||||
const float *param[BRW_MAX_CURBE];
|
||||
};
|
||||
|
||||
struct brw_sf_prog_data {
|
||||
unsigned urb_read_length;
|
||||
unsigned total_grf;
|
||||
|
||||
/* Each vertex may have upto 12 attributes, 4 components each,
|
||||
* except WPOS which requires only 2. (11*4 + 2) == 44 ==> 11
|
||||
* rows.
|
||||
*
|
||||
* Actually we use 4 for each, so call it 12 rows.
|
||||
*/
|
||||
unsigned urb_entry_size;
|
||||
};
|
||||
|
||||
struct brw_clip_prog_data {
|
||||
unsigned curb_read_length; /* user planes? */
|
||||
unsigned clip_mode;
|
||||
unsigned urb_read_length;
|
||||
unsigned total_grf;
|
||||
};
|
||||
|
||||
struct brw_gs_prog_data {
|
||||
unsigned urb_read_length;
|
||||
unsigned total_grf;
|
||||
};
|
||||
|
||||
struct brw_vs_prog_data {
|
||||
unsigned curb_read_length;
|
||||
unsigned urb_read_length;
|
||||
unsigned total_grf;
|
||||
unsigned outputs_written;
|
||||
|
||||
unsigned inputs_read;
|
||||
|
||||
/* 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
|
||||
|
||||
/* Create a fixed sized struct for caching binding tables:
|
||||
*/
|
||||
struct brw_surface_binding_table {
|
||||
unsigned surf_ss_offset[BRW_WM_MAX_SURF];
|
||||
};
|
||||
|
||||
|
||||
struct brw_cache;
|
||||
|
||||
struct brw_mem_pool {
|
||||
struct pipe_buffer_handle *buffer;
|
||||
|
||||
unsigned size;
|
||||
unsigned offset; /* offset of first free byte */
|
||||
|
||||
struct brw_context *brw;
|
||||
};
|
||||
|
||||
struct brw_cache_item {
|
||||
unsigned hash;
|
||||
unsigned key_size; /* for variable-sized keys */
|
||||
const void *key;
|
||||
|
||||
unsigned offset; /* offset within pool's buffer */
|
||||
unsigned data_size;
|
||||
|
||||
struct brw_cache_item *next;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct brw_cache {
|
||||
unsigned id;
|
||||
|
||||
const char *name;
|
||||
|
||||
struct brw_context *brw;
|
||||
struct brw_mem_pool *pool;
|
||||
|
||||
struct brw_cache_item **items;
|
||||
unsigned size, n_items;
|
||||
|
||||
unsigned key_size; /* for fixed-size keys */
|
||||
unsigned aux_size;
|
||||
|
||||
unsigned last_addr; /* offset of active item */
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/* Considered adding a member to this struct to document which flags
|
||||
* an update might raise so that ordering of the state atoms can be
|
||||
* checked or derived at runtime. Dropped the idea in favor of having
|
||||
* a debug mode where the state is monitored for flags which are
|
||||
* raised that have already been tested against.
|
||||
*/
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
/* Flags for brw->state.cache.
|
||||
*/
|
||||
#define CACHE_NEW_CC_VP (1<<BRW_CC_VP)
|
||||
#define CACHE_NEW_CC_UNIT (1<<BRW_CC_UNIT)
|
||||
#define CACHE_NEW_WM_PROG (1<<BRW_WM_PROG)
|
||||
#define CACHE_NEW_SAMPLER_DEFAULT_COLOR (1<<BRW_SAMPLER_DEFAULT_COLOR)
|
||||
#define CACHE_NEW_SAMPLER (1<<BRW_SAMPLER)
|
||||
#define CACHE_NEW_WM_UNIT (1<<BRW_WM_UNIT)
|
||||
#define CACHE_NEW_SF_PROG (1<<BRW_SF_PROG)
|
||||
#define CACHE_NEW_SF_VP (1<<BRW_SF_VP)
|
||||
#define CACHE_NEW_SF_UNIT (1<<BRW_SF_UNIT)
|
||||
#define CACHE_NEW_VS_UNIT (1<<BRW_VS_UNIT)
|
||||
#define CACHE_NEW_VS_PROG (1<<BRW_VS_PROG)
|
||||
#define CACHE_NEW_GS_UNIT (1<<BRW_GS_UNIT)
|
||||
#define CACHE_NEW_GS_PROG (1<<BRW_GS_PROG)
|
||||
#define CACHE_NEW_CLIP_VP (1<<BRW_CLIP_VP)
|
||||
#define CACHE_NEW_CLIP_UNIT (1<<BRW_CLIP_UNIT)
|
||||
#define CACHE_NEW_CLIP_PROG (1<<BRW_CLIP_PROG)
|
||||
#define CACHE_NEW_SURFACE (1<<BRW_SS_SURFACE)
|
||||
#define CACHE_NEW_SURF_BIND (1<<BRW_SS_SURF_BIND)
|
||||
|
||||
|
||||
|
||||
|
||||
enum brw_mempool_id {
|
||||
BRW_GS_POOL,
|
||||
BRW_SS_POOL,
|
||||
BRW_MAX_POOL
|
||||
};
|
||||
|
||||
|
||||
struct brw_cached_batch_item {
|
||||
struct header *header;
|
||||
unsigned sz;
|
||||
struct brw_cached_batch_item *next;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* Protect against a future where PIPE_ATTRIB_MAX > 32. Wouldn't life
|
||||
* be easier if C allowed arrays of packed elements?
|
||||
*/
|
||||
#define ATTRIB_BIT_DWORDS ((PIPE_ATTRIB_MAX+31)/32)
|
||||
|
||||
struct brw_vertex_element {
|
||||
struct brw_vertex_element_state vep;
|
||||
|
||||
unsigned index;
|
||||
unsigned element_size;
|
||||
unsigned count;
|
||||
unsigned vbo_rebase_offset;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct brw_vertex_info {
|
||||
unsigned varying; /* varying:1[PIPE_ATTRIB_MAX] */
|
||||
unsigned sizes[ATTRIB_BIT_DWORDS * 2]; /* sizes:2[PIPE_ATTRIB_MAX] */
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
struct brw_context
|
||||
{
|
||||
struct pipe_context pipe;
|
||||
struct brw_winsys *winsys;
|
||||
|
||||
unsigned primitive;
|
||||
unsigned reduced_primitive;
|
||||
|
||||
boolean emit_state_always;
|
||||
|
||||
struct {
|
||||
struct brw_state_flags dirty;
|
||||
struct brw_tracked_state **atoms;
|
||||
unsigned nr_atoms;
|
||||
} state;
|
||||
|
||||
|
||||
struct {
|
||||
const struct pipe_alpha_test_state *AlphaTest;
|
||||
const struct pipe_blend_state *Blend;
|
||||
const struct pipe_depth_stencil_state *DepthStencil;
|
||||
const struct pipe_poly_stipple *PolygonStipple;
|
||||
const struct pipe_rasterizer_state *Raster;
|
||||
const struct pipe_sampler_state *Samplers[PIPE_MAX_SAMPLERS];
|
||||
const struct brw_vertex_program *VertexProgram;
|
||||
const struct brw_fragment_program *FragmentProgram;
|
||||
|
||||
struct pipe_clip_state Clip;
|
||||
struct pipe_blend_color BlendColor;
|
||||
struct pipe_scissor_state Scissor;
|
||||
struct pipe_viewport_state Viewport;
|
||||
struct pipe_framebuffer_state FrameBuffer;
|
||||
struct pipe_clear_color_state ClearColor;
|
||||
|
||||
const struct pipe_constant_buffer *Constants[2];
|
||||
const struct brw_texture *Texture[PIPE_MAX_SAMPLERS];
|
||||
} attribs;
|
||||
|
||||
struct brw_mem_pool pool[BRW_MAX_POOL];
|
||||
struct brw_cache cache[BRW_MAX_CACHE];
|
||||
struct brw_cached_batch_item *cached_batch_items;
|
||||
|
||||
struct {
|
||||
|
||||
/* Arrays with buffer objects to copy non-bufferobj arrays into
|
||||
* for upload:
|
||||
*/
|
||||
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 {
|
||||
unsigned vsize; /* vertex size plus header in urb registers */
|
||||
unsigned csize; /* constant buffer size in urb registers */
|
||||
unsigned sfsize; /* setup data size in urb registers */
|
||||
|
||||
boolean constrained;
|
||||
|
||||
unsigned nr_vs_entries;
|
||||
unsigned nr_gs_entries;
|
||||
unsigned nr_clip_entries;
|
||||
unsigned nr_sf_entries;
|
||||
unsigned nr_cs_entries;
|
||||
|
||||
/* unsigned vs_size; */
|
||||
/* unsigned gs_size; */
|
||||
/* unsigned clip_size; */
|
||||
/* unsigned sf_size; */
|
||||
/* unsigned cs_size; */
|
||||
|
||||
unsigned vs_start;
|
||||
unsigned gs_start;
|
||||
unsigned clip_start;
|
||||
unsigned sf_start;
|
||||
unsigned cs_start;
|
||||
} urb;
|
||||
|
||||
|
||||
/* BRW_NEW_CURBE_OFFSETS:
|
||||
*/
|
||||
struct {
|
||||
unsigned wm_start;
|
||||
unsigned wm_size;
|
||||
unsigned clip_start;
|
||||
unsigned clip_size;
|
||||
unsigned vs_start;
|
||||
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;
|
||||
unsigned last_bufsz;
|
||||
} curbe;
|
||||
|
||||
struct {
|
||||
struct brw_vs_prog_data *prog_data;
|
||||
|
||||
unsigned prog_gs_offset;
|
||||
unsigned state_gs_offset;
|
||||
} vs;
|
||||
|
||||
struct {
|
||||
struct brw_gs_prog_data *prog_data;
|
||||
|
||||
boolean prog_active;
|
||||
unsigned prog_gs_offset;
|
||||
unsigned state_gs_offset;
|
||||
} gs;
|
||||
|
||||
struct {
|
||||
struct brw_clip_prog_data *prog_data;
|
||||
|
||||
unsigned prog_gs_offset;
|
||||
unsigned vp_gs_offset;
|
||||
unsigned state_gs_offset;
|
||||
} clip;
|
||||
|
||||
|
||||
struct {
|
||||
struct brw_sf_prog_data *prog_data;
|
||||
|
||||
unsigned prog_gs_offset;
|
||||
unsigned vp_gs_offset;
|
||||
unsigned state_gs_offset;
|
||||
} sf;
|
||||
|
||||
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];
|
||||
|
||||
|
||||
/**
|
||||
* Array of sampler state uploaded at sampler_gs_offset of BRW_SAMPLER
|
||||
* cache
|
||||
*/
|
||||
struct brw_sampler_state sampler[BRW_MAX_TEX_UNIT];
|
||||
|
||||
unsigned render_surf;
|
||||
unsigned nr_surfaces;
|
||||
|
||||
unsigned max_threads;
|
||||
struct pipe_buffer_handle *scratch_buffer;
|
||||
unsigned scratch_buffer_size;
|
||||
|
||||
unsigned sampler_count;
|
||||
unsigned sampler_gs_offset;
|
||||
|
||||
struct brw_surface_binding_table bind;
|
||||
unsigned bind_ss_offset;
|
||||
|
||||
unsigned prog_gs_offset;
|
||||
unsigned state_gs_offset;
|
||||
} wm;
|
||||
|
||||
|
||||
struct {
|
||||
unsigned vp_gs_offset;
|
||||
unsigned state_gs_offset;
|
||||
} cc;
|
||||
|
||||
|
||||
/* Used to give every program string a unique id
|
||||
*/
|
||||
unsigned program_id;
|
||||
};
|
||||
|
||||
|
||||
#define BRW_PACKCOLOR8888(r,g,b,a) ((r<<24) | (g<<16) | (b<<8) | a)
|
||||
|
||||
|
||||
/*======================================================================
|
||||
* brw_vtbl.c
|
||||
*/
|
||||
void brw_do_flush( struct brw_context *brw,
|
||||
unsigned flags );
|
||||
|
||||
|
||||
/*======================================================================
|
||||
* brw_state.c
|
||||
*/
|
||||
void brw_validate_state(struct brw_context *brw);
|
||||
void brw_init_state(struct brw_context *brw);
|
||||
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
|
||||
*/
|
||||
void brw_upload_urb_fence(struct brw_context *brw);
|
||||
|
||||
void brw_upload_constant_buffer_state(struct brw_context *brw);
|
||||
void brw_upload_polygon_stipple(struct brw_context *brw);
|
||||
void brw_upload_line_stipple(struct brw_context *brw);
|
||||
|
||||
void brw_init_surface_functions(struct brw_context *brw);
|
||||
void brw_init_state_functions(struct brw_context *brw);
|
||||
void brw_init_flush_functions(struct brw_context *brw);
|
||||
void brw_init_string_functions(struct brw_context *brw);
|
||||
|
||||
/*======================================================================
|
||||
* Inline conversion functions. These are better-typed than the
|
||||
* macros used previously:
|
||||
*/
|
||||
static inline struct brw_context *
|
||||
brw_context( struct pipe_context *ctx )
|
||||
{
|
||||
return (struct brw_context *)ctx;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,369 @@
|
||||
/*
|
||||
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_util.h"
|
||||
|
||||
#define FILE_DEBUG_FLAG DEBUG_FALLBACKS
|
||||
|
||||
/* Partition the CURBE between the various users of constant values:
|
||||
*/
|
||||
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;
|
||||
|
||||
/* 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_clip_regs = 0;
|
||||
unsigned total_regs;
|
||||
|
||||
#if 0
|
||||
/* 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;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
total_regs = nr_fp_regs + nr_vp_regs + nr_clip_regs;
|
||||
|
||||
/* This can happen - what to do? Probably rather than falling
|
||||
* back, the best thing to do is emit programs which code the
|
||||
* constants as immediate values. Could do this either as a static
|
||||
* cap on WM and VS, or adaptively.
|
||||
*
|
||||
* Unfortunately, this is currently dependent on the results of the
|
||||
* program generation process (in the case of wm), so this would
|
||||
* introduce the need to re-generate programs in the event of a
|
||||
* curbe allocation failure.
|
||||
*/
|
||||
/* Max size is 32 - just large enough to
|
||||
* hold the 128 parameters allowed by
|
||||
* the fragment and vertex program
|
||||
* api's. It's not clear what happens
|
||||
* when both VP and FP want to use 128
|
||||
* parameters, though.
|
||||
*/
|
||||
assert(total_regs <= 32);
|
||||
|
||||
/* Lazy resize:
|
||||
*/
|
||||
if (nr_fp_regs > brw->curbe.wm_size ||
|
||||
nr_vp_regs > brw->curbe.vs_size ||
|
||||
nr_clip_regs != brw->curbe.clip_size ||
|
||||
(total_regs < brw->curbe.total_size / 4 &&
|
||||
brw->curbe.total_size > 16)) {
|
||||
|
||||
unsigned reg = 0;
|
||||
|
||||
/* Calculate a new layout:
|
||||
*/
|
||||
reg = 0;
|
||||
brw->curbe.wm_start = reg;
|
||||
brw->curbe.wm_size = nr_fp_regs; reg += nr_fp_regs;
|
||||
brw->curbe.clip_start = reg;
|
||||
brw->curbe.clip_size = nr_clip_regs; reg += nr_clip_regs;
|
||||
brw->curbe.vs_start = reg;
|
||||
brw->curbe.vs_size = nr_vp_regs; reg += nr_vp_regs;
|
||||
brw->curbe.total_size = reg;
|
||||
|
||||
#if 0
|
||||
if (0)
|
||||
DBG("curbe wm %d+%d clip %d+%d vs %d+%d\n",
|
||||
brw->curbe.wm_start,
|
||||
brw->curbe.wm_size,
|
||||
brw->curbe.clip_start,
|
||||
brw->curbe.clip_size,
|
||||
brw->curbe.vs_start,
|
||||
brw->curbe.vs_size );
|
||||
#endif
|
||||
|
||||
brw->state.dirty.brw |= BRW_NEW_CURBE_OFFSETS;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const struct brw_tracked_state brw_curbe_offsets = {
|
||||
.dirty = {
|
||||
.brw = (BRW_NEW_CLIP |
|
||||
BRW_NEW_VS),
|
||||
.cache = CACHE_NEW_WM_PROG
|
||||
},
|
||||
.update = calculate_curbe_offsets
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* Define the number of curbes within CS's urb allocation. Multiple
|
||||
* urb entries -> multiple curbes. These will be used by
|
||||
* fixed-function hardware in a double-buffering scheme to avoid a
|
||||
* pipeline stall each time the contents of the curbe is changed.
|
||||
*/
|
||||
void brw_upload_constant_buffer_state(struct brw_context *brw)
|
||||
{
|
||||
struct brw_constant_buffer_state cbs;
|
||||
memset(&cbs, 0, sizeof(cbs));
|
||||
|
||||
/* It appears that this is the state packet for the CS unit, ie. the
|
||||
* urb entries detailed here are housed in the CS range from the
|
||||
* URB_FENCE command.
|
||||
*/
|
||||
cbs.header.opcode = CMD_CONST_BUFFER_STATE;
|
||||
cbs.header.length = sizeof(cbs)/4 - 2;
|
||||
|
||||
/* BRW_NEW_URB_FENCE */
|
||||
cbs.bits0.nr_urb_entries = brw->urb.nr_cs_entries;
|
||||
cbs.bits0.urb_entry_size = brw->urb.csize - 1;
|
||||
|
||||
assert(brw->urb.nr_cs_entries);
|
||||
BRW_CACHED_BATCH_STRUCT(brw, &cbs);
|
||||
}
|
||||
|
||||
const struct brw_tracked_state brw_constant_buffer_state = {
|
||||
.dirty = {
|
||||
.brw = BRW_NEW_URB_FENCE,
|
||||
.cache = 0
|
||||
},
|
||||
.update = brw_upload_constant_buffer_state
|
||||
};
|
||||
|
||||
|
||||
static float fixed_plane[6][4] = {
|
||||
{ 0, 0, -1, 1 },
|
||||
{ 0, 0, 1, 1 },
|
||||
{ 0, -1, 0, 1 },
|
||||
{ 0, 1, 0, 1 },
|
||||
{-1, 0, 0, 1 },
|
||||
{ 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;
|
||||
cb.header.opcode = CMD_CONST_BUFFER;
|
||||
cb.header.length = sizeof(cb)/4 - 2;
|
||||
cb.header.valid = 0;
|
||||
cb.bits0.buffer_length = 0;
|
||||
cb.bits0.buffer_address = 0;
|
||||
BRW_BATCH_STRUCT(brw, &cb);
|
||||
|
||||
if (brw->curbe.last_buf) {
|
||||
free(brw->curbe.last_buf);
|
||||
brw->curbe.last_buf = NULL;
|
||||
brw->curbe.last_bufsz = 0;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
buf = (float *)malloc(bufsz);
|
||||
|
||||
memset(buf, 0, bufsz);
|
||||
|
||||
if (brw->curbe.wm_size) {
|
||||
unsigned offset = brw->curbe.wm_start * 16;
|
||||
|
||||
_mesa_load_state_parameters(ctx, fp->program.Base.Parameters);
|
||||
|
||||
for (i = 0; i < brw->wm.prog_data->nr_params; i++)
|
||||
buf[offset + i] = brw->wm.prog_data->param[i][0];
|
||||
}
|
||||
|
||||
|
||||
/* The clipplanes are actually delivered to both CLIP and VS units.
|
||||
* VS uses them to calculate the outcode bitmasks.
|
||||
*/
|
||||
if (brw->curbe.clip_size) {
|
||||
unsigned offset = brw->curbe.clip_start * 16;
|
||||
unsigned j;
|
||||
|
||||
/* If any planes are going this way, send them all this way:
|
||||
*/
|
||||
for (i = 0; i < 6; i++) {
|
||||
buf[offset + i * 4 + 0] = fixed_plane[i][0];
|
||||
buf[offset + i * 4 + 1] = fixed_plane[i][1];
|
||||
buf[offset + i * 4 + 2] = fixed_plane[i][2];
|
||||
buf[offset + i * 4 + 3] = fixed_plane[i][3];
|
||||
}
|
||||
|
||||
/* Clip planes: _NEW_TRANSFORM plus _NEW_PROJECTION to get to
|
||||
* clip-space:
|
||||
*/
|
||||
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++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (brw->curbe.vs_size) {
|
||||
unsigned offset = brw->curbe.vs_start * 16;
|
||||
unsigned nr = vp->program.Base.Parameters->NumParameters;
|
||||
|
||||
_mesa_load_state_parameters(ctx, vp->program.Base.Parameters);
|
||||
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
if (0) {
|
||||
for (i = 0; i < sz*16; i+=4)
|
||||
_mesa_printf("curbe %d.%d: %f %f %f %f\n", i/8, i&4,
|
||||
buf[i+0], buf[i+1], buf[i+2], buf[i+3]);
|
||||
|
||||
_mesa_printf("last_buf %p buf %p sz %d/%d cmp %d\n",
|
||||
brw->curbe.last_buf, buf,
|
||||
bufsz, brw->curbe.last_bufsz,
|
||||
brw->curbe.last_buf ? memcmp(buf, brw->curbe.last_buf, bufsz) : -1);
|
||||
}
|
||||
|
||||
if (brw->curbe.last_buf &&
|
||||
bufsz == brw->curbe.last_bufsz &&
|
||||
memcmp(buf, brw->curbe.last_buf, bufsz) == 0) {
|
||||
free(buf);
|
||||
/* return; */
|
||||
}
|
||||
else {
|
||||
if (brw->curbe.last_buf)
|
||||
free(brw->curbe.last_buf);
|
||||
brw->curbe.last_buf = buf;
|
||||
brw->curbe.last_bufsz = bufsz;
|
||||
|
||||
|
||||
if (!brw_pool_alloc(pool,
|
||||
bufsz,
|
||||
1 << 6,
|
||||
&brw->curbe.gs_offset)) {
|
||||
_mesa_printf("out of GS memory for curbe\n");
|
||||
assert(0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Copy data to the buffer:
|
||||
*/
|
||||
dri_bo_subdata(pool->buffer, brw->curbe.gs_offset, bufsz, buf);
|
||||
}
|
||||
|
||||
/* TODO: only emit the constant_buffer packet when necessary, ie:
|
||||
- contents have changed
|
||||
- offset has changed
|
||||
- hw requirements due to other packets emitted.
|
||||
*/
|
||||
{
|
||||
struct brw_constant_buffer cb;
|
||||
|
||||
memset(&cb, 0, sizeof(cb));
|
||||
|
||||
cb.header.opcode = CMD_CONST_BUFFER;
|
||||
cb.header.length = sizeof(cb)/4 - 2;
|
||||
cb.header.valid = 1;
|
||||
cb.bits0.buffer_length = sz - 1;
|
||||
cb.bits0.buffer_address = brw->curbe.gs_offset >> 6;
|
||||
|
||||
/* Because this provokes an action (ie copy the constants into the
|
||||
* URB), it shouldn't be shortcircuited if identical to the
|
||||
* previous time - because eg. the urb destination may have
|
||||
* changed, or the urb contents different to last time.
|
||||
*
|
||||
* Note that the data referred to is actually copied internally,
|
||||
* not just used in place according to passed pointer.
|
||||
*
|
||||
* It appears that the CS unit takes care of using each available
|
||||
* URB entry (Const URB Entry == CURBE) in turn, and issuing
|
||||
* 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); */
|
||||
}
|
||||
}
|
||||
|
||||
/* This tracked state is unique in that the state it monitors varies
|
||||
* dynamically depending on the parameters tracked by the fragment and
|
||||
* vertex programs. This is the template used as a starting point,
|
||||
* each context will maintain a copy of this internally and update as
|
||||
* required.
|
||||
*/
|
||||
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_NEW_URB_FENCE | /* Implicit - hardware requires this, not used above */
|
||||
BRW_NEW_PSP | /* Implicit - hardware requires this, not used above */
|
||||
BRW_NEW_CURBE_OFFSETS),
|
||||
.cache = (CACHE_NEW_WM_PROG)
|
||||
},
|
||||
.update = upload_constant_buffer
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,852 @@
|
||||
/*
|
||||
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>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef BRW_DEFINES_H
|
||||
#define BRW_DEFINES_H
|
||||
|
||||
/*
|
||||
*/
|
||||
#define MI_NOOP 0x00
|
||||
#define MI_USER_INTERRUPT 0x02
|
||||
#define MI_WAIT_FOR_EVENT 0x03
|
||||
#define MI_FLUSH 0x04
|
||||
#define MI_REPORT_HEAD 0x07
|
||||
#define MI_ARB_ON_OFF 0x08
|
||||
#define MI_BATCH_BUFFER_END 0x0A
|
||||
#define MI_OVERLAY_FLIP 0x11
|
||||
#define MI_LOAD_SCAN_LINES_INCL 0x12
|
||||
#define MI_LOAD_SCAN_LINES_EXCL 0x13
|
||||
#define MI_DISPLAY_BUFFER_INFO 0x14
|
||||
#define MI_SET_CONTEXT 0x18
|
||||
#define MI_STORE_DATA_IMM 0x20
|
||||
#define MI_STORE_DATA_INDEX 0x21
|
||||
#define MI_LOAD_REGISTER_IMM 0x22
|
||||
#define MI_STORE_REGISTER_MEM 0x24
|
||||
#define MI_BATCH_BUFFER_START 0x31
|
||||
|
||||
#define MI_SYNCHRONOUS_FLIP 0x0
|
||||
#define MI_ASYNCHRONOUS_FLIP 0x1
|
||||
|
||||
#define MI_BUFFER_SECURE 0x0
|
||||
#define MI_BUFFER_NONSECURE 0x1
|
||||
|
||||
#define MI_ARBITRATE_AT_CHAIN_POINTS 0x0
|
||||
#define MI_ARBITRATE_BETWEEN_INSTS 0x1
|
||||
#define MI_NO_ARBITRATION 0x3
|
||||
|
||||
#define MI_CONDITION_CODE_WAIT_DISABLED 0x0
|
||||
#define MI_CONDITION_CODE_WAIT_0 0x1
|
||||
#define MI_CONDITION_CODE_WAIT_1 0x2
|
||||
#define MI_CONDITION_CODE_WAIT_2 0x3
|
||||
#define MI_CONDITION_CODE_WAIT_3 0x4
|
||||
#define MI_CONDITION_CODE_WAIT_4 0x5
|
||||
|
||||
#define MI_DISPLAY_PIPE_A 0x0
|
||||
#define MI_DISPLAY_PIPE_B 0x1
|
||||
|
||||
#define MI_DISPLAY_PLANE_A 0x0
|
||||
#define MI_DISPLAY_PLANE_B 0x1
|
||||
#define MI_DISPLAY_PLANE_C 0x2
|
||||
|
||||
#define MI_STANDARD_FLIP 0x0
|
||||
#define MI_ENQUEUE_FLIP_PERFORM_BASE_FRAME_NUMBER_LOAD 0x1
|
||||
#define MI_ENQUEUE_FLIP_TARGET_FRAME_NUMBER_RELATIVE 0x2
|
||||
#define MI_ENQUEUE_FLIP_ABSOLUTE_TARGET_FRAME_NUMBER 0x3
|
||||
|
||||
#define MI_PHYSICAL_ADDRESS 0x0
|
||||
#define MI_VIRTUAL_ADDRESS 0x1
|
||||
|
||||
#define MI_BUFFER_MEMORY_MAIN 0x0
|
||||
#define MI_BUFFER_MEMORY_GTT 0x2
|
||||
#define MI_BUFFER_MEMORY_PER_PROCESS_GTT 0x3
|
||||
|
||||
#define MI_FLIP_CONTINUE 0x0
|
||||
#define MI_FLIP_ON 0x1
|
||||
#define MI_FLIP_OFF 0x2
|
||||
|
||||
#define MI_UNTRUSTED_REGISTER_SPACE 0x0
|
||||
#define MI_TRUSTED_REGISTER_SPACE 0x1
|
||||
|
||||
/* 3D state:
|
||||
*/
|
||||
#define _3DOP_3DSTATE_PIPELINED 0x0
|
||||
#define _3DOP_3DSTATE_NONPIPELINED 0x1
|
||||
#define _3DOP_3DCONTROL 0x2
|
||||
#define _3DOP_3DPRIMITIVE 0x3
|
||||
|
||||
#define _3DSTATE_PIPELINED_POINTERS 0x00
|
||||
#define _3DSTATE_BINDING_TABLE_POINTERS 0x01
|
||||
#define _3DSTATE_VERTEX_BUFFERS 0x08
|
||||
#define _3DSTATE_VERTEX_ELEMENTS 0x09
|
||||
#define _3DSTATE_INDEX_BUFFER 0x0A
|
||||
#define _3DSTATE_VF_STATISTICS 0x0B
|
||||
#define _3DSTATE_DRAWING_RECTANGLE 0x00
|
||||
#define _3DSTATE_CONSTANT_COLOR 0x01
|
||||
#define _3DSTATE_SAMPLER_PALETTE_LOAD 0x02
|
||||
#define _3DSTATE_CHROMA_KEY 0x04
|
||||
#define _3DSTATE_DEPTH_BUFFER 0x05
|
||||
#define _3DSTATE_POLY_STIPPLE_OFFSET 0x06
|
||||
#define _3DSTATE_POLY_STIPPLE_PATTERN 0x07
|
||||
#define _3DSTATE_LINE_STIPPLE 0x08
|
||||
#define _3DSTATE_GLOBAL_DEPTH_OFFSET_CLAMP 0x09
|
||||
#define _3DCONTROL 0x00
|
||||
#define _3DPRIMITIVE 0x00
|
||||
|
||||
#define PIPE_CONTROL_NOWRITE 0x00
|
||||
#define PIPE_CONTROL_WRITEIMMEDIATE 0x01
|
||||
#define PIPE_CONTROL_WRITEDEPTH 0x02
|
||||
#define PIPE_CONTROL_WRITETIMESTAMP 0x03
|
||||
|
||||
#define PIPE_CONTROL_GTTWRITE_PROCESS_LOCAL 0x00
|
||||
#define PIPE_CONTROL_GTTWRITE_GLOBAL 0x01
|
||||
|
||||
#define _3DPRIM_POINTLIST 0x01
|
||||
#define _3DPRIM_LINELIST 0x02
|
||||
#define _3DPRIM_LINESTRIP 0x03
|
||||
#define _3DPRIM_TRILIST 0x04
|
||||
#define _3DPRIM_TRISTRIP 0x05
|
||||
#define _3DPRIM_TRIFAN 0x06
|
||||
#define _3DPRIM_QUADLIST 0x07
|
||||
#define _3DPRIM_QUADSTRIP 0x08
|
||||
#define _3DPRIM_LINELIST_ADJ 0x09
|
||||
#define _3DPRIM_LINESTRIP_ADJ 0x0A
|
||||
#define _3DPRIM_TRILIST_ADJ 0x0B
|
||||
#define _3DPRIM_TRISTRIP_ADJ 0x0C
|
||||
#define _3DPRIM_TRISTRIP_REVERSE 0x0D
|
||||
#define _3DPRIM_POLYGON 0x0E
|
||||
#define _3DPRIM_RECTLIST 0x0F
|
||||
#define _3DPRIM_LINELOOP 0x10
|
||||
#define _3DPRIM_POINTLIST_BF 0x11
|
||||
#define _3DPRIM_LINESTRIP_CONT 0x12
|
||||
#define _3DPRIM_LINESTRIP_BF 0x13
|
||||
#define _3DPRIM_LINESTRIP_CONT_BF 0x14
|
||||
#define _3DPRIM_TRIFAN_NOSTIPPLE 0x15
|
||||
|
||||
#define _3DPRIM_VERTEXBUFFER_ACCESS_SEQUENTIAL 0
|
||||
#define _3DPRIM_VERTEXBUFFER_ACCESS_RANDOM 1
|
||||
|
||||
#define BRW_ANISORATIO_2 0
|
||||
#define BRW_ANISORATIO_4 1
|
||||
#define BRW_ANISORATIO_6 2
|
||||
#define BRW_ANISORATIO_8 3
|
||||
#define BRW_ANISORATIO_10 4
|
||||
#define BRW_ANISORATIO_12 5
|
||||
#define BRW_ANISORATIO_14 6
|
||||
#define BRW_ANISORATIO_16 7
|
||||
|
||||
#define BRW_BLENDFACTOR_ONE 0x1
|
||||
#define BRW_BLENDFACTOR_SRC_COLOR 0x2
|
||||
#define BRW_BLENDFACTOR_SRC_ALPHA 0x3
|
||||
#define BRW_BLENDFACTOR_DST_ALPHA 0x4
|
||||
#define BRW_BLENDFACTOR_DST_COLOR 0x5
|
||||
#define BRW_BLENDFACTOR_SRC_ALPHA_SATURATE 0x6
|
||||
#define BRW_BLENDFACTOR_CONST_COLOR 0x7
|
||||
#define BRW_BLENDFACTOR_CONST_ALPHA 0x8
|
||||
#define BRW_BLENDFACTOR_SRC1_COLOR 0x9
|
||||
#define BRW_BLENDFACTOR_SRC1_ALPHA 0x0A
|
||||
#define BRW_BLENDFACTOR_ZERO 0x11
|
||||
#define BRW_BLENDFACTOR_INV_SRC_COLOR 0x12
|
||||
#define BRW_BLENDFACTOR_INV_SRC_ALPHA 0x13
|
||||
#define BRW_BLENDFACTOR_INV_DST_ALPHA 0x14
|
||||
#define BRW_BLENDFACTOR_INV_DST_COLOR 0x15
|
||||
#define BRW_BLENDFACTOR_INV_CONST_COLOR 0x17
|
||||
#define BRW_BLENDFACTOR_INV_CONST_ALPHA 0x18
|
||||
#define BRW_BLENDFACTOR_INV_SRC1_COLOR 0x19
|
||||
#define BRW_BLENDFACTOR_INV_SRC1_ALPHA 0x1A
|
||||
|
||||
#define BRW_BLENDFUNCTION_ADD 0
|
||||
#define BRW_BLENDFUNCTION_SUBTRACT 1
|
||||
#define BRW_BLENDFUNCTION_REVERSE_SUBTRACT 2
|
||||
#define BRW_BLENDFUNCTION_MIN 3
|
||||
#define BRW_BLENDFUNCTION_MAX 4
|
||||
|
||||
#define BRW_ALPHATEST_FORMAT_UNORM8 0
|
||||
#define BRW_ALPHATEST_FORMAT_FLOAT32 1
|
||||
|
||||
#define BRW_CHROMAKEY_KILL_ON_ANY_MATCH 0
|
||||
#define BRW_CHROMAKEY_REPLACE_BLACK 1
|
||||
|
||||
#define BRW_CLIP_API_OGL 0
|
||||
#define BRW_CLIP_API_DX 1
|
||||
|
||||
#define BRW_CLIPMODE_NORMAL 0
|
||||
#define BRW_CLIPMODE_CLIP_ALL 1
|
||||
#define BRW_CLIPMODE_CLIP_NON_REJECTED 2
|
||||
#define BRW_CLIPMODE_REJECT_ALL 3
|
||||
#define BRW_CLIPMODE_ACCEPT_ALL 4
|
||||
|
||||
#define BRW_CLIP_NDCSPACE 0
|
||||
#define BRW_CLIP_SCREENSPACE 1
|
||||
|
||||
#define BRW_COMPAREFUNCTION_ALWAYS 0
|
||||
#define BRW_COMPAREFUNCTION_NEVER 1
|
||||
#define BRW_COMPAREFUNCTION_LESS 2
|
||||
#define BRW_COMPAREFUNCTION_EQUAL 3
|
||||
#define BRW_COMPAREFUNCTION_LEQUAL 4
|
||||
#define BRW_COMPAREFUNCTION_GREATER 5
|
||||
#define BRW_COMPAREFUNCTION_NOTEQUAL 6
|
||||
#define BRW_COMPAREFUNCTION_GEQUAL 7
|
||||
|
||||
#define BRW_COVERAGE_PIXELS_HALF 0
|
||||
#define BRW_COVERAGE_PIXELS_1 1
|
||||
#define BRW_COVERAGE_PIXELS_2 2
|
||||
#define BRW_COVERAGE_PIXELS_4 3
|
||||
|
||||
#define BRW_CULLMODE_BOTH 0
|
||||
#define BRW_CULLMODE_NONE 1
|
||||
#define BRW_CULLMODE_FRONT 2
|
||||
#define BRW_CULLMODE_BACK 3
|
||||
|
||||
#define BRW_DEFAULTCOLOR_R8G8B8A8_UNORM 0
|
||||
#define BRW_DEFAULTCOLOR_R32G32B32A32_FLOAT 1
|
||||
|
||||
#define BRW_DEPTHFORMAT_D32_FLOAT_S8X24_UINT 0
|
||||
#define BRW_DEPTHFORMAT_D32_FLOAT 1
|
||||
#define BRW_DEPTHFORMAT_D24_UNORM_S8_UINT 2
|
||||
#define BRW_DEPTHFORMAT_D16_UNORM 5
|
||||
|
||||
#define BRW_FLOATING_POINT_IEEE_754 0
|
||||
#define BRW_FLOATING_POINT_NON_IEEE_754 1
|
||||
|
||||
#define BRW_FRONTWINDING_CW 0
|
||||
#define BRW_FRONTWINDING_CCW 1
|
||||
|
||||
#define BRW_SPRITE_POINT_ENABLE 16
|
||||
|
||||
#define BRW_INDEX_BYTE 0
|
||||
#define BRW_INDEX_WORD 1
|
||||
#define BRW_INDEX_DWORD 2
|
||||
|
||||
#define BRW_LOGICOPFUNCTION_CLEAR 0
|
||||
#define BRW_LOGICOPFUNCTION_NOR 1
|
||||
#define BRW_LOGICOPFUNCTION_AND_INVERTED 2
|
||||
#define BRW_LOGICOPFUNCTION_COPY_INVERTED 3
|
||||
#define BRW_LOGICOPFUNCTION_AND_REVERSE 4
|
||||
#define BRW_LOGICOPFUNCTION_INVERT 5
|
||||
#define BRW_LOGICOPFUNCTION_XOR 6
|
||||
#define BRW_LOGICOPFUNCTION_NAND 7
|
||||
#define BRW_LOGICOPFUNCTION_AND 8
|
||||
#define BRW_LOGICOPFUNCTION_EQUIV 9
|
||||
#define BRW_LOGICOPFUNCTION_NOOP 10
|
||||
#define BRW_LOGICOPFUNCTION_OR_INVERTED 11
|
||||
#define BRW_LOGICOPFUNCTION_COPY 12
|
||||
#define BRW_LOGICOPFUNCTION_OR_REVERSE 13
|
||||
#define BRW_LOGICOPFUNCTION_OR 14
|
||||
#define BRW_LOGICOPFUNCTION_SET 15
|
||||
|
||||
#define BRW_MAPFILTER_NEAREST 0x0
|
||||
#define BRW_MAPFILTER_LINEAR 0x1
|
||||
#define BRW_MAPFILTER_ANISOTROPIC 0x2
|
||||
|
||||
#define BRW_MIPFILTER_NONE 0
|
||||
#define BRW_MIPFILTER_NEAREST 1
|
||||
#define BRW_MIPFILTER_LINEAR 3
|
||||
|
||||
#define BRW_POLYGON_FRONT_FACING 0
|
||||
#define BRW_POLYGON_BACK_FACING 1
|
||||
|
||||
#define BRW_PREFILTER_ALWAYS 0x0
|
||||
#define BRW_PREFILTER_NEVER 0x1
|
||||
#define BRW_PREFILTER_LESS 0x2
|
||||
#define BRW_PREFILTER_EQUAL 0x3
|
||||
#define BRW_PREFILTER_LEQUAL 0x4
|
||||
#define BRW_PREFILTER_GREATER 0x5
|
||||
#define BRW_PREFILTER_NOTEQUAL 0x6
|
||||
#define BRW_PREFILTER_GEQUAL 0x7
|
||||
|
||||
#define BRW_PROVOKING_VERTEX_0 0
|
||||
#define BRW_PROVOKING_VERTEX_1 1
|
||||
#define BRW_PROVOKING_VERTEX_2 2
|
||||
|
||||
#define BRW_RASTRULE_UPPER_LEFT 0
|
||||
#define BRW_RASTRULE_UPPER_RIGHT 1
|
||||
|
||||
#define BRW_RENDERTARGET_CLAMPRANGE_UNORM 0
|
||||
#define BRW_RENDERTARGET_CLAMPRANGE_SNORM 1
|
||||
#define BRW_RENDERTARGET_CLAMPRANGE_FORMAT 2
|
||||
|
||||
#define BRW_STENCILOP_KEEP 0
|
||||
#define BRW_STENCILOP_ZERO 1
|
||||
#define BRW_STENCILOP_REPLACE 2
|
||||
#define BRW_STENCILOP_INCRSAT 3
|
||||
#define BRW_STENCILOP_DECRSAT 4
|
||||
#define BRW_STENCILOP_INCR 5
|
||||
#define BRW_STENCILOP_DECR 6
|
||||
#define BRW_STENCILOP_INVERT 7
|
||||
|
||||
#define BRW_SURFACE_MIPMAPLAYOUT_BELOW 0
|
||||
#define BRW_SURFACE_MIPMAPLAYOUT_RIGHT 1
|
||||
|
||||
#define BRW_SURFACEFORMAT_R32G32B32A32_FLOAT 0x000
|
||||
#define BRW_SURFACEFORMAT_R32G32B32A32_SINT 0x001
|
||||
#define BRW_SURFACEFORMAT_R32G32B32A32_UINT 0x002
|
||||
#define BRW_SURFACEFORMAT_R32G32B32A32_UNORM 0x003
|
||||
#define BRW_SURFACEFORMAT_R32G32B32A32_SNORM 0x004
|
||||
#define BRW_SURFACEFORMAT_R64G64_FLOAT 0x005
|
||||
#define BRW_SURFACEFORMAT_R32G32B32X32_FLOAT 0x006
|
||||
#define BRW_SURFACEFORMAT_R32G32B32A32_SSCALED 0x007
|
||||
#define BRW_SURFACEFORMAT_R32G32B32A32_USCALED 0x008
|
||||
#define BRW_SURFACEFORMAT_R32G32B32_FLOAT 0x040
|
||||
#define BRW_SURFACEFORMAT_R32G32B32_SINT 0x041
|
||||
#define BRW_SURFACEFORMAT_R32G32B32_UINT 0x042
|
||||
#define BRW_SURFACEFORMAT_R32G32B32_UNORM 0x043
|
||||
#define BRW_SURFACEFORMAT_R32G32B32_SNORM 0x044
|
||||
#define BRW_SURFACEFORMAT_R32G32B32_SSCALED 0x045
|
||||
#define BRW_SURFACEFORMAT_R32G32B32_USCALED 0x046
|
||||
#define BRW_SURFACEFORMAT_R16G16B16A16_UNORM 0x080
|
||||
#define BRW_SURFACEFORMAT_R16G16B16A16_SNORM 0x081
|
||||
#define BRW_SURFACEFORMAT_R16G16B16A16_SINT 0x082
|
||||
#define BRW_SURFACEFORMAT_R16G16B16A16_UINT 0x083
|
||||
#define BRW_SURFACEFORMAT_R16G16B16A16_FLOAT 0x084
|
||||
#define BRW_SURFACEFORMAT_R32G32_FLOAT 0x085
|
||||
#define BRW_SURFACEFORMAT_R32G32_SINT 0x086
|
||||
#define BRW_SURFACEFORMAT_R32G32_UINT 0x087
|
||||
#define BRW_SURFACEFORMAT_R32_FLOAT_X8X24_TYPELESS 0x088
|
||||
#define BRW_SURFACEFORMAT_X32_TYPELESS_G8X24_UINT 0x089
|
||||
#define BRW_SURFACEFORMAT_L32A32_FLOAT 0x08A
|
||||
#define BRW_SURFACEFORMAT_R32G32_UNORM 0x08B
|
||||
#define BRW_SURFACEFORMAT_R32G32_SNORM 0x08C
|
||||
#define BRW_SURFACEFORMAT_R64_FLOAT 0x08D
|
||||
#define BRW_SURFACEFORMAT_R16G16B16X16_UNORM 0x08E
|
||||
#define BRW_SURFACEFORMAT_R16G16B16X16_FLOAT 0x08F
|
||||
#define BRW_SURFACEFORMAT_A32X32_FLOAT 0x090
|
||||
#define BRW_SURFACEFORMAT_L32X32_FLOAT 0x091
|
||||
#define BRW_SURFACEFORMAT_I32X32_FLOAT 0x092
|
||||
#define BRW_SURFACEFORMAT_R16G16B16A16_SSCALED 0x093
|
||||
#define BRW_SURFACEFORMAT_R16G16B16A16_USCALED 0x094
|
||||
#define BRW_SURFACEFORMAT_R32G32_SSCALED 0x095
|
||||
#define BRW_SURFACEFORMAT_R32G32_USCALED 0x096
|
||||
#define BRW_SURFACEFORMAT_B8G8R8A8_UNORM 0x0C0
|
||||
#define BRW_SURFACEFORMAT_B8G8R8A8_UNORM_SRGB 0x0C1
|
||||
#define BRW_SURFACEFORMAT_R10G10B10A2_UNORM 0x0C2
|
||||
#define BRW_SURFACEFORMAT_R10G10B10A2_UNORM_SRGB 0x0C3
|
||||
#define BRW_SURFACEFORMAT_R10G10B10A2_UINT 0x0C4
|
||||
#define BRW_SURFACEFORMAT_R10G10B10_SNORM_A2_UNORM 0x0C5
|
||||
#define BRW_SURFACEFORMAT_R8G8B8A8_UNORM 0x0C7
|
||||
#define BRW_SURFACEFORMAT_R8G8B8A8_UNORM_SRGB 0x0C8
|
||||
#define BRW_SURFACEFORMAT_R8G8B8A8_SNORM 0x0C9
|
||||
#define BRW_SURFACEFORMAT_R8G8B8A8_SINT 0x0CA
|
||||
#define BRW_SURFACEFORMAT_R8G8B8A8_UINT 0x0CB
|
||||
#define BRW_SURFACEFORMAT_R16G16_UNORM 0x0CC
|
||||
#define BRW_SURFACEFORMAT_R16G16_SNORM 0x0CD
|
||||
#define BRW_SURFACEFORMAT_R16G16_SINT 0x0CE
|
||||
#define BRW_SURFACEFORMAT_R16G16_UINT 0x0CF
|
||||
#define BRW_SURFACEFORMAT_R16G16_FLOAT 0x0D0
|
||||
#define BRW_SURFACEFORMAT_B10G10R10A2_UNORM 0x0D1
|
||||
#define BRW_SURFACEFORMAT_B10G10R10A2_UNORM_SRGB 0x0D2
|
||||
#define BRW_SURFACEFORMAT_R11G11B10_FLOAT 0x0D3
|
||||
#define BRW_SURFACEFORMAT_R32_SINT 0x0D6
|
||||
#define BRW_SURFACEFORMAT_R32_UINT 0x0D7
|
||||
#define BRW_SURFACEFORMAT_R32_FLOAT 0x0D8
|
||||
#define BRW_SURFACEFORMAT_R24_UNORM_X8_TYPELESS 0x0D9
|
||||
#define BRW_SURFACEFORMAT_X24_TYPELESS_G8_UINT 0x0DA
|
||||
#define BRW_SURFACEFORMAT_L16A16_UNORM 0x0DF
|
||||
#define BRW_SURFACEFORMAT_I24X8_UNORM 0x0E0
|
||||
#define BRW_SURFACEFORMAT_L24X8_UNORM 0x0E1
|
||||
#define BRW_SURFACEFORMAT_A24X8_UNORM 0x0E2
|
||||
#define BRW_SURFACEFORMAT_I32_FLOAT 0x0E3
|
||||
#define BRW_SURFACEFORMAT_L32_FLOAT 0x0E4
|
||||
#define BRW_SURFACEFORMAT_A32_FLOAT 0x0E5
|
||||
#define BRW_SURFACEFORMAT_B8G8R8X8_UNORM 0x0E9
|
||||
#define BRW_SURFACEFORMAT_B8G8R8X8_UNORM_SRGB 0x0EA
|
||||
#define BRW_SURFACEFORMAT_R8G8B8X8_UNORM 0x0EB
|
||||
#define BRW_SURFACEFORMAT_R8G8B8X8_UNORM_SRGB 0x0EC
|
||||
#define BRW_SURFACEFORMAT_R9G9B9E5_SHAREDEXP 0x0ED
|
||||
#define BRW_SURFACEFORMAT_B10G10R10X2_UNORM 0x0EE
|
||||
#define BRW_SURFACEFORMAT_L16A16_FLOAT 0x0F0
|
||||
#define BRW_SURFACEFORMAT_R32_UNORM 0x0F1
|
||||
#define BRW_SURFACEFORMAT_R32_SNORM 0x0F2
|
||||
#define BRW_SURFACEFORMAT_R10G10B10X2_USCALED 0x0F3
|
||||
#define BRW_SURFACEFORMAT_R8G8B8A8_SSCALED 0x0F4
|
||||
#define BRW_SURFACEFORMAT_R8G8B8A8_USCALED 0x0F5
|
||||
#define BRW_SURFACEFORMAT_R16G16_SSCALED 0x0F6
|
||||
#define BRW_SURFACEFORMAT_R16G16_USCALED 0x0F7
|
||||
#define BRW_SURFACEFORMAT_R32_SSCALED 0x0F8
|
||||
#define BRW_SURFACEFORMAT_R32_USCALED 0x0F9
|
||||
#define BRW_SURFACEFORMAT_B5G6R5_UNORM 0x100
|
||||
#define BRW_SURFACEFORMAT_B5G6R5_UNORM_SRGB 0x101
|
||||
#define BRW_SURFACEFORMAT_B5G5R5A1_UNORM 0x102
|
||||
#define BRW_SURFACEFORMAT_B5G5R5A1_UNORM_SRGB 0x103
|
||||
#define BRW_SURFACEFORMAT_B4G4R4A4_UNORM 0x104
|
||||
#define BRW_SURFACEFORMAT_B4G4R4A4_UNORM_SRGB 0x105
|
||||
#define BRW_SURFACEFORMAT_R8G8_UNORM 0x106
|
||||
#define BRW_SURFACEFORMAT_R8G8_SNORM 0x107
|
||||
#define BRW_SURFACEFORMAT_R8G8_SINT 0x108
|
||||
#define BRW_SURFACEFORMAT_R8G8_UINT 0x109
|
||||
#define BRW_SURFACEFORMAT_R16_UNORM 0x10A
|
||||
#define BRW_SURFACEFORMAT_R16_SNORM 0x10B
|
||||
#define BRW_SURFACEFORMAT_R16_SINT 0x10C
|
||||
#define BRW_SURFACEFORMAT_R16_UINT 0x10D
|
||||
#define BRW_SURFACEFORMAT_R16_FLOAT 0x10E
|
||||
#define BRW_SURFACEFORMAT_I16_UNORM 0x111
|
||||
#define BRW_SURFACEFORMAT_L16_UNORM 0x112
|
||||
#define BRW_SURFACEFORMAT_A16_UNORM 0x113
|
||||
#define BRW_SURFACEFORMAT_L8A8_UNORM 0x114
|
||||
#define BRW_SURFACEFORMAT_I16_FLOAT 0x115
|
||||
#define BRW_SURFACEFORMAT_L16_FLOAT 0x116
|
||||
#define BRW_SURFACEFORMAT_A16_FLOAT 0x117
|
||||
#define BRW_SURFACEFORMAT_R5G5_SNORM_B6_UNORM 0x119
|
||||
#define BRW_SURFACEFORMAT_B5G5R5X1_UNORM 0x11A
|
||||
#define BRW_SURFACEFORMAT_B5G5R5X1_UNORM_SRGB 0x11B
|
||||
#define BRW_SURFACEFORMAT_R8G8_SSCALED 0x11C
|
||||
#define BRW_SURFACEFORMAT_R8G8_USCALED 0x11D
|
||||
#define BRW_SURFACEFORMAT_R16_SSCALED 0x11E
|
||||
#define BRW_SURFACEFORMAT_R16_USCALED 0x11F
|
||||
#define BRW_SURFACEFORMAT_R8_UNORM 0x140
|
||||
#define BRW_SURFACEFORMAT_R8_SNORM 0x141
|
||||
#define BRW_SURFACEFORMAT_R8_SINT 0x142
|
||||
#define BRW_SURFACEFORMAT_R8_UINT 0x143
|
||||
#define BRW_SURFACEFORMAT_A8_UNORM 0x144
|
||||
#define BRW_SURFACEFORMAT_I8_UNORM 0x145
|
||||
#define BRW_SURFACEFORMAT_L8_UNORM 0x146
|
||||
#define BRW_SURFACEFORMAT_P4A4_UNORM 0x147
|
||||
#define BRW_SURFACEFORMAT_A4P4_UNORM 0x148
|
||||
#define BRW_SURFACEFORMAT_R8_SSCALED 0x149
|
||||
#define BRW_SURFACEFORMAT_R8_USCALED 0x14A
|
||||
#define BRW_SURFACEFORMAT_R1_UINT 0x181
|
||||
#define BRW_SURFACEFORMAT_YCRCB_NORMAL 0x182
|
||||
#define BRW_SURFACEFORMAT_YCRCB_SWAPUVY 0x183
|
||||
#define BRW_SURFACEFORMAT_BC1_UNORM 0x186
|
||||
#define BRW_SURFACEFORMAT_BC2_UNORM 0x187
|
||||
#define BRW_SURFACEFORMAT_BC3_UNORM 0x188
|
||||
#define BRW_SURFACEFORMAT_BC4_UNORM 0x189
|
||||
#define BRW_SURFACEFORMAT_BC5_UNORM 0x18A
|
||||
#define BRW_SURFACEFORMAT_BC1_UNORM_SRGB 0x18B
|
||||
#define BRW_SURFACEFORMAT_BC2_UNORM_SRGB 0x18C
|
||||
#define BRW_SURFACEFORMAT_BC3_UNORM_SRGB 0x18D
|
||||
#define BRW_SURFACEFORMAT_MONO8 0x18E
|
||||
#define BRW_SURFACEFORMAT_YCRCB_SWAPUV 0x18F
|
||||
#define BRW_SURFACEFORMAT_YCRCB_SWAPY 0x190
|
||||
#define BRW_SURFACEFORMAT_DXT1_RGB 0x191
|
||||
#define BRW_SURFACEFORMAT_FXT1 0x192
|
||||
#define BRW_SURFACEFORMAT_R8G8B8_UNORM 0x193
|
||||
#define BRW_SURFACEFORMAT_R8G8B8_SNORM 0x194
|
||||
#define BRW_SURFACEFORMAT_R8G8B8_SSCALED 0x195
|
||||
#define BRW_SURFACEFORMAT_R8G8B8_USCALED 0x196
|
||||
#define BRW_SURFACEFORMAT_R64G64B64A64_FLOAT 0x197
|
||||
#define BRW_SURFACEFORMAT_R64G64B64_FLOAT 0x198
|
||||
#define BRW_SURFACEFORMAT_BC4_SNORM 0x199
|
||||
#define BRW_SURFACEFORMAT_BC5_SNORM 0x19A
|
||||
#define BRW_SURFACEFORMAT_R16G16B16_UNORM 0x19C
|
||||
#define BRW_SURFACEFORMAT_R16G16B16_SNORM 0x19D
|
||||
#define BRW_SURFACEFORMAT_R16G16B16_SSCALED 0x19E
|
||||
#define BRW_SURFACEFORMAT_R16G16B16_USCALED 0x19F
|
||||
|
||||
#define BRW_SURFACERETURNFORMAT_FLOAT32 0
|
||||
#define BRW_SURFACERETURNFORMAT_S1 1
|
||||
|
||||
#define BRW_SURFACE_1D 0
|
||||
#define BRW_SURFACE_2D 1
|
||||
#define BRW_SURFACE_3D 2
|
||||
#define BRW_SURFACE_CUBE 3
|
||||
#define BRW_SURFACE_BUFFER 4
|
||||
#define BRW_SURFACE_NULL 7
|
||||
|
||||
#define BRW_TEXCOORDMODE_WRAP 0
|
||||
#define BRW_TEXCOORDMODE_MIRROR 1
|
||||
#define BRW_TEXCOORDMODE_CLAMP 2
|
||||
#define BRW_TEXCOORDMODE_CUBE 3
|
||||
#define BRW_TEXCOORDMODE_CLAMP_BORDER 4
|
||||
#define BRW_TEXCOORDMODE_MIRROR_ONCE 5
|
||||
|
||||
#define BRW_THREAD_PRIORITY_NORMAL 0
|
||||
#define BRW_THREAD_PRIORITY_HIGH 1
|
||||
|
||||
#define BRW_TILEWALK_XMAJOR 0
|
||||
#define BRW_TILEWALK_YMAJOR 1
|
||||
|
||||
#define BRW_VERTEX_SUBPIXEL_PRECISION_8BITS 0
|
||||
#define BRW_VERTEX_SUBPIXEL_PRECISION_4BITS 1
|
||||
|
||||
#define BRW_VERTEXBUFFER_ACCESS_VERTEXDATA 0
|
||||
#define BRW_VERTEXBUFFER_ACCESS_INSTANCEDATA 1
|
||||
|
||||
#define BRW_VFCOMPONENT_NOSTORE 0
|
||||
#define BRW_VFCOMPONENT_STORE_SRC 1
|
||||
#define BRW_VFCOMPONENT_STORE_0 2
|
||||
#define BRW_VFCOMPONENT_STORE_1_FLT 3
|
||||
#define BRW_VFCOMPONENT_STORE_1_INT 4
|
||||
#define BRW_VFCOMPONENT_STORE_VID 5
|
||||
#define BRW_VFCOMPONENT_STORE_IID 6
|
||||
#define BRW_VFCOMPONENT_STORE_PID 7
|
||||
|
||||
|
||||
|
||||
/* Execution Unit (EU) defines
|
||||
*/
|
||||
|
||||
#define BRW_ALIGN_1 0
|
||||
#define BRW_ALIGN_16 1
|
||||
|
||||
#define BRW_ADDRESS_DIRECT 0
|
||||
#define BRW_ADDRESS_REGISTER_INDIRECT_REGISTER 1
|
||||
|
||||
#define BRW_CHANNEL_X 0
|
||||
#define BRW_CHANNEL_Y 1
|
||||
#define BRW_CHANNEL_Z 2
|
||||
#define BRW_CHANNEL_W 3
|
||||
|
||||
#define BRW_COMPRESSION_NONE 0
|
||||
#define BRW_COMPRESSION_2NDHALF 1
|
||||
#define BRW_COMPRESSION_COMPRESSED 2
|
||||
|
||||
#define BRW_CONDITIONAL_NONE 0
|
||||
#define BRW_CONDITIONAL_Z 1
|
||||
#define BRW_CONDITIONAL_NZ 2
|
||||
#define BRW_CONDITIONAL_EQ 1 /* Z */
|
||||
#define BRW_CONDITIONAL_NEQ 2 /* NZ */
|
||||
#define BRW_CONDITIONAL_G 3
|
||||
#define BRW_CONDITIONAL_GE 4
|
||||
#define BRW_CONDITIONAL_L 5
|
||||
#define BRW_CONDITIONAL_LE 6
|
||||
#define BRW_CONDITIONAL_C 7
|
||||
#define BRW_CONDITIONAL_O 8
|
||||
|
||||
#define BRW_DEBUG_NONE 0
|
||||
#define BRW_DEBUG_BREAKPOINT 1
|
||||
|
||||
#define BRW_DEPENDENCY_NORMAL 0
|
||||
#define BRW_DEPENDENCY_NOTCLEARED 1
|
||||
#define BRW_DEPENDENCY_NOTCHECKED 2
|
||||
#define BRW_DEPENDENCY_DISABLE 3
|
||||
|
||||
#define BRW_EXECUTE_1 0
|
||||
#define BRW_EXECUTE_2 1
|
||||
#define BRW_EXECUTE_4 2
|
||||
#define BRW_EXECUTE_8 3
|
||||
#define BRW_EXECUTE_16 4
|
||||
#define BRW_EXECUTE_32 5
|
||||
|
||||
#define BRW_HORIZONTAL_STRIDE_0 0
|
||||
#define BRW_HORIZONTAL_STRIDE_1 1
|
||||
#define BRW_HORIZONTAL_STRIDE_2 2
|
||||
#define BRW_HORIZONTAL_STRIDE_4 3
|
||||
|
||||
#define BRW_INSTRUCTION_NORMAL 0
|
||||
#define BRW_INSTRUCTION_SATURATE 1
|
||||
|
||||
#define BRW_MASK_ENABLE 0
|
||||
#define BRW_MASK_DISABLE 1
|
||||
|
||||
#define BRW_OPCODE_MOV 1
|
||||
#define BRW_OPCODE_SEL 2
|
||||
#define BRW_OPCODE_NOT 4
|
||||
#define BRW_OPCODE_AND 5
|
||||
#define BRW_OPCODE_OR 6
|
||||
#define BRW_OPCODE_XOR 7
|
||||
#define BRW_OPCODE_SHR 8
|
||||
#define BRW_OPCODE_SHL 9
|
||||
#define BRW_OPCODE_RSR 10
|
||||
#define BRW_OPCODE_RSL 11
|
||||
#define BRW_OPCODE_ASR 12
|
||||
#define BRW_OPCODE_CMP 16
|
||||
#define BRW_OPCODE_JMPI 32
|
||||
#define BRW_OPCODE_IF 34
|
||||
#define BRW_OPCODE_IFF 35
|
||||
#define BRW_OPCODE_ELSE 36
|
||||
#define BRW_OPCODE_ENDIF 37
|
||||
#define BRW_OPCODE_DO 38
|
||||
#define BRW_OPCODE_WHILE 39
|
||||
#define BRW_OPCODE_BREAK 40
|
||||
#define BRW_OPCODE_CONTINUE 41
|
||||
#define BRW_OPCODE_HALT 42
|
||||
#define BRW_OPCODE_MSAVE 44
|
||||
#define BRW_OPCODE_MRESTORE 45
|
||||
#define BRW_OPCODE_PUSH 46
|
||||
#define BRW_OPCODE_POP 47
|
||||
#define BRW_OPCODE_WAIT 48
|
||||
#define BRW_OPCODE_SEND 49
|
||||
#define BRW_OPCODE_ADD 64
|
||||
#define BRW_OPCODE_MUL 65
|
||||
#define BRW_OPCODE_AVG 66
|
||||
#define BRW_OPCODE_FRC 67
|
||||
#define BRW_OPCODE_RNDU 68
|
||||
#define BRW_OPCODE_RNDD 69
|
||||
#define BRW_OPCODE_RNDE 70
|
||||
#define BRW_OPCODE_RNDZ 71
|
||||
#define BRW_OPCODE_MAC 72
|
||||
#define BRW_OPCODE_MACH 73
|
||||
#define BRW_OPCODE_LZD 74
|
||||
#define BRW_OPCODE_SAD2 80
|
||||
#define BRW_OPCODE_SADA2 81
|
||||
#define BRW_OPCODE_DP4 84
|
||||
#define BRW_OPCODE_DPH 85
|
||||
#define BRW_OPCODE_DP3 86
|
||||
#define BRW_OPCODE_DP2 87
|
||||
#define BRW_OPCODE_DPA2 88
|
||||
#define BRW_OPCODE_LINE 89
|
||||
#define BRW_OPCODE_NOP 126
|
||||
|
||||
#define BRW_PREDICATE_NONE 0
|
||||
#define BRW_PREDICATE_NORMAL 1
|
||||
#define BRW_PREDICATE_ALIGN1_ANYV 2
|
||||
#define BRW_PREDICATE_ALIGN1_ALLV 3
|
||||
#define BRW_PREDICATE_ALIGN1_ANY2H 4
|
||||
#define BRW_PREDICATE_ALIGN1_ALL2H 5
|
||||
#define BRW_PREDICATE_ALIGN1_ANY4H 6
|
||||
#define BRW_PREDICATE_ALIGN1_ALL4H 7
|
||||
#define BRW_PREDICATE_ALIGN1_ANY8H 8
|
||||
#define BRW_PREDICATE_ALIGN1_ALL8H 9
|
||||
#define BRW_PREDICATE_ALIGN1_ANY16H 10
|
||||
#define BRW_PREDICATE_ALIGN1_ALL16H 11
|
||||
#define BRW_PREDICATE_ALIGN16_REPLICATE_X 2
|
||||
#define BRW_PREDICATE_ALIGN16_REPLICATE_Y 3
|
||||
#define BRW_PREDICATE_ALIGN16_REPLICATE_Z 4
|
||||
#define BRW_PREDICATE_ALIGN16_REPLICATE_W 5
|
||||
#define BRW_PREDICATE_ALIGN16_ANY4H 6
|
||||
#define BRW_PREDICATE_ALIGN16_ALL4H 7
|
||||
|
||||
#define BRW_ARCHITECTURE_REGISTER_FILE 0
|
||||
#define BRW_GENERAL_REGISTER_FILE 1
|
||||
#define BRW_MESSAGE_REGISTER_FILE 2
|
||||
#define BRW_IMMEDIATE_VALUE 3
|
||||
|
||||
#define BRW_REGISTER_TYPE_UD 0
|
||||
#define BRW_REGISTER_TYPE_D 1
|
||||
#define BRW_REGISTER_TYPE_UW 2
|
||||
#define BRW_REGISTER_TYPE_W 3
|
||||
#define BRW_REGISTER_TYPE_UB 4
|
||||
#define BRW_REGISTER_TYPE_B 5
|
||||
#define BRW_REGISTER_TYPE_VF 5 /* packed float vector, immediates only? */
|
||||
#define BRW_REGISTER_TYPE_HF 6
|
||||
#define BRW_REGISTER_TYPE_V 6 /* packed int vector, immediates only, uword dest only */
|
||||
#define BRW_REGISTER_TYPE_F 7
|
||||
|
||||
#define BRW_ARF_NULL 0x00
|
||||
#define BRW_ARF_ADDRESS 0x10
|
||||
#define BRW_ARF_ACCUMULATOR 0x20
|
||||
#define BRW_ARF_FLAG 0x30
|
||||
#define BRW_ARF_MASK 0x40
|
||||
#define BRW_ARF_MASK_STACK 0x50
|
||||
#define BRW_ARF_MASK_STACK_DEPTH 0x60
|
||||
#define BRW_ARF_STATE 0x70
|
||||
#define BRW_ARF_CONTROL 0x80
|
||||
#define BRW_ARF_NOTIFICATION_COUNT 0x90
|
||||
#define BRW_ARF_IP 0xA0
|
||||
|
||||
#define BRW_AMASK 0
|
||||
#define BRW_IMASK 1
|
||||
#define BRW_LMASK 2
|
||||
#define BRW_CMASK 3
|
||||
|
||||
|
||||
|
||||
#define BRW_THREAD_NORMAL 0
|
||||
#define BRW_THREAD_ATOMIC 1
|
||||
#define BRW_THREAD_SWITCH 2
|
||||
|
||||
#define BRW_VERTICAL_STRIDE_0 0
|
||||
#define BRW_VERTICAL_STRIDE_1 1
|
||||
#define BRW_VERTICAL_STRIDE_2 2
|
||||
#define BRW_VERTICAL_STRIDE_4 3
|
||||
#define BRW_VERTICAL_STRIDE_8 4
|
||||
#define BRW_VERTICAL_STRIDE_16 5
|
||||
#define BRW_VERTICAL_STRIDE_32 6
|
||||
#define BRW_VERTICAL_STRIDE_64 7
|
||||
#define BRW_VERTICAL_STRIDE_128 8
|
||||
#define BRW_VERTICAL_STRIDE_256 9
|
||||
#define BRW_VERTICAL_STRIDE_ONE_DIMENSIONAL 0xF
|
||||
|
||||
#define BRW_WIDTH_1 0
|
||||
#define BRW_WIDTH_2 1
|
||||
#define BRW_WIDTH_4 2
|
||||
#define BRW_WIDTH_8 3
|
||||
#define BRW_WIDTH_16 4
|
||||
|
||||
#define BRW_STATELESS_BUFFER_BOUNDARY_1K 0
|
||||
#define BRW_STATELESS_BUFFER_BOUNDARY_2K 1
|
||||
#define BRW_STATELESS_BUFFER_BOUNDARY_4K 2
|
||||
#define BRW_STATELESS_BUFFER_BOUNDARY_8K 3
|
||||
#define BRW_STATELESS_BUFFER_BOUNDARY_16K 4
|
||||
#define BRW_STATELESS_BUFFER_BOUNDARY_32K 5
|
||||
#define BRW_STATELESS_BUFFER_BOUNDARY_64K 6
|
||||
#define BRW_STATELESS_BUFFER_BOUNDARY_128K 7
|
||||
#define BRW_STATELESS_BUFFER_BOUNDARY_256K 8
|
||||
#define BRW_STATELESS_BUFFER_BOUNDARY_512K 9
|
||||
#define BRW_STATELESS_BUFFER_BOUNDARY_1M 10
|
||||
#define BRW_STATELESS_BUFFER_BOUNDARY_2M 11
|
||||
|
||||
#define BRW_POLYGON_FACING_FRONT 0
|
||||
#define BRW_POLYGON_FACING_BACK 1
|
||||
|
||||
#define BRW_MESSAGE_TARGET_NULL 0
|
||||
#define BRW_MESSAGE_TARGET_MATH 1
|
||||
#define BRW_MESSAGE_TARGET_SAMPLER 2
|
||||
#define BRW_MESSAGE_TARGET_GATEWAY 3
|
||||
#define BRW_MESSAGE_TARGET_DATAPORT_READ 4
|
||||
#define BRW_MESSAGE_TARGET_DATAPORT_WRITE 5
|
||||
#define BRW_MESSAGE_TARGET_URB 6
|
||||
#define BRW_MESSAGE_TARGET_THREAD_SPAWNER 7
|
||||
|
||||
#define BRW_SAMPLER_RETURN_FORMAT_FLOAT32 0
|
||||
#define BRW_SAMPLER_RETURN_FORMAT_UINT32 2
|
||||
#define BRW_SAMPLER_RETURN_FORMAT_SINT32 3
|
||||
|
||||
#define BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE 0
|
||||
#define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE 0
|
||||
#define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS 0
|
||||
#define BRW_SAMPLER_MESSAGE_SIMD8_KILLPIX 1
|
||||
#define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_LOD 1
|
||||
#define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_LOD 1
|
||||
#define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_GRADIENTS 2
|
||||
#define BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_GRADIENTS 2
|
||||
#define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_COMPARE 0
|
||||
#define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_COMPARE 2
|
||||
#define BRW_SAMPLER_MESSAGE_SIMD4X2_RESINFO 2
|
||||
#define BRW_SAMPLER_MESSAGE_SIMD8_RESINFO 2
|
||||
#define BRW_SAMPLER_MESSAGE_SIMD16_RESINFO 2
|
||||
#define BRW_SAMPLER_MESSAGE_SIMD4X2_LD 3
|
||||
#define BRW_SAMPLER_MESSAGE_SIMD8_LD 3
|
||||
#define BRW_SAMPLER_MESSAGE_SIMD16_LD 3
|
||||
|
||||
#define BRW_DATAPORT_OWORD_BLOCK_1_OWORDLOW 0
|
||||
#define BRW_DATAPORT_OWORD_BLOCK_1_OWORDHIGH 1
|
||||
#define BRW_DATAPORT_OWORD_BLOCK_2_OWORDS 2
|
||||
#define BRW_DATAPORT_OWORD_BLOCK_4_OWORDS 3
|
||||
#define BRW_DATAPORT_OWORD_BLOCK_8_OWORDS 4
|
||||
|
||||
#define BRW_DATAPORT_OWORD_DUAL_BLOCK_1OWORD 0
|
||||
#define BRW_DATAPORT_OWORD_DUAL_BLOCK_4OWORDS 2
|
||||
|
||||
#define BRW_DATAPORT_DWORD_SCATTERED_BLOCK_8DWORDS 2
|
||||
#define BRW_DATAPORT_DWORD_SCATTERED_BLOCK_16DWORDS 3
|
||||
|
||||
#define BRW_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ 0
|
||||
#define BRW_DATAPORT_READ_MESSAGE_OWORD_DUAL_BLOCK_READ 1
|
||||
#define BRW_DATAPORT_READ_MESSAGE_DWORD_BLOCK_READ 2
|
||||
#define BRW_DATAPORT_READ_MESSAGE_DWORD_SCATTERED_READ 3
|
||||
|
||||
#define BRW_DATAPORT_READ_TARGET_DATA_CACHE 0
|
||||
#define BRW_DATAPORT_READ_TARGET_RENDER_CACHE 1
|
||||
#define BRW_DATAPORT_READ_TARGET_SAMPLER_CACHE 2
|
||||
|
||||
#define BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE 0
|
||||
#define BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE_REPLICATED 1
|
||||
#define BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD8_DUAL_SOURCE_SUBSPAN01 2
|
||||
#define BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD8_DUAL_SOURCE_SUBSPAN23 3
|
||||
#define BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD8_SINGLE_SOURCE_SUBSPAN01 4
|
||||
|
||||
#define BRW_DATAPORT_WRITE_MESSAGE_OWORD_BLOCK_WRITE 0
|
||||
#define BRW_DATAPORT_WRITE_MESSAGE_OWORD_DUAL_BLOCK_WRITE 1
|
||||
#define BRW_DATAPORT_WRITE_MESSAGE_DWORD_BLOCK_WRITE 2
|
||||
#define BRW_DATAPORT_WRITE_MESSAGE_DWORD_SCATTERED_WRITE 3
|
||||
#define BRW_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE 4
|
||||
#define BRW_DATAPORT_WRITE_MESSAGE_STREAMED_VERTEX_BUFFER_WRITE 5
|
||||
#define BRW_DATAPORT_WRITE_MESSAGE_FLUSH_RENDER_CACHE 7
|
||||
|
||||
#define BRW_MATH_FUNCTION_INV 1
|
||||
#define BRW_MATH_FUNCTION_LOG 2
|
||||
#define BRW_MATH_FUNCTION_EXP 3
|
||||
#define BRW_MATH_FUNCTION_SQRT 4
|
||||
#define BRW_MATH_FUNCTION_RSQ 5
|
||||
#define BRW_MATH_FUNCTION_SIN 6 /* was 7 */
|
||||
#define BRW_MATH_FUNCTION_COS 7 /* was 8 */
|
||||
#define BRW_MATH_FUNCTION_SINCOS 8 /* was 6 */
|
||||
#define BRW_MATH_FUNCTION_TAN 9
|
||||
#define BRW_MATH_FUNCTION_POW 10
|
||||
#define BRW_MATH_FUNCTION_INT_DIV_QUOTIENT_AND_REMAINDER 11
|
||||
#define BRW_MATH_FUNCTION_INT_DIV_QUOTIENT 12
|
||||
#define BRW_MATH_FUNCTION_INT_DIV_REMAINDER 13
|
||||
|
||||
#define BRW_MATH_INTEGER_UNSIGNED 0
|
||||
#define BRW_MATH_INTEGER_SIGNED 1
|
||||
|
||||
#define BRW_MATH_PRECISION_FULL 0
|
||||
#define BRW_MATH_PRECISION_PARTIAL 1
|
||||
|
||||
#define BRW_MATH_SATURATE_NONE 0
|
||||
#define BRW_MATH_SATURATE_SATURATE 1
|
||||
|
||||
#define BRW_MATH_DATA_VECTOR 0
|
||||
#define BRW_MATH_DATA_SCALAR 1
|
||||
|
||||
#define BRW_URB_OPCODE_WRITE 0
|
||||
|
||||
#define BRW_URB_SWIZZLE_NONE 0
|
||||
#define BRW_URB_SWIZZLE_INTERLEAVE 1
|
||||
#define BRW_URB_SWIZZLE_TRANSPOSE 2
|
||||
|
||||
#define BRW_SCRATCH_SPACE_SIZE_1K 0
|
||||
#define BRW_SCRATCH_SPACE_SIZE_2K 1
|
||||
#define BRW_SCRATCH_SPACE_SIZE_4K 2
|
||||
#define BRW_SCRATCH_SPACE_SIZE_8K 3
|
||||
#define BRW_SCRATCH_SPACE_SIZE_16K 4
|
||||
#define BRW_SCRATCH_SPACE_SIZE_32K 5
|
||||
#define BRW_SCRATCH_SPACE_SIZE_64K 6
|
||||
#define BRW_SCRATCH_SPACE_SIZE_128K 7
|
||||
#define BRW_SCRATCH_SPACE_SIZE_256K 8
|
||||
#define BRW_SCRATCH_SPACE_SIZE_512K 9
|
||||
#define BRW_SCRATCH_SPACE_SIZE_1M 10
|
||||
#define BRW_SCRATCH_SPACE_SIZE_2M 11
|
||||
|
||||
|
||||
|
||||
|
||||
#define CMD_URB_FENCE 0x6000
|
||||
#define CMD_CONST_BUFFER_STATE 0x6001
|
||||
#define CMD_CONST_BUFFER 0x6002
|
||||
|
||||
#define CMD_STATE_BASE_ADDRESS 0x6101
|
||||
#define CMD_STATE_INSN_POINTER 0x6102
|
||||
#define CMD_PIPELINE_SELECT 0x6104
|
||||
|
||||
#define CMD_PIPELINED_STATE_POINTERS 0x7800
|
||||
#define CMD_BINDING_TABLE_PTRS 0x7801
|
||||
#define CMD_VERTEX_BUFFER 0x7808
|
||||
#define CMD_VERTEX_ELEMENT 0x7809
|
||||
#define CMD_INDEX_BUFFER 0x780a
|
||||
#define CMD_VF_STATISTICS 0x780b
|
||||
|
||||
#define CMD_DRAW_RECT 0x7900
|
||||
#define CMD_BLEND_CONSTANT_COLOR 0x7901
|
||||
#define CMD_CHROMA_KEY 0x7904
|
||||
#define CMD_DEPTH_BUFFER 0x7905
|
||||
#define CMD_POLY_STIPPLE_OFFSET 0x7906
|
||||
#define CMD_POLY_STIPPLE_PATTERN 0x7907
|
||||
#define CMD_LINE_STIPPLE_PATTERN 0x7908
|
||||
#define CMD_GLOBAL_DEPTH_OFFSET_CLAMP 0x7909
|
||||
|
||||
#define CMD_PIPE_CONTROL 0x7a00
|
||||
|
||||
#define CMD_3D_PRIM 0x7b00
|
||||
|
||||
#define CMD_MI_FLUSH 0x0200
|
||||
|
||||
|
||||
/* Various values from the R0 vertex header:
|
||||
*/
|
||||
#define R02_PRIM_END 0x1
|
||||
#define R02_PRIM_START 0x2
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,238 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* 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, sub license, 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 NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS 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.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "brw_batch.h"
|
||||
#include "brw_draw.h"
|
||||
#include "brw_defines.h"
|
||||
#include "brw_context.h"
|
||||
#include "brw_state.h"
|
||||
|
||||
#include "pipe/p_context.h"
|
||||
#include "pipe/p_winsys.h"
|
||||
|
||||
static unsigned hw_prim[PIPE_PRIM_POLYGON+1] = {
|
||||
_3DPRIM_POINTLIST,
|
||||
_3DPRIM_LINELIST,
|
||||
_3DPRIM_LINELOOP,
|
||||
_3DPRIM_LINESTRIP,
|
||||
_3DPRIM_TRILIST,
|
||||
_3DPRIM_TRISTRIP,
|
||||
_3DPRIM_TRIFAN,
|
||||
_3DPRIM_QUADLIST,
|
||||
_3DPRIM_QUADSTRIP,
|
||||
_3DPRIM_POLYGON
|
||||
};
|
||||
|
||||
|
||||
static const int reduced_prim[PIPE_PRIM_POLYGON+1] = {
|
||||
PIPE_PRIM_POINTS,
|
||||
PIPE_PRIM_LINES,
|
||||
PIPE_PRIM_LINES,
|
||||
PIPE_PRIM_LINES,
|
||||
PIPE_PRIM_TRIANGLES,
|
||||
PIPE_PRIM_TRIANGLES,
|
||||
PIPE_PRIM_TRIANGLES,
|
||||
PIPE_PRIM_TRIANGLES,
|
||||
PIPE_PRIM_TRIANGLES,
|
||||
PIPE_PRIM_TRIANGLES
|
||||
};
|
||||
|
||||
|
||||
/* When the primitive changes, set a state bit and re-validate. Not
|
||||
* the nicest and would rather deal with this by having all the
|
||||
* programs be immune to the active primitive (ie. cope with all
|
||||
* possibilities). That may not be realistic however.
|
||||
*/
|
||||
static void brw_set_prim(struct brw_context *brw, int prim)
|
||||
{
|
||||
PRINT("PRIM: %d\n", prim);
|
||||
|
||||
/* Slight optimization to avoid the GS program when not needed:
|
||||
*/
|
||||
if (prim == PIPE_PRIM_QUAD_STRIP &&
|
||||
brw->attribs.Raster->flatshade &&
|
||||
brw->attribs.Raster->fill_cw == PIPE_POLYGON_MODE_FILL &&
|
||||
brw->attribs.Raster->fill_ccw == PIPE_POLYGON_MODE_FILL)
|
||||
prim = PIPE_PRIM_TRIANGLE_STRIP;
|
||||
|
||||
if (prim != brw->primitive) {
|
||||
brw->primitive = prim;
|
||||
brw->state.dirty.brw |= BRW_NEW_PRIMITIVE;
|
||||
|
||||
if (reduced_prim[prim] != brw->reduced_primitive) {
|
||||
brw->reduced_primitive = reduced_prim[prim];
|
||||
brw->state.dirty.brw |= BRW_NEW_REDUCED_PRIMITIVE;
|
||||
}
|
||||
|
||||
brw_validate_state(brw);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
static unsigned trim(int prim, unsigned length)
|
||||
{
|
||||
if (prim == PIPE_PRIM_QUAD_STRIP)
|
||||
return length > 3 ? (length - length % 2) : 0;
|
||||
else if (prim == PIPE_PRIM_QUADS)
|
||||
return length - length % 4;
|
||||
else
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static boolean brw_emit_prim( struct brw_context *brw,
|
||||
boolean indexed,
|
||||
unsigned start,
|
||||
unsigned count )
|
||||
|
||||
{
|
||||
struct brw_3d_primitive prim_packet;
|
||||
|
||||
if (BRW_DEBUG & DEBUG_PRIMS)
|
||||
PRINT("PRIM: %d %d %d\n", brw->primitive, start, count);
|
||||
|
||||
prim_packet.header.opcode = CMD_3D_PRIM;
|
||||
prim_packet.header.length = sizeof(prim_packet)/4 - 2;
|
||||
prim_packet.header.pad = 0;
|
||||
prim_packet.header.topology = hw_prim[brw->primitive];
|
||||
prim_packet.header.indexed = indexed;
|
||||
|
||||
prim_packet.verts_per_instance = trim(brw->primitive, count);
|
||||
prim_packet.start_vert_location = start;
|
||||
prim_packet.instance_count = 1;
|
||||
prim_packet.start_instance_location = 0;
|
||||
prim_packet.base_vert_location = 0;
|
||||
|
||||
if (prim_packet.verts_per_instance == 0)
|
||||
return TRUE;
|
||||
|
||||
return brw_batchbuffer_data( brw->winsys,
|
||||
&prim_packet,
|
||||
sizeof(prim_packet) );
|
||||
}
|
||||
|
||||
|
||||
/* May fail if out of video memory for texture or vbo upload, or on
|
||||
* fallback conditions.
|
||||
*/
|
||||
static boolean brw_try_draw_elements( struct pipe_context *pipe,
|
||||
struct pipe_buffer_handle *index_buffer,
|
||||
unsigned index_size,
|
||||
unsigned mode,
|
||||
unsigned start,
|
||||
unsigned count )
|
||||
{
|
||||
struct brw_context *brw = brw_context(pipe);
|
||||
boolean retval = FALSE;
|
||||
|
||||
/* Set the first primitive ahead of validate_state:
|
||||
*/
|
||||
brw_set_prim(brw, mode);
|
||||
|
||||
/* Upload index, vertex data:
|
||||
*/
|
||||
if (!brw_upload_indices( brw, index_buffer, index_size, start, count ))
|
||||
return FALSE;
|
||||
|
||||
if (!brw_upload_vertex_elements( brw ))
|
||||
return FALSE;
|
||||
|
||||
/* XXX: Need to separate validate and upload of state.
|
||||
*/
|
||||
if (brw->state.dirty.brw)
|
||||
brw_validate_state( brw );
|
||||
|
||||
if (brw_emit_prim(brw, TRUE, start, count))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static boolean brw_draw_elements( struct pipe_context *pipe,
|
||||
struct pipe_buffer_handle *indexBuffer,
|
||||
unsigned indexSize,
|
||||
unsigned mode,
|
||||
unsigned start,
|
||||
unsigned count )
|
||||
{
|
||||
if (!brw_try_draw_elements( pipe,
|
||||
indexBuffer,
|
||||
indexSize,
|
||||
mode, start, count ))
|
||||
{
|
||||
/* flush ? */
|
||||
|
||||
if (!brw_try_draw_elements( pipe,
|
||||
indexBuffer,
|
||||
indexSize,
|
||||
mode, start,
|
||||
count )) {
|
||||
assert(0);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static boolean brw_draw_arrays( struct pipe_context *pipe,
|
||||
unsigned mode,
|
||||
unsigned start,
|
||||
unsigned count )
|
||||
{
|
||||
if (!brw_try_draw_elements( pipe, NULL, 0, mode, start, count )) {
|
||||
/* flush ? */
|
||||
|
||||
if (!brw_try_draw_elements( pipe, NULL, 0, mode, start, count )) {
|
||||
assert(0);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void brw_draw_init( struct brw_context *brw )
|
||||
{
|
||||
brw->pipe.draw_arrays = brw_draw_arrays;
|
||||
brw->pipe.draw_elements = brw_draw_elements;
|
||||
}
|
||||
|
||||
void brw_draw_destroy( struct brw_context *brw )
|
||||
{
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2005 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* 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, sub license, 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 NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS 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.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef BRW_DRAW_H
|
||||
#define BRW_DRAW_H
|
||||
|
||||
#include "pipe/p_context.h"
|
||||
|
||||
struct brw_context;
|
||||
|
||||
|
||||
|
||||
void brw_draw_init( struct brw_context *brw );
|
||||
void brw_draw_destroy( struct brw_context *brw );
|
||||
|
||||
|
||||
boolean brw_upload_vertices( struct brw_context *brw,
|
||||
unsigned min_index,
|
||||
unsigned max_index );
|
||||
|
||||
boolean brw_upload_indices(struct brw_context *brw,
|
||||
const struct pipe_buffer_handle *index_buffer,
|
||||
int ib_size, int start, int count);
|
||||
|
||||
boolean brw_upload_vertex_buffers( struct brw_context *brw );
|
||||
boolean brw_upload_vertex_elements( struct brw_context *brw );
|
||||
|
||||
unsigned brw_translate_surface_format( unsigned id );
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,306 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* 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, sub license, 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 NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS 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.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "brw_batch.h"
|
||||
#include "brw_draw.h"
|
||||
#include "brw_defines.h"
|
||||
#include "brw_context.h"
|
||||
#include "brw_state.h"
|
||||
|
||||
struct brw_array_state {
|
||||
union header_union header;
|
||||
|
||||
struct {
|
||||
union {
|
||||
struct {
|
||||
unsigned pitch:11;
|
||||
unsigned pad:15;
|
||||
unsigned access_type:1;
|
||||
unsigned vb_index:5;
|
||||
} bits;
|
||||
unsigned dword;
|
||||
} vb0;
|
||||
|
||||
struct pipe_buffer_handle *buffer;
|
||||
unsigned offset;
|
||||
|
||||
unsigned max_index;
|
||||
unsigned instance_data_step_rate;
|
||||
|
||||
} vb[BRW_VBP_MAX];
|
||||
};
|
||||
|
||||
|
||||
|
||||
unsigned brw_translate_surface_format( unsigned id )
|
||||
{
|
||||
switch (id) {
|
||||
case PIPE_FORMAT_R64_FLOAT:
|
||||
return BRW_SURFACEFORMAT_R64_FLOAT;
|
||||
case PIPE_FORMAT_R64G64_FLOAT:
|
||||
return BRW_SURFACEFORMAT_R64G64_FLOAT;
|
||||
case PIPE_FORMAT_R64G64B64_FLOAT:
|
||||
return BRW_SURFACEFORMAT_R64G64B64_FLOAT;
|
||||
case PIPE_FORMAT_R64G64B64A64_FLOAT:
|
||||
return BRW_SURFACEFORMAT_R64G64B64A64_FLOAT;
|
||||
|
||||
case PIPE_FORMAT_R32_FLOAT:
|
||||
return BRW_SURFACEFORMAT_R32_FLOAT;
|
||||
case PIPE_FORMAT_R32G32_FLOAT:
|
||||
return BRW_SURFACEFORMAT_R32G32_FLOAT;
|
||||
case PIPE_FORMAT_R32G32B32_FLOAT:
|
||||
return BRW_SURFACEFORMAT_R32G32B32_FLOAT;
|
||||
case PIPE_FORMAT_R32G32B32A32_FLOAT:
|
||||
return BRW_SURFACEFORMAT_R32G32B32A32_FLOAT;
|
||||
|
||||
case PIPE_FORMAT_R32_UNORM:
|
||||
return BRW_SURFACEFORMAT_R32_UNORM;
|
||||
case PIPE_FORMAT_R32G32_UNORM:
|
||||
return BRW_SURFACEFORMAT_R32G32_UNORM;
|
||||
case PIPE_FORMAT_R32G32B32_UNORM:
|
||||
return BRW_SURFACEFORMAT_R32G32B32_UNORM;
|
||||
case PIPE_FORMAT_R32G32B32A32_UNORM:
|
||||
return BRW_SURFACEFORMAT_R32G32B32A32_UNORM;
|
||||
|
||||
case PIPE_FORMAT_R32_USCALED:
|
||||
return BRW_SURFACEFORMAT_R32_USCALED;
|
||||
case PIPE_FORMAT_R32G32_USCALED:
|
||||
return BRW_SURFACEFORMAT_R32G32_USCALED;
|
||||
case PIPE_FORMAT_R32G32B32_USCALED:
|
||||
return BRW_SURFACEFORMAT_R32G32B32_USCALED;
|
||||
case PIPE_FORMAT_R32G32B32A32_USCALED:
|
||||
return BRW_SURFACEFORMAT_R32G32B32A32_USCALED;
|
||||
|
||||
case PIPE_FORMAT_R32_SNORM:
|
||||
return BRW_SURFACEFORMAT_R32_SNORM;
|
||||
case PIPE_FORMAT_R32G32_SNORM:
|
||||
return BRW_SURFACEFORMAT_R32G32_SNORM;
|
||||
case PIPE_FORMAT_R32G32B32_SNORM:
|
||||
return BRW_SURFACEFORMAT_R32G32B32_SNORM;
|
||||
case PIPE_FORMAT_R32G32B32A32_SNORM:
|
||||
return BRW_SURFACEFORMAT_R32G32B32A32_SNORM;
|
||||
|
||||
case PIPE_FORMAT_R32_SSCALED:
|
||||
return BRW_SURFACEFORMAT_R32_SSCALED;
|
||||
case PIPE_FORMAT_R32G32_SSCALED:
|
||||
return BRW_SURFACEFORMAT_R32G32_SSCALED;
|
||||
case PIPE_FORMAT_R32G32B32_SSCALED:
|
||||
return BRW_SURFACEFORMAT_R32G32B32_SSCALED;
|
||||
case PIPE_FORMAT_R32G32B32A32_SSCALED:
|
||||
return BRW_SURFACEFORMAT_R32G32B32A32_SSCALED;
|
||||
|
||||
case PIPE_FORMAT_R16_UNORM:
|
||||
return BRW_SURFACEFORMAT_R16_UNORM;
|
||||
case PIPE_FORMAT_R16G16_UNORM:
|
||||
return BRW_SURFACEFORMAT_R16G16_UNORM;
|
||||
case PIPE_FORMAT_R16G16B16_UNORM:
|
||||
return BRW_SURFACEFORMAT_R16G16B16_UNORM;
|
||||
case PIPE_FORMAT_R16G16B16A16_UNORM:
|
||||
return BRW_SURFACEFORMAT_R16G16B16A16_UNORM;
|
||||
|
||||
case PIPE_FORMAT_R16_USCALED:
|
||||
return BRW_SURFACEFORMAT_R16_USCALED;
|
||||
case PIPE_FORMAT_R16G16_USCALED:
|
||||
return BRW_SURFACEFORMAT_R16G16_USCALED;
|
||||
case PIPE_FORMAT_R16G16B16_USCALED:
|
||||
return BRW_SURFACEFORMAT_R16G16B16_USCALED;
|
||||
case PIPE_FORMAT_R16G16B16A16_USCALED:
|
||||
return BRW_SURFACEFORMAT_R16G16B16A16_USCALED;
|
||||
|
||||
case PIPE_FORMAT_R16_SNORM:
|
||||
return BRW_SURFACEFORMAT_R16_SNORM;
|
||||
case PIPE_FORMAT_R16G16_SNORM:
|
||||
return BRW_SURFACEFORMAT_R16G16_SNORM;
|
||||
case PIPE_FORMAT_R16G16B16_SNORM:
|
||||
return BRW_SURFACEFORMAT_R16G16B16_SNORM;
|
||||
case PIPE_FORMAT_R16G16B16A16_SNORM:
|
||||
return BRW_SURFACEFORMAT_R16G16B16A16_SNORM;
|
||||
|
||||
case PIPE_FORMAT_R16_SSCALED:
|
||||
return BRW_SURFACEFORMAT_R16_SSCALED;
|
||||
case PIPE_FORMAT_R16G16_SSCALED:
|
||||
return BRW_SURFACEFORMAT_R16G16_SSCALED;
|
||||
case PIPE_FORMAT_R16G16B16_SSCALED:
|
||||
return BRW_SURFACEFORMAT_R16G16B16_SSCALED;
|
||||
case PIPE_FORMAT_R16G16B16A16_SSCALED:
|
||||
return BRW_SURFACEFORMAT_R16G16B16A16_SSCALED;
|
||||
|
||||
case PIPE_FORMAT_R8_UNORM:
|
||||
return BRW_SURFACEFORMAT_R8_UNORM;
|
||||
case PIPE_FORMAT_R8G8_UNORM:
|
||||
return BRW_SURFACEFORMAT_R8G8_UNORM;
|
||||
case PIPE_FORMAT_R8G8B8_UNORM:
|
||||
return BRW_SURFACEFORMAT_R8G8B8_UNORM;
|
||||
case PIPE_FORMAT_R8G8B8A8_UNORM:
|
||||
return BRW_SURFACEFORMAT_R8G8B8A8_UNORM;
|
||||
|
||||
case PIPE_FORMAT_R8_USCALED:
|
||||
return BRW_SURFACEFORMAT_R8_USCALED;
|
||||
case PIPE_FORMAT_R8G8_USCALED:
|
||||
return BRW_SURFACEFORMAT_R8G8_USCALED;
|
||||
case PIPE_FORMAT_R8G8B8_USCALED:
|
||||
return BRW_SURFACEFORMAT_R8G8B8_USCALED;
|
||||
case PIPE_FORMAT_R8G8B8A8_USCALED:
|
||||
return BRW_SURFACEFORMAT_R8G8B8A8_USCALED;
|
||||
|
||||
case PIPE_FORMAT_R8_SNORM:
|
||||
return BRW_SURFACEFORMAT_R8_SNORM;
|
||||
case PIPE_FORMAT_R8G8_SNORM:
|
||||
return BRW_SURFACEFORMAT_R8G8_SNORM;
|
||||
case PIPE_FORMAT_R8G8B8_SNORM:
|
||||
return BRW_SURFACEFORMAT_R8G8B8_SNORM;
|
||||
case PIPE_FORMAT_R8G8B8A8_SNORM:
|
||||
return BRW_SURFACEFORMAT_R8G8B8A8_SNORM;
|
||||
|
||||
case PIPE_FORMAT_R8_SSCALED:
|
||||
return BRW_SURFACEFORMAT_R8_SSCALED;
|
||||
case PIPE_FORMAT_R8G8_SSCALED:
|
||||
return BRW_SURFACEFORMAT_R8G8_SSCALED;
|
||||
case PIPE_FORMAT_R8G8B8_SSCALED:
|
||||
return BRW_SURFACEFORMAT_R8G8B8_SSCALED;
|
||||
case PIPE_FORMAT_R8G8B8A8_SSCALED:
|
||||
return BRW_SURFACEFORMAT_R8G8B8A8_SSCALED;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned get_index_type(int type)
|
||||
{
|
||||
switch (type) {
|
||||
case 1: return BRW_INDEX_BYTE;
|
||||
case 2: return BRW_INDEX_WORD;
|
||||
case 4: return BRW_INDEX_DWORD;
|
||||
default: assert(0); return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
boolean brw_upload_vertex_buffers( struct brw_context *brw )
|
||||
{
|
||||
struct brw_array_state vbp;
|
||||
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++)
|
||||
{
|
||||
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.header.bits.length = (1 + nr_enabled * 4) - 2;
|
||||
vbp.header.bits.opcode = CMD_VERTEX_BUFFER;
|
||||
|
||||
BEGIN_BATCH(vbp.header.bits.length+2, 0);
|
||||
OUT_BATCH( vbp.header.dword );
|
||||
|
||||
for (i = 0; i < nr_enabled; i++) {
|
||||
OUT_BATCH( vbp.vb[i].vb0.dword );
|
||||
OUT_RELOC( vbp.vb[i].buffer, PIPE_BUFFER_FLAG_READ,
|
||||
vbp.vb[i].offset);
|
||||
OUT_BATCH( vbp.vb[i].max_index );
|
||||
OUT_BATCH( vbp.vb[i].instance_data_step_rate );
|
||||
}
|
||||
ADVANCE_BATCH();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
boolean brw_upload_vertex_elements( struct brw_context *brw )
|
||||
{
|
||||
struct brw_vertex_element_packet vep;
|
||||
|
||||
unsigned i;
|
||||
unsigned nr_enabled = brw->attribs.VertexProgram->program.num_inputs;
|
||||
|
||||
memset(&vep, 0, sizeof(vep));
|
||||
|
||||
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) {
|
||||
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;
|
||||
case 3: input->vep.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_1_FLT;
|
||||
break;
|
||||
}
|
||||
vep.ve[i] = input->vep;
|
||||
}
|
||||
|
||||
|
||||
vep.header.length = (1 + nr_enabled * sizeof(vep.ve[0])/4) - 2;
|
||||
vep.header.opcode = CMD_VERTEX_ELEMENT;
|
||||
brw_cached_batch_struct(brw, &vep, 4 + nr_enabled * sizeof(vep.ve[0]));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
boolean brw_upload_indices( struct brw_context *brw,
|
||||
const struct pipe_buffer_handle *index_buffer,
|
||||
int ib_size, int start, int count)
|
||||
{
|
||||
/* Emit the indexbuffer packet:
|
||||
*/
|
||||
{
|
||||
struct brw_indexbuffer ib;
|
||||
|
||||
memset(&ib, 0, sizeof(ib));
|
||||
|
||||
ib.header.bits.opcode = CMD_INDEX_BUFFER;
|
||||
ib.header.bits.length = sizeof(ib)/4 - 2;
|
||||
ib.header.bits.index_format = get_index_type(ib_size);
|
||||
ib.header.bits.cut_index_enable = 0;
|
||||
|
||||
|
||||
BEGIN_BATCH(4, 0);
|
||||
OUT_BATCH( ib.header.dword );
|
||||
OUT_RELOC( index_buffer, PIPE_BUFFER_FLAG_READ, start);
|
||||
OUT_RELOC( index_buffer, PIPE_BUFFER_FLAG_READ, start + count);
|
||||
OUT_BATCH( 0 );
|
||||
ADVANCE_BATCH();
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
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_eu.h"
|
||||
|
||||
|
||||
|
||||
/* How does predicate control work when execution_size != 8? Do I
|
||||
* need to test/set for 0xffff when execution_size is 16?
|
||||
*/
|
||||
void brw_set_predicate_control_flag_value( struct brw_compile *p, unsigned value )
|
||||
{
|
||||
p->current->header.predicate_control = BRW_PREDICATE_NONE;
|
||||
|
||||
if (value != 0xff) {
|
||||
if (value != p->flag_value) {
|
||||
brw_push_insn_state(p);
|
||||
brw_MOV(p, brw_flag_reg(), brw_imm_uw(value));
|
||||
p->flag_value = value;
|
||||
brw_pop_insn_state(p);
|
||||
}
|
||||
|
||||
p->current->header.predicate_control = BRW_PREDICATE_NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
void brw_set_predicate_control( struct brw_compile *p, unsigned pc )
|
||||
{
|
||||
p->current->header.predicate_control = pc;
|
||||
}
|
||||
|
||||
void brw_set_conditionalmod( struct brw_compile *p, unsigned conditional )
|
||||
{
|
||||
p->current->header.destreg__conditonalmod = conditional;
|
||||
}
|
||||
|
||||
void brw_set_access_mode( struct brw_compile *p, unsigned access_mode )
|
||||
{
|
||||
p->current->header.access_mode = access_mode;
|
||||
}
|
||||
|
||||
void brw_set_compression_control( struct brw_compile *p, boolean compression_control )
|
||||
{
|
||||
p->current->header.compression_control = compression_control;
|
||||
}
|
||||
|
||||
void brw_set_mask_control( struct brw_compile *p, unsigned value )
|
||||
{
|
||||
p->current->header.mask_control = value;
|
||||
}
|
||||
|
||||
void brw_set_saturate( struct brw_compile *p, unsigned value )
|
||||
{
|
||||
p->current->header.saturate = value;
|
||||
}
|
||||
|
||||
void brw_push_insn_state( struct brw_compile *p )
|
||||
{
|
||||
assert(p->current != &p->stack[BRW_EU_MAX_INSN_STACK-1]);
|
||||
memcpy(p->current+1, p->current, sizeof(struct brw_instruction));
|
||||
p->current++;
|
||||
}
|
||||
|
||||
void brw_pop_insn_state( struct brw_compile *p )
|
||||
{
|
||||
assert(p->current != p->stack);
|
||||
p->current--;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
*/
|
||||
void brw_init_compile( struct brw_compile *p )
|
||||
{
|
||||
p->nr_insn = 0;
|
||||
p->current = p->stack;
|
||||
memset(p->current, 0, sizeof(p->current[0]));
|
||||
|
||||
/* Some defaults?
|
||||
*/
|
||||
brw_set_mask_control(p, BRW_MASK_ENABLE); /* what does this do? */
|
||||
brw_set_saturate(p, 0);
|
||||
brw_set_compression_control(p, BRW_COMPRESSION_NONE);
|
||||
brw_set_predicate_control_flag_value(p, 0xff);
|
||||
}
|
||||
|
||||
|
||||
const unsigned *brw_get_program( struct brw_compile *p,
|
||||
unsigned *sz )
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
brw_NOP(p);
|
||||
|
||||
*sz = p->nr_insn * sizeof(struct brw_instruction);
|
||||
return (const unsigned *)p->store;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,877 @@
|
||||
/*
|
||||
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>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef BRW_EU_H
|
||||
#define BRW_EU_H
|
||||
|
||||
#include "brw_structs.h"
|
||||
#include "brw_defines.h"
|
||||
|
||||
#include "pipe/p_compiler.h"
|
||||
#include "pipe/p_shader_tokens.h"
|
||||
|
||||
#define BRW_SWIZZLE4(a,b,c,d) (((a)<<0) | ((b)<<2) | ((c)<<4) | ((d)<<6))
|
||||
#define BRW_GET_SWZ(swz, idx) (((swz) >> ((idx)*2)) & 0x3)
|
||||
|
||||
#define BRW_SWIZZLE_NOOP BRW_SWIZZLE4(0,1,2,3)
|
||||
#define BRW_SWIZZLE_XYZW BRW_SWIZZLE4(0,1,2,3)
|
||||
#define BRW_SWIZZLE_XXXX BRW_SWIZZLE4(0,0,0,0)
|
||||
#define BRW_SWIZZLE_XYXY BRW_SWIZZLE4(0,1,0,1)
|
||||
|
||||
|
||||
#define REG_SIZE (8*4)
|
||||
|
||||
|
||||
/* These aren't hardware structs, just something useful for us to pass around:
|
||||
*
|
||||
* Align1 operation has a lot of control over input ranges. Used in
|
||||
* WM programs to implement shaders decomposed into "channel serial"
|
||||
* or "structure of array" form:
|
||||
*/
|
||||
struct brw_reg
|
||||
{
|
||||
unsigned type:4;
|
||||
unsigned file:2;
|
||||
unsigned nr:8;
|
||||
unsigned subnr:5; /* :1 in align16 */
|
||||
unsigned negate:1; /* source only */
|
||||
unsigned abs:1; /* source only */
|
||||
unsigned vstride:4; /* source only */
|
||||
unsigned width:3; /* src only, align1 only */
|
||||
unsigned hstride:2; /* src only, align1 only */
|
||||
unsigned address_mode:1; /* relative addressing, hopefully! */
|
||||
unsigned pad0:1;
|
||||
|
||||
union {
|
||||
struct {
|
||||
unsigned swizzle:8; /* src only, align16 only */
|
||||
unsigned writemask:4; /* dest only, align16 only */
|
||||
int indirect_offset:10; /* relative addressing offset */
|
||||
unsigned pad1:10; /* two dwords total */
|
||||
} bits;
|
||||
|
||||
float f;
|
||||
int d;
|
||||
unsigned ud;
|
||||
} dw1;
|
||||
};
|
||||
|
||||
|
||||
struct brw_indirect {
|
||||
unsigned addr_subnr:4;
|
||||
int addr_offset:10;
|
||||
unsigned pad:18;
|
||||
};
|
||||
|
||||
|
||||
#define BRW_EU_MAX_INSN_STACK 5
|
||||
#define BRW_EU_MAX_INSN 1200
|
||||
|
||||
struct brw_compile {
|
||||
struct brw_instruction store[BRW_EU_MAX_INSN];
|
||||
unsigned nr_insn;
|
||||
|
||||
/* Allow clients to push/pop instruction state:
|
||||
*/
|
||||
struct brw_instruction stack[BRW_EU_MAX_INSN_STACK];
|
||||
struct brw_instruction *current;
|
||||
|
||||
unsigned flag_value;
|
||||
boolean single_program_flow;
|
||||
};
|
||||
|
||||
|
||||
|
||||
static __inline int type_sz( unsigned type )
|
||||
{
|
||||
switch( type ) {
|
||||
case BRW_REGISTER_TYPE_UD:
|
||||
case BRW_REGISTER_TYPE_D:
|
||||
case BRW_REGISTER_TYPE_F:
|
||||
return 4;
|
||||
case BRW_REGISTER_TYPE_HF:
|
||||
case BRW_REGISTER_TYPE_UW:
|
||||
case BRW_REGISTER_TYPE_W:
|
||||
return 2;
|
||||
case BRW_REGISTER_TYPE_UB:
|
||||
case BRW_REGISTER_TYPE_B:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static __inline struct brw_reg brw_reg( unsigned file,
|
||||
unsigned nr,
|
||||
unsigned subnr,
|
||||
unsigned type,
|
||||
unsigned vstride,
|
||||
unsigned width,
|
||||
unsigned hstride,
|
||||
unsigned swizzle,
|
||||
unsigned writemask)
|
||||
{
|
||||
|
||||
struct brw_reg reg;
|
||||
reg.type = type;
|
||||
reg.file = file;
|
||||
reg.nr = nr;
|
||||
reg.subnr = subnr * type_sz(type);
|
||||
reg.negate = 0;
|
||||
reg.abs = 0;
|
||||
reg.vstride = vstride;
|
||||
reg.width = width;
|
||||
reg.hstride = hstride;
|
||||
reg.address_mode = BRW_ADDRESS_DIRECT;
|
||||
reg.pad0 = 0;
|
||||
|
||||
/* Could do better: If the reg is r5.3<0;1,0>, we probably want to
|
||||
* set swizzle and writemask to W, as the lower bits of subnr will
|
||||
* be lost when converted to align16. This is probably too much to
|
||||
* keep track of as you'd want it adjusted by suboffset(), etc.
|
||||
* Perhaps fix up when converting to align16?
|
||||
*/
|
||||
reg.dw1.bits.swizzle = swizzle;
|
||||
reg.dw1.bits.writemask = writemask;
|
||||
reg.dw1.bits.indirect_offset = 0;
|
||||
reg.dw1.bits.pad1 = 0;
|
||||
return reg;
|
||||
}
|
||||
|
||||
static __inline struct brw_reg brw_vec16_reg( unsigned file,
|
||||
unsigned nr,
|
||||
unsigned subnr )
|
||||
{
|
||||
return brw_reg(file,
|
||||
nr,
|
||||
subnr,
|
||||
BRW_REGISTER_TYPE_F,
|
||||
BRW_VERTICAL_STRIDE_16,
|
||||
BRW_WIDTH_16,
|
||||
BRW_HORIZONTAL_STRIDE_1,
|
||||
BRW_SWIZZLE_XYZW,
|
||||
TGSI_WRITEMASK_XYZW);
|
||||
}
|
||||
|
||||
static __inline struct brw_reg brw_vec8_reg( unsigned file,
|
||||
unsigned nr,
|
||||
unsigned subnr )
|
||||
{
|
||||
return brw_reg(file,
|
||||
nr,
|
||||
subnr,
|
||||
BRW_REGISTER_TYPE_F,
|
||||
BRW_VERTICAL_STRIDE_8,
|
||||
BRW_WIDTH_8,
|
||||
BRW_HORIZONTAL_STRIDE_1,
|
||||
BRW_SWIZZLE_XYZW,
|
||||
TGSI_WRITEMASK_XYZW);
|
||||
}
|
||||
|
||||
|
||||
static __inline struct brw_reg brw_vec4_reg( unsigned file,
|
||||
unsigned nr,
|
||||
unsigned subnr )
|
||||
{
|
||||
return brw_reg(file,
|
||||
nr,
|
||||
subnr,
|
||||
BRW_REGISTER_TYPE_F,
|
||||
BRW_VERTICAL_STRIDE_4,
|
||||
BRW_WIDTH_4,
|
||||
BRW_HORIZONTAL_STRIDE_1,
|
||||
BRW_SWIZZLE_XYZW,
|
||||
TGSI_WRITEMASK_XYZW);
|
||||
}
|
||||
|
||||
|
||||
static __inline struct brw_reg brw_vec2_reg( unsigned file,
|
||||
unsigned nr,
|
||||
unsigned subnr )
|
||||
{
|
||||
return brw_reg(file,
|
||||
nr,
|
||||
subnr,
|
||||
BRW_REGISTER_TYPE_F,
|
||||
BRW_VERTICAL_STRIDE_2,
|
||||
BRW_WIDTH_2,
|
||||
BRW_HORIZONTAL_STRIDE_1,
|
||||
BRW_SWIZZLE_XYXY,
|
||||
TGSI_WRITEMASK_XY);
|
||||
}
|
||||
|
||||
static __inline struct brw_reg brw_vec1_reg( unsigned file,
|
||||
unsigned nr,
|
||||
unsigned subnr )
|
||||
{
|
||||
return brw_reg(file,
|
||||
nr,
|
||||
subnr,
|
||||
BRW_REGISTER_TYPE_F,
|
||||
BRW_VERTICAL_STRIDE_0,
|
||||
BRW_WIDTH_1,
|
||||
BRW_HORIZONTAL_STRIDE_0,
|
||||
BRW_SWIZZLE_XXXX,
|
||||
TGSI_WRITEMASK_X);
|
||||
}
|
||||
|
||||
|
||||
static __inline struct brw_reg retype( struct brw_reg reg,
|
||||
unsigned type )
|
||||
{
|
||||
reg.type = type;
|
||||
return reg;
|
||||
}
|
||||
|
||||
static __inline struct brw_reg suboffset( struct brw_reg reg,
|
||||
unsigned delta )
|
||||
{
|
||||
reg.subnr += delta * type_sz(reg.type);
|
||||
return reg;
|
||||
}
|
||||
|
||||
|
||||
static __inline struct brw_reg offset( struct brw_reg reg,
|
||||
unsigned delta )
|
||||
{
|
||||
reg.nr += delta;
|
||||
return reg;
|
||||
}
|
||||
|
||||
|
||||
static __inline struct brw_reg byte_offset( struct brw_reg reg,
|
||||
unsigned bytes )
|
||||
{
|
||||
unsigned newoffset = reg.nr * REG_SIZE + reg.subnr + bytes;
|
||||
reg.nr = newoffset / REG_SIZE;
|
||||
reg.subnr = newoffset % REG_SIZE;
|
||||
return reg;
|
||||
}
|
||||
|
||||
|
||||
static __inline struct brw_reg brw_uw16_reg( unsigned file,
|
||||
unsigned nr,
|
||||
unsigned subnr )
|
||||
{
|
||||
return suboffset(retype(brw_vec16_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
|
||||
}
|
||||
|
||||
static __inline struct brw_reg brw_uw8_reg( unsigned file,
|
||||
unsigned nr,
|
||||
unsigned subnr )
|
||||
{
|
||||
return suboffset(retype(brw_vec8_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
|
||||
}
|
||||
|
||||
static __inline struct brw_reg brw_uw1_reg( unsigned file,
|
||||
unsigned nr,
|
||||
unsigned subnr )
|
||||
{
|
||||
return suboffset(retype(brw_vec1_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
|
||||
}
|
||||
|
||||
static __inline struct brw_reg brw_imm_reg( unsigned type )
|
||||
{
|
||||
return brw_reg( BRW_IMMEDIATE_VALUE,
|
||||
0,
|
||||
0,
|
||||
type,
|
||||
BRW_VERTICAL_STRIDE_0,
|
||||
BRW_WIDTH_1,
|
||||
BRW_HORIZONTAL_STRIDE_0,
|
||||
0,
|
||||
0);
|
||||
}
|
||||
|
||||
static __inline struct brw_reg brw_imm_f( float f )
|
||||
{
|
||||
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_F);
|
||||
imm.dw1.f = f;
|
||||
return imm;
|
||||
}
|
||||
|
||||
static __inline struct brw_reg brw_imm_d( int d )
|
||||
{
|
||||
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_D);
|
||||
imm.dw1.d = d;
|
||||
return imm;
|
||||
}
|
||||
|
||||
static __inline struct brw_reg brw_imm_ud( unsigned ud )
|
||||
{
|
||||
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UD);
|
||||
imm.dw1.ud = ud;
|
||||
return imm;
|
||||
}
|
||||
|
||||
static __inline struct brw_reg brw_imm_uw( ushort uw )
|
||||
{
|
||||
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UW);
|
||||
imm.dw1.ud = uw;
|
||||
return imm;
|
||||
}
|
||||
|
||||
static __inline struct brw_reg brw_imm_w( short w )
|
||||
{
|
||||
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_W);
|
||||
imm.dw1.d = w;
|
||||
return imm;
|
||||
}
|
||||
|
||||
/* brw_imm_b and brw_imm_ub aren't supported by hardware - the type
|
||||
* numbers alias with _V and _VF below:
|
||||
*/
|
||||
|
||||
/* Vector of eight signed half-byte values:
|
||||
*/
|
||||
static __inline struct brw_reg brw_imm_v( unsigned v )
|
||||
{
|
||||
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_V);
|
||||
imm.vstride = BRW_VERTICAL_STRIDE_0;
|
||||
imm.width = BRW_WIDTH_8;
|
||||
imm.hstride = BRW_HORIZONTAL_STRIDE_1;
|
||||
imm.dw1.ud = v;
|
||||
return imm;
|
||||
}
|
||||
|
||||
/* Vector of four 8-bit float values:
|
||||
*/
|
||||
static __inline struct brw_reg brw_imm_vf( unsigned v )
|
||||
{
|
||||
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
|
||||
imm.vstride = BRW_VERTICAL_STRIDE_0;
|
||||
imm.width = BRW_WIDTH_4;
|
||||
imm.hstride = BRW_HORIZONTAL_STRIDE_1;
|
||||
imm.dw1.ud = v;
|
||||
return imm;
|
||||
}
|
||||
|
||||
#define VF_ZERO 0x0
|
||||
#define VF_ONE 0x30
|
||||
#define VF_NEG (1<<7)
|
||||
|
||||
static __inline struct brw_reg brw_imm_vf4( unsigned v0,
|
||||
unsigned v1,
|
||||
unsigned v2,
|
||||
unsigned v3)
|
||||
{
|
||||
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
|
||||
imm.vstride = BRW_VERTICAL_STRIDE_0;
|
||||
imm.width = BRW_WIDTH_4;
|
||||
imm.hstride = BRW_HORIZONTAL_STRIDE_1;
|
||||
imm.dw1.ud = ((v0 << 0) |
|
||||
(v1 << 8) |
|
||||
(v2 << 16) |
|
||||
(v3 << 24));
|
||||
return imm;
|
||||
}
|
||||
|
||||
|
||||
static __inline struct brw_reg brw_address( struct brw_reg reg )
|
||||
{
|
||||
return brw_imm_uw(reg.nr * REG_SIZE + reg.subnr);
|
||||
}
|
||||
|
||||
|
||||
static __inline struct brw_reg brw_vec1_grf( unsigned nr,
|
||||
unsigned subnr )
|
||||
{
|
||||
return brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
|
||||
}
|
||||
|
||||
static __inline struct brw_reg brw_vec8_grf( unsigned nr,
|
||||
unsigned subnr )
|
||||
{
|
||||
return brw_vec8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
|
||||
}
|
||||
|
||||
static __inline struct brw_reg brw_vec4_grf( unsigned nr,
|
||||
unsigned subnr )
|
||||
{
|
||||
return brw_vec4_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
|
||||
}
|
||||
|
||||
|
||||
static __inline struct brw_reg brw_vec2_grf( unsigned nr,
|
||||
unsigned subnr )
|
||||
{
|
||||
return brw_vec2_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
|
||||
}
|
||||
|
||||
static __inline struct brw_reg brw_uw8_grf( unsigned nr,
|
||||
unsigned subnr )
|
||||
{
|
||||
return brw_uw8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
|
||||
}
|
||||
|
||||
static __inline struct brw_reg brw_null_reg( void )
|
||||
{
|
||||
return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE,
|
||||
BRW_ARF_NULL,
|
||||
0);
|
||||
}
|
||||
|
||||
static __inline struct brw_reg brw_address_reg( unsigned subnr )
|
||||
{
|
||||
return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
|
||||
BRW_ARF_ADDRESS,
|
||||
subnr);
|
||||
}
|
||||
|
||||
/* If/else instructions break in align16 mode if writemask & swizzle
|
||||
* aren't xyzw. This goes against the convention for other scalar
|
||||
* regs:
|
||||
*/
|
||||
static __inline struct brw_reg brw_ip_reg( void )
|
||||
{
|
||||
return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
|
||||
BRW_ARF_IP,
|
||||
0,
|
||||
BRW_REGISTER_TYPE_UD,
|
||||
BRW_VERTICAL_STRIDE_4, /* ? */
|
||||
BRW_WIDTH_1,
|
||||
BRW_HORIZONTAL_STRIDE_0,
|
||||
BRW_SWIZZLE_XYZW, /* NOTE! */
|
||||
TGSI_WRITEMASK_XYZW); /* NOTE! */
|
||||
}
|
||||
|
||||
static __inline struct brw_reg brw_acc_reg( void )
|
||||
{
|
||||
return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE,
|
||||
BRW_ARF_ACCUMULATOR,
|
||||
0);
|
||||
}
|
||||
|
||||
|
||||
static __inline struct brw_reg brw_flag_reg( void )
|
||||
{
|
||||
return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
|
||||
BRW_ARF_FLAG,
|
||||
0);
|
||||
}
|
||||
|
||||
|
||||
static __inline struct brw_reg brw_mask_reg( unsigned subnr )
|
||||
{
|
||||
return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
|
||||
BRW_ARF_MASK,
|
||||
subnr);
|
||||
}
|
||||
|
||||
static __inline struct brw_reg brw_message_reg( unsigned nr )
|
||||
{
|
||||
return brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE,
|
||||
nr,
|
||||
0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* This is almost always called with a numeric constant argument, so
|
||||
* make things easy to evaluate at compile time:
|
||||
*/
|
||||
static __inline unsigned cvt( unsigned val )
|
||||
{
|
||||
switch (val) {
|
||||
case 0: return 0;
|
||||
case 1: return 1;
|
||||
case 2: return 2;
|
||||
case 4: return 3;
|
||||
case 8: return 4;
|
||||
case 16: return 5;
|
||||
case 32: return 6;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __inline struct brw_reg stride( struct brw_reg reg,
|
||||
unsigned vstride,
|
||||
unsigned width,
|
||||
unsigned hstride )
|
||||
{
|
||||
|
||||
reg.vstride = cvt(vstride);
|
||||
reg.width = cvt(width) - 1;
|
||||
reg.hstride = cvt(hstride);
|
||||
return reg;
|
||||
}
|
||||
|
||||
static __inline struct brw_reg vec16( struct brw_reg reg )
|
||||
{
|
||||
return stride(reg, 16,16,1);
|
||||
}
|
||||
|
||||
static __inline struct brw_reg vec8( struct brw_reg reg )
|
||||
{
|
||||
return stride(reg, 8,8,1);
|
||||
}
|
||||
|
||||
static __inline struct brw_reg vec4( struct brw_reg reg )
|
||||
{
|
||||
return stride(reg, 4,4,1);
|
||||
}
|
||||
|
||||
static __inline struct brw_reg vec2( struct brw_reg reg )
|
||||
{
|
||||
return stride(reg, 2,2,1);
|
||||
}
|
||||
|
||||
static __inline struct brw_reg vec1( struct brw_reg reg )
|
||||
{
|
||||
return stride(reg, 0,1,0);
|
||||
}
|
||||
|
||||
static __inline struct brw_reg get_element( struct brw_reg reg, unsigned elt )
|
||||
{
|
||||
return vec1(suboffset(reg, elt));
|
||||
}
|
||||
|
||||
static __inline struct brw_reg get_element_ud( struct brw_reg reg, unsigned elt )
|
||||
{
|
||||
return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_UD), elt));
|
||||
}
|
||||
|
||||
|
||||
static __inline struct brw_reg brw_swizzle( struct brw_reg reg,
|
||||
unsigned x,
|
||||
unsigned y,
|
||||
unsigned z,
|
||||
unsigned w)
|
||||
{
|
||||
reg.dw1.bits.swizzle = BRW_SWIZZLE4(BRW_GET_SWZ(reg.dw1.bits.swizzle, x),
|
||||
BRW_GET_SWZ(reg.dw1.bits.swizzle, y),
|
||||
BRW_GET_SWZ(reg.dw1.bits.swizzle, z),
|
||||
BRW_GET_SWZ(reg.dw1.bits.swizzle, w));
|
||||
return reg;
|
||||
}
|
||||
|
||||
|
||||
static __inline struct brw_reg brw_swizzle1( struct brw_reg reg,
|
||||
unsigned x )
|
||||
{
|
||||
return brw_swizzle(reg, x, x, x, x);
|
||||
}
|
||||
|
||||
static __inline struct brw_reg brw_writemask( struct brw_reg reg,
|
||||
unsigned mask )
|
||||
{
|
||||
reg.dw1.bits.writemask &= mask;
|
||||
return reg;
|
||||
}
|
||||
|
||||
static __inline struct brw_reg brw_set_writemask( struct brw_reg reg,
|
||||
unsigned mask )
|
||||
{
|
||||
reg.dw1.bits.writemask = mask;
|
||||
return reg;
|
||||
}
|
||||
|
||||
static __inline struct brw_reg negate( struct brw_reg reg )
|
||||
{
|
||||
reg.negate ^= 1;
|
||||
return reg;
|
||||
}
|
||||
|
||||
static __inline struct brw_reg brw_abs( struct brw_reg reg )
|
||||
{
|
||||
reg.abs = 1;
|
||||
return reg;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
*/
|
||||
static __inline struct brw_reg brw_vec4_indirect( unsigned subnr,
|
||||
int offset )
|
||||
{
|
||||
struct brw_reg reg = brw_vec4_grf(0, 0);
|
||||
reg.subnr = subnr;
|
||||
reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
|
||||
reg.dw1.bits.indirect_offset = offset;
|
||||
return reg;
|
||||
}
|
||||
|
||||
static __inline struct brw_reg brw_vec1_indirect( unsigned subnr,
|
||||
int offset )
|
||||
{
|
||||
struct brw_reg reg = brw_vec1_grf(0, 0);
|
||||
reg.subnr = subnr;
|
||||
reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
|
||||
reg.dw1.bits.indirect_offset = offset;
|
||||
return reg;
|
||||
}
|
||||
|
||||
static __inline struct brw_reg deref_4f(struct brw_indirect ptr, int offset)
|
||||
{
|
||||
return brw_vec4_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
|
||||
}
|
||||
|
||||
static __inline struct brw_reg deref_1f(struct brw_indirect ptr, int offset)
|
||||
{
|
||||
return brw_vec1_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
|
||||
}
|
||||
|
||||
static __inline struct brw_reg deref_4b(struct brw_indirect ptr, int offset)
|
||||
{
|
||||
return retype(deref_4f(ptr, offset), BRW_REGISTER_TYPE_B);
|
||||
}
|
||||
|
||||
static __inline struct brw_reg deref_1uw(struct brw_indirect ptr, int offset)
|
||||
{
|
||||
return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UW);
|
||||
}
|
||||
|
||||
static __inline struct brw_reg deref_1ud(struct brw_indirect ptr, int offset)
|
||||
{
|
||||
return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UD);
|
||||
}
|
||||
|
||||
static __inline struct brw_reg get_addr_reg(struct brw_indirect ptr)
|
||||
{
|
||||
return brw_address_reg(ptr.addr_subnr);
|
||||
}
|
||||
|
||||
static __inline struct brw_indirect brw_indirect_offset( struct brw_indirect ptr, int offset )
|
||||
{
|
||||
ptr.addr_offset += offset;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static __inline struct brw_indirect brw_indirect( unsigned addr_subnr, int offset )
|
||||
{
|
||||
struct brw_indirect ptr;
|
||||
ptr.addr_subnr = addr_subnr;
|
||||
ptr.addr_offset = offset;
|
||||
ptr.pad = 0;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static __inline struct brw_instruction *current_insn( struct brw_compile *p)
|
||||
{
|
||||
return &p->store[p->nr_insn];
|
||||
}
|
||||
|
||||
void brw_pop_insn_state( struct brw_compile *p );
|
||||
void brw_push_insn_state( struct brw_compile *p );
|
||||
void brw_set_mask_control( struct brw_compile *p, unsigned value );
|
||||
void brw_set_saturate( struct brw_compile *p, unsigned value );
|
||||
void brw_set_access_mode( struct brw_compile *p, unsigned access_mode );
|
||||
void brw_set_compression_control( struct brw_compile *p, boolean control );
|
||||
void brw_set_predicate_control_flag_value( struct brw_compile *p, unsigned value );
|
||||
void brw_set_predicate_control( struct brw_compile *p, unsigned pc );
|
||||
void brw_set_conditionalmod( struct brw_compile *p, unsigned conditional );
|
||||
|
||||
void brw_init_compile( struct brw_compile *p );
|
||||
const unsigned *brw_get_program( struct brw_compile *p, unsigned *sz );
|
||||
|
||||
|
||||
/* Helpers for regular instructions:
|
||||
*/
|
||||
#define ALU1(OP) \
|
||||
struct brw_instruction *brw_##OP(struct brw_compile *p, \
|
||||
struct brw_reg dest, \
|
||||
struct brw_reg src0);
|
||||
|
||||
#define ALU2(OP) \
|
||||
struct brw_instruction *brw_##OP(struct brw_compile *p, \
|
||||
struct brw_reg dest, \
|
||||
struct brw_reg src0, \
|
||||
struct brw_reg src1);
|
||||
|
||||
ALU1(MOV)
|
||||
ALU2(SEL)
|
||||
ALU1(NOT)
|
||||
ALU2(AND)
|
||||
ALU2(OR)
|
||||
ALU2(XOR)
|
||||
ALU2(SHR)
|
||||
ALU2(SHL)
|
||||
ALU2(RSR)
|
||||
ALU2(RSL)
|
||||
ALU2(ASR)
|
||||
ALU2(JMPI)
|
||||
ALU2(ADD)
|
||||
ALU2(MUL)
|
||||
ALU1(FRC)
|
||||
ALU1(RNDD)
|
||||
ALU2(MAC)
|
||||
ALU2(MACH)
|
||||
ALU1(LZD)
|
||||
ALU2(DP4)
|
||||
ALU2(DPH)
|
||||
ALU2(DP3)
|
||||
ALU2(DP2)
|
||||
ALU2(LINE)
|
||||
|
||||
#undef ALU1
|
||||
#undef ALU2
|
||||
|
||||
|
||||
|
||||
/* Helpers for SEND instruction:
|
||||
*/
|
||||
void brw_urb_WRITE(struct brw_compile *p,
|
||||
struct brw_reg dest,
|
||||
unsigned msg_reg_nr,
|
||||
struct brw_reg src0,
|
||||
boolean allocate,
|
||||
boolean used,
|
||||
unsigned msg_length,
|
||||
unsigned response_length,
|
||||
boolean eot,
|
||||
boolean writes_complete,
|
||||
unsigned offset,
|
||||
unsigned swizzle);
|
||||
|
||||
void brw_fb_WRITE(struct brw_compile *p,
|
||||
struct brw_reg dest,
|
||||
unsigned msg_reg_nr,
|
||||
struct brw_reg src0,
|
||||
unsigned binding_table_index,
|
||||
unsigned msg_length,
|
||||
unsigned response_length,
|
||||
boolean eot);
|
||||
|
||||
void brw_SAMPLE(struct brw_compile *p,
|
||||
struct brw_reg dest,
|
||||
unsigned msg_reg_nr,
|
||||
struct brw_reg src0,
|
||||
unsigned binding_table_index,
|
||||
unsigned sampler,
|
||||
unsigned writemask,
|
||||
unsigned msg_type,
|
||||
unsigned response_length,
|
||||
unsigned msg_length,
|
||||
boolean eot);
|
||||
|
||||
void brw_math_16( struct brw_compile *p,
|
||||
struct brw_reg dest,
|
||||
unsigned function,
|
||||
unsigned saturate,
|
||||
unsigned msg_reg_nr,
|
||||
struct brw_reg src,
|
||||
unsigned precision );
|
||||
|
||||
void brw_math( struct brw_compile *p,
|
||||
struct brw_reg dest,
|
||||
unsigned function,
|
||||
unsigned saturate,
|
||||
unsigned msg_reg_nr,
|
||||
struct brw_reg src,
|
||||
unsigned data_type,
|
||||
unsigned precision );
|
||||
|
||||
void brw_dp_READ_16( struct brw_compile *p,
|
||||
struct brw_reg dest,
|
||||
unsigned msg_reg_nr,
|
||||
unsigned scratch_offset );
|
||||
|
||||
void brw_dp_WRITE_16( struct brw_compile *p,
|
||||
struct brw_reg src,
|
||||
unsigned msg_reg_nr,
|
||||
unsigned scratch_offset );
|
||||
|
||||
/* If/else/endif. Works by manipulating the execution flags on each
|
||||
* channel.
|
||||
*/
|
||||
struct brw_instruction *brw_IF(struct brw_compile *p,
|
||||
unsigned execute_size);
|
||||
|
||||
struct brw_instruction *brw_ELSE(struct brw_compile *p,
|
||||
struct brw_instruction *if_insn);
|
||||
|
||||
void brw_ENDIF(struct brw_compile *p,
|
||||
struct brw_instruction *if_or_else_insn);
|
||||
|
||||
|
||||
/* DO/WHILE loops:
|
||||
*/
|
||||
struct brw_instruction *brw_DO(struct brw_compile *p,
|
||||
unsigned execute_size);
|
||||
|
||||
struct brw_instruction *brw_WHILE(struct brw_compile *p,
|
||||
struct brw_instruction *patch_insn);
|
||||
|
||||
struct brw_instruction *brw_BREAK(struct brw_compile *p);
|
||||
struct brw_instruction *brw_CONT(struct brw_compile *p);
|
||||
/* Forward jumps:
|
||||
*/
|
||||
void brw_land_fwd_jump(struct brw_compile *p,
|
||||
struct brw_instruction *jmp_insn);
|
||||
|
||||
|
||||
|
||||
void brw_NOP(struct brw_compile *p);
|
||||
|
||||
/* Special case: there is never a destination, execution size will be
|
||||
* taken from src0:
|
||||
*/
|
||||
void brw_CMP(struct brw_compile *p,
|
||||
struct brw_reg dest,
|
||||
unsigned conditional,
|
||||
struct brw_reg src0,
|
||||
struct brw_reg src1);
|
||||
|
||||
void brw_print_reg( struct brw_reg reg );
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* brw_eu_util.c:
|
||||
*/
|
||||
|
||||
void brw_copy_indirect_to_indirect(struct brw_compile *p,
|
||||
struct brw_indirect dst_ptr,
|
||||
struct brw_indirect src_ptr,
|
||||
unsigned count);
|
||||
|
||||
void brw_copy_from_indirect(struct brw_compile *p,
|
||||
struct brw_reg dst,
|
||||
struct brw_indirect ptr,
|
||||
unsigned count);
|
||||
|
||||
void brw_copy4(struct brw_compile *p,
|
||||
struct brw_reg dst,
|
||||
struct brw_reg src,
|
||||
unsigned count);
|
||||
|
||||
void brw_copy8(struct brw_compile *p,
|
||||
struct brw_reg dst,
|
||||
struct brw_reg src,
|
||||
unsigned count);
|
||||
|
||||
void brw_math_invert( struct brw_compile *p,
|
||||
struct brw_reg dst,
|
||||
struct brw_reg src);
|
||||
|
||||
void brw_set_src1( struct brw_instruction *insn,
|
||||
struct brw_reg reg );
|
||||
#endif
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
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_eu.h"
|
||||
|
||||
void brw_print_reg( struct brw_reg hwreg )
|
||||
{
|
||||
static const char *file[] = {
|
||||
"arf",
|
||||
"grf",
|
||||
"msg",
|
||||
"imm"
|
||||
};
|
||||
|
||||
static const char *type[] = {
|
||||
"ud",
|
||||
"d",
|
||||
"uw",
|
||||
"w",
|
||||
"ub",
|
||||
"vf",
|
||||
"hf",
|
||||
"f"
|
||||
};
|
||||
|
||||
_mesa_printf("%s%s",
|
||||
hwreg.abs ? "abs/" : "",
|
||||
hwreg.negate ? "-" : "");
|
||||
|
||||
if (hwreg.file == BRW_GENERAL_REGISTER_FILE &&
|
||||
hwreg.nr % 2 == 0 &&
|
||||
hwreg.subnr == 0 &&
|
||||
hwreg.vstride == BRW_VERTICAL_STRIDE_8 &&
|
||||
hwreg.width == BRW_WIDTH_8 &&
|
||||
hwreg.hstride == BRW_HORIZONTAL_STRIDE_1 &&
|
||||
hwreg.type == BRW_REGISTER_TYPE_F) {
|
||||
_mesa_printf("vec%d", hwreg.nr);
|
||||
}
|
||||
else if (hwreg.file == BRW_GENERAL_REGISTER_FILE &&
|
||||
hwreg.vstride == BRW_VERTICAL_STRIDE_0 &&
|
||||
hwreg.width == BRW_WIDTH_1 &&
|
||||
hwreg.hstride == BRW_HORIZONTAL_STRIDE_0 &&
|
||||
hwreg.type == BRW_REGISTER_TYPE_F) {
|
||||
_mesa_printf("scl%d.%d", hwreg.nr, hwreg.subnr / 4);
|
||||
}
|
||||
else {
|
||||
_mesa_printf("%s%d.%d<%d;%d,%d>:%s",
|
||||
file[hwreg.file],
|
||||
hwreg.nr,
|
||||
hwreg.subnr / type_sz(hwreg.type),
|
||||
hwreg.vstride ? (1<<(hwreg.vstride-1)) : 0,
|
||||
1<<hwreg.width,
|
||||
hwreg.hstride ? (1<<(hwreg.hstride-1)) : 0,
|
||||
type[hwreg.type]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
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_eu.h"
|
||||
|
||||
|
||||
void brw_math_invert( struct brw_compile *p,
|
||||
struct brw_reg dst,
|
||||
struct brw_reg src)
|
||||
{
|
||||
brw_math( p,
|
||||
dst,
|
||||
BRW_MATH_FUNCTION_INV,
|
||||
BRW_MATH_SATURATE_NONE,
|
||||
0,
|
||||
src,
|
||||
BRW_MATH_PRECISION_FULL,
|
||||
BRW_MATH_DATA_VECTOR );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void brw_copy4(struct brw_compile *p,
|
||||
struct brw_reg dst,
|
||||
struct brw_reg src,
|
||||
unsigned count)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
dst = vec4(dst);
|
||||
src = vec4(src);
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
unsigned delta = i*32;
|
||||
brw_MOV(p, byte_offset(dst, delta), byte_offset(src, delta));
|
||||
brw_MOV(p, byte_offset(dst, delta+16), byte_offset(src, delta+16));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void brw_copy8(struct brw_compile *p,
|
||||
struct brw_reg dst,
|
||||
struct brw_reg src,
|
||||
unsigned count)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
dst = vec8(dst);
|
||||
src = vec8(src);
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
unsigned delta = i*32;
|
||||
brw_MOV(p, byte_offset(dst, delta), byte_offset(src, delta));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void brw_copy_indirect_to_indirect(struct brw_compile *p,
|
||||
struct brw_indirect dst_ptr,
|
||||
struct brw_indirect src_ptr,
|
||||
unsigned count)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
unsigned delta = i*32;
|
||||
brw_MOV(p, deref_4f(dst_ptr, delta), deref_4f(src_ptr, delta));
|
||||
brw_MOV(p, deref_4f(dst_ptr, delta+16), deref_4f(src_ptr, delta+16));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void brw_copy_from_indirect(struct brw_compile *p,
|
||||
struct brw_reg dst,
|
||||
struct brw_indirect ptr,
|
||||
unsigned count)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
dst = vec4(dst);
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
unsigned delta = i*32;
|
||||
brw_MOV(p, byte_offset(dst, delta), deref_4f(ptr, delta));
|
||||
brw_MOV(p, byte_offset(dst, delta+16), deref_4f(ptr, delta+16));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* 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, sub license, 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 NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS 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.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/* Author:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "pipe/p_defines.h"
|
||||
#include "brw_context.h"
|
||||
#include "brw_defines.h"
|
||||
#include "brw_batch.h"
|
||||
|
||||
|
||||
/**
|
||||
* In future we may want a fence-like interface instead of finish.
|
||||
*/
|
||||
static void brw_flush( struct pipe_context *pipe,
|
||||
unsigned flags )
|
||||
{
|
||||
struct brw_context *brw = brw_context(pipe);
|
||||
struct pipe_fence_handle *fence;
|
||||
|
||||
/* Do we need to emit an MI_FLUSH command to flush the hardware
|
||||
* caches?
|
||||
*/
|
||||
if (flags & (PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_TEXTURE_CACHE)) {
|
||||
unsigned flush = CMD_MI_FLUSH;
|
||||
|
||||
#if 0
|
||||
if (!(flags & PIPE_FLUSH_RENDER_CACHE))
|
||||
flush |= INHIBIT_FLUSH_RENDER_CACHE;
|
||||
|
||||
if (flags & PIPE_FLUSH_TEXTURE_CACHE)
|
||||
flush |= FLUSH_MAP_CACHE;
|
||||
#endif
|
||||
|
||||
if (!BEGIN_BATCH(1, 0)) {
|
||||
FLUSH_BATCH( &fence );
|
||||
assert(BEGIN_BATCH(1, 0));
|
||||
}
|
||||
OUT_BATCH( flush );
|
||||
ADVANCE_BATCH();
|
||||
}
|
||||
|
||||
/* If there are no flags, just flush pending commands to hardware:
|
||||
*/
|
||||
FLUSH_BATCH( &fence );
|
||||
|
||||
if (flags & PIPE_FLUSH_WAIT) {
|
||||
// brw->winsys->wait_fence(brw->winsys, fence);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void brw_init_flush_functions( struct brw_context *brw )
|
||||
{
|
||||
brw->pipe.flush = brw_flush;
|
||||
}
|
||||
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
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_defines.h"
|
||||
#include "brw_context.h"
|
||||
#include "brw_eu.h"
|
||||
#include "brw_util.h"
|
||||
#include "brw_state.h"
|
||||
#include "brw_gs.h"
|
||||
|
||||
|
||||
|
||||
static void compile_gs_prog( struct brw_context *brw,
|
||||
struct brw_gs_prog_key *key )
|
||||
{
|
||||
struct brw_gs_compile c;
|
||||
const unsigned *program;
|
||||
unsigned program_size;
|
||||
|
||||
memset(&c, 0, sizeof(c));
|
||||
|
||||
c.key = *key;
|
||||
|
||||
/* Need to locate the two positions present in vertex + header.
|
||||
* These are currently hardcoded:
|
||||
*/
|
||||
c.nr_attrs = brw_count_bits(c.key.attrs);
|
||||
c.nr_regs = (c.nr_attrs + 1) / 2 + 1; /* are vertices packed, or reg-aligned? */
|
||||
c.nr_bytes = c.nr_regs * REG_SIZE;
|
||||
|
||||
|
||||
/* Begin the compilation:
|
||||
*/
|
||||
brw_init_compile(&c.func);
|
||||
|
||||
c.func.single_program_flow = 1;
|
||||
|
||||
/* For some reason the thread is spawned with only 4 channels
|
||||
* unmasked.
|
||||
*/
|
||||
brw_set_mask_control(&c.func, BRW_MASK_DISABLE);
|
||||
|
||||
|
||||
/* Note that primitives which don't require a GS program have
|
||||
* already been weeded out by this stage:
|
||||
*/
|
||||
switch (key->primitive) {
|
||||
case PIPE_PRIM_QUADS:
|
||||
brw_gs_quads( &c );
|
||||
break;
|
||||
case PIPE_PRIM_QUAD_STRIP:
|
||||
brw_gs_quad_strip( &c );
|
||||
break;
|
||||
case PIPE_PRIM_LINE_LOOP:
|
||||
brw_gs_lines( &c );
|
||||
break;
|
||||
case PIPE_PRIM_LINES:
|
||||
if (key->hint_gs_always)
|
||||
brw_gs_lines( &c );
|
||||
else {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case PIPE_PRIM_TRIANGLES:
|
||||
if (key->hint_gs_always)
|
||||
brw_gs_tris( &c );
|
||||
else {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case PIPE_PRIM_POINTS:
|
||||
if (key->hint_gs_always)
|
||||
brw_gs_points( &c );
|
||||
else {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
/* get the program
|
||||
*/
|
||||
program = brw_get_program(&c.func, &program_size);
|
||||
|
||||
/* Upload
|
||||
*/
|
||||
brw->gs.prog_gs_offset = brw_upload_cache( &brw->cache[BRW_GS_PROG],
|
||||
&c.key,
|
||||
sizeof(c.key),
|
||||
program,
|
||||
program_size,
|
||||
&c.prog_data,
|
||||
&brw->gs.prog_data );
|
||||
}
|
||||
|
||||
|
||||
static boolean search_cache( struct brw_context *brw,
|
||||
struct brw_gs_prog_key *key )
|
||||
{
|
||||
return brw_search_cache(&brw->cache[BRW_GS_PROG],
|
||||
key, sizeof(*key),
|
||||
&brw->gs.prog_data,
|
||||
&brw->gs.prog_gs_offset);
|
||||
}
|
||||
|
||||
|
||||
static const int gs_prim[PIPE_PRIM_POLYGON+1] = {
|
||||
PIPE_PRIM_POINTS,
|
||||
PIPE_PRIM_LINES,
|
||||
PIPE_PRIM_LINE_LOOP,
|
||||
PIPE_PRIM_LINES,
|
||||
PIPE_PRIM_TRIANGLES,
|
||||
PIPE_PRIM_TRIANGLES,
|
||||
PIPE_PRIM_TRIANGLES,
|
||||
PIPE_PRIM_QUADS,
|
||||
PIPE_PRIM_QUAD_STRIP,
|
||||
PIPE_PRIM_TRIANGLES
|
||||
};
|
||||
|
||||
static void populate_key( struct brw_context *brw,
|
||||
struct brw_gs_prog_key *key )
|
||||
{
|
||||
memset(key, 0, sizeof(*key));
|
||||
|
||||
/* CACHE_NEW_VS_PROG */
|
||||
key->attrs = brw->vs.prog_data->outputs_written;
|
||||
|
||||
/* BRW_NEW_PRIMITIVE */
|
||||
key->primitive = gs_prim[brw->primitive];
|
||||
|
||||
key->hint_gs_always = 0; /* debug code? */
|
||||
|
||||
key->need_gs_prog = (key->hint_gs_always ||
|
||||
brw->primitive == PIPE_PRIM_QUADS ||
|
||||
brw->primitive == PIPE_PRIM_QUAD_STRIP ||
|
||||
brw->primitive == PIPE_PRIM_LINE_LOOP);
|
||||
}
|
||||
|
||||
/* Calculate interpolants for triangle and line rasterization.
|
||||
*/
|
||||
static void upload_gs_prog( struct brw_context *brw )
|
||||
{
|
||||
struct brw_gs_prog_key key;
|
||||
|
||||
/* Populate the key:
|
||||
*/
|
||||
populate_key(brw, &key);
|
||||
|
||||
if (brw->gs.prog_active != key.need_gs_prog) {
|
||||
brw->state.dirty.cache |= CACHE_NEW_GS_PROG;
|
||||
brw->gs.prog_active = key.need_gs_prog;
|
||||
}
|
||||
|
||||
if (brw->gs.prog_active) {
|
||||
if (!search_cache(brw, &key))
|
||||
compile_gs_prog( brw, &key );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const struct brw_tracked_state brw_gs_prog = {
|
||||
.dirty = {
|
||||
.brw = BRW_NEW_PRIMITIVE,
|
||||
.cache = CACHE_NEW_VS_PROG
|
||||
},
|
||||
.update = upload_gs_prog
|
||||
};
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
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>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef BRW_GS_H
|
||||
#define BRW_GS_H
|
||||
|
||||
|
||||
#include "brw_context.h"
|
||||
#include "brw_eu.h"
|
||||
|
||||
#define MAX_GS_VERTS (4)
|
||||
|
||||
struct brw_gs_prog_key {
|
||||
unsigned attrs:32;
|
||||
unsigned primitive:4;
|
||||
unsigned hint_gs_always:1;
|
||||
unsigned need_gs_prog:1;
|
||||
unsigned pad:26;
|
||||
};
|
||||
|
||||
struct brw_gs_compile {
|
||||
struct brw_compile func;
|
||||
struct brw_gs_prog_key key;
|
||||
struct brw_gs_prog_data prog_data;
|
||||
|
||||
struct {
|
||||
struct brw_reg R0;
|
||||
struct brw_reg vertex[MAX_GS_VERTS];
|
||||
} reg;
|
||||
|
||||
/* 3 different ways of expressing vertex size:
|
||||
*/
|
||||
unsigned nr_attrs;
|
||||
unsigned nr_regs;
|
||||
unsigned nr_bytes;
|
||||
};
|
||||
|
||||
#define ATTR_SIZE (4*4)
|
||||
|
||||
void brw_gs_quads( struct brw_gs_compile *c );
|
||||
void brw_gs_quad_strip( struct brw_gs_compile *c );
|
||||
void brw_gs_tris( struct brw_gs_compile *c );
|
||||
void brw_gs_lines( struct brw_gs_compile *c );
|
||||
void brw_gs_points( struct brw_gs_compile *c );
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
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_defines.h"
|
||||
#include "brw_context.h"
|
||||
#include "brw_eu.h"
|
||||
#include "brw_util.h"
|
||||
#include "brw_gs.h"
|
||||
|
||||
static void brw_gs_alloc_regs( struct brw_gs_compile *c,
|
||||
unsigned nr_verts )
|
||||
{
|
||||
unsigned i = 0,j;
|
||||
|
||||
/* Register usage is static, precompute here:
|
||||
*/
|
||||
c->reg.R0 = retype(brw_vec8_grf(i, 0), BRW_REGISTER_TYPE_UD); i++;
|
||||
|
||||
/* Payload vertices plus space for more generated vertices:
|
||||
*/
|
||||
for (j = 0; j < nr_verts; j++) {
|
||||
c->reg.vertex[j] = brw_vec4_grf(i, 0);
|
||||
i += c->nr_regs;
|
||||
}
|
||||
|
||||
c->prog_data.urb_read_length = c->nr_regs;
|
||||
c->prog_data.total_grf = i;
|
||||
}
|
||||
|
||||
|
||||
static void brw_gs_emit_vue(struct brw_gs_compile *c,
|
||||
struct brw_reg vert,
|
||||
boolean last,
|
||||
unsigned header)
|
||||
{
|
||||
struct brw_compile *p = &c->func;
|
||||
boolean allocate = !last;
|
||||
|
||||
/* Overwrite PrimType and PrimStart in the message header, for
|
||||
* each vertex in turn:
|
||||
*/
|
||||
brw_MOV(p, get_element_ud(c->reg.R0, 2), brw_imm_ud(header));
|
||||
|
||||
/* Copy the vertex from vertn into m1..mN+1:
|
||||
*/
|
||||
brw_copy8(p, brw_message_reg(1), vert, c->nr_regs);
|
||||
|
||||
/* Send each vertex as a seperate write to the urb. This is
|
||||
* different to the concept in brw_sf_emit.c, where subsequent
|
||||
* writes are used to build up a single urb entry. Each of these
|
||||
* writes instantiates a seperate urb entry, and a new one must be
|
||||
* allocated each time.
|
||||
*/
|
||||
brw_urb_WRITE(p,
|
||||
allocate ? c->reg.R0 : retype(brw_null_reg(), BRW_REGISTER_TYPE_UD),
|
||||
0,
|
||||
c->reg.R0,
|
||||
allocate,
|
||||
1, /* used */
|
||||
c->nr_regs + 1, /* msg length */
|
||||
allocate ? 1 : 0, /* response length */
|
||||
allocate ? 0 : 1, /* eot */
|
||||
1, /* writes_complete */
|
||||
0, /* urb offset */
|
||||
BRW_URB_SWIZZLE_NONE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void brw_gs_quads( struct brw_gs_compile *c )
|
||||
{
|
||||
brw_gs_alloc_regs(c, 4);
|
||||
|
||||
/* Use polygons for correct edgeflag behaviour. Note that vertex 3
|
||||
* is the PV for quads, but vertex 0 for polygons:
|
||||
*/
|
||||
brw_gs_emit_vue(c, c->reg.vertex[3], 0, ((_3DPRIM_POLYGON << 2) | R02_PRIM_START));
|
||||
brw_gs_emit_vue(c, c->reg.vertex[0], 0, (_3DPRIM_POLYGON << 2));
|
||||
brw_gs_emit_vue(c, c->reg.vertex[1], 0, (_3DPRIM_POLYGON << 2));
|
||||
brw_gs_emit_vue(c, c->reg.vertex[2], 1, ((_3DPRIM_POLYGON << 2) | R02_PRIM_END));
|
||||
}
|
||||
|
||||
void brw_gs_quad_strip( struct brw_gs_compile *c )
|
||||
{
|
||||
brw_gs_alloc_regs(c, 4);
|
||||
|
||||
brw_gs_emit_vue(c, c->reg.vertex[2], 0, ((_3DPRIM_POLYGON << 2) | R02_PRIM_START));
|
||||
brw_gs_emit_vue(c, c->reg.vertex[3], 0, (_3DPRIM_POLYGON << 2));
|
||||
brw_gs_emit_vue(c, c->reg.vertex[0], 0, (_3DPRIM_POLYGON << 2));
|
||||
brw_gs_emit_vue(c, c->reg.vertex[1], 1, ((_3DPRIM_POLYGON << 2) | R02_PRIM_END));
|
||||
}
|
||||
|
||||
void brw_gs_tris( struct brw_gs_compile *c )
|
||||
{
|
||||
brw_gs_alloc_regs(c, 3);
|
||||
brw_gs_emit_vue(c, c->reg.vertex[0], 0, ((_3DPRIM_TRILIST << 2) | R02_PRIM_START));
|
||||
brw_gs_emit_vue(c, c->reg.vertex[1], 0, (_3DPRIM_TRILIST << 2));
|
||||
brw_gs_emit_vue(c, c->reg.vertex[2], 1, ((_3DPRIM_TRILIST << 2) | R02_PRIM_END));
|
||||
}
|
||||
|
||||
void brw_gs_lines( struct brw_gs_compile *c )
|
||||
{
|
||||
brw_gs_alloc_regs(c, 2);
|
||||
brw_gs_emit_vue(c, c->reg.vertex[0], 0, ((_3DPRIM_LINESTRIP << 2) | R02_PRIM_START));
|
||||
brw_gs_emit_vue(c, c->reg.vertex[1], 1, ((_3DPRIM_LINESTRIP << 2) | R02_PRIM_END));
|
||||
}
|
||||
|
||||
void brw_gs_points( struct brw_gs_compile *c )
|
||||
{
|
||||
brw_gs_alloc_regs(c, 1);
|
||||
brw_gs_emit_vue(c, c->reg.vertex[0], 1, ((_3DPRIM_POINTLIST << 2) | R02_PRIM_START | R02_PRIM_END));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
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_state.h"
|
||||
#include "brw_defines.h"
|
||||
|
||||
|
||||
|
||||
static void upload_gs_unit( struct brw_context *brw )
|
||||
{
|
||||
struct brw_gs_unit_state gs;
|
||||
|
||||
memset(&gs, 0, sizeof(gs));
|
||||
|
||||
/* CACHE_NEW_GS_PROG */
|
||||
if (brw->gs.prog_active) {
|
||||
gs.thread0.grf_reg_count =
|
||||
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;
|
||||
}
|
||||
else {
|
||||
gs.thread0.grf_reg_count = 0;
|
||||
gs.thread0.kernel_start_pointer = 0;
|
||||
gs.thread3.urb_entry_read_length = 1;
|
||||
}
|
||||
|
||||
/* BRW_NEW_URB_FENCE */
|
||||
gs.thread4.nr_urb_entries = brw->urb.nr_gs_entries;
|
||||
gs.thread4.urb_entry_allocation_size = brw->urb.vsize - 1;
|
||||
|
||||
gs.thread4.max_threads = 0; /* Hardware requirement */
|
||||
|
||||
if (BRW_DEBUG & DEBUG_STATS)
|
||||
gs.thread4.stats_enable = 1;
|
||||
|
||||
/* CONSTANT */
|
||||
gs.thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754;
|
||||
gs.thread1.single_program_flow = 1;
|
||||
gs.thread3.dispatch_grf_start_reg = 1;
|
||||
gs.thread3.const_urb_entry_read_offset = 0;
|
||||
gs.thread3.const_urb_entry_read_length = 0;
|
||||
gs.thread3.urb_entry_read_offset = 0;
|
||||
|
||||
|
||||
brw->gs.state_gs_offset = brw_cache_data( &brw->cache[BRW_GS_UNIT], &gs );
|
||||
}
|
||||
|
||||
|
||||
const struct brw_tracked_state brw_gs_unit = {
|
||||
.dirty = {
|
||||
.brw = (BRW_NEW_CURBE_OFFSETS |
|
||||
BRW_NEW_URB_FENCE),
|
||||
.cache = CACHE_NEW_GS_PROG
|
||||
},
|
||||
.update = upload_gs_unit
|
||||
};
|
||||
@@ -0,0 +1,538 @@
|
||||
/*
|
||||
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>
|
||||
* frame buffer texture by Gary Wong <gtw@gnu.org>
|
||||
*/
|
||||
|
||||
|
||||
#include "brw_context.h"
|
||||
#include "brw_defines.h"
|
||||
#include "brw_draw.h"
|
||||
|
||||
#if 0
|
||||
|
||||
#define INIT(brw, STRUCT, ATTRIB) \
|
||||
do { \
|
||||
brw->attribs.ATTRIB = &ctx->ATTRIB; \
|
||||
} while (0)
|
||||
|
||||
#define DUP(brw, STRUCT, ATTRIB) \
|
||||
do { \
|
||||
brw->metaops.attribs.ATTRIB = MALLOC_STRUCT(STRUCT); \
|
||||
memcpy(brw->metaops.attribs.ATTRIB, \
|
||||
brw->attribs.ATTRIB, \
|
||||
sizeof(struct STRUCT)); \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define INSTALL(brw, ATTRIB, STATE) \
|
||||
do { \
|
||||
brw->attribs.ATTRIB = brw->metaops.attribs.ATTRIB; \
|
||||
brw->state.dirty.mesa |= STATE; \
|
||||
} while (0)
|
||||
|
||||
#define RESTORE(brw, ATTRIB, STATE) \
|
||||
do { \
|
||||
brw->attribs.ATTRIB = &brw->intel.ctx.ATTRIB; \
|
||||
brw->state.dirty.mesa |= STATE; \
|
||||
} while (0)
|
||||
|
||||
static void init_attribs( struct brw_context *brw )
|
||||
{
|
||||
DUP(brw, gl_colorbuffer_attrib, Color);
|
||||
DUP(brw, gl_depthbuffer_attrib, Depth);
|
||||
DUP(brw, gl_fog_attrib, Fog);
|
||||
DUP(brw, gl_hint_attrib, Hint);
|
||||
DUP(brw, gl_light_attrib, Light);
|
||||
DUP(brw, gl_line_attrib, Line);
|
||||
DUP(brw, gl_point_attrib, Point);
|
||||
DUP(brw, gl_polygon_attrib, Polygon);
|
||||
DUP(brw, gl_scissor_attrib, Scissor);
|
||||
DUP(brw, gl_stencil_attrib, Stencil);
|
||||
DUP(brw, gl_texture_attrib, Texture);
|
||||
DUP(brw, gl_transform_attrib, Transform);
|
||||
DUP(brw, gl_viewport_attrib, Viewport);
|
||||
DUP(brw, gl_vertex_program_state, VertexProgram);
|
||||
DUP(brw, gl_fragment_program_state, FragmentProgram);
|
||||
}
|
||||
|
||||
static void install_attribs( struct brw_context *brw )
|
||||
{
|
||||
INSTALL(brw, Color, _NEW_COLOR);
|
||||
INSTALL(brw, Depth, _NEW_DEPTH);
|
||||
INSTALL(brw, Fog, _NEW_FOG);
|
||||
INSTALL(brw, Hint, _NEW_HINT);
|
||||
INSTALL(brw, Light, _NEW_LIGHT);
|
||||
INSTALL(brw, Line, _NEW_LINE);
|
||||
INSTALL(brw, Point, _NEW_POINT);
|
||||
INSTALL(brw, Polygon, _NEW_POLYGON);
|
||||
INSTALL(brw, Scissor, _NEW_SCISSOR);
|
||||
INSTALL(brw, Stencil, _NEW_STENCIL);
|
||||
INSTALL(brw, Texture, _NEW_TEXTURE);
|
||||
INSTALL(brw, Transform, _NEW_TRANSFORM);
|
||||
INSTALL(brw, Viewport, _NEW_VIEWPORT);
|
||||
INSTALL(brw, VertexProgram, _NEW_PROGRAM);
|
||||
INSTALL(brw, FragmentProgram, _NEW_PROGRAM);
|
||||
}
|
||||
|
||||
static void restore_attribs( struct brw_context *brw )
|
||||
{
|
||||
RESTORE(brw, Color, _NEW_COLOR);
|
||||
RESTORE(brw, Depth, _NEW_DEPTH);
|
||||
RESTORE(brw, Fog, _NEW_FOG);
|
||||
RESTORE(brw, Hint, _NEW_HINT);
|
||||
RESTORE(brw, Light, _NEW_LIGHT);
|
||||
RESTORE(brw, Line, _NEW_LINE);
|
||||
RESTORE(brw, Point, _NEW_POINT);
|
||||
RESTORE(brw, Polygon, _NEW_POLYGON);
|
||||
RESTORE(brw, Scissor, _NEW_SCISSOR);
|
||||
RESTORE(brw, Stencil, _NEW_STENCIL);
|
||||
RESTORE(brw, Texture, _NEW_TEXTURE);
|
||||
RESTORE(brw, Transform, _NEW_TRANSFORM);
|
||||
RESTORE(brw, Viewport, _NEW_VIEWPORT);
|
||||
RESTORE(brw, VertexProgram, _NEW_PROGRAM);
|
||||
RESTORE(brw, FragmentProgram, _NEW_PROGRAM);
|
||||
}
|
||||
|
||||
|
||||
static const char *vp_prog =
|
||||
"!!ARBvp1.0\n"
|
||||
"MOV result.color, vertex.color;\n"
|
||||
"MOV result.position, vertex.position;\n"
|
||||
"END\n";
|
||||
|
||||
static const char *fp_prog =
|
||||
"!!ARBfp1.0\n"
|
||||
"MOV result.color, fragment.color;\n"
|
||||
"END\n";
|
||||
|
||||
static const char *fp_tex_prog =
|
||||
"!!ARBfp1.0\n"
|
||||
"TEMP a;\n"
|
||||
"ADD a, fragment.position, program.local[0];\n"
|
||||
"MUL a, a, program.local[1];\n"
|
||||
"TEX result.color, a, texture[0], 2D;\n"
|
||||
"MOV result.depth.z, fragment.position;\n"
|
||||
"END\n";
|
||||
|
||||
/* Derived values of importance:
|
||||
*
|
||||
* FragmentProgram->_Current
|
||||
* VertexProgram->_Enabled
|
||||
* brw->vertex_program
|
||||
* DrawBuffer->_ColorDrawBufferMask[0]
|
||||
*
|
||||
*
|
||||
* More if drawpixels-through-texture is added.
|
||||
*/
|
||||
static void init_metaops_state( struct brw_context *brw )
|
||||
{
|
||||
GLcontext *ctx = &brw->intel.ctx;
|
||||
|
||||
brw->metaops.vbo = ctx->Driver.NewBufferObject(ctx, 1, GL_ARRAY_BUFFER_ARB);
|
||||
|
||||
ctx->Driver.BufferData(ctx,
|
||||
GL_ARRAY_BUFFER_ARB,
|
||||
4096,
|
||||
NULL,
|
||||
GL_DYNAMIC_DRAW_ARB,
|
||||
brw->metaops.vbo);
|
||||
|
||||
brw->metaops.fp = (struct gl_fragment_program *)
|
||||
ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 1 );
|
||||
|
||||
brw->metaops.fp_tex = (struct gl_fragment_program *)
|
||||
ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 1 );
|
||||
|
||||
brw->metaops.vp = (struct gl_vertex_program *)
|
||||
ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 1 );
|
||||
|
||||
_mesa_parse_arb_fragment_program(ctx, GL_FRAGMENT_PROGRAM_ARB,
|
||||
fp_prog, strlen(fp_prog),
|
||||
brw->metaops.fp);
|
||||
|
||||
_mesa_parse_arb_fragment_program(ctx, GL_FRAGMENT_PROGRAM_ARB,
|
||||
fp_tex_prog, strlen(fp_tex_prog),
|
||||
brw->metaops.fp_tex);
|
||||
|
||||
_mesa_parse_arb_vertex_program(ctx, GL_VERTEX_PROGRAM_ARB,
|
||||
vp_prog, strlen(vp_prog),
|
||||
brw->metaops.vp);
|
||||
|
||||
brw->metaops.attribs.VertexProgram->Current = brw->metaops.vp;
|
||||
brw->metaops.attribs.VertexProgram->_Enabled = TRUE;
|
||||
|
||||
brw->metaops.attribs.FragmentProgram->_Current = brw->metaops.fp;
|
||||
}
|
||||
|
||||
static void meta_flat_shade( struct intel_context *intel )
|
||||
{
|
||||
struct brw_context *brw = brw_context(&intel->ctx);
|
||||
|
||||
brw->metaops.attribs.Raster->flatshade = TRUE;
|
||||
brw->state.dirty.mesa |= _NEW_LIGHT;
|
||||
}
|
||||
|
||||
|
||||
static void meta_no_stencil_write( struct intel_context *intel )
|
||||
{
|
||||
struct brw_context *brw = brw_context(&intel->ctx);
|
||||
|
||||
brw->metaops.attribs.Stencil->Enabled = FALSE;
|
||||
brw->metaops.attribs.Stencil->WriteMask[0] = FALSE;
|
||||
brw->state.dirty.mesa |= _NEW_STENCIL;
|
||||
}
|
||||
|
||||
static void meta_no_depth_write( struct intel_context *intel )
|
||||
{
|
||||
struct brw_context *brw = brw_context(&intel->ctx);
|
||||
|
||||
brw->metaops.attribs.Depth->Test = FALSE;
|
||||
brw->metaops.attribs.Depth->Mask = FALSE;
|
||||
brw->state.dirty.mesa |= _NEW_DEPTH;
|
||||
}
|
||||
|
||||
|
||||
static void meta_depth_replace( struct intel_context *intel )
|
||||
{
|
||||
struct brw_context *brw = brw_context(&intel->ctx);
|
||||
|
||||
/* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, TRUE )
|
||||
* ctx->Driver.DepthMask( ctx, TRUE )
|
||||
*/
|
||||
brw->metaops.attribs.Depth->Test = TRUE;
|
||||
brw->metaops.attribs.Depth->Mask = TRUE;
|
||||
brw->state.dirty.mesa |= _NEW_DEPTH;
|
||||
|
||||
/* ctx->Driver.DepthFunc( ctx, GL_ALWAYS )
|
||||
*/
|
||||
brw->metaops.attribs.Depth->Func = GL_ALWAYS;
|
||||
|
||||
brw->state.dirty.mesa |= _NEW_DEPTH;
|
||||
}
|
||||
|
||||
|
||||
static void meta_stencil_replace( struct intel_context *intel,
|
||||
unsigned s_mask,
|
||||
unsigned s_clear)
|
||||
{
|
||||
struct brw_context *brw = brw_context(&intel->ctx);
|
||||
|
||||
brw->metaops.attribs.Stencil->Enabled = TRUE;
|
||||
brw->metaops.attribs.Stencil->WriteMask[0] = s_mask;
|
||||
brw->metaops.attribs.Stencil->ValueMask[0] = 0xff;
|
||||
brw->metaops.attribs.Stencil->Ref[0] = s_clear;
|
||||
brw->metaops.attribs.Stencil->Function[0] = GL_ALWAYS;
|
||||
brw->metaops.attribs.Stencil->FailFunc[0] = GL_REPLACE;
|
||||
brw->metaops.attribs.Stencil->ZPassFunc[0] = GL_REPLACE;
|
||||
brw->metaops.attribs.Stencil->ZFailFunc[0] = GL_REPLACE;
|
||||
brw->state.dirty.mesa |= _NEW_STENCIL;
|
||||
}
|
||||
|
||||
|
||||
static void meta_color_mask( struct intel_context *intel, boolean state )
|
||||
{
|
||||
struct brw_context *brw = brw_context(&intel->ctx);
|
||||
|
||||
if (state)
|
||||
COPY_4V(brw->metaops.attribs.Color->ColorMask,
|
||||
brw->intel.ctx.Color.ColorMask);
|
||||
else
|
||||
ASSIGN_4V(brw->metaops.attribs.Color->ColorMask, 0, 0, 0, 0);
|
||||
|
||||
brw->state.dirty.mesa |= _NEW_COLOR;
|
||||
}
|
||||
|
||||
static void meta_no_texture( struct intel_context *intel )
|
||||
{
|
||||
struct brw_context *brw = brw_context(&intel->ctx);
|
||||
|
||||
brw->metaops.attribs.FragmentProgram->_Current = brw->metaops.fp;
|
||||
|
||||
brw->metaops.attribs.Texture->CurrentUnit = 0;
|
||||
brw->metaops.attribs.Texture->_EnabledUnits = 0;
|
||||
brw->metaops.attribs.Texture->_EnabledCoordUnits = 0;
|
||||
brw->metaops.attribs.Texture->Unit[ 0 ].Enabled = 0;
|
||||
brw->metaops.attribs.Texture->Unit[ 0 ]._ReallyEnabled = 0;
|
||||
|
||||
brw->state.dirty.mesa |= _NEW_TEXTURE | _NEW_PROGRAM;
|
||||
}
|
||||
|
||||
static void meta_texture_blend_replace(struct intel_context *intel)
|
||||
{
|
||||
struct brw_context *brw = brw_context(&intel->ctx);
|
||||
|
||||
brw->metaops.attribs.Texture->CurrentUnit = 0;
|
||||
brw->metaops.attribs.Texture->_EnabledUnits = 1;
|
||||
brw->metaops.attribs.Texture->_EnabledCoordUnits = 1;
|
||||
brw->metaops.attribs.Texture->Unit[ 0 ].Enabled = TEXTURE_2D_BIT;
|
||||
brw->metaops.attribs.Texture->Unit[ 0 ]._ReallyEnabled = TEXTURE_2D_BIT;
|
||||
brw->metaops.attribs.Texture->Unit[ 0 ].Current2D =
|
||||
intel->frame_buffer_texobj;
|
||||
brw->metaops.attribs.Texture->Unit[ 0 ]._Current =
|
||||
intel->frame_buffer_texobj;
|
||||
|
||||
brw->state.dirty.mesa |= _NEW_TEXTURE | _NEW_PROGRAM;
|
||||
}
|
||||
|
||||
static void meta_import_pixel_state(struct intel_context *intel)
|
||||
{
|
||||
struct brw_context *brw = brw_context(&intel->ctx);
|
||||
|
||||
RESTORE(brw, Color, _NEW_COLOR);
|
||||
RESTORE(brw, Depth, _NEW_DEPTH);
|
||||
RESTORE(brw, Fog, _NEW_FOG);
|
||||
RESTORE(brw, Scissor, _NEW_SCISSOR);
|
||||
RESTORE(brw, Stencil, _NEW_STENCIL);
|
||||
RESTORE(brw, Texture, _NEW_TEXTURE);
|
||||
RESTORE(brw, FragmentProgram, _NEW_PROGRAM);
|
||||
}
|
||||
|
||||
static void meta_frame_buffer_texture( struct intel_context *intel,
|
||||
int xoff, int yoff )
|
||||
{
|
||||
struct brw_context *brw = brw_context(&intel->ctx);
|
||||
struct intel_region *region = intel_drawbuf_region( intel );
|
||||
|
||||
INSTALL(brw, FragmentProgram, _NEW_PROGRAM);
|
||||
|
||||
brw->metaops.attribs.FragmentProgram->_Current = brw->metaops.fp_tex;
|
||||
/* This is unfortunate, but seems to be necessary, since later on we
|
||||
will end up calling _mesa_load_state_parameters to lookup the
|
||||
local params (below), and that will want to look in ctx.FragmentProgram
|
||||
instead of brw->attribs.FragmentProgram. */
|
||||
intel->ctx.FragmentProgram.Current = brw->metaops.fp_tex;
|
||||
|
||||
brw->metaops.fp_tex->Base.LocalParams[ 0 ][ 0 ] = xoff;
|
||||
brw->metaops.fp_tex->Base.LocalParams[ 0 ][ 1 ] = yoff;
|
||||
brw->metaops.fp_tex->Base.LocalParams[ 0 ][ 2 ] = 0.0;
|
||||
brw->metaops.fp_tex->Base.LocalParams[ 0 ][ 3 ] = 0.0;
|
||||
brw->metaops.fp_tex->Base.LocalParams[ 1 ][ 0 ] =
|
||||
1.0 / region->pitch;
|
||||
brw->metaops.fp_tex->Base.LocalParams[ 1 ][ 1 ] =
|
||||
-1.0 / region->height;
|
||||
brw->metaops.fp_tex->Base.LocalParams[ 1 ][ 2 ] = 0.0;
|
||||
brw->metaops.fp_tex->Base.LocalParams[ 1 ][ 3 ] = 1.0;
|
||||
|
||||
brw->state.dirty.mesa |= _NEW_PROGRAM;
|
||||
}
|
||||
|
||||
|
||||
static void meta_draw_region( struct intel_context *intel,
|
||||
struct intel_region *draw_region,
|
||||
struct intel_region *depth_region )
|
||||
{
|
||||
struct brw_context *brw = brw_context(&intel->ctx);
|
||||
|
||||
if (!brw->metaops.saved_draw_region) {
|
||||
brw->metaops.saved_draw_region = brw->state.draw_region;
|
||||
brw->metaops.saved_depth_region = brw->state.depth_region;
|
||||
}
|
||||
|
||||
brw->state.draw_region = draw_region;
|
||||
brw->state.depth_region = depth_region;
|
||||
|
||||
brw->state.dirty.mesa |= _NEW_BUFFERS;
|
||||
}
|
||||
|
||||
|
||||
static void meta_draw_quad(struct intel_context *intel,
|
||||
float x0, float x1,
|
||||
float y0, float y1,
|
||||
float z,
|
||||
ubyte red, ubyte green,
|
||||
ubyte blue, ubyte alpha,
|
||||
float s0, float s1,
|
||||
float t0, float t1)
|
||||
{
|
||||
GLcontext *ctx = &intel->ctx;
|
||||
struct brw_context *brw = brw_context(&intel->ctx);
|
||||
struct gl_client_array pos_array;
|
||||
struct gl_client_array color_array;
|
||||
struct gl_client_array *attribs[PIPE_ATTRIB_MAX];
|
||||
struct _mesa_prim prim[1];
|
||||
float pos[4][3];
|
||||
ubyte color[4];
|
||||
|
||||
ctx->Driver.BufferData(ctx,
|
||||
GL_ARRAY_BUFFER_ARB,
|
||||
sizeof(pos) + sizeof(color),
|
||||
NULL,
|
||||
GL_DYNAMIC_DRAW_ARB,
|
||||
brw->metaops.vbo);
|
||||
|
||||
pos[0][0] = x0;
|
||||
pos[0][1] = y0;
|
||||
pos[0][2] = z;
|
||||
|
||||
pos[1][0] = x1;
|
||||
pos[1][1] = y0;
|
||||
pos[1][2] = z;
|
||||
|
||||
pos[2][0] = x1;
|
||||
pos[2][1] = y1;
|
||||
pos[2][2] = z;
|
||||
|
||||
pos[3][0] = x0;
|
||||
pos[3][1] = y1;
|
||||
pos[3][2] = z;
|
||||
|
||||
|
||||
ctx->Driver.BufferSubData(ctx,
|
||||
GL_ARRAY_BUFFER_ARB,
|
||||
0,
|
||||
sizeof(pos),
|
||||
pos,
|
||||
brw->metaops.vbo);
|
||||
|
||||
color[0] = red;
|
||||
color[1] = green;
|
||||
color[2] = blue;
|
||||
color[3] = alpha;
|
||||
|
||||
ctx->Driver.BufferSubData(ctx,
|
||||
GL_ARRAY_BUFFER_ARB,
|
||||
sizeof(pos),
|
||||
sizeof(color),
|
||||
color,
|
||||
brw->metaops.vbo);
|
||||
|
||||
/* Ignoring texture coords.
|
||||
*/
|
||||
|
||||
memset(attribs, 0, PIPE_ATTRIB_MAX * sizeof(*attribs));
|
||||
|
||||
attribs[VERT_ATTRIB_POS] = &pos_array;
|
||||
attribs[VERT_ATTRIB_POS]->Ptr = 0;
|
||||
attribs[VERT_ATTRIB_POS]->Type = GL_FLOAT;
|
||||
attribs[VERT_ATTRIB_POS]->Enabled = 1;
|
||||
attribs[VERT_ATTRIB_POS]->Size = 3;
|
||||
attribs[VERT_ATTRIB_POS]->StrideB = 3 * sizeof(float);
|
||||
attribs[VERT_ATTRIB_POS]->Stride = 3 * sizeof(float);
|
||||
attribs[VERT_ATTRIB_POS]->_MaxElement = 4;
|
||||
attribs[VERT_ATTRIB_POS]->Normalized = 0;
|
||||
attribs[VERT_ATTRIB_POS]->BufferObj = brw->metaops.vbo;
|
||||
|
||||
attribs[VERT_ATTRIB_COLOR0] = &color_array;
|
||||
attribs[VERT_ATTRIB_COLOR0]->Ptr = (const ubyte *)sizeof(pos);
|
||||
attribs[VERT_ATTRIB_COLOR0]->Type = GL_UNSIGNED_BYTE;
|
||||
attribs[VERT_ATTRIB_COLOR0]->Enabled = 1;
|
||||
attribs[VERT_ATTRIB_COLOR0]->Size = 4;
|
||||
attribs[VERT_ATTRIB_COLOR0]->StrideB = 0;
|
||||
attribs[VERT_ATTRIB_COLOR0]->Stride = 0;
|
||||
attribs[VERT_ATTRIB_COLOR0]->_MaxElement = 1;
|
||||
attribs[VERT_ATTRIB_COLOR0]->Normalized = 1;
|
||||
attribs[VERT_ATTRIB_COLOR0]->BufferObj = brw->metaops.vbo;
|
||||
|
||||
/* Just ignoring texture coordinates for now.
|
||||
*/
|
||||
|
||||
memset(prim, 0, sizeof(*prim));
|
||||
|
||||
prim[0].mode = GL_TRIANGLE_FAN;
|
||||
prim[0].begin = 1;
|
||||
prim[0].end = 1;
|
||||
prim[0].weak = 0;
|
||||
prim[0].pad = 0;
|
||||
prim[0].start = 0;
|
||||
prim[0].count = 4;
|
||||
|
||||
brw_draw_prims(&brw->intel.ctx,
|
||||
(const struct gl_client_array **)attribs,
|
||||
prim, 1,
|
||||
NULL,
|
||||
0,
|
||||
3 );
|
||||
}
|
||||
|
||||
|
||||
static void install_meta_state( struct intel_context *intel )
|
||||
{
|
||||
GLcontext *ctx = &intel->ctx;
|
||||
struct brw_context *brw = brw_context(ctx);
|
||||
|
||||
if (!brw->metaops.vbo) {
|
||||
init_metaops_state(brw);
|
||||
}
|
||||
|
||||
install_attribs(brw);
|
||||
|
||||
meta_no_texture(&brw->intel);
|
||||
meta_flat_shade(&brw->intel);
|
||||
brw->metaops.restore_draw_mask = ctx->DrawBuffer->_ColorDrawBufferMask[0];
|
||||
brw->metaops.restore_fp = ctx->FragmentProgram.Current;
|
||||
|
||||
/* This works without adjusting refcounts. Fix later?
|
||||
*/
|
||||
brw->metaops.saved_draw_region = brw->state.draw_region;
|
||||
brw->metaops.saved_depth_region = brw->state.depth_region;
|
||||
brw->metaops.active = 1;
|
||||
|
||||
brw->state.dirty.brw |= BRW_NEW_METAOPS;
|
||||
}
|
||||
|
||||
static void leave_meta_state( struct intel_context *intel )
|
||||
{
|
||||
GLcontext *ctx = &intel->ctx;
|
||||
struct brw_context *brw = brw_context(ctx);
|
||||
|
||||
restore_attribs(brw);
|
||||
|
||||
ctx->DrawBuffer->_ColorDrawBufferMask[0] = brw->metaops.restore_draw_mask;
|
||||
ctx->FragmentProgram.Current = brw->metaops.restore_fp;
|
||||
|
||||
brw->state.draw_region = brw->metaops.saved_draw_region;
|
||||
brw->state.depth_region = brw->metaops.saved_depth_region;
|
||||
brw->metaops.saved_draw_region = NULL;
|
||||
brw->metaops.saved_depth_region = NULL;
|
||||
brw->metaops.active = 0;
|
||||
|
||||
brw->state.dirty.mesa |= _NEW_BUFFERS;
|
||||
brw->state.dirty.brw |= BRW_NEW_METAOPS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void brw_init_metaops( struct brw_context *brw )
|
||||
{
|
||||
init_attribs(brw);
|
||||
}
|
||||
|
||||
void brw_destroy_metaops( struct brw_context *brw )
|
||||
{
|
||||
GLcontext *ctx = &brw->intel.ctx;
|
||||
|
||||
if (brw->metaops.vbo)
|
||||
ctx->Driver.DeleteBuffer( ctx, brw->metaops.vbo );
|
||||
|
||||
/* ctx->Driver.DeleteProgram( ctx, brw->metaops.fp ); */
|
||||
/* ctx->Driver.DeleteProgram( ctx, brw->metaops.fp_tex ); */
|
||||
/* ctx->Driver.DeleteProgram( ctx, brw->metaops.vp ); */
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,425 @@
|
||||
/*
|
||||
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_batch.h"
|
||||
#include "brw_context.h"
|
||||
#include "brw_state.h"
|
||||
#include "brw_defines.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Blend color
|
||||
*/
|
||||
|
||||
void brw_upload_blend_constant_color(struct brw_context *brw)
|
||||
{
|
||||
struct brw_blend_constant_color bcc;
|
||||
|
||||
memset(&bcc, 0, sizeof(bcc));
|
||||
bcc.header.opcode = CMD_BLEND_CONSTANT_COLOR;
|
||||
bcc.header.length = sizeof(bcc)/4-2;
|
||||
bcc.blend_constant_color[0] = brw->attribs.BlendColor.color[0];
|
||||
bcc.blend_constant_color[1] = brw->attribs.BlendColor.color[1];
|
||||
bcc.blend_constant_color[2] = brw->attribs.BlendColor.color[2];
|
||||
bcc.blend_constant_color[3] = brw->attribs.BlendColor.color[3];
|
||||
|
||||
BRW_CACHED_BATCH_STRUCT(brw, &bcc);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Upload the binding table pointers, which point each stage's array of surface
|
||||
* state pointers.
|
||||
*
|
||||
* The binding table pointers are relative to the surface state base address,
|
||||
* which is the BRW_SS_POOL cache buffer.
|
||||
*/
|
||||
static void upload_binding_table_pointers(struct brw_context *brw)
|
||||
{
|
||||
struct brw_binding_table_pointers btp;
|
||||
memset(&btp, 0, sizeof(btp));
|
||||
|
||||
btp.header.opcode = CMD_BINDING_TABLE_PTRS;
|
||||
btp.header.length = sizeof(btp)/4 - 2;
|
||||
btp.vs = 0;
|
||||
btp.gs = 0;
|
||||
btp.clp = 0;
|
||||
btp.sf = 0;
|
||||
btp.wm = brw->wm.bind_ss_offset;
|
||||
|
||||
BRW_CACHED_BATCH_STRUCT(brw, &btp);
|
||||
}
|
||||
|
||||
const struct brw_tracked_state brw_binding_table_pointers = {
|
||||
.dirty = {
|
||||
.brw = 0,
|
||||
.cache = CACHE_NEW_SURF_BIND
|
||||
},
|
||||
.update = upload_binding_table_pointers,
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Upload pointers to the per-stage state.
|
||||
*
|
||||
* The state pointers in this packet are all relative to the general state
|
||||
* base address set by CMD_STATE_BASE_ADDRESS, which is the BRW_GS_POOL buffer.
|
||||
*/
|
||||
static void upload_pipelined_state_pointers(struct brw_context *brw )
|
||||
{
|
||||
struct brw_pipelined_state_pointers psp;
|
||||
memset(&psp, 0, sizeof(psp));
|
||||
|
||||
psp.header.opcode = CMD_PIPELINED_STATE_POINTERS;
|
||||
psp.header.length = sizeof(psp)/4 - 2;
|
||||
|
||||
psp.vs.offset = brw->vs.state_gs_offset >> 5;
|
||||
psp.sf.offset = brw->sf.state_gs_offset >> 5;
|
||||
psp.wm.offset = brw->wm.state_gs_offset >> 5;
|
||||
psp.cc.offset = brw->cc.state_gs_offset >> 5;
|
||||
|
||||
/* GS gets turned on and off regularly. Need to re-emit URB fence
|
||||
* after this occurs.
|
||||
*/
|
||||
if (brw->gs.prog_active) {
|
||||
psp.gs.offset = brw->gs.state_gs_offset >> 5;
|
||||
psp.gs.enable = 1;
|
||||
}
|
||||
|
||||
{
|
||||
psp.clp.offset = brw->clip.state_gs_offset >> 5;
|
||||
psp.clp.enable = 1;
|
||||
}
|
||||
|
||||
|
||||
if (BRW_CACHED_BATCH_STRUCT(brw, &psp))
|
||||
brw->state.dirty.brw |= BRW_NEW_PSP;
|
||||
}
|
||||
|
||||
const struct brw_tracked_state brw_pipelined_state_pointers = {
|
||||
.dirty = {
|
||||
.brw = 0,
|
||||
.cache = (CACHE_NEW_VS_UNIT |
|
||||
CACHE_NEW_GS_UNIT |
|
||||
CACHE_NEW_GS_PROG |
|
||||
CACHE_NEW_CLIP_UNIT |
|
||||
CACHE_NEW_SF_UNIT |
|
||||
CACHE_NEW_WM_UNIT |
|
||||
CACHE_NEW_CC_UNIT)
|
||||
},
|
||||
.update = upload_pipelined_state_pointers
|
||||
};
|
||||
|
||||
static void upload_psp_urb_cbs(struct brw_context *brw )
|
||||
{
|
||||
upload_pipelined_state_pointers(brw);
|
||||
brw_upload_urb_fence(brw);
|
||||
brw_upload_constant_buffer_state(brw);
|
||||
}
|
||||
|
||||
|
||||
const struct brw_tracked_state brw_psp_urb_cbs = {
|
||||
.dirty = {
|
||||
.brw = BRW_NEW_URB_FENCE,
|
||||
.cache = (CACHE_NEW_VS_UNIT |
|
||||
CACHE_NEW_GS_UNIT |
|
||||
CACHE_NEW_GS_PROG |
|
||||
CACHE_NEW_CLIP_UNIT |
|
||||
CACHE_NEW_SF_UNIT |
|
||||
CACHE_NEW_WM_UNIT |
|
||||
CACHE_NEW_CC_UNIT)
|
||||
},
|
||||
.update = upload_psp_urb_cbs
|
||||
};
|
||||
|
||||
/**
|
||||
* Upload the depthbuffer offset and format.
|
||||
*
|
||||
* We have to do this per state validation as we need to emit the relocation
|
||||
* in the batch buffer.
|
||||
*/
|
||||
static void upload_depthbuffer(struct brw_context *brw)
|
||||
{
|
||||
struct pipe_surface *depth_surface = brw->attribs.FrameBuffer.zbuf;
|
||||
|
||||
BEGIN_BATCH(5, INTEL_BATCH_NO_CLIPRECTS);
|
||||
OUT_BATCH(CMD_DEPTH_BUFFER << 16 | (5 - 2));
|
||||
if (depth_surface == NULL) {
|
||||
OUT_BATCH((BRW_DEPTHFORMAT_D32_FLOAT << 18) |
|
||||
(BRW_SURFACE_NULL << 29));
|
||||
OUT_BATCH(0);
|
||||
OUT_BATCH(0);
|
||||
OUT_BATCH(0);
|
||||
} else {
|
||||
unsigned int format;
|
||||
|
||||
switch (depth_surface->cpp) {
|
||||
case 2:
|
||||
format = BRW_DEPTHFORMAT_D16_UNORM;
|
||||
break;
|
||||
case 4:
|
||||
if (depth_surface->format == PIPE_FORMAT_Z32_FLOAT)
|
||||
format = BRW_DEPTHFORMAT_D32_FLOAT;
|
||||
else
|
||||
format = BRW_DEPTHFORMAT_D24_UNORM_S8_UINT;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
return;
|
||||
}
|
||||
|
||||
OUT_BATCH(((depth_surface->pitch * depth_surface->cpp) - 1) |
|
||||
(format << 18) |
|
||||
(BRW_TILEWALK_YMAJOR << 26) |
|
||||
#if 0
|
||||
(depth_surface->region->tiled << 27) |
|
||||
#endif
|
||||
(BRW_SURFACE_2D << 29));
|
||||
OUT_RELOC(depth_surface->buffer,
|
||||
PIPE_BUFFER_FLAG_READ | PIPE_BUFFER_FLAG_WRITE, 0);
|
||||
OUT_BATCH((BRW_SURFACE_MIPMAPLAYOUT_BELOW << 1) |
|
||||
((depth_surface->pitch - 1) << 6) |
|
||||
((depth_surface->height - 1) << 19));
|
||||
OUT_BATCH(0);
|
||||
}
|
||||
ADVANCE_BATCH();
|
||||
}
|
||||
|
||||
const struct brw_tracked_state brw_depthbuffer = {
|
||||
.dirty = {
|
||||
.brw = 0,
|
||||
.cache = 0
|
||||
},
|
||||
.update = upload_depthbuffer,
|
||||
};
|
||||
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Polygon stipple offset packet
|
||||
*/
|
||||
|
||||
static void upload_polygon_stipple_offset(struct brw_context *brw)
|
||||
{
|
||||
struct brw_polygon_stipple_offset bpso;
|
||||
|
||||
memset(&bpso, 0, sizeof(bpso));
|
||||
bpso.header.opcode = CMD_POLY_STIPPLE_OFFSET;
|
||||
bpso.header.length = sizeof(bpso)/4-2;
|
||||
|
||||
bpso.bits0.x_offset = 0;
|
||||
bpso.bits0.y_offset = 0;
|
||||
|
||||
BRW_CACHED_BATCH_STRUCT(brw, &bpso);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Polygon stipple packet
|
||||
*/
|
||||
|
||||
void brw_upload_polygon_stipple(struct brw_context *brw)
|
||||
{
|
||||
struct brw_polygon_stipple bps;
|
||||
unsigned i;
|
||||
|
||||
/*update the offset at the same time it will always be 0*/
|
||||
upload_polygon_stipple_offset(brw);
|
||||
memset(&bps, 0, sizeof(bps));
|
||||
bps.header.opcode = CMD_POLY_STIPPLE_PATTERN;
|
||||
bps.header.length = sizeof(bps)/4-2;
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
bps.stipple[i] = brw->attribs.PolygonStipple->stipple[31 - i]; /* invert */
|
||||
|
||||
BRW_CACHED_BATCH_STRUCT(brw, &bps);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Line stipple packet
|
||||
*/
|
||||
|
||||
void brw_upload_line_stipple(struct brw_context *brw)
|
||||
{
|
||||
struct brw_line_stipple bls;
|
||||
float tmp;
|
||||
int tmpi;
|
||||
|
||||
memset(&bls, 0, sizeof(bls));
|
||||
bls.header.opcode = CMD_LINE_STIPPLE_PATTERN;
|
||||
bls.header.length = sizeof(bls)/4 - 2;
|
||||
|
||||
bls.bits0.pattern = brw->attribs.Raster->line_stipple_pattern;
|
||||
bls.bits1.repeat_count = brw->attribs.Raster->line_stipple_factor;
|
||||
|
||||
tmp = 1.0 / (float) brw->attribs.Raster->line_stipple_factor;
|
||||
tmpi = tmp * (1<<13);
|
||||
|
||||
|
||||
bls.bits1.inverse_repeat_count = tmpi;
|
||||
|
||||
BRW_CACHED_BATCH_STRUCT(brw, &bls);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Misc constant state packets
|
||||
*/
|
||||
|
||||
static void upload_pipe_control(struct brw_context *brw)
|
||||
{
|
||||
struct brw_pipe_control pc;
|
||||
|
||||
return;
|
||||
|
||||
memset(&pc, 0, sizeof(pc));
|
||||
|
||||
pc.header.opcode = CMD_PIPE_CONTROL;
|
||||
pc.header.length = sizeof(pc)/4 - 2;
|
||||
pc.header.post_sync_operation = PIPE_CONTROL_NOWRITE;
|
||||
|
||||
pc.header.instruction_state_cache_flush_enable = 1;
|
||||
|
||||
pc.bits1.dest_addr_type = PIPE_CONTROL_GTTWRITE_GLOBAL;
|
||||
|
||||
BRW_BATCH_STRUCT(brw, &pc);
|
||||
}
|
||||
|
||||
const struct brw_tracked_state brw_pipe_control = {
|
||||
.dirty = {
|
||||
.brw = BRW_NEW_CONTEXT,
|
||||
.cache = 0
|
||||
},
|
||||
.update = upload_pipe_control
|
||||
};
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Misc invarient state packets
|
||||
*/
|
||||
|
||||
static void upload_invarient_state( struct brw_context *brw )
|
||||
{
|
||||
{
|
||||
/* 0x61040000 Pipeline Select */
|
||||
/* PipelineSelect : 0 */
|
||||
struct brw_pipeline_select ps;
|
||||
|
||||
memset(&ps, 0, sizeof(ps));
|
||||
ps.header.opcode = CMD_PIPELINE_SELECT;
|
||||
ps.header.pipeline_select = 0;
|
||||
BRW_BATCH_STRUCT(brw, &ps);
|
||||
}
|
||||
|
||||
{
|
||||
struct brw_global_depth_offset_clamp gdo;
|
||||
memset(&gdo, 0, sizeof(gdo));
|
||||
|
||||
/* Disable depth offset clamping.
|
||||
*/
|
||||
gdo.header.opcode = CMD_GLOBAL_DEPTH_OFFSET_CLAMP;
|
||||
gdo.header.length = sizeof(gdo)/4 - 2;
|
||||
gdo.depth_offset_clamp = 0.0;
|
||||
|
||||
BRW_BATCH_STRUCT(brw, &gdo);
|
||||
}
|
||||
|
||||
|
||||
/* 0x61020000 State Instruction Pointer */
|
||||
{
|
||||
struct brw_system_instruction_pointer sip;
|
||||
memset(&sip, 0, sizeof(sip));
|
||||
|
||||
sip.header.opcode = CMD_STATE_INSN_POINTER;
|
||||
sip.header.length = 0;
|
||||
sip.bits0.pad = 0;
|
||||
sip.bits0.system_instruction_pointer = 0;
|
||||
BRW_BATCH_STRUCT(brw, &sip);
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
struct brw_vf_statistics vfs;
|
||||
memset(&vfs, 0, sizeof(vfs));
|
||||
|
||||
vfs.opcode = CMD_VF_STATISTICS;
|
||||
if (BRW_DEBUG & DEBUG_STATS)
|
||||
vfs.statistics_enable = 1;
|
||||
|
||||
BRW_BATCH_STRUCT(brw, &vfs);
|
||||
}
|
||||
}
|
||||
|
||||
const struct brw_tracked_state brw_invarient_state = {
|
||||
.dirty = {
|
||||
.brw = BRW_NEW_CONTEXT,
|
||||
.cache = 0
|
||||
},
|
||||
.update = upload_invarient_state
|
||||
};
|
||||
|
||||
/**
|
||||
* Define the base addresses which some state is referenced from.
|
||||
*
|
||||
* This allows us to avoid having to emit relocations in many places for
|
||||
* cached state, and instead emit pointers inside of large, mostly-static
|
||||
* state pools. This comes at the expense of memory, and more expensive cache
|
||||
* misses.
|
||||
*/
|
||||
static void upload_state_base_address( struct brw_context *brw )
|
||||
{
|
||||
/* Output the structure (brw_state_base_address) directly to the
|
||||
* batchbuffer, so we can emit relocations inline.
|
||||
*/
|
||||
BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS);
|
||||
OUT_BATCH(CMD_STATE_BASE_ADDRESS << 16 | (6 - 2));
|
||||
OUT_RELOC(brw->pool[BRW_GS_POOL].buffer,
|
||||
PIPE_BUFFER_FLAG_READ,
|
||||
1); /* General state base address */
|
||||
OUT_RELOC(brw->pool[BRW_SS_POOL].buffer,
|
||||
PIPE_BUFFER_FLAG_READ,
|
||||
1); /* Surface state base address */
|
||||
OUT_BATCH(1); /* Indirect object base address */
|
||||
OUT_BATCH(1); /* General state upper bound */
|
||||
OUT_BATCH(1); /* Indirect object upper bound */
|
||||
ADVANCE_BATCH();
|
||||
}
|
||||
|
||||
|
||||
const struct brw_tracked_state brw_state_base_address = {
|
||||
.dirty = {
|
||||
.brw = BRW_NEW_CONTEXT,
|
||||
.cache = 0
|
||||
},
|
||||
.update = upload_state_base_address
|
||||
};
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
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_util.h"
|
||||
|
||||
#if 0
|
||||
static void brwBindProgram( GLcontext *ctx,
|
||||
int target,
|
||||
struct gl_program *prog )
|
||||
{
|
||||
struct brw_context *brw = brw_context(ctx);
|
||||
|
||||
switch (target) {
|
||||
case GL_VERTEX_PROGRAM_ARB:
|
||||
brw->state.dirty.brw |= BRW_NEW_VERTEX_PROGRAM;
|
||||
break;
|
||||
case GL_FRAGMENT_PROGRAM_ARB:
|
||||
brw->state.dirty.brw |= BRW_NEW_FRAGMENT_PROGRAM;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static struct gl_program *brwNewProgram( GLcontext *ctx,
|
||||
int target,
|
||||
unsigned id )
|
||||
{
|
||||
struct brw_context *brw = brw_context(ctx);
|
||||
|
||||
switch (target) {
|
||||
case GL_VERTEX_PROGRAM_ARB: {
|
||||
struct brw_vertex_program *prog = CALLOC_STRUCT(brw_vertex_program);
|
||||
if (prog) {
|
||||
prog->id = brw->program_id++;
|
||||
|
||||
return _mesa_init_vertex_program( ctx, &prog->program,
|
||||
target, id );
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
case GL_FRAGMENT_PROGRAM_ARB: {
|
||||
struct brw_fragment_program *prog = CALLOC_STRUCT(brw_fragment_program);
|
||||
if (prog) {
|
||||
prog->id = brw->program_id++;
|
||||
|
||||
return _mesa_init_fragment_program( ctx, &prog->program,
|
||||
target, id );
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
default:
|
||||
return _mesa_new_program(ctx, target, id);
|
||||
}
|
||||
}
|
||||
|
||||
static void brwDeleteProgram( GLcontext *ctx,
|
||||
struct gl_program *prog )
|
||||
{
|
||||
|
||||
_mesa_delete_program( ctx, prog );
|
||||
}
|
||||
|
||||
|
||||
static boolean brwIsProgramNative( GLcontext *ctx,
|
||||
int target,
|
||||
struct gl_program *prog )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void brwProgramStringNotify( GLcontext *ctx,
|
||||
int target,
|
||||
struct gl_program *prog )
|
||||
{
|
||||
if (target == GL_FRAGMENT_PROGRAM_ARB) {
|
||||
struct brw_context *brw = brw_context(ctx);
|
||||
struct brw_fragment_program *p = (struct brw_fragment_program *)prog;
|
||||
struct brw_fragment_program *fp = (struct brw_fragment_program *)brw->fragment_program;
|
||||
if (p == fp)
|
||||
brw->state.dirty.brw |= BRW_NEW_FRAGMENT_PROGRAM;
|
||||
p->id = brw->program_id++;
|
||||
p->param_state = p->program.Base.Parameters->StateFlags;
|
||||
}
|
||||
else if (target == GL_VERTEX_PROGRAM_ARB) {
|
||||
struct brw_context *brw = brw_context(ctx);
|
||||
struct brw_vertex_program *p = (struct brw_vertex_program *)prog;
|
||||
struct brw_vertex_program *vp = (struct brw_vertex_program *)brw->vertex_program;
|
||||
if (p == vp)
|
||||
brw->state.dirty.brw |= BRW_NEW_VERTEX_PROGRAM;
|
||||
p->id = brw->program_id++;
|
||||
p->param_state = p->program.Base.Parameters->StateFlags;
|
||||
|
||||
/* Also tell tnl about it:
|
||||
*/
|
||||
_tnl_program_string(ctx, target, prog);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,76 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* 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, sub license, 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 NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS 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.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#define CMD_MI (0x0 << 29)
|
||||
#define CMD_2D (0x2 << 29)
|
||||
#define CMD_3D (0x3 << 29)
|
||||
|
||||
#define MI_BATCH_BUFFER_END (CMD_MI | 0xA << 23)
|
||||
|
||||
/* Stalls command execution waiting for the given events to have occurred. */
|
||||
#define MI_WAIT_FOR_EVENT (CMD_MI | (0x3 << 23))
|
||||
#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6)
|
||||
#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2)
|
||||
|
||||
/* Primitive dispatch on 830-945 */
|
||||
#define _3DPRIMITIVE (CMD_3D | (0x1f << 24))
|
||||
#define PRIM_INDIRECT (1<<23)
|
||||
#define PRIM_INLINE (0<<23)
|
||||
#define PRIM_INDIRECT_SEQUENTIAL (0<<17)
|
||||
#define PRIM_INDIRECT_ELTS (1<<17)
|
||||
|
||||
#define PRIM3D_TRILIST (0x0<<18)
|
||||
#define PRIM3D_TRISTRIP (0x1<<18)
|
||||
#define PRIM3D_TRISTRIP_RVRSE (0x2<<18)
|
||||
#define PRIM3D_TRIFAN (0x3<<18)
|
||||
#define PRIM3D_POLY (0x4<<18)
|
||||
#define PRIM3D_LINELIST (0x5<<18)
|
||||
#define PRIM3D_LINESTRIP (0x6<<18)
|
||||
#define PRIM3D_RECTLIST (0x7<<18)
|
||||
#define PRIM3D_POINTLIST (0x8<<18)
|
||||
#define PRIM3D_DIB (0x9<<18)
|
||||
#define PRIM3D_MASK (0x1f<<18)
|
||||
|
||||
#define XY_SETUP_BLT_CMD (CMD_2D | (0x01 << 22) | 6)
|
||||
|
||||
#define XY_COLOR_BLT_CMD (CMD_2D | (0x50 << 22) | 4)
|
||||
|
||||
#define XY_SRC_COPY_BLT_CMD (CMD_2D | (0x53 << 22) | 6)
|
||||
|
||||
/* BR00 */
|
||||
#define XY_BLT_WRITE_ALPHA (1 << 21)
|
||||
#define XY_BLT_WRITE_RGB (1 << 20)
|
||||
#define XY_SRC_TILED (1 << 15)
|
||||
#define XY_DST_TILED (1 << 11)
|
||||
|
||||
/* BR13 */
|
||||
#define BR13_565 (0x1 << 24)
|
||||
#define BR13_8888 (0x3 << 24)
|
||||
|
||||
#define FENCE_LINEAR 0
|
||||
#define FENCE_XMAJOR 1
|
||||
#define FENCE_YMAJOR 2
|
||||
@@ -0,0 +1,39 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* 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, sub license, 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 NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS 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.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/* Provide additional functionality on top of bufmgr buffers:
|
||||
* - 2d semantics and blit operations (XXX: remove/simplify blits??)
|
||||
* - refcounting of buffers for multiple images in a buffer.
|
||||
* - refcounting of buffer mappings.
|
||||
*/
|
||||
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_winsys.h"
|
||||
#include "brw_context.h"
|
||||
#include "brw_blit.h"
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
#ifndef BRW_REGIONS_H
|
||||
#define BRW_REGIONS_H
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
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_defines.h"
|
||||
#include "brw_context.h"
|
||||
#include "brw_eu.h"
|
||||
#include "brw_util.h"
|
||||
#include "brw_sf.h"
|
||||
#include "brw_state.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 )
|
||||
{
|
||||
struct brw_sf_compile c;
|
||||
const unsigned *program;
|
||||
unsigned program_size;
|
||||
unsigned i, idx;
|
||||
|
||||
memset(&c, 0, sizeof(c));
|
||||
|
||||
/* Begin the compilation:
|
||||
*/
|
||||
brw_init_compile(&c.func);
|
||||
|
||||
c.key = *key;
|
||||
c.nr_attrs = brw_count_bits(c.key.attrs);
|
||||
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_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?
|
||||
*/
|
||||
switch (key->primitive) {
|
||||
case SF_TRIANGLES:
|
||||
c.nr_verts = 3;
|
||||
brw_emit_tri_setup( &c );
|
||||
break;
|
||||
case SF_LINES:
|
||||
c.nr_verts = 2;
|
||||
brw_emit_line_setup( &c );
|
||||
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 );
|
||||
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);
|
||||
|
||||
/* Upload
|
||||
*/
|
||||
brw->sf.prog_gs_offset = brw_upload_cache( &brw->cache[BRW_SF_PROG],
|
||||
&c.key,
|
||||
sizeof(c.key),
|
||||
program,
|
||||
program_size,
|
||||
&c.prog_data,
|
||||
&brw->sf.prog_data );
|
||||
}
|
||||
|
||||
|
||||
static boolean search_cache( struct brw_context *brw,
|
||||
struct brw_sf_prog_key *key )
|
||||
{
|
||||
return brw_search_cache(&brw->cache[BRW_SF_PROG],
|
||||
key, sizeof(*key),
|
||||
&brw->sf.prog_data,
|
||||
&brw->sf.prog_gs_offset);
|
||||
}
|
||||
|
||||
|
||||
/* Calculate interpolants for triangle and line rasterization.
|
||||
*/
|
||||
static void upload_sf_prog( struct brw_context *brw )
|
||||
{
|
||||
struct brw_sf_prog_key key;
|
||||
|
||||
memset(&key, 0, sizeof(key));
|
||||
|
||||
/* Populate the key, noting state dependencies:
|
||||
*/
|
||||
/* CACHE_NEW_VS_PROG */
|
||||
key.attrs = 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;
|
||||
break;
|
||||
case PIPE_PRIM_LINES:
|
||||
key.primitive = SF_LINES;
|
||||
break;
|
||||
case PIPE_PRIM_POINTS:
|
||||
key.primitive = SF_POINTS;
|
||||
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);
|
||||
|
||||
|
||||
if (!search_cache(brw, &key))
|
||||
compile_sf_prog( brw, &key );
|
||||
}
|
||||
|
||||
|
||||
const struct brw_tracked_state brw_sf_prog = {
|
||||
.dirty = {
|
||||
.brw = (BRW_NEW_RASTER |
|
||||
BRW_NEW_REDUCED_PRIMITIVE),
|
||||
.cache = CACHE_NEW_VS_PROG
|
||||
},
|
||||
.update = upload_sf_prog
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
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>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef BRW_SF_H
|
||||
#define BRW_SF_H
|
||||
|
||||
#include "brw_context.h"
|
||||
#include "brw_eu.h"
|
||||
|
||||
|
||||
#define SF_POINTS 0
|
||||
#define SF_LINES 1
|
||||
#define SF_TRIANGLES 2
|
||||
#define SF_UNFILLED_TRIS 3
|
||||
|
||||
struct brw_sf_prog_key {
|
||||
unsigned attrs:32;
|
||||
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;
|
||||
};
|
||||
|
||||
struct brw_sf_point_tex {
|
||||
boolean CoordReplace;
|
||||
};
|
||||
|
||||
struct brw_sf_compile {
|
||||
struct brw_compile func;
|
||||
struct brw_sf_prog_key key;
|
||||
struct brw_sf_prog_data prog_data;
|
||||
|
||||
struct brw_reg pv;
|
||||
struct brw_reg det;
|
||||
struct brw_reg dx0;
|
||||
struct brw_reg dx2;
|
||||
struct brw_reg dy0;
|
||||
struct brw_reg dy2;
|
||||
|
||||
/* z and 1/w passed in seperately:
|
||||
*/
|
||||
struct brw_reg z[3];
|
||||
struct brw_reg inv_w[3];
|
||||
|
||||
/* The vertices:
|
||||
*/
|
||||
struct brw_reg vert[3];
|
||||
|
||||
/* Temporaries, allocated after last vertex reg.
|
||||
*/
|
||||
struct brw_reg inv_det;
|
||||
struct brw_reg a1_sub_a0;
|
||||
struct brw_reg a2_sub_a0;
|
||||
struct brw_reg tmp;
|
||||
|
||||
struct brw_reg m1Cx;
|
||||
struct brw_reg m2Cy;
|
||||
struct brw_reg m3C0;
|
||||
|
||||
unsigned nr_verts;
|
||||
unsigned nr_attrs;
|
||||
unsigned nr_attr_regs;
|
||||
unsigned nr_setup_attrs;
|
||||
unsigned nr_setup_regs;
|
||||
#if 0
|
||||
ubyte attr_to_idx[VERT_RESULT_MAX];
|
||||
ubyte idx_to_attr[VERT_RESULT_MAX];
|
||||
struct brw_sf_point_tex point_attrs[VERT_RESULT_MAX];
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
void brw_emit_tri_setup( struct brw_sf_compile *c );
|
||||
void brw_emit_line_setup( struct brw_sf_compile *c );
|
||||
void brw_emit_point_setup( struct brw_sf_compile *c );
|
||||
void brw_emit_point_sprite_setup( struct brw_sf_compile *c );
|
||||
void brw_emit_anyprim_setup( struct brw_sf_compile *c );
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,696 @@
|
||||
/*
|
||||
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_defines.h"
|
||||
#include "brw_context.h"
|
||||
#include "brw_eu.h"
|
||||
#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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Triangle setup.
|
||||
*/
|
||||
|
||||
|
||||
static void alloc_regs( struct brw_sf_compile *c )
|
||||
{
|
||||
unsigned reg, i;
|
||||
|
||||
/* Values computed by fixed function unit:
|
||||
*/
|
||||
c->pv = retype(brw_vec1_grf(1, 1), BRW_REGISTER_TYPE_UD);
|
||||
c->det = brw_vec1_grf(1, 2);
|
||||
c->dx0 = brw_vec1_grf(1, 3);
|
||||
c->dx2 = brw_vec1_grf(1, 4);
|
||||
c->dy0 = brw_vec1_grf(1, 5);
|
||||
c->dy2 = brw_vec1_grf(1, 6);
|
||||
|
||||
/* z and 1/w passed in seperately:
|
||||
*/
|
||||
c->z[0] = brw_vec1_grf(2, 0);
|
||||
c->inv_w[0] = brw_vec1_grf(2, 1);
|
||||
c->z[1] = brw_vec1_grf(2, 2);
|
||||
c->inv_w[1] = brw_vec1_grf(2, 3);
|
||||
c->z[2] = brw_vec1_grf(2, 4);
|
||||
c->inv_w[2] = brw_vec1_grf(2, 5);
|
||||
|
||||
/* The vertices:
|
||||
*/
|
||||
reg = 3;
|
||||
for (i = 0; i < c->nr_verts; i++) {
|
||||
c->vert[i] = brw_vec8_grf(reg, 0);
|
||||
reg += c->nr_attr_regs;
|
||||
}
|
||||
|
||||
/* Temporaries, allocated after last vertex reg.
|
||||
*/
|
||||
c->inv_det = brw_vec1_grf(reg, 0); reg++;
|
||||
c->a1_sub_a0 = brw_vec8_grf(reg, 0); reg++;
|
||||
c->a2_sub_a0 = brw_vec8_grf(reg, 0); reg++;
|
||||
c->tmp = brw_vec8_grf(reg, 0); reg++;
|
||||
|
||||
/* Note grf allocation:
|
||||
*/
|
||||
c->prog_data.total_grf = reg;
|
||||
|
||||
|
||||
/* Outputs of this program - interpolation coefficients for
|
||||
* rasterization:
|
||||
*/
|
||||
c->m1Cx = brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, 1, 0);
|
||||
c->m2Cy = brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, 2, 0);
|
||||
c->m3C0 = brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, 3, 0);
|
||||
}
|
||||
|
||||
|
||||
static void copy_z_inv_w( struct brw_sf_compile *c )
|
||||
{
|
||||
struct brw_compile *p = &c->func;
|
||||
unsigned i;
|
||||
|
||||
brw_push_insn_state(p);
|
||||
|
||||
/* Copy both scalars with a single MOV:
|
||||
*/
|
||||
for (i = 0; i < c->nr_verts; i++)
|
||||
brw_MOV(p, vec2(suboffset(c->vert[i], 2)), vec2(c->z[i]));
|
||||
|
||||
brw_pop_insn_state(p);
|
||||
}
|
||||
|
||||
|
||||
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,
|
||||
BRW_MATH_SATURATE_NONE,
|
||||
0,
|
||||
c->det,
|
||||
BRW_MATH_DATA_SCALAR,
|
||||
BRW_MATH_PRECISION_FULL);
|
||||
|
||||
}
|
||||
|
||||
#define NON_PERPECTIVE_ATTRS (FRAG_BIT_WPOS | \
|
||||
FRAG_BIT_COL0 | \
|
||||
FRAG_BIT_COL1)
|
||||
|
||||
static boolean calculate_masks( struct brw_sf_compile *c,
|
||||
unsigned reg,
|
||||
ushort *pc,
|
||||
ushort *pc_persp,
|
||||
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 (linear_mask & (1 << c->idx_to_attr[reg*2]))
|
||||
*pc_linear = 0xf;
|
||||
|
||||
/* Maybe only processs one attribute on the final round:
|
||||
*/
|
||||
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 (linear_mask & (1 << c->idx_to_attr[reg*2+1]))
|
||||
*pc_linear |= 0xf0;
|
||||
}
|
||||
|
||||
return is_last_attr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void brw_emit_tri_setup( struct brw_sf_compile *c )
|
||||
{
|
||||
struct brw_compile *p = &c->func;
|
||||
unsigned i;
|
||||
|
||||
c->nr_verts = 3;
|
||||
alloc_regs(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++)
|
||||
{
|
||||
/* Pair of incoming attributes:
|
||||
*/
|
||||
struct brw_reg a0 = offset(c->vert[0], i);
|
||||
struct brw_reg a1 = offset(c->vert[1], i);
|
||||
struct brw_reg a2 = offset(c->vert[2], i);
|
||||
ushort pc, pc_persp, pc_linear;
|
||||
boolean last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear);
|
||||
|
||||
if (pc_persp)
|
||||
{
|
||||
brw_set_predicate_control_flag_value(p, pc_persp);
|
||||
brw_MUL(p, a0, a0, c->inv_w[0]);
|
||||
brw_MUL(p, a1, a1, c->inv_w[1]);
|
||||
brw_MUL(p, a2, a2, c->inv_w[2]);
|
||||
}
|
||||
|
||||
|
||||
/* Calculate coefficients for interpolated values:
|
||||
*/
|
||||
if (pc_linear)
|
||||
{
|
||||
brw_set_predicate_control_flag_value(p, pc_linear);
|
||||
|
||||
brw_ADD(p, c->a1_sub_a0, a1, negate(a0));
|
||||
brw_ADD(p, c->a2_sub_a0, a2, negate(a0));
|
||||
|
||||
/* calculate dA/dx
|
||||
*/
|
||||
brw_MUL(p, brw_null_reg(), c->a1_sub_a0, c->dy2);
|
||||
brw_MAC(p, c->tmp, c->a2_sub_a0, negate(c->dy0));
|
||||
brw_MUL(p, c->m1Cx, c->tmp, c->inv_det);
|
||||
|
||||
/* calculate dA/dy
|
||||
*/
|
||||
brw_MUL(p, brw_null_reg(), c->a2_sub_a0, c->dx0);
|
||||
brw_MAC(p, c->tmp, c->a1_sub_a0, negate(c->dx2));
|
||||
brw_MUL(p, c->m2Cy, c->tmp, c->inv_det);
|
||||
}
|
||||
|
||||
{
|
||||
brw_set_predicate_control_flag_value(p, pc);
|
||||
/* start point for interpolation
|
||||
*/
|
||||
brw_MOV(p, c->m3C0, a0);
|
||||
|
||||
/* Copy m0..m3 to URB. m0 is implicitly copied from r0 in
|
||||
* the send instruction:
|
||||
*/
|
||||
brw_urb_WRITE(p,
|
||||
brw_null_reg(),
|
||||
0,
|
||||
brw_vec8_grf(0, 0), /* r0, will be copied to m0 */
|
||||
0, /* allocate */
|
||||
1, /* used */
|
||||
4, /* msg len */
|
||||
0, /* response len */
|
||||
last, /* eot */
|
||||
last, /* writes complete */
|
||||
i*4, /* offset */
|
||||
BRW_URB_SWIZZLE_TRANSPOSE); /* XXX: Swizzle control "SF to windower" */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void brw_emit_line_setup( struct brw_sf_compile *c )
|
||||
{
|
||||
struct brw_compile *p = &c->func;
|
||||
unsigned i;
|
||||
|
||||
|
||||
c->nr_verts = 2;
|
||||
alloc_regs(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:
|
||||
*/
|
||||
struct brw_reg a0 = offset(c->vert[0], i);
|
||||
struct brw_reg a1 = offset(c->vert[1], i);
|
||||
ushort pc, pc_persp, pc_linear;
|
||||
boolean last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear);
|
||||
|
||||
if (pc_persp)
|
||||
{
|
||||
brw_set_predicate_control_flag_value(p, pc_persp);
|
||||
brw_MUL(p, a0, a0, c->inv_w[0]);
|
||||
brw_MUL(p, a1, a1, c->inv_w[1]);
|
||||
}
|
||||
|
||||
/* Calculate coefficients for position, color:
|
||||
*/
|
||||
if (pc_linear) {
|
||||
brw_set_predicate_control_flag_value(p, pc_linear);
|
||||
|
||||
brw_ADD(p, c->a1_sub_a0, a1, negate(a0));
|
||||
|
||||
brw_MUL(p, c->tmp, c->a1_sub_a0, c->dx0);
|
||||
brw_MUL(p, c->m1Cx, c->tmp, c->inv_det);
|
||||
|
||||
brw_MUL(p, c->tmp, c->a1_sub_a0, c->dy0);
|
||||
brw_MUL(p, c->m2Cy, c->tmp, c->inv_det);
|
||||
}
|
||||
|
||||
{
|
||||
brw_set_predicate_control_flag_value(p, pc);
|
||||
|
||||
/* start point for interpolation
|
||||
*/
|
||||
brw_MOV(p, c->m3C0, a0);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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!)
|
||||
*/
|
||||
void brw_emit_point_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);
|
||||
|
||||
brw_MOV(p, c->m1Cx, brw_imm_ud(0)); /* zero - move out of loop */
|
||||
brw_MOV(p, c->m2Cy, brw_imm_ud(0)); /* zero - move out of loop */
|
||||
|
||||
for (i = 0; i < c->nr_setup_regs; 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)
|
||||
{
|
||||
/* This seems odd as the values are all constant, but the
|
||||
* fragment shader will be expecting it:
|
||||
*/
|
||||
brw_set_predicate_control_flag_value(p, pc_persp);
|
||||
brw_MUL(p, a0, a0, c->inv_w[0]);
|
||||
}
|
||||
|
||||
|
||||
/* The delta values are always zero, just send the starting
|
||||
* coordinate. Again, this is to fit in with the interpolation
|
||||
* code in the fragment shader.
|
||||
*/
|
||||
{
|
||||
brw_set_predicate_control_flag_value(p, pc);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
@@ -0,0 +1,236 @@
|
||||
/*
|
||||
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_state.h"
|
||||
#include "brw_defines.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 */
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* _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);
|
||||
|
||||
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,
|
||||
.cache = 0
|
||||
},
|
||||
.update = upload_sf_vp
|
||||
};
|
||||
|
||||
static void upload_sf_unit( struct brw_context *brw )
|
||||
{
|
||||
struct brw_sf_unit_state sf;
|
||||
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.kernel_start_pointer = brw->sf.prog_gs_offset >> 6;
|
||||
sf.thread3.urb_entry_read_length = brw->sf.prog_data->urb_read_length;
|
||||
|
||||
sf.thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754;
|
||||
sf.thread3.dispatch_grf_start_reg = 3;
|
||||
sf.thread3.urb_entry_read_offset = 1;
|
||||
|
||||
/* BRW_NEW_URB_FENCE */
|
||||
sf.thread4.nr_urb_entries = brw->urb.nr_sf_entries;
|
||||
sf.thread4.urb_entry_allocation_size = brw->urb.sfsize - 1;
|
||||
sf.thread4.max_threads = MIN2(12, brw->urb.nr_sf_entries / 2) - 1;
|
||||
|
||||
if (BRW_DEBUG & DEBUG_SINGLE_THREAD)
|
||||
sf.thread4.max_threads = 0;
|
||||
|
||||
if (BRW_DEBUG & DEBUG_STATS)
|
||||
sf.thread4.stats_enable = 1;
|
||||
|
||||
/* 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)
|
||||
sf.sf6.scissor = 1;
|
||||
|
||||
/* _NEW_POLYGON */
|
||||
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:
|
||||
sf.sf6.cull_mode = BRW_CULLMODE_FRONT;
|
||||
break;
|
||||
case GL_BACK:
|
||||
sf.sf6.cull_mode = BRW_CULLMODE_BACK;
|
||||
break;
|
||||
case GL_FRONT_AND_BACK:
|
||||
sf.sf6.cull_mode = BRW_CULLMODE_BOTH;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
sf.sf6.cull_mode = BRW_CULLMODE_NONE;
|
||||
|
||||
|
||||
/* _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_endcap_aa_region_width = 1;
|
||||
if (brw->attribs.Line->SmoothFlag)
|
||||
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;
|
||||
|
||||
/* might be BRW_NEW_PRIMITIVE if we have to adjust pv for polygons:
|
||||
*/
|
||||
sf.sf7.trifan_pv = 2;
|
||||
sf.sf7.linestrip_pv = 1;
|
||||
sf.sf7.tristrip_pv = 2;
|
||||
sf.sf7.line_last_pixel_enable = 0;
|
||||
|
||||
/* Set bias for OpenGL rasterization rules:
|
||||
*/
|
||||
sf.sf6.dest_org_vbias = 0x8;
|
||||
sf.sf6.dest_org_hbias = 0x8;
|
||||
|
||||
brw->sf.state_gs_offset = brw_cache_data( &brw->cache[BRW_SF_UNIT], &sf );
|
||||
}
|
||||
|
||||
|
||||
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),
|
||||
.cache = (CACHE_NEW_SF_VP |
|
||||
CACHE_NEW_SF_PROG)
|
||||
},
|
||||
.update = upload_sf_unit
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,466 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* 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, sub license, 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 NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS 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: Zack Rusin <zack@tungstengraphics.com>
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "pipe/p_winsys.h"
|
||||
#include "pipe/p_util.h"
|
||||
#include "pipe/p_shader_tokens.h"
|
||||
#include "pipe/tgsi/util/tgsi_dump.h"
|
||||
|
||||
#include "brw_context.h"
|
||||
#include "brw_defines.h"
|
||||
#include "brw_state.h"
|
||||
#include "brw_draw.h"
|
||||
|
||||
|
||||
#define DUP( TYPE, VAL ) \
|
||||
do { \
|
||||
struct TYPE *x = malloc(sizeof(*x)); \
|
||||
memcpy(x, VAL, sizeof(*x) ); \
|
||||
return x; \
|
||||
} while (0)
|
||||
|
||||
/************************************************************************
|
||||
* Blend
|
||||
*/
|
||||
static void *
|
||||
brw_create_blend_state(struct pipe_context *pipe,
|
||||
const struct pipe_blend_state *blend)
|
||||
{
|
||||
DUP( pipe_blend_state, blend );
|
||||
}
|
||||
|
||||
static void brw_bind_blend_state(struct pipe_context *pipe,
|
||||
void *blend)
|
||||
{
|
||||
struct brw_context *brw = brw_context(pipe);
|
||||
|
||||
brw->attribs.Blend = (struct pipe_blend_state*)blend;
|
||||
brw->state.dirty.brw |= BRW_NEW_BLEND;
|
||||
}
|
||||
|
||||
|
||||
static void brw_delete_blend_state(struct pipe_context *pipe, void *blend)
|
||||
{
|
||||
free(blend);
|
||||
}
|
||||
|
||||
static void brw_set_blend_color( struct pipe_context *pipe,
|
||||
const struct pipe_blend_color *blend_color )
|
||||
{
|
||||
struct brw_context *brw = brw_context(pipe);
|
||||
|
||||
brw->attribs.BlendColor = *blend_color;
|
||||
|
||||
brw->state.dirty.brw |= BRW_NEW_BLEND;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Sampler
|
||||
*/
|
||||
|
||||
static void *
|
||||
brw_create_sampler_state(struct pipe_context *pipe,
|
||||
const struct pipe_sampler_state *sampler)
|
||||
{
|
||||
DUP( pipe_sampler_state, sampler );
|
||||
}
|
||||
|
||||
static void brw_bind_sampler_state(struct pipe_context *pipe,
|
||||
unsigned unit, void *sampler)
|
||||
{
|
||||
struct brw_context *brw = brw_context(pipe);
|
||||
|
||||
brw->attribs.Samplers[unit] = sampler;
|
||||
brw->state.dirty.brw |= BRW_NEW_SAMPLER;
|
||||
}
|
||||
|
||||
static void brw_delete_sampler_state(struct pipe_context *pipe,
|
||||
void *sampler)
|
||||
{
|
||||
free(sampler);
|
||||
}
|
||||
|
||||
|
||||
static void brw_set_sampler_units(struct pipe_context *pipe,
|
||||
uint numSamplers, const uint *units)
|
||||
{
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Depth stencil
|
||||
*/
|
||||
|
||||
static void *
|
||||
brw_create_depth_stencil_state(struct pipe_context *pipe,
|
||||
const struct pipe_depth_stencil_state *depth_stencil)
|
||||
{
|
||||
DUP( pipe_depth_stencil_state, depth_stencil );
|
||||
}
|
||||
|
||||
static void brw_bind_depth_stencil_state(struct pipe_context *pipe,
|
||||
void *depth_stencil)
|
||||
{
|
||||
struct brw_context *brw = brw_context(pipe);
|
||||
|
||||
brw->attribs.DepthStencil = (const struct pipe_depth_stencil_state *)depth_stencil;
|
||||
|
||||
brw->state.dirty.brw |= BRW_NEW_DEPTH_STENCIL;
|
||||
}
|
||||
|
||||
static void brw_delete_depth_stencil_state(struct pipe_context *pipe,
|
||||
void *depth_stencil)
|
||||
{
|
||||
free(depth_stencil);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Alpha test
|
||||
*/
|
||||
static void *
|
||||
brw_create_alpha_test_state(struct pipe_context *pipe,
|
||||
const struct pipe_alpha_test_state *alpha_test)
|
||||
{
|
||||
DUP(pipe_alpha_test_state, alpha_test);
|
||||
}
|
||||
|
||||
static void brw_bind_alpha_test_state(struct pipe_context *pipe,
|
||||
void *alpha)
|
||||
{
|
||||
struct brw_context *brw = brw_context(pipe);
|
||||
|
||||
brw->attribs.AlphaTest = (const struct pipe_alpha_test_state*)alpha;
|
||||
|
||||
brw->state.dirty.brw |= BRW_NEW_ALPHA_TEST;
|
||||
}
|
||||
|
||||
static void brw_delete_alpha_test_state(struct pipe_context *pipe,
|
||||
void *alpha)
|
||||
{
|
||||
free(alpha);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Scissor
|
||||
*/
|
||||
static void brw_set_scissor_state( struct pipe_context *pipe,
|
||||
const struct pipe_scissor_state *scissor )
|
||||
{
|
||||
struct brw_context *brw = brw_context(pipe);
|
||||
|
||||
memcpy( &brw->attribs.Scissor, scissor, sizeof(*scissor) );
|
||||
brw->state.dirty.brw |= BRW_NEW_SCISSOR;
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* Stipple
|
||||
*/
|
||||
|
||||
static void brw_set_polygon_stipple( struct pipe_context *pipe,
|
||||
const struct pipe_poly_stipple *stipple )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* Fragment shader
|
||||
*/
|
||||
|
||||
static void * brw_create_fs_state(struct pipe_context *pipe,
|
||||
const struct pipe_shader_state *shader)
|
||||
{
|
||||
struct brw_fragment_program *brw_fp = CALLOC_STRUCT(brw_fragment_program);
|
||||
|
||||
/* XXX: Do I have to duplicate the tokens as well??
|
||||
*/
|
||||
brw_fp->program = *shader;
|
||||
|
||||
return (void *)brw_fp;
|
||||
}
|
||||
|
||||
static void brw_bind_fs_state(struct pipe_context *pipe, void *shader)
|
||||
{
|
||||
struct brw_context *brw = brw_context(pipe);
|
||||
|
||||
brw->attribs.FragmentProgram = (struct brw_fragment_program *)shader;
|
||||
brw->state.dirty.brw |= BRW_NEW_FS;
|
||||
}
|
||||
|
||||
static void brw_delete_fs_state(struct pipe_context *pipe, void *shader)
|
||||
{
|
||||
FREE(shader);
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* Vertex shader and other TNL state
|
||||
*/
|
||||
|
||||
static void *brw_create_vs_state(struct pipe_context *pipe,
|
||||
const struct pipe_shader_state *shader)
|
||||
{
|
||||
struct brw_vertex_program *brw_vp = CALLOC_STRUCT(brw_vertex_program);
|
||||
|
||||
/* XXX: Do I have to duplicate the tokens as well??
|
||||
*/
|
||||
brw_vp->program = *shader;
|
||||
|
||||
tgsi_dump(shader->tokens, 0);
|
||||
|
||||
return (void *)brw_vp;
|
||||
}
|
||||
|
||||
static void brw_bind_vs_state(struct pipe_context *pipe, void *vs)
|
||||
{
|
||||
struct brw_context *brw = brw_context(pipe);
|
||||
|
||||
brw->attribs.VertexProgram = (struct brw_vertex_program *)vs;
|
||||
brw->state.dirty.brw |= BRW_NEW_VS;
|
||||
|
||||
printf("YYYYYYYYYYYYY BINDING VERTEX SHADER\n");
|
||||
}
|
||||
|
||||
static void brw_delete_vs_state(struct pipe_context *pipe, void *shader)
|
||||
{
|
||||
FREE(shader);
|
||||
}
|
||||
|
||||
|
||||
static void brw_set_clip_state( struct pipe_context *pipe,
|
||||
const struct pipe_clip_state *clip )
|
||||
{
|
||||
struct brw_context *brw = brw_context(pipe);
|
||||
|
||||
brw->attribs.Clip = *clip;
|
||||
}
|
||||
|
||||
|
||||
static void brw_set_viewport_state( struct pipe_context *pipe,
|
||||
const struct pipe_viewport_state *viewport )
|
||||
{
|
||||
struct brw_context *brw = brw_context(pipe);
|
||||
|
||||
brw->attribs.Viewport = *viewport; /* struct copy */
|
||||
brw->state.dirty.brw |= BRW_NEW_VIEWPORT;
|
||||
|
||||
/* pass the viewport info to the draw module */
|
||||
//draw_set_viewport_state(brw->draw, viewport);
|
||||
}
|
||||
|
||||
|
||||
static void brw_set_vertex_buffer( struct pipe_context *pipe,
|
||||
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);
|
||||
}
|
||||
|
||||
static void brw_set_vertex_element(struct pipe_context *pipe,
|
||||
unsigned index,
|
||||
const struct pipe_vertex_element *element)
|
||||
{
|
||||
/* flush ? */
|
||||
struct brw_context *brw = brw_context(pipe);
|
||||
|
||||
assert(index < PIPE_ATTRIB_MAX);
|
||||
struct brw_vertex_element el;
|
||||
memset(&el, 0, sizeof(struct brw_vertex_element));
|
||||
|
||||
/* do we need those anymore?*/
|
||||
el.index = index;
|
||||
#if 0
|
||||
/*FIXME*/
|
||||
el.element_size = 0;
|
||||
el.count = 0;
|
||||
el.vbo_rebase_offset = 0;
|
||||
#endif
|
||||
|
||||
el.vep.ve0.src_offset = element->src_offset;
|
||||
el.vep.ve0.src_format = brw_translate_surface_format(element->src_format);
|
||||
el.vep.ve0.valid = 1;
|
||||
el.vep.ve0.vertex_buffer_index = element->vertex_buffer_index;
|
||||
|
||||
el.vep.ve1.dst_offset = element->dst_offset;
|
||||
el.vep.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_SRC;
|
||||
el.vep.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_SRC;
|
||||
el.vep.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_SRC;
|
||||
el.vep.ve1.vfcomponent0 = BRW_VFCOMPONENT_STORE_SRC;
|
||||
/*can we count of brw->vb.vbo_array[element->vertex_buffer_index]
|
||||
* being initialized ok to actually compute vbcomponent's
|
||||
* correctly? */
|
||||
|
||||
brw->vb.inputs[index] = el;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* Constant buffers
|
||||
*/
|
||||
|
||||
static void brw_set_constant_buffer(struct pipe_context *pipe,
|
||||
uint shader, uint index,
|
||||
const struct pipe_constant_buffer *buf)
|
||||
{
|
||||
struct brw_context *brw = brw_context(pipe);
|
||||
|
||||
assert(buf == 0 || index == 0);
|
||||
|
||||
brw->attribs.Constants[shader] = buf;
|
||||
brw->state.dirty.brw |= BRW_NEW_CONSTANTS;
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* Texture surfaces
|
||||
*/
|
||||
|
||||
|
||||
static void brw_set_texture_state(struct pipe_context *pipe,
|
||||
unsigned unit,
|
||||
struct pipe_texture *texture)
|
||||
{
|
||||
struct brw_context *brw = brw_context(pipe);
|
||||
|
||||
brw->attribs.Texture[unit] = (struct brw_texture*)texture; /* ptr, not struct */
|
||||
|
||||
brw->state.dirty.brw |= BRW_NEW_TEXTURE;
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* Render targets, etc
|
||||
*/
|
||||
|
||||
static void brw_set_framebuffer_state(struct pipe_context *pipe,
|
||||
const struct pipe_framebuffer_state *fb)
|
||||
{
|
||||
struct brw_context *brw = brw_context(pipe);
|
||||
|
||||
brw->attribs.FrameBuffer = *fb; /* struct copy */
|
||||
|
||||
brw->state.dirty.brw |= BRW_NEW_FRAMEBUFFER;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void brw_set_clear_color_state(struct pipe_context *pipe,
|
||||
const struct pipe_clear_color_state *clear)
|
||||
{
|
||||
struct brw_context *brw = brw_context(pipe);
|
||||
|
||||
brw->attribs.ClearColor = *clear; /* struct copy */
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Rasterizer state
|
||||
*/
|
||||
|
||||
static void *
|
||||
brw_create_rasterizer_state(struct pipe_context *pipe,
|
||||
const struct pipe_rasterizer_state *rasterizer)
|
||||
{
|
||||
DUP(pipe_rasterizer_state, rasterizer);
|
||||
}
|
||||
|
||||
static void brw_bind_rasterizer_state( struct pipe_context *pipe,
|
||||
void *setup )
|
||||
{
|
||||
struct brw_context *brw = brw_context(pipe);
|
||||
|
||||
brw->attribs.Raster = (struct pipe_rasterizer_state *)setup;
|
||||
|
||||
/* Also pass-through to draw module:
|
||||
*/
|
||||
//draw_set_rasterizer_state(brw->draw, setup);
|
||||
|
||||
brw->state.dirty.brw |= BRW_NEW_RASTERIZER;
|
||||
}
|
||||
|
||||
static void brw_delete_rasterizer_state(struct pipe_context *pipe,
|
||||
void *setup)
|
||||
{
|
||||
free(setup);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
brw_init_state_functions( struct brw_context *brw )
|
||||
{
|
||||
brw->pipe.create_alpha_test_state = brw_create_alpha_test_state;
|
||||
brw->pipe.bind_alpha_test_state = brw_bind_alpha_test_state;
|
||||
brw->pipe.delete_alpha_test_state = brw_delete_alpha_test_state;
|
||||
|
||||
brw->pipe.create_blend_state = brw_create_blend_state;
|
||||
brw->pipe.bind_blend_state = brw_bind_blend_state;
|
||||
brw->pipe.delete_blend_state = brw_delete_blend_state;
|
||||
|
||||
brw->pipe.create_sampler_state = brw_create_sampler_state;
|
||||
brw->pipe.bind_sampler_state = brw_bind_sampler_state;
|
||||
brw->pipe.delete_sampler_state = brw_delete_sampler_state;
|
||||
|
||||
brw->pipe.create_depth_stencil_state = brw_create_depth_stencil_state;
|
||||
brw->pipe.bind_depth_stencil_state = brw_bind_depth_stencil_state;
|
||||
brw->pipe.delete_depth_stencil_state = brw_delete_depth_stencil_state;
|
||||
|
||||
brw->pipe.create_rasterizer_state = brw_create_rasterizer_state;
|
||||
brw->pipe.bind_rasterizer_state = brw_bind_rasterizer_state;
|
||||
brw->pipe.delete_rasterizer_state = brw_delete_rasterizer_state;
|
||||
brw->pipe.create_fs_state = brw_create_fs_state;
|
||||
brw->pipe.bind_fs_state = brw_bind_fs_state;
|
||||
brw->pipe.delete_fs_state = brw_delete_fs_state;
|
||||
brw->pipe.create_vs_state = brw_create_vs_state;
|
||||
brw->pipe.bind_vs_state = brw_bind_vs_state;
|
||||
brw->pipe.delete_vs_state = brw_delete_vs_state;
|
||||
|
||||
brw->pipe.set_blend_color = brw_set_blend_color;
|
||||
brw->pipe.set_clip_state = brw_set_clip_state;
|
||||
brw->pipe.set_clear_color_state = brw_set_clear_color_state;
|
||||
brw->pipe.set_constant_buffer = brw_set_constant_buffer;
|
||||
brw->pipe.set_framebuffer_state = brw_set_framebuffer_state;
|
||||
|
||||
// brw->pipe.set_feedback_state = brw_set_feedback_state;
|
||||
// brw->pipe.set_feedback_buffer = brw_set_feedback_buffer;
|
||||
|
||||
brw->pipe.set_polygon_stipple = brw_set_polygon_stipple;
|
||||
brw->pipe.set_sampler_units = brw_set_sampler_units;
|
||||
brw->pipe.set_scissor_state = brw_set_scissor_state;
|
||||
brw->pipe.set_texture_state = brw_set_texture_state;
|
||||
brw->pipe.set_viewport_state = brw_set_viewport_state;
|
||||
brw->pipe.set_vertex_buffer = brw_set_vertex_buffer;
|
||||
brw->pipe.set_vertex_element = brw_set_vertex_element;
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
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>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef BRW_STATE_H
|
||||
#define BRW_STATE_H
|
||||
|
||||
#include "brw_context.h"
|
||||
#include "brw_winsys.h"
|
||||
|
||||
|
||||
const struct brw_tracked_state brw_blend_constant_color;
|
||||
const struct brw_tracked_state brw_cc_unit;
|
||||
const struct brw_tracked_state brw_cc_vp;
|
||||
const struct brw_tracked_state brw_clip_prog;
|
||||
const struct brw_tracked_state brw_clip_unit;
|
||||
const struct brw_tracked_state brw_constant_buffer_state;
|
||||
const struct brw_tracked_state brw_constant_buffer;
|
||||
const struct brw_tracked_state brw_curbe_offsets;
|
||||
const struct brw_tracked_state brw_invarient_state;
|
||||
const struct brw_tracked_state brw_gs_prog;
|
||||
const struct brw_tracked_state brw_gs_unit;
|
||||
const struct brw_tracked_state brw_drawing_rect;
|
||||
const struct brw_tracked_state brw_line_stipple;
|
||||
const struct brw_tracked_state brw_pipelined_state_pointers;
|
||||
const struct brw_tracked_state brw_binding_table_pointers;
|
||||
const struct brw_tracked_state brw_depthbuffer;
|
||||
const struct brw_tracked_state brw_polygon_stipple_offset;
|
||||
const struct brw_tracked_state brw_polygon_stipple;
|
||||
const struct brw_tracked_state brw_program_parameters;
|
||||
const struct brw_tracked_state brw_recalculate_urb_fence;
|
||||
const struct brw_tracked_state brw_sf_prog;
|
||||
const struct brw_tracked_state brw_sf_unit;
|
||||
const struct brw_tracked_state brw_sf_vp;
|
||||
const struct brw_tracked_state brw_state_base_address;
|
||||
const struct brw_tracked_state brw_urb_fence;
|
||||
const struct brw_tracked_state brw_vertex_state;
|
||||
const struct brw_tracked_state brw_vs_prog;
|
||||
const struct brw_tracked_state brw_vs_unit;
|
||||
const struct brw_tracked_state brw_wm_input_sizes;
|
||||
const struct brw_tracked_state brw_wm_prog;
|
||||
const struct brw_tracked_state brw_wm_samplers;
|
||||
const struct brw_tracked_state brw_wm_surfaces;
|
||||
const struct brw_tracked_state brw_wm_unit;
|
||||
|
||||
const struct brw_tracked_state brw_psp_urb_cbs;
|
||||
|
||||
const struct brw_tracked_state brw_active_vertprog;
|
||||
const struct brw_tracked_state brw_tnl_vertprog;
|
||||
const struct brw_tracked_state brw_pipe_control;
|
||||
|
||||
const struct brw_tracked_state brw_clear_surface_cache;
|
||||
const struct brw_tracked_state brw_clear_batch_cache;
|
||||
|
||||
/***********************************************************************
|
||||
* brw_state_cache.c
|
||||
*/
|
||||
unsigned brw_cache_data(struct brw_cache *cache,
|
||||
const void *data );
|
||||
|
||||
unsigned brw_cache_data_sz(struct brw_cache *cache,
|
||||
const void *data,
|
||||
unsigned data_sz);
|
||||
|
||||
unsigned brw_upload_cache( struct brw_cache *cache,
|
||||
const void *key,
|
||||
unsigned key_sz,
|
||||
const void *data,
|
||||
unsigned data_sz,
|
||||
const void *aux,
|
||||
void *aux_return );
|
||||
|
||||
boolean brw_search_cache( struct brw_cache *cache,
|
||||
const void *key,
|
||||
unsigned key_size,
|
||||
void *aux_return,
|
||||
unsigned *offset_return);
|
||||
|
||||
void brw_init_caches( struct brw_context *brw );
|
||||
void brw_destroy_caches( struct brw_context *brw );
|
||||
|
||||
static inline struct pipe_buffer_handle *brw_cache_buffer(struct brw_context *brw,
|
||||
enum brw_cache_id id)
|
||||
{
|
||||
return brw->cache[id].pool->buffer;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* brw_state_batch.c
|
||||
*/
|
||||
#define BRW_BATCH_STRUCT(brw, s) brw_batchbuffer_data( brw->winsys, (s), sizeof(*(s)))
|
||||
#define BRW_CACHED_BATCH_STRUCT(brw, s) brw_cached_batch_struct( brw, (s), sizeof(*(s)) )
|
||||
|
||||
boolean brw_cached_batch_struct( struct brw_context *brw,
|
||||
const void *data,
|
||||
unsigned sz );
|
||||
|
||||
void brw_destroy_batch_cache( struct brw_context *brw );
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* brw_state_pool.c
|
||||
*/
|
||||
void brw_init_pools( struct brw_context *brw );
|
||||
void brw_destroy_pools( struct brw_context *brw );
|
||||
|
||||
boolean brw_pool_alloc( struct brw_mem_pool *pool,
|
||||
unsigned size,
|
||||
unsigned alignment,
|
||||
unsigned *offset_return);
|
||||
|
||||
void brw_pool_fence( struct brw_context *brw,
|
||||
struct brw_mem_pool *pool,
|
||||
unsigned fence );
|
||||
|
||||
|
||||
void brw_pool_check_wrap( struct brw_context *brw,
|
||||
struct brw_mem_pool *pool );
|
||||
|
||||
void brw_clear_all_caches( struct brw_context *brw );
|
||||
void brw_invalidate_pools( struct brw_context *brw );
|
||||
void brw_clear_batch_cache_flush( struct brw_context *brw );
|
||||
|
||||
void brw_upload_cc_unit(struct brw_context *brw);
|
||||
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);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
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_state.h"
|
||||
#include "brw_winsys.h"
|
||||
|
||||
#include "pipe/p_util.h"
|
||||
|
||||
/* A facility similar to the data caching code above, which aims to
|
||||
* prevent identical commands being issued repeatedly.
|
||||
*/
|
||||
boolean brw_cached_batch_struct( struct brw_context *brw,
|
||||
const void *data,
|
||||
unsigned sz )
|
||||
{
|
||||
struct brw_cached_batch_item *item = brw->cached_batch_items;
|
||||
struct header *newheader = (struct header *)data;
|
||||
|
||||
if (brw->emit_state_always) {
|
||||
brw_batchbuffer_data(brw->winsys, data, sz);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
while (item) {
|
||||
if (item->header->opcode == newheader->opcode) {
|
||||
if (item->sz == sz && memcmp(item->header, newheader, sz) == 0)
|
||||
return FALSE;
|
||||
if (item->sz != sz) {
|
||||
FREE(item->header);
|
||||
item->header = MALLOC(sz);
|
||||
item->sz = sz;
|
||||
}
|
||||
goto emit;
|
||||
}
|
||||
item = item->next;
|
||||
}
|
||||
|
||||
assert(!item);
|
||||
item = CALLOC_STRUCT(brw_cached_batch_item);
|
||||
item->header = MALLOC(sz);
|
||||
item->sz = sz;
|
||||
item->next = brw->cached_batch_items;
|
||||
brw->cached_batch_items = item;
|
||||
|
||||
emit:
|
||||
memcpy(item->header, newheader, sz);
|
||||
brw_batchbuffer_data(brw->winsys, data, sz);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void clear_batch_cache( struct brw_context *brw )
|
||||
{
|
||||
struct brw_cached_batch_item *item = brw->cached_batch_items;
|
||||
|
||||
while (item) {
|
||||
struct brw_cached_batch_item *next = item->next;
|
||||
free((void *)item->header);
|
||||
free(item);
|
||||
item = next;
|
||||
}
|
||||
|
||||
brw->cached_batch_items = NULL;
|
||||
|
||||
|
||||
brw_clear_all_caches(brw);
|
||||
|
||||
brw_invalidate_pools(brw);
|
||||
}
|
||||
|
||||
void brw_clear_batch_cache_flush( struct brw_context *brw )
|
||||
{
|
||||
clear_batch_cache(brw);
|
||||
|
||||
/* brw_do_flush(brw, BRW_FLUSH_STATE_CACHE|BRW_FLUSH_READ_CACHE); */
|
||||
|
||||
brw->state.dirty.brw |= ~0;
|
||||
brw->state.dirty.cache |= ~0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void brw_destroy_batch_cache( struct brw_context *brw )
|
||||
{
|
||||
clear_batch_cache(brw);
|
||||
}
|
||||
@@ -0,0 +1,442 @@
|
||||
/*
|
||||
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_state.h"
|
||||
|
||||
#include "brw_wm.h"
|
||||
#include "brw_vs.h"
|
||||
#include "brw_clip.h"
|
||||
#include "brw_sf.h"
|
||||
#include "brw_gs.h"
|
||||
|
||||
#include "pipe/p_util.h"
|
||||
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Check cache for uploaded version of struct, else upload new one.
|
||||
* Fail when memory is exhausted.
|
||||
*
|
||||
* XXX: FIXME: Currently search is so slow it would be quicker to
|
||||
* regenerate the data every time...
|
||||
*/
|
||||
|
||||
static unsigned hash_key( const void *key, unsigned key_size )
|
||||
{
|
||||
unsigned *ikey = (unsigned *)key;
|
||||
unsigned hash = 0, i;
|
||||
|
||||
assert(key_size % 4 == 0);
|
||||
|
||||
/* I'm sure this can be improved on:
|
||||
*/
|
||||
for (i = 0; i < key_size/4; i++)
|
||||
hash ^= ikey[i];
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
static struct brw_cache_item *search_cache( struct brw_cache *cache,
|
||||
unsigned hash,
|
||||
const void *key,
|
||||
unsigned key_size)
|
||||
{
|
||||
struct brw_cache_item *c;
|
||||
|
||||
for (c = cache->items[hash % cache->size]; c; c = c->next) {
|
||||
if (c->hash == hash &&
|
||||
c->key_size == key_size &&
|
||||
memcmp(c->key, key, key_size) == 0)
|
||||
return c;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static void rehash( struct brw_cache *cache )
|
||||
{
|
||||
struct brw_cache_item **items;
|
||||
struct brw_cache_item *c, *next;
|
||||
unsigned size, i;
|
||||
|
||||
size = cache->size * 3;
|
||||
items = (struct brw_cache_item**) MALLOC(size * sizeof(*items));
|
||||
memset(items, 0, size * sizeof(*items));
|
||||
|
||||
for (i = 0; i < cache->size; i++)
|
||||
for (c = cache->items[i]; c; c = next) {
|
||||
next = c->next;
|
||||
c->next = items[c->hash % size];
|
||||
items[c->hash % size] = c;
|
||||
}
|
||||
|
||||
FREE(cache->items);
|
||||
cache->items = items;
|
||||
cache->size = size;
|
||||
}
|
||||
|
||||
|
||||
boolean brw_search_cache( struct brw_cache *cache,
|
||||
const void *key,
|
||||
unsigned key_size,
|
||||
void *aux_return,
|
||||
unsigned *offset_return)
|
||||
{
|
||||
struct brw_cache_item *item;
|
||||
unsigned addr = 0;
|
||||
unsigned hash = hash_key(key, key_size);
|
||||
|
||||
item = search_cache(cache, hash, key, key_size);
|
||||
|
||||
if (item) {
|
||||
if (aux_return)
|
||||
*(void **)aux_return = (void *)((char *)item->key + item->key_size);
|
||||
|
||||
*offset_return = addr = item->offset;
|
||||
}
|
||||
|
||||
if (item == NULL || addr != cache->last_addr) {
|
||||
cache->brw->state.dirty.cache |= 1<<cache->id;
|
||||
cache->last_addr = addr;
|
||||
}
|
||||
|
||||
return item != NULL;
|
||||
}
|
||||
|
||||
unsigned brw_upload_cache( struct brw_cache *cache,
|
||||
const void *key,
|
||||
unsigned key_size,
|
||||
const void *data,
|
||||
unsigned data_size,
|
||||
const void *aux,
|
||||
void *aux_return )
|
||||
{
|
||||
unsigned offset;
|
||||
struct brw_cache_item *item = CALLOC_STRUCT(brw_cache_item);
|
||||
unsigned hash = hash_key(key, key_size);
|
||||
void *tmp = MALLOC(key_size + cache->aux_size);
|
||||
|
||||
if (!brw_pool_alloc(cache->pool, data_size, 1 << 6, &offset)) {
|
||||
/* Should not be possible:
|
||||
*/
|
||||
printf("brw_pool_alloc failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memcpy(tmp, key, key_size);
|
||||
|
||||
if (cache->aux_size)
|
||||
memcpy(tmp+key_size, aux, cache->aux_size);
|
||||
|
||||
item->key = tmp;
|
||||
item->hash = hash;
|
||||
item->key_size = key_size;
|
||||
item->offset = offset;
|
||||
item->data_size = data_size;
|
||||
|
||||
if (++cache->n_items > cache->size * 1.5)
|
||||
rehash(cache);
|
||||
|
||||
hash %= cache->size;
|
||||
item->next = cache->items[hash];
|
||||
cache->items[hash] = item;
|
||||
|
||||
if (aux_return) {
|
||||
assert(cache->aux_size);
|
||||
*(void **)aux_return = (void *)((char *)item->key + item->key_size);
|
||||
}
|
||||
|
||||
if (BRW_DEBUG & DEBUG_STATE)
|
||||
printf("upload %s: %d bytes to pool buffer %p offset %x\n",
|
||||
cache->name, data_size,
|
||||
cache->pool->buffer,
|
||||
offset);
|
||||
|
||||
/* Copy data to the buffer:
|
||||
*/
|
||||
cache->brw->winsys->buffer_subdata_typed(cache->brw->winsys,
|
||||
cache->pool->buffer,
|
||||
offset,
|
||||
data_size,
|
||||
data,
|
||||
cache->id);
|
||||
|
||||
cache->brw->state.dirty.cache |= 1<<cache->id;
|
||||
cache->last_addr = offset;
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
/* This doesn't really work with aux data. Use search/upload instead
|
||||
*/
|
||||
unsigned brw_cache_data_sz(struct brw_cache *cache,
|
||||
const void *data,
|
||||
unsigned data_size)
|
||||
{
|
||||
unsigned addr;
|
||||
|
||||
if (!brw_search_cache(cache, data, data_size, NULL, &addr)) {
|
||||
addr = brw_upload_cache(cache,
|
||||
data, data_size,
|
||||
data, data_size,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
unsigned brw_cache_data(struct brw_cache *cache,
|
||||
const void *data)
|
||||
{
|
||||
return brw_cache_data_sz(cache, data, cache->key_size);
|
||||
}
|
||||
|
||||
enum pool_type {
|
||||
DW_SURFACE_STATE,
|
||||
DW_GENERAL_STATE
|
||||
};
|
||||
|
||||
static void brw_init_cache( struct brw_context *brw,
|
||||
const char *name,
|
||||
unsigned id,
|
||||
unsigned key_size,
|
||||
unsigned aux_size,
|
||||
enum pool_type pool_type)
|
||||
{
|
||||
struct brw_cache *cache = &brw->cache[id];
|
||||
cache->brw = brw;
|
||||
cache->id = id;
|
||||
cache->name = name;
|
||||
cache->items = NULL;
|
||||
|
||||
cache->size = 7;
|
||||
cache->n_items = 0;
|
||||
cache->items = (struct brw_cache_item **)
|
||||
CALLOC(cache->size, sizeof(struct brw_cache_item));
|
||||
|
||||
|
||||
cache->key_size = key_size;
|
||||
cache->aux_size = aux_size;
|
||||
switch (pool_type) {
|
||||
case DW_GENERAL_STATE: cache->pool = &brw->pool[BRW_GS_POOL]; break;
|
||||
case DW_SURFACE_STATE: cache->pool = &brw->pool[BRW_SS_POOL]; break;
|
||||
default: assert(0); break;
|
||||
}
|
||||
}
|
||||
|
||||
void brw_init_caches( struct brw_context *brw )
|
||||
{
|
||||
|
||||
brw_init_cache(brw,
|
||||
"CC_VP",
|
||||
BRW_CC_VP,
|
||||
sizeof(struct brw_cc_viewport),
|
||||
0,
|
||||
DW_GENERAL_STATE);
|
||||
|
||||
brw_init_cache(brw,
|
||||
"CC_UNIT",
|
||||
BRW_CC_UNIT,
|
||||
sizeof(struct brw_cc_unit_state),
|
||||
0,
|
||||
DW_GENERAL_STATE);
|
||||
|
||||
brw_init_cache(brw,
|
||||
"WM_PROG",
|
||||
BRW_WM_PROG,
|
||||
sizeof(struct brw_wm_prog_key),
|
||||
sizeof(struct brw_wm_prog_data),
|
||||
DW_GENERAL_STATE);
|
||||
|
||||
brw_init_cache(brw,
|
||||
"SAMPLER_DEFAULT_COLOR",
|
||||
BRW_SAMPLER_DEFAULT_COLOR,
|
||||
sizeof(struct brw_sampler_default_color),
|
||||
0,
|
||||
DW_GENERAL_STATE);
|
||||
|
||||
brw_init_cache(brw,
|
||||
"SAMPLER",
|
||||
BRW_SAMPLER,
|
||||
0, /* variable key/data size */
|
||||
0,
|
||||
DW_GENERAL_STATE);
|
||||
|
||||
brw_init_cache(brw,
|
||||
"WM_UNIT",
|
||||
BRW_WM_UNIT,
|
||||
sizeof(struct brw_wm_unit_state),
|
||||
0,
|
||||
DW_GENERAL_STATE);
|
||||
|
||||
brw_init_cache(brw,
|
||||
"SF_PROG",
|
||||
BRW_SF_PROG,
|
||||
sizeof(struct brw_sf_prog_key),
|
||||
sizeof(struct brw_sf_prog_data),
|
||||
DW_GENERAL_STATE);
|
||||
|
||||
brw_init_cache(brw,
|
||||
"SF_VP",
|
||||
BRW_SF_VP,
|
||||
sizeof(struct brw_sf_viewport),
|
||||
0,
|
||||
DW_GENERAL_STATE);
|
||||
|
||||
brw_init_cache(brw,
|
||||
"SF_UNIT",
|
||||
BRW_SF_UNIT,
|
||||
sizeof(struct brw_sf_unit_state),
|
||||
0,
|
||||
DW_GENERAL_STATE);
|
||||
|
||||
brw_init_cache(brw,
|
||||
"VS_UNIT",
|
||||
BRW_VS_UNIT,
|
||||
sizeof(struct brw_vs_unit_state),
|
||||
0,
|
||||
DW_GENERAL_STATE);
|
||||
|
||||
brw_init_cache(brw,
|
||||
"VS_PROG",
|
||||
BRW_VS_PROG,
|
||||
sizeof(struct brw_vs_prog_key),
|
||||
sizeof(struct brw_vs_prog_data),
|
||||
DW_GENERAL_STATE);
|
||||
|
||||
brw_init_cache(brw,
|
||||
"CLIP_UNIT",
|
||||
BRW_CLIP_UNIT,
|
||||
sizeof(struct brw_clip_unit_state),
|
||||
0,
|
||||
DW_GENERAL_STATE);
|
||||
|
||||
brw_init_cache(brw,
|
||||
"CLIP_PROG",
|
||||
BRW_CLIP_PROG,
|
||||
sizeof(struct brw_clip_prog_key),
|
||||
sizeof(struct brw_clip_prog_data),
|
||||
DW_GENERAL_STATE);
|
||||
|
||||
brw_init_cache(brw,
|
||||
"GS_UNIT",
|
||||
BRW_GS_UNIT,
|
||||
sizeof(struct brw_gs_unit_state),
|
||||
0,
|
||||
DW_GENERAL_STATE);
|
||||
|
||||
brw_init_cache(brw,
|
||||
"GS_PROG",
|
||||
BRW_GS_PROG,
|
||||
sizeof(struct brw_gs_prog_key),
|
||||
sizeof(struct brw_gs_prog_data),
|
||||
DW_GENERAL_STATE);
|
||||
|
||||
brw_init_cache(brw,
|
||||
"SS_SURFACE",
|
||||
BRW_SS_SURFACE,
|
||||
sizeof(struct brw_surface_state),
|
||||
0,
|
||||
DW_SURFACE_STATE);
|
||||
|
||||
brw_init_cache(brw,
|
||||
"SS_SURF_BIND",
|
||||
BRW_SS_SURF_BIND,
|
||||
sizeof(struct brw_surface_binding_table),
|
||||
0,
|
||||
DW_SURFACE_STATE);
|
||||
}
|
||||
|
||||
|
||||
/* When we lose hardware context, need to invalidate the surface cache
|
||||
* as these structs must be explicitly re-uploaded. They are subject
|
||||
* to fixup by the memory manager as they contain absolute agp
|
||||
* offsets, so we need to ensure there is a fresh version of the
|
||||
* struct available to receive the fixup.
|
||||
*
|
||||
* XXX: Need to ensure that there aren't two versions of a surface or
|
||||
* bufferobj with different backing data active in the same buffer at
|
||||
* once? Otherwise the cache could confuse them. Maybe better not to
|
||||
* cache at all?
|
||||
*
|
||||
* --> Isn't this the same as saying need to ensure batch is flushed
|
||||
* before new data is uploaded to an existing buffer? We
|
||||
* already try to make sure of that.
|
||||
*/
|
||||
static void clear_cache( struct brw_cache *cache )
|
||||
{
|
||||
struct brw_cache_item *c, *next;
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < cache->size; i++) {
|
||||
for (c = cache->items[i]; c; c = next) {
|
||||
next = c->next;
|
||||
free((void *)c->key);
|
||||
free(c);
|
||||
}
|
||||
cache->items[i] = NULL;
|
||||
}
|
||||
|
||||
cache->n_items = 0;
|
||||
}
|
||||
|
||||
void brw_clear_all_caches( struct brw_context *brw )
|
||||
{
|
||||
int i;
|
||||
|
||||
if (BRW_DEBUG & DEBUG_STATE)
|
||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
||||
|
||||
for (i = 0; i < BRW_MAX_CACHE; i++)
|
||||
clear_cache(&brw->cache[i]);
|
||||
|
||||
if (brw->curbe.last_buf) {
|
||||
FREE(brw->curbe.last_buf);
|
||||
brw->curbe.last_buf = NULL;
|
||||
}
|
||||
|
||||
brw->state.dirty.brw |= ~0;
|
||||
brw->state.dirty.cache |= ~0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void brw_destroy_caches( struct brw_context *brw )
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < BRW_MAX_CACHE; i++)
|
||||
clear_cache(&brw->cache[i]);
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
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>
|
||||
*/
|
||||
|
||||
/** @file brw_state_pool.c
|
||||
* Implements the state pool allocator.
|
||||
*
|
||||
* For the 965, we create two state pools for state cache entries. Objects
|
||||
* will be allocated into the pools depending on which state base address
|
||||
* their pointer is relative to in other 965 state.
|
||||
*
|
||||
* The state pools are relatively simple: As objects are allocated, increment
|
||||
* the offset to allocate space. When the pool is "full" (rather, close to
|
||||
* full), we reset the pool and reset the state cache entries that point into
|
||||
* the pool.
|
||||
*/
|
||||
|
||||
#include "pipe/p_winsys.h"
|
||||
#include "brw_context.h"
|
||||
#include "brw_state.h"
|
||||
|
||||
boolean brw_pool_alloc( struct brw_mem_pool *pool,
|
||||
unsigned size,
|
||||
unsigned align,
|
||||
unsigned *offset_return)
|
||||
{
|
||||
unsigned fixup = ALIGN(pool->offset, align) - pool->offset;
|
||||
|
||||
size = ALIGN(size, 4);
|
||||
|
||||
if (pool->offset + fixup + size >= pool->size) {
|
||||
printf("%s failed\n", __FUNCTION__);
|
||||
assert(0);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
pool->offset += fixup;
|
||||
*offset_return = pool->offset;
|
||||
pool->offset += size;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static
|
||||
void brw_invalidate_pool( struct brw_mem_pool *pool )
|
||||
{
|
||||
if (BRW_DEBUG & DEBUG_STATE)
|
||||
printf("\n\n\n %s \n\n\n", __FUNCTION__);
|
||||
|
||||
pool->offset = 0;
|
||||
|
||||
brw_clear_all_caches(pool->brw);
|
||||
}
|
||||
|
||||
|
||||
static void brw_init_pool( struct brw_context *brw,
|
||||
unsigned pool_id,
|
||||
unsigned size )
|
||||
{
|
||||
struct brw_mem_pool *pool = &brw->pool[pool_id];
|
||||
|
||||
pool->size = size;
|
||||
pool->brw = brw;
|
||||
|
||||
pool->buffer = brw->pipe.winsys->buffer_create(brw->pipe.winsys,
|
||||
4096, 0, 0);
|
||||
|
||||
brw->pipe.winsys->buffer_data(brw->pipe.winsys,
|
||||
pool->buffer,
|
||||
size,
|
||||
NULL,
|
||||
0 /* DRM_BO_FLAG_MEM_TT */);
|
||||
}
|
||||
|
||||
static void brw_destroy_pool( struct brw_context *brw,
|
||||
unsigned pool_id )
|
||||
{
|
||||
struct brw_mem_pool *pool = &brw->pool[pool_id];
|
||||
|
||||
pool->brw->pipe.winsys->buffer_reference( pool->brw->pipe.winsys,
|
||||
&pool->buffer,
|
||||
NULL );
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void brw_init_pools( struct brw_context *brw )
|
||||
{
|
||||
brw_init_pool(brw, BRW_GS_POOL, 0x80000);
|
||||
brw_init_pool(brw, BRW_SS_POOL, 0x80000);
|
||||
}
|
||||
|
||||
void brw_destroy_pools( struct brw_context *brw )
|
||||
{
|
||||
brw_destroy_pool(brw, BRW_GS_POOL);
|
||||
brw_destroy_pool(brw, BRW_SS_POOL);
|
||||
}
|
||||
|
||||
|
||||
void brw_invalidate_pools( struct brw_context *brw )
|
||||
{
|
||||
brw_invalidate_pool(&brw->pool[BRW_GS_POOL]);
|
||||
brw_invalidate_pool(&brw->pool[BRW_SS_POOL]);
|
||||
}
|
||||
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
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_state.h"
|
||||
|
||||
#include "pipe/p_util.h"
|
||||
|
||||
/* This is used to initialize brw->state.atoms[]. We could use this
|
||||
* list directly except for a single atom, brw_constant_buffer, which
|
||||
* has a .dirty value which changes according to the parameters of the
|
||||
* current fragment and vertex programs, and so cannot be a static
|
||||
* value.
|
||||
*/
|
||||
const struct brw_tracked_state *atoms[] =
|
||||
{
|
||||
&brw_wm_input_sizes,
|
||||
&brw_vs_prog,
|
||||
&brw_gs_prog,
|
||||
&brw_clip_prog,
|
||||
&brw_sf_prog,
|
||||
&brw_wm_prog,
|
||||
|
||||
/* Once all the programs are done, we know how large urb entry
|
||||
* sizes need to be and can decide if we need to change the urb
|
||||
* layout.
|
||||
*/
|
||||
&brw_curbe_offsets,
|
||||
&brw_recalculate_urb_fence,
|
||||
|
||||
|
||||
&brw_cc_vp,
|
||||
&brw_cc_unit,
|
||||
|
||||
&brw_wm_surfaces, /* must do before samplers */
|
||||
&brw_wm_samplers,
|
||||
|
||||
&brw_wm_unit,
|
||||
&brw_sf_vp,
|
||||
&brw_sf_unit,
|
||||
&brw_vs_unit, /* always required, enabled or not */
|
||||
&brw_clip_unit,
|
||||
&brw_gs_unit,
|
||||
|
||||
/* Command packets:
|
||||
*/
|
||||
&brw_invarient_state,
|
||||
&brw_state_base_address,
|
||||
&brw_pipe_control,
|
||||
|
||||
&brw_binding_table_pointers,
|
||||
&brw_blend_constant_color,
|
||||
|
||||
&brw_drawing_rect,
|
||||
&brw_depthbuffer,
|
||||
|
||||
&brw_polygon_stipple,
|
||||
&brw_polygon_stipple_offset,
|
||||
|
||||
&brw_line_stipple,
|
||||
|
||||
&brw_psp_urb_cbs,
|
||||
|
||||
|
||||
NULL, /* brw_constant_buffer */
|
||||
};
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
*/
|
||||
|
||||
static boolean check_state( const struct brw_state_flags *a,
|
||||
const struct brw_state_flags *b )
|
||||
{
|
||||
return ((a->brw & b->brw) ||
|
||||
(a->cache & b->cache));
|
||||
}
|
||||
|
||||
static void accumulate_state( struct brw_state_flags *a,
|
||||
const struct brw_state_flags *b )
|
||||
{
|
||||
a->brw |= b->brw;
|
||||
a->cache |= b->cache;
|
||||
}
|
||||
|
||||
|
||||
static void xor_states( struct brw_state_flags *result,
|
||||
const struct brw_state_flags *a,
|
||||
const struct brw_state_flags *b )
|
||||
{
|
||||
result->brw = a->brw ^ b->brw;
|
||||
result->cache = a->cache ^ b->cache;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Emit all state:
|
||||
*/
|
||||
void brw_validate_state( struct brw_context *brw )
|
||||
{
|
||||
struct brw_state_flags *state = &brw->state.dirty;
|
||||
unsigned i;
|
||||
|
||||
if (brw->emit_state_always)
|
||||
state->brw |= ~0;
|
||||
|
||||
if (state->cache == 0 &&
|
||||
state->brw == 0)
|
||||
return;
|
||||
|
||||
if (brw->state.dirty.brw & BRW_NEW_CONTEXT)
|
||||
brw_clear_batch_cache_flush(brw);
|
||||
|
||||
if (BRW_DEBUG) {
|
||||
/* Debug version which enforces various sanity checks on the
|
||||
* state flags which are generated and checked to help ensure
|
||||
* state atoms are ordered correctly in the list.
|
||||
*/
|
||||
struct brw_state_flags examined, prev;
|
||||
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];
|
||||
struct brw_state_flags generated;
|
||||
|
||||
assert(atom->dirty.brw ||
|
||||
atom->dirty.cache);
|
||||
assert(atom->update);
|
||||
|
||||
if (check_state(state, &atom->dirty) || atom->always_update) {
|
||||
atom->update( brw );
|
||||
|
||||
/* emit_foo(brw); */
|
||||
}
|
||||
if (atom->emit_reloc != NULL)
|
||||
atom->emit_reloc(brw);
|
||||
|
||||
accumulate_state(&examined, &atom->dirty);
|
||||
|
||||
/* generated = (prev ^ state)
|
||||
* if (examined & generated)
|
||||
* fail;
|
||||
*/
|
||||
xor_states(&generated, &prev, state);
|
||||
assert(!check_state(&examined, &generated));
|
||||
prev = *state;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < Elements(atoms); i++) {
|
||||
const struct brw_tracked_state *atom = brw->state.atoms[i];
|
||||
|
||||
if (check_state(state, &atom->dirty) || atom->always_update)
|
||||
atom->update( brw );
|
||||
if (atom->emit_reloc != NULL)
|
||||
atom->emit_reloc(brw);
|
||||
}
|
||||
}
|
||||
|
||||
memset(state, 0, sizeof(*state));
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* 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, sub license, 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 NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS 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.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include "brw_context.h"
|
||||
#include "brw_reg.h"
|
||||
|
||||
|
||||
static const char *brw_get_vendor( struct pipe_context *pipe )
|
||||
{
|
||||
return "Tungsten Graphics, Inc.";
|
||||
}
|
||||
|
||||
|
||||
static const char *brw_get_name( struct pipe_context *pipe )
|
||||
{
|
||||
static char buffer[128];
|
||||
const char *chipset;
|
||||
|
||||
switch (brw_context(pipe)->pci_id) {
|
||||
case PCI_CHIP_I965_Q:
|
||||
chipset = "Intel(R) 965Q";
|
||||
break;
|
||||
case PCI_CHIP_I965_G:
|
||||
case PCI_CHIP_I965_G_1:
|
||||
chipset = "Intel(R) 965G";
|
||||
break;
|
||||
case PCI_CHIP_I965_GM:
|
||||
chipset = "Intel(R) 965GM";
|
||||
break;
|
||||
case PCI_CHIP_I965_GME:
|
||||
chipset = "Intel(R) 965GME/GLE";
|
||||
break;
|
||||
default:
|
||||
chipset = "unknown";
|
||||
break;
|
||||
}
|
||||
|
||||
sprintf(buffer, "pipe/i965 (chipset: %s)", chipset);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
brw_init_string_functions(struct brw_context *brw)
|
||||
{
|
||||
brw->pipe.get_name = brw_get_name;
|
||||
brw->pipe.get_vendor = brw_get_vendor;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,397 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* 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, sub license, 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 NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS 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.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include "brw_blit.h"
|
||||
#include "brw_context.h"
|
||||
#include "brw_state.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_util.h"
|
||||
#include "pipe/p_inlines.h"
|
||||
#include "pipe/p_winsys.h"
|
||||
|
||||
|
||||
#define CLIP_TILE \
|
||||
do { \
|
||||
if (x >= ps->width) \
|
||||
return; \
|
||||
if (y >= ps->height) \
|
||||
return; \
|
||||
if (x + w > ps->width) \
|
||||
w = ps->width - x; \
|
||||
if (y + h > ps->height) \
|
||||
h = ps->height -y; \
|
||||
} while(0)
|
||||
|
||||
|
||||
/**
|
||||
* Note: this is exactly like a8r8g8b8_get_tile() in sp_surface.c
|
||||
* Share it someday.
|
||||
*/
|
||||
static void
|
||||
brw_get_tile_rgba(struct pipe_context *pipe,
|
||||
struct pipe_surface *ps,
|
||||
uint x, uint y, uint w, uint h, float *p)
|
||||
{
|
||||
const unsigned *src
|
||||
= ((const unsigned *) (ps->map + ps->offset))
|
||||
+ y * ps->pitch + x;
|
||||
unsigned i, j;
|
||||
unsigned w0 = w;
|
||||
|
||||
CLIP_TILE;
|
||||
|
||||
switch (ps->format) {
|
||||
case PIPE_FORMAT_A8R8G8B8_UNORM:
|
||||
for (i = 0; i < h; i++) {
|
||||
float *pRow = p;
|
||||
for (j = 0; j < w; j++) {
|
||||
const unsigned pixel = src[j];
|
||||
pRow[0] = UBYTE_TO_FLOAT((pixel >> 16) & 0xff);
|
||||
pRow[1] = UBYTE_TO_FLOAT((pixel >> 8) & 0xff);
|
||||
pRow[2] = UBYTE_TO_FLOAT((pixel >> 0) & 0xff);
|
||||
pRow[3] = UBYTE_TO_FLOAT((pixel >> 24) & 0xff);
|
||||
pRow += 4;
|
||||
}
|
||||
src += ps->pitch;
|
||||
p += w0 * 4;
|
||||
}
|
||||
break;
|
||||
case PIPE_FORMAT_S8Z24_UNORM:
|
||||
{
|
||||
const float scale = 1.0f / (float) 0xffffff;
|
||||
for (i = 0; i < h; i++) {
|
||||
float *pRow = p;
|
||||
for (j = 0; j < w; j++) {
|
||||
const unsigned pixel = src[j];
|
||||
pRow[0] =
|
||||
pRow[1] =
|
||||
pRow[2] =
|
||||
pRow[3] = (pixel & 0xffffff) * scale;
|
||||
pRow += 4;
|
||||
}
|
||||
src += ps->pitch;
|
||||
p += w0 * 4;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
brw_put_tile_rgba(struct pipe_context *pipe,
|
||||
struct pipe_surface *ps,
|
||||
uint x, uint y, uint w, uint h, const float *p)
|
||||
{
|
||||
/* TODO */
|
||||
assert(0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* XXX note: same as code in sp_surface.c
|
||||
*/
|
||||
static void
|
||||
brw_get_tile(struct pipe_context *pipe,
|
||||
struct pipe_surface *ps,
|
||||
uint x, uint y, uint w, uint h,
|
||||
void *p, int dst_stride)
|
||||
{
|
||||
const uint cpp = ps->cpp;
|
||||
const uint w0 = w;
|
||||
const ubyte *pSrc;
|
||||
ubyte *pDest;
|
||||
uint i;
|
||||
|
||||
assert(ps->map);
|
||||
|
||||
CLIP_TILE;
|
||||
|
||||
if (dst_stride == 0) {
|
||||
dst_stride = w0 * cpp;
|
||||
}
|
||||
|
||||
pSrc = ps->map + ps->offset + (y * ps->pitch + x) * cpp;
|
||||
pDest = (ubyte *) p;
|
||||
|
||||
for (i = 0; i < h; i++) {
|
||||
memcpy(pDest, pSrc, w0 * cpp);
|
||||
pDest += dst_stride;
|
||||
pSrc += ps->pitch * cpp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* XXX note: same as code in sp_surface.c
|
||||
*/
|
||||
static void
|
||||
brw_put_tile(struct pipe_context *pipe,
|
||||
struct pipe_surface *ps,
|
||||
uint x, uint y, uint w, uint h,
|
||||
const void *p, int src_stride)
|
||||
{
|
||||
const uint cpp = ps->cpp;
|
||||
const uint w0 = w;
|
||||
const ubyte *pSrc;
|
||||
ubyte *pDest;
|
||||
uint i;
|
||||
|
||||
assert(ps->map);
|
||||
|
||||
CLIP_TILE;
|
||||
|
||||
if (src_stride == 0) {
|
||||
src_stride = w0 * cpp;
|
||||
}
|
||||
|
||||
pSrc = (const ubyte *) p;
|
||||
pDest = ps->map + ps->offset + (y * ps->pitch + x) * cpp;
|
||||
|
||||
for (i = 0; i < h; i++) {
|
||||
memcpy(pDest, pSrc, w0 * cpp);
|
||||
pDest += ps->pitch * cpp;
|
||||
pSrc += src_stride;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* XXX note: same as code in sp_surface.c
|
||||
*/
|
||||
static struct pipe_surface *
|
||||
brw_get_tex_surface(struct pipe_context *pipe,
|
||||
struct pipe_texture *pt,
|
||||
unsigned face, unsigned level, unsigned zslice)
|
||||
{
|
||||
struct brw_texture *tex = (struct brw_texture *)pt;
|
||||
struct pipe_surface *ps;
|
||||
unsigned offset; /* in bytes */
|
||||
|
||||
offset = tex->level_offset[level];
|
||||
|
||||
if (pt->target == PIPE_TEXTURE_CUBE) {
|
||||
offset += tex->image_offset[level][face] * pt->cpp;
|
||||
}
|
||||
else if (pt->target == PIPE_TEXTURE_3D) {
|
||||
offset += tex->image_offset[level][zslice] * pt->cpp;
|
||||
}
|
||||
else {
|
||||
assert(face == 0);
|
||||
assert(zslice == 0);
|
||||
}
|
||||
|
||||
ps = pipe->winsys->surface_alloc(pipe->winsys);
|
||||
if (ps) {
|
||||
assert(ps->format);
|
||||
assert(ps->refcount);
|
||||
pipe->winsys->buffer_reference(pipe->winsys, &ps->buffer, tex->buffer);
|
||||
ps->format = pt->format;
|
||||
ps->cpp = pt->cpp;
|
||||
ps->width = pt->width[level];
|
||||
ps->height = pt->height[level];
|
||||
ps->pitch = tex->pitch;
|
||||
ps->offset = offset;
|
||||
}
|
||||
return ps;
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX Move this into core Mesa?
|
||||
*/
|
||||
static void
|
||||
_mesa_copy_rect(ubyte * dst,
|
||||
unsigned cpp,
|
||||
unsigned dst_pitch,
|
||||
unsigned dst_x,
|
||||
unsigned dst_y,
|
||||
unsigned width,
|
||||
unsigned height,
|
||||
const ubyte * src,
|
||||
unsigned src_pitch,
|
||||
unsigned src_x,
|
||||
unsigned src_y)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
dst_pitch *= cpp;
|
||||
src_pitch *= cpp;
|
||||
dst += dst_x * cpp;
|
||||
src += src_x * cpp;
|
||||
dst += dst_y * dst_pitch;
|
||||
src += src_y * dst_pitch;
|
||||
width *= cpp;
|
||||
|
||||
if (width == dst_pitch && width == src_pitch)
|
||||
memcpy(dst, src, height * width);
|
||||
else {
|
||||
for (i = 0; i < height; i++) {
|
||||
memcpy(dst, src, width);
|
||||
dst += dst_pitch;
|
||||
src += src_pitch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Upload data to a rectangular sub-region. Lots of choices how to do this:
|
||||
*
|
||||
* - memcpy by span to current destination
|
||||
* - upload data as new buffer and blit
|
||||
*
|
||||
* Currently always memcpy.
|
||||
*/
|
||||
static void
|
||||
brw_surface_data(struct pipe_context *pipe,
|
||||
struct pipe_surface *dst,
|
||||
unsigned dstx, unsigned dsty,
|
||||
const void *src, unsigned src_pitch,
|
||||
unsigned srcx, unsigned srcy, unsigned width, unsigned height)
|
||||
{
|
||||
_mesa_copy_rect(pipe_surface_map(dst) + dst->offset,
|
||||
dst->cpp,
|
||||
dst->pitch,
|
||||
dstx, dsty, width, height, src, src_pitch, srcx, srcy);
|
||||
|
||||
pipe_surface_unmap(dst);
|
||||
}
|
||||
|
||||
|
||||
/* Assumes all values are within bounds -- no checking at this level -
|
||||
* do it higher up if required.
|
||||
*/
|
||||
static void
|
||||
brw_surface_copy(struct pipe_context *pipe,
|
||||
struct pipe_surface *dst,
|
||||
unsigned dstx, unsigned dsty,
|
||||
struct pipe_surface *src,
|
||||
unsigned srcx, unsigned srcy, unsigned width, unsigned height)
|
||||
{
|
||||
assert(dst != src);
|
||||
assert(dst->cpp == src->cpp);
|
||||
|
||||
if (0) {
|
||||
_mesa_copy_rect(pipe_surface_map(dst) + dst->offset,
|
||||
dst->cpp,
|
||||
dst->pitch,
|
||||
dstx, dsty,
|
||||
width, height,
|
||||
pipe_surface_map(src) + src->offset,
|
||||
src->pitch,
|
||||
srcx, srcy);
|
||||
|
||||
pipe_surface_unmap(src);
|
||||
pipe_surface_unmap(dst);
|
||||
}
|
||||
else {
|
||||
brw_copy_blit(brw_context(pipe),
|
||||
dst->cpp,
|
||||
(short) src->pitch, src->buffer, src->offset, FALSE,
|
||||
(short) dst->pitch, dst->buffer, dst->offset, FALSE,
|
||||
(short) srcx, (short) srcy, (short) dstx, (short) dsty,
|
||||
(short) width, (short) height, PIPE_LOGICOP_COPY);
|
||||
}
|
||||
}
|
||||
|
||||
/* Fill a rectangular sub-region. Need better logic about when to
|
||||
* push buffers into AGP - will currently do so whenever possible.
|
||||
*/
|
||||
static ubyte *
|
||||
get_pointer(struct pipe_surface *dst, unsigned x, unsigned y)
|
||||
{
|
||||
return dst->map + (y * dst->pitch + x) * dst->cpp;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
brw_surface_fill(struct pipe_context *pipe,
|
||||
struct pipe_surface *dst,
|
||||
unsigned dstx, unsigned dsty,
|
||||
unsigned width, unsigned height, unsigned value)
|
||||
{
|
||||
if (0) {
|
||||
unsigned i, j;
|
||||
|
||||
(void)pipe_surface_map(dst);
|
||||
|
||||
switch (dst->cpp) {
|
||||
case 1: {
|
||||
ubyte *row = get_pointer(dst, dstx, dsty);
|
||||
for (i = 0; i < height; i++) {
|
||||
memset(row, value, width);
|
||||
row += dst->pitch;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2: {
|
||||
ushort *row = (ushort *) get_pointer(dst, dstx, dsty);
|
||||
for (i = 0; i < height; i++) {
|
||||
for (j = 0; j < width; j++)
|
||||
row[j] = (ushort) value;
|
||||
row += dst->pitch;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 4: {
|
||||
unsigned *row = (unsigned *) get_pointer(dst, dstx, dsty);
|
||||
for (i = 0; i < height; i++) {
|
||||
for (j = 0; j < width; j++)
|
||||
row[j] = value;
|
||||
row += dst->pitch;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
brw_fill_blit(brw_context(pipe),
|
||||
dst->cpp,
|
||||
(short) dst->pitch,
|
||||
dst->buffer, dst->offset, FALSE,
|
||||
(short) dstx, (short) dsty,
|
||||
(short) width, (short) height,
|
||||
value);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
brw_init_surface_functions(struct brw_context *brw)
|
||||
{
|
||||
brw->pipe.get_tex_surface = brw_get_tex_surface;
|
||||
brw->pipe.get_tile = brw_get_tile;
|
||||
brw->pipe.put_tile = brw_put_tile;
|
||||
brw->pipe.get_tile_rgba = brw_get_tile_rgba;
|
||||
brw->pipe.put_tile_rgba = brw_put_tile_rgba;
|
||||
|
||||
brw->pipe.surface_data = brw_surface_data;
|
||||
brw->pipe.surface_copy = brw_surface_copy;
|
||||
brw->pipe.surface_fill = brw_surface_fill;
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
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"
|
||||
|
||||
#if 0
|
||||
void brw_FrameBufferTexInit( struct brw_context *brw )
|
||||
{
|
||||
struct intel_context *intel = &brw->intel;
|
||||
GLcontext *ctx = &intel->ctx;
|
||||
struct intel_region *region = intel->intelScreen->front_region;
|
||||
struct gl_texture_object *obj;
|
||||
struct gl_texture_image *img;
|
||||
|
||||
intel->frame_buffer_texobj = obj =
|
||||
ctx->Driver.NewTextureObject( ctx, (unsigned) -1, GL_TEXTURE_2D );
|
||||
|
||||
obj->MinFilter = GL_NEAREST;
|
||||
obj->MagFilter = GL_NEAREST;
|
||||
|
||||
img = ctx->Driver.NewTextureImage( ctx );
|
||||
|
||||
_mesa_init_teximage_fields( ctx, GL_TEXTURE_2D, img,
|
||||
region->pitch, region->height, 1, 0,
|
||||
region->cpp == 4 ? GL_RGBA : GL_RGB );
|
||||
|
||||
_mesa_set_tex_image( obj, GL_TEXTURE_2D, 0, img );
|
||||
}
|
||||
|
||||
void brw_FrameBufferTexDestroy( struct brw_context *brw )
|
||||
{
|
||||
brw->intel.ctx.Driver.DeleteTexture( &brw->intel.ctx,
|
||||
brw->intel.frame_buffer_texobj );
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,359 @@
|
||||
/*
|
||||
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>
|
||||
*/
|
||||
|
||||
|
||||
/* Code to layout images in a mipmap tree for i965.
|
||||
*/
|
||||
|
||||
#include "brw_tex_layout.h"
|
||||
|
||||
#include "pipe/p_state.h"
|
||||
#include "pipe/p_context.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_util.h"
|
||||
#include "pipe/p_winsys.h"
|
||||
|
||||
#include "brw_context.h"
|
||||
|
||||
#define FILE_DEBUG_FLAG DEBUG_TEXTURE
|
||||
|
||||
#if 0
|
||||
unsigned intel_compressed_alignment(unsigned internalFormat)
|
||||
{
|
||||
unsigned alignment = 4;
|
||||
|
||||
switch (internalFormat) {
|
||||
case GL_COMPRESSED_RGB_FXT1_3DFX:
|
||||
case GL_COMPRESSED_RGBA_FXT1_3DFX:
|
||||
alignment = 8;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return alignment;
|
||||
}
|
||||
#endif
|
||||
|
||||
static unsigned minify( unsigned d )
|
||||
{
|
||||
return MAX2(1, d>>1);
|
||||
}
|
||||
|
||||
|
||||
static boolean brw_miptree_layout(struct pipe_context *, struct brw_texture *);
|
||||
|
||||
static void intel_miptree_set_image_offset(struct brw_texture *tex,
|
||||
unsigned level,
|
||||
unsigned img,
|
||||
unsigned x, unsigned y)
|
||||
{
|
||||
struct pipe_texture *pt = &tex->base;
|
||||
if (img == 0 && level == 0)
|
||||
assert(x == 0 && y == 0);
|
||||
assert(img < tex->nr_images[level]);
|
||||
|
||||
tex->image_offset[level][img] = (x + y * tex->pitch) * pt->cpp;
|
||||
}
|
||||
|
||||
static void intel_miptree_set_level_info(struct brw_texture *tex,
|
||||
unsigned level,
|
||||
unsigned nr_images,
|
||||
unsigned x, unsigned y,
|
||||
unsigned w, unsigned h, unsigned d)
|
||||
{
|
||||
struct pipe_texture *pt = &tex->base;
|
||||
|
||||
assert(level < PIPE_MAX_TEXTURE_LEVELS);
|
||||
|
||||
pt->width[level] = w;
|
||||
pt->height[level] = h;
|
||||
pt->depth[level] = d;
|
||||
|
||||
tex->level_offset[level] = (x + y * tex->pitch) * pt->cpp;
|
||||
tex->nr_images[level] = nr_images;
|
||||
|
||||
/*
|
||||
DBG("%s level %d size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__,
|
||||
level, w, h, d, x, y, tex->level_offset[level]);
|
||||
*/
|
||||
|
||||
/* Not sure when this would happen, but anyway:
|
||||
*/
|
||||
if (tex->image_offset[level]) {
|
||||
FREE(tex->image_offset[level]);
|
||||
tex->image_offset[level] = NULL;
|
||||
}
|
||||
|
||||
assert(nr_images);
|
||||
assert(!tex->image_offset[level]);
|
||||
|
||||
tex->image_offset[level] = (unsigned *) MALLOC(nr_images * sizeof(unsigned));
|
||||
tex->image_offset[level][0] = 0;
|
||||
}
|
||||
|
||||
static void i945_miptree_layout_2d(struct brw_texture *tex)
|
||||
{
|
||||
struct pipe_texture *pt = &tex->base;
|
||||
unsigned align_h = 2, align_w = 4;
|
||||
unsigned level;
|
||||
unsigned x = 0;
|
||||
unsigned y = 0;
|
||||
unsigned width = pt->width[0];
|
||||
unsigned height = pt->height[0];
|
||||
|
||||
tex->pitch = pt->width[0];
|
||||
|
||||
#if 0
|
||||
if (pt->compressed) {
|
||||
align_w = intel_compressed_alignment(pt->internal_format);
|
||||
tex->pitch = ALIGN(pt->width[0], align_w);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* May need to adjust pitch to accomodate the placement of
|
||||
* the 2nd mipmap. This occurs when the alignment
|
||||
* constraints of mipmap placement push the right edge of the
|
||||
* 2nd mipmap out past the width of its parent.
|
||||
*/
|
||||
if (pt->first_level != pt->last_level) {
|
||||
unsigned mip1_width;
|
||||
|
||||
if (pt->compressed) {
|
||||
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)
|
||||
+ minify(minify(pt->width[0]));
|
||||
}
|
||||
|
||||
if (mip1_width > tex->pitch) {
|
||||
tex->pitch = mip1_width;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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->total_height = 0;
|
||||
|
||||
for ( level = pt->first_level ; level <= pt->last_level ; level++ ) {
|
||||
unsigned img_height;
|
||||
|
||||
intel_miptree_set_level_info(tex, level, 1, x, y, width,
|
||||
height, 1);
|
||||
|
||||
if (pt->compressed)
|
||||
img_height = MAX2(1, height/4);
|
||||
else
|
||||
img_height = ALIGN(height, align_h);
|
||||
|
||||
|
||||
/* Because the images are packed better, the final offset
|
||||
* might not be the maximal one:
|
||||
*/
|
||||
tex->total_height = MAX2(tex->total_height, y + img_height);
|
||||
|
||||
/* Layout_below: step right after second mipmap.
|
||||
*/
|
||||
if (level == pt->first_level + 1) {
|
||||
x += ALIGN(width, align_w);
|
||||
}
|
||||
else {
|
||||
y += img_height;
|
||||
}
|
||||
|
||||
width = minify(width);
|
||||
height = minify(height);
|
||||
}
|
||||
}
|
||||
|
||||
static boolean brw_miptree_layout(struct pipe_context *pipe, struct brw_texture *tex)
|
||||
{
|
||||
struct pipe_texture *pt = &tex->base;
|
||||
/* XXX: these vary depending on image format:
|
||||
*/
|
||||
/* int align_w = 4; */
|
||||
|
||||
switch (pt->target) {
|
||||
case PIPE_TEXTURE_CUBE:
|
||||
case PIPE_TEXTURE_3D: {
|
||||
unsigned width = pt->width[0];
|
||||
unsigned height = pt->height[0];
|
||||
unsigned depth = pt->depth[0];
|
||||
unsigned pack_x_pitch, pack_x_nr;
|
||||
unsigned pack_y_pitch;
|
||||
unsigned level;
|
||||
unsigned align_h = 2;
|
||||
unsigned align_w = 4;
|
||||
|
||||
tex->total_height = 0;
|
||||
#if 0
|
||||
if (pt->compressed) {
|
||||
align_w = intel_compressed_alignment(pt->internal_format);
|
||||
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);
|
||||
}
|
||||
|
||||
pack_x_pitch = tex->pitch;
|
||||
pack_x_nr = 1;
|
||||
|
||||
for ( level = pt->first_level ; level <= pt->last_level ; level++ ) {
|
||||
unsigned nr_images = pt->target == PIPE_TEXTURE_3D ? depth : 6;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int q, j;
|
||||
|
||||
intel_miptree_set_level_info(tex, level, nr_images,
|
||||
0, tex->total_height,
|
||||
width, height, depth);
|
||||
|
||||
for (q = 0; q < nr_images;) {
|
||||
for (j = 0; j < pack_x_nr && q < nr_images; j++, q++) {
|
||||
intel_miptree_set_image_offset(tex, level, q, x, y);
|
||||
x += pack_x_pitch;
|
||||
}
|
||||
|
||||
x = 0;
|
||||
y += pack_y_pitch;
|
||||
}
|
||||
|
||||
|
||||
tex->total_height += y;
|
||||
width = minify(width);
|
||||
height = minify(height);
|
||||
depth = minify(depth);
|
||||
|
||||
if (pt->compressed) {
|
||||
pack_y_pitch = (height + 3) / 4;
|
||||
|
||||
if (pack_x_pitch > ALIGN(width, align_w)) {
|
||||
pack_x_pitch = ALIGN(width, align_w);
|
||||
pack_x_nr <<= 1;
|
||||
}
|
||||
} else {
|
||||
if (pack_x_pitch > 4) {
|
||||
pack_x_pitch >>= 1;
|
||||
pack_x_nr <<= 1;
|
||||
assert(pack_x_pitch * pack_x_nr <= tex->pitch);
|
||||
}
|
||||
|
||||
if (pack_y_pitch > 2) {
|
||||
pack_y_pitch >>= 1;
|
||||
pack_y_pitch = ALIGN(pack_y_pitch, align_h);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
i945_miptree_layout_2d(tex);
|
||||
break;
|
||||
}
|
||||
#if 0
|
||||
PRINT("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__,
|
||||
pt->pitch,
|
||||
pt->total_height,
|
||||
pt->cpp,
|
||||
pt->pitch * pt->total_height * pt->cpp );
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
brw_texture_create(struct pipe_context *pipe, struct pipe_texture **pt)
|
||||
{
|
||||
struct brw_texture *tex = REALLOC(*pt, sizeof(struct pipe_texture),
|
||||
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));
|
||||
|
||||
if (brw_miptree_layout(pipe, tex)) {
|
||||
tex->buffer = pipe->winsys->buffer_create(pipe->winsys, 64, 0, 0);
|
||||
|
||||
if (tex->buffer)
|
||||
pipe->winsys->buffer_data(pipe->winsys, tex->buffer,
|
||||
tex->pitch * tex->base.cpp *
|
||||
tex->total_height, NULL,
|
||||
PIPE_BUFFER_USAGE_PIXEL);
|
||||
}
|
||||
|
||||
if (!tex->buffer) {
|
||||
FREE(tex);
|
||||
tex = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
*pt = &tex->base;
|
||||
}
|
||||
|
||||
void
|
||||
brw_texture_release(struct pipe_context *pipe, struct pipe_texture **pt)
|
||||
{
|
||||
if (!*pt)
|
||||
return;
|
||||
|
||||
/*
|
||||
DBG("%s %p refcount will be %d\n",
|
||||
__FUNCTION__, (void *) *pt, (*pt)->refcount - 1);
|
||||
*/
|
||||
if (--(*pt)->refcount <= 0) {
|
||||
struct brw_texture *tex = (struct brw_texture *)*pt;
|
||||
uint i;
|
||||
|
||||
/*
|
||||
DBG("%s deleting %p\n", __FUNCTION__, (void *) tex);
|
||||
*/
|
||||
|
||||
pipe->winsys->buffer_reference(pipe->winsys, &tex->buffer, NULL);
|
||||
|
||||
for (i = 0; i < PIPE_MAX_TEXTURE_LEVELS; i++)
|
||||
if (tex->image_offset[i])
|
||||
free(tex->image_offset[i]);
|
||||
|
||||
free(tex);
|
||||
}
|
||||
*pt = NULL;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#ifndef BRW_TEX_LAYOUT_H
|
||||
#define BRW_TEX_LAYOUT_H
|
||||
|
||||
#include "pipe/p_compiler.h"
|
||||
|
||||
struct pipe_context;
|
||||
struct pipe_texture;
|
||||
|
||||
extern void
|
||||
brw_texture_create(struct pipe_context *pipe, struct pipe_texture **pt);
|
||||
|
||||
extern void
|
||||
brw_texture_release(struct pipe_context *pipe, struct pipe_texture **pt);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
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_state.h"
|
||||
#include "brw_defines.h"
|
||||
|
||||
#define VS 0
|
||||
#define GS 1
|
||||
#define CLP 2
|
||||
#define SF 3
|
||||
#define CS 4
|
||||
|
||||
/* XXX: Are the min_entry_size numbers useful?
|
||||
* XXX: Verify min_nr_entries, esp for VS.
|
||||
* XXX: Verify SF min_entry_size.
|
||||
*/
|
||||
static const struct {
|
||||
unsigned min_nr_entries;
|
||||
unsigned preferred_nr_entries;
|
||||
unsigned min_entry_size;
|
||||
unsigned max_entry_size;
|
||||
} limits[CS+1] = {
|
||||
{ 8, 32, 1, 5 }, /* vs */
|
||||
{ 4, 8, 1, 5 }, /* gs */
|
||||
{ 6, 8, 1, 5 }, /* clp */
|
||||
{ 1, 8, 1, 12 }, /* sf */
|
||||
{ 1, 4, 1, 32 } /* cs */
|
||||
};
|
||||
|
||||
|
||||
static boolean check_urb_layout( struct brw_context *brw )
|
||||
{
|
||||
brw->urb.vs_start = 0;
|
||||
brw->urb.gs_start = brw->urb.nr_vs_entries * brw->urb.vsize;
|
||||
brw->urb.clip_start = brw->urb.gs_start + brw->urb.nr_gs_entries * brw->urb.vsize;
|
||||
brw->urb.sf_start = brw->urb.clip_start + brw->urb.nr_clip_entries * brw->urb.vsize;
|
||||
brw->urb.cs_start = brw->urb.sf_start + brw->urb.nr_sf_entries * brw->urb.sfsize;
|
||||
|
||||
return brw->urb.cs_start + brw->urb.nr_cs_entries * brw->urb.csize <= 256;
|
||||
}
|
||||
|
||||
/* Most minimal update, forces re-emit of URB fence packet after GS
|
||||
* unit turned on/off.
|
||||
*/
|
||||
static void recalculate_urb_fence( struct brw_context *brw )
|
||||
{
|
||||
unsigned csize = brw->curbe.total_size;
|
||||
unsigned vsize = brw->vs.prog_data->urb_entry_size;
|
||||
unsigned sfsize = brw->sf.prog_data->urb_entry_size;
|
||||
|
||||
if (csize < limits[CS].min_entry_size)
|
||||
csize = limits[CS].min_entry_size;
|
||||
|
||||
if (vsize < limits[VS].min_entry_size)
|
||||
vsize = limits[VS].min_entry_size;
|
||||
|
||||
if (sfsize < limits[SF].min_entry_size)
|
||||
sfsize = limits[SF].min_entry_size;
|
||||
|
||||
if (brw->urb.vsize < vsize ||
|
||||
brw->urb.sfsize < sfsize ||
|
||||
brw->urb.csize < csize ||
|
||||
(brw->urb.constrained && (brw->urb.vsize > brw->urb.vsize ||
|
||||
brw->urb.sfsize > brw->urb.sfsize ||
|
||||
brw->urb.csize > brw->urb.csize))) {
|
||||
|
||||
|
||||
brw->urb.csize = csize;
|
||||
brw->urb.sfsize = sfsize;
|
||||
brw->urb.vsize = vsize;
|
||||
|
||||
brw->urb.nr_vs_entries = limits[VS].preferred_nr_entries;
|
||||
brw->urb.nr_gs_entries = limits[GS].preferred_nr_entries;
|
||||
brw->urb.nr_clip_entries = limits[CLP].preferred_nr_entries;
|
||||
brw->urb.nr_sf_entries = limits[SF].preferred_nr_entries;
|
||||
brw->urb.nr_cs_entries = limits[CS].preferred_nr_entries;
|
||||
|
||||
if (!check_urb_layout(brw)) {
|
||||
brw->urb.nr_vs_entries = limits[VS].min_nr_entries;
|
||||
brw->urb.nr_gs_entries = limits[GS].min_nr_entries;
|
||||
brw->urb.nr_clip_entries = limits[CLP].min_nr_entries;
|
||||
brw->urb.nr_sf_entries = limits[SF].min_nr_entries;
|
||||
brw->urb.nr_cs_entries = limits[CS].min_nr_entries;
|
||||
|
||||
brw->urb.constrained = 1;
|
||||
|
||||
if (!check_urb_layout(brw)) {
|
||||
/* This is impossible, given the maximal sizes of urb
|
||||
* entries and the values for minimum nr of entries
|
||||
* provided above.
|
||||
*/
|
||||
fprintf(stderr, "couldn't calculate URB layout!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (BRW_DEBUG & (DEBUG_URB|DEBUG_FALLBACKS))
|
||||
printf("URB CONSTRAINED\n");
|
||||
}
|
||||
else
|
||||
brw->urb.constrained = 0;
|
||||
|
||||
if (BRW_DEBUG & DEBUG_URB)
|
||||
printf("URB fence: %d ..VS.. %d ..GS.. %d ..CLP.. %d ..SF.. %d ..CS.. %d\n",
|
||||
brw->urb.vs_start,
|
||||
brw->urb.gs_start,
|
||||
brw->urb.clip_start,
|
||||
brw->urb.sf_start,
|
||||
brw->urb.cs_start,
|
||||
256);
|
||||
|
||||
brw->state.dirty.brw |= BRW_NEW_URB_FENCE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const struct brw_tracked_state brw_recalculate_urb_fence = {
|
||||
.dirty = {
|
||||
.brw = BRW_NEW_CURBE_OFFSETS,
|
||||
.cache = (CACHE_NEW_VS_PROG |
|
||||
CACHE_NEW_SF_PROG)
|
||||
},
|
||||
.update = recalculate_urb_fence
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void brw_upload_urb_fence(struct brw_context *brw)
|
||||
{
|
||||
struct brw_urb_fence uf;
|
||||
memset(&uf, 0, sizeof(uf));
|
||||
|
||||
uf.header.opcode = CMD_URB_FENCE;
|
||||
uf.header.length = sizeof(uf)/4-2;
|
||||
uf.header.vs_realloc = 1;
|
||||
uf.header.gs_realloc = 1;
|
||||
uf.header.clp_realloc = 1;
|
||||
uf.header.sf_realloc = 1;
|
||||
uf.header.vfe_realloc = 1;
|
||||
uf.header.cs_realloc = 1;
|
||||
|
||||
/* The ordering below is correct, not the layout in the
|
||||
* instruction.
|
||||
*
|
||||
* There are 256 urb reg pairs in total.
|
||||
*/
|
||||
uf.bits0.vs_fence = brw->urb.gs_start;
|
||||
uf.bits0.gs_fence = brw->urb.clip_start;
|
||||
uf.bits0.clp_fence = brw->urb.sf_start;
|
||||
uf.bits1.sf_fence = brw->urb.cs_start;
|
||||
uf.bits1.cs_fence = 256;
|
||||
|
||||
BRW_BATCH_STRUCT(brw, &uf);
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
const struct brw_tracked_state brw_urb_fence = {
|
||||
.dirty = {
|
||||
.mesa = 0,
|
||||
.brw = BRW_NEW_URB_FENCE | BRW_NEW_PSP,
|
||||
.cache = 0
|
||||
},
|
||||
.update = brw_upload_urb_fence
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
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_util.h"
|
||||
#include "brw_defines.h"
|
||||
|
||||
#include "pipe/p_defines.h"
|
||||
|
||||
unsigned brw_count_bits( unsigned val )
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; val ; val >>= 1)
|
||||
if (val & 1)
|
||||
i++;
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
unsigned brw_translate_blend_equation( int mode )
|
||||
{
|
||||
switch (mode) {
|
||||
case PIPE_BLEND_ADD:
|
||||
return BRW_BLENDFUNCTION_ADD;
|
||||
case PIPE_BLEND_MIN:
|
||||
return BRW_BLENDFUNCTION_MIN;
|
||||
case PIPE_BLEND_MAX:
|
||||
return BRW_BLENDFUNCTION_MAX;
|
||||
case PIPE_BLEND_SUBTRACT:
|
||||
return BRW_BLENDFUNCTION_SUBTRACT;
|
||||
case PIPE_BLEND_REVERSE_SUBTRACT:
|
||||
return BRW_BLENDFUNCTION_REVERSE_SUBTRACT;
|
||||
default:
|
||||
assert(0);
|
||||
return BRW_BLENDFUNCTION_ADD;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned brw_translate_blend_factor( int factor )
|
||||
{
|
||||
switch(factor) {
|
||||
case PIPE_BLENDFACTOR_ZERO:
|
||||
return BRW_BLENDFACTOR_ZERO;
|
||||
case PIPE_BLENDFACTOR_SRC_ALPHA:
|
||||
return BRW_BLENDFACTOR_SRC_ALPHA;
|
||||
case PIPE_BLENDFACTOR_ONE:
|
||||
return BRW_BLENDFACTOR_ONE;
|
||||
case PIPE_BLENDFACTOR_SRC_COLOR:
|
||||
return BRW_BLENDFACTOR_SRC_COLOR;
|
||||
case PIPE_BLENDFACTOR_INV_SRC_COLOR:
|
||||
return BRW_BLENDFACTOR_INV_SRC_COLOR;
|
||||
case PIPE_BLENDFACTOR_DST_COLOR:
|
||||
return BRW_BLENDFACTOR_DST_COLOR;
|
||||
case PIPE_BLENDFACTOR_INV_DST_COLOR:
|
||||
return BRW_BLENDFACTOR_INV_DST_COLOR;
|
||||
case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
|
||||
return BRW_BLENDFACTOR_INV_SRC_ALPHA;
|
||||
case PIPE_BLENDFACTOR_DST_ALPHA:
|
||||
return BRW_BLENDFACTOR_DST_ALPHA;
|
||||
case PIPE_BLENDFACTOR_INV_DST_ALPHA:
|
||||
return BRW_BLENDFACTOR_INV_DST_ALPHA;
|
||||
case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
|
||||
return BRW_BLENDFACTOR_SRC_ALPHA_SATURATE;
|
||||
case PIPE_BLENDFACTOR_CONST_COLOR:
|
||||
return BRW_BLENDFACTOR_CONST_COLOR;
|
||||
case PIPE_BLENDFACTOR_INV_CONST_COLOR:
|
||||
return BRW_BLENDFACTOR_INV_CONST_COLOR;
|
||||
case PIPE_BLENDFACTOR_CONST_ALPHA:
|
||||
return BRW_BLENDFACTOR_CONST_ALPHA;
|
||||
case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
|
||||
return BRW_BLENDFACTOR_INV_CONST_ALPHA;
|
||||
default:
|
||||
assert(0);
|
||||
return BRW_BLENDFACTOR_ZERO;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
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>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef BRW_UTIL_H
|
||||
#define BRW_UTIL_H
|
||||
|
||||
#include "pipe/p_state.h"
|
||||
|
||||
extern unsigned brw_count_bits( unsigned val );
|
||||
extern unsigned brw_translate_blend_factor( int factor );
|
||||
extern unsigned brw_translate_blend_equation( int mode );
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
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"
|
||||
#include "brw_util.h"
|
||||
#include "brw_state.h"
|
||||
|
||||
|
||||
static void do_vs_prog( struct brw_context *brw,
|
||||
const struct brw_vertex_program *vp,
|
||||
struct brw_vs_prog_key *key )
|
||||
{
|
||||
unsigned program_size;
|
||||
const unsigned *program;
|
||||
struct brw_vs_compile c;
|
||||
|
||||
memset(&c, 0, sizeof(c));
|
||||
memcpy(&c.key, key, sizeof(*key));
|
||||
|
||||
brw_init_compile(&c.func);
|
||||
c.vp = vp;
|
||||
|
||||
c.prog_data.outputs_written = vp->program.num_outputs;
|
||||
c.prog_data.inputs_read = vp->program.num_inputs;
|
||||
|
||||
#if 0
|
||||
if (c.key.copy_edgeflag) {
|
||||
c.prog_data.outputs_written |= 1<<VERT_RESULT_EDGE;
|
||||
c.prog_data.inputs_read |= 1<<VERT_ATTRIB_EDGEFLAG;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Emit GEN4 code.
|
||||
*/
|
||||
brw_vs_emit(&c);
|
||||
|
||||
/* get the program
|
||||
*/
|
||||
program = brw_get_program(&c.func, &program_size);
|
||||
|
||||
/*
|
||||
*/
|
||||
brw->vs.prog_gs_offset = brw_upload_cache( &brw->cache[BRW_VS_PROG],
|
||||
&c.key,
|
||||
sizeof(c.key),
|
||||
program,
|
||||
program_size,
|
||||
&c.prog_data,
|
||||
&brw->vs.prog_data);
|
||||
}
|
||||
|
||||
|
||||
static void brw_upload_vs_prog( struct brw_context *brw )
|
||||
{
|
||||
struct brw_vs_prog_key key;
|
||||
const struct brw_vertex_program *vp = brw->attribs.VertexProgram;
|
||||
|
||||
assert(vp);
|
||||
|
||||
memset(&key, 0, sizeof(key));
|
||||
|
||||
/* Just upload the program verbatim for now. Always send it all
|
||||
* the inputs it asks for, whether they are varying or not.
|
||||
*/
|
||||
key.program_string_id = vp->id;
|
||||
key.nr_userclip = brw->attribs.Clip.nr;
|
||||
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],
|
||||
&key, sizeof(key),
|
||||
&brw->vs.prog_data,
|
||||
&brw->vs.prog_gs_offset))
|
||||
return;
|
||||
|
||||
do_vs_prog(brw, vp, &key);
|
||||
}
|
||||
|
||||
|
||||
/* See brw_vs.c:
|
||||
*/
|
||||
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
|
||||
},
|
||||
.update = brw_upload_vs_prog
|
||||
};
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
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>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef BRW_VS_H
|
||||
#define BRW_VS_H
|
||||
|
||||
|
||||
#include "brw_context.h"
|
||||
#include "brw_eu.h"
|
||||
|
||||
|
||||
struct brw_vs_prog_key {
|
||||
unsigned program_string_id;
|
||||
unsigned nr_userclip:4;
|
||||
unsigned copy_edgeflag:1;
|
||||
unsigned know_w_is_one:1;
|
||||
unsigned pad:26;
|
||||
};
|
||||
|
||||
|
||||
struct brw_vs_compile {
|
||||
struct brw_compile func;
|
||||
struct brw_vs_prog_key key;
|
||||
struct brw_vs_prog_data prog_data;
|
||||
|
||||
struct brw_vertex_program *vp;
|
||||
|
||||
unsigned nr_inputs;
|
||||
|
||||
unsigned first_output;
|
||||
unsigned nr_outputs;
|
||||
|
||||
unsigned first_tmp;
|
||||
unsigned last_tmp;
|
||||
|
||||
struct brw_reg r0;
|
||||
struct brw_reg r1;
|
||||
struct brw_reg regs[12][128];
|
||||
struct brw_reg tmp;
|
||||
struct brw_reg stack;
|
||||
|
||||
struct {
|
||||
boolean used_in_src;
|
||||
struct brw_reg reg;
|
||||
} output_regs[128];
|
||||
|
||||
struct brw_reg userplane[6];
|
||||
|
||||
};
|
||||
|
||||
void brw_vs_emit( struct brw_vs_compile *c );
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,223 @@
|
||||
/*
|
||||
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
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
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_state.h"
|
||||
#include "brw_defines.h"
|
||||
|
||||
#include "pipe/p_util.h"
|
||||
|
||||
static void upload_vs_unit( struct brw_context *brw )
|
||||
{
|
||||
struct brw_vs_unit_state vs;
|
||||
|
||||
memset(&vs, 0, sizeof(vs));
|
||||
|
||||
/* 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.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;
|
||||
|
||||
|
||||
/* BRW_NEW_URB_FENCE */
|
||||
vs.thread4.nr_urb_entries = brw->urb.nr_vs_entries;
|
||||
vs.thread4.urb_entry_allocation_size = brw->urb.vsize - 1;
|
||||
vs.thread4.max_threads = MIN2(
|
||||
MAX2(0, (brw->urb.nr_vs_entries - 6) / 2 - 1),
|
||||
15);
|
||||
|
||||
|
||||
|
||||
if (BRW_DEBUG & DEBUG_SINGLE_THREAD)
|
||||
vs.thread4.max_threads = 0;
|
||||
|
||||
/* BRW_NEW_CURBE_OFFSETS, _NEW_TRANSFORM */
|
||||
if (0 /*brw->attribs.Clip->ClipPlanesEnabled*/) {
|
||||
/* Note that we read in the userclip planes as well, hence
|
||||
* clip_start:
|
||||
*/
|
||||
vs.thread3.const_urb_entry_read_offset = brw->curbe.clip_start * 2;
|
||||
}
|
||||
else {
|
||||
vs.thread3.const_urb_entry_read_offset = brw->curbe.vs_start * 2;
|
||||
}
|
||||
|
||||
vs.thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754;
|
||||
vs.thread3.urb_entry_read_offset = 0;
|
||||
|
||||
/* No samplers for ARB_vp programs:
|
||||
*/
|
||||
vs.vs5.sampler_count = 0;
|
||||
|
||||
if (BRW_DEBUG & DEBUG_STATS)
|
||||
vs.thread4.stats_enable = 1;
|
||||
|
||||
/* Vertex program always enabled:
|
||||
*/
|
||||
vs.vs6.vs_enable = 1;
|
||||
|
||||
brw->vs.state_gs_offset = brw_cache_data( &brw->cache[BRW_VS_UNIT], &vs );
|
||||
}
|
||||
|
||||
|
||||
const struct brw_tracked_state brw_vs_unit = {
|
||||
.dirty = {
|
||||
.brw = (BRW_NEW_CLIP |
|
||||
BRW_NEW_CURBE_OFFSETS |
|
||||
BRW_NEW_URB_FENCE),
|
||||
.cache = CACHE_NEW_VS_PROG
|
||||
},
|
||||
.update = upload_vs_unit
|
||||
};
|
||||
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
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
|
||||
@@ -0,0 +1,192 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* 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, sub license, 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 NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS 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.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* This is the interface that i965simple requires any window system
|
||||
* hosting it to implement. This is the only include file in i965simple
|
||||
* which is public.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BRW_WINSYS_H
|
||||
#define BRW_WINSYS_H
|
||||
|
||||
|
||||
#include "pipe/p_defines.h"
|
||||
|
||||
|
||||
/* Pipe drivers are (meant to be!) independent of both GL and the
|
||||
* window system. The window system provides a buffer manager and a
|
||||
* set of additional hooks for things like command buffer submission,
|
||||
* etc.
|
||||
*
|
||||
* There clearly has to be some agreement between the window system
|
||||
* driver and the hardware driver about the format of command buffers,
|
||||
* etc.
|
||||
*/
|
||||
|
||||
struct pipe_buffer_handle;
|
||||
struct pipe_fence_handle;
|
||||
struct pipe_winsys;
|
||||
|
||||
/* The pipe driver currently understands the following chipsets:
|
||||
*/
|
||||
#define PCI_CHIP_I965_G 0x29A2
|
||||
#define PCI_CHIP_I965_Q 0x2992
|
||||
#define PCI_CHIP_I965_G_1 0x2982
|
||||
#define PCI_CHIP_I965_GM 0x2A02
|
||||
#define PCI_CHIP_I965_GME 0x2A12
|
||||
|
||||
|
||||
/* These are the names of all the state caches managed by the driver.
|
||||
*
|
||||
* When data is uploaded to a buffer with buffer_subdata, we use the
|
||||
* special version of that function below so that information about
|
||||
* what type of data this is can be passed to the winsys backend.
|
||||
* That in turn allows the correct flags to be set in the aub file
|
||||
* dump to allow human-readable file dumps later on.
|
||||
*/
|
||||
|
||||
enum brw_cache_id {
|
||||
BRW_CC_VP,
|
||||
BRW_CC_UNIT,
|
||||
BRW_WM_PROG,
|
||||
BRW_SAMPLER_DEFAULT_COLOR,
|
||||
BRW_SAMPLER,
|
||||
BRW_WM_UNIT,
|
||||
BRW_SF_PROG,
|
||||
BRW_SF_VP,
|
||||
BRW_SF_UNIT,
|
||||
BRW_VS_UNIT,
|
||||
BRW_VS_PROG,
|
||||
BRW_GS_UNIT,
|
||||
BRW_GS_PROG,
|
||||
BRW_CLIP_VP,
|
||||
BRW_CLIP_UNIT,
|
||||
BRW_CLIP_PROG,
|
||||
BRW_SS_SURFACE,
|
||||
BRW_SS_SURF_BIND,
|
||||
|
||||
BRW_MAX_CACHE
|
||||
};
|
||||
|
||||
/**
|
||||
* Additional winsys interface for i965simple.
|
||||
*
|
||||
* It is an over-simple batchbuffer mechanism. Will want to improve the
|
||||
* performance of this, perhaps based on the cmdstream stuff. It
|
||||
* would be pretty impossible to implement swz on top of this
|
||||
* interface.
|
||||
*
|
||||
* Will also need additions/changes to implement static/dynamic
|
||||
* indirect state.
|
||||
*/
|
||||
struct brw_winsys {
|
||||
|
||||
/**
|
||||
* Reserve space on batch buffer.
|
||||
*
|
||||
* Returns a null pointer if there is insufficient space in the batch buffer
|
||||
* to hold the requested number of dwords and relocations.
|
||||
*
|
||||
* The number of dwords should also include the number of relocations.
|
||||
*/
|
||||
unsigned *(*batch_start)(struct brw_winsys *sws,
|
||||
unsigned dwords,
|
||||
unsigned relocs);
|
||||
|
||||
void (*batch_dword)(struct brw_winsys *sws,
|
||||
unsigned dword);
|
||||
|
||||
/**
|
||||
* Emit a relocation to a buffer.
|
||||
*
|
||||
* Used not only when the buffer addresses are not pinned, but also to
|
||||
* ensure refered buffers will not be destroyed until the current batch
|
||||
* buffer execution is finished.
|
||||
*
|
||||
* The access flags is a combination of I915_BUFFER_ACCESS_WRITE and
|
||||
* I915_BUFFER_ACCESS_READ macros.
|
||||
*/
|
||||
void (*batch_reloc)(struct brw_winsys *sws,
|
||||
struct pipe_buffer_handle *buf,
|
||||
unsigned access_flags,
|
||||
unsigned delta);
|
||||
|
||||
|
||||
/* Not used yet, but really want this:
|
||||
*/
|
||||
void (*batch_end)( struct brw_winsys *sws );
|
||||
|
||||
/**
|
||||
* Flush the batch buffer.
|
||||
*
|
||||
* Fence argument must point to NULL or to a previous fence, and the caller
|
||||
* must call fence_reference when done with the fence.
|
||||
*/
|
||||
void (*batch_flush)(struct brw_winsys *sws,
|
||||
struct pipe_fence_handle **fence);
|
||||
|
||||
|
||||
/* A version of buffer_subdata that includes information for the
|
||||
* simulator:
|
||||
*/
|
||||
void (*buffer_subdata_typed)(struct brw_winsys *sws,
|
||||
struct pipe_buffer_handle *buf,
|
||||
unsigned long offset,
|
||||
unsigned long size,
|
||||
const void *data,
|
||||
unsigned data_type);
|
||||
|
||||
|
||||
};
|
||||
|
||||
#define BRW_BUFFER_ACCESS_WRITE 0x1
|
||||
#define BRW_BUFFER_ACCESS_READ 0x2
|
||||
|
||||
#define BRW_BUFFER_USAGE_LIT_VERTEX (PIPE_BUFFER_USAGE_CUSTOM << 0)
|
||||
|
||||
|
||||
struct pipe_context *brw_create(struct pipe_winsys *,
|
||||
struct brw_winsys *,
|
||||
unsigned pci_id);
|
||||
|
||||
static inline boolean brw_batchbuffer_data(struct brw_winsys *winsys,
|
||||
const void *data,
|
||||
unsigned bytes)
|
||||
{
|
||||
static const unsigned incr = sizeof(unsigned);
|
||||
int i;
|
||||
const unsigned *udata = (const unsigned*)(data);
|
||||
unsigned size = bytes/incr;
|
||||
for (i = 0; i < size; ++i) {
|
||||
winsys->batch_dword(winsys, udata[i]);
|
||||
}
|
||||
return (i == size);
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,338 @@
|
||||
/*
|
||||
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_util.h"
|
||||
#include "brw_wm.h"
|
||||
#include "brw_state.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;
|
||||
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->fp = fp;
|
||||
fprintf(stderr, "XXXXXXXX FP\n");
|
||||
|
||||
#if 0
|
||||
c->env_param = brw->intel.ctx.FragmentProgram.Parameters;
|
||||
|
||||
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);
|
||||
|
||||
/*
|
||||
*/
|
||||
brw->wm.prog_gs_offset = brw_upload_cache( &brw->cache[BRW_WM_PROG],
|
||||
&c->key,
|
||||
sizeof(c->key),
|
||||
program,
|
||||
program_size,
|
||||
&c->prog_data,
|
||||
&brw->wm.prog_data );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void brw_wm_populate_key( struct brw_context *brw,
|
||||
struct brw_wm_prog_key *key )
|
||||
{
|
||||
/* BRW_NEW_FRAGMENT_PROGRAM */
|
||||
struct brw_fragment_program *fp =
|
||||
(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
|
||||
*/
|
||||
/* _NEW_COLOR */
|
||||
if (fp->UsesKill ||
|
||||
brw->attribs.AlphaTest->enabled)
|
||||
lookup |= IZ_PS_KILL_ALPHATEST_BIT;
|
||||
|
||||
if (fp->ComputesDepth)
|
||||
lookup |= IZ_PS_COMPUTES_DEPTH_BIT;
|
||||
|
||||
/* _NEW_DEPTH */
|
||||
if (brw->attribs.DepthStencil->depth.enabled)
|
||||
lookup |= IZ_DEPTH_TEST_ENABLE_BIT;
|
||||
|
||||
if (brw->attribs.DepthStencil->depth.enabled &&
|
||||
brw->attribs.DepthStencil->depth.writemask) /* ?? */
|
||||
lookup |= IZ_DEPTH_WRITE_ENABLE_BIT;
|
||||
|
||||
/* _NEW_STENCIL */
|
||||
if (brw->attribs.DepthStencil->stencil.front_enabled) {
|
||||
lookup |= IZ_STENCIL_TEST_ENABLE_BIT;
|
||||
|
||||
if (brw->attribs.DepthStencil->stencil.write_mask[0] ||
|
||||
(brw->attribs.DepthStencil->stencil.back_enabled &&
|
||||
brw->attribs.DepthStencil->stencil.write_mask[1]))
|
||||
lookup |= IZ_STENCIL_WRITE_ENABLE_BIT;
|
||||
}
|
||||
|
||||
/* XXX: when should this be disabled?
|
||||
*/
|
||||
if (1)
|
||||
lookup |= IZ_EARLY_DEPTH_TEST_BIT;
|
||||
|
||||
|
||||
line_aa = AA_NEVER;
|
||||
|
||||
/* _NEW_LINE, _NEW_POLYGON, BRW_NEW_REDUCED_PRIMITIVE */
|
||||
if (brw->attribs.Raster->line_smooth) {
|
||||
if (brw->reduced_primitive == PIPE_PRIM_LINES) {
|
||||
line_aa = AA_ALWAYS;
|
||||
}
|
||||
else if (brw->reduced_primitive == PIPE_PRIM_TRIANGLES) {
|
||||
if (brw->attribs.Raster->fill_ccw == PIPE_POLYGON_MODE_LINE) {
|
||||
line_aa = AA_SOMETIMES;
|
||||
|
||||
if (brw->attribs.Raster->fill_cw == PIPE_POLYGON_MODE_LINE ||
|
||||
(brw->attribs.Raster->cull_mode == PIPE_WINDING_CW))
|
||||
line_aa = AA_ALWAYS;
|
||||
}
|
||||
else if (brw->attribs.Raster->fill_cw == PIPE_POLYGON_MODE_LINE) {
|
||||
line_aa = AA_SOMETIMES;
|
||||
|
||||
if (brw->attribs.Raster->cull_mode == PIPE_WINDING_CCW)
|
||||
line_aa = AA_ALWAYS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
brw_wm_lookup_iz(line_aa,
|
||||
lookup,
|
||||
key);
|
||||
|
||||
|
||||
#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 */
|
||||
for (i = 0; i < BRW_MAX_TEX_UNIT; i++) {
|
||||
const struct pipe_sampler_state *unit = brw->attribs.Samplers[i];
|
||||
|
||||
if (unit) {
|
||||
|
||||
if (unit->compare &&
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Extra info:
|
||||
*/
|
||||
key->program_string_id = fp->id;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void brw_upload_wm_prog( struct brw_context *brw )
|
||||
{
|
||||
struct brw_wm_prog_key key;
|
||||
struct brw_fragment_program *fp = (struct brw_fragment_program *)
|
||||
brw->attribs.FragmentProgram;
|
||||
|
||||
brw_wm_populate_key(brw, &key);
|
||||
|
||||
/* Make an early check for the key.
|
||||
*/
|
||||
if (brw_search_cache(&brw->cache[BRW_WM_PROG],
|
||||
&key, sizeof(key),
|
||||
&brw->wm.prog_data,
|
||||
&brw->wm.prog_gs_offset))
|
||||
return;
|
||||
|
||||
do_wm_prog(brw, fp, &key);
|
||||
}
|
||||
|
||||
|
||||
const struct brw_tracked_state brw_wm_prog = {
|
||||
.dirty = {
|
||||
.brw = (BRW_NEW_FS |
|
||||
BRW_NEW_WM_INPUT_DIMENSIONS |
|
||||
BRW_NEW_REDUCED_PRIMITIVE),
|
||||
.cache = 0
|
||||
},
|
||||
.update = brw_upload_wm_prog
|
||||
};
|
||||
|
||||
@@ -0,0 +1,274 @@
|
||||
/*
|
||||
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>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef BRW_WM_H
|
||||
#define BRW_WM_H
|
||||
|
||||
|
||||
#include "brw_context.h"
|
||||
#include "brw_eu.h"
|
||||
|
||||
/* A big lookup table is used to figure out which and how many
|
||||
* additional regs will inserted before the main payload in the WM
|
||||
* program execution. These mainly relate to depth and stencil
|
||||
* processing and the early-depth-test optimization.
|
||||
*/
|
||||
#define IZ_PS_KILL_ALPHATEST_BIT 0x1
|
||||
#define IZ_PS_COMPUTES_DEPTH_BIT 0x2
|
||||
#define IZ_DEPTH_WRITE_ENABLE_BIT 0x4
|
||||
#define IZ_DEPTH_TEST_ENABLE_BIT 0x8
|
||||
#define IZ_STENCIL_WRITE_ENABLE_BIT 0x10
|
||||
#define IZ_STENCIL_TEST_ENABLE_BIT 0x20
|
||||
#define IZ_EARLY_DEPTH_TEST_BIT 0x40
|
||||
#define IZ_BIT_MAX 0x80
|
||||
|
||||
#define AA_NEVER 0
|
||||
#define AA_SOMETIMES 1
|
||||
#define AA_ALWAYS 2
|
||||
|
||||
struct brw_wm_prog_key {
|
||||
unsigned source_depth_reg:3;
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
/* 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)
|
||||
#define BRW_WM_MAX_GRF 128 /* hardware limit */
|
||||
#define BRW_WM_MAX_VREG (BRW_WM_MAX_INSN * 4)
|
||||
#define BRW_WM_MAX_REF (BRW_WM_MAX_INSN * 12)
|
||||
#define BRW_WM_MAX_PARAM 256
|
||||
#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)
|
||||
|
||||
struct brw_wm_compile {
|
||||
struct brw_compile func;
|
||||
struct brw_wm_prog_key key;
|
||||
struct brw_wm_prog_data prog_data;
|
||||
|
||||
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 emit_mask_reg;
|
||||
unsigned reg_index;
|
||||
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
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
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_wm.h"
|
||||
|
||||
#if 0
|
||||
void brw_wm_print_value( struct brw_wm_compile *c,
|
||||
struct brw_wm_value *value )
|
||||
{
|
||||
assert(value);
|
||||
if (c->state >= PASS2_DONE)
|
||||
brw_print_reg(value->hw_reg);
|
||||
else if( value == &c->undef_value )
|
||||
_mesa_printf("undef");
|
||||
else if( value - c->vreg >= 0 &&
|
||||
value - c->vreg < BRW_WM_MAX_VREG)
|
||||
_mesa_printf("r%d", value - c->vreg);
|
||||
else if (value - c->creg >= 0 &&
|
||||
value - c->creg < BRW_WM_MAX_PARAM)
|
||||
_mesa_printf("c%d", value - c->creg);
|
||||
else if (value - c->payload.input_interp >= 0 &&
|
||||
value - c->payload.input_interp < FRAG_ATTRIB_MAX)
|
||||
_mesa_printf("i%d", value - c->payload.input_interp);
|
||||
else if (value - c->payload.depth >= 0 &&
|
||||
value - c->payload.depth < FRAG_ATTRIB_MAX)
|
||||
_mesa_printf("d%d", value - c->payload.depth);
|
||||
else
|
||||
_mesa_printf("?");
|
||||
}
|
||||
|
||||
void brw_wm_print_ref( struct brw_wm_compile *c,
|
||||
struct brw_wm_ref *ref )
|
||||
{
|
||||
struct brw_reg hw_reg = ref->hw_reg;
|
||||
|
||||
if (ref->unspill_reg)
|
||||
_mesa_printf("UNSPILL(%x)/", ref->value->spill_slot);
|
||||
|
||||
if (c->state >= PASS2_DONE)
|
||||
brw_print_reg(ref->hw_reg);
|
||||
else {
|
||||
_mesa_printf("%s", hw_reg.negate ? "-" : "");
|
||||
_mesa_printf("%s", hw_reg.abs ? "abs/" : "");
|
||||
brw_wm_print_value(c, ref->value);
|
||||
if ((hw_reg.nr&1) || hw_reg.subnr) {
|
||||
_mesa_printf("->%d.%d", (hw_reg.nr&1), hw_reg.subnr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void brw_wm_print_insn( struct brw_wm_compile *c,
|
||||
struct brw_wm_instruction *inst )
|
||||
{
|
||||
unsigned i, arg;
|
||||
unsigned nr_args = brw_wm_nr_args(inst->opcode);
|
||||
|
||||
_mesa_printf("[");
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (inst->dst[i]) {
|
||||
brw_wm_print_value(c, inst->dst[i]);
|
||||
if (inst->dst[i]->spill_slot)
|
||||
_mesa_printf("/SPILL(%x)",inst->dst[i]->spill_slot);
|
||||
}
|
||||
else
|
||||
_mesa_printf("#");
|
||||
if (i < 3)
|
||||
_mesa_printf(",");
|
||||
}
|
||||
_mesa_printf("]");
|
||||
|
||||
if (inst->writemask != WRITEMASK_XYZW)
|
||||
_mesa_printf(".%s%s%s%s",
|
||||
GET_BIT(inst->writemask, 0) ? "x" : "",
|
||||
GET_BIT(inst->writemask, 1) ? "y" : "",
|
||||
GET_BIT(inst->writemask, 2) ? "z" : "",
|
||||
GET_BIT(inst->writemask, 3) ? "w" : "");
|
||||
|
||||
switch (inst->opcode) {
|
||||
case WM_PIXELXY:
|
||||
_mesa_printf(" = PIXELXY");
|
||||
break;
|
||||
case WM_DELTAXY:
|
||||
_mesa_printf(" = DELTAXY");
|
||||
break;
|
||||
case WM_PIXELW:
|
||||
_mesa_printf(" = PIXELW");
|
||||
break;
|
||||
case WM_WPOSXY:
|
||||
_mesa_printf(" = WPOSXY");
|
||||
break;
|
||||
case WM_PINTERP:
|
||||
_mesa_printf(" = PINTERP");
|
||||
break;
|
||||
case WM_LINTERP:
|
||||
_mesa_printf(" = LINTERP");
|
||||
break;
|
||||
case WM_CINTERP:
|
||||
_mesa_printf(" = CINTERP");
|
||||
break;
|
||||
case WM_FB_WRITE:
|
||||
_mesa_printf(" = FB_WRITE");
|
||||
break;
|
||||
default:
|
||||
_mesa_printf(" = %s", _mesa_opcode_string(inst->opcode));
|
||||
break;
|
||||
}
|
||||
|
||||
if (inst->saturate)
|
||||
_mesa_printf("_SAT");
|
||||
|
||||
for (arg = 0; arg < nr_args; arg++) {
|
||||
|
||||
_mesa_printf(" [");
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (inst->src[arg][i]) {
|
||||
brw_wm_print_ref(c, inst->src[arg][i]);
|
||||
}
|
||||
else
|
||||
_mesa_printf("%%");
|
||||
|
||||
if (i < 3)
|
||||
_mesa_printf(",");
|
||||
else
|
||||
_mesa_printf("]");
|
||||
}
|
||||
}
|
||||
_mesa_printf("\n");
|
||||
}
|
||||
|
||||
void brw_wm_print_program( struct brw_wm_compile *c,
|
||||
const char *stage )
|
||||
{
|
||||
unsigned insn;
|
||||
|
||||
_mesa_printf("\n\n\n%s:\n", stage);
|
||||
for (insn = 0; insn < c->nr_insns; insn++)
|
||||
brw_wm_print_insn(c, &c->instruction[insn]);
|
||||
_mesa_printf("\n\n\n");
|
||||
}
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
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_wm.h"
|
||||
|
||||
|
||||
#undef P /* prompted depth */
|
||||
#undef C /* computed */
|
||||
#undef N /* non-promoted? */
|
||||
|
||||
#define P 0
|
||||
#define C 1
|
||||
#define N 2
|
||||
|
||||
const struct {
|
||||
unsigned mode:2;
|
||||
unsigned sd_present:1;
|
||||
unsigned sd_to_rt:1;
|
||||
unsigned dd_present:1;
|
||||
unsigned ds_present:1;
|
||||
} wm_iz_table[IZ_BIT_MAX] =
|
||||
{
|
||||
{ P, 0, 0, 0, 0 },
|
||||
{ P, 0, 0, 0, 0 },
|
||||
{ C, 0, 1, 0, 0 },
|
||||
{ C, 0, 1, 0, 0 },
|
||||
{ C, 1, 1, 0, 0 },
|
||||
{ C, 1, 1, 0, 0 },
|
||||
{ C, 0, 1, 0, 0 },
|
||||
{ C, 0, 1, 0, 0 },
|
||||
{ C, 1, 1, 1, 0 },
|
||||
{ C, 1, 1, 1, 0 },
|
||||
{ C, 0, 1, 1, 0 },
|
||||
{ C, 0, 1, 1, 0 },
|
||||
{ C, 1, 1, 1, 0 },
|
||||
{ C, 1, 1, 1, 0 },
|
||||
{ C, 0, 1, 1, 0 },
|
||||
{ C, 0, 1, 1, 0 },
|
||||
{ P, 0, 0, 0, 0 },
|
||||
{ P, 0, 0, 0, 0 },
|
||||
{ C, 0, 1, 0, 0 },
|
||||
{ C, 0, 1, 0, 0 },
|
||||
{ C, 1, 1, 0, 0 },
|
||||
{ C, 1, 1, 0, 0 },
|
||||
{ C, 0, 1, 0, 0 },
|
||||
{ C, 0, 1, 0, 0 },
|
||||
{ C, 1, 1, 1, 0 },
|
||||
{ C, 1, 1, 1, 0 },
|
||||
{ C, 0, 1, 1, 0 },
|
||||
{ C, 0, 1, 1, 0 },
|
||||
{ C, 1, 1, 1, 0 },
|
||||
{ C, 1, 1, 1, 0 },
|
||||
{ C, 0, 1, 1, 0 },
|
||||
{ C, 0, 1, 1, 0 },
|
||||
{ C, 0, 0, 0, 1 },
|
||||
{ C, 0, 0, 0, 1 },
|
||||
{ C, 0, 1, 0, 1 },
|
||||
{ C, 0, 1, 0, 1 },
|
||||
{ C, 1, 1, 0, 1 },
|
||||
{ C, 1, 1, 0, 1 },
|
||||
{ C, 0, 1, 0, 1 },
|
||||
{ C, 0, 1, 0, 1 },
|
||||
{ C, 1, 1, 1, 1 },
|
||||
{ C, 1, 1, 1, 1 },
|
||||
{ C, 0, 1, 1, 1 },
|
||||
{ C, 0, 1, 1, 1 },
|
||||
{ C, 1, 1, 1, 1 },
|
||||
{ C, 1, 1, 1, 1 },
|
||||
{ C, 0, 1, 1, 1 },
|
||||
{ C, 0, 1, 1, 1 },
|
||||
{ C, 0, 0, 0, 1 },
|
||||
{ C, 0, 0, 0, 1 },
|
||||
{ C, 0, 1, 0, 1 },
|
||||
{ C, 0, 1, 0, 1 },
|
||||
{ C, 1, 1, 0, 1 },
|
||||
{ C, 1, 1, 0, 1 },
|
||||
{ C, 0, 1, 0, 1 },
|
||||
{ C, 0, 1, 0, 1 },
|
||||
{ C, 1, 1, 1, 1 },
|
||||
{ C, 1, 1, 1, 1 },
|
||||
{ C, 0, 1, 1, 1 },
|
||||
{ C, 0, 1, 1, 1 },
|
||||
{ C, 1, 1, 1, 1 },
|
||||
{ C, 1, 1, 1, 1 },
|
||||
{ C, 0, 1, 1, 1 },
|
||||
{ C, 0, 1, 1, 1 },
|
||||
{ P, 0, 0, 0, 0 },
|
||||
{ P, 0, 0, 0, 0 },
|
||||
{ P, 0, 0, 0, 0 },
|
||||
{ P, 0, 0, 0, 0 },
|
||||
{ P, 0, 0, 0, 0 },
|
||||
{ N, 1, 1, 0, 0 },
|
||||
{ N, 0, 1, 0, 0 },
|
||||
{ N, 0, 1, 0, 0 },
|
||||
{ P, 0, 0, 0, 0 },
|
||||
{ P, 0, 0, 0, 0 },
|
||||
{ C, 0, 1, 1, 0 },
|
||||
{ C, 0, 1, 1, 0 },
|
||||
{ P, 0, 0, 0, 0 },
|
||||
{ N, 1, 1, 0, 0 },
|
||||
{ C, 0, 1, 1, 0 },
|
||||
{ C, 0, 1, 1, 0 },
|
||||
{ P, 0, 0, 0, 0 },
|
||||
{ P, 0, 0, 0, 0 },
|
||||
{ P, 0, 0, 0, 0 },
|
||||
{ P, 0, 0, 0, 0 },
|
||||
{ P, 0, 0, 0, 0 },
|
||||
{ N, 1, 1, 0, 0 },
|
||||
{ N, 0, 1, 0, 0 },
|
||||
{ N, 0, 1, 0, 0 },
|
||||
{ P, 0, 0, 0, 0 },
|
||||
{ P, 0, 0, 0, 0 },
|
||||
{ C, 0, 1, 1, 0 },
|
||||
{ C, 0, 1, 1, 0 },
|
||||
{ P, 0, 0, 0, 0 },
|
||||
{ N, 1, 1, 0, 0 },
|
||||
{ C, 0, 1, 1, 0 },
|
||||
{ C, 0, 1, 1, 0 },
|
||||
{ P, 0, 0, 0, 0 },
|
||||
{ P, 0, 0, 0, 0 },
|
||||
{ P, 0, 0, 0, 0 },
|
||||
{ P, 0, 0, 0, 0 },
|
||||
{ P, 0, 0, 0, 0 },
|
||||
{ N, 1, 1, 0, 1 },
|
||||
{ N, 0, 1, 0, 1 },
|
||||
{ N, 0, 1, 0, 1 },
|
||||
{ P, 0, 0, 0, 0 },
|
||||
{ P, 0, 0, 0, 0 },
|
||||
{ C, 0, 1, 1, 1 },
|
||||
{ C, 0, 1, 1, 1 },
|
||||
{ P, 0, 0, 0, 0 },
|
||||
{ N, 1, 1, 0, 1 },
|
||||
{ C, 0, 1, 1, 1 },
|
||||
{ C, 0, 1, 1, 1 },
|
||||
{ P, 0, 0, 0, 0 },
|
||||
{ C, 0, 0, 0, 1 },
|
||||
{ P, 0, 0, 0, 0 },
|
||||
{ C, 0, 1, 0, 1 },
|
||||
{ P, 0, 0, 0, 0 },
|
||||
{ C, 1, 1, 0, 1 },
|
||||
{ C, 0, 1, 0, 1 },
|
||||
{ C, 0, 1, 0, 1 },
|
||||
{ P, 0, 0, 0, 0 },
|
||||
{ C, 1, 1, 1, 1 },
|
||||
{ C, 0, 1, 1, 1 },
|
||||
{ C, 0, 1, 1, 1 },
|
||||
{ P, 0, 0, 0, 0 },
|
||||
{ C, 1, 1, 1, 1 },
|
||||
{ C, 0, 1, 1, 1 },
|
||||
{ C, 0, 1, 1, 1 }
|
||||
};
|
||||
|
||||
void brw_wm_lookup_iz( unsigned line_aa,
|
||||
unsigned lookup,
|
||||
struct brw_wm_prog_key *key )
|
||||
{
|
||||
unsigned reg = 2;
|
||||
|
||||
assert (lookup < IZ_BIT_MAX);
|
||||
|
||||
if (lookup & IZ_PS_COMPUTES_DEPTH_BIT)
|
||||
key->computes_depth = 1;
|
||||
|
||||
if (wm_iz_table[lookup].sd_present) {
|
||||
key->source_depth_reg = reg;
|
||||
reg += 2;
|
||||
}
|
||||
|
||||
if (wm_iz_table[lookup].sd_to_rt)
|
||||
key->source_depth_to_render_target = 1;
|
||||
|
||||
if (wm_iz_table[lookup].ds_present || line_aa != AA_NEVER) {
|
||||
key->aa_dest_stencil_reg = reg;
|
||||
key->runtime_check_aads_emit = (!wm_iz_table[lookup].ds_present &&
|
||||
line_aa == AA_SOMETIMES);
|
||||
reg++;
|
||||
}
|
||||
|
||||
if (wm_iz_table[lookup].dd_present) {
|
||||
key->dest_depth_reg = reg;
|
||||
reg+=2;
|
||||
}
|
||||
|
||||
key->nr_depth_regs = (reg+1)/2;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,466 @@
|
||||
/*
|
||||
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_wm.h"
|
||||
|
||||
|
||||
#if 0
|
||||
/***********************************************************************
|
||||
*/
|
||||
|
||||
static struct brw_wm_ref *get_ref( struct brw_wm_compile *c )
|
||||
{
|
||||
assert(c->nr_refs < BRW_WM_MAX_REF);
|
||||
return &c->refs[c->nr_refs++];
|
||||
}
|
||||
|
||||
static struct brw_wm_value *get_value( struct brw_wm_compile *c)
|
||||
{
|
||||
assert(c->nr_refs < BRW_WM_MAX_VREG);
|
||||
return &c->vreg[c->nr_vreg++];
|
||||
}
|
||||
|
||||
static struct brw_wm_instruction *get_instruction( struct brw_wm_compile *c )
|
||||
{
|
||||
assert(c->nr_insns < BRW_WM_MAX_INSN);
|
||||
return &c->instruction[c->nr_insns++];
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
*/
|
||||
|
||||
static void pass0_init_undef( struct brw_wm_compile *c)
|
||||
{
|
||||
struct brw_wm_ref *ref = &c->undef_ref;
|
||||
ref->value = &c->undef_value;
|
||||
ref->hw_reg = brw_vec8_grf(0, 0);
|
||||
ref->insn = 0;
|
||||
ref->prevuse = NULL;
|
||||
}
|
||||
|
||||
static void pass0_set_fpreg_value( struct brw_wm_compile *c,
|
||||
unsigned file,
|
||||
unsigned idx,
|
||||
unsigned component,
|
||||
struct brw_wm_value *value )
|
||||
{
|
||||
struct brw_wm_ref *ref = get_ref(c);
|
||||
ref->value = value;
|
||||
ref->hw_reg = brw_vec8_grf(0, 0);
|
||||
ref->insn = 0;
|
||||
ref->prevuse = NULL;
|
||||
c->pass0_fp_reg[file][idx][component] = ref;
|
||||
}
|
||||
|
||||
static void pass0_set_fpreg_ref( struct brw_wm_compile *c,
|
||||
unsigned file,
|
||||
unsigned idx,
|
||||
unsigned component,
|
||||
const struct brw_wm_ref *src_ref )
|
||||
{
|
||||
c->pass0_fp_reg[file][idx][component] = src_ref;
|
||||
}
|
||||
|
||||
static const struct brw_wm_ref *get_param_ref( struct brw_wm_compile *c,
|
||||
const float *param_ptr )
|
||||
{
|
||||
unsigned i = c->prog_data.nr_params++;
|
||||
|
||||
if (i >= BRW_WM_MAX_PARAM) {
|
||||
_mesa_printf("%s: out of params\n", __FUNCTION__);
|
||||
c->prog_data.error = 1;
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
struct brw_wm_ref *ref = get_ref(c);
|
||||
|
||||
c->prog_data.param[i] = param_ptr;
|
||||
c->nr_creg = (i+16)/16;
|
||||
|
||||
/* Push the offsets into hw_reg. These will be added to the
|
||||
* real register numbers once one is allocated in pass2.
|
||||
*/
|
||||
ref->hw_reg = brw_vec1_grf((i&8)?1:0, i%8);
|
||||
ref->value = &c->creg[i/16];
|
||||
ref->insn = 0;
|
||||
ref->prevuse = NULL;
|
||||
|
||||
return ref;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static const struct brw_wm_ref *get_const_ref( struct brw_wm_compile *c,
|
||||
const float *constval )
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
/* Search for an existing const value matching the request:
|
||||
*/
|
||||
for (i = 0; i < c->nr_constrefs; i++) {
|
||||
if (c->constref[i].constval == *constval)
|
||||
return c->constref[i].ref;
|
||||
}
|
||||
|
||||
/* Else try to add a new one:
|
||||
*/
|
||||
if (c->nr_constrefs < BRW_WM_MAX_CONST) {
|
||||
unsigned i = c->nr_constrefs++;
|
||||
|
||||
/* A constant is a special type of parameter:
|
||||
*/
|
||||
c->constref[i].constval = *constval;
|
||||
c->constref[i].ref = get_param_ref(c, constval);
|
||||
|
||||
return c->constref[i].ref;
|
||||
}
|
||||
else {
|
||||
_mesa_printf("%s: out of constrefs\n", __FUNCTION__);
|
||||
c->prog_data.error = 1;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Lookup our internal registers
|
||||
*/
|
||||
static const struct brw_wm_ref *pass0_get_reg( struct brw_wm_compile *c,
|
||||
unsigned file,
|
||||
unsigned idx,
|
||||
unsigned component )
|
||||
{
|
||||
const struct brw_wm_ref *ref = c->pass0_fp_reg[file][idx][component];
|
||||
|
||||
if (!ref) {
|
||||
switch (file) {
|
||||
case PROGRAM_INPUT:
|
||||
case PROGRAM_PAYLOAD:
|
||||
case PROGRAM_TEMPORARY:
|
||||
case PROGRAM_OUTPUT:
|
||||
case PROGRAM_VARYING:
|
||||
break;
|
||||
|
||||
case PROGRAM_LOCAL_PARAM:
|
||||
ref = get_param_ref(c, &c->fp->program.Base.LocalParams[idx][component]);
|
||||
break;
|
||||
|
||||
case PROGRAM_ENV_PARAM:
|
||||
ref = get_param_ref(c, &c->env_param[idx][component]);
|
||||
break;
|
||||
|
||||
case PROGRAM_STATE_VAR:
|
||||
case PROGRAM_UNIFORM:
|
||||
case PROGRAM_CONSTANT:
|
||||
case PROGRAM_NAMED_PARAM: {
|
||||
struct gl_program_parameter_list *plist = c->fp->program.Base.Parameters;
|
||||
|
||||
/* There's something really hokey about parameters parsed in
|
||||
* arb programs - they all end up in here, whether they be
|
||||
* state values, paramters or constants. This duplicates the
|
||||
* structure above & also seems to subvert the limits set for
|
||||
* each type of constant/param.
|
||||
*/
|
||||
switch (plist->Parameters[idx].Type) {
|
||||
case PROGRAM_NAMED_PARAM:
|
||||
case PROGRAM_CONSTANT:
|
||||
/* These are invarient:
|
||||
*/
|
||||
ref = get_const_ref(c, &plist->ParameterValues[idx][component]);
|
||||
break;
|
||||
|
||||
case PROGRAM_STATE_VAR:
|
||||
case PROGRAM_UNIFORM:
|
||||
/* These may change from run to run:
|
||||
*/
|
||||
ref = get_param_ref(c, &plist->ParameterValues[idx][component] );
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
c->pass0_fp_reg[file][idx][component] = ref;
|
||||
}
|
||||
|
||||
if (!ref)
|
||||
ref = &c->undef_ref;
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Straight translation to internal instruction format
|
||||
*/
|
||||
|
||||
static void pass0_set_dst( struct brw_wm_compile *c,
|
||||
struct brw_wm_instruction *out,
|
||||
const struct prog_instruction *inst,
|
||||
unsigned writemask )
|
||||
{
|
||||
const struct prog_dst_register *dst = &inst->DstReg;
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (writemask & (1<<i)) {
|
||||
out->dst[i] = get_value(c);
|
||||
|
||||
pass0_set_fpreg_value(c, dst->File, dst->Index, i, out->dst[i]);
|
||||
}
|
||||
}
|
||||
|
||||
out->writemask = writemask;
|
||||
}
|
||||
|
||||
|
||||
static void pass0_set_dst_scalar( struct brw_wm_compile *c,
|
||||
struct brw_wm_instruction *out,
|
||||
const struct prog_instruction *inst,
|
||||
unsigned writemask )
|
||||
{
|
||||
if (writemask) {
|
||||
const struct prog_dst_register *dst = &inst->DstReg;
|
||||
unsigned i;
|
||||
|
||||
/* Compute only the first (X) value:
|
||||
*/
|
||||
out->writemask = WRITEMASK_X;
|
||||
out->dst[0] = get_value(c);
|
||||
|
||||
/* Update our tracking register file for all the components in
|
||||
* writemask:
|
||||
*/
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (writemask & (1<<i)) {
|
||||
pass0_set_fpreg_value(c, dst->File, dst->Index, i, out->dst[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
out->writemask = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const struct brw_wm_ref *get_fp_src_reg_ref( struct brw_wm_compile *c,
|
||||
struct prog_src_register src,
|
||||
unsigned i )
|
||||
{
|
||||
unsigned component = GET_SWZ(src.Swizzle,i);
|
||||
const struct brw_wm_ref *src_ref;
|
||||
static const float const_zero = 0.0;
|
||||
static const float const_one = 1.0;
|
||||
|
||||
|
||||
if (component == SWIZZLE_ZERO)
|
||||
src_ref = get_const_ref(c, &const_zero);
|
||||
else if (component == SWIZZLE_ONE)
|
||||
src_ref = get_const_ref(c, &const_one);
|
||||
else
|
||||
src_ref = pass0_get_reg(c, src.File, src.Index, component);
|
||||
|
||||
return src_ref;
|
||||
}
|
||||
|
||||
|
||||
static struct brw_wm_ref *get_new_ref( struct brw_wm_compile *c,
|
||||
struct prog_src_register src,
|
||||
unsigned i,
|
||||
struct brw_wm_instruction *insn)
|
||||
{
|
||||
const struct brw_wm_ref *ref = get_fp_src_reg_ref(c, src, i);
|
||||
struct brw_wm_ref *newref = get_ref(c);
|
||||
|
||||
newref->value = ref->value;
|
||||
newref->hw_reg = ref->hw_reg;
|
||||
|
||||
if (insn) {
|
||||
newref->insn = insn - c->instruction;
|
||||
newref->prevuse = newref->value->lastuse;
|
||||
newref->value->lastuse = newref;
|
||||
}
|
||||
|
||||
if (src.NegateBase & (1<<i))
|
||||
newref->hw_reg.negate ^= 1;
|
||||
|
||||
if (src.Abs) {
|
||||
newref->hw_reg.negate = 0;
|
||||
newref->hw_reg.abs = 1;
|
||||
}
|
||||
|
||||
return newref;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static struct brw_wm_instruction *translate_insn( struct brw_wm_compile *c,
|
||||
const struct prog_instruction *inst )
|
||||
{
|
||||
struct brw_wm_instruction *out = get_instruction(c);
|
||||
unsigned writemask = inst->DstReg.WriteMask;
|
||||
unsigned nr_args = brw_wm_nr_args(inst->Opcode);
|
||||
unsigned i, j;
|
||||
|
||||
/* Copy some data out of the instruction
|
||||
*/
|
||||
out->opcode = inst->Opcode;
|
||||
out->saturate = (inst->SaturateMode != SATURATE_OFF);
|
||||
out->tex_unit = inst->TexSrcUnit;
|
||||
out->tex_idx = inst->TexSrcTarget;
|
||||
|
||||
/* Args:
|
||||
*/
|
||||
for (i = 0; i < nr_args; i++) {
|
||||
for (j = 0; j < 4; j++) {
|
||||
out->src[i][j] = get_new_ref(c, inst->SrcReg[i], j, out);
|
||||
}
|
||||
}
|
||||
|
||||
/* Dst:
|
||||
*/
|
||||
if (brw_wm_is_scalar_result(out->opcode))
|
||||
pass0_set_dst_scalar(c, out, inst, writemask);
|
||||
else
|
||||
pass0_set_dst(c, out, inst, writemask);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Optimize moves and swizzles away:
|
||||
*/
|
||||
static void pass0_precalc_mov( struct brw_wm_compile *c,
|
||||
const struct prog_instruction *inst )
|
||||
{
|
||||
const struct prog_dst_register *dst = &inst->DstReg;
|
||||
unsigned writemask = inst->DstReg.WriteMask;
|
||||
unsigned i;
|
||||
|
||||
/* Get the effect of a MOV by manipulating our register table:
|
||||
*/
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (writemask & (1<<i)) {
|
||||
pass0_set_fpreg_ref( c, dst->File, dst->Index, i,
|
||||
get_new_ref(c, inst->SrcReg[0], i, NULL));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Initialize payload "registers".
|
||||
*/
|
||||
static void pass0_init_payload( struct brw_wm_compile *c )
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
unsigned j = i >= c->key.nr_depth_regs ? 0 : i;
|
||||
pass0_set_fpreg_value( c, PROGRAM_PAYLOAD, PAYLOAD_DEPTH, i,
|
||||
&c->payload.depth[j] );
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* This seems to be an alternative to the INTERP_WPOS stuff I do
|
||||
* elsewhere:
|
||||
*/
|
||||
if (c->key.source_depth_reg)
|
||||
pass0_set_fpreg_value(c, PROGRAM_INPUT, FRAG_ATTRIB_WPOS, 2,
|
||||
&c->payload.depth[c->key.source_depth_reg/2]);
|
||||
#endif
|
||||
|
||||
for (i = 0; i < FRAG_ATTRIB_MAX; i++)
|
||||
pass0_set_fpreg_value( c, PROGRAM_PAYLOAD, i, 0,
|
||||
&c->payload.input_interp[i] );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* PASS 0
|
||||
*
|
||||
* Work forwards to give each calculated value a unique number. Where
|
||||
* an instruction produces duplicate values (eg DP3), all are given
|
||||
* the same number.
|
||||
*
|
||||
* Translate away swizzling and eliminate non-saturating moves.
|
||||
*/
|
||||
void brw_wm_pass0( struct brw_wm_compile *c )
|
||||
{
|
||||
unsigned insn;
|
||||
|
||||
c->nr_vreg = 0;
|
||||
c->nr_insns = 0;
|
||||
|
||||
pass0_init_undef(c);
|
||||
pass0_init_payload(c);
|
||||
|
||||
for (insn = 0; insn < c->nr_fp_insns; insn++) {
|
||||
const struct prog_instruction *inst = &c->prog_instructions[insn];
|
||||
|
||||
|
||||
/* Optimize away moves, otherwise emit translated instruction:
|
||||
*/
|
||||
switch (inst->Opcode) {
|
||||
case OPCODE_MOV:
|
||||
case OPCODE_SWZ:
|
||||
if (!inst->SaturateMode) {
|
||||
pass0_precalc_mov(c, inst);
|
||||
}
|
||||
else {
|
||||
translate_insn(c, inst);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
translate_insn(c, inst);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (BRW_DEBUG & DEBUG_WM) {
|
||||
brw_wm_print_program(c, "pass0");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,277 @@
|
||||
/*
|
||||
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_wm.h"
|
||||
|
||||
#if 0
|
||||
static unsigned get_tracked_mask(struct brw_wm_compile *c,
|
||||
struct brw_wm_instruction *inst)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (inst->writemask & (1<<i)) {
|
||||
if (!inst->dst[i]->contributes_to_output) {
|
||||
inst->writemask &= ~(1<<i);
|
||||
inst->dst[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return inst->writemask;
|
||||
}
|
||||
|
||||
/* Remove a reference from a value's usage chain.
|
||||
*/
|
||||
static void unlink_ref(struct brw_wm_ref *ref)
|
||||
{
|
||||
struct brw_wm_value *value = ref->value;
|
||||
|
||||
if (ref == value->lastuse) {
|
||||
value->lastuse = ref->prevuse;
|
||||
} else {
|
||||
struct brw_wm_ref *i = value->lastuse;
|
||||
while (i->prevuse != ref) i = i->prevuse;
|
||||
i->prevuse = ref->prevuse;
|
||||
}
|
||||
}
|
||||
|
||||
static void track_arg(struct brw_wm_compile *c,
|
||||
struct brw_wm_instruction *inst,
|
||||
unsigned arg,
|
||||
unsigned readmask)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
struct brw_wm_ref *ref = inst->src[arg][i];
|
||||
if (ref) {
|
||||
if (readmask & (1<<i))
|
||||
ref->value->contributes_to_output = 1;
|
||||
else {
|
||||
unlink_ref(ref);
|
||||
inst->src[arg][i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned get_texcoord_mask( unsigned tex_idx )
|
||||
{
|
||||
switch (tex_idx) {
|
||||
case TEXTURE_1D_INDEX: return WRITEMASK_X;
|
||||
case TEXTURE_2D_INDEX: return WRITEMASK_XY;
|
||||
case TEXTURE_3D_INDEX: return WRITEMASK_XYZ;
|
||||
case TEXTURE_CUBE_INDEX: return WRITEMASK_XYZ;
|
||||
case TEXTURE_RECT_INDEX: return WRITEMASK_XY;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Step two: Basically this is dead code elimination.
|
||||
*
|
||||
* Iterate backwards over instructions, noting which values
|
||||
* contribute to the final result. Adjust writemasks to only
|
||||
* calculate these values.
|
||||
*/
|
||||
void brw_wm_pass1( struct brw_wm_compile *c )
|
||||
{
|
||||
int insn;
|
||||
|
||||
for (insn = c->nr_insns-1; insn >= 0; insn--) {
|
||||
struct brw_wm_instruction *inst = &c->instruction[insn];
|
||||
unsigned writemask;
|
||||
unsigned read0, read1, read2;
|
||||
|
||||
if (inst->opcode == OPCODE_KIL) {
|
||||
track_arg(c, inst, 0, WRITEMASK_XYZW); /* All args contribute to final */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (inst->opcode == WM_FB_WRITE) {
|
||||
track_arg(c, inst, 0, WRITEMASK_XYZW);
|
||||
track_arg(c, inst, 1, WRITEMASK_XYZW);
|
||||
if (c->key.source_depth_to_render_target &&
|
||||
c->key.computes_depth)
|
||||
track_arg(c, inst, 2, WRITEMASK_Z);
|
||||
else
|
||||
track_arg(c, inst, 2, 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Lookup all the registers which were written by this
|
||||
* instruction and get a mask of those that contribute to the output:
|
||||
*/
|
||||
writemask = get_tracked_mask(c, inst);
|
||||
if (!writemask) {
|
||||
unsigned arg;
|
||||
for (arg = 0; arg < 3; arg++)
|
||||
track_arg(c, inst, arg, 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
read0 = 0;
|
||||
read1 = 0;
|
||||
read2 = 0;
|
||||
|
||||
/* Mark all inputs which contribute to the marked outputs:
|
||||
*/
|
||||
switch (inst->opcode) {
|
||||
case OPCODE_ABS:
|
||||
case OPCODE_FLR:
|
||||
case OPCODE_FRC:
|
||||
case OPCODE_MOV:
|
||||
read0 = writemask;
|
||||
break;
|
||||
|
||||
case OPCODE_SUB:
|
||||
case OPCODE_SLT:
|
||||
case OPCODE_SLE:
|
||||
case OPCODE_SGE:
|
||||
case OPCODE_SGT:
|
||||
case OPCODE_SEQ:
|
||||
case OPCODE_SNE:
|
||||
case OPCODE_ADD:
|
||||
case OPCODE_MAX:
|
||||
case OPCODE_MIN:
|
||||
case OPCODE_MUL:
|
||||
read0 = writemask;
|
||||
read1 = writemask;
|
||||
break;
|
||||
|
||||
case OPCODE_MAD:
|
||||
case OPCODE_CMP:
|
||||
case OPCODE_LRP:
|
||||
read0 = writemask;
|
||||
read1 = writemask;
|
||||
read2 = writemask;
|
||||
break;
|
||||
|
||||
case OPCODE_XPD:
|
||||
if (writemask & WRITEMASK_X) read0 |= WRITEMASK_YZ;
|
||||
if (writemask & WRITEMASK_Y) read0 |= WRITEMASK_XZ;
|
||||
if (writemask & WRITEMASK_Z) read0 |= WRITEMASK_XY;
|
||||
read1 = read0;
|
||||
break;
|
||||
|
||||
case OPCODE_COS:
|
||||
case OPCODE_EX2:
|
||||
case OPCODE_LG2:
|
||||
case OPCODE_RCP:
|
||||
case OPCODE_RSQ:
|
||||
case OPCODE_SIN:
|
||||
case OPCODE_SCS:
|
||||
case WM_CINTERP:
|
||||
case WM_PIXELXY:
|
||||
read0 = WRITEMASK_X;
|
||||
break;
|
||||
|
||||
case OPCODE_POW:
|
||||
read0 = WRITEMASK_X;
|
||||
read1 = WRITEMASK_X;
|
||||
break;
|
||||
|
||||
case OPCODE_TEX:
|
||||
read0 = get_texcoord_mask(inst->tex_idx);
|
||||
|
||||
if (c->key.shadowtex_mask & (1<<inst->tex_unit))
|
||||
read0 |= WRITEMASK_Z;
|
||||
break;
|
||||
|
||||
case OPCODE_TXB:
|
||||
/* Shadow ignored for txb.
|
||||
*/
|
||||
read0 = get_texcoord_mask(inst->tex_idx) | WRITEMASK_W;
|
||||
break;
|
||||
|
||||
case WM_WPOSXY:
|
||||
read0 = writemask & WRITEMASK_XY;
|
||||
break;
|
||||
|
||||
case WM_DELTAXY:
|
||||
read0 = writemask & WRITEMASK_XY;
|
||||
read1 = WRITEMASK_X;
|
||||
break;
|
||||
|
||||
case WM_PIXELW:
|
||||
read0 = WRITEMASK_X;
|
||||
read1 = WRITEMASK_XY;
|
||||
break;
|
||||
|
||||
case WM_LINTERP:
|
||||
read0 = WRITEMASK_X;
|
||||
read1 = WRITEMASK_XY;
|
||||
break;
|
||||
|
||||
case WM_PINTERP:
|
||||
read0 = WRITEMASK_X; /* interpolant */
|
||||
read1 = WRITEMASK_XY; /* deltas */
|
||||
read2 = WRITEMASK_W; /* pixel w */
|
||||
break;
|
||||
|
||||
case OPCODE_DP3:
|
||||
read0 = WRITEMASK_XYZ;
|
||||
read1 = WRITEMASK_XYZ;
|
||||
break;
|
||||
|
||||
case OPCODE_DPH:
|
||||
read0 = WRITEMASK_XYZ;
|
||||
read1 = WRITEMASK_XYZW;
|
||||
break;
|
||||
|
||||
case OPCODE_DP4:
|
||||
read0 = WRITEMASK_XYZW;
|
||||
read1 = WRITEMASK_XYZW;
|
||||
break;
|
||||
|
||||
case OPCODE_LIT:
|
||||
read0 = WRITEMASK_XYW;
|
||||
break;
|
||||
|
||||
case OPCODE_SWZ:
|
||||
case OPCODE_DST:
|
||||
case OPCODE_TXP:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
track_arg(c, inst, 0, read0);
|
||||
track_arg(c, inst, 1, read1);
|
||||
track_arg(c, inst, 2, read2);
|
||||
}
|
||||
|
||||
if (BRW_DEBUG & DEBUG_WM) {
|
||||
brw_wm_print_program(c, "pass1");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,335 @@
|
||||
/*
|
||||
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_wm.h"
|
||||
|
||||
#if 0
|
||||
/* Use these to force spilling so that that functionality can be
|
||||
* tested with known-good examples rather than having to construct new
|
||||
* tests.
|
||||
*/
|
||||
#define TEST_PAYLOAD_SPILLS 0
|
||||
#define TEST_DST_SPILLS 0
|
||||
|
||||
static void spill_value(struct brw_wm_compile *c,
|
||||
struct brw_wm_value *value);
|
||||
|
||||
static void prealloc_reg(struct brw_wm_compile *c,
|
||||
struct brw_wm_value *value,
|
||||
unsigned reg)
|
||||
{
|
||||
if (value->lastuse) {
|
||||
/* Set nextuse to zero, it will be corrected by
|
||||
* update_register_usage().
|
||||
*/
|
||||
c->pass2_grf[reg].value = value;
|
||||
c->pass2_grf[reg].nextuse = 0;
|
||||
|
||||
value->resident = &c->pass2_grf[reg];
|
||||
value->hw_reg = brw_vec8_grf(reg*2, 0);
|
||||
|
||||
if (TEST_PAYLOAD_SPILLS)
|
||||
spill_value(c, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Initialize all the register values. Do the initial setup
|
||||
* calculations for interpolants.
|
||||
*/
|
||||
static void init_registers( struct brw_wm_compile *c )
|
||||
{
|
||||
unsigned inputs = FRAG_BIT_WPOS | c->fp_interp_emitted;
|
||||
unsigned nr_interp_regs = 0;
|
||||
unsigned i = 0;
|
||||
unsigned j;
|
||||
|
||||
for (j = 0; j < c->grf_limit; j++)
|
||||
c->pass2_grf[j].nextuse = BRW_WM_MAX_INSN;
|
||||
|
||||
for (j = 0; j < c->key.nr_depth_regs; j++)
|
||||
prealloc_reg(c, &c->payload.depth[j], i++);
|
||||
|
||||
for (j = 0; j < c->nr_creg; j++)
|
||||
prealloc_reg(c, &c->creg[j], i++);
|
||||
|
||||
for (j = 0; j < FRAG_ATTRIB_MAX; j++)
|
||||
if (inputs & (1<<j)) {
|
||||
nr_interp_regs++;
|
||||
prealloc_reg(c, &c->payload.input_interp[j], i++);
|
||||
}
|
||||
|
||||
assert(nr_interp_regs >= 1);
|
||||
|
||||
c->prog_data.first_curbe_grf = c->key.nr_depth_regs * 2;
|
||||
c->prog_data.urb_read_length = nr_interp_regs * 2;
|
||||
c->prog_data.curb_read_length = c->nr_creg * 2;
|
||||
|
||||
c->max_wm_grf = i * 2;
|
||||
}
|
||||
|
||||
|
||||
/* Update the nextuse value for each register in our file.
|
||||
*/
|
||||
static void update_register_usage(struct brw_wm_compile *c,
|
||||
unsigned thisinsn)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 1; i < c->grf_limit; i++) {
|
||||
struct brw_wm_grf *grf = &c->pass2_grf[i];
|
||||
|
||||
/* Only search those which can change:
|
||||
*/
|
||||
if (grf->nextuse < thisinsn) {
|
||||
struct brw_wm_ref *ref = grf->value->lastuse;
|
||||
|
||||
/* Has last use of value been passed?
|
||||
*/
|
||||
if (ref->insn < thisinsn) {
|
||||
grf->value->resident = 0;
|
||||
grf->value = 0;
|
||||
grf->nextuse = BRW_WM_MAX_INSN;
|
||||
}
|
||||
else {
|
||||
/* Else loop through chain to update:
|
||||
*/
|
||||
while (ref->prevuse && ref->prevuse->insn >= thisinsn)
|
||||
ref = ref->prevuse;
|
||||
|
||||
grf->nextuse = ref->insn;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void spill_value(struct brw_wm_compile *c,
|
||||
struct brw_wm_value *value)
|
||||
{
|
||||
/* Allocate a spill slot. Note that allocations start from 0x40 -
|
||||
* the first slot is reserved to mean "undef" in brw_wm_emit.c
|
||||
*/
|
||||
if (!value->spill_slot) {
|
||||
c->last_scratch += 0x40;
|
||||
value->spill_slot = c->last_scratch;
|
||||
}
|
||||
|
||||
/* The spill will be done in brw_wm_emit.c immediately after the
|
||||
* value is calculated, so we can just take this reg without any
|
||||
* further work.
|
||||
*/
|
||||
value->resident->value = NULL;
|
||||
value->resident->nextuse = BRW_WM_MAX_INSN;
|
||||
value->resident = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Search for contiguous region with the most distant nearest
|
||||
* member. Free regs count as very distant.
|
||||
*
|
||||
* TODO: implement spill-to-reg so that we can rearrange discontigous
|
||||
* free regs and then spill the oldest non-free regs in sequence.
|
||||
* This would mean inserting instructions in this pass.
|
||||
*/
|
||||
static unsigned search_contiguous_regs(struct brw_wm_compile *c,
|
||||
unsigned nr,
|
||||
unsigned thisinsn)
|
||||
{
|
||||
struct brw_wm_grf *grf = c->pass2_grf;
|
||||
unsigned furthest = 0;
|
||||
unsigned reg = 0;
|
||||
unsigned i, j;
|
||||
|
||||
/* Start search at 1: r0 is special and can't be used or spilled.
|
||||
*/
|
||||
for (i = 1; i < c->grf_limit && furthest < BRW_WM_MAX_INSN; i++) {
|
||||
unsigned group_nextuse = BRW_WM_MAX_INSN;
|
||||
|
||||
for (j = 0; j < nr; j++) {
|
||||
if (grf[i+j].nextuse < group_nextuse)
|
||||
group_nextuse = grf[i+j].nextuse;
|
||||
}
|
||||
|
||||
if (group_nextuse > furthest) {
|
||||
furthest = group_nextuse;
|
||||
reg = i;
|
||||
}
|
||||
}
|
||||
|
||||
assert(furthest != thisinsn);
|
||||
|
||||
/* Any non-empty regs will need to be spilled:
|
||||
*/
|
||||
for (j = 0; j < nr; j++)
|
||||
if (grf[reg+j].value)
|
||||
spill_value(c, grf[reg+j].value);
|
||||
|
||||
return reg;
|
||||
}
|
||||
|
||||
|
||||
static void alloc_contiguous_dest(struct brw_wm_compile *c,
|
||||
struct brw_wm_value *dst[],
|
||||
unsigned nr,
|
||||
unsigned thisinsn)
|
||||
{
|
||||
unsigned reg = search_contiguous_regs(c, nr, thisinsn);
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < nr; i++) {
|
||||
if (!dst[i]) {
|
||||
/* Need to grab a dummy value in TEX case. Don't introduce
|
||||
* it into the tracking scheme.
|
||||
*/
|
||||
dst[i] = &c->vreg[c->nr_vreg++];
|
||||
}
|
||||
else {
|
||||
assert(!dst[i]->resident);
|
||||
assert(c->pass2_grf[reg+i].nextuse != thisinsn);
|
||||
|
||||
c->pass2_grf[reg+i].value = dst[i];
|
||||
c->pass2_grf[reg+i].nextuse = thisinsn;
|
||||
|
||||
dst[i]->resident = &c->pass2_grf[reg+i];
|
||||
}
|
||||
|
||||
dst[i]->hw_reg = brw_vec8_grf((reg+i)*2, 0);
|
||||
}
|
||||
|
||||
if ((reg+nr)*2 > c->max_wm_grf)
|
||||
c->max_wm_grf = (reg+nr) * 2;
|
||||
}
|
||||
|
||||
|
||||
static void load_args(struct brw_wm_compile *c,
|
||||
struct brw_wm_instruction *inst)
|
||||
{
|
||||
unsigned thisinsn = inst - c->instruction;
|
||||
unsigned i,j;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (j = 0; j < 4; j++) {
|
||||
struct brw_wm_ref *ref = inst->src[i][j];
|
||||
|
||||
if (ref) {
|
||||
if (!ref->value->resident) {
|
||||
/* Need to bring the value in from scratch space. The code for
|
||||
* this will be done in brw_wm_emit.c, here we just do the
|
||||
* register allocation and mark the ref as requiring a fill.
|
||||
*/
|
||||
unsigned reg = search_contiguous_regs(c, 1, thisinsn);
|
||||
|
||||
c->pass2_grf[reg].value = ref->value;
|
||||
c->pass2_grf[reg].nextuse = thisinsn;
|
||||
|
||||
ref->value->resident = &c->pass2_grf[reg];
|
||||
|
||||
/* Note that a fill is required:
|
||||
*/
|
||||
ref->unspill_reg = reg*2;
|
||||
}
|
||||
|
||||
/* Adjust the hw_reg to point at the value's current location:
|
||||
*/
|
||||
assert(ref->value == ref->value->resident->value);
|
||||
ref->hw_reg.nr += (ref->value->resident - c->pass2_grf) * 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Step 3: Work forwards once again. Perform register allocations,
|
||||
* taking into account instructions like TEX which require contiguous
|
||||
* result registers. Where necessary spill registers to scratch space
|
||||
* and reload later.
|
||||
*/
|
||||
void brw_wm_pass2( struct brw_wm_compile *c )
|
||||
{
|
||||
unsigned insn;
|
||||
unsigned i;
|
||||
|
||||
init_registers(c);
|
||||
|
||||
for (insn = 0; insn < c->nr_insns; insn++) {
|
||||
struct brw_wm_instruction *inst = &c->instruction[insn];
|
||||
|
||||
/* Update registers' nextuse values:
|
||||
*/
|
||||
update_register_usage(c, insn);
|
||||
|
||||
/* May need to unspill some args.
|
||||
*/
|
||||
load_args(c, inst);
|
||||
|
||||
/* Allocate registers to hold results:
|
||||
*/
|
||||
switch (inst->opcode) {
|
||||
case OPCODE_TEX:
|
||||
case OPCODE_TXB:
|
||||
case OPCODE_TXP:
|
||||
alloc_contiguous_dest(c, inst->dst, 4, insn);
|
||||
break;
|
||||
|
||||
default:
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (inst->writemask & (1<<i)) {
|
||||
assert(inst->dst[i]);
|
||||
alloc_contiguous_dest(c, &inst->dst[i], 1, insn);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (TEST_DST_SPILLS && inst->opcode != WM_PIXELXY)
|
||||
for (i = 0; i < 4; i++)
|
||||
if (inst->dst[i])
|
||||
spill_value(c, inst->dst[i]);
|
||||
|
||||
}
|
||||
|
||||
if (BRW_DEBUG & DEBUG_WM) {
|
||||
brw_wm_print_program(c, "pass2");
|
||||
}
|
||||
|
||||
c->state = PASS2_DONE;
|
||||
|
||||
if (BRW_DEBUG & DEBUG_WM) {
|
||||
brw_wm_print_program(c, "pass2/done");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,275 @@
|
||||
/*
|
||||
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_state.h"
|
||||
#include "brw_defines.h"
|
||||
|
||||
#include "pipe/p_util.h"
|
||||
|
||||
|
||||
#define COMPAREFUNC_ALWAYS 0
|
||||
#define COMPAREFUNC_NEVER 0x1
|
||||
#define COMPAREFUNC_LESS 0x2
|
||||
#define COMPAREFUNC_EQUAL 0x3
|
||||
#define COMPAREFUNC_LEQUAL 0x4
|
||||
#define COMPAREFUNC_GREATER 0x5
|
||||
#define COMPAREFUNC_NOTEQUAL 0x6
|
||||
#define COMPAREFUNC_GEQUAL 0x7
|
||||
|
||||
/* Samplers aren't strictly wm state from the hardware's perspective,
|
||||
* but that is the only situation in which we use them in this driver.
|
||||
*/
|
||||
|
||||
static int intel_translate_shadow_compare_func(unsigned func)
|
||||
{
|
||||
switch(func) {
|
||||
case PIPE_FUNC_NEVER:
|
||||
return COMPAREFUNC_ALWAYS;
|
||||
case PIPE_FUNC_LESS:
|
||||
return COMPAREFUNC_LEQUAL;
|
||||
case PIPE_FUNC_LEQUAL:
|
||||
return COMPAREFUNC_LESS;
|
||||
case PIPE_FUNC_GREATER:
|
||||
return COMPAREFUNC_GEQUAL;
|
||||
case PIPE_FUNC_GEQUAL:
|
||||
return COMPAREFUNC_GREATER;
|
||||
case PIPE_FUNC_NOTEQUAL:
|
||||
return COMPAREFUNC_EQUAL;
|
||||
case PIPE_FUNC_EQUAL:
|
||||
return COMPAREFUNC_NOTEQUAL;
|
||||
case PIPE_FUNC_ALWAYS:
|
||||
return COMPAREFUNC_NEVER;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Unknown value in %s: %x\n", __FUNCTION__, func);
|
||||
return COMPAREFUNC_NEVER;
|
||||
}
|
||||
|
||||
/* The brw (and related graphics cores) do not support GL_CLAMP. The
|
||||
* Intel drivers for "other operating systems" implement GL_CLAMP as
|
||||
* GL_CLAMP_TO_EDGE, so the same is done here.
|
||||
*/
|
||||
static unsigned translate_wrap_mode( int wrap )
|
||||
{
|
||||
switch( wrap ) {
|
||||
case PIPE_TEX_WRAP_REPEAT:
|
||||
return BRW_TEXCOORDMODE_WRAP;
|
||||
case PIPE_TEX_WRAP_CLAMP:
|
||||
return BRW_TEXCOORDMODE_CLAMP;
|
||||
case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
|
||||
return BRW_TEXCOORDMODE_CLAMP; /* conform likes it this way */
|
||||
case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
|
||||
return BRW_TEXCOORDMODE_CLAMP_BORDER;
|
||||
case PIPE_TEX_WRAP_MIRROR_REPEAT:
|
||||
return BRW_TEXCOORDMODE_MIRROR;
|
||||
default:
|
||||
return BRW_TEXCOORDMODE_WRAP;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static unsigned U_FIXED(float value, unsigned frac_bits)
|
||||
{
|
||||
value *= (1<<frac_bits);
|
||||
return value < 0 ? 0 : value;
|
||||
}
|
||||
|
||||
static int S_FIXED(float value, unsigned frac_bits)
|
||||
{
|
||||
return value * (1<<frac_bits);
|
||||
}
|
||||
|
||||
|
||||
static unsigned upload_default_color( struct brw_context *brw,
|
||||
const float *color )
|
||||
{
|
||||
struct brw_sampler_default_color sdc;
|
||||
|
||||
COPY_4V(sdc.color, color);
|
||||
|
||||
return brw_cache_data( &brw->cache[BRW_SAMPLER_DEFAULT_COLOR], &sdc );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*/
|
||||
static void brw_update_sampler_state( const struct pipe_sampler_state *pipe_sampler,
|
||||
unsigned sdc_gs_offset,
|
||||
struct brw_sampler_state *sampler)
|
||||
{
|
||||
memset(sampler, 0, sizeof(*sampler));
|
||||
|
||||
switch (pipe_sampler->min_mip_filter) {
|
||||
case PIPE_TEX_FILTER_NEAREST:
|
||||
sampler->ss0.min_filter = BRW_MAPFILTER_NEAREST;
|
||||
break;
|
||||
case PIPE_TEX_FILTER_LINEAR:
|
||||
sampler->ss0.min_filter = BRW_MAPFILTER_LINEAR;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (pipe_sampler->min_mip_filter) {
|
||||
case PIPE_TEX_MIPFILTER_NEAREST:
|
||||
sampler->ss0.mip_filter = BRW_MIPFILTER_NEAREST;
|
||||
break;
|
||||
case PIPE_TEX_MIPFILTER_LINEAR:
|
||||
sampler->ss0.mip_filter = BRW_MIPFILTER_LINEAR;
|
||||
break;
|
||||
case PIPE_TEX_MIPFILTER_NONE:
|
||||
sampler->ss0.mip_filter = BRW_MIPFILTER_NONE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* Set Anisotropy:
|
||||
*/
|
||||
if (pipe_sampler->max_anisotropy > 1.0) {
|
||||
sampler->ss0.min_filter = BRW_MAPFILTER_ANISOTROPIC;
|
||||
sampler->ss0.mag_filter = BRW_MAPFILTER_ANISOTROPIC;
|
||||
|
||||
if (pipe_sampler->max_anisotropy > 2.0) {
|
||||
sampler->ss3.max_aniso = MAX2((pipe_sampler->max_anisotropy - 2) / 2,
|
||||
BRW_ANISORATIO_16);
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch (pipe_sampler->mag_img_filter) {
|
||||
case PIPE_TEX_FILTER_NEAREST:
|
||||
sampler->ss0.mag_filter = BRW_MAPFILTER_NEAREST;
|
||||
break;
|
||||
case PIPE_TEX_FILTER_LINEAR:
|
||||
sampler->ss0.mag_filter = BRW_MAPFILTER_LINEAR;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sampler->ss1.s_wrap_mode = translate_wrap_mode(pipe_sampler->wrap_s);
|
||||
sampler->ss1.r_wrap_mode = translate_wrap_mode(pipe_sampler->wrap_r);
|
||||
sampler->ss1.t_wrap_mode = translate_wrap_mode(pipe_sampler->wrap_t);
|
||||
|
||||
/* Fulsim complains if I don't do this. Hardware doesn't mind:
|
||||
*/
|
||||
#if 0
|
||||
if (texObj->Target == GL_TEXTURE_CUBE_MAP_ARB) {
|
||||
sampler->ss1.r_wrap_mode = BRW_TEXCOORDMODE_CUBE;
|
||||
sampler->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CUBE;
|
||||
sampler->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CUBE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Set shadow function:
|
||||
*/
|
||||
if (pipe_sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
|
||||
/* Shadowing is "enabled" by emitting a particular sampler
|
||||
* message (sample_c). So need to recompile WM program when
|
||||
* shadow comparison is enabled on each/any texture unit.
|
||||
*/
|
||||
sampler->ss0.shadow_function = intel_translate_shadow_compare_func(pipe_sampler->compare_func);
|
||||
}
|
||||
|
||||
/* Set LOD bias:
|
||||
*/
|
||||
sampler->ss0.lod_bias = S_FIXED(CLAMP(pipe_sampler->lod_bias, -16, 15), 6);
|
||||
|
||||
sampler->ss0.lod_preclamp = 1; /* OpenGL mode */
|
||||
sampler->ss0.default_color_mode = 0; /* OpenGL/DX10 mode */
|
||||
|
||||
/* Set BaseMipLevel, MaxLOD, MinLOD:
|
||||
*
|
||||
* XXX: I don't think that using firstLevel, lastLevel works,
|
||||
* because we always setup the surface state as if firstLevel ==
|
||||
* level zero. Probably have to subtract firstLevel from each of
|
||||
* these:
|
||||
*/
|
||||
sampler->ss0.base_level = U_FIXED(0, 1);
|
||||
|
||||
sampler->ss1.max_lod = U_FIXED(MIN2(MAX2(pipe_sampler->max_lod, 0), 13), 6);
|
||||
sampler->ss1.min_lod = U_FIXED(MIN2(MAX2(pipe_sampler->min_lod, 0), 13), 6);
|
||||
|
||||
sampler->ss2.default_color_pointer = sdc_gs_offset >> 5;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* All samplers must be uploaded in a single contiguous array, which
|
||||
* 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)
|
||||
{
|
||||
unsigned unit;
|
||||
unsigned sampler_count = 0;
|
||||
|
||||
/* _NEW_TEXTURE */
|
||||
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];
|
||||
unsigned sdc_gs_offset = upload_default_color(brw, sampler->border_color);
|
||||
|
||||
brw_update_sampler_state(sampler,
|
||||
sdc_gs_offset,
|
||||
&brw->wm.sampler[unit]);
|
||||
|
||||
sampler_count = unit + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (brw->wm.sampler_count != sampler_count) {
|
||||
brw->wm.sampler_count = sampler_count;
|
||||
brw->state.dirty.cache |= CACHE_NEW_SAMPLER;
|
||||
}
|
||||
|
||||
brw->wm.sampler_gs_offset = 0;
|
||||
|
||||
if (brw->wm.sampler_count)
|
||||
brw->wm.sampler_gs_offset =
|
||||
brw_cache_data_sz(&brw->cache[BRW_SAMPLER],
|
||||
brw->wm.sampler,
|
||||
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,
|
||||
.cache = 0
|
||||
},
|
||||
.update = upload_wm_samplers
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
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_state.h"
|
||||
#include "brw_defines.h"
|
||||
#include "brw_wm.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;
|
||||
|
||||
if (BRW_DEBUG & DEBUG_SINGLE_THREAD)
|
||||
max_threads = 0;
|
||||
else
|
||||
max_threads = 31;
|
||||
|
||||
|
||||
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.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;
|
||||
wm.thread3.const_urb_entry_read_length = brw->wm.prog_data->curb_read_length;
|
||||
|
||||
wm.wm5.max_threads = max_threads;
|
||||
|
||||
per_thread = ALIGN(brw->wm.prog_data->total_scratch, 1024);
|
||||
assert(per_thread <= 12 * 1024);
|
||||
|
||||
if (brw->wm.prog_data->total_scratch) {
|
||||
unsigned total = per_thread * (max_threads + 1);
|
||||
|
||||
/* Scratch space -- just have to make sure there is sufficient
|
||||
* allocated for the active program and current number of threads.
|
||||
*/
|
||||
brw->wm.scratch_buffer_size = total;
|
||||
if (brw->wm.scratch_buffer &&
|
||||
brw->wm.scratch_buffer_size > brw->wm.scratch_buffer->size) {
|
||||
dri_bo_unreference(brw->wm.scratch_buffer);
|
||||
brw->wm.scratch_buffer = NULL;
|
||||
}
|
||||
if (!brw->wm.scratch_buffer) {
|
||||
brw->wm.scratch_buffer = dri_bo_alloc(intel->intelScreen->bufmgr,
|
||||
"wm scratch",
|
||||
brw->wm.scratch_buffer_size,
|
||||
4096, DRM_BO_FLAG_MEM_TT);
|
||||
}
|
||||
}
|
||||
/* XXX: Scratch buffers are not implemented correectly.
|
||||
*
|
||||
* The scratch offset to be programmed into wm is relative to the general
|
||||
* state base address. However, using dri_bo_alloc/dri_bo_emit_reloc (or
|
||||
* the previous bmGenBuffers scheme), we get an offset relative to the
|
||||
* start of framebuffer. Even before then, it was broken in other ways,
|
||||
* so just fail for now if we hit that path.
|
||||
*/
|
||||
assert(brw->wm.prog_data->total_scratch == 0);
|
||||
|
||||
/* CACHE_NEW_SURFACE */
|
||||
wm.thread1.binding_table_entry_count = brw->wm.nr_surfaces;
|
||||
|
||||
/* BRW_NEW_CURBE_OFFSETS */
|
||||
wm.thread3.const_urb_entry_read_offset = brw->curbe.wm_start * 2;
|
||||
|
||||
wm.thread3.urb_entry_read_offset = 0;
|
||||
wm.thread1.depth_coef_urb_read_offset = 1;
|
||||
wm.thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754;
|
||||
|
||||
/* CACHE_NEW_SAMPLER */
|
||||
wm.wm4.sampler_count = (brw->wm.sampler_count + 1) / 4;
|
||||
wm.wm4.sampler_state_pointer = brw->wm.sampler_gs_offset >> 5;
|
||||
|
||||
/* BRW_NEW_FRAGMENT_PROGRAM */
|
||||
{
|
||||
const struct gl_fragment_program *fp = brw->fragment_program;
|
||||
|
||||
if (fp->Base.InputsRead & (1<<FRAG_ATTRIB_WPOS))
|
||||
wm.wm5.program_uses_depth = 1; /* as far as we can tell */
|
||||
|
||||
if (fp->Base.OutputsWritten & (1<<FRAG_RESULT_DEPR))
|
||||
wm.wm5.program_computes_depth = 1;
|
||||
|
||||
/* _NEW_COLOR */
|
||||
if (fp->UsesKill ||
|
||||
brw->attribs.Color->AlphaEnabled)
|
||||
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.thread_dispatch_enable = 1; /* AKA: color_write */
|
||||
wm.wm5.legacy_line_rast = 0;
|
||||
wm.wm5.legacy_global_depth_bias = 0;
|
||||
wm.wm5.early_depth_test = 1; /* never need to disable */
|
||||
wm.wm5.line_aa_region_width = 0;
|
||||
wm.wm5.line_endcap_aa_region_width = 1;
|
||||
|
||||
/* _NEW_POLYGONSTIPPLE */
|
||||
if (brw->attribs.Polygon->StippleFlag)
|
||||
wm.wm5.polygon_stipple = 1;
|
||||
|
||||
/* _NEW_POLYGON */
|
||||
if (brw->attribs.Polygon->OffsetFill) {
|
||||
wm.wm5.depth_offset = 1;
|
||||
/* Something wierd going on with legacy_global_depth_bias,
|
||||
* offset_constant, scaling and MRD. This value passes glean
|
||||
* but gives some odd results elsewere (eg. the
|
||||
* quad-offset-units test).
|
||||
*/
|
||||
wm.global_depth_offset_constant = brw->attribs.Polygon->OffsetUnits * 2;
|
||||
|
||||
/* This is the only value that passes glean:
|
||||
*/
|
||||
wm.global_depth_offset_scale = brw->attribs.Polygon->OffsetFactor;
|
||||
}
|
||||
|
||||
/* _NEW_LINE */
|
||||
if (brw->attribs.Line->StippleFlag) {
|
||||
wm.wm5.line_stipple = 1;
|
||||
}
|
||||
|
||||
if (BRW_DEBUG & DEBUG_STATS || intel->stats_wm)
|
||||
wm.wm4.stats_enable = 1;
|
||||
|
||||
brw->wm.state_gs_offset = brw_cache_data( &brw->cache[BRW_WM_UNIT], &wm );
|
||||
|
||||
if (brw->wm.prog_data->total_scratch) {
|
||||
/*
|
||||
dri_emit_reloc(brw->cache[BRW_WM_UNIT].pool->buffer,
|
||||
DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE,
|
||||
(per_thread / 1024) - 1,
|
||||
brw->wm.state_gs_offset +
|
||||
((char *)&wm.thread2 - (char *)&wm),
|
||||
brw->wm.scratch_buffer);
|
||||
*/
|
||||
} else {
|
||||
wm.thread2.scratch_space_base_pointer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
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),
|
||||
|
||||
.cache = (CACHE_NEW_SURFACE |
|
||||
CACHE_NEW_WM_PROG |
|
||||
CACHE_NEW_SAMPLER)
|
||||
},
|
||||
.update = upload_wm_unit
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,294 @@
|
||||
/*
|
||||
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_state.h"
|
||||
#include "brw_defines.h"
|
||||
|
||||
|
||||
#if 0
|
||||
static unsigned translate_tex_target( int target )
|
||||
{
|
||||
switch (target) {
|
||||
case PIPE_TEXTURE_1D:
|
||||
return BRW_SURFACE_1D;
|
||||
|
||||
case PIPE_TEXTURE_2D:
|
||||
return BRW_SURFACE_2D;
|
||||
|
||||
case PIPE_TEXTURE_3D:
|
||||
return BRW_SURFACE_3D;
|
||||
|
||||
case PIPE_TEXTURE_CUBE:
|
||||
return BRW_SURFACE_CUBE;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned translate_tex_format( unsigned mesa_format )
|
||||
{
|
||||
switch( mesa_format ) {
|
||||
case PIPE_FORMAT_U_L8:
|
||||
return BRW_SURFACEFORMAT_L8_UNORM;
|
||||
|
||||
case PIPE_FORMAT_U_I8:
|
||||
return BRW_SURFACEFORMAT_I8_UNORM;
|
||||
|
||||
case PIPE_FORMAT_U_A8:
|
||||
return BRW_SURFACEFORMAT_A8_UNORM;
|
||||
|
||||
case PIPE_FORMAT_U_A8_L8:
|
||||
return BRW_SURFACEFORMAT_L8A8_UNORM;
|
||||
|
||||
case PIPE_FORMAT_R8G8B8_UNORM:
|
||||
assert(0); /* not supported for sampling */
|
||||
return BRW_SURFACEFORMAT_R8G8B8_UNORM;
|
||||
|
||||
case PIPE_FORMAT_U_A8_R8_G8_B8:
|
||||
return BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
|
||||
|
||||
case PIPE_FORMAT_RGBA8888_REV:
|
||||
return BRW_SURFACEFORMAT_R8G8B8A8_UNORM;
|
||||
|
||||
case PIPE_FORMAT_U_R5_G6_B5:
|
||||
return BRW_SURFACEFORMAT_B5G6R5_UNORM;
|
||||
|
||||
case PIPE_FORMAT_A1R5G5B5_UNORM:
|
||||
return BRW_SURFACEFORMAT_B5G5R5A1_UNORM;
|
||||
|
||||
case PIPE_FORMAT_A4R4G4B4_UNORM:
|
||||
return BRW_SURFACEFORMAT_B4G4R4A4_UNORM;
|
||||
|
||||
case PIPE_FORMAT_YCBCR_REV:
|
||||
return BRW_SURFACEFORMAT_YCRCB_NORMAL;
|
||||
|
||||
case PIPE_FORMAT_YCBCR:
|
||||
return BRW_SURFACEFORMAT_YCRCB_SWAPUVY;
|
||||
|
||||
case PIPE_FORMAT_RGB_FXT1:
|
||||
case PIPE_FORMAT_RGBA_FXT1:
|
||||
return BRW_SURFACEFORMAT_FXT1;
|
||||
|
||||
case PIPE_FORMAT_Z16_UNORM:
|
||||
return BRW_SURFACEFORMAT_I16_UNORM;
|
||||
|
||||
case PIPE_FORMAT_RGB_DXT1:
|
||||
return BRW_SURFACEFORMAT_DXT1_RGB;
|
||||
|
||||
case PIPE_FORMAT_RGBA_DXT1:
|
||||
return BRW_SURFACEFORMAT_BC1_UNORM;
|
||||
|
||||
case PIPE_FORMAT_RGBA_DXT3:
|
||||
return BRW_SURFACEFORMAT_BC2_UNORM;
|
||||
|
||||
case PIPE_FORMAT_RGBA_DXT5:
|
||||
return BRW_SURFACEFORMAT_BC3_UNORM;
|
||||
|
||||
case PIPE_FORMAT_SRGBA8:
|
||||
return BRW_SURFACEFORMAT_R8G8B8A8_UNORM_SRGB;
|
||||
case PIPE_FORMAT_SRGB_DXT1:
|
||||
return BRW_SURFACEFORMAT_BC1_UNORM_SRGB;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void brw_update_texture_surface( GLcontext *ctx,
|
||||
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];
|
||||
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);
|
||||
|
||||
/* 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 = intelObj->mt->region->buffer->offset;
|
||||
|
||||
surf.ss2.mip_count = intelObj->lastLevel - intelObj->firstLevel;
|
||||
surf.ss2.width = firstImage->Width - 1;
|
||||
surf.ss2.height = firstImage->Height - 1;
|
||||
|
||||
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.ss4.min_lod = 0;
|
||||
|
||||
if (tObj->Target == GL_TEXTURE_CUBE_MAP) {
|
||||
surf.ss0.cube_pos_x = 1;
|
||||
surf.ss0.cube_pos_y = 1;
|
||||
surf.ss0.cube_pos_z = 1;
|
||||
surf.ss0.cube_neg_x = 1;
|
||||
surf.ss0.cube_neg_y = 1;
|
||||
surf.ss0.cube_neg_z = 1;
|
||||
}
|
||||
|
||||
brw->wm.bind.surf_ss_offset[unit + 1] =
|
||||
brw_cache_data( &brw->cache[BRW_SS_SURFACE], &surf );
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define OFFSET(TYPE, FIELD) ( (unsigned)&(((TYPE *)0)->FIELD) )
|
||||
|
||||
|
||||
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;
|
||||
|
||||
memset(&surf, 0, sizeof(surf));
|
||||
|
||||
if (region != NULL) {
|
||||
if (region->cpp == 4)
|
||||
surf.ss0.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
|
||||
else
|
||||
surf.ss0.surface_format = BRW_SURFACEFORMAT_B5G6R5_UNORM;
|
||||
|
||||
surf.ss0.surface_type = BRW_SURFACE_2D;
|
||||
|
||||
surf.ss2.width = region->pitch - 1; /* XXX: not really! */
|
||||
surf.ss2.height = region->height - 1;
|
||||
surf.ss3.tile_walk = BRW_TILEWALK_XMAJOR;
|
||||
surf.ss3.tiled_surface = region->tiled;
|
||||
surf.ss3.pitch = (region->pitch * region->cpp) - 1;
|
||||
} 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);
|
||||
|
||||
|
||||
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];
|
||||
|
||||
brw->wm.bind.surf_ss_offset[0] = brw_cache_data( &brw->cache[BRW_SS_SURFACE], &surf );
|
||||
|
||||
brw->wm.nr_surfaces = 1;
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < BRW_MAX_TEX_UNIT; i++) {
|
||||
struct gl_texture_unit *texUnit = &brw->attribs.Texture->Unit[i];
|
||||
|
||||
/* _NEW_TEXTURE, BRW_NEW_TEXDATA
|
||||
*/
|
||||
if (texUnit->_ReallyEnabled &&
|
||||
intel_finalize_mipmap_tree(intel, i)) {
|
||||
|
||||
brw_update_texture_surface(ctx, i);
|
||||
|
||||
brw->wm.nr_surfaces = i+2;
|
||||
}
|
||||
else if( texUnit->_ReallyEnabled &&
|
||||
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;
|
||||
}
|
||||
else {
|
||||
brw->wm.bind.surf_ss_offset[i+1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
brw->wm.bind_ss_offset = brw_cache_data( &brw->cache[BRW_SS_SURF_BIND],
|
||||
&brw->wm.bind );
|
||||
}
|
||||
|
||||
static void emit_reloc_wm_surfaces(struct brw_context *brw)
|
||||
{
|
||||
int unit;
|
||||
|
||||
if (brw->state.draw_region != NULL) {
|
||||
/* Emit framebuffer relocation */
|
||||
dri_emit_reloc(brw_cache_buffer(brw, BRW_SS_SURFACE),
|
||||
DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE,
|
||||
0,
|
||||
brw->wm.bind.surf_ss_offset[0] +
|
||||
offsetof(struct brw_surface_state, ss1),
|
||||
brw->state.draw_region->buffer);
|
||||
}
|
||||
|
||||
/* Emit relocations for texture buffers */
|
||||
for (unit = 0; unit < BRW_MAX_TEX_UNIT; unit++) {
|
||||
struct gl_texture_unit *texUnit = &brw->attribs.Texture->Unit[unit];
|
||||
struct gl_texture_object *tObj = texUnit->_Current;
|
||||
struct intel_texture_object *intelObj = intel_texture_object(tObj);
|
||||
|
||||
if (texUnit->_ReallyEnabled && intelObj->mt != NULL) {
|
||||
dri_emit_reloc(brw_cache_buffer(brw, BRW_SS_SURFACE),
|
||||
DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ,
|
||||
0,
|
||||
brw->wm.bind.surf_ss_offset[unit + 1] +
|
||||
offsetof(struct brw_surface_state, ss1),
|
||||
intelObj->mt->region->buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const struct brw_tracked_state brw_wm_surfaces = {
|
||||
.dirty = {
|
||||
.mesa = _NEW_COLOR | _NEW_TEXTURE | _NEW_BUFFERS,
|
||||
.brw = BRW_NEW_CONTEXT,
|
||||
.cache = 0
|
||||
},
|
||||
.update = upload_wm_surfaces,
|
||||
.emit_reloc = emit_reloc_wm_surfaces,
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,392 @@
|
||||
/*
|
||||
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_aub.h"
|
||||
#include "pipe/p_context.h"
|
||||
#include "pipe/p_state.h"
|
||||
#include "imports.h"
|
||||
//#include "intel_winsys.h"
|
||||
|
||||
|
||||
struct brw_aubfile {
|
||||
FILE *file;
|
||||
unsigned next_free_page;
|
||||
};
|
||||
|
||||
|
||||
extern char *__progname;
|
||||
|
||||
|
||||
struct aub_file_header {
|
||||
unsigned int instruction_type;
|
||||
unsigned int pad0:16;
|
||||
unsigned int minor:8;
|
||||
unsigned int major:8;
|
||||
unsigned char application[8*4];
|
||||
unsigned int day:8;
|
||||
unsigned int month:8;
|
||||
unsigned int year:16;
|
||||
unsigned int timezone:8;
|
||||
unsigned int second:8;
|
||||
unsigned int minute:8;
|
||||
unsigned int hour:8;
|
||||
unsigned int comment_length:16;
|
||||
unsigned int pad1:16;
|
||||
};
|
||||
|
||||
struct aub_block_header {
|
||||
unsigned int instruction_type;
|
||||
unsigned int operation:8;
|
||||
unsigned int type:8;
|
||||
unsigned int address_space:8;
|
||||
unsigned int pad0:8;
|
||||
unsigned int general_state_type:8;
|
||||
unsigned int surface_state_type:8;
|
||||
unsigned int pad1:16;
|
||||
unsigned int address;
|
||||
unsigned int length;
|
||||
};
|
||||
|
||||
struct aub_dump_bmp {
|
||||
unsigned int instruction_type;
|
||||
unsigned int xmin:16;
|
||||
unsigned int ymin:16;
|
||||
unsigned int pitch:16;
|
||||
unsigned int bpp:8;
|
||||
unsigned int format:8;
|
||||
unsigned int xsize:16;
|
||||
unsigned int ysize:16;
|
||||
unsigned int addr;
|
||||
unsigned int unknown;
|
||||
};
|
||||
|
||||
enum bh_operation {
|
||||
BH_COMMENT,
|
||||
BH_DATA_WRITE,
|
||||
BH_COMMAND_WRITE,
|
||||
BH_MMI0_WRITE32,
|
||||
BH_END_SCENE,
|
||||
BH_CONFIG_MEMORY_MAP,
|
||||
BH_MAX_OPERATION
|
||||
};
|
||||
|
||||
enum command_write_type {
|
||||
CW_HWB_RING = 1,
|
||||
CW_PRIMARY_RING_A,
|
||||
CW_PRIMARY_RING_B, /* XXX - disagreement with listaub! */
|
||||
CW_PRIMARY_RING_C,
|
||||
CW_MAX_TYPE
|
||||
};
|
||||
|
||||
enum memory_map_type {
|
||||
MM_DEFAULT,
|
||||
MM_DYNAMIC,
|
||||
MM_MAX_TYPE
|
||||
};
|
||||
|
||||
enum address_space {
|
||||
ADDR_GTT,
|
||||
ADDR_LOCAL,
|
||||
ADDR_MAIN,
|
||||
ADDR_MAX
|
||||
};
|
||||
|
||||
|
||||
#define AUB_FILE_HEADER 0xe085000b
|
||||
#define AUB_BLOCK_HEADER 0xe0c10003
|
||||
#define AUB_DUMP_BMP 0xe09e0004
|
||||
|
||||
/* Registers to control page table
|
||||
*/
|
||||
#define PGETBL_CTL 0x2020
|
||||
#define PGETBL_ENABLED 0x1
|
||||
|
||||
#define NR_GTT_ENTRIES 65536 /* 256 mb */
|
||||
|
||||
#define FAIL \
|
||||
do { \
|
||||
fprintf(stderr, "failed to write aub data at %s/%d\n", __FUNCTION__, __LINE__); \
|
||||
exit(1); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* Emit the headers at the top of each aubfile. Initialize the GTT.
|
||||
*/
|
||||
static void init_aubfile( FILE *aub_file )
|
||||
{
|
||||
struct aub_file_header fh;
|
||||
struct aub_block_header bh;
|
||||
unsigned int data;
|
||||
|
||||
static int nr;
|
||||
|
||||
nr++;
|
||||
|
||||
/* Emit the aub header:
|
||||
*/
|
||||
memset(&fh, 0, sizeof(fh));
|
||||
|
||||
fh.instruction_type = AUB_FILE_HEADER;
|
||||
fh.minor = 0x0;
|
||||
fh.major = 0x7;
|
||||
memcpy(fh.application, __progname, sizeof(fh.application));
|
||||
fh.day = (nr>>24) & 0xff;
|
||||
fh.month = 0x0;
|
||||
fh.year = 0x0;
|
||||
fh.timezone = 0x0;
|
||||
fh.second = nr & 0xff;
|
||||
fh.minute = (nr>>8) & 0xff;
|
||||
fh.hour = (nr>>16) & 0xff;
|
||||
fh.comment_length = 0x0;
|
||||
|
||||
if (fwrite(&fh, sizeof(fh), 1, aub_file) < 0)
|
||||
FAIL;
|
||||
|
||||
/* Setup the GTT starting at main memory address zero (!):
|
||||
*/
|
||||
memset(&bh, 0, sizeof(bh));
|
||||
|
||||
bh.instruction_type = AUB_BLOCK_HEADER;
|
||||
bh.operation = BH_MMI0_WRITE32;
|
||||
bh.type = 0x0;
|
||||
bh.address_space = ADDR_GTT; /* ??? */
|
||||
bh.general_state_type = 0x0;
|
||||
bh.surface_state_type = 0x0;
|
||||
bh.address = PGETBL_CTL;
|
||||
bh.length = 0x4;
|
||||
|
||||
if (fwrite(&bh, sizeof(bh), 1, aub_file) < 0)
|
||||
FAIL;
|
||||
|
||||
data = 0x0 | PGETBL_ENABLED;
|
||||
|
||||
if (fwrite(&data, sizeof(data), 1, aub_file) < 0)
|
||||
FAIL;
|
||||
}
|
||||
|
||||
|
||||
static void init_aub_gtt( struct brw_aubfile *aubfile,
|
||||
unsigned start_offset,
|
||||
unsigned size )
|
||||
{
|
||||
FILE *aub_file = aubfile->file;
|
||||
struct aub_block_header bh;
|
||||
unsigned int i;
|
||||
|
||||
assert(start_offset + size < NR_GTT_ENTRIES * 4096);
|
||||
|
||||
|
||||
memset(&bh, 0, sizeof(bh));
|
||||
|
||||
bh.instruction_type = AUB_BLOCK_HEADER;
|
||||
bh.operation = BH_DATA_WRITE;
|
||||
bh.type = 0x0;
|
||||
bh.address_space = ADDR_MAIN;
|
||||
bh.general_state_type = 0x0;
|
||||
bh.surface_state_type = 0x0;
|
||||
bh.address = start_offset / 4096 * 4;
|
||||
bh.length = size / 4096 * 4;
|
||||
|
||||
if (fwrite(&bh, sizeof(bh), 1, aub_file) < 0)
|
||||
FAIL;
|
||||
|
||||
for (i = 0; i < size / 4096; i++) {
|
||||
unsigned data = aubfile->next_free_page | 1;
|
||||
|
||||
aubfile->next_free_page += 4096;
|
||||
|
||||
if (fwrite(&data, sizeof(data), 1, aub_file) < 0)
|
||||
FAIL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void write_block_header( FILE *aub_file,
|
||||
struct aub_block_header *bh,
|
||||
const unsigned *data,
|
||||
unsigned sz )
|
||||
{
|
||||
sz = (sz + 3) & ~3;
|
||||
|
||||
if (fwrite(bh, sizeof(*bh), 1, aub_file) < 0)
|
||||
FAIL;
|
||||
|
||||
if (fwrite(data, sz, 1, aub_file) < 0)
|
||||
FAIL;
|
||||
|
||||
fflush(aub_file);
|
||||
}
|
||||
|
||||
|
||||
static void write_dump_bmp( FILE *aub_file,
|
||||
struct aub_dump_bmp *db )
|
||||
{
|
||||
if (fwrite(db, sizeof(*db), 1, aub_file) < 0)
|
||||
FAIL;
|
||||
|
||||
fflush(aub_file);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void brw_aub_gtt_data( struct brw_aubfile *aubfile,
|
||||
unsigned offset,
|
||||
const void *data,
|
||||
unsigned sz,
|
||||
unsigned type,
|
||||
unsigned state_type )
|
||||
{
|
||||
struct aub_block_header bh;
|
||||
|
||||
bh.instruction_type = AUB_BLOCK_HEADER;
|
||||
bh.operation = BH_DATA_WRITE;
|
||||
bh.type = type;
|
||||
bh.address_space = ADDR_GTT;
|
||||
bh.pad0 = 0;
|
||||
|
||||
if (type == DW_GENERAL_STATE) {
|
||||
bh.general_state_type = state_type;
|
||||
bh.surface_state_type = 0;
|
||||
}
|
||||
else {
|
||||
bh.general_state_type = 0;
|
||||
bh.surface_state_type = state_type;
|
||||
}
|
||||
|
||||
bh.pad1 = 0;
|
||||
bh.address = offset;
|
||||
bh.length = sz;
|
||||
|
||||
write_block_header(aubfile->file, &bh, data, sz);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void brw_aub_gtt_cmds( struct brw_aubfile *aubfile,
|
||||
unsigned offset,
|
||||
const void *data,
|
||||
unsigned sz )
|
||||
{
|
||||
struct aub_block_header bh;
|
||||
unsigned type = CW_PRIMARY_RING_A;
|
||||
|
||||
|
||||
bh.instruction_type = AUB_BLOCK_HEADER;
|
||||
bh.operation = BH_COMMAND_WRITE;
|
||||
bh.type = type;
|
||||
bh.address_space = ADDR_GTT;
|
||||
bh.pad0 = 0;
|
||||
bh.general_state_type = 0;
|
||||
bh.surface_state_type = 0;
|
||||
bh.pad1 = 0;
|
||||
bh.address = offset;
|
||||
bh.length = sz;
|
||||
|
||||
write_block_header(aubfile->file, &bh, data, sz);
|
||||
}
|
||||
|
||||
void brw_aub_dump_bmp( struct brw_aubfile *aubfile,
|
||||
struct pipe_surface *surface,
|
||||
unsigned gtt_offset )
|
||||
{
|
||||
struct aub_dump_bmp db;
|
||||
unsigned format;
|
||||
|
||||
if (surface->cpp == 4)
|
||||
format = 0x7;
|
||||
else
|
||||
format = 0x3;
|
||||
|
||||
db.instruction_type = AUB_DUMP_BMP;
|
||||
db.xmin = 0;
|
||||
db.ymin = 0;
|
||||
db.format = format;
|
||||
db.bpp = surface->cpp * 8;
|
||||
db.pitch = surface->pitch;
|
||||
db.xsize = surface->pitch;
|
||||
db.ysize = surface->height;
|
||||
db.addr = gtt_offset;
|
||||
db.unknown = /* surface->tiled ? 0x4 : */ 0x0;
|
||||
|
||||
write_dump_bmp(aubfile->file, &db);
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct brw_aubfile *brw_aubfile_create( void )
|
||||
{
|
||||
struct brw_aubfile *aubfile = CALLOC_STRUCT(brw_aubfile);
|
||||
char filename[80];
|
||||
int val;
|
||||
static int i = 0;
|
||||
|
||||
i++;
|
||||
|
||||
if (_mesa_getenv("INTEL_AUBFILE")) {
|
||||
val = snprintf(filename, sizeof(filename), "%s%d.aub", _mesa_getenv("INTEL_AUBFILE"), i%4);
|
||||
_mesa_printf("--> Aub file: %s\n", filename);
|
||||
aubfile->file = fopen(filename, "w");
|
||||
}
|
||||
else {
|
||||
val = snprintf(filename, sizeof(filename), "%s.aub", __progname);
|
||||
if (val < 0 || val > sizeof(filename))
|
||||
strcpy(filename, "default.aub");
|
||||
|
||||
_mesa_printf("--> Aub file: %s\n", filename);
|
||||
aubfile->file = fopen(filename, "w");
|
||||
}
|
||||
|
||||
if (!aubfile->file) {
|
||||
_mesa_printf("couldn't open aubfile\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
init_aubfile(aubfile->file);
|
||||
|
||||
/* The GTT is located starting address zero in main memory. Pages
|
||||
* to populate the gtt start after this point.
|
||||
*/
|
||||
aubfile->next_free_page = (NR_GTT_ENTRIES * 4 + 4095) & ~4095;
|
||||
|
||||
/* More or less correspond with all the agp regions mapped by the
|
||||
* driver:
|
||||
*/
|
||||
init_aub_gtt(aubfile, 0, 4096*4);
|
||||
init_aub_gtt(aubfile, AUB_BUF_START, AUB_BUF_SIZE);
|
||||
|
||||
return aubfile;
|
||||
}
|
||||
|
||||
void brw_aub_destroy( struct brw_aubfile *aubfile )
|
||||
{
|
||||
fclose(aubfile->file);
|
||||
FREE(aubfile);
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
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>
|
||||
*/
|
||||
|
||||
#ifndef BRW_AUB_H
|
||||
#define BRW_AUB_H
|
||||
|
||||
/* We set up this region, buffers may be allocated here:
|
||||
*/
|
||||
#define AUB_BUF_START (4096*4)
|
||||
#define AUB_BUF_SIZE (8*1024*1024)
|
||||
|
||||
struct intel_context;
|
||||
struct pipe_surface;
|
||||
|
||||
struct brw_aubfile *brw_aubfile_create( void );
|
||||
|
||||
void brw_aub_destroy( struct brw_aubfile *aubfile );
|
||||
|
||||
void brw_aub_gtt_data( struct brw_aubfile *aubfile,
|
||||
unsigned offset,
|
||||
const void *data,
|
||||
unsigned sz,
|
||||
unsigned type,
|
||||
unsigned state_type );
|
||||
|
||||
void brw_aub_gtt_cmds( struct brw_aubfile *aubfile,
|
||||
unsigned offset,
|
||||
const void *data,
|
||||
unsigned sz );
|
||||
|
||||
void brw_aub_dump_bmp( struct brw_aubfile *aubfile,
|
||||
struct pipe_surface *surface,
|
||||
unsigned gtt_offset );
|
||||
|
||||
|
||||
enum data_write_type {
|
||||
DW_NOTYPE,
|
||||
DW_BATCH_BUFFER,
|
||||
DW_BIN_BUFFER,
|
||||
DW_BIN_POINTER_LIST,
|
||||
DW_SLOW_STATE_BUFFER,
|
||||
DW_VERTEX_BUFFER,
|
||||
DW_2D_MAP,
|
||||
DW_CUBE_MAP,
|
||||
DW_INDIRECT_STATE_BUFFER,
|
||||
DW_VOLUME_MAP,
|
||||
DW_1D_MAP,
|
||||
DW_CONSTANT_BUFFER,
|
||||
DW_CONSTANT_URB_ENTRY,
|
||||
DW_INDEX_BUFFER,
|
||||
DW_GENERAL_STATE,
|
||||
DW_SURFACE_STATE,
|
||||
DW_MEDIA_OBJECT_INDIRECT_DATA,
|
||||
DW_MAX_TYPE
|
||||
};
|
||||
|
||||
enum data_write_general_state_type {
|
||||
DWGS_NOTYPE,
|
||||
DWGS_VERTEX_SHADER_STATE,
|
||||
DWGS_GEOMETRY_SHADER_STATE ,
|
||||
DWGS_CLIPPER_STATE,
|
||||
DWGS_STRIPS_FANS_STATE,
|
||||
DWGS_WINDOWER_IZ_STATE,
|
||||
DWGS_COLOR_CALC_STATE,
|
||||
DWGS_CLIPPER_VIEWPORT_STATE, /* was 0x7 */
|
||||
DWGS_STRIPS_FANS_VIEWPORT_STATE,
|
||||
DWGS_COLOR_CALC_VIEWPORT_STATE, /* was 0x9 */
|
||||
DWGS_SAMPLER_STATE,
|
||||
DWGS_KERNEL_INSTRUCTIONS,
|
||||
DWGS_SCRATCH_SPACE,
|
||||
DWGS_SAMPLER_DEFAULT_COLOR,
|
||||
DWGS_INTERFACE_DESCRIPTOR,
|
||||
DWGS_VLD_STATE,
|
||||
DWGS_VFE_STATE,
|
||||
DWGS_MAX_TYPE
|
||||
};
|
||||
|
||||
enum data_write_surface_state_type {
|
||||
DWSS_NOTYPE,
|
||||
DWSS_BINDING_TABLE_STATE,
|
||||
DWSS_SURFACE_STATE,
|
||||
DWSS_MAX_TYPE
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -75,12 +75,16 @@
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_context.h"
|
||||
|
||||
#include "xm_winsys_aub.h"
|
||||
|
||||
/**
|
||||
* Global X driver lock
|
||||
*/
|
||||
_glthread_Mutex _xmesa_lock;
|
||||
|
||||
|
||||
int xmesa_mode;
|
||||
|
||||
|
||||
/**********************************************************************/
|
||||
/***** X Utility Functions *****/
|
||||
@@ -738,7 +742,14 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
|
||||
pf = choose_pixel_format(v);
|
||||
assert(pf);
|
||||
|
||||
pipe = xmesa_create_pipe_context( c, pf );
|
||||
if (!getenv("XM_AUB")) {
|
||||
xmesa_mode = XMESA_SOFTPIPE;
|
||||
pipe = xmesa_create_pipe_context( c, pf );
|
||||
}
|
||||
else {
|
||||
xmesa_mode = XMESA_AUB;
|
||||
pipe = xmesa_create_i965simple( xmesa_get_pipe_winsys_aub() );
|
||||
}
|
||||
|
||||
c->st = st_create_context(pipe, &v->mesa_visual,
|
||||
share_list ? share_list->st : NULL);
|
||||
@@ -1164,7 +1175,10 @@ void XMesaSwapBuffers( XMesaBuffer b )
|
||||
|
||||
surf = st_get_framebuffer_surface(b->stfb, ST_SURFACE_BACK_LEFT);
|
||||
if (surf) {
|
||||
xmesa_display_surface(b, surf);
|
||||
if (xmesa_mode == XMESA_AUB)
|
||||
xmesa_display_aub( surf );
|
||||
else
|
||||
xmesa_display_surface(b, surf);
|
||||
}
|
||||
|
||||
xmesa_check_and_update_buffer_size(NULL, b);
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
#include "pipe/cell/ppu/cell_context.h"
|
||||
#include "pipe/cell/ppu/cell_winsys.h"
|
||||
#endif
|
||||
#include "xm_winsys_aub.h"
|
||||
|
||||
|
||||
/** XXX from Mesa core */
|
||||
@@ -468,12 +469,15 @@ xm_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s)
|
||||
* For Xlib, this is a singleton object.
|
||||
* Nothing special for the Xlib driver so no subclassing or anything.
|
||||
*/
|
||||
static struct pipe_winsys *
|
||||
xmesa_get_pipe_winsys(void)
|
||||
struct pipe_winsys *
|
||||
xmesa_get_pipe_winsys_aub(void)
|
||||
{
|
||||
static struct pipe_winsys *ws = NULL;
|
||||
|
||||
if (!ws) {
|
||||
if (!ws && getenv("XM_AUB")) {
|
||||
ws = xmesa_create_pipe_winsys_aub();
|
||||
}
|
||||
else if (!ws) {
|
||||
ws = CALLOC_STRUCT(pipe_winsys);
|
||||
|
||||
/* Fill in this struct with callbacks that pipe will need to
|
||||
@@ -537,7 +541,7 @@ xmesa_get_softpipe_winsys(uint pixelformat)
|
||||
struct pipe_context *
|
||||
xmesa_create_pipe_context(XMesaContext xmesa, uint pixelformat)
|
||||
{
|
||||
struct pipe_winsys *pws = xmesa_get_pipe_winsys();
|
||||
struct pipe_winsys *pws = xmesa_get_pipe_winsys_aub();
|
||||
struct pipe_context *pipe;
|
||||
|
||||
#ifdef GALLIUM_CELL
|
||||
|
||||
@@ -41,6 +41,12 @@ extern _glthread_Mutex _xmesa_lock;
|
||||
|
||||
extern XMesaBuffer XMesaBufferList;
|
||||
|
||||
/*
|
||||
*/
|
||||
#define XMESA_SOFTPIPE 1
|
||||
#define XMESA_AUB 2
|
||||
extern int xmesa_mode;
|
||||
|
||||
|
||||
/**
|
||||
* Visual inforation, derived from GLvisual.
|
||||
|
||||
+3
-1
@@ -334,7 +334,9 @@ X11_DRIVER_SOURCES = \
|
||||
pipe/xlib/fakeglx.c \
|
||||
pipe/xlib/xfonts.c \
|
||||
pipe/xlib/xm_api.c \
|
||||
pipe/xlib/xm_winsys.c
|
||||
pipe/xlib/xm_winsys.c \
|
||||
pipe/xlib/xm_winsys_aub.c \
|
||||
pipe/xlib/brw_aub.c
|
||||
|
||||
OSMESA_DRIVER_SOURCES = \
|
||||
drivers/osmesa/osmesa.c
|
||||
|
||||
Reference in New Issue
Block a user