~ubuntu-branches/ubuntu/natty/mesa/natty-proposed

« back to all changes in this revision

Viewing changes to src/mesa/state_tracker/st_cb_fbo.c

  • Committer: Bazaar Package Importer
  • Author(s): Robert Hooker, Robert Hooker, Christopher James Halse Rogers
  • Date: 2010-09-14 08:55:40 UTC
  • mfrom: (1.2.28 upstream)
  • Revision ID: james.westby@ubuntu.com-20100914085540-m4fpl0hdjlfd4jgz
Tags: 7.9~git20100909-0ubuntu1
[ Robert Hooker ]
* New upstream git snapshot up to commit 94118fe2d4b1e5 (LP: #631413)
* New features include ATI HD5xxx series support in r600, and a vastly
  improved glsl compiler.
* Remove pre-generated .pc's, use the ones generated at build time
  instead.
* Remove all references to mesa-utils now that its no longer shipped
  with the mesa source.
* Disable the experimental ARB_fragment_shader option by default on
  i915, it exposes incomplete functionality that breaks KDE compositing
  among other things. It can be enabled via driconf still. (LP: #628930).

[ Christopher James Halse Rogers ]
* debian/patches/04_osmesa_version.diff:
  - Refresh for new upstream
* Bugs fixed in this release:
  - Fixes severe rendering corruption in Unity on radeon (LP: #628727,
    LP: #596292, LP: #599741, LP: #630315, LP: #613694, LP: #599741).
  - Also fixes rendering in gnome-shell (LP: #578619).
  - Flickering in OpenGL apps on radeon (LP: #626943, LP: #610541).
  - Provides preliminary support for new intel chips (LP: #601052).
* debian/rules:
  - Update configure flags to match upstream reshuffling.
  - Explicitly remove gallium DRI drivers that we don't want to ship.
* Update debian/gbp.conf for this Maverick-specific packaging
* libegl1-mesa-dri-x11,kms: There are no longer separate kms or x11 drivers
  for EGL, libegl1-mesa-drivers now contains a single driver that provides
  both backends.

Show diffs side-by-side

added added

removed removed

Lines of Context:
45
45
#include "pipe/p_screen.h"
46
46
#include "st_context.h"
47
47
#include "st_cb_fbo.h"
 
48
#include "st_cb_flush.h"
48
49
#include "st_format.h"
49
 
#include "st_public.h"
50
50
#include "st_texture.h"
 
51
#include "st_manager.h"
51
52
 
52
53
#include "util/u_format.h"
53
 
#include "util/u_rect.h"
54
54
#include "util/u_inlines.h"
55
55
 
56
56
 
64
64
                              GLenum internalFormat,
65
65
                              GLuint width, GLuint height)
66
66
{
67
 
   struct pipe_screen *screen = ctx->st->pipe->screen;
 
67
   struct st_context *st = st_context(ctx);
 
68
   struct pipe_screen *screen = st->pipe->screen;
68
69
   struct st_renderbuffer *strb = st_renderbuffer(rb);
69
70
   enum pipe_format format;
70
71
 
71
72
   if (strb->format != PIPE_FORMAT_NONE)
72
73
      format = strb->format;
73
74
   else
74
 
      format = st_choose_renderbuffer_format(screen, internalFormat);
 
75
      format = st_choose_renderbuffer_format(screen, internalFormat, rb->NumSamples);
75
76
      
76
77
   /* init renderbuffer fields */
77
78
   strb->Base.Width  = width;
96
97
      return strb->data != NULL;
97
98
   }
98
99
   else {
99
 
      struct pipe_texture template;
100
 
      unsigned surface_usage;
 
100
      struct pipe_resource template;
101
101
    
102
102
      /* Free the old surface and texture
103
103
       */
104
104
      pipe_surface_reference( &strb->surface, NULL );
105
 
      pipe_texture_reference( &strb->texture, NULL );
 
105
      pipe_resource_reference( &strb->texture, NULL );
 
106
      pipe_sampler_view_reference(&strb->sampler_view, NULL);
106
107
 
107
108
      /* Setup new texture template.
108
109
       */
109
110
      memset(&template, 0, sizeof(template));
110
 
      template.target = PIPE_TEXTURE_2D;
 
111
      template.target = st->internal_target;
111
112
      template.format = format;
112
113
      template.width0 = width;
113
114
      template.height0 = height;
115
116
      template.last_level = 0;
116
117
      template.nr_samples = rb->NumSamples;
117
118
      if (util_format_is_depth_or_stencil(format)) {
118
 
         template.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
 
119
         template.bind = PIPE_BIND_DEPTH_STENCIL;
119
120
      }
120
121
      else {
121
 
         template.tex_usage = (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
122
 
                               PIPE_TEXTURE_USAGE_RENDER_TARGET);
 
122
         template.bind = (PIPE_BIND_DISPLAY_TARGET |
 
123
                          PIPE_BIND_RENDER_TARGET);
123
124
      }
124
125
 
125
 
      /* Probably need dedicated flags for surface usage too: 
126
 
       */
127
 
      surface_usage = (PIPE_BUFFER_USAGE_GPU_READ |
128
 
                       PIPE_BUFFER_USAGE_GPU_WRITE);
129
 
#if 0
130
 
                       PIPE_BUFFER_USAGE_CPU_READ |
131
 
                       PIPE_BUFFER_USAGE_CPU_WRITE);
132
 
#endif
133
 
 
134
 
      strb->texture = screen->texture_create(screen, &template);
 
126
      strb->texture = screen->resource_create(screen, &template);
135
127
 
136
128
      if (!strb->texture) 
137
129
         return FALSE;
139
131
      strb->surface = screen->get_tex_surface(screen,
140
132
                                              strb->texture,
141
133
                                              0, 0, 0,
142
 
                                              surface_usage);
 
134
                                              template.bind);
143
135
      if (strb->surface) {
144
136
         assert(strb->surface->texture);
145
137
         assert(strb->surface->format);
161
153
   struct st_renderbuffer *strb = st_renderbuffer(rb);
162
154
   ASSERT(strb);
163
155
   pipe_surface_reference(&strb->surface, NULL);
164
 
   pipe_texture_reference(&strb->texture, NULL);
 
156
   pipe_resource_reference(&strb->texture, NULL);
 
157
   pipe_sampler_view_reference(&strb->sampler_view, NULL);
165
158
   free(strb->data);
166
159
   free(strb);
167
160
}
238
231
   strb->software = sw;
239
232
   
240
233
   switch (format) {
 
234
   case PIPE_FORMAT_R8G8B8A8_UNORM:
241
235
   case PIPE_FORMAT_B8G8R8A8_UNORM:
242
236
   case PIPE_FORMAT_A8R8G8B8_UNORM:
 
237
   case PIPE_FORMAT_R8G8B8X8_UNORM:
243
238
   case PIPE_FORMAT_B8G8R8X8_UNORM:
244
239
   case PIPE_FORMAT_X8R8G8B8_UNORM:
245
240
   case PIPE_FORMAT_B5G5R5A1_UNORM:
253
248
   case PIPE_FORMAT_Z32_UNORM:
254
249
      strb->Base.InternalFormat = GL_DEPTH_COMPONENT32;
255
250
      break;
256
 
   case PIPE_FORMAT_Z24S8_UNORM:
257
 
   case PIPE_FORMAT_S8Z24_UNORM:
 
251
   case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
 
252
   case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
258
253
   case PIPE_FORMAT_Z24X8_UNORM:
259
254
   case PIPE_FORMAT_X8Z24_UNORM:
260
255
      strb->Base.InternalFormat = GL_DEPTH24_STENCIL8_EXT;
261
256
      break;
262
 
   case PIPE_FORMAT_S8_UNORM:
 
257
   case PIPE_FORMAT_S8_USCALED:
263
258
      strb->Base.InternalFormat = GL_STENCIL_INDEX8_EXT;
264
259
      break;
265
260
   case PIPE_FORMAT_R16G16B16A16_SNORM:
318
313
                  struct gl_framebuffer *fb,
319
314
                  struct gl_renderbuffer_attachment *att)
320
315
{
321
 
   struct pipe_screen *screen = ctx->st->pipe->screen;
 
316
   struct st_context *st = st_context(ctx);
 
317
   struct pipe_context *pipe = st->pipe;
 
318
   struct pipe_screen *screen = pipe->screen;
322
319
   struct st_renderbuffer *strb;
323
320
   struct gl_renderbuffer *rb;
324
 
   struct pipe_texture *pt = st_get_texobj_texture(att->Texture);
 
321
   struct pipe_resource *pt = st_get_texobj_resource(att->Texture);
325
322
   struct st_texture_object *stObj;
326
323
   const struct gl_texture_image *texImage;
327
 
   GLint pt_level;
328
324
 
329
325
   /* When would this fail?  Perhaps assert? */
330
326
   if (!pt) 
331
327
      return;
332
328
 
333
 
   /* The first gallium texture level = Mesa BaseLevel */
334
 
   pt_level = MAX2(0, (GLint) att->TextureLevel - att->Texture->BaseLevel);
335
 
   texImage = att->Texture->Image[att->CubeMapFace][pt_level];
 
329
   /* get pointer to texture image we're rendeing to */
 
330
   texImage = att->Texture->Image[att->CubeMapFace][att->TextureLevel];
336
331
 
337
332
   /* create new renderbuffer which wraps the texture image */
338
333
   rb = st_new_renderbuffer(ctx, 0);
353
348
 
354
349
   /* point renderbuffer at texobject */
355
350
   strb->rtt = stObj;
356
 
   strb->rtt_level = pt_level;
 
351
   strb->rtt_level = att->TextureLevel;
357
352
   strb->rtt_face = att->CubeMapFace;
358
353
   strb->rtt_slice = att->Zoffset;
359
354
 
364
359
 
365
360
   /*printf("***** pipe texture %d x %d\n", pt->width0, pt->height0);*/
366
361
 
367
 
   pipe_texture_reference( &strb->texture, pt );
 
362
   pipe_resource_reference( &strb->texture, pt );
368
363
 
369
364
   pipe_surface_reference(&strb->surface, NULL);
370
365
 
 
366
   pipe_sampler_view_reference(&strb->sampler_view,
 
367
                               st_get_texture_sampler_view(stObj, pipe));
 
368
 
371
369
   assert(strb->rtt_level <= strb->texture->last_level);
372
370
 
373
371
   /* new surface for rendering into the texture */
376
374
                                           strb->rtt_face,
377
375
                                           strb->rtt_level,
378
376
                                           strb->rtt_slice,
379
 
                                           PIPE_BUFFER_USAGE_GPU_READ |
380
 
                                           PIPE_BUFFER_USAGE_GPU_WRITE);
 
377
                                           PIPE_BIND_RENDER_TARGET);
 
378
 
 
379
   strb->format = pt->format;
381
380
 
382
381
   strb->Base.Format = st_pipe_format_to_mesa_format(pt->format);
383
382
   strb->Base.DataType = st_format_datatype(pt->format);
403
402
st_finish_render_texture(GLcontext *ctx,
404
403
                         struct gl_renderbuffer_attachment *att)
405
404
{
 
405
   struct st_context *st = st_context(ctx);
406
406
   struct st_renderbuffer *strb = st_renderbuffer(att->Renderbuffer);
407
407
 
408
408
   if (!strb)
409
409
      return;
410
410
 
411
 
   st_flush( ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL );
 
411
   st_flush(st, PIPE_FLUSH_RENDER_CACHE, NULL);
412
412
 
413
413
   strb->rtt = NULL;
414
414
 
422
422
 
423
423
 
424
424
/**
425
 
 * Validate a renderbuffer attachment for a particular usage.
 
425
 * Validate a renderbuffer attachment for a particular set of bindings.
426
426
 */
427
 
 
428
427
static GLboolean
429
428
st_validate_attachment(struct pipe_screen *screen,
430
429
                       const struct gl_renderbuffer_attachment *att,
431
 
                       GLuint usage)
 
430
                       unsigned bindings)
432
431
{
433
 
   const struct st_texture_object *stObj =
434
 
      st_texture_object(att->Texture);
 
432
   const struct st_texture_object *stObj = st_texture_object(att->Texture);
435
433
 
436
 
   /**
437
 
    * Only validate texture attachments for now, since
 
434
   /* Only validate texture attachments for now, since
438
435
    * st_renderbuffer_alloc_storage makes sure that
439
436
    * the format is supported.
440
437
    */
441
 
 
442
438
   if (att->Type != GL_TEXTURE)
443
439
      return GL_TRUE;
444
440
 
446
442
      return GL_FALSE;
447
443
 
448
444
   return screen->is_format_supported(screen, stObj->pt->format,
449
 
                                      PIPE_TEXTURE_2D,
450
 
                                      usage, 0);
451
 
}
 
445
                                      PIPE_TEXTURE_2D,
 
446
                                      stObj->pt->nr_samples, bindings, 0);
 
447
}
 
448
 
 
449
 
 
450
/**
 
451
 * Check if two renderbuffer attachments name a combined depth/stencil
 
452
 * renderbuffer.
 
453
 */
 
454
GLboolean
 
455
st_is_depth_stencil_combined(const struct gl_renderbuffer_attachment *depth,
 
456
                             const struct gl_renderbuffer_attachment *stencil)
 
457
{
 
458
   assert(depth && stencil);
 
459
 
 
460
   if (depth->Type == stencil->Type) {
 
461
      if (depth->Type == GL_RENDERBUFFER_EXT &&
 
462
          depth->Renderbuffer == stencil->Renderbuffer)
 
463
         return GL_TRUE;
 
464
 
 
465
      if (depth->Type == GL_TEXTURE &&
 
466
          depth->Texture == stencil->Texture)
 
467
         return GL_TRUE;
 
468
   }
 
469
 
 
470
   return GL_FALSE;
 
471
}
 
472
 
452
473
 
453
474
/**
454
475
 * Check that the framebuffer configuration is valid in terms of what
459
480
static void
460
481
st_validate_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb)
461
482
{
462
 
   struct pipe_screen *screen = ctx->st->pipe->screen;
463
 
   const struct gl_renderbuffer *depthRb =
464
 
      fb->Attachment[BUFFER_DEPTH].Renderbuffer;
465
 
   const struct gl_renderbuffer *stencilRb =
466
 
      fb->Attachment[BUFFER_STENCIL].Renderbuffer;
 
483
   struct st_context *st = st_context(ctx);
 
484
   struct pipe_screen *screen = st->pipe->screen;
 
485
   const struct gl_renderbuffer_attachment *depth =
 
486
         &fb->Attachment[BUFFER_DEPTH];
 
487
   const struct gl_renderbuffer_attachment *stencil =
 
488
         &fb->Attachment[BUFFER_STENCIL];
467
489
   GLuint i;
468
490
 
469
 
   if (stencilRb && depthRb && stencilRb != depthRb) {
 
491
   if (depth->Type && stencil->Type && depth->Type != stencil->Type) {
 
492
      fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
 
493
      return;
 
494
   }
 
495
   if (depth->Type == GL_RENDERBUFFER_EXT &&
 
496
       stencil->Type == GL_RENDERBUFFER_EXT &&
 
497
       depth->Renderbuffer != stencil->Renderbuffer) {
 
498
      fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
 
499
      return;
 
500
   }
 
501
   if (depth->Type == GL_TEXTURE &&
 
502
       stencil->Type == GL_TEXTURE &&
 
503
       depth->Texture != stencil->Texture) {
470
504
      fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
471
505
      return;
472
506
   }
473
507
 
474
508
   if (!st_validate_attachment(screen,
475
 
                               &fb->Attachment[BUFFER_DEPTH],
476
 
                               PIPE_TEXTURE_USAGE_DEPTH_STENCIL)) {
 
509
                               depth,
 
510
                               PIPE_BIND_DEPTH_STENCIL)) {
477
511
      fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
478
512
      return;
479
513
   }
480
514
   if (!st_validate_attachment(screen,
481
 
                               &fb->Attachment[BUFFER_STENCIL],
482
 
                               PIPE_TEXTURE_USAGE_DEPTH_STENCIL)) {
 
515
                               stencil,
 
516
                               PIPE_BIND_DEPTH_STENCIL)) {
483
517
      fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
484
518
      return;
485
519
   }
486
520
   for (i = 0; i < ctx->Const.MaxColorAttachments; i++) {
487
521
      if (!st_validate_attachment(screen,
488
522
                                  &fb->Attachment[BUFFER_COLOR0 + i],
489
 
                                  PIPE_TEXTURE_USAGE_RENDER_TARGET)) {
 
523
                                  PIPE_BIND_RENDER_TARGET)) {
490
524
         fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
491
525
         return;
492
526
      }
495
529
 
496
530
 
497
531
/**
498
 
 * Copy back color buffer to front color buffer.
499
 
 */
500
 
static void
501
 
copy_back_to_front(struct st_context *st,
502
 
                   struct gl_framebuffer *fb,
503
 
                   gl_buffer_index frontIndex,
504
 
                   gl_buffer_index backIndex)
505
 
 
506
 
{
507
 
   struct st_framebuffer *stfb = (struct st_framebuffer *) fb;
508
 
   struct pipe_surface *surf_front, *surf_back;
509
 
 
510
 
   (void) st_get_framebuffer_surface(stfb, frontIndex, &surf_front);
511
 
   (void) st_get_framebuffer_surface(stfb, backIndex, &surf_back);
512
 
 
513
 
   if (surf_front && surf_back) {
514
 
      if (st->pipe->surface_copy) {
515
 
         st->pipe->surface_copy(st->pipe,
516
 
                                surf_front, 0, 0,  /* dest */
517
 
                                surf_back, 0, 0,   /* src */
518
 
                                fb->Width, fb->Height);
519
 
      } else {
520
 
         util_surface_copy(st->pipe, FALSE,
521
 
                           surf_front, 0, 0,
522
 
                           surf_back, 0, 0,
523
 
                           fb->Width, fb->Height);
524
 
      }
525
 
   }
526
 
}
527
 
 
528
 
 
529
 
/**
530
 
 * Check if we're drawing into, or read from, a front color buffer.  If the
531
 
 * front buffer is missing, create it now.
532
 
 *
533
 
 * The back color buffer must exist since we'll use its format/samples info
534
 
 * for creating the front buffer.
535
 
 *
536
 
 * \param frontIndex  either BUFFER_FRONT_LEFT or BUFFER_FRONT_RIGHT
537
 
 * \param backIndex  either BUFFER_BACK_LEFT or BUFFER_BACK_RIGHT
538
 
 */
539
 
static void
540
 
check_create_front_buffer(GLcontext *ctx, struct gl_framebuffer *fb,
541
 
                          gl_buffer_index frontIndex,
542
 
                          gl_buffer_index backIndex)
543
 
{
544
 
   if (fb->Attachment[frontIndex].Renderbuffer == NULL) {
545
 
      GLboolean create = GL_FALSE;
546
 
 
547
 
      /* check if drawing to or reading from front buffer */
548
 
      if (fb->_ColorReadBufferIndex == frontIndex) {
549
 
         create = GL_TRUE;
550
 
      }
551
 
      else {
552
 
         GLuint b;
553
 
         for (b = 0; b < fb->_NumColorDrawBuffers; b++) {
554
 
            if (fb->_ColorDrawBufferIndexes[b] == frontIndex) {
555
 
               create = GL_TRUE;
556
 
               break;
557
 
            }
558
 
         }
559
 
      }
560
 
 
561
 
      if (create) {
562
 
         struct st_renderbuffer *back;
563
 
         struct gl_renderbuffer *front;
564
 
         enum pipe_format colorFormat;
565
 
         uint samples;
566
 
 
567
 
         if (0)
568
 
            _mesa_debug(ctx, "Allocate new front buffer\n");
569
 
 
570
 
         /* get back renderbuffer info */
571
 
         back = st_renderbuffer(fb->Attachment[backIndex].Renderbuffer);
572
 
         colorFormat = back->format;
573
 
         samples = back->Base.NumSamples;
574
 
 
575
 
         /* create front renderbuffer */
576
 
         front = st_new_renderbuffer_fb(colorFormat, samples, FALSE);
577
 
         _mesa_add_renderbuffer(fb, frontIndex, front);
578
 
 
579
 
         /* alloc texture/surface for new front buffer */
580
 
         front->AllocStorage(ctx, front, front->InternalFormat,
581
 
                             fb->Width, fb->Height);
582
 
 
583
 
         /* initialize the front color buffer contents by copying
584
 
          * the back buffer.
585
 
          */
586
 
         copy_back_to_front(ctx->st, fb, frontIndex, backIndex);
587
 
      }
588
 
   }
589
 
}
590
 
 
591
 
 
592
 
/**
593
 
 * If front left/right color buffers are missing, create them now.
594
 
 */
595
 
static void
596
 
check_create_front_buffers(GLcontext *ctx, struct gl_framebuffer *fb)
597
 
{
598
 
   /* check if we need to create the front left buffer now */
599
 
   check_create_front_buffer(ctx, fb, BUFFER_FRONT_LEFT, BUFFER_BACK_LEFT);
600
 
 
601
 
   if (fb->Visual.stereoMode) {
602
 
      check_create_front_buffer(ctx, fb, BUFFER_FRONT_RIGHT, BUFFER_BACK_RIGHT);
603
 
   }
604
 
 
605
 
   st_invalidate_state(ctx, _NEW_BUFFERS);
606
 
}
607
 
 
608
 
 
609
 
/**
610
532
 * Called via glDrawBuffer.
611
533
 */
612
534
static void
613
535
st_DrawBuffers(GLcontext *ctx, GLsizei count, const GLenum *buffers)
614
536
{
 
537
   struct st_context *st = st_context(ctx);
 
538
   GLframebuffer *fb = ctx->DrawBuffer;
 
539
   GLuint i;
 
540
 
615
541
   (void) count;
616
542
   (void) buffers;
617
 
   check_create_front_buffers(ctx, ctx->DrawBuffer);
 
543
 
 
544
   /* add the renderbuffers on demand */
 
545
   for (i = 0; i < fb->_NumColorDrawBuffers; i++) {
 
546
      gl_buffer_index idx = fb->_ColorDrawBufferIndexes[i];
 
547
      st_manager_add_color_renderbuffer(st, fb, idx);
 
548
   }
618
549
}
619
550
 
620
551
 
624
555
static void
625
556
st_ReadBuffer(GLcontext *ctx, GLenum buffer)
626
557
{
 
558
   struct st_context *st = st_context(ctx);
 
559
   GLframebuffer *fb = ctx->ReadBuffer;
 
560
 
627
561
   (void) buffer;
628
 
   check_create_front_buffers(ctx, ctx->ReadBuffer);
 
562
 
 
563
   /* add the renderbuffer on demand */
 
564
   st_manager_add_color_renderbuffer(st, fb, fb->_ColorReadBufferIndex);
629
565
}
630
566
 
631
567
 
632
568
void st_init_fbo_functions(struct dd_function_table *functions)
633
569
{
 
570
#if FEATURE_EXT_framebuffer_object
634
571
   functions->NewFramebuffer = st_new_framebuffer;
635
572
   functions->NewRenderbuffer = st_new_renderbuffer;
636
573
   functions->BindFramebuffer = st_bind_framebuffer;
638
575
   functions->RenderTexture = st_render_texture;
639
576
   functions->FinishRenderTexture = st_finish_render_texture;
640
577
   functions->ValidateFramebuffer = st_validate_framebuffer;
 
578
#endif
641
579
   /* no longer needed by core Mesa, drivers handle resizes...
642
580
   functions->ResizeBuffers = st_resize_buffers;
643
581
   */
645
583
   functions->DrawBuffers = st_DrawBuffers;
646
584
   functions->ReadBuffer = st_ReadBuffer;
647
585
}
 
586
 
 
587
/* XXX unused ? */
 
588
struct pipe_sampler_view *
 
589
st_get_renderbuffer_sampler_view(struct st_renderbuffer *rb,
 
590
                                 struct pipe_context *pipe)
 
591
{
 
592
   if (!rb->sampler_view) {
 
593
      rb->sampler_view = st_create_texture_sampler_view(pipe, rb->texture);
 
594
   }
 
595
 
 
596
   return rb->sampler_view;
 
597
}