static uint32_t gen8_fill_interface_descriptor(struct intel_batchbuffer *batch, struct igt_buf *dst) { struct gen8_interface_descriptor_data *idd; uint32_t offset; uint32_t binding_table_offset, kernel_offset; binding_table_offset = gen8_fill_binding_table(batch, dst); kernel_offset = gen8_fill_media_kernel(batch, media_kernel, sizeof(media_kernel)); idd = batch_alloc(batch, sizeof(*idd), 64); offset = batch_offset(batch, idd); idd->desc0.kernel_start_pointer = (kernel_offset >> 6); idd->desc2.single_program_flow = 1; idd->desc2.floating_point_mode = GEN8_FLOATING_POINT_IEEE_754; idd->desc3.sampler_count = 0; /* 0 samplers used */ idd->desc3.sampler_state_pointer = 0; idd->desc4.binding_table_entry_count = 0; idd->desc4.binding_table_pointer = (binding_table_offset >> 5); idd->desc5.constant_urb_entry_read_offset = 0; idd->desc5.constant_urb_entry_read_length = 1; /* grf 1 */ return offset; }
static uint32_t gen6_create_cc_viewport(struct intel_batchbuffer *batch) { struct gen6_cc_viewport *vp; vp = batch_alloc(batch, sizeof(*vp), 32); vp->min_depth = -1.e35; vp->max_depth = 1.e35; return batch_offset(batch, vp); }
static uint32_t gen6_create_sampler(struct intel_batchbuffer *batch, sampler_filter_t filter, sampler_extend_t extend) { struct gen6_sampler_state *ss; ss = batch_alloc(batch, sizeof(*ss), 32); ss->ss0.lod_preclamp = 1; /* GL mode */ /* We use the legacy mode to get the semantics specified by * the Render extension. */ ss->ss0.border_color_mode = GEN6_BORDER_COLOR_MODE_LEGACY; switch (filter) { default: case SAMPLER_FILTER_NEAREST: ss->ss0.min_filter = GEN6_MAPFILTER_NEAREST; ss->ss0.mag_filter = GEN6_MAPFILTER_NEAREST; break; case SAMPLER_FILTER_BILINEAR: ss->ss0.min_filter = GEN6_MAPFILTER_LINEAR; ss->ss0.mag_filter = GEN6_MAPFILTER_LINEAR; break; } switch (extend) { default: case SAMPLER_EXTEND_NONE: ss->ss1.r_wrap_mode = GEN6_TEXCOORDMODE_CLAMP_BORDER; ss->ss1.s_wrap_mode = GEN6_TEXCOORDMODE_CLAMP_BORDER; ss->ss1.t_wrap_mode = GEN6_TEXCOORDMODE_CLAMP_BORDER; break; case SAMPLER_EXTEND_REPEAT: ss->ss1.r_wrap_mode = GEN6_TEXCOORDMODE_WRAP; ss->ss1.s_wrap_mode = GEN6_TEXCOORDMODE_WRAP; ss->ss1.t_wrap_mode = GEN6_TEXCOORDMODE_WRAP; break; case SAMPLER_EXTEND_PAD: ss->ss1.r_wrap_mode = GEN6_TEXCOORDMODE_CLAMP; ss->ss1.s_wrap_mode = GEN6_TEXCOORDMODE_CLAMP; ss->ss1.t_wrap_mode = GEN6_TEXCOORDMODE_CLAMP; break; case SAMPLER_EXTEND_REFLECT: ss->ss1.r_wrap_mode = GEN6_TEXCOORDMODE_MIRROR; ss->ss1.s_wrap_mode = GEN6_TEXCOORDMODE_MIRROR; ss->ss1.t_wrap_mode = GEN6_TEXCOORDMODE_MIRROR; break; } return batch_offset(batch, ss); }
static uint32_t gen8_fill_curbe_buffer_data(struct intel_batchbuffer *batch, uint8_t color) { uint8_t *curbe_buffer; uint32_t offset; curbe_buffer = batch_alloc(batch, sizeof(uint32_t) * 8, 64); offset = batch_offset(batch, curbe_buffer); *curbe_buffer = color; return offset; }
static uint32_t gen6_create_scissor_rect(struct intel_batchbuffer *batch) { struct gen6_scissor_rect *scissor; uint32_t offset; scissor = batch_alloc(batch, sizeof(*scissor), 64); offset = batch_offset(batch, scissor); annotation_add_state(&aub_annotations, AUB_TRACE_SCISSOR_STATE, offset, sizeof(*scissor)); return offset; }
static uint32_t gen8_fill_binding_table(struct intel_batchbuffer *batch, struct igt_buf *dst) { uint32_t *binding_table, offset; binding_table = batch_alloc(batch, 32, 64); offset = batch_offset(batch, binding_table); binding_table[0] = gen8_fill_surface_state(batch, dst, GEN8_SURFACEFORMAT_R8_UNORM, 1); return offset; }
static uint32_t gen6_create_cc_state(struct intel_batchbuffer *batch) { struct gen6_color_calc_state *cc_state; uint32_t offset; cc_state = batch_alloc(batch, sizeof(*cc_state), 64); offset = batch_offset(batch, cc_state); annotation_add_state(&aub_annotations, AUB_TRACE_CC_STATE, offset, sizeof(*cc_state)); return offset; }
static uint32_t gen8_fill_surface_state(struct intel_batchbuffer *batch, struct igt_buf *buf, uint32_t format, int is_dst) { struct gen8_surface_state *ss; uint32_t write_domain, read_domain, offset; int ret; if (is_dst) { write_domain = read_domain = I915_GEM_DOMAIN_RENDER; } else { write_domain = 0; read_domain = I915_GEM_DOMAIN_SAMPLER; } ss = batch_alloc(batch, sizeof(*ss), 64); offset = batch_offset(batch, ss); ss->ss0.surface_type = GEN8_SURFACE_2D; ss->ss0.surface_format = format; ss->ss0.render_cache_read_write = 1; ss->ss0.vertical_alignment = 1; /* align 4 */ ss->ss0.horizontal_alignment = 1; /* align 4 */ if (buf->tiling == I915_TILING_X) ss->ss0.tiled_mode = 2; else if (buf->tiling == I915_TILING_Y) ss->ss0.tiled_mode = 3; ss->ss8.base_addr = buf->bo->offset; ret = drm_intel_bo_emit_reloc(batch->bo, batch_offset(batch, ss) + 8 * 4, buf->bo, 0, read_domain, write_domain); assert(ret == 0); ss->ss2.height = igt_buf_height(buf) - 1; ss->ss2.width = igt_buf_width(buf) - 1; ss->ss3.pitch = buf->stride - 1; ss->ss7.shader_chanel_select_r = 4; ss->ss7.shader_chanel_select_g = 5; ss->ss7.shader_chanel_select_b = 6; ss->ss7.shader_chanel_select_a = 7; return offset; }
static uint32_t gen6_bind_surfaces(struct intel_batchbuffer *batch, struct scratch_buf *src, struct scratch_buf *dst) { uint32_t *binding_table; binding_table = batch_alloc(batch, 32, 32); binding_table[0] = gen6_bind_buf(batch, dst, GEN6_SURFACEFORMAT_B8G8R8A8_UNORM, 1); binding_table[1] = gen6_bind_buf(batch, src, GEN6_SURFACEFORMAT_B8G8R8A8_UNORM, 0); return batch_offset(batch, binding_table); }
static uint32_t gen6_create_cc_viewport(struct intel_batchbuffer *batch) { struct gen6_cc_viewport *vp; uint32_t offset; vp = batch_alloc(batch, sizeof(*vp), 32); offset = batch_offset(batch, vp); annotation_add_state(&aub_annotations, AUB_TRACE_CC_VP_STATE, offset, sizeof(*vp)); /* XXX I don't understand this */ vp->min_depth = -1.e35; vp->max_depth = 1.e35; return offset; }
static uint32_t gen6_create_cc_blend(struct intel_batchbuffer *batch) { struct gen6_blend_state *blend; blend = batch_alloc(batch, sizeof(*blend), 64); blend->blend0.dest_blend_factor = GEN6_BLENDFACTOR_ZERO; blend->blend0.source_blend_factor = GEN6_BLENDFACTOR_ONE; blend->blend0.blend_func = GEN6_BLENDFUNCTION_ADD; blend->blend0.blend_enable = 1; blend->blend1.post_blend_clamp_enable = 1; blend->blend1.pre_blend_clamp_enable = 1; return batch_offset(batch, blend); }
static uint32_t gen7_create_sf_clip_viewport(struct intel_batchbuffer *batch) { /* XXX these are likely not needed */ struct gen7_sf_clip_viewport *scv_state; uint32_t offset; scv_state = batch_alloc(batch, sizeof(*scv_state), 64); offset = batch_offset(batch, scv_state); annotation_add_state(&aub_annotations, AUB_TRACE_CLIP_VP_STATE, offset, sizeof(*scv_state)); scv_state->guardband.xmin = 0; scv_state->guardband.xmax = 1.0f; scv_state->guardband.ymin = 0; scv_state->guardband.ymax = 1.0f; return offset; }
static uint32_t gen8_bind_surfaces(struct intel_batchbuffer *batch, struct igt_buf *src, struct igt_buf *dst) { uint32_t *binding_table, offset; binding_table = batch_alloc(batch, 8, 32); offset = batch_offset(batch, binding_table); annotation_add_state(&aub_annotations, AUB_TRACE_BINDING_TABLE, offset, 8); binding_table[0] = gen8_bind_buf(batch, dst, GEN6_SURFACEFORMAT_B8G8R8A8_UNORM, 1); binding_table[1] = gen8_bind_buf(batch, src, GEN6_SURFACEFORMAT_B8G8R8A8_UNORM, 0); return offset; }
static uint32_t gen8_create_blend_state(struct intel_batchbuffer *batch) { struct gen8_blend_state *blend; int i; uint32_t offset; blend = batch_alloc(batch, sizeof(*blend), 64); offset = batch_offset(batch, blend); annotation_add_state(&aub_annotations, AUB_TRACE_BLEND_STATE, offset, sizeof(*blend)); for (i = 0; i < 16; i++) { blend->bs[i].dest_blend_factor = GEN6_BLENDFACTOR_ZERO; blend->bs[i].source_blend_factor = GEN6_BLENDFACTOR_ONE; blend->bs[i].color_blend_func = GEN6_BLENDFUNCTION_ADD; blend->bs[i].pre_blend_color_clamp = 1; blend->bs[i].color_buffer_blend = 0; } return offset; }
/* Mostly copy+paste from gen6, except wrap modes moved */ static uint32_t gen8_create_sampler(struct intel_batchbuffer *batch) { struct gen8_sampler_state *ss; uint32_t offset; ss = batch_alloc(batch, sizeof(*ss), 64); offset = batch_offset(batch, ss); annotation_add_state(&aub_annotations, AUB_TRACE_SAMPLER_STATE, offset, sizeof(*ss)); ss->ss0.min_filter = GEN6_MAPFILTER_NEAREST; ss->ss0.mag_filter = GEN6_MAPFILTER_NEAREST; ss->ss3.r_wrap_mode = GEN6_TEXCOORDMODE_CLAMP; ss->ss3.s_wrap_mode = GEN6_TEXCOORDMODE_CLAMP; ss->ss3.t_wrap_mode = GEN6_TEXCOORDMODE_CLAMP; /* I've experimented with non-normalized coordinates and using the LD * sampler fetch, but couldn't make it work. */ ss->ss3.non_normalized_coord = 0; return offset; }
static uint32_t gen6_bind_buf(struct intel_batchbuffer *batch, struct scratch_buf *buf, uint32_t format, int is_dst) { struct gen6_surface_state *ss; uint32_t write_domain, read_domain; int ret; if (is_dst) { write_domain = read_domain = I915_GEM_DOMAIN_RENDER; } else { write_domain = 0; read_domain = I915_GEM_DOMAIN_SAMPLER; } ss = batch_alloc(batch, sizeof(*ss), 32); ss->ss0.surface_type = GEN6_SURFACE_2D; ss->ss0.surface_format = format; ss->ss0.data_return_format = GEN6_SURFACERETURNFORMAT_FLOAT32; ss->ss0.color_blend = 1; ss->ss1.base_addr = buf->bo->offset; ret = drm_intel_bo_emit_reloc(batch->bo, batch_offset(batch, ss) + 4, buf->bo, 0, read_domain, write_domain); assert(ret == 0); ss->ss2.height = buf_height(buf) - 1; ss->ss2.width = buf_width(buf) - 1; ss->ss3.pitch = buf->stride - 1; ss->ss3.tiled_surface = buf->tiling != I915_TILING_NONE; ss->ss3.tile_walk = buf->tiling == I915_TILING_Y; return batch_offset(batch, ss); }
static uint32_t batch_copy(struct intel_batchbuffer *batch, const void *ptr, uint32_t size, uint32_t align) { return batch_offset(batch, memcpy(batch_alloc(batch, size, align), ptr, size)); }
void gen6_render_copyfunc(struct intel_batchbuffer *batch, struct scratch_buf *src, unsigned src_x, unsigned src_y, unsigned width, unsigned height, struct scratch_buf *dst, unsigned dst_x, unsigned dst_y) { uint32_t wm_state, wm_kernel, wm_table; uint32_t cc_vp, cc_blend, offset; uint32_t batch_end; intel_batchbuffer_flush(batch); batch->ptr = batch->buffer + 1024; batch_alloc(batch, 64, 64); wm_table = gen6_bind_surfaces(batch, src, dst); wm_kernel = gen6_create_kernel(batch); wm_state = gen6_create_sampler(batch, SAMPLER_FILTER_NEAREST, SAMPLER_EXTEND_NONE); cc_vp = gen6_create_cc_viewport(batch); cc_blend = gen6_create_cc_blend(batch); batch->ptr = batch->buffer; gen6_emit_invariant(batch); gen6_emit_state_base_address(batch); gen6_emit_sip(batch); gen6_emit_urb(batch); gen6_emit_viewports(batch, cc_vp); gen6_emit_vs(batch); gen6_emit_gs(batch); gen6_emit_clip(batch); gen6_emit_wm_constants(batch); gen6_emit_null_depth_buffer(batch); gen6_emit_drawing_rectangle(batch, dst); gen6_emit_cc(batch, cc_blend); gen6_emit_sampler(batch, wm_state); gen6_emit_sf(batch); gen6_emit_wm(batch, wm_kernel); gen6_emit_vertex_elements(batch); gen6_emit_binding_table(batch, wm_table); gen6_emit_vertex_buffer(batch); offset = gen6_emit_primitive(batch); OUT_BATCH(MI_BATCH_BUFFER_END); batch_end = batch_align(batch, 8); *(uint32_t*)(batch->buffer + offset) = batch_round_upto(batch, VERTEX_SIZE)/VERTEX_SIZE; emit_vertex_2s(batch, dst_x + width, dst_y + height); emit_vertex_normalized(batch, src_x + width, buf_width(src)); emit_vertex_normalized(batch, src_y + height, buf_height(src)); emit_vertex_2s(batch, dst_x, dst_y + height); emit_vertex_normalized(batch, src_x, buf_width(src)); emit_vertex_normalized(batch, src_y + height, buf_height(src)); emit_vertex_2s(batch, dst_x, dst_y); emit_vertex_normalized(batch, src_x, buf_width(src)); emit_vertex_normalized(batch, src_y, buf_height(src)); gen6_render_flush(batch, batch_end); intel_batchbuffer_reset(batch); }