#include "pipe/p_context.h"
#include "pipe/p_state.h"
+#include "pipe/p_util.h"
#include "i915_state_inlines.h"
#include "i915_context.h"
}
}
+static unsigned translate_compare_func(unsigned func)
+{
+ switch (func) {
+ case PIPE_FUNC_NEVER:
+ case PIPE_FUNC_LESS:
+ case PIPE_FUNC_EQUAL:
+ case PIPE_FUNC_LEQUAL:
+ case PIPE_FUNC_GREATER:
+ case PIPE_FUNC_NOTEQUAL:
+ case PIPE_FUNC_GEQUAL:
+ case PIPE_FUNC_ALWAYS:
+ return 0;
+ default:
+ assert(0);
+ return 0;
+ }
+}
+
-/* Recalculate all state from scratch. Perhaps not the most
+static uint
+bitcount(uint k)
+{
+ uint count = 0;
+ while (k) {
+ if (k & 1)
+ count++;
+ k = k >> 1;
+ }
+ return count;
+}
+
+
+static boolean
+is_power_of_two_texture(const struct pipe_mipmap_tree *mt)
+{
+ if (bitcount(mt->width0) == 1 &&
+ bitcount(mt->height0) == 1 &&
+ bitcount(mt->depth0) == 1) {
+ return 1;
+ }
+ else
+ return 0;
+}
+
+
+/**
+ * Compute i915 texture sampling state.
+ *
+ * Recalculate all state from scratch. Perhaps not the most
* efficient, but this has gotten complex enough that we need
* something which is understandable and reliable.
+ * \param state returns the 3 words of compute state
*/
-static void update_sampler(struct i915_context *i915,
+static void update_sampler(struct i915_context *i915,
+ uint unit,
const struct pipe_sampler_state *sampler,
- const struct pipe_surface_state *surface,
- unsigned surface_index,
- unsigned target,
- unsigned *state )
+ const struct pipe_mipmap_tree *mt,
+ const struct pipe_surface *surface,
+ unsigned state[3] )
{
+ const unsigned ws = sampler->wrap_s;
+ const unsigned wt = sampler->wrap_t;
+ const unsigned wr = sampler->wrap_r;
/* Need to do this after updating the maps, which call the
* intel_finalize_mipmap_tree and hence can update firstLevel:
mipFilt = translate_mip_filter( sampler->min_mip_filter );
- if (tObj->MaxAnisotropy > 1.0) {
+ if (sampler->max_anisotropy > 1.0) {
minFilt = FILTER_ANISOTROPIC;
magFilt = FILTER_ANISOTROPIC;
}
state[0] |= ((b << SS2_LOD_BIAS_SHIFT) & SS2_LOD_BIAS_MASK);
}
- if (surface->format == MESA_FORMAT_YCBCR ||
- surface->format == MESA_FORMAT_YCBCR_REV)
+ if (surface->format == PIPE_FORMAT_YCBCR ||
+ surface->format == PIPE_FORMAT_YCBCR_REV)
state[0] |= SS2_COLORSPACE_CONVERSION;
(magFilt << SS2_MAG_FILTER_SHIFT));
- if (0)
- {
- unsigned ws = tObj->WrapS;
- unsigned wt = tObj->WrapT;
- unsigned wr = tObj->WrapR;
-
- /* 3D textures don't seem to respect the border color.
- * Fallback if there's ever a danger that they might refer to
- * it.
- *
- * Effectively this means fallback on 3D clamp or
- * clamp_to_border.
- *
- * XXX: Check if this is true on i945.
- * XXX: Check if this bug got fixed in release silicon.
- */
- if (target == PIPE_TEXTURE_3D &&
- (sampler->min_img_filter != PIPE_TEX_FILTER_NEAREST ||
- sampler->mag_img_filter != PIPE_TEX_FILTER_NEAREST) &&
- (ws == GL_CLAMP ||
- wt == GL_CLAMP ||
- wr == GL_CLAMP ||
- ws == GL_CLAMP_TO_BORDER ||
- wt == GL_CLAMP_TO_BORDER ||
- wr == GL_CLAMP_TO_BORDER)) {
-
- if (intel->strict_conformance) {
- assert(0);
-/* sampler->fallback = true; */
- /* TODO */
- }
+ /* 3D textures don't seem to respect the border color.
+ * Fallback if there's ever a danger that they might refer to
+ * it.
+ *
+ * Effectively this means fallback on 3D clamp or
+ * clamp_to_border.
+ *
+ * XXX: Check if this is true on i945.
+ * XXX: Check if this bug got fixed in release silicon.
+ */
+ if (mt->target == PIPE_TEXTURE_3D &&
+ (sampler->min_img_filter != PIPE_TEX_FILTER_NEAREST ||
+ sampler->mag_img_filter != PIPE_TEX_FILTER_NEAREST) &&
+ (ws == PIPE_TEX_WRAP_CLAMP ||
+ wt == PIPE_TEX_WRAP_CLAMP ||
+ wr == PIPE_TEX_WRAP_CLAMP ||
+ ws == PIPE_TEX_WRAP_CLAMP_TO_BORDER ||
+ wt == PIPE_TEX_WRAP_CLAMP_TO_BORDER ||
+ wr == PIPE_TEX_WRAP_CLAMP_TO_BORDER)) {
+#if 0
+ if (i915->strict_conformance) {
+ assert(0);
+ /* sampler->fallback = true; */
+ /* TODO */
}
+#endif
+ }
+ state[1] =
+ ((translate_wrap_mode(ws) << SS3_TCX_ADDR_MODE_SHIFT) |
+ (translate_wrap_mode(wt) << SS3_TCY_ADDR_MODE_SHIFT) |
+ (translate_wrap_mode(wr) << SS3_TCZ_ADDR_MODE_SHIFT) |
+ (unit << SS3_TEXTUREMAP_INDEX_SHIFT));
- state[1] =
- ((translate_wrap_mode(ws) << SS3_TCX_ADDR_MODE_SHIFT) |
- (translate_wrap_mode(wt) << SS3_TCY_ADDR_MODE_SHIFT) |
- (translate_wrap_mode(wr) << SS3_TCZ_ADDR_MODE_SHIFT) |
- (unit << SS3_TEXTUREMAP_INDEX_SHIFT));
-
- if (target != TEXTURE_RECT_BIT)
- state[1] |= SS3_NORMALIZED_COORDS;
+ if (is_power_of_two_texture(mt)) {
+ state[1] |= SS3_NORMALIZED_COORDS;
+ }
- state[2] = INTEL_PACKCOLOR8888(tObj->_BorderChan[0],
- tObj->_BorderChan[1],
- tObj->_BorderChan[2],
- tObj->_BorderChan[3]);
+ {
+ ubyte r = float_to_ubyte(sampler->border_color[0]);
+ ubyte g = float_to_ubyte(sampler->border_color[1]);
+ ubyte b = float_to_ubyte(sampler->border_color[2]);
+ ubyte a = float_to_ubyte(sampler->border_color[3]);
+ state[2] = I915PACKCOLOR8888(r, g, b, a);
+ }
}
void i915_update_samplers( struct i915_context *i915 )
{
- int i, dirty = 0, nr = 0;
-
- for (i = 0; i < I915_TEX_UNITS; i++) {
- if (i915->sampler[i].enabled) { /* ??? */
- update_sampler( i915, i,
- i915->current.sampler[i] );
- nr++;
- dirty |= (1<<i);
+ const struct pipe_surface *surface = i915->framebuffer.cbufs[0];
+ uint unit;
+
+ i915->current.sampler_enable_nr = 0;
+ i915->current.sampler_enable_flags = 0x0;
+
+ for (unit = 0; unit < I915_TEX_UNITS; unit++) {
+ /* determine unit enable/disable by looking for a bound mipmap tree */
+ /* could also examine the fragment program? */
+ if (i915->texture[unit]) {
+ update_sampler( i915,
+ unit,
+ i915->sampler + unit, /* sampler state */
+ i915->texture[unit], /* mipmap tree */
+ surface, /* cbuffer info */
+ i915->current.sampler[unit] /* the result */
+ );
+
+ i915->current.sampler_enable_nr++;
+ i915->current.sampler_enable_flags |= (1 << unit);
}
}
-}
+ i915->hardware_dirty |= I915_HW_SAMPLER;
+}