static bool surface_validate_gen6_buffer(const struct ilo_dev *dev, const struct ilo_state_surface_buffer_info *info) { uint32_t alignment; ILO_DEV_ASSERT(dev, 6, 8); if (info->offset + info->size > info->vma->vm_size) { ilo_warn("invalid buffer range\n"); return false; } /* * From the Sandy Bridge PRM, volume 4 part 1, page 81: * * "For surfaces of type SURFTYPE_BUFFER: [0,2047] -> [1B, 2048B] * For surfaces of type SURFTYPE_STRBUF: [0,2047] -> [1B, 2048B]" */ if (!info->struct_size || info->struct_size > 2048) { ilo_warn("invalid buffer struct size\n"); return false; } alignment = surface_get_gen6_buffer_offset_alignment(dev, info); if (info->offset % alignment || info->vma->vm_alignment % alignment) { ilo_warn("bad buffer offset\n"); return false; } /* no STRBUF on Gen6 */ if (info->format == GEN6_FORMAT_RAW && info->struct_size > 1) assert(ilo_dev_gen(dev) >= ILO_GEN(7)); /* SVB writes are Gen6 only */ if (info->access == ILO_STATE_SURFACE_ACCESS_DP_SVB) assert(ilo_dev_gen(dev) == ILO_GEN(6)); /* * From the Ivy Bridge PRM, volume 4 part 1, page 83: * * "NOTE: "RAW" is supported only with buffers and structured buffers * accessed via the untyped surface read/write and untyped atomic * operation messages, which do not have a column in the table." * * From the Ivy Bridge PRM, volume 4 part 1, page 252: * * "For untyped messages, the Surface Format must be RAW and the * Surface Type must be SURFTYPE_BUFFER or SURFTYPE_STRBUF." */ assert((info->access == ILO_STATE_SURFACE_ACCESS_DP_UNTYPED) == (info->format == GEN6_FORMAT_RAW)); return true; }
struct ilo_render * ilo_render_create(struct ilo_builder *builder) { struct ilo_render *render; render = CALLOC_STRUCT(ilo_render); if (!render) return NULL; render->dev = builder->dev; render->builder = builder; render->workaround_bo = intel_winsys_alloc_bo(builder->winsys, "PIPE_CONTROL workaround", 4096, false); if (!render->workaround_bo) { ilo_warn("failed to allocate PIPE_CONTROL workaround bo\n"); FREE(render); return NULL; } ilo_state_sample_pattern_init_default(&render->sample_pattern, render->dev); ilo_render_invalidate_hw(render); ilo_render_invalidate_builder(render); return render; }
struct ilo_3d_pipeline * ilo_3d_pipeline_create(struct ilo_cp *cp, const struct ilo_dev_info *dev) { struct ilo_3d_pipeline *p; int i; p = CALLOC_STRUCT(ilo_3d_pipeline); if (!p) return NULL; p->cp = cp; p->dev = dev; switch (p->dev->gen) { case ILO_GEN(6): ilo_3d_pipeline_init_gen6(p); break; case ILO_GEN(7): case ILO_GEN(7.5): ilo_3d_pipeline_init_gen7(p); break; default: assert(!"unsupported GEN"); FREE(p); return NULL; break; } p->invalidate_flags = ILO_3D_PIPELINE_INVALIDATE_ALL; p->workaround_bo = intel_winsys_alloc_buffer(p->cp->winsys, "PIPE_CONTROL workaround", 4096, false); if (!p->workaround_bo) { ilo_warn("failed to allocate PIPE_CONTROL workaround bo\n"); FREE(p); return NULL; } p->packed_sample_position_1x = sample_position_1x[0].x << 4 | sample_position_1x[0].y; /* pack into dwords */ for (i = 0; i < 4; i++) { p->packed_sample_position_4x |= sample_position_4x[i].x << (8 * i + 4) | sample_position_4x[i].y << (8 * i); p->packed_sample_position_8x[0] |= sample_position_8x[i].x << (8 * i + 4) | sample_position_8x[i].y << (8 * i); p->packed_sample_position_8x[1] |= sample_position_8x[4 + i].x << (8 * i + 4) | sample_position_8x[4 + i].y << (8 * i); } return p; }
static bool surface_get_gen6_buffer_struct_count(const struct ilo_dev *dev, const struct ilo_state_surface_buffer_info *info, uint32_t *count) { uint32_t max_struct, c; ILO_DEV_ASSERT(dev, 6, 8); c = info->size / info->struct_size; if (info->format_size < info->size - info->struct_size * c) c++; /* * From the Sandy Bridge PRM, volume 4 part 1, page 77: * * "For buffer surfaces, the number of entries in the buffer ranges * from 1 to 2^27." * * From the Ivy Bridge PRM, volume 4 part 1, page 68: * * "For typed buffer and structured buffer surfaces, the number of * entries in the buffer ranges from 1 to 2^27. For raw buffer * surfaces, the number of entries in the buffer is the number of * bytes which can range from 1 to 2^30." * * From the Ivy Bridge PRM, volume 4 part 1, page 69: * * For SURFTYPE_BUFFER: The low two bits of this field (Width) must be * 11 if the Surface Format is RAW (the size of the buffer must be a * multiple of 4 bytes)." */ max_struct = 1 << 27; if (info->format == GEN6_FORMAT_RAW && info->struct_size == 1) { if (ilo_dev_gen(dev) >= ILO_GEN(7)) max_struct = 1 << 30; c &= ~3; } if (!c || c > max_struct) { ilo_warn("too many or zero buffer structs\n"); return false; } *count = c - 1; return true; }
bool ilo_blitter_pipe_blit(struct ilo_blitter *blitter, const struct pipe_blit_info *info) { struct blitter_context *b = blitter->pipe_blitter; struct pipe_blit_info skip_stencil; if (util_try_blit_via_copy_region(&blitter->ilo->base, info)) return true; if (!util_blitter_is_blit_supported(b, info)) { /* try without stencil */ if (info->mask & PIPE_MASK_S) { skip_stencil = *info; skip_stencil.mask = info->mask & ~PIPE_MASK_S; if (util_blitter_is_blit_supported(blitter->pipe_blitter, &skip_stencil)) { ilo_warn("ignore stencil buffer blitting\n"); info = &skip_stencil; } } if (info != &skip_stencil) { ilo_warn("failed to blit with pipe blitter\n"); return false; } } ilo_blitter_pipe_begin(blitter, ILO_BLITTER_PIPE_BLIT, info->scissor_enable); util_blitter_blit(b, info); ilo_blitter_pipe_end(blitter); return true; }
static struct pipe_sampler_view * ilo_create_sampler_view(struct pipe_context *pipe, struct pipe_resource *res, const struct pipe_sampler_view *templ) { const struct ilo_dev_info *dev = ilo_context(pipe)->dev; struct ilo_view_cso *view; view = MALLOC_STRUCT(ilo_view_cso); assert(view); view->base = *templ; pipe_reference_init(&view->base.reference, 1); view->base.texture = NULL; pipe_resource_reference(&view->base.texture, res); view->base.context = pipe; if (res->target == PIPE_BUFFER) { const unsigned elem_size = util_format_get_blocksize(templ->format); const unsigned first_elem = templ->u.buf.first_element; const unsigned num_elems = templ->u.buf.last_element - first_elem + 1; ilo_gpe_init_view_surface_for_buffer(dev, ilo_buffer(res), first_elem * elem_size, num_elems * elem_size, elem_size, templ->format, false, false, &view->surface); } else { struct ilo_texture *tex = ilo_texture(res); /* warn about degraded performance because of a missing binding flag */ if (tex->layout.tiling == INTEL_TILING_NONE && !(tex->base.bind & PIPE_BIND_SAMPLER_VIEW)) { ilo_warn("creating sampler view for a resource " "not created for sampling\n"); } ilo_gpe_init_view_surface_for_texture(dev, tex, templ->format, templ->u.tex.first_level, templ->u.tex.last_level - templ->u.tex.first_level + 1, templ->u.tex.first_layer, templ->u.tex.last_layer - templ->u.tex.first_layer + 1, false, &view->surface); } return &view->base; }
static void gen6_emit_launch_grid_surface_global(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_global_binding_cso *bindings = util_dynarray_begin(&vec->global_binding.bindings); 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_CS_SURFACE_GLOBAL_BASE); count = ilo_shader_get_kernel_param(cs, ILO_KERNEL_CS_SURFACE_GLOBAL_COUNT); if (!count) return; if (base + count > Elements(r->state.cs.SURFACE_STATE)) { ilo_warn("too many global bindings\n"); count = Elements(r->state.cs.SURFACE_STATE) - base; } /* SURFACE_STATEs for global bindings */ surface_state += base; for (i = 0; i < count; i++) { if (i < vec->global_binding.count && bindings[i].resource) { const struct ilo_buffer *buf = ilo_buffer(bindings[i].resource); struct ilo_view_surface view; assert(bindings[i].resource->target == PIPE_BUFFER); ilo_gpe_init_view_surface_for_buffer(r->dev, buf, 0, buf->bo_size, 1, PIPE_FORMAT_NONE, true, true, &view); surface_state[i] = gen6_SURFACE_STATE(r->builder, &view, true); } else { surface_state[i] = 0; } } }
/* note that this may force the texture to be linear */ static void layout_calculate_bo_size(struct ilo_layout *layout, struct ilo_layout_params *params) { assert(params->max_x % layout->block_width == 0); assert(params->max_y % layout->block_height == 0); assert(layout->layer_height % layout->block_height == 0); layout->bo_stride = (params->max_x / layout->block_width) * layout->block_size; layout->bo_height = params->max_y / layout->block_height; while (true) { unsigned w = layout->bo_stride, h = layout->bo_height; unsigned align_w, align_h; /* * From the Haswell PRM, volume 5, page 163: * * "For linear surfaces, additional padding of 64 bytes is required * at the bottom of the surface. This is in addition to the padding * required above." */ if (ilo_dev_gen(params->dev) >= ILO_GEN(7.5) && (params->templ->bind & PIPE_BIND_SAMPLER_VIEW) && layout->tiling == INTEL_TILING_NONE) { layout->bo_height += (64 + layout->bo_stride - 1) / layout->bo_stride; } /* * From the Sandy Bridge PRM, volume 4 part 1, page 81: * * "- For linear render target surfaces, the pitch must be a * multiple of the element size for non-YUV surface formats. * Pitch must be a multiple of 2 * element size for YUV surface * formats. * - For other linear surfaces, the pitch can be any multiple of * bytes. * - For tiled surfaces, the pitch must be a multiple of the tile * width." * * Different requirements may exist when the bo is used in different * places, but our alignments here should be good enough that we do not * need to check layout->templ->bind. */ switch (layout->tiling) { case INTEL_TILING_X: align_w = 512; align_h = 8; break; case INTEL_TILING_Y: align_w = 128; align_h = 32; break; default: if (layout->format == PIPE_FORMAT_S8_UINT) { /* * From the Sandy Bridge PRM, volume 1 part 2, page 22: * * "A 4KB tile is subdivided into 8-high by 8-wide array of * Blocks for W-Major Tiles (W Tiles). Each Block is 8 rows by 8 * bytes." * * Since we asked for INTEL_TILING_NONE instead of the non-existent * INTEL_TILING_W, we want to align to W tiles here. */ align_w = 64; align_h = 64; } else { /* some good enough values */ align_w = 64; align_h = 2; } break; } w = align(w, align_w); h = align(h, align_h); /* make sure the bo is mappable */ if (layout->tiling != INTEL_TILING_NONE) { /* * Usually only the first 256MB of the GTT is mappable. * * See also how intel_context::max_gtt_map_object_size is calculated. */ const size_t mappable_gtt_size = 256 * 1024 * 1024; /* * Be conservative. We may be able to switch from VALIGN_4 to * VALIGN_2 if the layout was Y-tiled, but let's keep it simple. */ if (mappable_gtt_size / w / 4 < h) { if (layout->valid_tilings & LAYOUT_TILING_NONE) { layout->tiling = INTEL_TILING_NONE; /* MCS support for non-MSRTs is limited to tiled RTs */ if (layout->aux == ILO_LAYOUT_AUX_MCS && params->templ->nr_samples <= 1) layout->aux = ILO_LAYOUT_AUX_NONE; continue; } else { ilo_warn("cannot force texture to be linear\n"); } } } layout->bo_stride = w; layout->bo_height = h; break; } }
static bool surface_get_gen6_image_levels(const struct ilo_dev *dev, const struct ilo_state_surface_image_info *info, uint8_t *min_lod, uint8_t *mip_count) { uint8_t max_level = (ilo_dev_gen(dev) >= ILO_GEN(7)) ? 15 : 14; ILO_DEV_ASSERT(dev, 6, 8); assert(info->img->level_count <= max_level); max_level = info->img->level_count; if (!info->level_count || info->level_base + info->level_count > max_level) { ilo_warn("invalid level range\n"); return false; } /* * From the Sandy Bridge PRM, volume 4 part 1, page 79: * * "For Sampling Engine Surfaces: * This field (MIP Count / LOD) indicates the number of MIP levels * allowed to be accessed starting at Surface Min LOD, which must be * less than or equal to the number of MIP levels actually stored in * memory for this surface. * * Force the mip map access to be between the mipmap specified by the * integer bits of the Min LOD and the ceiling of the value specified * here. * * For Render Target Surfaces: * This field defines the MIP level that is currently being rendered * into. This is the absolute MIP level on the surface and is not * relative to the Surface Min LOD field, which is ignored for render * target surfaces. * * For Other Surfaces: * This field is reserved : MBZ" * * From the Sandy Bridge PRM, volume 4 part 1, page 83: * * "For Sampling Engine Surfaces: * * This field (Surface Min LOD) indicates the most detailed LOD that * can be accessed as part of this surface. This field is added to * the delivered LOD (sample_l, ld, or resinfo message types) before * it is used to address the surface. * * For Other Surfaces: * This field is ignored." * * On Gen7+, typed sufaces are treated like sampling engine surfaces. */ if (info->access == ILO_STATE_SURFACE_ACCESS_DP_RENDER) { assert(info->level_count == 1); *min_lod = 0; *mip_count = info->level_base; } else { *min_lod = info->level_base; *mip_count = info->level_count - 1; } return true; }
static bool surface_get_gen6_image_slices(const struct ilo_dev *dev, const struct ilo_state_surface_image_info *info, uint16_t *depth, uint16_t *min_array_elem, uint16_t *rt_view_extent) { uint16_t max_slice, d; ILO_DEV_ASSERT(dev, 6, 8); /* * From the Ivy Bridge PRM, volume 4 part 1, page 63: * * "If this field (Surface Array) is enabled, the Surface Type must be * SURFTYPE_1D, SURFTYPE_2D, or SURFTYPE_CUBE. If this field is * disabled and Surface Type is SURFTYPE_1D, SURFTYPE_2D, or * SURFTYPE_CUBE, the Depth field must be set to zero." * * From the Ivy Bridge PRM, volume 4 part 1, page 69: * * "This field (Depth) specifies the total number of levels for a * volume texture or the number of array elements allowed to be * accessed starting at the Minimum Array Element for arrayed * surfaces. If the volume texture is MIP-mapped, this field * specifies the depth of the base MIP level." * * "For SURFTYPE_CUBE:For Sampling Engine Surfaces, the range of this * field is [0,340], indicating the number of cube array elements * (equal to the number of underlying 2D array elements divided by 6). * For other surfaces, this field must be zero." * * "Errata: For SURFTYPE_CUBE sampling engine surfaces, the range of * this field is limited to [0,85]. * * Errata: If Surface Array is enabled, and Depth is between 1024 and * 2047, an incorrect array slice may be accessed if the requested * array index in the message is greater than or equal to 4096." * * The errata are for Gen7-specific, and they limit the number of useable * layers to (86 * 6), about 512. */ switch (info->type) { case GEN6_SURFTYPE_1D: case GEN6_SURFTYPE_2D: case GEN6_SURFTYPE_CUBE: max_slice = (ilo_dev_gen(dev) >= ILO_GEN(7.5)) ? 2048 : 512; assert(info->img->array_size <= max_slice); max_slice = info->img->array_size; d = info->slice_count; if (info->type == GEN6_SURFTYPE_CUBE) { if (info->access == ILO_STATE_SURFACE_ACCESS_SAMPLER) { if (!d || d % 6) { ilo_warn("invalid cube slice count\n"); return false; } if (ilo_dev_gen(dev) == ILO_GEN(7) && d > 86 * 6) { ilo_warn("cube slice count exceeds Gen7 limit\n"); return false; } } else { /* * Minumum Array Element and Depth must be 0; Render Target View * Extent is ignored. */ if (info->slice_base || d != 6) { ilo_warn("no cube RT array support in data port\n"); return false; } } d /= 6; } if (!info->is_array && d > 1) { ilo_warn("non-array surface with non-zero depth\n"); return false; } break; case GEN6_SURFTYPE_3D: max_slice = 2048; assert(info->img->depth0 <= max_slice); max_slice = u_minify(info->img->depth0, info->level_base); d = info->img->depth0; if (info->is_array) { ilo_warn("3D surfaces cannot be arrays\n"); return false; } break; default: assert(!"invalid surface type"); return false; break; } if (!info->slice_count || info->slice_base + info->slice_count > max_slice) { ilo_warn("invalid slice range\n"); return false; } assert(d); *depth = d - 1; /* * From the Sandy Bridge PRM, volume 4 part 1, page 84: * * "For Sampling Engine and Render Target 1D and 2D Surfaces: * This field (Minimum Array Element) indicates the minimum array * element that can be accessed as part of this surface. This field * is added to the delivered array index before it is used to address * the surface. * * For Render Target 3D Surfaces: * This field indicates the minimum `R' coordinate on the LOD * currently being rendered to. This field is added to the delivered * array index before it is used to address the surface. * * For Sampling Engine Cube Surfaces on [DevSNB+] only: * This field indicates the minimum array element in the underlying 2D * surface array that can be accessed as part of this surface (the * cube array index is multipled by 6 to compute this value, although * this field is not restricted to only multiples of 6). This field is * added to the delivered array index before it is used to address the * surface. * * For Other Surfaces: * This field must be set to zero." * * On Gen7+, typed sufaces are treated like sampling engine 1D and 2D * surfaces. */ *min_array_elem = info->slice_base; /* * From the Sandy Bridge PRM, volume 4 part 1, page 84: * * "For Render Target 3D Surfaces: * This field (Render Target View Extent) indicates the extent of the * accessible `R' coordinates minus 1 on the LOD currently being * rendered to. * * For Render Target 1D and 2D Surfaces: * This field must be set to the same value as the Depth field. * * For Other Surfaces: * This field is ignored." */ *rt_view_extent = info->slice_count - 1; return true; }
static bool surface_validate_gen6_image(const struct ilo_dev *dev, const struct ilo_state_surface_image_info *info) { ILO_DEV_ASSERT(dev, 6, 8); switch (info->access) { case ILO_STATE_SURFACE_ACCESS_SAMPLER: case ILO_STATE_SURFACE_ACCESS_DP_RENDER: break; case ILO_STATE_SURFACE_ACCESS_DP_TYPED: assert(ilo_dev_gen(dev) >= ILO_GEN(7)); break; default: assert(!"unsupported surface access"); break; } assert(info->img && info->vma); if (info->img->tiling != GEN6_TILING_NONE) assert(info->vma->vm_alignment % 4096 == 0); if (info->aux_vma) { assert(ilo_image_can_enable_aux(info->img, info->level_base)); /* always tiled */ assert(info->aux_vma->vm_alignment % 4096 == 0); } /* * From the Sandy Bridge PRM, volume 4 part 1, page 78: * * "For surface types other than SURFTYPE_BUFFER, the Width specified * by this field must be less than or equal to the surface pitch * (specified in bytes via the Surface Pitch field)." */ assert(info->img->bo_stride && info->img->bo_stride <= 512 * 1024 && info->img->width0 <= info->img->bo_stride); if (info->type != info->img->type) { assert(info->type == GEN6_SURFTYPE_2D && info->img->type == GEN6_SURFTYPE_CUBE); } /* * From the Sandy Bridge PRM, volume 4 part 1, page 78: * * "For cube maps, Width must be set equal to the Height." */ if (info->type == GEN6_SURFTYPE_CUBE) assert(info->img->width0 == info->img->height0); /* * From the Sandy Bridge PRM, volume 4 part 1, page 72: * * "Tile Walk TILEWALK_YMAJOR is UNDEFINED for render target formats * that have 128 bits-per-element (BPE)." * * "If Number of Multisamples is set to a value other than * MULTISAMPLECOUNT_1, this field cannot be set to the following * formats: * * - any format with greater than 64 bits per element * - any compressed texture format (BC*) * - any YCRCB* format" * * From the Ivy Bridge PRM, volume 4 part 1, page 63: * * If Number of Multisamples is set to a value other than * MULTISAMPLECOUNT_1, this field cannot be set to the following * formats: any format with greater than 64 bits per element, if * Number of Multisamples is MULTISAMPLECOUNT_8, any compressed * texture format (BC*), and any YCRCB* format. * * TODO */ if (ilo_dev_gen(dev) < ILO_GEN(8) && info->img->tiling == GEN8_TILING_W) { ilo_warn("tiling W is not supported\n"); return false; } return true; }
/** * Initialize the \p dev from \p winsys. */ bool ilo_dev_init(struct ilo_dev *dev, struct intel_winsys *winsys) { const struct intel_winsys_info *info; assert(ilo_is_zeroed(dev, sizeof(*dev))); info = intel_winsys_get_info(winsys); dev->winsys = winsys; dev->devid = info->devid; dev->aperture_total = info->aperture_total; dev->aperture_mappable = info->aperture_mappable; dev->has_llc = info->has_llc; dev->has_address_swizzling = info->has_address_swizzling; dev->has_logical_context = info->has_logical_context; dev->has_ppgtt = info->has_ppgtt; dev->has_timestamp = info->has_timestamp; dev->has_gen7_sol_reset = info->has_gen7_sol_reset; if (!dev->has_logical_context) { ilo_err("missing hardware logical context support\n"); return false; } /* * PIPE_CONTROL and MI_* use PPGTT writes on GEN7+ and privileged GGTT * writes on GEN6. * * From the Sandy Bridge PRM, volume 1 part 3, page 101: * * "[DevSNB] When Per-Process GTT Enable is set, it is assumed that all * code is in a secure environment, independent of address space. * Under this condition, this bit only specifies the address space * (GGTT or PPGTT). All commands are executed "as-is"" * * We need PPGTT to be enabled on GEN6 too. */ if (!dev->has_ppgtt) { /* experiments show that it does not really matter... */ ilo_warn("PPGTT disabled\n"); } if (gen_is_bdw(info->devid) || gen_is_chv(info->devid)) { dev->gen_opaque = ILO_GEN(8); dev->gt = (gen_is_bdw(info->devid)) ? gen_get_bdw_gt(info->devid) : 1; /* XXX random values */ if (dev->gt == 3) { dev->eu_count = 48; dev->thread_count = 336; dev->urb_size = 384 * 1024; } else if (dev->gt == 2) { dev->eu_count = 24; dev->thread_count = 168; dev->urb_size = 384 * 1024; } else { dev->eu_count = 12; dev->thread_count = 84; dev->urb_size = 192 * 1024; } } else if (gen_is_hsw(info->devid)) { /* * From the Haswell PRM, volume 4, page 8: * * "Description GT3 GT2 GT1.5 GT1 * (...) * EUs (Total) 40 20 12 10 * Threads (Total) 280 140 84 70 * (...) * URB Size (max, within L3$) 512KB 256KB 256KB 128KB */ dev->gen_opaque = ILO_GEN(7.5); dev->gt = gen_get_hsw_gt(info->devid); if (dev->gt == 3) { dev->eu_count = 40; dev->thread_count = 280; dev->urb_size = 512 * 1024; } else if (dev->gt == 2) { dev->eu_count = 20; dev->thread_count = 140; dev->urb_size = 256 * 1024; } else { dev->eu_count = 10; dev->thread_count = 70; dev->urb_size = 128 * 1024; } } else if (gen_is_ivb(info->devid) || gen_is_vlv(info->devid)) { /* * From the Ivy Bridge PRM, volume 1 part 1, page 18: * * "Device # of EUs #Threads/EU * Ivy Bridge (GT2) 16 8 * Ivy Bridge (GT1) 6 6" * * From the Ivy Bridge PRM, volume 4 part 2, page 17: * * "URB Size URB Rows URB Rows when SLM Enabled * 128k 4096 2048 * 256k 8096 4096" */ dev->gen_opaque = ILO_GEN(7); dev->gt = (gen_is_ivb(info->devid)) ? gen_get_ivb_gt(info->devid) : 1; if (dev->gt == 2) { dev->eu_count = 16; dev->thread_count = 128; dev->urb_size = 256 * 1024; } else { dev->eu_count = 6; dev->thread_count = 36; dev->urb_size = 128 * 1024; } } else if (gen_is_snb(info->devid)) { /* * From the Sandy Bridge PRM, volume 1 part 1, page 22: * * "Device # of EUs #Threads/EU * SNB GT2 12 5 * SNB GT1 6 4" * * From the Sandy Bridge PRM, volume 4 part 2, page 18: * * "[DevSNB]: The GT1 product's URB provides 32KB of storage, * arranged as 1024 256-bit rows. The GT2 product's URB provides * 64KB of storage, arranged as 2048 256-bit rows. A row * corresponds in size to an EU GRF register. Read/write access to * the URB is generally supported on a row-granular basis." */ dev->gen_opaque = ILO_GEN(6); dev->gt = gen_get_snb_gt(info->devid); if (dev->gt == 2) { dev->eu_count = 12; dev->thread_count = 60; dev->urb_size = 64 * 1024; } else { dev->eu_count = 6; dev->thread_count = 24; dev->urb_size = 32 * 1024; } } else { ilo_err("unknown GPU generation\n"); return false; } return true; }