swrast: Support sampler object for texture fetching state
swrast needs to pass sampler object into all texture fetching functions to use correct sampling state when sampler object is bound to the unit. The changes were made using half manual regular expression replace. v2: Fix NULL deref in _swrast_choose_triangle(), because the _Current values aren't set yet, so we need to look at our texObj2D. (anholt) Signed-off-by: Pauli Nieminen <pauli.nieminen@linux.intel.com> Reviewed-by: Brian Paul <brianp@vmware.com>
This commit is contained in:

committed by
Eric Anholt

parent
8129dabb5f
commit
cbdc1d5354
@@ -23,6 +23,7 @@
|
||||
#include "main/colormac.h"
|
||||
#include "main/macros.h"
|
||||
#include "main/atifragshader.h"
|
||||
#include "main/samplerobj.h"
|
||||
#include "swrast/s_atifragshader.h"
|
||||
#include "swrast/s_context.h"
|
||||
|
||||
@@ -49,7 +50,8 @@ fetch_texel(struct gl_context * ctx, const GLfloat texcoord[4], GLfloat lambda,
|
||||
SWcontext *swrast = SWRAST_CONTEXT(ctx);
|
||||
|
||||
/* XXX use a float-valued TextureSample routine here!!! */
|
||||
swrast->TextureSample[unit](ctx, ctx->Texture.Unit[unit]._Current,
|
||||
swrast->TextureSample[unit](ctx, _mesa_get_samplerobj(ctx, unit),
|
||||
ctx->Texture.Unit[unit]._Current,
|
||||
1, (const GLfloat(*)[4]) texcoord,
|
||||
&lambda, (GLfloat (*)[4]) color);
|
||||
}
|
||||
|
@@ -480,9 +480,7 @@ _swrast_update_texture_samplers(struct gl_context *ctx)
|
||||
/* Note: If tObj is NULL, the sample function will be a simple
|
||||
* function that just returns opaque black (0,0,0,1).
|
||||
*/
|
||||
if (tObj) {
|
||||
_mesa_update_fetch_functions(tObj);
|
||||
}
|
||||
_mesa_update_fetch_functions(ctx, u);
|
||||
swrast->TextureSample[u] =
|
||||
_swrast_choose_texture_sample_func(ctx, tObj,
|
||||
_mesa_get_samplerobj(ctx, u));
|
||||
|
@@ -52,6 +52,7 @@
|
||||
|
||||
|
||||
typedef void (*texture_sample_func)(struct gl_context *ctx,
|
||||
const struct gl_sampler_object *samp,
|
||||
const struct gl_texture_object *tObj,
|
||||
GLuint n, const GLfloat texcoords[][4],
|
||||
const GLfloat lambda[], GLfloat rgba[][4]);
|
||||
|
@@ -24,6 +24,7 @@
|
||||
|
||||
#include "main/glheader.h"
|
||||
#include "main/colormac.h"
|
||||
#include "main/samplerobj.h"
|
||||
#include "program/prog_instruction.h"
|
||||
|
||||
#include "s_context.h"
|
||||
@@ -83,11 +84,12 @@ fetch_texel_lod( struct gl_context *ctx, const GLfloat texcoord[4], GLfloat lamb
|
||||
if (texObj) {
|
||||
SWcontext *swrast = SWRAST_CONTEXT(ctx);
|
||||
GLfloat rgba[4];
|
||||
const struct gl_sampler_object *samp = _mesa_get_samplerobj(ctx, unit);
|
||||
|
||||
lambda = CLAMP(lambda, texObj->Sampler.MinLod, texObj->Sampler.MaxLod);
|
||||
lambda = CLAMP(lambda, samp->MinLod, samp->MaxLod);
|
||||
|
||||
swrast->TextureSample[unit](ctx, texObj, 1,
|
||||
(const GLfloat (*)[4]) texcoord,
|
||||
swrast->TextureSample[unit](ctx, samp, ctx->Texture.Unit[unit]._Current,
|
||||
1, (const GLfloat (*)[4]) texcoord,
|
||||
&lambda, &rgba);
|
||||
swizzle_texel(rgba, color, texObj->_Swizzle);
|
||||
}
|
||||
@@ -118,6 +120,7 @@ fetch_texel_deriv( struct gl_context *ctx, const GLfloat texcoord[4],
|
||||
texObj->Image[0][texObj->BaseLevel];
|
||||
const struct swrast_texture_image *swImg =
|
||||
swrast_texture_image_const(texImg);
|
||||
const struct gl_sampler_object *samp = _mesa_get_samplerobj(ctx, unit);
|
||||
const GLfloat texW = (GLfloat) swImg->WidthScale;
|
||||
const GLfloat texH = (GLfloat) swImg->HeightScale;
|
||||
GLfloat lambda;
|
||||
@@ -130,12 +133,12 @@ fetch_texel_deriv( struct gl_context *ctx, const GLfloat texcoord[4],
|
||||
texcoord[0], texcoord[1], texcoord[3],
|
||||
1.0F / texcoord[3]);
|
||||
|
||||
lambda += lodBias + texUnit->LodBias + texObj->Sampler.LodBias;
|
||||
lambda += lodBias + texUnit->LodBias + samp->LodBias;
|
||||
|
||||
lambda = CLAMP(lambda, texObj->Sampler.MinLod, texObj->Sampler.MaxLod);
|
||||
lambda = CLAMP(lambda, samp->MinLod, samp->MaxLod);
|
||||
|
||||
swrast->TextureSample[unit](ctx, texObj, 1,
|
||||
(const GLfloat (*)[4]) texcoord,
|
||||
swrast->TextureSample[unit](ctx, samp, ctx->Texture.Unit[unit]._Current,
|
||||
1, (const GLfloat (*)[4]) texcoord,
|
||||
&lambda, &rgba);
|
||||
swizzle_texel(rgba, color, texObj->_Swizzle);
|
||||
}
|
||||
|
@@ -38,6 +38,7 @@
|
||||
#include "main/macros.h"
|
||||
#include "main/imports.h"
|
||||
#include "main/image.h"
|
||||
#include "main/samplerobj.h"
|
||||
|
||||
#include "s_atifragshader.h"
|
||||
#include "s_alpha.h"
|
||||
@@ -497,14 +498,15 @@ interpolate_texcoords(struct gl_context *ctx, SWspan *span)
|
||||
const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel];
|
||||
const struct swrast_texture_image *swImg =
|
||||
swrast_texture_image_const(img);
|
||||
const struct gl_sampler_object *samp = _mesa_get_samplerobj(ctx, u);
|
||||
|
||||
needLambda = (obj->Sampler.MinFilter != obj->Sampler.MagFilter)
|
||||
needLambda = (samp->MinFilter != samp->MagFilter)
|
||||
|| _swrast_use_fragment_program(ctx);
|
||||
/* LOD is calculated directly in the ansiotropic filter, we can
|
||||
* skip the normal lambda function as the result is ignored.
|
||||
*/
|
||||
if (obj->Sampler.MaxAnisotropy > 1.0 &&
|
||||
obj->Sampler.MinFilter == GL_LINEAR_MIPMAP_LINEAR) {
|
||||
if (samp->MaxAnisotropy > 1.0 &&
|
||||
samp->MinFilter == GL_LINEAR_MIPMAP_LINEAR) {
|
||||
needLambda = GL_FALSE;
|
||||
}
|
||||
texW = swImg->WidthScale;
|
||||
|
@@ -29,6 +29,7 @@
|
||||
#include "main/colormac.h"
|
||||
#include "main/imports.h"
|
||||
#include "main/pixeltransfer.h"
|
||||
#include "main/samplerobj.h"
|
||||
#include "program/prog_instruction.h"
|
||||
|
||||
#include "s_context.h"
|
||||
@@ -652,7 +653,7 @@ _swrast_texture_span( struct gl_context *ctx, SWspan *span )
|
||||
span->array->attribs[FRAG_ATTRIB_TEX0 +
|
||||
ctx->Texture.Unit[unit].BumpTarget - GL_TEXTURE0];
|
||||
|
||||
const struct gl_texture_object *curObj = texUnit->_Current;
|
||||
const struct gl_sampler_object *samp = _mesa_get_samplerobj(ctx, unit);
|
||||
GLfloat *lambda = span->array->lambda[unit];
|
||||
float4_array texels = get_texel_array(swrast, unit);
|
||||
GLuint i;
|
||||
@@ -663,9 +664,9 @@ _swrast_texture_span( struct gl_context *ctx, SWspan *span )
|
||||
|
||||
/* adjust texture lod (lambda) */
|
||||
if (span->arrayMask & SPAN_LAMBDA) {
|
||||
if (texUnit->LodBias + curObj->Sampler.LodBias != 0.0F) {
|
||||
if (texUnit->LodBias + samp->LodBias != 0.0F) {
|
||||
/* apply LOD bias, but don't clamp yet */
|
||||
const GLfloat bias = CLAMP(texUnit->LodBias + curObj->Sampler.LodBias,
|
||||
const GLfloat bias = CLAMP(texUnit->LodBias + samp->LodBias,
|
||||
-ctx->Const.MaxTextureLodBias,
|
||||
ctx->Const.MaxTextureLodBias);
|
||||
GLuint i;
|
||||
@@ -674,11 +675,11 @@ _swrast_texture_span( struct gl_context *ctx, SWspan *span )
|
||||
}
|
||||
}
|
||||
|
||||
if (curObj->Sampler.MinLod != -1000.0 ||
|
||||
curObj->Sampler.MaxLod != 1000.0) {
|
||||
if (samp->MinLod != -1000.0 ||
|
||||
samp->MaxLod != 1000.0) {
|
||||
/* apply LOD clamping to lambda */
|
||||
const GLfloat min = curObj->Sampler.MinLod;
|
||||
const GLfloat max = curObj->Sampler.MaxLod;
|
||||
const GLfloat min = samp->MinLod;
|
||||
const GLfloat max = samp->MaxLod;
|
||||
GLuint i;
|
||||
for (i = 0; i < span->end; i++) {
|
||||
GLfloat l = lambda[i];
|
||||
@@ -688,8 +689,9 @@ _swrast_texture_span( struct gl_context *ctx, SWspan *span )
|
||||
}
|
||||
|
||||
/* Sample the texture (span->end = number of fragments) */
|
||||
swrast->TextureSample[unit]( ctx, texUnit->_Current, span->end,
|
||||
texcoords, lambda, texels );
|
||||
swrast->TextureSample[unit]( ctx, samp,
|
||||
ctx->Texture.Unit[unit]._Current,
|
||||
span->end, texcoords, lambda, texels );
|
||||
|
||||
/* manipulate the span values of the bump target
|
||||
not sure this can work correctly even ignoring
|
||||
@@ -714,14 +716,15 @@ _swrast_texture_span( struct gl_context *ctx, SWspan *span )
|
||||
const GLfloat (*texcoords)[4] = (const GLfloat (*)[4])
|
||||
span->array->attribs[FRAG_ATTRIB_TEX0 + unit];
|
||||
const struct gl_texture_object *curObj = texUnit->_Current;
|
||||
const struct gl_sampler_object *samp = _mesa_get_samplerobj(ctx, unit);
|
||||
GLfloat *lambda = span->array->lambda[unit];
|
||||
float4_array texels = get_texel_array(swrast, unit);
|
||||
|
||||
/* adjust texture lod (lambda) */
|
||||
if (span->arrayMask & SPAN_LAMBDA) {
|
||||
if (texUnit->LodBias + curObj->Sampler.LodBias != 0.0F) {
|
||||
if (texUnit->LodBias + samp->LodBias != 0.0F) {
|
||||
/* apply LOD bias, but don't clamp yet */
|
||||
const GLfloat bias = CLAMP(texUnit->LodBias + curObj->Sampler.LodBias,
|
||||
const GLfloat bias = CLAMP(texUnit->LodBias + samp->LodBias,
|
||||
-ctx->Const.MaxTextureLodBias,
|
||||
ctx->Const.MaxTextureLodBias);
|
||||
GLuint i;
|
||||
@@ -730,11 +733,11 @@ _swrast_texture_span( struct gl_context *ctx, SWspan *span )
|
||||
}
|
||||
}
|
||||
|
||||
if (curObj->Sampler.MinLod != -1000.0 ||
|
||||
curObj->Sampler.MaxLod != 1000.0) {
|
||||
if (samp->MinLod != -1000.0 ||
|
||||
samp->MaxLod != 1000.0) {
|
||||
/* apply LOD clamping to lambda */
|
||||
const GLfloat min = curObj->Sampler.MinLod;
|
||||
const GLfloat max = curObj->Sampler.MaxLod;
|
||||
const GLfloat min = samp->MinLod;
|
||||
const GLfloat max = samp->MaxLod;
|
||||
GLuint i;
|
||||
for (i = 0; i < span->end; i++) {
|
||||
GLfloat l = lambda[i];
|
||||
@@ -742,8 +745,8 @@ _swrast_texture_span( struct gl_context *ctx, SWspan *span )
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (curObj->Sampler.MaxAnisotropy > 1.0 &&
|
||||
curObj->Sampler.MinFilter == GL_LINEAR_MIPMAP_LINEAR) {
|
||||
else if (samp->MaxAnisotropy > 1.0 &&
|
||||
samp->MinFilter == GL_LINEAR_MIPMAP_LINEAR) {
|
||||
/* sample_lambda_2d_aniso is beeing used as texture_sample_func,
|
||||
* it requires the current SWspan *span as an additional parameter.
|
||||
* In order to keep the same function signature, the unused lambda
|
||||
@@ -756,8 +759,9 @@ _swrast_texture_span( struct gl_context *ctx, SWspan *span )
|
||||
}
|
||||
|
||||
/* Sample the texture (span->end = number of fragments) */
|
||||
swrast->TextureSample[unit]( ctx, texUnit->_Current, span->end,
|
||||
texcoords, lambda, texels );
|
||||
swrast->TextureSample[unit]( ctx, samp,
|
||||
ctx->Texture.Unit[unit]._Current,
|
||||
span->end, texcoords, lambda, texels );
|
||||
|
||||
/* GL_EXT_texture_swizzle */
|
||||
if (curObj->_Swizzle != SWIZZLE_NOOP) {
|
||||
|
@@ -41,6 +41,7 @@
|
||||
#include "main/texcompress_rgtc.h"
|
||||
#include "main/texcompress_etc.h"
|
||||
#include "main/teximage.h"
|
||||
#include "main/samplerobj.h"
|
||||
#include "s_context.h"
|
||||
#include "s_texfetch.h"
|
||||
#include "../../gallium/auxiliary/util/u_format_rgb9e5.h"
|
||||
@@ -1147,13 +1148,14 @@ _mesa_get_texel_fetch_func(gl_format format, GLuint dims)
|
||||
* Initialize the texture image's FetchTexel methods.
|
||||
*/
|
||||
static void
|
||||
set_fetch_functions(struct swrast_texture_image *texImage, GLuint dims)
|
||||
set_fetch_functions(struct gl_sampler_object *samp,
|
||||
struct swrast_texture_image *texImage, GLuint dims)
|
||||
{
|
||||
gl_format format = texImage->Base.TexFormat;
|
||||
|
||||
ASSERT(dims == 1 || dims == 2 || dims == 3);
|
||||
|
||||
if (texImage->Base.TexObject->Sampler.sRGBDecode == GL_SKIP_DECODE_EXT &&
|
||||
if (samp->sRGBDecode == GL_SKIP_DECODE_EXT &&
|
||||
_mesa_get_format_color_encoding(format) == GL_SRGB) {
|
||||
format = _mesa_get_srgb_format_linear(format);
|
||||
}
|
||||
@@ -1163,17 +1165,25 @@ set_fetch_functions(struct swrast_texture_image *texImage, GLuint dims)
|
||||
}
|
||||
|
||||
void
|
||||
_mesa_update_fetch_functions(struct gl_texture_object *texObj)
|
||||
_mesa_update_fetch_functions(struct gl_context *ctx, GLuint unit)
|
||||
{
|
||||
struct gl_texture_object *texObj = ctx->Texture.Unit[unit]._Current;
|
||||
struct gl_sampler_object *samp;
|
||||
GLuint face, i;
|
||||
GLuint dims;
|
||||
|
||||
if (!texObj)
|
||||
return;
|
||||
|
||||
samp = _mesa_get_samplerobj(ctx, unit);
|
||||
|
||||
dims = _mesa_get_texture_dimensions(texObj->Target);
|
||||
|
||||
for (face = 0; face < 6; face++) {
|
||||
for (i = 0; i < MAX_TEXTURE_LEVELS; i++) {
|
||||
if (texObj->Image[face][i]) {
|
||||
set_fetch_functions(swrast_texture_image(texObj->Image[face][i]),
|
||||
set_fetch_functions(samp,
|
||||
swrast_texture_image(texObj->Image[face][i]),
|
||||
dims);
|
||||
}
|
||||
}
|
||||
|
@@ -33,6 +33,6 @@ extern FetchTexelFunc
|
||||
_mesa_get_texel_fetch_func(gl_format format, GLuint dims);
|
||||
|
||||
void
|
||||
_mesa_update_fetch_functions(struct gl_texture_object *texObj);
|
||||
_mesa_update_fetch_functions(struct gl_context *ctx, GLuint unit);
|
||||
|
||||
#endif /* S_TEXFETCH_H */
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -36,6 +36,7 @@
|
||||
#include "main/macros.h"
|
||||
#include "main/mtypes.h"
|
||||
#include "main/state.h"
|
||||
#include "main/samplerobj.h"
|
||||
#include "program/prog_instruction.h"
|
||||
|
||||
#include "s_aatriangle.h"
|
||||
@@ -1045,18 +1046,25 @@ _swrast_choose_triangle( struct gl_context *ctx )
|
||||
swrast->_FogEnabled) {
|
||||
/* Ugh, we do a _lot_ of tests to pick the best textured tri func */
|
||||
const struct gl_texture_object *texObj2D;
|
||||
const struct gl_sampler_object *samp;
|
||||
const struct gl_texture_image *texImg;
|
||||
const struct swrast_texture_image *swImg;
|
||||
GLenum minFilter, magFilter, envMode;
|
||||
gl_format format;
|
||||
texObj2D = ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX];
|
||||
if (ctx->Texture.Unit[0].Sampler)
|
||||
samp = ctx->Texture.Unit[0].Sampler;
|
||||
else if (texObj2D)
|
||||
samp = &texObj2D->Sampler;
|
||||
else
|
||||
samp = NULL;
|
||||
|
||||
texImg = texObj2D ? texObj2D->Image[0][texObj2D->BaseLevel] : NULL;
|
||||
swImg = swrast_texture_image_const(texImg);
|
||||
|
||||
format = texImg ? texImg->TexFormat : MESA_FORMAT_NONE;
|
||||
minFilter = texObj2D ? texObj2D->Sampler.MinFilter : GL_NONE;
|
||||
magFilter = texObj2D ? texObj2D->Sampler.MagFilter : GL_NONE;
|
||||
minFilter = texObj2D ? samp->MinFilter : GL_NONE;
|
||||
magFilter = texObj2D ? samp->MagFilter : GL_NONE;
|
||||
envMode = ctx->Texture.Unit[0].EnvMode;
|
||||
|
||||
/* First see if we can use an optimized 2-D texture function */
|
||||
@@ -1065,8 +1073,8 @@ _swrast_choose_triangle( struct gl_context *ctx )
|
||||
&& !ctx->ATIFragmentShader._Enabled
|
||||
&& ctx->Texture._EnabledUnits == 0x1
|
||||
&& ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT
|
||||
&& texObj2D->Sampler.WrapS == GL_REPEAT
|
||||
&& texObj2D->Sampler.WrapT == GL_REPEAT
|
||||
&& samp->WrapS == GL_REPEAT
|
||||
&& samp->WrapT == GL_REPEAT
|
||||
&& texObj2D->_Swizzle == SWIZZLE_NOOP
|
||||
&& swImg->_IsPowerOfTwo
|
||||
&& texImg->Border == 0
|
||||
|
@@ -35,6 +35,7 @@
|
||||
#include "main/colormac.h"
|
||||
#include "main/macros.h"
|
||||
#include "main/imports.h"
|
||||
#include "main/samplerobj.h"
|
||||
#include "math/m_xform.h"
|
||||
#include "program/prog_instruction.h"
|
||||
#include "program/prog_statevars.h"
|
||||
@@ -197,7 +198,8 @@ vp_fetch_texel(struct gl_context *ctx, const GLfloat texcoord[4], GLfloat lambda
|
||||
SWcontext *swrast = SWRAST_CONTEXT(ctx);
|
||||
|
||||
/* XXX use a float-valued TextureSample routine here!!! */
|
||||
swrast->TextureSample[unit](ctx, ctx->Texture.Unit[unit]._Current,
|
||||
swrast->TextureSample[unit](ctx, _mesa_get_samplerobj(ctx, unit),
|
||||
ctx->Texture.Unit[unit]._Current,
|
||||
1, (const GLfloat (*)[4]) texcoord,
|
||||
&lambda, (GLfloat (*)[4]) color);
|
||||
}
|
||||
|
Reference in New Issue
Block a user