}
}
-static drm_intel_bo *upload_default_color( struct brw_context *brw,
- const GLfloat *color )
+static void
+upload_default_color(struct brw_context *brw, struct gl_sampler_object *sampler,
+ int unit)
{
struct intel_context *intel = &brw->intel;
+ struct gl_context *ctx = &intel->ctx;
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+ struct gl_texture_object *texObj = texUnit->_Current;
+ struct gl_texture_image *firstImage = texObj->Image[0][texObj->BaseLevel];
+ float color[4];
+
+ if (firstImage->_BaseFormat == GL_DEPTH_COMPONENT) {
+ /* GL specs that border color for depth textures is taken from the
+ * R channel, while the hardware uses A. Spam R into all the
+ * channels for safety.
+ */
+ color[0] = sampler->BorderColor.f[0];
+ color[1] = sampler->BorderColor.f[0];
+ color[2] = sampler->BorderColor.f[0];
+ color[3] = sampler->BorderColor.f[0];
+ } else {
+ color[0] = sampler->BorderColor.f[0];
+ color[1] = sampler->BorderColor.f[1];
+ color[2] = sampler->BorderColor.f[2];
+ color[3] = sampler->BorderColor.f[3];
+ }
if (intel->gen >= 5) {
- struct gen5_sampler_default_color sdc;
-
- memset(&sdc, 0, sizeof(sdc));
-
- UNCLAMPED_FLOAT_TO_UBYTE(sdc.ub[0], color[0]);
- UNCLAMPED_FLOAT_TO_UBYTE(sdc.ub[1], color[1]);
- UNCLAMPED_FLOAT_TO_UBYTE(sdc.ub[2], color[2]);
- UNCLAMPED_FLOAT_TO_UBYTE(sdc.ub[3], color[3]);
-
- UNCLAMPED_FLOAT_TO_USHORT(sdc.us[0], color[0]);
- UNCLAMPED_FLOAT_TO_USHORT(sdc.us[1], color[1]);
- UNCLAMPED_FLOAT_TO_USHORT(sdc.us[2], color[2]);
- UNCLAMPED_FLOAT_TO_USHORT(sdc.us[3], color[3]);
-
- UNCLAMPED_FLOAT_TO_SHORT(sdc.s[0], color[0]);
- UNCLAMPED_FLOAT_TO_SHORT(sdc.s[1], color[1]);
- UNCLAMPED_FLOAT_TO_SHORT(sdc.s[2], color[2]);
- UNCLAMPED_FLOAT_TO_SHORT(sdc.s[3], color[3]);
-
- sdc.hf[0] = _mesa_float_to_half(color[0]);
- sdc.hf[1] = _mesa_float_to_half(color[1]);
- sdc.hf[2] = _mesa_float_to_half(color[2]);
- sdc.hf[3] = _mesa_float_to_half(color[3]);
-
- sdc.b[0] = sdc.s[0] >> 8;
- sdc.b[1] = sdc.s[1] >> 8;
- sdc.b[2] = sdc.s[2] >> 8;
- sdc.b[3] = sdc.s[3] >> 8;
-
- sdc.f[0] = color[0];
- sdc.f[1] = color[1];
- sdc.f[2] = color[2];
- sdc.f[3] = color[3];
-
- return brw_cache_data(&brw->cache, BRW_SAMPLER_DEFAULT_COLOR,
- &sdc, sizeof(sdc));
- } else {
- struct brw_sampler_default_color sdc;
+ struct gen5_sampler_default_color *sdc;
- COPY_4V(sdc.color, color);
+ sdc = brw_state_batch(brw, sizeof(*sdc), 32, &brw->wm.sdc_offset[unit]);
- return brw_cache_data(&brw->cache, BRW_SAMPLER_DEFAULT_COLOR,
- &sdc, sizeof(sdc));
- }
-}
+ memset(sdc, 0, sizeof(*sdc));
+ UNCLAMPED_FLOAT_TO_UBYTE(sdc->ub[0], color[0]);
+ UNCLAMPED_FLOAT_TO_UBYTE(sdc->ub[1], color[1]);
+ UNCLAMPED_FLOAT_TO_UBYTE(sdc->ub[2], color[2]);
+ UNCLAMPED_FLOAT_TO_UBYTE(sdc->ub[3], color[3]);
-struct wm_sampler_key {
- int sampler_count;
+ UNCLAMPED_FLOAT_TO_USHORT(sdc->us[0], color[0]);
+ UNCLAMPED_FLOAT_TO_USHORT(sdc->us[1], color[1]);
+ UNCLAMPED_FLOAT_TO_USHORT(sdc->us[2], color[2]);
+ UNCLAMPED_FLOAT_TO_USHORT(sdc->us[3], color[3]);
- 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;
+ UNCLAMPED_FLOAT_TO_SHORT(sdc->s[0], color[0]);
+ UNCLAMPED_FLOAT_TO_SHORT(sdc->s[1], color[1]);
+ UNCLAMPED_FLOAT_TO_SHORT(sdc->s[2], color[2]);
+ UNCLAMPED_FLOAT_TO_SHORT(sdc->s[3], color[3]);
- /** If target is cubemap, take context setting.
- */
- GLboolean seamless_cube_map;
- } sampler[BRW_MAX_TEX_UNIT];
-};
+ sdc->hf[0] = _mesa_float_to_half(color[0]);
+ sdc->hf[1] = _mesa_float_to_half(color[1]);
+ sdc->hf[2] = _mesa_float_to_half(color[2]);
+ sdc->hf[3] = _mesa_float_to_half(color[3]);
+
+ sdc->b[0] = sdc->s[0] >> 8;
+ sdc->b[1] = sdc->s[1] >> 8;
+ sdc->b[2] = sdc->s[2] >> 8;
+ sdc->b[3] = sdc->s[3] >> 8;
+
+ sdc->f[0] = color[0];
+ sdc->f[1] = color[1];
+ sdc->f[2] = color[2];
+ sdc->f[3] = color[3];
+ } else {
+ struct brw_sampler_default_color *sdc;
+
+ sdc = brw_state_batch(brw, sizeof(*sdc), 32, &brw->wm.sdc_offset[unit]);
+
+ COPY_4V(sdc->color, color);
+ }
+}
/**
* Sets the sampler state for a single unit based off of the sampler key
* entry.
*/
static void brw_update_sampler_state(struct brw_context *brw,
- struct wm_sampler_entry *key,
- drm_intel_bo *sdc_bo,
+ int unit,
struct brw_sampler_state *sampler)
{
struct intel_context *intel = &brw->intel;
+ struct gl_context *ctx = &intel->ctx;
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+ struct gl_texture_object *texObj = texUnit->_Current;
+ struct gl_sampler_object *gl_sampler = _mesa_get_samplerobj(ctx, unit);
- memset(sampler, 0, sizeof(*sampler));
-
- switch (key->minfilter) {
+ switch (gl_sampler->MinFilter) {
case GL_NEAREST:
sampler->ss0.min_filter = BRW_MAPFILTER_NEAREST;
sampler->ss0.mip_filter = BRW_MIPFILTER_NONE;
/* Set Anisotropy:
*/
- if (key->max_aniso > 1.0) {
+ if (gl_sampler->MaxAnisotropy > 1.0) {
sampler->ss0.min_filter = BRW_MAPFILTER_ANISOTROPIC;
sampler->ss0.mag_filter = BRW_MAPFILTER_ANISOTROPIC;
- if (key->max_aniso > 2.0) {
- sampler->ss3.max_aniso = MIN2((key->max_aniso - 2) / 2,
+ if (gl_sampler->MaxAnisotropy > 2.0) {
+ sampler->ss3.max_aniso = MIN2((gl_sampler->MaxAnisotropy - 2) / 2,
BRW_ANISORATIO_16);
}
}
else {
- switch (key->magfilter) {
+ switch (gl_sampler->MagFilter) {
case GL_NEAREST:
sampler->ss0.mag_filter = BRW_MAPFILTER_NEAREST;
break;
}
}
- sampler->ss1.r_wrap_mode = translate_wrap_mode(key->wrap_r);
- sampler->ss1.s_wrap_mode = translate_wrap_mode(key->wrap_s);
- sampler->ss1.t_wrap_mode = translate_wrap_mode(key->wrap_t);
+ sampler->ss1.r_wrap_mode = translate_wrap_mode(gl_sampler->WrapR);
+ sampler->ss1.s_wrap_mode = translate_wrap_mode(gl_sampler->WrapS);
+ sampler->ss1.t_wrap_mode = translate_wrap_mode(gl_sampler->WrapT);
if (intel->gen >= 6 &&
sampler->ss0.min_filter != sampler->ss0.mag_filter)
/* 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)) {
+ if (texObj->Target == GL_TEXTURE_CUBE_MAP) {
+ if (ctx->Texture.CubeMapSeamless &&
+ (gl_sampler->MinFilter != GL_NEAREST ||
+ gl_sampler->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;
sampler->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
sampler->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
}
- } else if (key->tex_target == GL_TEXTURE_1D) {
+ } else if (texObj->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
/* Set shadow function:
*/
- if (key->comparemode == GL_COMPARE_R_TO_TEXTURE_ARB) {
+ if (gl_sampler->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB) {
/* 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(key->comparefunc);
+ intel_translate_shadow_compare_func(gl_sampler->CompareFunc);
}
/* Set LOD bias:
*/
- sampler->ss0.lod_bias = S_FIXED(CLAMP(key->lod_bias, -16, 15), 6);
+ sampler->ss0.lod_bias = S_FIXED(CLAMP(texUnit->LodBias +
+ gl_sampler->LodBias, -16, 15), 6);
sampler->ss0.lod_preclamp = 1; /* OpenGL mode */
sampler->ss0.default_color_mode = 0; /* OpenGL/DX10 mode */
*/
sampler->ss0.base_level = U_FIXED(0, 1);
- sampler->ss1.max_lod = U_FIXED(CLAMP(key->maxlod, 0, 13), 6);
- sampler->ss1.min_lod = U_FIXED(CLAMP(key->minlod, 0, 13), 6);
-
- sampler->ss2.default_color_pointer = sdc_bo->offset >> 5; /* reloc */
-}
+ sampler->ss1.max_lod = U_FIXED(CLAMP(gl_sampler->MaxLod, 0, 13), 6);
+ sampler->ss1.min_lod = U_FIXED(CLAMP(gl_sampler->MinLod, 0, 13), 6);
+ upload_default_color(brw, gl_sampler, unit);
-/** 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)
-{
- struct gl_context *ctx = &brw->intel.ctx;
- int unit;
- char *last_entry_end = ((char*)&key->sampler_count) +
- sizeof(key->sampler_count);
-
- key->sampler_count = 0;
-
- for (unit = 0; unit < BRW_MAX_TEX_UNIT; unit++) {
- if (ctx->Texture.Unit[unit]._ReallyEnabled) {
- struct wm_sampler_entry *entry = &key->sampler[unit];
- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
- struct gl_texture_object *texObj = texUnit->_Current;
- struct gl_texture_image *firstImage =
- texObj->Image[0][texObj->BaseLevel];
- struct gl_sampler_object *sampler = _mesa_get_samplerobj(ctx, unit);
-
- memset(last_entry_end, 0,
- (char*)entry - last_entry_end + sizeof(*entry));
- last_entry_end = ((char*)entry) + sizeof(*entry);
-
- entry->tex_target = texObj->Target;
-
- entry->seamless_cube_map = (texObj->Target == GL_TEXTURE_CUBE_MAP)
- ? ctx->Texture.CubeMapSeamless : GL_FALSE;
-
- entry->wrap_r = sampler->WrapR;
- entry->wrap_s = sampler->WrapS;
- entry->wrap_t = sampler->WrapT;
-
- entry->maxlod = sampler->MaxLod;
- entry->minlod = sampler->MinLod;
- entry->lod_bias = texUnit->LodBias + sampler->LodBias;
- entry->max_aniso = sampler->MaxAnisotropy;
- entry->minfilter = sampler->MinFilter;
- entry->magfilter = sampler->MagFilter;
- entry->comparemode = sampler->CompareMode;
- entry->comparefunc = sampler->CompareFunc;
-
- drm_intel_bo_unreference(brw->wm.sdc_bo[unit]);
- if (firstImage->_BaseFormat == GL_DEPTH_COMPONENT) {
- float bordercolor[4] = {
- sampler->BorderColor.f[0],
- sampler->BorderColor.f[0],
- sampler->BorderColor.f[0],
- sampler->BorderColor.f[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
- * channels for safety.
- */
- brw->wm.sdc_bo[unit] = upload_default_color(brw, bordercolor);
- } else {
- brw->wm.sdc_bo[unit] = upload_default_color(brw,
- sampler->BorderColor.f);
- }
- key->sampler_count = unit + 1;
- }
- }
- struct wm_sampler_entry *entry = &key->sampler[key->sampler_count];
- memset(last_entry_end, 0, (char*)entry - last_entry_end);
+ /* reloc */
+ sampler->ss2.default_color_pointer = (intel->batch.bo->offset +
+ brw->wm.sdc_offset[unit]) >> 5;
+
+ drm_intel_bo_emit_reloc(intel->batch.bo,
+ brw->wm.sampler_offset +
+ unit * sizeof(struct brw_sampler_state) +
+ offsetof(struct brw_sampler_state, ss2),
+ intel->batch.bo, brw->wm.sdc_offset[unit],
+ I915_GEM_DOMAIN_SAMPLER, 0);
}
+
/* 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.
*/
-static void upload_wm_samplers( struct brw_context *brw )
+static void
+prepare_wm_samplers(struct brw_context *brw)
{
struct gl_context *ctx = &brw->intel.ctx;
- struct wm_sampler_key key;
- int i, sampler_key_size;
+ struct brw_sampler_state *samplers;
+ int i;
- brw_wm_sampler_populate_key(brw, &key);
-
- if (brw->wm.sampler_count != key.sampler_count) {
- brw->wm.sampler_count = key.sampler_count;
- brw->state.dirty.cache |= CACHE_NEW_SAMPLER;
+ brw->wm.sampler_count = 0;
+ for (i = 0; i < BRW_MAX_TEX_UNIT; i++) {
+ if (ctx->Texture.Unit[i]._ReallyEnabled)
+ brw->wm.sampler_count = i + 1;
}
- drm_intel_bo_unreference(brw->wm.sampler_bo);
- brw->wm.sampler_bo = NULL;
if (brw->wm.sampler_count == 0)
return;
- /* Only include the populated portion of the key in the search. */
- sampler_key_size = offsetof(struct wm_sampler_key,
- sampler[key.sampler_count]);
- brw->wm.sampler_bo = brw_search_cache(&brw->cache, BRW_SAMPLER,
- &key, sampler_key_size,
- brw->wm.sdc_bo, key.sampler_count,
- NULL);
-
- /* If we didnt find it in the cache, compute the state and put it in the
- * 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;
+ samplers = brw_state_batch(brw, brw->wm.sampler_count * sizeof(*samplers),
+ 32, &brw->wm.sampler_offset);
+ memset(samplers, 0, brw->wm.sampler_count * sizeof(*samplers));
- brw_update_sampler_state(brw, &key.sampler[i], brw->wm.sdc_bo[i],
- &sampler[i]);
- }
-
- brw->wm.sampler_bo = brw_upload_cache(&brw->cache, BRW_SAMPLER,
- &key, sampler_key_size,
- brw->wm.sdc_bo, key.sampler_count,
- &sampler, sizeof(sampler));
-
- /* Emit SDC relocations */
- for (i = 0; i < BRW_MAX_TEX_UNIT; i++) {
- if (!ctx->Texture.Unit[i]._ReallyEnabled)
- continue;
-
- drm_intel_bo_emit_reloc(brw->wm.sampler_bo,
- i * sizeof(struct brw_sampler_state) +
- offsetof(struct brw_sampler_state, ss2),
- brw->wm.sdc_bo[i], 0,
- I915_GEM_DOMAIN_SAMPLER, 0);
- }
+ for (i = 0; i < brw->wm.sampler_count; i++) {
+ if (ctx->Texture.Unit[i]._ReallyEnabled)
+ brw_update_sampler_state(brw, i, &samplers[i]);
}
+
+ brw->state.dirty.cache |= CACHE_NEW_SAMPLER;
}
const struct brw_tracked_state brw_wm_samplers = {
.dirty = {
.mesa = _NEW_TEXTURE,
- .brw = 0,
+ .brw = BRW_NEW_BATCH,
.cache = 0
},
- .prepare = upload_wm_samplers,
+ .prepare = prepare_wm_samplers,
};