#include <assert.h>
#include "intel_batchbuffer.h"
-#include "intel_fbo.h"
#include "intel_mipmap_tree.h"
#include "brw_context.h"
-#include "brw_defines.h"
#include "brw_state.h"
#include "brw_blorp.h"
-#include "gen6_blorp.h"
-
-/**
- * \name Constants for BLORP VBO
- * \{
- */
-#define GEN6_BLORP_NUM_VERTICES 3
-#define GEN6_BLORP_NUM_VUE_ELEMS 8
-#define GEN6_BLORP_VBO_SIZE (GEN6_BLORP_NUM_VERTICES \
- * GEN6_BLORP_NUM_VUE_ELEMS \
- * sizeof(float))
-/** \} */
/**
* CMD_STATE_BASE_ADDRESS
ADVANCE_BATCH();
}
+static void
+gen6_blorp_emit_vertex_buffer_state(struct brw_context *brw,
+ unsigned num_elems,
+ unsigned vbo_size,
+ uint32_t vertex_offset)
+{
+ /* 3DSTATE_VERTEX_BUFFERS */
+ const int num_buffers = 1;
+ const int batch_length = 1 + 4 * num_buffers;
+
+ uint32_t dw0 = GEN6_VB0_ACCESS_VERTEXDATA |
+ (num_elems * sizeof(float)) << BRW_VB0_PITCH_SHIFT;
+
+ if (brw->gen >= 7)
+ dw0 |= GEN7_VB0_ADDRESS_MODIFYENABLE;
+
+ switch (brw->gen) {
+ case 7:
+ dw0 |= GEN7_MOCS_L3 << 16;
+ break;
+ case 8:
+ dw0 |= BDW_MOCS_WB << 16;
+ break;
+ case 9:
+ dw0 |= SKL_MOCS_WB << 16;
+ break;
+ }
+
+ BEGIN_BATCH(batch_length);
+ OUT_BATCH((_3DSTATE_VERTEX_BUFFERS << 16) | (batch_length - 2));
+ OUT_BATCH(dw0);
+ if (brw->gen >= 8) {
+ OUT_RELOC64(brw->batch.bo, I915_GEM_DOMAIN_VERTEX, 0, vertex_offset);
+ OUT_BATCH(vbo_size);
+ } else {
+ /* start address */
+ OUT_RELOC(brw->batch.bo, I915_GEM_DOMAIN_VERTEX, 0,
+ vertex_offset);
+ /* end address */
+ OUT_RELOC(brw->batch.bo, I915_GEM_DOMAIN_VERTEX, 0,
+ vertex_offset + vbo_size - 1);
+ OUT_BATCH(0);
+ }
+ ADVANCE_BATCH();
+}
void
gen6_blorp_emit_vertices(struct brw_context *brw,
*
* For details, see the Sandybridge PRM, Volume 2, Part 1, Section 1.5.1
* "Vertex URB Entry (VUE) Formats".
+ *
+ * Only vertex position X and Y are going to be variable, Z is fixed to
+ * zero and W to one. Header words dw0-3 are all zero. There is no need to
+ * include the fixed values in the vertex buffer. Vertex fetcher can be
+ * instructed to fill vertex elements with constant values of one and zero
+ * instead of reading them from the buffer. See the vertex element setup
+ * below.
*/
{
float *vertex_data;
- const float vertices[GEN6_BLORP_VBO_SIZE] = {
- /* v0 */ 0, 0, 0, 0, (float) params->x0, (float) params->y1, 0, 1,
- /* v1 */ 0, 0, 0, 0, (float) params->x1, (float) params->y1, 0, 1,
- /* v2 */ 0, 0, 0, 0, (float) params->x0, (float) params->y0, 0, 1,
+ const float vertices[] = {
+ /* v0 */ (float)params->x0, (float)params->y1,
+ /* v1 */ (float)params->x1, (float)params->y1,
+ /* v2 */ (float)params->x0, (float)params->y0,
};
vertex_data = (float *) brw_state_batch(brw, AUB_TRACE_VERTEX_BUFFER,
- GEN6_BLORP_VBO_SIZE, 32,
+ sizeof(vertices), 32,
&vertex_offset);
- memcpy(vertex_data, vertices, GEN6_BLORP_VBO_SIZE);
- }
+ memcpy(vertex_data, vertices, sizeof(vertices));
- /* 3DSTATE_VERTEX_BUFFERS */
- {
- const int num_buffers = 1;
- const int batch_length = 1 + 4 * num_buffers;
-
- uint32_t dw0 = GEN6_VB0_ACCESS_VERTEXDATA |
- (GEN6_BLORP_NUM_VUE_ELEMS * sizeof(float)) << BRW_VB0_PITCH_SHIFT;
-
- if (brw->gen >= 7)
- dw0 |= GEN7_VB0_ADDRESS_MODIFYENABLE;
-
- if (brw->gen == 7)
- dw0 |= GEN7_MOCS_L3 << 16;
-
- BEGIN_BATCH(batch_length);
- OUT_BATCH((_3DSTATE_VERTEX_BUFFERS << 16) | (batch_length - 2));
- OUT_BATCH(dw0);
- /* start address */
- OUT_RELOC(brw->batch.bo, I915_GEM_DOMAIN_VERTEX, 0,
- vertex_offset);
- /* end address */
- OUT_RELOC(brw->batch.bo, I915_GEM_DOMAIN_VERTEX, 0,
- vertex_offset + GEN6_BLORP_VBO_SIZE - 1);
- OUT_BATCH(0);
- ADVANCE_BATCH();
+ const unsigned blorp_num_vue_elems = 2;
+ gen6_blorp_emit_vertex_buffer_state(brw, blorp_num_vue_elems,
+ sizeof(vertices), vertex_offset);
}
/* 3DSTATE_VERTEX_ELEMENTS
OUT_BATCH(GEN6_VE0_VALID |
BRW_SURFACEFORMAT_R32G32B32A32_FLOAT << BRW_VE0_FORMAT_SHIFT |
0 << BRW_VE0_SRC_OFFSET_SHIFT);
- OUT_BATCH(BRW_VE1_COMPONENT_STORE_SRC << BRW_VE1_COMPONENT_0_SHIFT |
- BRW_VE1_COMPONENT_STORE_SRC << BRW_VE1_COMPONENT_1_SHIFT |
- BRW_VE1_COMPONENT_STORE_SRC << BRW_VE1_COMPONENT_2_SHIFT |
- BRW_VE1_COMPONENT_STORE_SRC << BRW_VE1_COMPONENT_3_SHIFT);
+ OUT_BATCH(BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_0_SHIFT |
+ BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_1_SHIFT |
+ BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_2_SHIFT |
+ BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_3_SHIFT);
/* Element 1 */
OUT_BATCH(GEN6_VE0_VALID |
- BRW_SURFACEFORMAT_R32G32B32A32_FLOAT << BRW_VE0_FORMAT_SHIFT |
- 16 << BRW_VE0_SRC_OFFSET_SHIFT);
+ BRW_SURFACEFORMAT_R32G32_FLOAT << BRW_VE0_FORMAT_SHIFT |
+ 0 << BRW_VE0_SRC_OFFSET_SHIFT);
OUT_BATCH(BRW_VE1_COMPONENT_STORE_SRC << BRW_VE1_COMPONENT_0_SHIFT |
BRW_VE1_COMPONENT_STORE_SRC << BRW_VE1_COMPONENT_1_SHIFT |
- BRW_VE1_COMPONENT_STORE_SRC << BRW_VE1_COMPONENT_2_SHIFT |
- BRW_VE1_COMPONENT_STORE_SRC << BRW_VE1_COMPONENT_3_SHIFT);
+ BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_2_SHIFT |
+ BRW_VE1_COMPONENT_STORE_1_FLT << BRW_VE1_COMPONENT_3_SHIFT);
ADVANCE_BATCH();
}
}
{
uint32_t cc_blend_state_offset;
+ assume(params->num_draw_buffers);
+
+ const unsigned size = params->num_draw_buffers *
+ sizeof(struct gen6_blend_state);
struct gen6_blend_state *blend = (struct gen6_blend_state *)
- brw_state_batch(brw, AUB_TRACE_BLEND_STATE,
- sizeof(struct gen6_blend_state), 64,
+ brw_state_batch(brw, AUB_TRACE_BLEND_STATE, size, 64,
&cc_blend_state_offset);
- memset(blend, 0, sizeof(*blend));
+ memset(blend, 0, size);
- blend->blend1.pre_blend_clamp_enable = 1;
- blend->blend1.post_blend_clamp_enable = 1;
- blend->blend1.clamp_range = BRW_RENDERTARGET_CLAMPRANGE_FORMAT;
+ for (unsigned i = 0; i < params->num_draw_buffers; ++i) {
+ blend[i].blend1.pre_blend_clamp_enable = 1;
+ blend[i].blend1.post_blend_clamp_enable = 1;
+ blend[i].blend1.clamp_range = BRW_RENDERTARGET_CLAMPRANGE_FORMAT;
- blend->blend1.write_disable_r = params->color_write_disable[0];
- blend->blend1.write_disable_g = params->color_write_disable[1];
- blend->blend1.write_disable_b = params->color_write_disable[2];
- blend->blend1.write_disable_a = params->color_write_disable[3];
-
- /* When blitting from an XRGB source to a ARGB destination, we need to
- * interpret the missing channel as 1.0. Blending can do that for us:
- * we simply use the RGB values from the fragment shader ("source RGB"),
- * but smash the alpha channel to 1.
- */
- if (params->src.mt &&
- _mesa_get_format_bits(params->dst.mt->format, GL_ALPHA_BITS) > 0 &&
- _mesa_get_format_bits(params->src.mt->format, GL_ALPHA_BITS) == 0) {
- blend->blend0.blend_enable = 1;
- blend->blend0.ia_blend_enable = 1;
-
- blend->blend0.blend_func = BRW_BLENDFUNCTION_ADD;
- blend->blend0.ia_blend_func = BRW_BLENDFUNCTION_ADD;
-
- blend->blend0.source_blend_factor = BRW_BLENDFACTOR_SRC_COLOR;
- blend->blend0.dest_blend_factor = BRW_BLENDFACTOR_ZERO;
- blend->blend0.ia_source_blend_factor = BRW_BLENDFACTOR_ONE;
- blend->blend0.ia_dest_blend_factor = BRW_BLENDFACTOR_ZERO;
+ blend[i].blend1.write_disable_r = params->color_write_disable[0];
+ blend[i].blend1.write_disable_g = params->color_write_disable[1];
+ blend[i].blend1.write_disable_b = params->color_write_disable[2];
+ blend[i].blend1.write_disable_a = params->color_write_disable[3];
}
return cc_blend_state_offset;
/* CC_STATE */
uint32_t
-gen6_blorp_emit_cc_state(struct brw_context *brw,
- const brw_blorp_params *params)
+gen6_blorp_emit_cc_state(struct brw_context *brw)
{
uint32_t cc_state_offset;
width /= 2;
height /= 2;
}
- struct intel_region *region = surface->mt->region;
+ struct intel_mipmap_tree *mt = surface->mt;
uint32_t tile_x, tile_y;
uint32_t *surf = (uint32_t *)
/* reloc */
surf[1] = (surface->compute_tile_offsets(&tile_x, &tile_y) +
- region->bo->offset);
+ mt->bo->offset64);
surf[2] = (0 << BRW_SURFACE_LOD_SHIFT |
(width - 1) << BRW_SURFACE_WIDTH_SHIFT |
uint32_t tiling = surface->map_stencil_as_y_tiled
? BRW_SURFACE_TILED | BRW_SURFACE_TILED_Y
- : brw_get_surface_tiling_bits(region->tiling);
- uint32_t pitch_bytes = region->pitch;
+ : brw_get_surface_tiling_bits(mt->tiling);
+ uint32_t pitch_bytes = mt->pitch;
if (surface->map_stencil_as_y_tiled)
pitch_bytes *= 2;
surf[3] = (tiling |
assert(tile_y % 2 == 0);
surf[5] = ((tile_x / 4) << BRW_SURFACE_X_OFFSET_SHIFT |
(tile_y / 2) << BRW_SURFACE_Y_OFFSET_SHIFT |
- (surface->mt->align_h == 4 ?
+ (surface->mt->valign == 4 ?
BRW_SURFACE_VERTICAL_ALIGN_ENABLE : 0));
/* Emit relocation to surface contents */
drm_intel_bo_emit_reloc(brw->batch.bo,
wm_surf_offset + 4,
- region->bo,
- surf[1] - region->bo->offset,
+ mt->bo,
+ surf[1] - mt->bo->offset64,
read_domains, write_domain);
return wm_surf_offset;
/* BINDING_TABLE. See brw_wm_binding_table(). */
uint32_t
gen6_blorp_emit_binding_table(struct brw_context *brw,
- const brw_blorp_params *params,
uint32_t wm_surf_offset_renderbuffer,
uint32_t wm_surf_offset_texture)
{
/**
* SAMPLER_STATE. See brw_update_sampler_state().
*/
-static uint32_t
+uint32_t
gen6_blorp_emit_sampler_state(struct brw_context *brw,
- const brw_blorp_params *params)
+ unsigned tex_filter, unsigned max_lod,
+ bool non_normalized_coords)
{
uint32_t sampler_offset;
+ uint32_t *sampler_state = (uint32_t *)
+ brw_state_batch(brw, AUB_TRACE_SAMPLER_STATE, 16, 32, &sampler_offset);
- struct brw_sampler_state *sampler = (struct brw_sampler_state *)
- brw_state_batch(brw, AUB_TRACE_SAMPLER_STATE,
- sizeof(struct brw_sampler_state),
- 32, &sampler_offset);
- memset(sampler, 0, sizeof(*sampler));
-
- sampler->ss0.min_filter = BRW_MAPFILTER_LINEAR;
- sampler->ss0.mip_filter = BRW_MIPFILTER_NONE;
- sampler->ss0.mag_filter = BRW_MAPFILTER_LINEAR;
-
- sampler->ss1.r_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
- sampler->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
- sampler->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
-
- sampler->ss0.min_mag_neq = 1;
-
- /* Set LOD bias:
- */
- sampler->ss0.lod_bias = 0;
-
- sampler->ss0.lod_preclamp = 1; /* OpenGL mode */
- sampler->ss0.default_color_mode = 0; /* OpenGL/DX10 mode */
+ unsigned address_rounding = BRW_ADDRESS_ROUNDING_ENABLE_U_MIN |
+ BRW_ADDRESS_ROUNDING_ENABLE_V_MIN |
+ BRW_ADDRESS_ROUNDING_ENABLE_R_MIN |
+ BRW_ADDRESS_ROUNDING_ENABLE_U_MAG |
+ BRW_ADDRESS_ROUNDING_ENABLE_V_MAG |
+ BRW_ADDRESS_ROUNDING_ENABLE_R_MAG;
- /* Set BaseMipLevel, MaxLOD, MinLOD:
- *
- * XXX: I don't think that using firstLevel, lastLevel works,
+ /* XXX: I don't think that using firstLevel, lastLevel works,
* because we always setup the surface state as if firstLevel ==
* level zero. Probably have to subtract firstLevel from each of
* these:
*/
- sampler->ss0.base_level = U_FIXED(0, 1);
-
- sampler->ss1.max_lod = U_FIXED(0, 6);
- sampler->ss1.min_lod = U_FIXED(0, 6);
-
- sampler->ss3.non_normalized_coord = 1;
-
- sampler->ss3.address_round |= BRW_ADDRESS_ROUNDING_ENABLE_U_MIN |
- BRW_ADDRESS_ROUNDING_ENABLE_V_MIN |
- BRW_ADDRESS_ROUNDING_ENABLE_R_MIN;
- sampler->ss3.address_round |= BRW_ADDRESS_ROUNDING_ENABLE_U_MAG |
- BRW_ADDRESS_ROUNDING_ENABLE_V_MAG |
- BRW_ADDRESS_ROUNDING_ENABLE_R_MAG;
+ brw_emit_sampler_state(brw,
+ sampler_state,
+ sampler_offset,
+ tex_filter, /* min filter */
+ tex_filter, /* mag filter */
+ BRW_MIPFILTER_NONE,
+ BRW_ANISORATIO_2,
+ address_rounding,
+ BRW_TEXCOORDMODE_CLAMP,
+ BRW_TEXCOORDMODE_CLAMP,
+ BRW_TEXCOORDMODE_CLAMP,
+ 0, /* min LOD */
+ max_lod,
+ 0, /* LOD bias */
+ 0, /* shadow function */
+ non_normalized_coords,
+ 0); /* border color offset - unused */
return sampler_offset;
}
*/
static void
gen6_blorp_emit_sampler_state_pointers(struct brw_context *brw,
- const brw_blorp_params *params,
uint32_t sampler_offset)
{
BEGIN_BATCH(4);
gen6_blorp_emit_vs_disable(struct brw_context *brw,
const brw_blorp_params *params)
{
- if (brw->gen == 6) {
- /* From the BSpec, 3D Pipeline > Geometry > Vertex Shader > State,
- * 3DSTATE_VS, Dword 5.0 "VS Function Enable":
- *
- * [DevSNB] A pipeline flush must be programmed prior to a
- * 3DSTATE_VS command that causes the VS Function Enable to
- * toggle. Pipeline flush can be executed by sending a PIPE_CONTROL
- * command with CS stall bit set and a post sync operation.
- */
- intel_emit_post_sync_nonzero_flush(brw);
- }
+ /* From the BSpec, 3D Pipeline > Geometry > Vertex Shader > State,
+ * 3DSTATE_VS, Dword 5.0 "VS Function Enable":
+ *
+ * [DevSNB] A pipeline flush must be programmed prior to a
+ * 3DSTATE_VS command that causes the VS Function Enable to
+ * toggle. Pipeline flush can be executed by sending a PIPE_CONTROL
+ * command with CS stall bit set and a post sync operation.
+ *
+ * We've already done one at the start of the BLORP operation.
+ */
/* Disable the push constant buffers. */
BEGIN_BATCH(5);
OUT_BATCH(0);
OUT_BATCH(0);
ADVANCE_BATCH();
+ brw->gs.enabled = false;
}
* output, but does spare a few electrons.
*/
void
-gen6_blorp_emit_clip_disable(struct brw_context *brw,
- const brw_blorp_params *params)
+gen6_blorp_emit_clip_disable(struct brw_context *brw)
{
BEGIN_BATCH(4);
OUT_BATCH(_3DSTATE_CLIP << 16 | (4 - 2));
{
BEGIN_BATCH(20);
OUT_BATCH(_3DSTATE_SF << 16 | (20 - 2));
- OUT_BATCH((1 - 1) << GEN6_SF_NUM_OUTPUTS_SHIFT | /* only position */
+ OUT_BATCH(params->num_varyings << GEN6_SF_NUM_OUTPUTS_SHIFT |
1 << GEN6_SF_URB_ENTRY_READ_LENGTH_SHIFT |
- 0 << GEN6_SF_URB_ENTRY_READ_OFFSET_SHIFT);
+ BRW_SF_URB_ENTRY_READ_OFFSET <<
+ GEN6_SF_URB_ENTRY_READ_OFFSET_SHIFT);
OUT_BATCH(0); /* dw2 */
OUT_BATCH(params->dst.num_samples > 1 ? GEN6_SF_MSRAST_ON_PATTERN : 0);
for (int i = 0; i < 16; ++i)
case GEN6_HIZ_OP_NONE:
break;
default:
- assert(0);
- break;
+ unreachable("not reached");
}
dw5 |= GEN6_WM_LINE_AA_WIDTH_1_0;
dw5 |= GEN6_WM_LINE_END_CAP_AA_WIDTH_0_5;
dw6 |= 0 << GEN6_WM_BARYCENTRIC_INTERPOLATION_MODE_SHIFT; /* No interp */
dw6 |= 0 << GEN6_WM_NUM_SF_OUTPUTS_SHIFT; /* No inputs from SF */
if (params->use_wm_prog) {
- dw2 |= 1 << GEN6_WM_SAMPLER_COUNT_SHIFT; /* Up to 4 samplers */
dw4 |= prog_data->first_curbe_grf << GEN6_WM_DISPATCH_START_GRF_SHIFT_0;
dw5 |= GEN6_WM_16_DISPATCH_ENABLE;
- dw5 |= GEN6_WM_KILL_ENABLE; /* TODO: temporarily smash on */
dw5 |= GEN6_WM_DISPATCH_ENABLE; /* We are rendering */
}
+ if (params->src.mt) {
+ dw5 |= GEN6_WM_KILL_ENABLE; /* TODO: temporarily smash on */
+ dw2 |= 1 << GEN6_WM_SAMPLER_COUNT_SHIFT; /* Up to 4 samplers */
+ }
+
if (params->dst.num_samples > 1) {
dw6 |= GEN6_WM_MSRAST_ON_PATTERN;
if (prog_data && prog_data->persample_msaa_dispatch)
*/
static void
gen6_blorp_emit_binding_table_pointers(struct brw_context *brw,
- const brw_blorp_params *params,
uint32_t wm_bind_bo_offset)
{
BEGIN_BATCH(4);
gen6_blorp_emit_depth_stencil_config(struct brw_context *brw,
const brw_blorp_params *params)
{
- struct gl_context *ctx = &brw->ctx;
- uint32_t draw_x = params->depth.x_offset;
- uint32_t draw_y = params->depth.y_offset;
- uint32_t tile_mask_x, tile_mask_y;
+ uint32_t surfwidth, surfheight;
+ uint32_t surftype;
+ unsigned int depth = MAX2(params->depth.mt->logical_depth0, 1);
+ GLenum gl_target = params->depth.mt->target;
+ unsigned int lod;
+
+ switch (gl_target) {
+ case GL_TEXTURE_CUBE_MAP_ARRAY:
+ case GL_TEXTURE_CUBE_MAP:
+ /* The PRM claims that we should use BRW_SURFACE_CUBE for this
+ * situation, but experiments show that gl_Layer doesn't work when we do
+ * this. So we use BRW_SURFACE_2D, since for rendering purposes this is
+ * equivalent.
+ */
+ surftype = BRW_SURFACE_2D;
+ depth *= 6;
+ break;
+ default:
+ surftype = translate_tex_target(gl_target);
+ break;
+ }
- brw_get_depthstencil_tile_masks(params->depth.mt,
- params->depth.level,
- params->depth.layer,
- NULL,
- &tile_mask_x, &tile_mask_y);
+ const unsigned min_array_element = params->depth.layer;
- /* 3DSTATE_DEPTH_BUFFER */
- {
- uint32_t tile_x = draw_x & tile_mask_x;
- uint32_t tile_y = draw_y & tile_mask_y;
- uint32_t offset =
- intel_region_get_aligned_offset(params->depth.mt->region,
- draw_x & ~tile_mask_x,
- draw_y & ~tile_mask_y, false);
-
- /* According to the Sandy Bridge PRM, volume 2 part 1, pp326-327
- * (3DSTATE_DEPTH_BUFFER dw5), in the documentation for "Depth
- * Coordinate Offset X/Y":
- *
- * "The 3 LSBs of both offsets must be zero to ensure correct
- * alignment"
- *
- * We have no guarantee that tile_x and tile_y are correctly aligned,
- * since they are determined by the mipmap layout, which is only aligned
- * to multiples of 4.
- *
- * So, to avoid hanging the GPU, just smash the low order 3 bits of
- * tile_x and tile_y to 0. This is a temporary workaround until we come
- * up with a better solution.
+ lod = params->depth.level - params->depth.mt->first_level;
+
+ if (params->hiz_op != GEN6_HIZ_OP_NONE && lod == 0) {
+ /* HIZ ops for lod 0 may set the width & height a little
+ * larger to allow the fast depth clear to fit the hardware
+ * alignment requirements. (8x4)
*/
- WARN_ONCE((tile_x & 7) || (tile_y & 7),
- "Depth/stencil buffer needs alignment to 8-pixel boundaries.\n"
- "Truncating offset, bad rendering may occur.\n");
- tile_x &= ~7;
- tile_y &= ~7;
+ surfwidth = params->depth.width;
+ surfheight = params->depth.height;
+ } else {
+ surfwidth = params->depth.mt->logical_width0;
+ surfheight = params->depth.mt->logical_height0;
+ }
- intel_emit_post_sync_nonzero_flush(brw);
- intel_emit_depth_stall_flushes(brw);
+ /* 3DSTATE_DEPTH_BUFFER */
+ {
+ brw_emit_depth_stall_flushes(brw);
BEGIN_BATCH(7);
+ /* 3DSTATE_DEPTH_BUFFER dw0 */
OUT_BATCH(_3DSTATE_DEPTH_BUFFER << 16 | (7 - 2));
- OUT_BATCH((params->depth.mt->region->pitch - 1) |
+
+ /* 3DSTATE_DEPTH_BUFFER dw1 */
+ OUT_BATCH((params->depth.mt->pitch - 1) |
params->depth_format << 18 |
1 << 21 | /* separate stencil enable */
1 << 22 | /* hiz enable */
BRW_TILEWALK_YMAJOR << 26 |
1 << 27 | /* y-tiled */
- BRW_SURFACE_2D << 29);
- OUT_RELOC(params->depth.mt->region->bo,
+ surftype << 29);
+
+ /* 3DSTATE_DEPTH_BUFFER dw2 */
+ OUT_RELOC(params->depth.mt->bo,
I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
- offset);
+ 0);
+
+ /* 3DSTATE_DEPTH_BUFFER dw3 */
OUT_BATCH(BRW_SURFACE_MIPMAPLAYOUT_BELOW << 1 |
- (params->depth.width + tile_x - 1) << 6 |
- (params->depth.height + tile_y - 1) << 19);
+ (surfwidth - 1) << 6 |
+ (surfheight - 1) << 19 |
+ lod << 2);
+
+ /* 3DSTATE_DEPTH_BUFFER dw4 */
+ OUT_BATCH((depth - 1) << 21 |
+ min_array_element << 10 |
+ (depth - 1) << 1);
+
+ /* 3DSTATE_DEPTH_BUFFER dw5 */
OUT_BATCH(0);
- OUT_BATCH(tile_x |
- tile_y << 16);
+
+ /* 3DSTATE_DEPTH_BUFFER dw6 */
OUT_BATCH(0);
ADVANCE_BATCH();
}
/* 3DSTATE_HIER_DEPTH_BUFFER */
{
- struct intel_region *hiz_region = params->depth.mt->hiz_mt->region;
- uint32_t hiz_offset =
- intel_region_get_aligned_offset(hiz_region,
- draw_x & ~tile_mask_x,
- (draw_y & ~tile_mask_y) / 2, false);
+ struct intel_mipmap_tree *hiz_mt = params->depth.mt->hiz_buf->mt;
+ uint32_t offset = 0;
+
+ if (hiz_mt->array_layout == ALL_SLICES_AT_EACH_LOD) {
+ offset = intel_miptree_get_aligned_offset(hiz_mt,
+ hiz_mt->level[lod].level_x,
+ hiz_mt->level[lod].level_y,
+ false);
+ }
BEGIN_BATCH(3);
OUT_BATCH((_3DSTATE_HIER_DEPTH_BUFFER << 16) | (3 - 2));
- OUT_BATCH(hiz_region->pitch - 1);
- OUT_RELOC(hiz_region->bo,
+ OUT_BATCH(hiz_mt->pitch - 1);
+ OUT_RELOC(hiz_mt->bo,
I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
- hiz_offset);
+ offset);
ADVANCE_BATCH();
}
gen6_blorp_emit_depth_disable(struct brw_context *brw,
const brw_blorp_params *params)
{
- intel_emit_post_sync_nonzero_flush(brw);
- intel_emit_depth_stall_flushes(brw);
+ brw_emit_depth_stall_flushes(brw);
BEGIN_BATCH(7);
OUT_BATCH(_3DSTATE_DEPTH_BUFFER << 16 | (7 - 2));
gen6_blorp_emit_drawing_rectangle(struct brw_context *brw,
const brw_blorp_params *params)
{
- if (brw->gen == 6)
- intel_emit_post_sync_nonzero_flush(brw);
-
BEGIN_BATCH(4);
OUT_BATCH(_3DSTATE_DRAWING_RECTANGLE << 16 | (4 - 2));
OUT_BATCH(0);
- OUT_BATCH(((params->x1 - 1) & 0xffff) |
- ((params->y1 - 1) << 16));
+ OUT_BATCH(((MAX2(params->x1, params->x0) - 1) & 0xffff) |
+ ((MAX2(params->y1, params->y0) - 1) << 16));
OUT_BATCH(0);
ADVANCE_BATCH();
}
GEN4_3DPRIM_VERTEXBUFFER_ACCESS_SEQUENTIAL);
OUT_BATCH(3); /* vertex count per instance */
OUT_BATCH(0);
- OUT_BATCH(1); /* instance count */
+ OUT_BATCH(params->num_layers); /* instance count */
OUT_BATCH(0);
OUT_BATCH(0);
ADVANCE_BATCH();
-
- /* Only used on Sandybridge; harmless to set elsewhere. */
- brw->batch.need_workaround_flush = true;
}
/**
uint32_t prog_offset = params->get_wm_prog(brw, &prog_data);
/* Emit workaround flushes when we switch from drawing to blorping. */
- brw->batch.need_workaround_flush = true;
+ brw_emit_post_sync_nonzero_flush(brw);
gen6_emit_3dstate_multisample(brw, params->dst.num_samples);
gen6_emit_3dstate_sample_mask(brw,
gen6_blorp_emit_urb_config(brw, params);
if (params->use_wm_prog) {
cc_blend_state_offset = gen6_blorp_emit_blend_state(brw, params);
- cc_state_offset = gen6_blorp_emit_cc_state(brw, params);
+ cc_state_offset = gen6_blorp_emit_cc_state(brw);
}
depthstencil_offset = gen6_blorp_emit_depth_stencil_state(brw, params);
gen6_blorp_emit_cc_state_pointers(brw, params, cc_blend_state_offset,
if (params->use_wm_prog) {
uint32_t wm_surf_offset_renderbuffer;
uint32_t wm_surf_offset_texture = 0;
- uint32_t sampler_offset;
wm_push_const_offset = gen6_blorp_emit_wm_constants(brw, params);
intel_miptree_used_for_rendering(params->dst.mt);
wm_surf_offset_renderbuffer =
I915_GEM_DOMAIN_SAMPLER, 0);
}
wm_bind_bo_offset =
- gen6_blorp_emit_binding_table(brw, params,
+ gen6_blorp_emit_binding_table(brw,
wm_surf_offset_renderbuffer,
wm_surf_offset_texture);
- sampler_offset = gen6_blorp_emit_sampler_state(brw, params);
- gen6_blorp_emit_sampler_state_pointers(brw, params, sampler_offset);
+ }
+
+ if (params->src.mt) {
+ const uint32_t sampler_offset =
+ gen6_blorp_emit_sampler_state(brw, BRW_MAPFILTER_LINEAR, 0, true);
+ gen6_blorp_emit_sampler_state_pointers(brw, sampler_offset);
}
gen6_blorp_emit_vs_disable(brw, params);
gen6_blorp_emit_gs_disable(brw, params);
- gen6_blorp_emit_clip_disable(brw, params);
+ gen6_blorp_emit_clip_disable(brw);
gen6_blorp_emit_sf_config(brw, params);
if (params->use_wm_prog)
gen6_blorp_emit_constant_ps(brw, params, wm_push_const_offset);
gen6_blorp_emit_constant_ps_disable(brw, params);
gen6_blorp_emit_wm_config(brw, params, prog_offset, prog_data);
if (params->use_wm_prog)
- gen6_blorp_emit_binding_table_pointers(brw, params, wm_bind_bo_offset);
+ gen6_blorp_emit_binding_table_pointers(brw, wm_bind_bo_offset);
gen6_blorp_emit_viewport_state(brw, params);
if (params->depth.mt)