1/************************************************************************** 2 * 3 * Copyright 2007 VMware, Inc. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 **************************************************************************/ 27 28 /* 29 * Authors: 30 * Keith Whitwell <keithw@vmware.com> 31 * Brian Paul 32 */ 33 34 35#include "main/context.h" 36#include "main/macros.h" 37#include "main/mtypes.h" 38#include "main/samplerobj.h" 39#include "main/teximage.h" 40#include "main/texobj.h" 41#include "program/prog_instruction.h" 42 43#include "st_context.h" 44#include "st_atom.h" 45#include "st_sampler_view.h" 46#include "st_texture.h" 47#include "st_format.h" 48#include "st_cb_texture.h" 49#include "pipe/p_context.h" 50#include "util/format/u_format.h" 51#include "util/u_inlines.h" 52#include "cso_cache/cso_context.h" 53 54 55/** 56 * Get a pipe_sampler_view object from a texture unit. 57 */ 58struct pipe_sampler_view * 59st_update_single_texture(struct st_context *st, 60 GLuint texUnit, bool glsl130_or_later, 61 bool ignore_srgb_decode, bool get_reference) 62{ 63 struct gl_context *ctx = st->ctx; 64 struct gl_texture_object *texObj; 65 struct st_texture_object *stObj; 66 67 texObj = ctx->Texture.Unit[texUnit]._Current; 68 assert(texObj); 69 70 stObj = st_texture_object(texObj); 71 GLenum target = texObj->Target; 72 73 if (unlikely(target == GL_TEXTURE_BUFFER)) 74 return st_get_buffer_sampler_view_from_stobj(st, stObj, get_reference); 75 76 if (!st_finalize_texture(ctx, st->pipe, texObj, 0) || !stObj->pt) 77 return NULL; /* out of mem */ 78 79 if (target == GL_TEXTURE_EXTERNAL_OES && 80 stObj->pt->screen->resource_changed) 81 stObj->pt->screen->resource_changed(stObj->pt->screen, stObj->pt); 82 83 return st_get_texture_sampler_view_from_stobj(st, stObj, 84 _mesa_get_samplerobj(ctx, texUnit), 85 glsl130_or_later, 86 ignore_srgb_decode, get_reference); 87} 88 89 90 91unsigned 92st_get_sampler_views(struct st_context *st, 93 enum pipe_shader_type shader_stage, 94 const struct gl_program *prog, 95 struct pipe_sampler_view **sampler_views) 96{ 97 struct pipe_context *pipe = st->pipe; 98 const GLuint old_max = st->state.num_sampler_views[shader_stage]; 99 GLbitfield samplers_used = prog->SamplersUsed; 100 GLbitfield texel_fetch_samplers = prog->info.textures_used_by_txf[0]; 101 GLbitfield free_slots = ~prog->SamplersUsed; 102 GLbitfield external_samplers_used = prog->ExternalSamplersUsed; 103 GLuint unit; 104 105 if (samplers_used == 0x0 && old_max == 0) 106 return 0; 107 108 unsigned num_textures = util_last_bit(samplers_used); 109 110 /* prog->sh.data is NULL if it's ARB_fragment_program */ 111 bool glsl130 = (prog->sh.data ? prog->sh.data->Version : 0) >= 130; 112 113 /* loop over sampler units (aka tex image units) */ 114 for (unit = 0; unit < num_textures; unit++) { 115 unsigned bit = BITFIELD_BIT(unit); 116 117 if (!(samplers_used & bit)) { 118 sampler_views[unit] = NULL; 119 continue; 120 } 121 122 /* The EXT_texture_sRGB_decode extension says: 123 * 124 * "The conversion of sRGB color space components to linear color 125 * space is always performed if the texel lookup function is one 126 * of the texelFetch builtin functions. 127 * 128 * Otherwise, if the texel lookup function is one of the texture 129 * builtin functions or one of the texture gather functions, the 130 * conversion of sRGB color space components to linear color space 131 * is controlled by the TEXTURE_SRGB_DECODE_EXT parameter. 132 * 133 * If the TEXTURE_SRGB_DECODE_EXT parameter is DECODE_EXT, the 134 * conversion of sRGB color space components to linear color space 135 * is performed. 136 * 137 * If the TEXTURE_SRGB_DECODE_EXT parameter is SKIP_DECODE_EXT, 138 * the value is returned without decoding. However, if the texture 139 * is also [statically] accessed with a texelFetch function, then 140 * the result of texture builtin functions and/or texture gather 141 * functions may be returned with decoding or without decoding." 142 * 143 * Note: the "statically" will be added to the language per 144 * https://cvs.khronos.org/bugzilla/show_bug.cgi?id=14934 145 * 146 * So we simply ignore the setting entirely for samplers that are 147 * (statically) accessed with a texelFetch function. 148 */ 149 sampler_views[unit] = 150 st_update_single_texture(st, prog->SamplerUnits[unit], glsl130, 151 texel_fetch_samplers & bit, true); 152 } 153 154 /* For any external samplers with multiplaner YUV, stuff the additional 155 * sampler views we need at the end. 156 * 157 * Trying to cache the sampler view in the stObj looks painful, so just 158 * re-create the sampler view for the extra planes each time. Main use 159 * case is video playback (ie. fps games wouldn't be using this) so I 160 * guess no point to try to optimize this feature. 161 */ 162 while (unlikely(external_samplers_used)) { 163 GLuint unit = u_bit_scan(&external_samplers_used); 164 GLuint extra = 0; 165 struct st_texture_object *stObj = 166 st_get_texture_object(st->ctx, prog, unit); 167 struct pipe_sampler_view tmpl; 168 169 if (!stObj) 170 continue; 171 172 /* use original view as template: */ 173 tmpl = *sampler_views[unit]; 174 175 /* if resource format matches then YUV wasn't lowered */ 176 if (st_get_view_format(stObj) == stObj->pt->format) 177 continue; 178 179 switch (st_get_view_format(stObj)) { 180 case PIPE_FORMAT_NV12: 181 if (stObj->pt->format == PIPE_FORMAT_R8_G8B8_420_UNORM) 182 /* no additional views needed */ 183 break; 184 185 /* we need one additional R8G8 view: */ 186 tmpl.format = PIPE_FORMAT_RG88_UNORM; 187 tmpl.swizzle_g = PIPE_SWIZZLE_Y; /* tmpl from Y plane is R8 */ 188 extra = u_bit_scan(&free_slots); 189 sampler_views[extra] = 190 pipe->create_sampler_view(pipe, stObj->pt->next, &tmpl); 191 break; 192 case PIPE_FORMAT_P010: 193 case PIPE_FORMAT_P012: 194 case PIPE_FORMAT_P016: 195 /* we need one additional R16G16 view: */ 196 tmpl.format = PIPE_FORMAT_RG1616_UNORM; 197 tmpl.swizzle_g = PIPE_SWIZZLE_Y; /* tmpl from Y plane is R16 */ 198 extra = u_bit_scan(&free_slots); 199 sampler_views[extra] = 200 pipe->create_sampler_view(pipe, stObj->pt->next, &tmpl); 201 break; 202 case PIPE_FORMAT_IYUV: 203 /* we need two additional R8 views: */ 204 tmpl.format = PIPE_FORMAT_R8_UNORM; 205 extra = u_bit_scan(&free_slots); 206 sampler_views[extra] = 207 pipe->create_sampler_view(pipe, stObj->pt->next, &tmpl); 208 extra = u_bit_scan(&free_slots); 209 sampler_views[extra] = 210 pipe->create_sampler_view(pipe, stObj->pt->next->next, &tmpl); 211 break; 212 case PIPE_FORMAT_YUYV: 213 if (stObj->pt->format == PIPE_FORMAT_R8G8_R8B8_UNORM) 214 /* no additional views needed */ 215 break; 216 217 /* we need one additional BGRA8888 view: */ 218 tmpl.format = PIPE_FORMAT_BGRA8888_UNORM; 219 tmpl.swizzle_b = PIPE_SWIZZLE_Z; 220 tmpl.swizzle_a = PIPE_SWIZZLE_W; 221 extra = u_bit_scan(&free_slots); 222 sampler_views[extra] = 223 pipe->create_sampler_view(pipe, stObj->pt->next, &tmpl); 224 break; 225 case PIPE_FORMAT_UYVY: 226 if (stObj->pt->format == PIPE_FORMAT_G8R8_B8R8_UNORM) 227 /* no additional views needed */ 228 break; 229 230 /* we need one additional RGBA8888 view: */ 231 tmpl.format = PIPE_FORMAT_RGBA8888_UNORM; 232 tmpl.swizzle_b = PIPE_SWIZZLE_Z; 233 tmpl.swizzle_a = PIPE_SWIZZLE_W; 234 extra = u_bit_scan(&free_slots); 235 sampler_views[extra] = 236 pipe->create_sampler_view(pipe, stObj->pt->next, &tmpl); 237 break; 238 case PIPE_FORMAT_Y210: 239 case PIPE_FORMAT_Y212: 240 case PIPE_FORMAT_Y216: 241 /* we need one additional R16G16B16A16 view: */ 242 tmpl.format = PIPE_FORMAT_R16G16B16A16_UNORM; 243 tmpl.swizzle_b = PIPE_SWIZZLE_Z; 244 tmpl.swizzle_a = PIPE_SWIZZLE_W; 245 extra = u_bit_scan(&free_slots); 246 sampler_views[extra] = 247 pipe->create_sampler_view(pipe, stObj->pt->next, &tmpl); 248 break; 249 default: 250 break; 251 } 252 253 num_textures = MAX2(num_textures, extra + 1); 254 } 255 256 return num_textures; 257} 258 259static void 260update_textures(struct st_context *st, 261 enum pipe_shader_type shader_stage, 262 const struct gl_program *prog) 263{ 264 struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS]; 265 struct pipe_context *pipe = st->pipe; 266 unsigned num_textures = 267 st_get_sampler_views(st, shader_stage, prog, sampler_views); 268 269 unsigned old_num_textures = st->state.num_sampler_views[shader_stage]; 270 unsigned num_unbind = old_num_textures > num_textures ? 271 old_num_textures - num_textures : 0; 272 273 pipe->set_sampler_views(pipe, shader_stage, 0, num_textures, num_unbind, 274 true, sampler_views); 275 st->state.num_sampler_views[shader_stage] = num_textures; 276} 277 278void 279st_update_vertex_textures(struct st_context *st) 280{ 281 const struct gl_context *ctx = st->ctx; 282 283 if (ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits > 0) { 284 update_textures(st, PIPE_SHADER_VERTEX, 285 ctx->VertexProgram._Current); 286 } 287} 288 289 290void 291st_update_fragment_textures(struct st_context *st) 292{ 293 const struct gl_context *ctx = st->ctx; 294 295 update_textures(st, PIPE_SHADER_FRAGMENT, 296 ctx->FragmentProgram._Current); 297} 298 299 300void 301st_update_geometry_textures(struct st_context *st) 302{ 303 const struct gl_context *ctx = st->ctx; 304 305 if (ctx->GeometryProgram._Current) { 306 update_textures(st, PIPE_SHADER_GEOMETRY, 307 ctx->GeometryProgram._Current); 308 } 309} 310 311 312void 313st_update_tessctrl_textures(struct st_context *st) 314{ 315 const struct gl_context *ctx = st->ctx; 316 317 if (ctx->TessCtrlProgram._Current) { 318 update_textures(st, PIPE_SHADER_TESS_CTRL, 319 ctx->TessCtrlProgram._Current); 320 } 321} 322 323 324void 325st_update_tesseval_textures(struct st_context *st) 326{ 327 const struct gl_context *ctx = st->ctx; 328 329 if (ctx->TessEvalProgram._Current) { 330 update_textures(st, PIPE_SHADER_TESS_EVAL, 331 ctx->TessEvalProgram._Current); 332 } 333} 334 335 336void 337st_update_compute_textures(struct st_context *st) 338{ 339 const struct gl_context *ctx = st->ctx; 340 341 if (ctx->ComputeProgram._Current) { 342 update_textures(st, PIPE_SHADER_COMPUTE, 343 ctx->ComputeProgram._Current); 344 } 345} 346