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 66 texObj = ctx->Texture.Unit[texUnit]._Current; 67 assert(texObj); 68 69 GLenum target = texObj->Target; 70 71 if (unlikely(target == GL_TEXTURE_BUFFER)) 72 return st_get_buffer_sampler_view_from_stobj(st, texObj, get_reference); 73 74 if (!st_finalize_texture(ctx, st->pipe, texObj, 0) || !texObj->pt) 75 return NULL; /* out of mem */ 76 77 if (target == GL_TEXTURE_EXTERNAL_OES && 78 texObj->pt->screen->resource_changed) 79 texObj->pt->screen->resource_changed(texObj->pt->screen, texObj->pt); 80 81 return st_get_texture_sampler_view_from_stobj(st, texObj, 82 _mesa_get_samplerobj(ctx, texUnit), 83 glsl130_or_later, 84 ignore_srgb_decode, get_reference); 85} 86 87 88 89unsigned 90st_get_sampler_views(struct st_context *st, 91 enum pipe_shader_type shader_stage, 92 const struct gl_program *prog, 93 struct pipe_sampler_view **sampler_views) 94{ 95 struct pipe_context *pipe = st->pipe; 96 const GLuint old_max = st->state.num_sampler_views[shader_stage]; 97 GLbitfield samplers_used = prog->SamplersUsed; 98 GLbitfield texel_fetch_samplers = prog->info.textures_used_by_txf[0]; 99 GLbitfield free_slots = ~prog->SamplersUsed; 100 GLbitfield external_samplers_used = prog->ExternalSamplersUsed; 101 GLuint unit; 102 103 if (samplers_used == 0x0 && old_max == 0) 104 return 0; 105 106 unsigned num_textures = util_last_bit(samplers_used); 107 108 /* prog->sh.data is NULL if it's ARB_fragment_program */ 109 bool glsl130 = (prog->sh.data ? prog->sh.data->Version : 0) >= 130; 110 111 /* loop over sampler units (aka tex image units) */ 112 for (unit = 0; unit < num_textures; unit++) { 113 unsigned bit = BITFIELD_BIT(unit); 114 115 if (!(samplers_used & bit)) { 116 sampler_views[unit] = NULL; 117 continue; 118 } 119 120 /* The EXT_texture_sRGB_decode extension says: 121 * 122 * "The conversion of sRGB color space components to linear color 123 * space is always performed if the texel lookup function is one 124 * of the texelFetch builtin functions. 125 * 126 * Otherwise, if the texel lookup function is one of the texture 127 * builtin functions or one of the texture gather functions, the 128 * conversion of sRGB color space components to linear color space 129 * is controlled by the TEXTURE_SRGB_DECODE_EXT parameter. 130 * 131 * If the TEXTURE_SRGB_DECODE_EXT parameter is DECODE_EXT, the 132 * conversion of sRGB color space components to linear color space 133 * is performed. 134 * 135 * If the TEXTURE_SRGB_DECODE_EXT parameter is SKIP_DECODE_EXT, 136 * the value is returned without decoding. However, if the texture 137 * is also [statically] accessed with a texelFetch function, then 138 * the result of texture builtin functions and/or texture gather 139 * functions may be returned with decoding or without decoding." 140 * 141 * Note: the "statically" will be added to the language per 142 * https://cvs.khronos.org/bugzilla/show_bug.cgi?id=14934 143 * 144 * So we simply ignore the setting entirely for samplers that are 145 * (statically) accessed with a texelFetch function. 146 */ 147 sampler_views[unit] = 148 st_update_single_texture(st, prog->SamplerUnits[unit], glsl130, 149 texel_fetch_samplers & bit, true); 150 } 151 152 /* For any external samplers with multiplaner YUV, stuff the additional 153 * sampler views we need at the end. 154 * 155 * Trying to cache the sampler view in the texObj looks painful, so just 156 * re-create the sampler view for the extra planes each time. Main use 157 * case is video playback (ie. fps games wouldn't be using this) so I 158 * guess no point to try to optimize this feature. 159 */ 160 while (unlikely(external_samplers_used)) { 161 GLuint unit = u_bit_scan(&external_samplers_used); 162 GLuint extra = 0; 163 struct gl_texture_object *stObj = 164 st_get_texture_object(st->ctx, prog, unit); 165 struct pipe_sampler_view tmpl; 166 167 if (!stObj) 168 continue; 169 170 /* use original view as template: */ 171 tmpl = *sampler_views[unit]; 172 173 /* if resource format matches then YUV wasn't lowered */ 174 if (st_get_view_format(stObj) == stObj->pt->format) 175 continue; 176 177 switch (st_get_view_format(stObj)) { 178 case PIPE_FORMAT_NV12: 179 if (stObj->pt->format == PIPE_FORMAT_R8_G8B8_420_UNORM) 180 /* no additional views needed */ 181 break; 182 183 /* we need one additional R8G8 view: */ 184 tmpl.format = PIPE_FORMAT_RG88_UNORM; 185 tmpl.swizzle_g = PIPE_SWIZZLE_Y; /* tmpl from Y plane is R8 */ 186 extra = u_bit_scan(&free_slots); 187 sampler_views[extra] = 188 pipe->create_sampler_view(pipe, stObj->pt->next, &tmpl); 189 break; 190 case PIPE_FORMAT_P010: 191 case PIPE_FORMAT_P012: 192 case PIPE_FORMAT_P016: 193 /* we need one additional R16G16 view: */ 194 tmpl.format = PIPE_FORMAT_RG1616_UNORM; 195 tmpl.swizzle_g = PIPE_SWIZZLE_Y; /* tmpl from Y plane is R16 */ 196 extra = u_bit_scan(&free_slots); 197 sampler_views[extra] = 198 pipe->create_sampler_view(pipe, stObj->pt->next, &tmpl); 199 break; 200 case PIPE_FORMAT_IYUV: 201 /* we need two additional R8 views: */ 202 tmpl.format = PIPE_FORMAT_R8_UNORM; 203 extra = u_bit_scan(&free_slots); 204 sampler_views[extra] = 205 pipe->create_sampler_view(pipe, stObj->pt->next, &tmpl); 206 extra = u_bit_scan(&free_slots); 207 sampler_views[extra] = 208 pipe->create_sampler_view(pipe, stObj->pt->next->next, &tmpl); 209 break; 210 case PIPE_FORMAT_YUYV: 211 if (stObj->pt->format == PIPE_FORMAT_R8G8_R8B8_UNORM) 212 /* no additional views needed */ 213 break; 214 215 /* we need one additional BGRA8888 view: */ 216 tmpl.format = PIPE_FORMAT_BGRA8888_UNORM; 217 tmpl.swizzle_b = PIPE_SWIZZLE_Z; 218 tmpl.swizzle_a = PIPE_SWIZZLE_W; 219 extra = u_bit_scan(&free_slots); 220 sampler_views[extra] = 221 pipe->create_sampler_view(pipe, stObj->pt->next, &tmpl); 222 break; 223 case PIPE_FORMAT_UYVY: 224 if (stObj->pt->format == PIPE_FORMAT_G8R8_B8R8_UNORM) 225 /* no additional views needed */ 226 break; 227 228 /* we need one additional RGBA8888 view: */ 229 tmpl.format = PIPE_FORMAT_RGBA8888_UNORM; 230 tmpl.swizzle_b = PIPE_SWIZZLE_Z; 231 tmpl.swizzle_a = PIPE_SWIZZLE_W; 232 extra = u_bit_scan(&free_slots); 233 sampler_views[extra] = 234 pipe->create_sampler_view(pipe, stObj->pt->next, &tmpl); 235 break; 236 case PIPE_FORMAT_Y210: 237 case PIPE_FORMAT_Y212: 238 case PIPE_FORMAT_Y216: 239 /* we need one additional R16G16B16A16 view: */ 240 tmpl.format = PIPE_FORMAT_R16G16B16A16_UNORM; 241 tmpl.swizzle_b = PIPE_SWIZZLE_Z; 242 tmpl.swizzle_a = PIPE_SWIZZLE_W; 243 extra = u_bit_scan(&free_slots); 244 sampler_views[extra] = 245 pipe->create_sampler_view(pipe, stObj->pt->next, &tmpl); 246 break; 247 default: 248 break; 249 } 250 251 num_textures = MAX2(num_textures, extra + 1); 252 } 253 254 return num_textures; 255} 256 257static void 258update_textures(struct st_context *st, 259 enum pipe_shader_type shader_stage, 260 const struct gl_program *prog) 261{ 262 struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS]; 263 struct pipe_context *pipe = st->pipe; 264 unsigned num_textures = 265 st_get_sampler_views(st, shader_stage, prog, sampler_views); 266 267 unsigned old_num_textures = st->state.num_sampler_views[shader_stage]; 268 unsigned num_unbind = old_num_textures > num_textures ? 269 old_num_textures - num_textures : 0; 270 271 pipe->set_sampler_views(pipe, shader_stage, 0, num_textures, num_unbind, 272 true, sampler_views); 273 st->state.num_sampler_views[shader_stage] = num_textures; 274} 275 276void 277st_update_vertex_textures(struct st_context *st) 278{ 279 const struct gl_context *ctx = st->ctx; 280 281 if (ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits > 0) { 282 update_textures(st, PIPE_SHADER_VERTEX, 283 ctx->VertexProgram._Current); 284 } 285} 286 287 288void 289st_update_fragment_textures(struct st_context *st) 290{ 291 const struct gl_context *ctx = st->ctx; 292 293 update_textures(st, PIPE_SHADER_FRAGMENT, 294 ctx->FragmentProgram._Current); 295} 296 297 298void 299st_update_geometry_textures(struct st_context *st) 300{ 301 const struct gl_context *ctx = st->ctx; 302 303 if (ctx->GeometryProgram._Current) { 304 update_textures(st, PIPE_SHADER_GEOMETRY, 305 ctx->GeometryProgram._Current); 306 } 307} 308 309 310void 311st_update_tessctrl_textures(struct st_context *st) 312{ 313 const struct gl_context *ctx = st->ctx; 314 315 if (ctx->TessCtrlProgram._Current) { 316 update_textures(st, PIPE_SHADER_TESS_CTRL, 317 ctx->TessCtrlProgram._Current); 318 } 319} 320 321 322void 323st_update_tesseval_textures(struct st_context *st) 324{ 325 const struct gl_context *ctx = st->ctx; 326 327 if (ctx->TessEvalProgram._Current) { 328 update_textures(st, PIPE_SHADER_TESS_EVAL, 329 ctx->TessEvalProgram._Current); 330 } 331} 332 333 334void 335st_update_compute_textures(struct st_context *st) 336{ 337 const struct gl_context *ctx = st->ctx; 338 339 if (ctx->ComputeProgram._Current) { 340 update_textures(st, PIPE_SHADER_COMPUTE, 341 ctx->ComputeProgram._Current); 342 } 343} 344