}
-static void
-convert_sampler(struct st_context *st,
- struct pipe_sampler_state *sampler,
- GLuint texUnit)
+/**
+ * Convert a gl_sampler_object to a pipe_sampler_state object.
+ */
+void
+st_convert_sampler(const struct st_context *st,
+ const struct gl_texture_object *texobj,
+ const struct gl_sampler_object *msamp,
+ struct pipe_sampler_state *sampler)
{
- const struct gl_texture_object *texobj;
- struct gl_context *ctx = st->ctx;
- const struct gl_sampler_object *msamp;
GLenum texBaseFormat;
- texobj = ctx->Texture.Unit[texUnit]._Current;
- if (!texobj) {
- texobj = _mesa_get_fallback_texture(ctx, TEXTURE_2D_INDEX);
- msamp = &texobj->Sampler;
- } else {
- msamp = _mesa_get_samplerobj(ctx, texUnit);
- }
-
texBaseFormat = _mesa_texture_base_format(texobj);
memset(sampler, 0, sizeof(*sampler));
if (texobj->Target != GL_TEXTURE_RECTANGLE_ARB)
sampler->normalized_coords = 1;
- sampler->lod_bias = ctx->Texture.Unit[texUnit].LodBias + msamp->LodBias;
+ sampler->lod_bias = msamp->LodBias;
+ /* Reduce the number of states by allowing only the values that AMD GCN
+ * can represent. Apps use lod_bias for smooth transitions to bigger mipmap
+ * levels.
+ */
+ sampler->lod_bias = CLAMP(sampler->lod_bias, -16, 16);
+ sampler->lod_bias = floorf(sampler->lod_bias * 256) / 256;
sampler->min_lod = MAX2(msamp->MinLod, 0.0f);
sampler->max_lod = msamp->MaxLod;
/* If sampling a depth texture and using shadow comparison */
if ((texBaseFormat == GL_DEPTH_COMPONENT ||
- texBaseFormat == GL_DEPTH_STENCIL) &&
+ (texBaseFormat == GL_DEPTH_STENCIL && !texobj->StencilSampling)) &&
msamp->CompareMode == GL_COMPARE_R_TO_TEXTURE) {
sampler->compare_mode = PIPE_TEX_COMPARE_R_TO_TEXTURE;
sampler->compare_func = st_compare_func_to_pipe(msamp->CompareFunc);
}
- sampler->seamless_cube_map =
- ctx->Texture.CubeMapSeamless || msamp->CubeMapSeamless;
+ /* Only set the seamless cube map texture parameter because the per-context
+ * enable should be ignored and treated as disabled when using texture
+ * handles, as specified by ARB_bindless_texture.
+ */
+ sampler->seamless_cube_map = msamp->CubeMapSeamless;
+}
+
+/**
+ * Get a pipe_sampler_state object from a texture unit.
+ */
+void
+st_convert_sampler_from_unit(const struct st_context *st,
+ struct pipe_sampler_state *sampler,
+ GLuint texUnit)
+{
+ const struct gl_texture_object *texobj;
+ struct gl_context *ctx = st->ctx;
+ const struct gl_sampler_object *msamp;
+
+ texobj = ctx->Texture.Unit[texUnit]._Current;
+ assert(texobj);
+
+ msamp = _mesa_get_samplerobj(ctx, texUnit);
+
+ st_convert_sampler(st, texobj, msamp, sampler);
+
+ sampler->lod_bias += ctx->Texture.Unit[texUnit].LodBias;
+ sampler->seamless_cube_map |= ctx->Texture.CubeMapSeamless;
}
const GLuint old_max = *num_samplers;
const struct pipe_sampler_state *states[PIPE_MAX_SAMPLERS];
- if (*num_samplers == 0 && samplers_used == 0x0)
+ if (samplers_used == 0x0)
return;
*num_samplers = 0;
if (samplers_used & 1) {
const GLuint texUnit = prog->SamplerUnits[unit];
- convert_sampler(st, sampler, texUnit);
+ st_convert_sampler_from_unit(st, sampler, texUnit);
states[unit] = sampler;
*num_samplers = unit + 1;
}
}
-static void
-update_samplers(struct st_context *st)
+void
+st_update_vertex_samplers(struct st_context *st)
{
const struct gl_context *ctx = st->ctx;
- update_shader_samplers(st,
- PIPE_SHADER_FRAGMENT,
- &ctx->FragmentProgram._Current->Base,
- ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits,
- st->state.samplers[PIPE_SHADER_FRAGMENT],
- &st->state.num_samplers[PIPE_SHADER_FRAGMENT]);
-
update_shader_samplers(st,
PIPE_SHADER_VERTEX,
- &ctx->VertexProgram._Current->Base,
+ ctx->VertexProgram._Current,
ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits,
st->state.samplers[PIPE_SHADER_VERTEX],
&st->state.num_samplers[PIPE_SHADER_VERTEX]);
+}
+
+
+void
+st_update_tessctrl_samplers(struct st_context *st)
+{
+ const struct gl_context *ctx = st->ctx;
- if (ctx->GeometryProgram._Current) {
- update_shader_samplers(st,
- PIPE_SHADER_GEOMETRY,
- &ctx->GeometryProgram._Current->Base,
- ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits,
- st->state.samplers[PIPE_SHADER_GEOMETRY],
- &st->state.num_samplers[PIPE_SHADER_GEOMETRY]);
- }
if (ctx->TessCtrlProgram._Current) {
update_shader_samplers(st,
PIPE_SHADER_TESS_CTRL,
- &ctx->TessCtrlProgram._Current->Base,
+ ctx->TessCtrlProgram._Current,
ctx->Const.Program[MESA_SHADER_TESS_CTRL].MaxTextureImageUnits,
st->state.samplers[PIPE_SHADER_TESS_CTRL],
&st->state.num_samplers[PIPE_SHADER_TESS_CTRL]);
}
+}
+
+
+void
+st_update_tesseval_samplers(struct st_context *st)
+{
+ const struct gl_context *ctx = st->ctx;
+
if (ctx->TessEvalProgram._Current) {
update_shader_samplers(st,
PIPE_SHADER_TESS_EVAL,
- &ctx->TessEvalProgram._Current->Base,
+ ctx->TessEvalProgram._Current,
ctx->Const.Program[MESA_SHADER_TESS_EVAL].MaxTextureImageUnits,
st->state.samplers[PIPE_SHADER_TESS_EVAL],
&st->state.num_samplers[PIPE_SHADER_TESS_EVAL]);
}
+}
+
+
+void
+st_update_geometry_samplers(struct st_context *st)
+{
+ const struct gl_context *ctx = st->ctx;
+
+ if (ctx->GeometryProgram._Current) {
+ update_shader_samplers(st,
+ PIPE_SHADER_GEOMETRY,
+ ctx->GeometryProgram._Current,
+ ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits,
+ st->state.samplers[PIPE_SHADER_GEOMETRY],
+ &st->state.num_samplers[PIPE_SHADER_GEOMETRY]);
+ }
+}
+
+
+void
+st_update_fragment_samplers(struct st_context *st)
+{
+ const struct gl_context *ctx = st->ctx;
+
+ update_shader_samplers(st,
+ PIPE_SHADER_FRAGMENT,
+ ctx->FragmentProgram._Current,
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits,
+ st->state.samplers[PIPE_SHADER_FRAGMENT],
+ &st->state.num_samplers[PIPE_SHADER_FRAGMENT]);
+}
+
+
+void
+st_update_compute_samplers(struct st_context *st)
+{
+ const struct gl_context *ctx = st->ctx;
+
if (ctx->ComputeProgram._Current) {
update_shader_samplers(st,
PIPE_SHADER_COMPUTE,
- &ctx->ComputeProgram._Current->Base,
+ ctx->ComputeProgram._Current,
ctx->Const.Program[MESA_SHADER_COMPUTE].MaxTextureImageUnits,
st->state.samplers[PIPE_SHADER_COMPUTE],
&st->state.num_samplers[PIPE_SHADER_COMPUTE]);
}
}
-
-
-const struct st_tracked_state st_update_sampler = {
- update_samplers /* update */
-};