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