2 Copyright (C) Intel Corp. 2006. All Rights Reserved.
3 Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
4 develop this 3D driver.
6 Permission is hereby granted, free of charge, to any person obtaining
7 a 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, sublicense, 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:
14 The above copyright notice and this permission notice (including the
15 next paragraph) shall be included in all copies or substantial
16 portions of the Software.
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
22 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **********************************************************************/
29 * Keith Whitwell <keith@tungstengraphics.com>
33 #include "main/context.h"
34 #include "main/blend.h"
35 #include "main/mtypes.h"
36 #include "main/samplerobj.h"
37 #include "program/prog_parameter.h"
39 #include "intel_mipmap_tree.h"
40 #include "intel_batchbuffer.h"
41 #include "intel_tex.h"
42 #include "intel_fbo.h"
43 #include "intel_buffer_objects.h"
45 #include "brw_context.h"
46 #include "brw_state.h"
47 #include "brw_defines.h"
51 translate_tex_target(GLenum target
)
55 case GL_TEXTURE_1D_ARRAY_EXT
:
56 return BRW_SURFACE_1D
;
58 case GL_TEXTURE_RECTANGLE_NV
:
59 return BRW_SURFACE_2D
;
62 case GL_TEXTURE_2D_ARRAY_EXT
:
63 case GL_TEXTURE_EXTERNAL_OES
:
64 case GL_TEXTURE_2D_MULTISAMPLE
:
65 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY
:
66 return BRW_SURFACE_2D
;
69 return BRW_SURFACE_3D
;
71 case GL_TEXTURE_CUBE_MAP
:
72 case GL_TEXTURE_CUBE_MAP_ARRAY
:
73 return BRW_SURFACE_CUBE
;
82 brw_get_surface_tiling_bits(uint32_t tiling
)
86 return BRW_SURFACE_TILED
;
88 return BRW_SURFACE_TILED
| BRW_SURFACE_TILED_Y
;
96 brw_get_surface_num_multisamples(unsigned num_samples
)
99 return BRW_SURFACE_MULTISAMPLECOUNT_4
;
101 return BRW_SURFACE_MULTISAMPLECOUNT_1
;
106 * Compute the combination of DEPTH_TEXTURE_MODE and EXT_texture_swizzle
110 brw_get_texture_swizzle(const struct gl_context
*ctx
,
111 const struct gl_texture_object
*t
)
113 const struct gl_texture_image
*img
= t
->Image
[0][t
->BaseLevel
];
115 int swizzles
[SWIZZLE_NIL
+ 1] = {
125 if (img
->_BaseFormat
== GL_DEPTH_COMPONENT
||
126 img
->_BaseFormat
== GL_DEPTH_STENCIL
) {
127 GLenum depth_mode
= t
->DepthMode
;
129 /* In ES 3.0, DEPTH_TEXTURE_MODE is expected to be GL_RED for textures
130 * with depth component data specified with a sized internal format.
131 * Otherwise, it's left at the old default, GL_LUMINANCE.
133 if (_mesa_is_gles3(ctx
) &&
134 img
->InternalFormat
!= GL_DEPTH_COMPONENT
&&
135 img
->InternalFormat
!= GL_DEPTH_STENCIL
) {
139 switch (depth_mode
) {
141 swizzles
[0] = SWIZZLE_ZERO
;
142 swizzles
[1] = SWIZZLE_ZERO
;
143 swizzles
[2] = SWIZZLE_ZERO
;
144 swizzles
[3] = SWIZZLE_X
;
147 swizzles
[0] = SWIZZLE_X
;
148 swizzles
[1] = SWIZZLE_X
;
149 swizzles
[2] = SWIZZLE_X
;
150 swizzles
[3] = SWIZZLE_ONE
;
153 swizzles
[0] = SWIZZLE_X
;
154 swizzles
[1] = SWIZZLE_X
;
155 swizzles
[2] = SWIZZLE_X
;
156 swizzles
[3] = SWIZZLE_X
;
159 swizzles
[0] = SWIZZLE_X
;
160 swizzles
[1] = SWIZZLE_ZERO
;
161 swizzles
[2] = SWIZZLE_ZERO
;
162 swizzles
[3] = SWIZZLE_ONE
;
167 /* If the texture's format is alpha-only, force R, G, and B to
168 * 0.0. Similarly, if the texture's format has no alpha channel,
169 * force the alpha value read to 1.0. This allows for the
170 * implementation to use an RGBA texture for any of these formats
171 * without leaking any unexpected values.
173 switch (img
->_BaseFormat
) {
175 swizzles
[0] = SWIZZLE_ZERO
;
176 swizzles
[1] = SWIZZLE_ZERO
;
177 swizzles
[2] = SWIZZLE_ZERO
;
182 if (_mesa_get_format_bits(img
->TexFormat
, GL_ALPHA_BITS
) > 0)
183 swizzles
[3] = SWIZZLE_ONE
;
187 return MAKE_SWIZZLE4(swizzles
[GET_SWZ(t
->_Swizzle
, 0)],
188 swizzles
[GET_SWZ(t
->_Swizzle
, 1)],
189 swizzles
[GET_SWZ(t
->_Swizzle
, 2)],
190 swizzles
[GET_SWZ(t
->_Swizzle
, 3)]);
195 brw_update_buffer_texture_surface(struct gl_context
*ctx
,
197 uint32_t *surf_offset
)
199 struct brw_context
*brw
= brw_context(ctx
);
200 struct gl_texture_object
*tObj
= ctx
->Texture
.Unit
[unit
]._Current
;
202 struct intel_buffer_object
*intel_obj
=
203 intel_buffer_object(tObj
->BufferObject
);
204 drm_intel_bo
*bo
= intel_obj
? intel_obj
->buffer
: NULL
;
205 gl_format format
= tObj
->_BufferObjectFormat
;
206 uint32_t brw_format
= brw_format_for_mesa_format(format
);
207 int texel_size
= _mesa_get_format_bytes(format
);
209 if (brw_format
== 0 && format
!= MESA_FORMAT_RGBA_FLOAT32
) {
210 _mesa_problem(NULL
, "bad format %s for texture buffer\n",
211 _mesa_get_format_name(format
));
214 surf
= brw_state_batch(brw
, AUB_TRACE_SURFACE_STATE
,
215 6 * 4, 32, surf_offset
);
217 surf
[0] = (BRW_SURFACE_BUFFER
<< BRW_SURFACE_TYPE_SHIFT
|
218 (brw_format_for_mesa_format(format
) << BRW_SURFACE_FORMAT_SHIFT
));
221 surf
[0] |= BRW_SURFACE_RC_READ_WRITE
;
224 surf
[1] = bo
->offset
; /* reloc */
226 /* Emit relocation to surface contents. */
227 drm_intel_bo_emit_reloc(brw
->batch
.bo
,
229 bo
, 0, I915_GEM_DOMAIN_SAMPLER
, 0);
231 int w
= intel_obj
->Base
.Size
/ texel_size
;
232 surf
[2] = ((w
& 0x7f) << BRW_SURFACE_WIDTH_SHIFT
|
233 ((w
>> 7) & 0x1fff) << BRW_SURFACE_HEIGHT_SHIFT
);
234 surf
[3] = (((w
>> 20) & 0x7f) << BRW_SURFACE_DEPTH_SHIFT
|
235 (texel_size
- 1) << BRW_SURFACE_PITCH_SHIFT
);
247 brw_update_texture_surface(struct gl_context
*ctx
,
249 uint32_t *surf_offset
)
251 struct brw_context
*brw
= brw_context(ctx
);
252 struct gl_texture_object
*tObj
= ctx
->Texture
.Unit
[unit
]._Current
;
253 struct intel_texture_object
*intelObj
= intel_texture_object(tObj
);
254 struct intel_mipmap_tree
*mt
= intelObj
->mt
;
255 struct gl_texture_image
*firstImage
= tObj
->Image
[0][tObj
->BaseLevel
];
256 struct intel_texture_image
*intel_image
= intel_texture_image(firstImage
);
257 struct gl_sampler_object
*sampler
= _mesa_get_samplerobj(ctx
, unit
);
260 if (tObj
->Target
== GL_TEXTURE_BUFFER
) {
261 brw_update_buffer_texture_surface(ctx
, unit
, surf_offset
);
265 surf
= brw_state_batch(brw
, AUB_TRACE_SURFACE_STATE
,
266 6 * 4, 32, surf_offset
);
268 surf
[0] = (translate_tex_target(tObj
->Target
) << BRW_SURFACE_TYPE_SHIFT
|
269 BRW_SURFACE_MIPMAPLAYOUT_BELOW
<< BRW_SURFACE_MIPLAYOUT_SHIFT
|
270 BRW_SURFACE_CUBEFACE_ENABLES
|
271 (translate_tex_format(brw
,
274 sampler
->sRGBDecode
) <<
275 BRW_SURFACE_FORMAT_SHIFT
));
277 surf
[1] = intelObj
->mt
->region
->bo
->offset
+ intelObj
->mt
->offset
; /* reloc */
279 surf
[2] = ((intelObj
->_MaxLevel
- intel_image
->mt
->first_level
) << BRW_SURFACE_LOD_SHIFT
|
280 (mt
->logical_width0
- 1) << BRW_SURFACE_WIDTH_SHIFT
|
281 (mt
->logical_height0
- 1) << BRW_SURFACE_HEIGHT_SHIFT
);
283 surf
[3] = (brw_get_surface_tiling_bits(intelObj
->mt
->region
->tiling
) |
284 (mt
->logical_depth0
- 1) << BRW_SURFACE_DEPTH_SHIFT
|
285 (intelObj
->mt
->region
->pitch
- 1) <<
286 BRW_SURFACE_PITCH_SHIFT
);
288 surf
[4] = brw_get_surface_num_multisamples(intelObj
->mt
->num_samples
);
290 surf
[5] = mt
->align_h
== 4 ? BRW_SURFACE_VERTICAL_ALIGN_ENABLE
: 0;
292 /* Emit relocation to surface contents */
293 drm_intel_bo_emit_reloc(brw
->batch
.bo
,
295 intelObj
->mt
->region
->bo
,
296 surf
[1] - intelObj
->mt
->region
->bo
->offset
,
297 I915_GEM_DOMAIN_SAMPLER
, 0);
301 * Create the constant buffer surface. Vertex/fragment shader constants will be
302 * read from this buffer with Data Port Read instructions/messages.
305 brw_create_constant_surface(struct brw_context
*brw
,
309 uint32_t *out_offset
,
312 uint32_t stride
= dword_pitch
? 4 : 16;
313 uint32_t elements
= ALIGN(size
, stride
) / stride
;
314 const GLint w
= elements
- 1;
317 surf
= brw_state_batch(brw
, AUB_TRACE_SURFACE_STATE
,
318 6 * 4, 32, out_offset
);
320 surf
[0] = (BRW_SURFACE_BUFFER
<< BRW_SURFACE_TYPE_SHIFT
|
321 BRW_SURFACEFORMAT_R32G32B32A32_FLOAT
<< BRW_SURFACE_FORMAT_SHIFT
);
324 surf
[0] |= BRW_SURFACE_RC_READ_WRITE
;
326 surf
[1] = bo
->offset
+ offset
; /* reloc */
328 surf
[2] = ((w
& 0x7f) << BRW_SURFACE_WIDTH_SHIFT
|
329 ((w
>> 7) & 0x1fff) << BRW_SURFACE_HEIGHT_SHIFT
);
331 surf
[3] = (((w
>> 20) & 0x7f) << BRW_SURFACE_DEPTH_SHIFT
|
332 (stride
- 1) << BRW_SURFACE_PITCH_SHIFT
);
337 /* Emit relocation to surface contents. The 965 PRM, Volume 4, section
338 * 5.1.2 "Data Cache" says: "the data cache does not exist as a separate
339 * physical cache. It is mapped in hardware to the sampler cache."
341 drm_intel_bo_emit_reloc(brw
->batch
.bo
,
344 I915_GEM_DOMAIN_SAMPLER
, 0);
348 * Set up a binding table entry for use by stream output logic (transform
351 * buffer_size_minus_1 must me less than BRW_MAX_NUM_BUFFER_ENTRIES.
354 brw_update_sol_surface(struct brw_context
*brw
,
355 struct gl_buffer_object
*buffer_obj
,
356 uint32_t *out_offset
, unsigned num_vector_components
,
357 unsigned stride_dwords
, unsigned offset_dwords
)
359 struct intel_buffer_object
*intel_bo
= intel_buffer_object(buffer_obj
);
360 drm_intel_bo
*bo
= intel_bufferobj_buffer(brw
, intel_bo
, INTEL_WRITE_PART
);
361 uint32_t *surf
= brw_state_batch(brw
, AUB_TRACE_SURFACE_STATE
, 6 * 4, 32,
363 uint32_t pitch_minus_1
= 4*stride_dwords
- 1;
364 uint32_t offset_bytes
= 4 * offset_dwords
;
365 size_t size_dwords
= buffer_obj
->Size
/ 4;
366 uint32_t buffer_size_minus_1
, width
, height
, depth
, surface_format
;
368 /* FIXME: can we rely on core Mesa to ensure that the buffer isn't
369 * too big to map using a single binding table entry?
371 assert((size_dwords
- offset_dwords
) / stride_dwords
372 <= BRW_MAX_NUM_BUFFER_ENTRIES
);
374 if (size_dwords
> offset_dwords
+ num_vector_components
) {
375 /* There is room for at least 1 transform feedback output in the buffer.
376 * Compute the number of additional transform feedback outputs the
377 * buffer has room for.
379 buffer_size_minus_1
=
380 (size_dwords
- offset_dwords
- num_vector_components
) / stride_dwords
;
382 /* There isn't even room for a single transform feedback output in the
383 * buffer. We can't configure the binding table entry to prevent output
384 * entirely; we'll have to rely on the geometry shader to detect
385 * overflow. But to minimize the damage in case of a bug, set up the
386 * binding table entry to just allow a single output.
388 buffer_size_minus_1
= 0;
390 width
= buffer_size_minus_1
& 0x7f;
391 height
= (buffer_size_minus_1
& 0xfff80) >> 7;
392 depth
= (buffer_size_minus_1
& 0x7f00000) >> 20;
394 switch (num_vector_components
) {
396 surface_format
= BRW_SURFACEFORMAT_R32_FLOAT
;
399 surface_format
= BRW_SURFACEFORMAT_R32G32_FLOAT
;
402 surface_format
= BRW_SURFACEFORMAT_R32G32B32_FLOAT
;
405 surface_format
= BRW_SURFACEFORMAT_R32G32B32A32_FLOAT
;
408 assert(!"Invalid vector size for transform feedback output");
409 surface_format
= BRW_SURFACEFORMAT_R32_FLOAT
;
413 surf
[0] = BRW_SURFACE_BUFFER
<< BRW_SURFACE_TYPE_SHIFT
|
414 BRW_SURFACE_MIPMAPLAYOUT_BELOW
<< BRW_SURFACE_MIPLAYOUT_SHIFT
|
415 surface_format
<< BRW_SURFACE_FORMAT_SHIFT
|
416 BRW_SURFACE_RC_READ_WRITE
;
417 surf
[1] = bo
->offset
+ offset_bytes
; /* reloc */
418 surf
[2] = (width
<< BRW_SURFACE_WIDTH_SHIFT
|
419 height
<< BRW_SURFACE_HEIGHT_SHIFT
);
420 surf
[3] = (depth
<< BRW_SURFACE_DEPTH_SHIFT
|
421 pitch_minus_1
<< BRW_SURFACE_PITCH_SHIFT
);
425 /* Emit relocation to surface contents. */
426 drm_intel_bo_emit_reloc(brw
->batch
.bo
,
429 I915_GEM_DOMAIN_RENDER
, I915_GEM_DOMAIN_RENDER
);
432 /* Creates a new WM constant buffer reflecting the current fragment program's
433 * constants, if needed by the fragment program.
435 * Otherwise, constants go through the CURBEs using the brw_constant_buffer
439 brw_upload_wm_pull_constants(struct brw_context
*brw
)
441 struct gl_context
*ctx
= &brw
->ctx
;
442 /* BRW_NEW_FRAGMENT_PROGRAM */
443 struct brw_fragment_program
*fp
=
444 (struct brw_fragment_program
*) brw
->fragment_program
;
445 struct gl_program_parameter_list
*params
= fp
->program
.Base
.Parameters
;
446 const int size
= brw
->wm
.prog_data
->nr_pull_params
* sizeof(float);
447 const int surf_index
= SURF_INDEX_FRAG_CONST_BUFFER
;
451 _mesa_load_state_parameters(ctx
, params
);
453 /* CACHE_NEW_WM_PROG */
454 if (brw
->wm
.prog_data
->nr_pull_params
== 0) {
455 if (brw
->wm
.base
.const_bo
) {
456 drm_intel_bo_unreference(brw
->wm
.base
.const_bo
);
457 brw
->wm
.base
.const_bo
= NULL
;
458 brw
->wm
.base
.surf_offset
[surf_index
] = 0;
459 brw
->state
.dirty
.brw
|= BRW_NEW_SURFACES
;
464 drm_intel_bo_unreference(brw
->wm
.base
.const_bo
);
465 brw
->wm
.base
.const_bo
= drm_intel_bo_alloc(brw
->bufmgr
, "WM const bo",
468 /* _NEW_PROGRAM_CONSTANTS */
469 drm_intel_gem_bo_map_gtt(brw
->wm
.base
.const_bo
);
470 constants
= brw
->wm
.base
.const_bo
->virtual;
471 for (i
= 0; i
< brw
->wm
.prog_data
->nr_pull_params
; i
++) {
472 constants
[i
] = *brw
->wm
.prog_data
->pull_param
[i
];
474 drm_intel_gem_bo_unmap_gtt(brw
->wm
.base
.const_bo
);
476 brw
->vtbl
.create_constant_surface(brw
, brw
->wm
.base
.const_bo
, 0, size
,
477 &brw
->wm
.base
.surf_offset
[surf_index
],
480 brw
->state
.dirty
.brw
|= BRW_NEW_SURFACES
;
483 const struct brw_tracked_state brw_wm_pull_constants
= {
485 .mesa
= (_NEW_PROGRAM_CONSTANTS
),
486 .brw
= (BRW_NEW_BATCH
| BRW_NEW_FRAGMENT_PROGRAM
),
487 .cache
= CACHE_NEW_WM_PROG
,
489 .emit
= brw_upload_wm_pull_constants
,
493 brw_update_null_renderbuffer_surface(struct brw_context
*brw
, unsigned int unit
)
495 /* From the Sandy bridge PRM, Vol4 Part1 p71 (Surface Type: Programming
498 * A null surface will be used in instances where an actual surface is
499 * not bound. When a write message is generated to a null surface, no
500 * actual surface is written to. When a read message (including any
501 * sampling engine message) is generated to a null surface, the result
502 * is all zeros. Note that a null surface type is allowed to be used
503 * with all messages, even if it is not specificially indicated as
504 * supported. All of the remaining fields in surface state are ignored
505 * for null surfaces, with the following exceptions:
507 * - [DevSNB+]: Width, Height, Depth, and LOD fields must match the
508 * depth buffer’s corresponding state for all render target surfaces,
511 * - Surface Format must be R8G8B8A8_UNORM.
513 struct gl_context
*ctx
= &brw
->ctx
;
515 unsigned surface_type
= BRW_SURFACE_NULL
;
516 drm_intel_bo
*bo
= NULL
;
517 unsigned pitch_minus_1
= 0;
518 uint32_t multisampling_state
= 0;
521 const struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
523 surf
= brw_state_batch(brw
, AUB_TRACE_SURFACE_STATE
, 6 * 4, 32,
524 &brw
->wm
.base
.surf_offset
[SURF_INDEX_DRAW(unit
)]);
526 if (fb
->Visual
.samples
> 1) {
527 /* On Gen6, null render targets seem to cause GPU hangs when
528 * multisampling. So work around this problem by rendering into dummy
531 * To decrease the amount of memory needed by the workaround buffer, we
532 * set its pitch to 128 bytes (the width of a Y tile). This means that
533 * the amount of memory needed for the workaround buffer is
534 * (width_in_tiles + height_in_tiles - 1) tiles.
536 * Note that since the workaround buffer will be interpreted by the
537 * hardware as an interleaved multisampled buffer, we need to compute
538 * width_in_tiles and height_in_tiles by dividing the width and height
539 * by 16 rather than the normal Y-tile size of 32.
541 unsigned width_in_tiles
= ALIGN(fb
->Width
, 16) / 16;
542 unsigned height_in_tiles
= ALIGN(fb
->Height
, 16) / 16;
543 unsigned size_needed
= (width_in_tiles
+ height_in_tiles
- 1) * 4096;
544 brw_get_scratch_bo(brw
, &brw
->wm
.multisampled_null_render_target_bo
,
546 bo
= brw
->wm
.multisampled_null_render_target_bo
;
547 surface_type
= BRW_SURFACE_2D
;
549 multisampling_state
=
550 brw_get_surface_num_multisamples(fb
->Visual
.samples
);
553 surf
[0] = (surface_type
<< BRW_SURFACE_TYPE_SHIFT
|
554 BRW_SURFACEFORMAT_B8G8R8A8_UNORM
<< BRW_SURFACE_FORMAT_SHIFT
);
556 surf
[0] |= (1 << BRW_SURFACE_WRITEDISABLE_R_SHIFT
|
557 1 << BRW_SURFACE_WRITEDISABLE_G_SHIFT
|
558 1 << BRW_SURFACE_WRITEDISABLE_B_SHIFT
|
559 1 << BRW_SURFACE_WRITEDISABLE_A_SHIFT
);
561 surf
[1] = bo
? bo
->offset
: 0;
562 surf
[2] = ((fb
->Width
- 1) << BRW_SURFACE_WIDTH_SHIFT
|
563 (fb
->Height
- 1) << BRW_SURFACE_HEIGHT_SHIFT
);
565 /* From Sandy bridge PRM, Vol4 Part1 p82 (Tiled Surface: Programming
568 * If Surface Type is SURFTYPE_NULL, this field must be TRUE
570 surf
[3] = (BRW_SURFACE_TILED
| BRW_SURFACE_TILED_Y
|
571 pitch_minus_1
<< BRW_SURFACE_PITCH_SHIFT
);
572 surf
[4] = multisampling_state
;
576 drm_intel_bo_emit_reloc(brw
->batch
.bo
,
577 brw
->wm
.base
.surf_offset
[SURF_INDEX_DRAW(unit
)] + 4,
579 I915_GEM_DOMAIN_RENDER
, I915_GEM_DOMAIN_RENDER
);
584 * Sets up a surface state structure to point at the given region.
585 * While it is only used for the front/back buffer currently, it should be
586 * usable for further buffers when doing ARB_draw_buffer support.
589 brw_update_renderbuffer_surface(struct brw_context
*brw
,
590 struct gl_renderbuffer
*rb
,
594 struct gl_context
*ctx
= &brw
->ctx
;
595 struct intel_renderbuffer
*irb
= intel_renderbuffer(rb
);
596 struct intel_mipmap_tree
*mt
= irb
->mt
;
597 struct intel_region
*region
;
599 uint32_t tile_x
, tile_y
;
602 gl_format rb_format
= _mesa_get_render_format(ctx
, intel_rb_format(irb
));
606 if (rb
->TexImage
&& !brw
->has_surface_tile_offset
) {
607 intel_renderbuffer_get_tile_offsets(irb
, &tile_x
, &tile_y
);
609 if (tile_x
!= 0 || tile_y
!= 0) {
610 /* Original gen4 hardware couldn't draw to a non-tile-aligned
611 * destination in a miptree unless you actually setup your renderbuffer
612 * as a miptree and used the fragile lod/array_index/etc. controls to
613 * select the image. So, instead, we just make a new single-level
614 * miptree and render into that.
616 intel_renderbuffer_move_to_temp(brw
, irb
, false);
621 intel_miptree_used_for_rendering(irb
->mt
);
623 region
= irb
->mt
->region
;
625 surf
= brw_state_batch(brw
, AUB_TRACE_SURFACE_STATE
, 6 * 4, 32,
626 &brw
->wm
.base
.surf_offset
[SURF_INDEX_DRAW(unit
)]);
628 format
= brw
->render_target_format
[rb_format
];
629 if (unlikely(!brw
->format_supported_as_render_target
[rb_format
])) {
630 _mesa_problem(ctx
, "%s: renderbuffer format %s unsupported\n",
631 __FUNCTION__
, _mesa_get_format_name(rb_format
));
634 surf
[0] = (BRW_SURFACE_2D
<< BRW_SURFACE_TYPE_SHIFT
|
635 format
<< BRW_SURFACE_FORMAT_SHIFT
);
638 surf
[1] = (intel_renderbuffer_get_tile_offsets(irb
, &tile_x
, &tile_y
) +
641 surf
[2] = ((rb
->Width
- 1) << BRW_SURFACE_WIDTH_SHIFT
|
642 (rb
->Height
- 1) << BRW_SURFACE_HEIGHT_SHIFT
);
644 surf
[3] = (brw_get_surface_tiling_bits(region
->tiling
) |
645 (region
->pitch
- 1) << BRW_SURFACE_PITCH_SHIFT
);
647 surf
[4] = brw_get_surface_num_multisamples(mt
->num_samples
);
649 assert(brw
->has_surface_tile_offset
|| (tile_x
== 0 && tile_y
== 0));
650 /* Note that the low bits of these fields are missing, so
651 * there's the possibility of getting in trouble.
653 assert(tile_x
% 4 == 0);
654 assert(tile_y
% 2 == 0);
655 surf
[5] = ((tile_x
/ 4) << BRW_SURFACE_X_OFFSET_SHIFT
|
656 (tile_y
/ 2) << BRW_SURFACE_Y_OFFSET_SHIFT
|
657 (mt
->align_h
== 4 ? BRW_SURFACE_VERTICAL_ALIGN_ENABLE
: 0));
661 if (!ctx
->Color
.ColorLogicOpEnabled
&&
662 (ctx
->Color
.BlendEnabled
& (1 << unit
)))
663 surf
[0] |= BRW_SURFACE_BLEND_ENABLED
;
665 if (!ctx
->Color
.ColorMask
[unit
][0])
666 surf
[0] |= 1 << BRW_SURFACE_WRITEDISABLE_R_SHIFT
;
667 if (!ctx
->Color
.ColorMask
[unit
][1])
668 surf
[0] |= 1 << BRW_SURFACE_WRITEDISABLE_G_SHIFT
;
669 if (!ctx
->Color
.ColorMask
[unit
][2])
670 surf
[0] |= 1 << BRW_SURFACE_WRITEDISABLE_B_SHIFT
;
672 /* As mentioned above, disable writes to the alpha component when the
673 * renderbuffer is XRGB.
675 if (ctx
->DrawBuffer
->Visual
.alphaBits
== 0 ||
676 !ctx
->Color
.ColorMask
[unit
][3]) {
677 surf
[0] |= 1 << BRW_SURFACE_WRITEDISABLE_A_SHIFT
;
681 drm_intel_bo_emit_reloc(brw
->batch
.bo
,
682 brw
->wm
.base
.surf_offset
[SURF_INDEX_DRAW(unit
)] + 4,
684 surf
[1] - region
->bo
->offset
,
685 I915_GEM_DOMAIN_RENDER
,
686 I915_GEM_DOMAIN_RENDER
);
690 * Construct SURFACE_STATE objects for renderbuffers/draw buffers.
693 brw_update_renderbuffer_surfaces(struct brw_context
*brw
)
695 struct gl_context
*ctx
= &brw
->ctx
;
698 /* _NEW_BUFFERS | _NEW_COLOR */
699 /* Update surfaces for drawing buffers */
700 if (ctx
->DrawBuffer
->_NumColorDrawBuffers
>= 1) {
701 for (i
= 0; i
< ctx
->DrawBuffer
->_NumColorDrawBuffers
; i
++) {
702 if (intel_renderbuffer(ctx
->DrawBuffer
->_ColorDrawBuffers
[i
])) {
703 brw
->vtbl
.update_renderbuffer_surface(brw
, ctx
->DrawBuffer
->_ColorDrawBuffers
[i
],
704 ctx
->DrawBuffer
->Layered
, i
);
706 brw
->vtbl
.update_null_renderbuffer_surface(brw
, i
);
710 brw
->vtbl
.update_null_renderbuffer_surface(brw
, 0);
712 brw
->state
.dirty
.brw
|= BRW_NEW_SURFACES
;
715 const struct brw_tracked_state brw_renderbuffer_surfaces
= {
717 .mesa
= (_NEW_COLOR
|
719 .brw
= BRW_NEW_BATCH
,
722 .emit
= brw_update_renderbuffer_surfaces
,
725 const struct brw_tracked_state gen6_renderbuffer_surfaces
= {
727 .mesa
= _NEW_BUFFERS
,
728 .brw
= BRW_NEW_BATCH
,
731 .emit
= brw_update_renderbuffer_surfaces
,
736 update_stage_texture_surfaces(struct brw_context
*brw
,
737 const struct gl_program
*prog
,
738 uint32_t *surf_offset
)
743 struct gl_context
*ctx
= &brw
->ctx
;
745 unsigned num_samplers
= _mesa_fls(prog
->SamplersUsed
);
747 for (unsigned s
= 0; s
< num_samplers
; s
++) {
750 if (prog
->SamplersUsed
& (1 << s
)) {
751 const unsigned unit
= prog
->SamplerUnits
[s
];
754 if (ctx
->Texture
.Unit
[unit
]._ReallyEnabled
) {
755 brw
->vtbl
.update_texture_surface(ctx
, unit
, surf_offset
+ s
);
763 * Construct SURFACE_STATE objects for enabled textures.
766 brw_update_texture_surfaces(struct brw_context
*brw
)
768 /* BRW_NEW_VERTEX_PROGRAM */
769 struct gl_program
*vs
= (struct gl_program
*) brw
->vertex_program
;
771 /* BRW_NEW_GEOMETRY_PROGRAM */
772 struct gl_program
*gs
= (struct gl_program
*) brw
->geometry_program
;
774 /* BRW_NEW_FRAGMENT_PROGRAM */
775 struct gl_program
*fs
= (struct gl_program
*) brw
->fragment_program
;
778 update_stage_texture_surfaces(brw
, vs
,
779 brw
->vs
.base
.surf_offset
+
780 SURF_INDEX_VEC4_TEXTURE(0));
781 update_stage_texture_surfaces(brw
, gs
,
782 brw
->gs
.base
.surf_offset
+
783 SURF_INDEX_VEC4_TEXTURE(0));
784 update_stage_texture_surfaces(brw
, fs
,
785 brw
->wm
.base
.surf_offset
+
786 SURF_INDEX_TEXTURE(0));
788 brw
->state
.dirty
.brw
|= BRW_NEW_SURFACES
;
791 const struct brw_tracked_state brw_texture_surfaces
= {
793 .mesa
= _NEW_TEXTURE
,
794 .brw
= BRW_NEW_BATCH
|
795 BRW_NEW_VERTEX_PROGRAM
|
796 BRW_NEW_GEOMETRY_PROGRAM
|
797 BRW_NEW_FRAGMENT_PROGRAM
,
800 .emit
= brw_update_texture_surfaces
,
804 brw_upload_ubo_surfaces(struct brw_context
*brw
,
805 struct gl_shader
*shader
,
806 uint32_t *surf_offsets
)
808 struct gl_context
*ctx
= &brw
->ctx
;
813 for (int i
= 0; i
< shader
->NumUniformBlocks
; i
++) {
814 struct gl_uniform_buffer_binding
*binding
;
815 struct intel_buffer_object
*intel_bo
;
817 binding
= &ctx
->UniformBufferBindings
[shader
->UniformBlocks
[i
].Binding
];
818 intel_bo
= intel_buffer_object(binding
->BufferObject
);
819 drm_intel_bo
*bo
= intel_bufferobj_buffer(brw
, intel_bo
, INTEL_READ
);
821 /* Because behavior for referencing outside of the binding's size in the
822 * glBindBufferRange case is undefined, we can just bind the whole buffer
823 * glBindBufferBase wants and be a correct implementation.
825 brw
->vtbl
.create_constant_surface(brw
, bo
, binding
->Offset
,
826 bo
->size
- binding
->Offset
,
828 shader
->Type
== GL_FRAGMENT_SHADER
);
831 if (shader
->NumUniformBlocks
)
832 brw
->state
.dirty
.brw
|= BRW_NEW_SURFACES
;
836 brw_upload_wm_ubo_surfaces(struct brw_context
*brw
)
838 struct gl_context
*ctx
= &brw
->ctx
;
840 struct gl_shader_program
*prog
= ctx
->Shader
._CurrentFragmentProgram
;
845 brw_upload_ubo_surfaces(brw
, prog
->_LinkedShaders
[MESA_SHADER_FRAGMENT
],
846 &brw
->wm
.base
.surf_offset
[SURF_INDEX_WM_UBO(0)]);
849 const struct brw_tracked_state brw_wm_ubo_surfaces
= {
851 .mesa
= _NEW_PROGRAM
,
852 .brw
= BRW_NEW_BATCH
| BRW_NEW_UNIFORM_BUFFER
,
855 .emit
= brw_upload_wm_ubo_surfaces
,
859 * Constructs the binding table for the WM surface state, which maps unit
860 * numbers to surface state objects.
863 brw_upload_wm_binding_table(struct brw_context
*brw
)
865 struct brw_stage_state
*stage_state
= &brw
->wm
.base
;
867 /* BRW_NEW_SURFACES and CACHE_NEW_WM_PROG */
868 brw_upload_binding_table(brw
, BRW_NEW_PS_BINDING_TABLE
, stage_state
,
869 brw
->wm
.prog_data
->binding_table_size
,
870 SURF_INDEX_WM_SHADER_TIME
);
873 const struct brw_tracked_state brw_wm_binding_table
= {
876 .brw
= (BRW_NEW_BATCH
|
878 .cache
= CACHE_NEW_WM_PROG
880 .emit
= brw_upload_wm_binding_table
,
884 gen4_init_vtable_surface_functions(struct brw_context
*brw
)
886 brw
->vtbl
.update_texture_surface
= brw_update_texture_surface
;
887 brw
->vtbl
.update_renderbuffer_surface
= brw_update_renderbuffer_surface
;
888 brw
->vtbl
.update_null_renderbuffer_surface
=
889 brw_update_null_renderbuffer_surface
;
890 brw
->vtbl
.create_constant_surface
= brw_create_constant_surface
;