* Keith Whitwell <keith@tungstengraphics.com>
*/
+#include "util/u_math.h"
#include "brw_context.h"
#include "brw_state.h"
#include "brw_defines.h"
+#include "brw_screen.h"
/* Samplers aren't strictly wm state from the hardware's perspective,
-/* 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 GLuint translate_wrap_mode( GLenum wrap )
-{
- switch( wrap ) {
- case GL_REPEAT:
- return BRW_TEXCOORDMODE_WRAP;
- case GL_CLAMP:
- return BRW_TEXCOORDMODE_CLAMP;
- case GL_CLAMP_TO_EDGE:
- return BRW_TEXCOORDMODE_CLAMP; /* conform likes it this way */
- case GL_CLAMP_TO_BORDER:
- return BRW_TEXCOORDMODE_CLAMP_BORDER;
- case GL_MIRRORED_REPEAT:
- return BRW_TEXCOORDMODE_MIRROR;
- default:
- return BRW_TEXCOORDMODE_WRAP;
- }
-}
-
-
-static GLuint U_FIXED(GLfloat value, GLuint frac_bits)
-{
- value *= (1<<frac_bits);
- return value < 0 ? 0 : value;
-}
-
-static GLint S_FIXED(GLfloat value, GLuint frac_bits)
-{
- return value * (1<<frac_bits);
-}
-
-
static struct brw_winsys_buffer *
upload_default_color( struct brw_context *brw,
const GLfloat *color )
struct wm_sampler_key {
int sampler_count;
-
- struct wm_sampler_entry {
- GLenum tex_target;
- GLenum wrap_r, wrap_s, wrap_t;
- float maxlod, minlod;
- float lod_bias;
- float max_aniso;
- GLenum minfilter, magfilter;
- GLenum comparemode, comparefunc;
- struct brw_winsys_buffer *sdc_bo;
-
- /** If target is cubemap, take context setting.
- */
- GLboolean seamless_cube_map;
- } sampler[BRW_MAX_TEX_UNIT];
+ struct brw_sampler_state sampler[BRW_MAX_TEX_UNIT];
};
-/**
- * Sets the sampler state for a single unit based off of the sampler key
- * entry.
- */
-static void brw_update_sampler_state(struct wm_sampler_entry *key,
- struct brw_winsys_buffer *sdc_bo,
- struct brw_sampler_state *sampler)
-{
- _mesa_memset(sampler, 0, sizeof(*sampler));
-
- /* Cube-maps on 965 and later must use the same wrap mode for all 3
- * coordinate dimensions. Futher, only CUBE and CLAMP are valid.
- */
- if (key->tex_target == GL_TEXTURE_CUBE_MAP) {
- if (key->seamless_cube_map &&
- (key->minfilter != GL_NEAREST || key->magfilter != GL_NEAREST)) {
- sampler->ss1.r_wrap_mode = BRW_TEXCOORDMODE_CUBE;
- sampler->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CUBE;
- sampler->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CUBE;
- } else {
- sampler->ss1.r_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
- sampler->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
- sampler->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
- }
- } else if (key->tex_target == GL_TEXTURE_1D) {
- /* There's a bug in 1D texture sampling - it actually pays
- * attention to the wrap_t value, though it should not.
- * Override the wrap_t value here to GL_REPEAT to keep
- * any nonexistent border pixels from floating in.
- */
- sampler->ss1.t_wrap_mode = BRW_TEXCOORDMODE_WRAP;
- }
-
-
-
- sampler->ss2.default_color_pointer = sdc_bo->offset >> 5; /* reloc */
-}
-
/** Sets up the cache key for sampler state for all texture units */
static void
brw_wm_sampler_populate_key(struct brw_context *brw,
struct wm_sampler_key *key)
{
- int nr = MIN2(brw->curr.number_textures,
- brw->curr.number_samplers);
int i;
memset(key, 0, sizeof(*key));
- for (i = 0; i < nr; i++) {
+ key->sampler_count = MIN2(brw->curr.num_textures,
+ brw->curr.num_samplers);
+
+ for (i = 0; i < key->sampler_count; i++) {
const struct brw_texture *tex = brw->curr.texture[i];
const struct brw_sampler *sampler = brw->curr.sampler[i];
- struct wm_sampler_entry *entry = &key->sampler[i];
+ struct brw_sampler_state *entry = &key->sampler[i];
- entry->tex_target = texObj->Target;
- entry->seamless_cube_map = FALSE; /* XXX: add this to gallium */
entry->ss0 = sampler->ss0;
entry->ss1 = sampler->ss1;
+ entry->ss2.default_color_pointer = brw->wm.sdc_bo[i]->offset >> 5; /* reloc */
entry->ss3 = sampler->ss3;
+ /* Cube-maps on 965 and later must use the same wrap mode for all 3
+ * coordinate dimensions. Futher, only CUBE and CLAMP are valid.
+ */
+ if (tex->base.target == PIPE_TEXTURE_CUBE) {
+ if (FALSE &&
+ (sampler->ss0.min_filter != BRW_MAPFILTER_NEAREST ||
+ sampler->ss0.mag_filter != BRW_MAPFILTER_NEAREST)) {
+ entry->ss1.r_wrap_mode = BRW_TEXCOORDMODE_CUBE;
+ entry->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CUBE;
+ entry->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CUBE;
+ } else {
+ entry->ss1.r_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
+ entry->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
+ entry->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
+ }
+ } else if (tex->base.target == PIPE_TEXTURE_1D) {
+ /* There's a bug in 1D texture sampling - it actually pays
+ * attention to the wrap_t value, though it should not.
+ * Override the wrap_t value here to GL_REPEAT to keep
+ * any nonexistent border pixels from floating in.
+ */
+ entry->ss1.t_wrap_mode = BRW_TEXCOORDMODE_WRAP;
+ }
+ }
+}
+
+
+static void
+brw_wm_sampler_update_default_colors(struct brw_context *brw)
+{
+ int nr = MIN2(brw->curr.num_textures,
+ brw->curr.num_samplers);
+ int i;
+
+ for (i = 0; i < nr; i++) {
+ const struct brw_texture *tex = brw->curr.texture[i];
+ const struct brw_sampler *sampler = brw->curr.sampler[i];
+
brw->sws->bo_unreference(brw->wm.sdc_bo[i]);
- if (firstImage->_BaseFormat == GL_DEPTH_COMPONENT) {
+
+ if (pf_is_depth_or_stencil(tex->base.format)) {
float bordercolor[4] = {
- texObj->BorderColor[0],
- texObj->BorderColor[0],
- texObj->BorderColor[0],
- texObj->BorderColor[0]
+ sampler->templ.border_color[0],
+ sampler->templ.border_color[0],
+ sampler->templ.border_color[0],
+ sampler->templ.border_color[0]
};
/* GL specs that border color for depth textures is taken from the
* R channel, while the hardware uses A. Spam R into all the
*/
brw->wm.sdc_bo[i] = upload_default_color(brw, bordercolor);
} else {
- brw->wm.sdc_bo[i] = upload_default_color(brw, texObj->BorderColor);
+ brw->wm.sdc_bo[i] = upload_default_color(brw, sampler->templ.border_color);
}
}
-
- key->sampler_count = nr;
}
-/* 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.
+
+
+/* All samplers must be uploaded in a single contiguous array.
*/
-static void upload_wm_samplers( struct brw_context *brw )
+static int upload_wm_samplers( struct brw_context *brw )
{
struct wm_sampler_key key;
int i;
+ brw_wm_sampler_update_default_colors(brw);
brw_wm_sampler_populate_key(brw, &key);
if (brw->wm.sampler_count != key.sampler_count) {
brw->sws->bo_unreference(brw->wm.sampler_bo);
brw->wm.sampler_bo = NULL;
if (brw->wm.sampler_count == 0)
- return;
+ return 0;
brw->wm.sampler_bo = brw_search_cache(&brw->cache, BRW_SAMPLER,
&key, sizeof(key),
* cache.
*/
if (brw->wm.sampler_bo == NULL) {
- struct brw_sampler_state sampler[BRW_MAX_TEX_UNIT];
-
- memset(sampler, 0, sizeof(sampler));
- for (i = 0; i < key.sampler_count; i++) {
- if (brw->wm.sdc_bo[i] == NULL)
- continue;
-
- brw_update_sampler_state(&key.sampler[i], brw->wm.sdc_bo[i],
- &sampler[i]);
- }
-
brw->wm.sampler_bo = brw_upload_cache(&brw->cache, BRW_SAMPLER,
&key, sizeof(key),
brw->wm.sdc_bo, key.sampler_count,
- &sampler, sizeof(sampler),
+ &key.sampler, sizeof(key.sampler),
NULL, NULL);
/* Emit SDC relocations */
- for (i = 0; i < BRW_MAX_TEX_UNIT; i++) {
- if (!ctx->Texture.Unit[i]._ReallyEnabled)
- continue;
-
- dri_bo_emit_reloc(brw->wm.sampler_bo,
- I915_GEM_DOMAIN_SAMPLER, 0,
- 0,
- i * sizeof(struct brw_sampler_state) +
- offsetof(struct brw_sampler_state, ss2),
- brw->wm.sdc_bo[i]);
+ for (i = 0; i < key.sampler_count; i++) {
+ brw->sws->bo_emit_reloc(brw->wm.sampler_bo,
+ I915_GEM_DOMAIN_SAMPLER, 0,
+ 0,
+ i * sizeof(struct brw_sampler_state) +
+ offsetof(struct brw_sampler_state, ss2),
+ brw->wm.sdc_bo[i]);
}
}
+
+ return 0;
}
const struct brw_tracked_state brw_wm_samplers = {
.dirty = {
- .mesa = PIPE_NEW_BOUND_TEXTURES | PIPE_NEW_SAMPLER,
+ .mesa = PIPE_NEW_BOUND_TEXTURES | PIPE_NEW_SAMPLERS,
.brw = 0,
.cache = 0
},
* Keith Whitwell <keith@tungstengraphics.com>
*/
-
+#include "util/u_math.h"
#include "brw_context.h"
#include "brw_state.h"
#include "brw_defines.h"
#include "brw_wm.h"
+#include "brw_debug.h"
+#include "brw_pipe_rast.h"
/***********************************************************************
* WM unit - fragment programs and rasterization
static void
wm_unit_populate_key(struct brw_context *brw, struct brw_wm_unit_key *key)
{
- const struct gl_fragment_program *fp = brw->fragment_program;
- const struct brw_fragment_program *bfp = (struct brw_fragment_program *) fp;
+ const struct brw_fragment_shader *fp = brw->curr.fragment_shader;
memset(key, 0, sizeof(*key));
key->urb_entry_read_length = brw->wm.prog_data->urb_read_length;
key->curb_entry_read_length = brw->wm.prog_data->curb_read_length;
key->dispatch_grf_start_reg = brw->wm.prog_data->first_curbe_grf;
- key->total_scratch = ALIGN(brw->wm.prog_data->total_scratch, 1024);
+ key->total_scratch = align(brw->wm.prog_data->total_scratch, 1024);
/* BRW_NEW_URB_FENCE */
key->urb_size = brw->urb.vsize;
/* CACHE_NEW_SAMPLER */
key->sampler_count = brw->wm.sampler_count;
- /* _NEW_POLYGONSTIPPLE */
- key->polygon_stipple = ctx->Polygon.StippleFlag;
+ /* PIPE_NEW_RAST */
+ key->polygon_stipple = brw->curr.rast->templ.poly_stipple_enable;
- /* BRW_NEW_FRAGMENT_PROGRAM */
- key->uses_depth = (fp->Base.InputsRead & (1 << FRAG_ATTRIB_WPOS)) != 0;
+ /* PIPE_NEW_FRAGMENT_PROGRAM */
+ key->uses_depth = fp->uses_depth;
+ key->computes_depth = fp->info.writes_z;
- /* as far as we can tell */
- key->computes_depth =
- (fp->Base.OutputsWritten & (1 << FRAG_RESULT_DEPTH)) != 0;
/* PIPE_NEW_DEPTH_BUFFER
+ *
* Override for NULL depthbuffer case, required by the Pixel Shader Computed
* Depth field.
*/
if (brw->curr.fb.zsbuf == NULL)
key->computes_depth = 0;
- /* _NEW_COLOR */
- key->uses_kill = fp->UsesKill || ctx->Color.AlphaEnabled;
- key->has_flow_control = bfp->has_flow_control;
+ /* PIPE_NEW_DEPTH_STENCIL_ALPHA */
+ key->uses_kill = (fp->info.uses_kill ||
+ brw->curr.zstencil->cc3.alpha_test);
+
+ key->has_flow_control = fp->has_flow_control;
/* temporary sanity check assertion */
- ASSERT(bfp->has_flow_control == brw_wm_has_flow_control(fp));
+ assert(fp->has_flow_control == 0);
- /* _NEW_QUERY */
+ /* PIPE_NEW_QUERY */
key->stats_wm = (brw->query.stats_wm != 0);
- /* _NEW_LINE */
- key->line_stipple = ctx->Line.StippleFlag;
+ /* PIPE_NEW_RAST */
+ key->line_stipple = brw->curr.rast->templ.line_stipple_enable;
+
- /* _NEW_POLYGON */
- key->offset_enable = ctx->Polygon.OffsetFill;
- key->offset_units = ctx->Polygon.OffsetUnits;
- key->offset_factor = ctx->Polygon.OffsetFactor;
+ key->offset_enable = (brw->curr.rast->templ.offset_cw ||
+ brw->curr.rast->templ.offset_ccw);
+
+ key->offset_units = brw->curr.rast->templ.offset_units;
+ key->offset_factor = brw->curr.rast->templ.offset_scale;
}
/**
memset(&wm, 0, sizeof(wm));
- wm.thread0.grf_reg_count = ALIGN(key->total_grf, 16) / 16 - 1;
+ wm.thread0.grf_reg_count = align(key->total_grf, 16) / 16 - 1;
wm.thread0.kernel_start_pointer = brw->wm.prog_bo->offset >> 6; /* reloc */
wm.thread1.depth_coef_urb_read_offset = 1;
wm.thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754;
NULL, NULL);
/* Emit WM program relocation */
- dri_bo_emit_reloc(bo,
+ brw->sws->bo_emit_reloc(bo,
I915_GEM_DOMAIN_INSTRUCTION, 0,
wm.thread0.grf_reg_count << 1,
offsetof(struct brw_wm_unit_state, thread0),
/* Emit scratch space relocation */
if (key->total_scratch != 0) {
- dri_bo_emit_reloc(bo,
+ brw->sws->bo_emit_reloc(bo,
0, 0,
wm.thread2.per_thread_scratch_space,
offsetof(struct brw_wm_unit_state, thread2),
/* Emit sampler state relocation */
if (key->sampler_count != 0) {
- dri_bo_emit_reloc(bo,
+ brw->sws->bo_emit_reloc(bo,
I915_GEM_DOMAIN_INSTRUCTION, 0,
wm.wm4.stats_enable | (wm.wm4.sampler_count << 2),
offsetof(struct brw_wm_unit_state, wm4),
}
-static void upload_wm_unit( struct brw_context *brw )
+static int upload_wm_unit( struct brw_context *brw )
{
struct brw_wm_unit_key key;
struct brw_winsys_buffer *reloc_bufs[3];
if (brw->wm.state_bo == NULL) {
brw->wm.state_bo = wm_unit_create_from_key(brw, &key, reloc_bufs);
}
+
+ return 0;
}
const struct brw_tracked_state brw_wm_unit = {
.dirty = {
- .mesa = (PIPE_NEW_DEPTH_BUFFER |
- _NEW_POLYGON |
- _NEW_POLYGONSTIPPLE |
- _NEW_LINE |
- _NEW_COLOR |
- _NEW_QUERY),
-
- .brw = (BRW_NEW_FRAGMENT_PROGRAM |
- BRW_NEW_CURBE_OFFSETS |
+ .mesa = (PIPE_NEW_FRAGMENT_SHADER |
+ PIPE_NEW_DEPTH_BUFFER |
+ PIPE_NEW_RAST |
+ PIPE_NEW_DEPTH_STENCIL_ALPHA |
+ PIPE_NEW_QUERY),
+
+ .brw = (BRW_NEW_CURBE_OFFSETS |
BRW_NEW_NR_WM_SURFACES),
.cache = (CACHE_NEW_WM_PROG |