static bool raster_set_gen8_3DSTATE_MULTISAMPLE(struct ilo_state_raster *rs, const struct ilo_dev *dev, const struct ilo_state_raster_info *info) { const struct ilo_state_raster_setup_info *setup = &info->setup; const struct ilo_state_raster_scan_info *scan = &info->scan; const enum gen_sample_count count = get_gen6_sample_count(dev, scan->sample_count); uint32_t dw1; ILO_DEV_ASSERT(dev, 6, 8); /* * From the Sandy Bridge PRM, volume 2 part 1, page 307: * * "Setting Multisample Rasterization Mode to MSRASTMODE_xxx_PATTERN * when Number of Multisamples == NUMSAMPLES_1 is UNDEFINED." */ if (setup->msaa_enable) assert(scan->sample_count > 1); dw1 = scan->pixloc << GEN6_MULTISAMPLE_DW1_PIXEL_LOCATION__SHIFT | count << GEN6_MULTISAMPLE_DW1_NUM_SAMPLES__SHIFT; STATIC_ASSERT(ARRAY_SIZE(rs->sample) >= 1); rs->sample[0] = dw1; return true; }
static bool urb_get_gen6_configuration(const struct ilo_dev *dev, const struct ilo_state_urb_info *info, struct urb_configuration *conf) { ILO_DEV_ASSERT(dev, 6, 8); memset(conf, 0, sizeof(*conf)); if (ilo_dev_gen(dev) >= ILO_GEN(7)) urb_alloc_gen7_pcb(dev, info, conf); urb_alloc_gen6_urb(dev, info, conf); if (ilo_dev_gen(dev) >= ILO_GEN(7)) { if (!urb_init_gen7_vs_entry(dev, info, conf) || !urb_init_gen7_hs_entry(dev, info, conf) || !urb_init_gen7_ds_entry(dev, info, conf) || !urb_init_gen7_gs_entry(dev, info, conf)) return false; } else { if (!urb_init_gen6_vs_entry(dev, info, conf) || !urb_init_gen6_gs_entry(dev, info, conf)) return false; } return true; }
static enum ilo_image_walk_type image_get_gen6_walk(const struct ilo_dev *dev, const struct ilo_image_info *info) { ILO_DEV_ASSERT(dev, 6, 6); /* TODO we want LODs to be page-aligned */ if (info->type == GEN6_SURFTYPE_3D) return ILO_IMAGE_WALK_3D; /* * From the Sandy Bridge PRM, volume 1 part 1, page 115: * * "The separate stencil buffer does not support mip mapping, thus the * storage for LODs other than LOD 0 is not needed. The following * QPitch equation applies only to the separate stencil buffer: * * QPitch = h_0" * * Use ILO_IMAGE_WALK_LOD and manually offset to the (page-aligned) levels * when bound. */ if (info->bind_zs && info->format == GEN6_FORMAT_R8_UINT) return ILO_IMAGE_WALK_LOD; /* compact spacing is not supported otherwise */ return ILO_IMAGE_WALK_LAYER; }
static bool vertex_buffer_set_gen8_vertex_buffer_state(struct ilo_state_vertex_buffer *vb, const struct ilo_dev *dev, const struct ilo_state_vertex_buffer_info *info) { const uint32_t size = vertex_buffer_get_gen6_size(dev, info); uint32_t dw0; ILO_DEV_ASSERT(dev, 6, 8); if (!vertex_buffer_validate_gen6(dev, info)) return false; dw0 = info->stride << GEN6_VB_DW0_PITCH__SHIFT; if (ilo_dev_gen(dev) >= ILO_GEN(7)) dw0 |= GEN7_VB_DW0_ADDR_MODIFIED; if (!info->vma) dw0 |= GEN6_VB_DW0_IS_NULL; STATIC_ASSERT(ARRAY_SIZE(vb->vb) >= 3); vb->vb[0] = dw0; vb->vb[1] = info->offset; if (ilo_dev_gen(dev) >= ILO_GEN(8)) { vb->vb[2] = size; } else { /* address of the last valid byte */ vb->vb[2] = (size) ? info->offset + size - 1 : 0; } vb->vma = info->vma; return true; }
static void gen6_wa_pre_depth(struct ilo_render *r) { ILO_DEV_ASSERT(r->dev, 6, 6); /* * From the Ivy Bridge PRM, volume 2 part 1, page 315: * * "Restriction: Prior to changing Depth/Stencil Buffer state (i.e., * any combination of 3DSTATE_DEPTH_BUFFER, 3DSTATE_CLEAR_PARAMS, * 3DSTATE_STENCIL_BUFFER, 3DSTATE_HIER_DEPTH_BUFFER) SW must first * issue a pipelined depth stall (PIPE_CONTROL with Depth Stall bit * set), followed by a pipelined depth cache flush (PIPE_CONTROL with * Depth Flush Bit set, followed by another pipelined depth stall * (PIPE_CONTROL with Depth Stall Bit set), unless SW can otherwise * guarantee that the pipeline from WM onwards is already flushed * (e.g., via a preceding MI_FLUSH)." * * According to the classic driver, it also applies for GEN6. */ gen6_wa_pre_pipe_control(r, GEN6_PIPE_CONTROL_DEPTH_STALL | GEN6_PIPE_CONTROL_DEPTH_CACHE_FLUSH); gen6_pipe_control(r, GEN6_PIPE_CONTROL_DEPTH_STALL); gen6_pipe_control(r, GEN6_PIPE_CONTROL_DEPTH_CACHE_FLUSH); gen6_pipe_control(r, GEN6_PIPE_CONTROL_DEPTH_STALL); }
void ilo_render_emit_draw(struct ilo_render *render, const struct ilo_state_vector *vec) { struct ilo_render_draw_session session; ILO_DEV_ASSERT(render->dev, 6, 8); draw_session_prepare(render, vec, &session); /* force all states to be uploaded if the state bo changed */ if (render->state_bo_changed) session.pipe_dirty = ILO_DIRTY_ALL; else session.pipe_dirty = vec->dirty; ilo_render_emit_draw_dynamic_states(render, vec, &session); ilo_render_emit_draw_surface_states(render, vec, &session); /* force all commands to be uploaded if the HW context changed */ if (render->hw_ctx_changed) session.pipe_dirty = ILO_DIRTY_ALL; else session.pipe_dirty = vec->dirty; ilo_render_emit_draw_commands(render, vec, &session); draw_session_end(render, vec, &session); }
static bool vf_params_set_gen8_3DSTATE_VF_SGVS(struct ilo_state_vf *vf, const struct ilo_dev *dev, const struct ilo_state_vf_params_info *params) { const uint8_t attr = (params->prepend_zeros) ? 1 : 0; uint32_t dw1; ILO_DEV_ASSERT(dev, 8, 8); dw1 = 0; if (params->prepend_instanceid) { dw1 |= GEN8_SGVS_DW1_IID_ENABLE | 1 << GEN8_SGVS_DW1_IID_VE_COMP__SHIFT | attr << GEN8_SGVS_DW1_IID_VE_INDEX__SHIFT; } if (params->prepend_vertexid) { dw1 |= GEN8_SGVS_DW1_VID_ENABLE | 0 << GEN8_SGVS_DW1_VID_VE_COMP__SHIFT | attr << GEN8_SGVS_DW1_VID_VE_INDEX__SHIFT; } STATIC_ASSERT(ARRAY_SIZE(vf->sgvs) >= 1); vf->sgvs[0] = dw1; return true; }
static void gen6_emit_launch_grid_surface_view(struct ilo_render *r, const struct ilo_state_vector *vec, struct ilo_render_launch_grid_session *session) { const struct ilo_shader_state *cs = vec->cs; const struct ilo_view_state *view = &vec->view[PIPE_SHADER_COMPUTE]; uint32_t *surface_state = r->state.cs.SURFACE_STATE; int base, count, i; ILO_DEV_ASSERT(r->dev, 7, 7.5); base = ilo_shader_get_kernel_param(cs, ILO_KERNEL_SURFACE_TEX_BASE); count = ilo_shader_get_kernel_param(cs, ILO_KERNEL_SURFACE_TEX_COUNT); /* SURFACE_STATEs for sampler views */ surface_state += base; for (i = 0; i < count; i++) { if (i < view->count && view->states[i]) { const struct ilo_view_cso *cso = (const struct ilo_view_cso *) view->states[i]; surface_state[i] = gen6_SURFACE_STATE(r->builder, &cso->surface, false); } else { surface_state[i] = 0; } } }
static void gen6_emit_launch_grid_surface_const(struct ilo_render *r, const struct ilo_state_vector *vec, struct ilo_render_launch_grid_session *session) { const struct ilo_shader_state *cs = vec->cs; uint32_t *surface_state = r->state.cs.SURFACE_STATE; struct ilo_view_surface view; int base, count; ILO_DEV_ASSERT(r->dev, 7, 7.5); base = ilo_shader_get_kernel_param(cs, ILO_KERNEL_SURFACE_CONST_BASE); count = ilo_shader_get_kernel_param(cs, ILO_KERNEL_SURFACE_CONST_COUNT); if (!count) return; ilo_gpe_init_view_surface_for_buffer(r->dev, ilo_buffer(session->input->buffer), session->input->buffer_offset, session->input->buffer_size, 1, PIPE_FORMAT_NONE, false, false, &view); assert(count == 1 && session->input->buffer); surface_state[base] = gen6_SURFACE_STATE(r->builder, &view, false); }
static bool sample_pattern_set_gen8_3DSTATE_SAMPLE_PATTERN(struct ilo_state_sample_pattern *pattern, const struct ilo_dev *dev, const struct ilo_state_sample_pattern_info *info) { ILO_DEV_ASSERT(dev, 6, 8); STATIC_ASSERT(ARRAY_SIZE(pattern->pattern_1x) >= 1); STATIC_ASSERT(ARRAY_SIZE(pattern->pattern_2x) >= 2); STATIC_ASSERT(ARRAY_SIZE(pattern->pattern_4x) >= 4); STATIC_ASSERT(ARRAY_SIZE(pattern->pattern_8x) >= 8); STATIC_ASSERT(ARRAY_SIZE(pattern->pattern_16x) >= 16); return (sample_pattern_get_gen6_packed_offsets(dev, 1, info->pattern_1x, pattern->pattern_1x) && sample_pattern_get_gen6_packed_offsets(dev, 2, info->pattern_2x, pattern->pattern_2x) && sample_pattern_get_gen6_packed_offsets(dev, 4, info->pattern_4x, pattern->pattern_4x) && sample_pattern_get_gen6_packed_offsets(dev, 8, info->pattern_8x, pattern->pattern_8x) && sample_pattern_get_gen6_packed_offsets(dev, 16, info->pattern_16x, pattern->pattern_16x)); }
void ilo_render_emit_draw_surface_states(struct ilo_render *render, const struct ilo_state_vector *vec, struct ilo_render_draw_session *session) { const unsigned surface_used = ilo_builder_surface_used(render->builder); int shader_type; ILO_DEV_ASSERT(render->dev, 6, 7.5); /* * upload all SURAFCE_STATEs together so that we know there are minimal * paddings */ gen6_emit_draw_surface_rt(render, vec, session); if (ilo_dev_gen(render->dev) == ILO_GEN(6)) gen6_emit_draw_surface_so(render, vec, session); for (shader_type = 0; shader_type < PIPE_SHADER_TYPES; shader_type++) { gen6_emit_draw_surface_view(render, vec, shader_type, session); gen6_emit_draw_surface_const(render, vec, shader_type, session); } /* this must be called after all SURFACE_STATEs have been uploaded */ for (shader_type = 0; shader_type < PIPE_SHADER_TYPES; shader_type++) { gen6_emit_draw_surface_binding_tables(render, vec, shader_type, session); } assert(ilo_builder_surface_used(render->builder) <= surface_used + ilo_render_get_draw_surface_states_len(render, vec)); }
static bool line_stipple_set_gen6_3DSTATE_LINE_STIPPLE(struct ilo_state_line_stipple *stipple, const struct ilo_dev *dev, const struct ilo_state_line_stipple_info *info) { uint32_t dw1, dw2; ILO_DEV_ASSERT(dev, 6, 8); assert(info->repeat_count >= 1 && info->repeat_count <= 256); dw1 = info->pattern; if (ilo_dev_gen(dev) >= ILO_GEN(7)) { /* in U1.16 */ const uint32_t inverse = 65536 / info->repeat_count; dw2 = inverse << GEN7_LINE_STIPPLE_DW2_INVERSE_REPEAT_COUNT__SHIFT | info->repeat_count << GEN6_LINE_STIPPLE_DW2_REPEAT_COUNT__SHIFT; } else { /* in U1.13 */ const uint16_t inverse = 8192 / info->repeat_count; dw2 = inverse << GEN6_LINE_STIPPLE_DW2_INVERSE_REPEAT_COUNT__SHIFT | info->repeat_count << GEN6_LINE_STIPPLE_DW2_REPEAT_COUNT__SHIFT; } STATIC_ASSERT(ARRAY_SIZE(stipple->stipple) >= 2); stipple->stipple[0] = dw1; stipple->stipple[1] = dw2; return true; }
static bool raster_set_gen6_3dstate_wm(struct ilo_state_raster *rs, const struct ilo_dev *dev, const struct ilo_state_raster_info *info, const struct ilo_state_raster_line_info *line) { const struct ilo_state_raster_tri_info *tri = &info->tri; const struct ilo_state_raster_setup_info *setup = &info->setup; const struct ilo_state_raster_scan_info *scan = &info->scan; const enum gen_msrast_mode msrast = raster_setup_get_gen6_msrast_mode(dev, setup); /* only scan conversion states are set, as in Gen8+ */ uint32_t dw4, dw5, dw6; ILO_DEV_ASSERT(dev, 6, 6); if (!raster_validate_gen6_wm(dev, info)) return false; dw4 = 0; if (scan->stats_enable) dw4 |= GEN6_WM_DW4_STATISTICS; switch (scan->earlyz_op) { case ILO_STATE_RASTER_EARLYZ_DEPTH_CLEAR: dw4 |= GEN6_WM_DW4_DEPTH_CLEAR; break; case ILO_STATE_RASTER_EARLYZ_DEPTH_RESOLVE: dw4 |= GEN6_WM_DW4_DEPTH_RESOLVE; break; case ILO_STATE_RASTER_EARLYZ_HIZ_RESOLVE: dw4 |= GEN6_WM_DW4_HIZ_RESOLVE; break; default: if (scan->earlyz_stencil_clear) dw4 |= GEN6_WM_DW4_DEPTH_CLEAR; break; } dw5 = GEN6_WM_DW5_AA_LINE_CAP_1_0 | /* same as in 3DSTATE_SF */ GEN6_WM_DW5_AA_LINE_WIDTH_2_0; if (tri->poly_stipple_enable) dw5 |= GEN6_WM_DW5_POLY_STIPPLE_ENABLE; if (line->stipple_enable) dw5 |= GEN6_WM_DW5_LINE_STIPPLE_ENABLE; dw6 = scan->zw_interp << GEN6_WM_DW6_ZW_INTERP__SHIFT | scan->barycentric_interps << GEN6_WM_DW6_BARYCENTRIC_INTERP__SHIFT | GEN6_WM_DW6_POINT_RASTRULE_UPPER_RIGHT | msrast << GEN6_WM_DW6_MSRASTMODE__SHIFT; STATIC_ASSERT(ARRAY_SIZE(rs->wm) >= 3); rs->wm[0] = dw4; rs->wm[1] = dw5; rs->wm[2] = dw6; return true; }
static bool raster_set_gen6_3DSTATE_SAMPLE_MASK(struct ilo_state_raster *rs, const struct ilo_dev *dev, const struct ilo_state_raster_info *info) { const struct ilo_state_raster_scan_info *scan = &info->scan; /* * From the Ivy Bridge PRM, volume 2 part 1, page 294: * * "If Number of Multisamples is NUMSAMPLES_1, bits 7:1 of this field * (Sample Mask) must be zero. * * If Number of Multisamples is NUMSAMPLES_4, bits 7:4 of this field * must be zero." */ const uint32_t mask = (1 << scan->sample_count) - 1; uint32_t dw1; ILO_DEV_ASSERT(dev, 6, 8); dw1 = (scan->sample_mask & mask) << GEN6_SAMPLE_MASK_DW1_VAL__SHIFT; STATIC_ASSERT(ARRAY_SIZE(rs->sample) >= 2); rs->sample[1] = dw1; return true; }
static void gen6_emit_draw_dynamic_cc(struct ilo_render *r, const struct ilo_state_vector *vec, struct ilo_render_draw_session *session) { ILO_DEV_ASSERT(r->dev, 6, 7.5); /* BLEND_STATE */ if (DIRTY(BLEND) || DIRTY(FB) || DIRTY(DSA)) { r->state.BLEND_STATE = gen6_BLEND_STATE(r->builder, vec->blend, &vec->fb, vec->dsa); session->blend_changed = true; } /* COLOR_CALC_STATE */ if (DIRTY(DSA) || DIRTY(STENCIL_REF) || DIRTY(BLEND_COLOR)) { r->state.COLOR_CALC_STATE = gen6_COLOR_CALC_STATE(r->builder, &vec->stencil_ref, vec->dsa->alpha_ref, &vec->blend_color); session->cc_changed = true; } /* DEPTH_STENCIL_STATE */ if (DIRTY(DSA)) { r->state.DEPTH_STENCIL_STATE = gen6_DEPTH_STENCIL_STATE(r->builder, vec->dsa); session->dsa_changed = true; } }
static uint16_t ps_get_gen6_thread_count(const struct ilo_dev *dev, const struct ilo_state_ps_info *info) { uint16_t thread_count; ILO_DEV_ASSERT(dev, 6, 8); /* Maximum Number of Threads of 3DSTATE_PS */ switch (ilo_dev_gen(dev)) { case ILO_GEN(8): /* scaled automatically */ thread_count = 64 - 1; break; case ILO_GEN(7.5): thread_count = (dev->gt == 3) ? 408 : (dev->gt == 2) ? 204 : 102; break; case ILO_GEN(7): thread_count = (dev->gt == 2) ? 172 : 48; break; case ILO_GEN(6): default: /* from the classic driver instead of the PRM */ thread_count = (dev->gt == 2) ? 80 : 40; break; } return thread_count - 1; }
static void surface_get_gen6_image_max_extent(const struct ilo_dev *dev, const struct ilo_state_surface_image_info *info, uint16_t *max_w, uint16_t *max_h) { const uint16_t max_size = (ilo_dev_gen(dev) >= ILO_GEN(7)) ? 16384 : 8192; ILO_DEV_ASSERT(dev, 6, 8); switch (info->type) { case GEN6_SURFTYPE_1D: *max_w = max_size; *max_h = 1; break; case GEN6_SURFTYPE_2D: case GEN6_SURFTYPE_CUBE: *max_w = max_size; *max_h = max_size; break; case GEN6_SURFTYPE_3D: *max_w = 2048; *max_h = 2048; break; default: assert(!"invalid surface type"); *max_w = 1; *max_h = 1; break; } }
static bool ps_params_get_gen6_kill_pixel(const struct ilo_dev *dev, const struct ilo_state_ps_params_info *params, const struct ilo_state_ps_dispatch_conds *conds) { ILO_DEV_ASSERT(dev, 6, 8); /* * From the Sandy Bridge PRM, volume 2 part 1, page 275: * * "This bit (Pixel Shader Kill Pixel), if ENABLED, indicates that the * PS kernel or color calculator has the ability to kill (discard) * pixels or samples, other than due to depth or stencil testing. * This bit is required to be ENABLED in the following situations: * * The API pixel shader program contains "killpix" or "discard" * instructions, or other code in the pixel shader kernel that can * cause the final pixel mask to differ from the pixel mask received * on dispatch. * * A sampler with chroma key enabled with kill pixel mode is used by * the pixel shader. * * Any render target has Alpha Test Enable or AlphaToCoverage Enable * enabled. * * The pixel shader kernel generates and outputs oMask. * * Note: As ClipDistance clipping is fully supported in hardware and * therefore not via PS instructions, there should be no need to * ENABLE this bit due to ClipDistance clipping." */ return (conds->ps_may_kill || params->alpha_may_kill); }
void ilo_render_emit_launch_grid(struct ilo_render *render, const struct ilo_state_vector *vec, const unsigned thread_group_offset[3], const unsigned thread_group_dim[3], unsigned thread_group_size, const struct pipe_constant_buffer *input, uint32_t pc) { struct ilo_render_launch_grid_session session; ILO_DEV_ASSERT(render->dev, 7, 7.5); assert(input->buffer); memset(&session, 0, sizeof(session)); session.thread_group_offset = thread_group_offset; session.thread_group_dim = thread_group_dim; session.thread_group_size = thread_group_size; session.input = input; session.pc = pc; ilo_render_emit_launch_grid_surface_states(render, vec, &session); ilo_render_emit_launch_grid_dynamic_states(render, vec, &session); ilo_render_emit_launch_grid_commands(render, vec, &session); }
static bool ps_set_gen7_3dstate_wm(struct ilo_state_ps *ps, const struct ilo_dev *dev, const struct ilo_state_ps_info *info, const struct pixel_ff *ff) { const struct ilo_state_ps_io_info *io = &info->io; uint32_t dw1, dw2; ILO_DEV_ASSERT(dev, 7, 7.5); dw1 = io->pscdepth << GEN7_WM_DW1_PSCDEPTH__SHIFT; if (ff->dispatch_enable) dw1 |= GEN7_WM_DW1_PS_DISPATCH_ENABLE; if (ff->kill_pixel) dw1 |= GEN7_WM_DW1_PS_KILL_PIXEL; if (io->use_z) dw1 |= GEN7_WM_DW1_PS_USE_DEPTH; if (io->use_w) dw1 |= GEN7_WM_DW1_PS_USE_W; if (io->use_coverage_mask) dw1 |= GEN7_WM_DW1_PS_USE_COVERAGE_MASK; dw2 = (info->per_sample_dispatch) ? GEN7_WM_DW2_MSDISPMODE_PERSAMPLE : GEN7_WM_DW2_MSDISPMODE_PERPIXEL; STATIC_ASSERT(ARRAY_SIZE(ps->ps) >= 2); ps->ps[0] = dw1; ps->ps[1] = dw2; return true; }
static uint32_t vertex_buffer_get_gen6_size(const struct ilo_dev *dev, const struct ilo_state_vertex_buffer_info *info) { ILO_DEV_ASSERT(dev, 6, 8); return (info->vma) ? info->size : 0; }
void ilo_render_emit_draw_dynamic_states(struct ilo_render *render, const struct ilo_state_vector *vec, struct ilo_render_draw_session *session) { const unsigned dynamic_used = ilo_builder_dynamic_used(render->builder); ILO_DEV_ASSERT(render->dev, 6, 7.5); if (ilo_dev_gen(render->dev) >= ILO_GEN(7)) gen7_emit_draw_dynamic_viewports(render, vec, session); else gen6_emit_draw_dynamic_viewports(render, vec, session); gen6_emit_draw_dynamic_cc(render, vec, session); gen6_emit_draw_dynamic_scissors(render, vec, session); gen6_emit_draw_dynamic_pcb(render, vec, session); gen6_emit_draw_dynamic_samplers(render, vec, PIPE_SHADER_VERTEX, session); gen6_emit_draw_dynamic_samplers(render, vec, PIPE_SHADER_FRAGMENT, session); assert(ilo_builder_dynamic_used(render->builder) <= dynamic_used + ilo_render_get_draw_dynamic_states_len(render, vec)); }
static bool index_buffer_set_gen8_3DSTATE_INDEX_BUFFER(struct ilo_state_index_buffer *ib, const struct ilo_dev *dev, const struct ilo_state_index_buffer_info *info) { const uint32_t size = index_buffer_get_gen6_size(dev, info); ILO_DEV_ASSERT(dev, 6, 8); if (!index_buffer_validate_gen6(dev, info)) return false; STATIC_ASSERT(ARRAY_SIZE(ib->ib) >= 3); if (ilo_dev_gen(dev) >= ILO_GEN(8)) { ib->ib[0] = info->format << GEN8_IB_DW1_FORMAT__SHIFT; ib->ib[1] = info->offset; ib->ib[2] = size; } else { ib->ib[0] = info->format << GEN6_IB_DW0_FORMAT__SHIFT; ib->ib[1] = info->offset; /* address of the last valid byte, or 0 */ ib->ib[2] = (size) ? info->offset + size - 1 : 0; } ib->vma = info->vma; return true; }
void ilo_render_emit_rectlist_dynamic_states(struct ilo_render *render, const struct ilo_blitter *blitter, struct ilo_render_rectlist_session *session) { const unsigned dynamic_used = ilo_builder_dynamic_used(render->builder); ILO_DEV_ASSERT(render->dev, 6, 7.5); /* both are inclusive */ session->vb_start = gen6_user_vertex_buffer(render->builder, sizeof(blitter->vertices), (const void *) blitter->vertices); session->vb_end = session->vb_start + sizeof(blitter->vertices) - 1; if (blitter->uses & ILO_BLITTER_USE_DSA) { render->state.DEPTH_STENCIL_STATE = gen6_DEPTH_STENCIL_STATE(render->builder, &blitter->dsa); } if (blitter->uses & ILO_BLITTER_USE_CC) { render->state.COLOR_CALC_STATE = gen6_COLOR_CALC_STATE(render->builder, &blitter->cc.stencil_ref, blitter->cc.alpha_ref, &blitter->cc.blend_color); } if (blitter->uses & ILO_BLITTER_USE_VIEWPORT) { render->state.CC_VIEWPORT = gen6_CC_VIEWPORT(render->builder, &blitter->viewport, 1); } assert(ilo_builder_dynamic_used(render->builder) <= dynamic_used + ilo_render_get_rectlist_dynamic_states_len(render, blitter)); }
void ilo_render_emit_draw_commands_gen6(struct ilo_render *render, const struct ilo_state_vector *vec, struct ilo_render_draw_session *session) { ILO_DEV_ASSERT(render->dev, 6, 6); /* * We try to keep the order of the commands match, as closely as possible, * that of the classic i965 driver. It allows us to compare the command * streams easily. */ gen6_draw_common_select(render, vec, session); gen6_draw_gs_svbi(render, vec, session); gen6_draw_common_sip(render, vec, session); gen6_draw_vf_statistics(render, vec, session); gen6_draw_common_base_address(render, vec, session); gen6_draw_common_pointers_1(render, vec, session); gen6_draw_common_urb(render, vec, session); gen6_draw_common_pointers_2(render, vec, session); gen6_draw_wm_multisample(render, vec, session); gen6_draw_vs(render, vec, session); gen6_draw_gs(render, vec, session); gen6_draw_clip(render, vec, session); gen6_draw_sf(render, vec, session); gen6_draw_wm(render, vec, session); gen6_draw_common_pointers_3(render, vec, session); gen6_draw_wm_depth(render, vec, session); gen6_draw_wm_raster(render, vec, session); gen6_draw_sf_rect(render, vec, session); gen6_draw_vf(render, vec, session); gen6_draw_vf_draw(render, vec, session); }
static void gen6_emit_launch_grid_dynamic_samplers(struct ilo_render *r, const struct ilo_state_vector *vec, struct ilo_render_launch_grid_session *session) { const unsigned shader_type = PIPE_SHADER_COMPUTE; const struct ilo_shader_state *cs = vec->cs; const struct ilo_sampler_cso * const *samplers = vec->sampler[shader_type].cso; const struct pipe_sampler_view * const *views = (const struct pipe_sampler_view **) vec->view[shader_type].states; int sampler_count, i; ILO_DEV_ASSERT(r->dev, 7, 7.5); sampler_count = ilo_shader_get_kernel_param(cs, ILO_KERNEL_SAMPLER_COUNT); assert(sampler_count <= Elements(vec->view[shader_type].states) && sampler_count <= Elements(vec->sampler[shader_type].cso)); for (i = 0; i < sampler_count; i++) { r->state.cs.SAMPLER_BORDER_COLOR_STATE[i] = (samplers[i]) ? gen6_SAMPLER_BORDER_COLOR_STATE(r->builder, samplers[i]) : 0; } r->state.cs.SAMPLER_STATE = gen6_SAMPLER_STATE(r->builder, samplers, views, r->state.cs.SAMPLER_BORDER_COLOR_STATE, sampler_count); }
static bool urb_set_gen7_3dstate_push_constant_alloc(struct ilo_state_urb *urb, const struct ilo_dev *dev, const struct ilo_state_urb_info *info, const struct urb_configuration *conf) { uint32_t dw1[5]; uint8_t sizes_kb[5], offset_kb; int i; ILO_DEV_ASSERT(dev, 7, 8); sizes_kb[0] = conf->vs_pcb_alloc_kb; sizes_kb[1] = conf->hs_pcb_alloc_kb; sizes_kb[2] = conf->ds_pcb_alloc_kb; sizes_kb[3] = conf->gs_pcb_alloc_kb; sizes_kb[4] = conf->ps_pcb_alloc_kb; offset_kb = 0; for (i = 0; i < 5; i++) { /* careful for the valid range of offsets */ if (sizes_kb[i]) { dw1[i] = offset_kb << GEN7_PCB_ALLOC_DW1_OFFSET__SHIFT | sizes_kb[i] << GEN7_PCB_ALLOC_DW1_SIZE__SHIFT; offset_kb += sizes_kb[i]; } else { dw1[i] = 0; } } STATIC_ASSERT(ARRAY_SIZE(urb->pcb) >= 5); memcpy(urb->pcb, dw1, sizeof(dw1)); return true; }
int ilo_render_get_launch_grid_dynamic_states_len(const struct ilo_render *render, const struct ilo_state_vector *vec) { const int alignment = 32 / 4; int num_samplers; int len = 0; ILO_DEV_ASSERT(render->dev, 7, 7.5); num_samplers = ilo_shader_get_kernel_param(vec->cs, ILO_KERNEL_SAMPLER_COUNT); /* SAMPLER_STATE array and SAMPLER_BORDER_COLORs */ if (num_samplers) { /* prefetches are done in multiples of 4 */ num_samplers = align(num_samplers, 4); len += align(GEN6_SAMPLER_STATE__SIZE * num_samplers, alignment) + align(GEN6_SAMPLER_BORDER_COLOR__SIZE, alignment) * num_samplers; } len += GEN6_INTERFACE_DESCRIPTOR_DATA__SIZE; return len; }
static enum ilo_image_walk_type image_get_gen7_walk(const struct ilo_dev *dev, const struct ilo_image_info *info) { ILO_DEV_ASSERT(dev, 7, 8); if (info->type == GEN6_SURFTYPE_3D) return ILO_IMAGE_WALK_3D; /* * From the Ivy Bridge PRM, volume 1 part 1, page 111: * * "note that the depth buffer and stencil buffer have an implied value * of ARYSPC_FULL" * * From the Ivy Bridge PRM, volume 4 part 1, page 66: * * "If Multisampled Surface Storage Format is MSFMT_MSS and Number of * Multisamples is not MULTISAMPLECOUNT_1, this field (Surface Array * Spacing) must be set to ARYSPC_LOD0." */ if (info->sample_count > 1) assert(info->level_count == 1); return (info->bind_zs || info->level_count > 1) ? ILO_IMAGE_WALK_LAYER : ILO_IMAGE_WALK_LOD; }
static enum gen_sample_count get_gen6_sample_count(const struct ilo_dev *dev, uint8_t sample_count) { enum gen_sample_count c; int min_gen; ILO_DEV_ASSERT(dev, 6, 8); switch (sample_count) { case 1: c = GEN6_NUMSAMPLES_1; min_gen = ILO_GEN(6); break; case 2: c = GEN8_NUMSAMPLES_2; min_gen = ILO_GEN(8); break; case 4: c = GEN6_NUMSAMPLES_4; min_gen = ILO_GEN(6); break; case 8: c = GEN7_NUMSAMPLES_8; min_gen = ILO_GEN(7); break; default: assert(!"unexpected sample count"); c = GEN6_NUMSAMPLES_1; break; } assert(ilo_dev_gen(dev) >= min_gen); return c; }