1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright 2016 VMware, Inc. 3bf215546Sopenharmony_ci * All Rights Reserved. 4bf215546Sopenharmony_ci * 5bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 6bf215546Sopenharmony_ci * copy of this software and associated documentation files (the 7bf215546Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 8bf215546Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 9bf215546Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to 10bf215546Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 11bf215546Sopenharmony_ci * the following conditions: 12bf215546Sopenharmony_ci * 13bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the 14bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions 15bf215546Sopenharmony_ci * of the Software. 16bf215546Sopenharmony_ci * 17bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 20bf215546Sopenharmony_ci * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 21bf215546Sopenharmony_ci * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22bf215546Sopenharmony_ci * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23bf215546Sopenharmony_ci * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24bf215546Sopenharmony_ci */ 25bf215546Sopenharmony_ci 26bf215546Sopenharmony_ci#include "pipe/p_context.h" 27bf215546Sopenharmony_ci#include "util/format/u_format.h" 28bf215546Sopenharmony_ci#include "util/u_inlines.h" 29bf215546Sopenharmony_ci 30bf215546Sopenharmony_ci#include "main/context.h" 31bf215546Sopenharmony_ci#include "main/macros.h" 32bf215546Sopenharmony_ci#include "main/mtypes.h" 33bf215546Sopenharmony_ci#include "main/teximage.h" 34bf215546Sopenharmony_ci#include "main/texobj.h" 35bf215546Sopenharmony_ci#include "program/prog_instruction.h" 36bf215546Sopenharmony_ci 37bf215546Sopenharmony_ci#include "st_context.h" 38bf215546Sopenharmony_ci#include "st_sampler_view.h" 39bf215546Sopenharmony_ci#include "st_texture.h" 40bf215546Sopenharmony_ci#include "st_format.h" 41bf215546Sopenharmony_ci#include "st_cb_texture.h" 42bf215546Sopenharmony_ci 43bf215546Sopenharmony_ci/* Subtract remaining private references. Typically used before 44bf215546Sopenharmony_ci * destruction. See the header file for explanation. 45bf215546Sopenharmony_ci */ 46bf215546Sopenharmony_cistatic void 47bf215546Sopenharmony_cist_remove_private_references(struct st_sampler_view *sv) 48bf215546Sopenharmony_ci{ 49bf215546Sopenharmony_ci if (sv->private_refcount) { 50bf215546Sopenharmony_ci assert(sv->private_refcount > 0); 51bf215546Sopenharmony_ci p_atomic_add(&sv->view->reference.count, -sv->private_refcount); 52bf215546Sopenharmony_ci sv->private_refcount = 0; 53bf215546Sopenharmony_ci } 54bf215546Sopenharmony_ci} 55bf215546Sopenharmony_ci 56bf215546Sopenharmony_ci/* Return a sampler view while incrementing the refcount by 1. */ 57bf215546Sopenharmony_cistatic struct pipe_sampler_view * 58bf215546Sopenharmony_ciget_sampler_view_reference(struct st_sampler_view *sv, 59bf215546Sopenharmony_ci struct pipe_sampler_view *view) 60bf215546Sopenharmony_ci{ 61bf215546Sopenharmony_ci if (unlikely(sv->private_refcount <= 0)) { 62bf215546Sopenharmony_ci assert(sv->private_refcount == 0); 63bf215546Sopenharmony_ci 64bf215546Sopenharmony_ci /* This is the number of atomic increments we will skip. */ 65bf215546Sopenharmony_ci sv->private_refcount = 100000000; 66bf215546Sopenharmony_ci p_atomic_add(&view->reference.count, sv->private_refcount); 67bf215546Sopenharmony_ci } 68bf215546Sopenharmony_ci 69bf215546Sopenharmony_ci /* Return a reference while decrementing the private refcount. */ 70bf215546Sopenharmony_ci sv->private_refcount--; 71bf215546Sopenharmony_ci return view; 72bf215546Sopenharmony_ci} 73bf215546Sopenharmony_ci 74bf215546Sopenharmony_ci/** 75bf215546Sopenharmony_ci * Set the given view as the current context's view for the texture. 76bf215546Sopenharmony_ci * 77bf215546Sopenharmony_ci * Overwrites any pre-existing view of the context. 78bf215546Sopenharmony_ci * 79bf215546Sopenharmony_ci * Takes ownership of the view (i.e., stores the view without incrementing the 80bf215546Sopenharmony_ci * reference count). 81bf215546Sopenharmony_ci * 82bf215546Sopenharmony_ci * \return the view, or NULL on error. In case of error, the reference to the 83bf215546Sopenharmony_ci * view is released. 84bf215546Sopenharmony_ci */ 85bf215546Sopenharmony_cistatic struct pipe_sampler_view * 86bf215546Sopenharmony_cist_texture_set_sampler_view(struct st_context *st, 87bf215546Sopenharmony_ci struct gl_texture_object *stObj, 88bf215546Sopenharmony_ci struct pipe_sampler_view *view, 89bf215546Sopenharmony_ci bool glsl130_or_later, bool srgb_skip_decode, 90bf215546Sopenharmony_ci bool get_reference, bool locked) 91bf215546Sopenharmony_ci{ 92bf215546Sopenharmony_ci struct st_sampler_views *views; 93bf215546Sopenharmony_ci struct st_sampler_view *free = NULL; 94bf215546Sopenharmony_ci struct st_sampler_view *sv; 95bf215546Sopenharmony_ci GLuint i; 96bf215546Sopenharmony_ci 97bf215546Sopenharmony_ci if (!locked) 98bf215546Sopenharmony_ci simple_mtx_lock(&stObj->validate_mutex); 99bf215546Sopenharmony_ci views = stObj->sampler_views; 100bf215546Sopenharmony_ci 101bf215546Sopenharmony_ci for (i = 0; i < views->count; ++i) { 102bf215546Sopenharmony_ci sv = &views->views[i]; 103bf215546Sopenharmony_ci 104bf215546Sopenharmony_ci /* Is the array entry used ? */ 105bf215546Sopenharmony_ci if (sv->view) { 106bf215546Sopenharmony_ci /* check if the context matches */ 107bf215546Sopenharmony_ci if (sv->view->context == st->pipe) { 108bf215546Sopenharmony_ci st_remove_private_references(sv); 109bf215546Sopenharmony_ci pipe_sampler_view_reference(&sv->view, NULL); 110bf215546Sopenharmony_ci goto found; 111bf215546Sopenharmony_ci } 112bf215546Sopenharmony_ci } else { 113bf215546Sopenharmony_ci /* Found a free slot, remember that */ 114bf215546Sopenharmony_ci free = sv; 115bf215546Sopenharmony_ci } 116bf215546Sopenharmony_ci } 117bf215546Sopenharmony_ci 118bf215546Sopenharmony_ci /* Couldn't find a slot for our context, create a new one */ 119bf215546Sopenharmony_ci if (free) { 120bf215546Sopenharmony_ci sv = free; 121bf215546Sopenharmony_ci } else { 122bf215546Sopenharmony_ci if (views->count >= views->max) { 123bf215546Sopenharmony_ci /* Allocate a larger container. */ 124bf215546Sopenharmony_ci unsigned new_max = 2 * views->max; 125bf215546Sopenharmony_ci unsigned new_size = sizeof(*views) + new_max * sizeof(views->views[0]); 126bf215546Sopenharmony_ci 127bf215546Sopenharmony_ci if (new_max < views->max || 128bf215546Sopenharmony_ci new_max > (UINT_MAX - sizeof(*views)) / sizeof(views->views[0])) { 129bf215546Sopenharmony_ci pipe_sampler_view_reference(&view, NULL); 130bf215546Sopenharmony_ci goto out; 131bf215546Sopenharmony_ci } 132bf215546Sopenharmony_ci 133bf215546Sopenharmony_ci struct st_sampler_views *new_views = malloc(new_size); 134bf215546Sopenharmony_ci if (!new_views) { 135bf215546Sopenharmony_ci pipe_sampler_view_reference(&view, NULL); 136bf215546Sopenharmony_ci goto out; 137bf215546Sopenharmony_ci } 138bf215546Sopenharmony_ci 139bf215546Sopenharmony_ci new_views->count = views->count; 140bf215546Sopenharmony_ci new_views->max = new_max; 141bf215546Sopenharmony_ci memcpy(&new_views->views[0], &views->views[0], 142bf215546Sopenharmony_ci views->count * sizeof(views->views[0])); 143bf215546Sopenharmony_ci 144bf215546Sopenharmony_ci /* Initialize the pipe_sampler_view pointers to zero so that we don't 145bf215546Sopenharmony_ci * have to worry about racing against readers when incrementing 146bf215546Sopenharmony_ci * views->count. 147bf215546Sopenharmony_ci */ 148bf215546Sopenharmony_ci memset(&new_views->views[views->count], 0, 149bf215546Sopenharmony_ci (new_max - views->count) * sizeof(views->views[0])); 150bf215546Sopenharmony_ci 151bf215546Sopenharmony_ci /* Use memory release semantics to ensure that concurrent readers will 152bf215546Sopenharmony_ci * get the correct contents of the new container. 153bf215546Sopenharmony_ci * 154bf215546Sopenharmony_ci * Also, the write should be atomic, but that's guaranteed anyway on 155bf215546Sopenharmony_ci * all supported platforms. 156bf215546Sopenharmony_ci */ 157bf215546Sopenharmony_ci p_atomic_set(&stObj->sampler_views, new_views); 158bf215546Sopenharmony_ci 159bf215546Sopenharmony_ci /* We keep the old container around until the texture object is 160bf215546Sopenharmony_ci * deleted, because another thread may still be reading from it. We 161bf215546Sopenharmony_ci * double the size of the container each time, so we end up with 162bf215546Sopenharmony_ci * at most twice the total memory allocation. 163bf215546Sopenharmony_ci */ 164bf215546Sopenharmony_ci views->next = stObj->sampler_views_old; 165bf215546Sopenharmony_ci stObj->sampler_views_old = views; 166bf215546Sopenharmony_ci 167bf215546Sopenharmony_ci views = new_views; 168bf215546Sopenharmony_ci } 169bf215546Sopenharmony_ci 170bf215546Sopenharmony_ci sv = &views->views[views->count]; 171bf215546Sopenharmony_ci 172bf215546Sopenharmony_ci /* Since modification is guarded by the lock, only the write part of the 173bf215546Sopenharmony_ci * increment has to be atomic, and that's already guaranteed on all 174bf215546Sopenharmony_ci * supported platforms without using an atomic intrinsic. 175bf215546Sopenharmony_ci */ 176bf215546Sopenharmony_ci views->count++; 177bf215546Sopenharmony_ci } 178bf215546Sopenharmony_ci 179bf215546Sopenharmony_cifound: 180bf215546Sopenharmony_ci assert(sv->view == NULL); 181bf215546Sopenharmony_ci 182bf215546Sopenharmony_ci sv->glsl130_or_later = glsl130_or_later; 183bf215546Sopenharmony_ci sv->srgb_skip_decode = srgb_skip_decode; 184bf215546Sopenharmony_ci sv->view = view; 185bf215546Sopenharmony_ci sv->st = st; 186bf215546Sopenharmony_ci 187bf215546Sopenharmony_ci if (get_reference) 188bf215546Sopenharmony_ci view = get_sampler_view_reference(sv, view); 189bf215546Sopenharmony_ci 190bf215546Sopenharmony_ciout: 191bf215546Sopenharmony_ci if (!locked) 192bf215546Sopenharmony_ci simple_mtx_unlock(&stObj->validate_mutex); 193bf215546Sopenharmony_ci return view; 194bf215546Sopenharmony_ci} 195bf215546Sopenharmony_ci 196bf215546Sopenharmony_ci 197bf215546Sopenharmony_ci/** 198bf215546Sopenharmony_ci * Return the most-recently validated sampler view for the texture \p stObj 199bf215546Sopenharmony_ci * in the given context, if any. 200bf215546Sopenharmony_ci * 201bf215546Sopenharmony_ci * Performs no additional validation. 202bf215546Sopenharmony_ci */ 203bf215546Sopenharmony_cistruct st_sampler_view * 204bf215546Sopenharmony_cist_texture_get_current_sampler_view(const struct st_context *st, 205bf215546Sopenharmony_ci const struct gl_texture_object *stObj) 206bf215546Sopenharmony_ci{ 207bf215546Sopenharmony_ci struct st_sampler_views *views = p_atomic_read(&stObj->sampler_views); 208bf215546Sopenharmony_ci 209bf215546Sopenharmony_ci for (unsigned i = 0; i < views->count; ++i) { 210bf215546Sopenharmony_ci struct st_sampler_view *sv = &views->views[i]; 211bf215546Sopenharmony_ci if (sv->view && sv->view->context == st->pipe) 212bf215546Sopenharmony_ci return sv; 213bf215546Sopenharmony_ci } 214bf215546Sopenharmony_ci 215bf215546Sopenharmony_ci return NULL; 216bf215546Sopenharmony_ci} 217bf215546Sopenharmony_ci 218bf215546Sopenharmony_ci 219bf215546Sopenharmony_ci/** 220bf215546Sopenharmony_ci * For the given texture object, release any sampler views which belong 221bf215546Sopenharmony_ci * to the calling context. This is used to free any sampler views 222bf215546Sopenharmony_ci * which belong to the context before the context is destroyed. 223bf215546Sopenharmony_ci */ 224bf215546Sopenharmony_civoid 225bf215546Sopenharmony_cist_texture_release_context_sampler_view(struct st_context *st, 226bf215546Sopenharmony_ci struct gl_texture_object *stObj) 227bf215546Sopenharmony_ci{ 228bf215546Sopenharmony_ci GLuint i; 229bf215546Sopenharmony_ci 230bf215546Sopenharmony_ci simple_mtx_lock(&stObj->validate_mutex); 231bf215546Sopenharmony_ci struct st_sampler_views *views = stObj->sampler_views; 232bf215546Sopenharmony_ci for (i = 0; i < views->count; ++i) { 233bf215546Sopenharmony_ci struct st_sampler_view *sv = &views->views[i]; 234bf215546Sopenharmony_ci 235bf215546Sopenharmony_ci if (sv->view && sv->view->context == st->pipe) { 236bf215546Sopenharmony_ci st_remove_private_references(sv); 237bf215546Sopenharmony_ci pipe_sampler_view_reference(&sv->view, NULL); 238bf215546Sopenharmony_ci break; 239bf215546Sopenharmony_ci } 240bf215546Sopenharmony_ci } 241bf215546Sopenharmony_ci simple_mtx_unlock(&stObj->validate_mutex); 242bf215546Sopenharmony_ci} 243bf215546Sopenharmony_ci 244bf215546Sopenharmony_ci 245bf215546Sopenharmony_ci/** 246bf215546Sopenharmony_ci * Release all sampler views attached to the given texture object, regardless 247bf215546Sopenharmony_ci * of the context. This is called fairly frequently. For example, whenever 248bf215546Sopenharmony_ci * the texture's base level, max level or swizzle change. 249bf215546Sopenharmony_ci */ 250bf215546Sopenharmony_civoid 251bf215546Sopenharmony_cist_texture_release_all_sampler_views(struct st_context *st, 252bf215546Sopenharmony_ci struct gl_texture_object *stObj) 253bf215546Sopenharmony_ci{ 254bf215546Sopenharmony_ci /* TODO: This happens while a texture is deleted, because the Driver API 255bf215546Sopenharmony_ci * is asymmetric: the driver allocates the texture object memory, but 256bf215546Sopenharmony_ci * mesa/main frees it. 257bf215546Sopenharmony_ci */ 258bf215546Sopenharmony_ci if (!stObj->sampler_views) 259bf215546Sopenharmony_ci return; 260bf215546Sopenharmony_ci 261bf215546Sopenharmony_ci simple_mtx_lock(&stObj->validate_mutex); 262bf215546Sopenharmony_ci struct st_sampler_views *views = stObj->sampler_views; 263bf215546Sopenharmony_ci for (unsigned i = 0; i < views->count; ++i) { 264bf215546Sopenharmony_ci struct st_sampler_view *stsv = &views->views[i]; 265bf215546Sopenharmony_ci if (stsv->view) { 266bf215546Sopenharmony_ci st_remove_private_references(stsv); 267bf215546Sopenharmony_ci 268bf215546Sopenharmony_ci if (stsv->st && stsv->st != st) { 269bf215546Sopenharmony_ci /* Transfer this reference to the zombie list. It will 270bf215546Sopenharmony_ci * likely be freed when the zombie list is freed. 271bf215546Sopenharmony_ci */ 272bf215546Sopenharmony_ci st_save_zombie_sampler_view(stsv->st, stsv->view); 273bf215546Sopenharmony_ci stsv->view = NULL; 274bf215546Sopenharmony_ci } else { 275bf215546Sopenharmony_ci pipe_sampler_view_reference(&stsv->view, NULL); 276bf215546Sopenharmony_ci } 277bf215546Sopenharmony_ci } 278bf215546Sopenharmony_ci } 279bf215546Sopenharmony_ci views->count = 0; 280bf215546Sopenharmony_ci simple_mtx_unlock(&stObj->validate_mutex); 281bf215546Sopenharmony_ci} 282bf215546Sopenharmony_ci 283bf215546Sopenharmony_ci 284bf215546Sopenharmony_ci/* 285bf215546Sopenharmony_ci * Delete the texture's sampler views and st_sampler_views containers. 286bf215546Sopenharmony_ci * This is to be called just before a texture is deleted. 287bf215546Sopenharmony_ci */ 288bf215546Sopenharmony_civoid 289bf215546Sopenharmony_cist_delete_texture_sampler_views(struct st_context *st, 290bf215546Sopenharmony_ci struct gl_texture_object *stObj) 291bf215546Sopenharmony_ci{ 292bf215546Sopenharmony_ci st_texture_release_all_sampler_views(st, stObj); 293bf215546Sopenharmony_ci 294bf215546Sopenharmony_ci /* Free the container of the current per-context sampler views */ 295bf215546Sopenharmony_ci assert(stObj->sampler_views->count == 0); 296bf215546Sopenharmony_ci free(stObj->sampler_views); 297bf215546Sopenharmony_ci stObj->sampler_views = NULL; 298bf215546Sopenharmony_ci 299bf215546Sopenharmony_ci /* Free old sampler view containers */ 300bf215546Sopenharmony_ci while (stObj->sampler_views_old) { 301bf215546Sopenharmony_ci struct st_sampler_views *views = stObj->sampler_views_old; 302bf215546Sopenharmony_ci stObj->sampler_views_old = views->next; 303bf215546Sopenharmony_ci free(views); 304bf215546Sopenharmony_ci } 305bf215546Sopenharmony_ci} 306bf215546Sopenharmony_ci 307bf215546Sopenharmony_ci 308bf215546Sopenharmony_ci/** 309bf215546Sopenharmony_ci * Return swizzle1(swizzle2) 310bf215546Sopenharmony_ci */ 311bf215546Sopenharmony_cistatic unsigned 312bf215546Sopenharmony_ciswizzle_swizzle(unsigned swizzle1, unsigned swizzle2) 313bf215546Sopenharmony_ci{ 314bf215546Sopenharmony_ci unsigned i, swz[4]; 315bf215546Sopenharmony_ci 316bf215546Sopenharmony_ci if (swizzle1 == SWIZZLE_XYZW) { 317bf215546Sopenharmony_ci /* identity swizzle, no change to swizzle2 */ 318bf215546Sopenharmony_ci return swizzle2; 319bf215546Sopenharmony_ci } 320bf215546Sopenharmony_ci 321bf215546Sopenharmony_ci for (i = 0; i < 4; i++) { 322bf215546Sopenharmony_ci unsigned s = GET_SWZ(swizzle1, i); 323bf215546Sopenharmony_ci switch (s) { 324bf215546Sopenharmony_ci case SWIZZLE_X: 325bf215546Sopenharmony_ci case SWIZZLE_Y: 326bf215546Sopenharmony_ci case SWIZZLE_Z: 327bf215546Sopenharmony_ci case SWIZZLE_W: 328bf215546Sopenharmony_ci swz[i] = GET_SWZ(swizzle2, s); 329bf215546Sopenharmony_ci break; 330bf215546Sopenharmony_ci case SWIZZLE_ZERO: 331bf215546Sopenharmony_ci swz[i] = SWIZZLE_ZERO; 332bf215546Sopenharmony_ci break; 333bf215546Sopenharmony_ci case SWIZZLE_ONE: 334bf215546Sopenharmony_ci swz[i] = SWIZZLE_ONE; 335bf215546Sopenharmony_ci break; 336bf215546Sopenharmony_ci default: 337bf215546Sopenharmony_ci assert(!"Bad swizzle term"); 338bf215546Sopenharmony_ci swz[i] = SWIZZLE_X; 339bf215546Sopenharmony_ci } 340bf215546Sopenharmony_ci } 341bf215546Sopenharmony_ci 342bf215546Sopenharmony_ci return MAKE_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]); 343bf215546Sopenharmony_ci} 344bf215546Sopenharmony_ci 345bf215546Sopenharmony_ci 346bf215546Sopenharmony_ci/** 347bf215546Sopenharmony_ci * Given a user-specified texture base format, the actual gallium texture 348bf215546Sopenharmony_ci * format and the current GL_DEPTH_MODE, return a texture swizzle. 349bf215546Sopenharmony_ci * 350bf215546Sopenharmony_ci * Consider the case where the user requests a GL_RGB internal texture 351bf215546Sopenharmony_ci * format the driver actually uses an RGBA format. The A component should 352bf215546Sopenharmony_ci * be ignored and sampling from the texture should always return (r,g,b,1). 353bf215546Sopenharmony_ci * But if we rendered to the texture we might have written A values != 1. 354bf215546Sopenharmony_ci * By sampling the texture with a ".xyz1" swizzle we'll get the expected A=1. 355bf215546Sopenharmony_ci * This function computes the texture swizzle needed to get the expected 356bf215546Sopenharmony_ci * values. 357bf215546Sopenharmony_ci * 358bf215546Sopenharmony_ci * In the case of depth textures, the GL_DEPTH_MODE state determines the 359bf215546Sopenharmony_ci * texture swizzle. 360bf215546Sopenharmony_ci * 361bf215546Sopenharmony_ci * This result must be composed with the user-specified swizzle to get 362bf215546Sopenharmony_ci * the final swizzle. 363bf215546Sopenharmony_ci */ 364bf215546Sopenharmony_cistatic unsigned 365bf215546Sopenharmony_cicompute_texture_format_swizzle(GLenum baseFormat, GLenum depthMode, 366bf215546Sopenharmony_ci bool glsl130_or_later) 367bf215546Sopenharmony_ci{ 368bf215546Sopenharmony_ci switch (baseFormat) { 369bf215546Sopenharmony_ci case GL_RGBA: 370bf215546Sopenharmony_ci return SWIZZLE_XYZW; 371bf215546Sopenharmony_ci case GL_RGB: 372bf215546Sopenharmony_ci return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ONE); 373bf215546Sopenharmony_ci case GL_RG: 374bf215546Sopenharmony_ci return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_ZERO, SWIZZLE_ONE); 375bf215546Sopenharmony_ci case GL_RED: 376bf215546Sopenharmony_ci return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO, 377bf215546Sopenharmony_ci SWIZZLE_ZERO, SWIZZLE_ONE); 378bf215546Sopenharmony_ci case GL_ALPHA: 379bf215546Sopenharmony_ci return MAKE_SWIZZLE4(SWIZZLE_ZERO, SWIZZLE_ZERO, 380bf215546Sopenharmony_ci SWIZZLE_ZERO, SWIZZLE_W); 381bf215546Sopenharmony_ci case GL_LUMINANCE: 382bf215546Sopenharmony_ci return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_ONE); 383bf215546Sopenharmony_ci case GL_LUMINANCE_ALPHA: 384bf215546Sopenharmony_ci return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_W); 385bf215546Sopenharmony_ci case GL_INTENSITY: 386bf215546Sopenharmony_ci return SWIZZLE_XXXX; 387bf215546Sopenharmony_ci case GL_STENCIL_INDEX: 388bf215546Sopenharmony_ci case GL_DEPTH_STENCIL: 389bf215546Sopenharmony_ci case GL_DEPTH_COMPONENT: 390bf215546Sopenharmony_ci /* Now examine the depth mode */ 391bf215546Sopenharmony_ci switch (depthMode) { 392bf215546Sopenharmony_ci case GL_LUMINANCE: 393bf215546Sopenharmony_ci return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_ONE); 394bf215546Sopenharmony_ci case GL_INTENSITY: 395bf215546Sopenharmony_ci return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X); 396bf215546Sopenharmony_ci case GL_ALPHA: 397bf215546Sopenharmony_ci /* The texture(sampler*Shadow) functions from GLSL 1.30 ignore 398bf215546Sopenharmony_ci * the depth mode and return float, while older shadow* functions 399bf215546Sopenharmony_ci * and ARB_fp instructions return vec4 according to the depth mode. 400bf215546Sopenharmony_ci * 401bf215546Sopenharmony_ci * The problem with the GLSL 1.30 functions is that GL_ALPHA forces 402bf215546Sopenharmony_ci * them to return 0, breaking them completely. 403bf215546Sopenharmony_ci * 404bf215546Sopenharmony_ci * A proper fix would increase code complexity and that's not worth 405bf215546Sopenharmony_ci * it for a rarely used feature such as the GL_ALPHA depth mode 406bf215546Sopenharmony_ci * in GL3. Therefore, change GL_ALPHA to GL_INTENSITY for all 407bf215546Sopenharmony_ci * shaders that use GLSL 1.30 or later. 408bf215546Sopenharmony_ci * 409bf215546Sopenharmony_ci * BTW, it's required that sampler views are updated when 410bf215546Sopenharmony_ci * shaders change (check_sampler_swizzle takes care of that). 411bf215546Sopenharmony_ci */ 412bf215546Sopenharmony_ci if (glsl130_or_later) 413bf215546Sopenharmony_ci return SWIZZLE_XXXX; 414bf215546Sopenharmony_ci else 415bf215546Sopenharmony_ci return MAKE_SWIZZLE4(SWIZZLE_ZERO, SWIZZLE_ZERO, 416bf215546Sopenharmony_ci SWIZZLE_ZERO, SWIZZLE_X); 417bf215546Sopenharmony_ci case GL_RED: 418bf215546Sopenharmony_ci return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO, 419bf215546Sopenharmony_ci SWIZZLE_ZERO, SWIZZLE_ONE); 420bf215546Sopenharmony_ci default: 421bf215546Sopenharmony_ci assert(!"Unexpected depthMode"); 422bf215546Sopenharmony_ci return SWIZZLE_XYZW; 423bf215546Sopenharmony_ci } 424bf215546Sopenharmony_ci default: 425bf215546Sopenharmony_ci assert(!"Unexpected baseFormat"); 426bf215546Sopenharmony_ci return SWIZZLE_XYZW; 427bf215546Sopenharmony_ci } 428bf215546Sopenharmony_ci} 429bf215546Sopenharmony_ci 430bf215546Sopenharmony_ci 431bf215546Sopenharmony_cistatic unsigned 432bf215546Sopenharmony_ciget_texture_format_swizzle(const struct st_context *st, 433bf215546Sopenharmony_ci const struct gl_texture_object *texObj, 434bf215546Sopenharmony_ci bool glsl130_or_later) 435bf215546Sopenharmony_ci{ 436bf215546Sopenharmony_ci GLenum baseFormat = _mesa_base_tex_image(texObj)->_BaseFormat; 437bf215546Sopenharmony_ci unsigned tex_swizzle; 438bf215546Sopenharmony_ci GLenum depth_mode = texObj->Attrib.DepthMode; 439bf215546Sopenharmony_ci 440bf215546Sopenharmony_ci /* In ES 3.0, DEPTH_TEXTURE_MODE is expected to be GL_RED for textures 441bf215546Sopenharmony_ci * with depth component data specified with a sized internal format. 442bf215546Sopenharmony_ci */ 443bf215546Sopenharmony_ci if (_mesa_is_gles3(st->ctx) && 444bf215546Sopenharmony_ci (baseFormat == GL_DEPTH_COMPONENT || 445bf215546Sopenharmony_ci baseFormat == GL_DEPTH_STENCIL || 446bf215546Sopenharmony_ci baseFormat == GL_STENCIL_INDEX)) { 447bf215546Sopenharmony_ci const struct gl_texture_image *firstImage = 448bf215546Sopenharmony_ci _mesa_base_tex_image(texObj); 449bf215546Sopenharmony_ci if (firstImage->InternalFormat != GL_DEPTH_COMPONENT && 450bf215546Sopenharmony_ci firstImage->InternalFormat != GL_DEPTH_STENCIL && 451bf215546Sopenharmony_ci firstImage->InternalFormat != GL_STENCIL_INDEX) 452bf215546Sopenharmony_ci depth_mode = GL_RED; 453bf215546Sopenharmony_ci } 454bf215546Sopenharmony_ci tex_swizzle = compute_texture_format_swizzle(baseFormat, 455bf215546Sopenharmony_ci depth_mode, 456bf215546Sopenharmony_ci glsl130_or_later); 457bf215546Sopenharmony_ci 458bf215546Sopenharmony_ci /* Combine the texture format swizzle with user's swizzle */ 459bf215546Sopenharmony_ci return swizzle_swizzle(texObj->Attrib._Swizzle, tex_swizzle); 460bf215546Sopenharmony_ci} 461bf215546Sopenharmony_ci 462bf215546Sopenharmony_ci 463bf215546Sopenharmony_ci/** 464bf215546Sopenharmony_ci * Return TRUE if the texture's sampler view swizzle is not equal to 465bf215546Sopenharmony_ci * the texture's swizzle. 466bf215546Sopenharmony_ci * 467bf215546Sopenharmony_ci * \param texObj the st texture object, 468bf215546Sopenharmony_ci */ 469bf215546Sopenharmony_ciASSERTED static boolean 470bf215546Sopenharmony_cicheck_sampler_swizzle(const struct st_context *st, 471bf215546Sopenharmony_ci const struct gl_texture_object *texObj, 472bf215546Sopenharmony_ci const struct pipe_sampler_view *sv, 473bf215546Sopenharmony_ci bool glsl130_or_later) 474bf215546Sopenharmony_ci{ 475bf215546Sopenharmony_ci unsigned swizzle = get_texture_format_swizzle(st, texObj, glsl130_or_later); 476bf215546Sopenharmony_ci 477bf215546Sopenharmony_ci return ((sv->swizzle_r != GET_SWZ(swizzle, 0)) || 478bf215546Sopenharmony_ci (sv->swizzle_g != GET_SWZ(swizzle, 1)) || 479bf215546Sopenharmony_ci (sv->swizzle_b != GET_SWZ(swizzle, 2)) || 480bf215546Sopenharmony_ci (sv->swizzle_a != GET_SWZ(swizzle, 3))); 481bf215546Sopenharmony_ci} 482bf215546Sopenharmony_ci 483bf215546Sopenharmony_ci 484bf215546Sopenharmony_cistatic unsigned 485bf215546Sopenharmony_cilast_level(const struct gl_texture_object *texObj) 486bf215546Sopenharmony_ci{ 487bf215546Sopenharmony_ci unsigned ret = MIN2(texObj->Attrib.MinLevel + texObj->_MaxLevel, 488bf215546Sopenharmony_ci texObj->pt->last_level); 489bf215546Sopenharmony_ci if (texObj->Immutable) 490bf215546Sopenharmony_ci ret = MIN2(ret, texObj->Attrib.MinLevel + 491bf215546Sopenharmony_ci texObj->Attrib.NumLevels - 1); 492bf215546Sopenharmony_ci return ret; 493bf215546Sopenharmony_ci} 494bf215546Sopenharmony_ci 495bf215546Sopenharmony_ci 496bf215546Sopenharmony_cistatic unsigned 497bf215546Sopenharmony_cilast_layer(const struct gl_texture_object *texObj) 498bf215546Sopenharmony_ci{ 499bf215546Sopenharmony_ci if (texObj->Immutable && texObj->pt->array_size > 1) 500bf215546Sopenharmony_ci return MIN2(texObj->Attrib.MinLayer + 501bf215546Sopenharmony_ci texObj->Attrib.NumLayers - 1, 502bf215546Sopenharmony_ci texObj->pt->array_size - 1); 503bf215546Sopenharmony_ci return texObj->pt->array_size - 1; 504bf215546Sopenharmony_ci} 505bf215546Sopenharmony_ci 506bf215546Sopenharmony_ci 507bf215546Sopenharmony_ci/** 508bf215546Sopenharmony_ci * Determine the format for the texture sampler view. 509bf215546Sopenharmony_ci */ 510bf215546Sopenharmony_cienum pipe_format 511bf215546Sopenharmony_cist_get_sampler_view_format(const struct st_context *st, 512bf215546Sopenharmony_ci const struct gl_texture_object *texObj, 513bf215546Sopenharmony_ci bool srgb_skip_decode) 514bf215546Sopenharmony_ci{ 515bf215546Sopenharmony_ci enum pipe_format format; 516bf215546Sopenharmony_ci 517bf215546Sopenharmony_ci GLenum baseFormat = _mesa_base_tex_image(texObj)->_BaseFormat; 518bf215546Sopenharmony_ci format = texObj->surface_based ? texObj->surface_format : texObj->pt->format; 519bf215546Sopenharmony_ci 520bf215546Sopenharmony_ci if (baseFormat == GL_DEPTH_COMPONENT || 521bf215546Sopenharmony_ci baseFormat == GL_DEPTH_STENCIL || 522bf215546Sopenharmony_ci baseFormat == GL_STENCIL_INDEX) { 523bf215546Sopenharmony_ci if (texObj->StencilSampling || baseFormat == GL_STENCIL_INDEX) 524bf215546Sopenharmony_ci format = util_format_stencil_only(format); 525bf215546Sopenharmony_ci 526bf215546Sopenharmony_ci return format; 527bf215546Sopenharmony_ci } 528bf215546Sopenharmony_ci 529bf215546Sopenharmony_ci /* If sRGB decoding is off, use the linear format */ 530bf215546Sopenharmony_ci if (srgb_skip_decode) 531bf215546Sopenharmony_ci format = util_format_linear(format); 532bf215546Sopenharmony_ci 533bf215546Sopenharmony_ci /* if resource format matches then YUV wasn't lowered */ 534bf215546Sopenharmony_ci if (format == texObj->pt->format) 535bf215546Sopenharmony_ci return format; 536bf215546Sopenharmony_ci 537bf215546Sopenharmony_ci /* Use R8_UNORM for video formats */ 538bf215546Sopenharmony_ci switch (format) { 539bf215546Sopenharmony_ci case PIPE_FORMAT_NV12: 540bf215546Sopenharmony_ci if (texObj->pt->format == PIPE_FORMAT_R8_G8B8_420_UNORM) { 541bf215546Sopenharmony_ci format = PIPE_FORMAT_R8_G8B8_420_UNORM; 542bf215546Sopenharmony_ci break; 543bf215546Sopenharmony_ci } 544bf215546Sopenharmony_ci FALLTHROUGH; 545bf215546Sopenharmony_ci case PIPE_FORMAT_IYUV: 546bf215546Sopenharmony_ci format = PIPE_FORMAT_R8_UNORM; 547bf215546Sopenharmony_ci break; 548bf215546Sopenharmony_ci case PIPE_FORMAT_P010: 549bf215546Sopenharmony_ci case PIPE_FORMAT_P012: 550bf215546Sopenharmony_ci case PIPE_FORMAT_P016: 551bf215546Sopenharmony_ci format = PIPE_FORMAT_R16_UNORM; 552bf215546Sopenharmony_ci break; 553bf215546Sopenharmony_ci case PIPE_FORMAT_Y210: 554bf215546Sopenharmony_ci case PIPE_FORMAT_Y212: 555bf215546Sopenharmony_ci case PIPE_FORMAT_Y216: 556bf215546Sopenharmony_ci format = PIPE_FORMAT_R16G16_UNORM; 557bf215546Sopenharmony_ci break; 558bf215546Sopenharmony_ci case PIPE_FORMAT_Y410: 559bf215546Sopenharmony_ci format = PIPE_FORMAT_R10G10B10A2_UNORM; 560bf215546Sopenharmony_ci break; 561bf215546Sopenharmony_ci case PIPE_FORMAT_Y412: 562bf215546Sopenharmony_ci case PIPE_FORMAT_Y416: 563bf215546Sopenharmony_ci format = PIPE_FORMAT_R16G16B16A16_UNORM; 564bf215546Sopenharmony_ci break; 565bf215546Sopenharmony_ci case PIPE_FORMAT_YUYV: 566bf215546Sopenharmony_ci case PIPE_FORMAT_UYVY: 567bf215546Sopenharmony_ci if (texObj->pt->format == PIPE_FORMAT_R8G8_R8B8_UNORM || 568bf215546Sopenharmony_ci texObj->pt->format == PIPE_FORMAT_G8R8_B8R8_UNORM) { 569bf215546Sopenharmony_ci format = texObj->pt->format; 570bf215546Sopenharmony_ci break; 571bf215546Sopenharmony_ci } 572bf215546Sopenharmony_ci format = PIPE_FORMAT_R8G8_UNORM; 573bf215546Sopenharmony_ci break; 574bf215546Sopenharmony_ci case PIPE_FORMAT_AYUV: 575bf215546Sopenharmony_ci format = PIPE_FORMAT_RGBA8888_UNORM; 576bf215546Sopenharmony_ci break; 577bf215546Sopenharmony_ci case PIPE_FORMAT_XYUV: 578bf215546Sopenharmony_ci format = PIPE_FORMAT_RGBX8888_UNORM; 579bf215546Sopenharmony_ci break; 580bf215546Sopenharmony_ci default: 581bf215546Sopenharmony_ci break; 582bf215546Sopenharmony_ci } 583bf215546Sopenharmony_ci return format; 584bf215546Sopenharmony_ci} 585bf215546Sopenharmony_ci 586bf215546Sopenharmony_ci 587bf215546Sopenharmony_cistatic struct pipe_sampler_view * 588bf215546Sopenharmony_cist_create_texture_sampler_view_from_stobj(struct st_context *st, 589bf215546Sopenharmony_ci struct gl_texture_object *texObj, 590bf215546Sopenharmony_ci enum pipe_format format, 591bf215546Sopenharmony_ci bool glsl130_or_later) 592bf215546Sopenharmony_ci{ 593bf215546Sopenharmony_ci /* There is no need to clear this structure (consider CPU overhead). */ 594bf215546Sopenharmony_ci struct pipe_sampler_view templ; 595bf215546Sopenharmony_ci unsigned swizzle = get_texture_format_swizzle(st, texObj, glsl130_or_later); 596bf215546Sopenharmony_ci 597bf215546Sopenharmony_ci templ.format = format; 598bf215546Sopenharmony_ci 599bf215546Sopenharmony_ci if (texObj->level_override >= 0) { 600bf215546Sopenharmony_ci templ.u.tex.first_level = templ.u.tex.last_level = texObj->level_override; 601bf215546Sopenharmony_ci } else { 602bf215546Sopenharmony_ci templ.u.tex.first_level = texObj->Attrib.MinLevel + 603bf215546Sopenharmony_ci texObj->Attrib.BaseLevel; 604bf215546Sopenharmony_ci templ.u.tex.last_level = last_level(texObj); 605bf215546Sopenharmony_ci } 606bf215546Sopenharmony_ci if (texObj->layer_override >= 0) { 607bf215546Sopenharmony_ci templ.u.tex.first_layer = templ.u.tex.last_layer = texObj->layer_override; 608bf215546Sopenharmony_ci } else { 609bf215546Sopenharmony_ci templ.u.tex.first_layer = texObj->Attrib.MinLayer; 610bf215546Sopenharmony_ci templ.u.tex.last_layer = last_layer(texObj); 611bf215546Sopenharmony_ci } 612bf215546Sopenharmony_ci assert(templ.u.tex.first_layer <= templ.u.tex.last_layer); 613bf215546Sopenharmony_ci assert(templ.u.tex.first_level <= templ.u.tex.last_level); 614bf215546Sopenharmony_ci templ.target = gl_target_to_pipe(texObj->Target); 615bf215546Sopenharmony_ci 616bf215546Sopenharmony_ci templ.swizzle_r = GET_SWZ(swizzle, 0); 617bf215546Sopenharmony_ci templ.swizzle_g = GET_SWZ(swizzle, 1); 618bf215546Sopenharmony_ci templ.swizzle_b = GET_SWZ(swizzle, 2); 619bf215546Sopenharmony_ci templ.swizzle_a = GET_SWZ(swizzle, 3); 620bf215546Sopenharmony_ci 621bf215546Sopenharmony_ci return st->pipe->create_sampler_view(st->pipe, texObj->pt, &templ); 622bf215546Sopenharmony_ci} 623bf215546Sopenharmony_ci 624bf215546Sopenharmony_cistruct pipe_sampler_view * 625bf215546Sopenharmony_cist_get_texture_sampler_view_from_stobj(struct st_context *st, 626bf215546Sopenharmony_ci struct gl_texture_object *texObj, 627bf215546Sopenharmony_ci const struct gl_sampler_object *samp, 628bf215546Sopenharmony_ci bool glsl130_or_later, 629bf215546Sopenharmony_ci bool ignore_srgb_decode, 630bf215546Sopenharmony_ci bool get_reference) 631bf215546Sopenharmony_ci{ 632bf215546Sopenharmony_ci struct st_sampler_view *sv; 633bf215546Sopenharmony_ci bool srgb_skip_decode = false; 634bf215546Sopenharmony_ci 635bf215546Sopenharmony_ci if (!ignore_srgb_decode && samp->Attrib.sRGBDecode == GL_SKIP_DECODE_EXT) 636bf215546Sopenharmony_ci srgb_skip_decode = true; 637bf215546Sopenharmony_ci 638bf215546Sopenharmony_ci simple_mtx_lock(&texObj->validate_mutex); 639bf215546Sopenharmony_ci sv = st_texture_get_current_sampler_view(st, texObj); 640bf215546Sopenharmony_ci 641bf215546Sopenharmony_ci if (sv && 642bf215546Sopenharmony_ci sv->glsl130_or_later == glsl130_or_later && 643bf215546Sopenharmony_ci sv->srgb_skip_decode == srgb_skip_decode) { 644bf215546Sopenharmony_ci /* Debug check: make sure that the sampler view's parameters are 645bf215546Sopenharmony_ci * what they're supposed to be. 646bf215546Sopenharmony_ci */ 647bf215546Sopenharmony_ci struct pipe_sampler_view *view = sv->view; 648bf215546Sopenharmony_ci assert(texObj->pt == view->texture); 649bf215546Sopenharmony_ci assert(!check_sampler_swizzle(st, texObj, view, glsl130_or_later)); 650bf215546Sopenharmony_ci assert(st_get_sampler_view_format(st, texObj, srgb_skip_decode) == view->format); 651bf215546Sopenharmony_ci assert(gl_target_to_pipe(texObj->Target) == view->target); 652bf215546Sopenharmony_ci assert(texObj->level_override >= 0 || 653bf215546Sopenharmony_ci texObj->Attrib.MinLevel + 654bf215546Sopenharmony_ci texObj->Attrib.BaseLevel == view->u.tex.first_level); 655bf215546Sopenharmony_ci assert(texObj->level_override >= 0 || last_level(texObj) == view->u.tex.last_level); 656bf215546Sopenharmony_ci assert(texObj->layer_override >= 0 || 657bf215546Sopenharmony_ci texObj->Attrib.MinLayer == view->u.tex.first_layer); 658bf215546Sopenharmony_ci assert(texObj->layer_override >= 0 || last_layer(texObj) == view->u.tex.last_layer); 659bf215546Sopenharmony_ci assert(texObj->layer_override < 0 || 660bf215546Sopenharmony_ci (texObj->layer_override == view->u.tex.first_layer && 661bf215546Sopenharmony_ci texObj->layer_override == view->u.tex.last_layer)); 662bf215546Sopenharmony_ci if (get_reference) 663bf215546Sopenharmony_ci view = get_sampler_view_reference(sv, view); 664bf215546Sopenharmony_ci simple_mtx_unlock(&texObj->validate_mutex); 665bf215546Sopenharmony_ci return view; 666bf215546Sopenharmony_ci } 667bf215546Sopenharmony_ci 668bf215546Sopenharmony_ci /* create new sampler view */ 669bf215546Sopenharmony_ci enum pipe_format format = st_get_sampler_view_format(st, texObj, 670bf215546Sopenharmony_ci srgb_skip_decode); 671bf215546Sopenharmony_ci struct pipe_sampler_view *view = 672bf215546Sopenharmony_ci st_create_texture_sampler_view_from_stobj(st, texObj, format, 673bf215546Sopenharmony_ci glsl130_or_later); 674bf215546Sopenharmony_ci 675bf215546Sopenharmony_ci view = st_texture_set_sampler_view(st, texObj, view, 676bf215546Sopenharmony_ci glsl130_or_later, srgb_skip_decode, 677bf215546Sopenharmony_ci get_reference, true); 678bf215546Sopenharmony_ci simple_mtx_unlock(&texObj->validate_mutex); 679bf215546Sopenharmony_ci 680bf215546Sopenharmony_ci return view; 681bf215546Sopenharmony_ci} 682bf215546Sopenharmony_ci 683bf215546Sopenharmony_ci 684bf215546Sopenharmony_cistruct pipe_sampler_view * 685bf215546Sopenharmony_cist_get_buffer_sampler_view_from_stobj(struct st_context *st, 686bf215546Sopenharmony_ci struct gl_texture_object *texObj, 687bf215546Sopenharmony_ci bool get_reference) 688bf215546Sopenharmony_ci{ 689bf215546Sopenharmony_ci struct st_sampler_view *sv; 690bf215546Sopenharmony_ci struct gl_buffer_object *stBuf = 691bf215546Sopenharmony_ci texObj->BufferObject; 692bf215546Sopenharmony_ci 693bf215546Sopenharmony_ci if (!stBuf || !stBuf->buffer) 694bf215546Sopenharmony_ci return NULL; 695bf215546Sopenharmony_ci 696bf215546Sopenharmony_ci sv = st_texture_get_current_sampler_view(st, texObj); 697bf215546Sopenharmony_ci 698bf215546Sopenharmony_ci struct pipe_resource *buf = stBuf->buffer; 699bf215546Sopenharmony_ci 700bf215546Sopenharmony_ci if (sv) { 701bf215546Sopenharmony_ci struct pipe_sampler_view *view = sv->view; 702bf215546Sopenharmony_ci 703bf215546Sopenharmony_ci if (view->texture == buf) { 704bf215546Sopenharmony_ci /* Debug check: make sure that the sampler view's parameters are 705bf215546Sopenharmony_ci * what they're supposed to be. 706bf215546Sopenharmony_ci */ 707bf215546Sopenharmony_ci assert(st_mesa_format_to_pipe_format(st, 708bf215546Sopenharmony_ci texObj->_BufferObjectFormat) 709bf215546Sopenharmony_ci == view->format); 710bf215546Sopenharmony_ci assert(view->target == PIPE_BUFFER); 711bf215546Sopenharmony_ci ASSERTED unsigned base = texObj->BufferOffset; 712bf215546Sopenharmony_ci ASSERTED unsigned size = MIN2(buf->width0 - base, 713bf215546Sopenharmony_ci (unsigned) texObj->BufferSize); 714bf215546Sopenharmony_ci assert(view->u.buf.offset == base); 715bf215546Sopenharmony_ci assert(view->u.buf.size == size); 716bf215546Sopenharmony_ci if (get_reference) 717bf215546Sopenharmony_ci view = get_sampler_view_reference(sv, view); 718bf215546Sopenharmony_ci return view; 719bf215546Sopenharmony_ci } 720bf215546Sopenharmony_ci } 721bf215546Sopenharmony_ci 722bf215546Sopenharmony_ci unsigned base = texObj->BufferOffset; 723bf215546Sopenharmony_ci 724bf215546Sopenharmony_ci if (base >= buf->width0) 725bf215546Sopenharmony_ci return NULL; 726bf215546Sopenharmony_ci 727bf215546Sopenharmony_ci unsigned size = buf->width0 - base; 728bf215546Sopenharmony_ci size = MIN2(size, (unsigned)texObj->BufferSize); 729bf215546Sopenharmony_ci if (!size) 730bf215546Sopenharmony_ci return NULL; 731bf215546Sopenharmony_ci 732bf215546Sopenharmony_ci /* Create a new sampler view. There is no need to clear the entire 733bf215546Sopenharmony_ci * structure (consider CPU overhead). 734bf215546Sopenharmony_ci */ 735bf215546Sopenharmony_ci struct pipe_sampler_view templ; 736bf215546Sopenharmony_ci 737bf215546Sopenharmony_ci templ.format = 738bf215546Sopenharmony_ci st_mesa_format_to_pipe_format(st, texObj->_BufferObjectFormat); 739bf215546Sopenharmony_ci templ.target = PIPE_BUFFER; 740bf215546Sopenharmony_ci templ.swizzle_r = PIPE_SWIZZLE_X; 741bf215546Sopenharmony_ci templ.swizzle_g = PIPE_SWIZZLE_Y; 742bf215546Sopenharmony_ci templ.swizzle_b = PIPE_SWIZZLE_Z; 743bf215546Sopenharmony_ci templ.swizzle_a = PIPE_SWIZZLE_W; 744bf215546Sopenharmony_ci templ.u.buf.offset = base; 745bf215546Sopenharmony_ci templ.u.buf.size = size; 746bf215546Sopenharmony_ci 747bf215546Sopenharmony_ci struct pipe_sampler_view *view = 748bf215546Sopenharmony_ci st->pipe->create_sampler_view(st->pipe, buf, &templ); 749bf215546Sopenharmony_ci 750bf215546Sopenharmony_ci view = st_texture_set_sampler_view(st, texObj, view, false, false, 751bf215546Sopenharmony_ci get_reference, false); 752bf215546Sopenharmony_ci 753bf215546Sopenharmony_ci return view; 754bf215546Sopenharmony_ci} 755