static void ilo_set_viewport_states(struct pipe_context *pipe, unsigned start_slot, unsigned num_viewports, const struct pipe_viewport_state *viewports) { const struct ilo_dev_info *dev = ilo_context(pipe)->dev; struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector; if (viewports) { unsigned i; for (i = 0; i < num_viewports; i++) { ilo_gpe_set_viewport_cso(dev, &viewports[i], &vec->viewport.cso[start_slot + i]); } if (vec->viewport.count < start_slot + num_viewports) vec->viewport.count = start_slot + num_viewports; /* need to save viewport 0 for util_blitter */ if (!start_slot && num_viewports) vec->viewport.viewport0 = viewports[0]; } else { if (vec->viewport.count <= start_slot + num_viewports && vec->viewport.count > start_slot) vec->viewport.count = start_slot; } vec->dirty |= ILO_DIRTY_VIEWPORT; }
static void ilo_set_framebuffer_state(struct pipe_context *pipe, const struct pipe_framebuffer_state *state) { const struct ilo_dev_info *dev = ilo_context(pipe)->dev; struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector; ilo_gpe_set_fb(dev, state, &vec->fb); vec->dirty |= ILO_DIRTY_FB; }
static void ilo_set_scissor_states(struct pipe_context *pipe, unsigned start_slot, unsigned num_scissors, const struct pipe_scissor_state *scissors) { const struct ilo_dev_info *dev = ilo_context(pipe)->dev; struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector; ilo_gpe_set_scissor(dev, start_slot, num_scissors, scissors, &vec->scissor); vec->dirty |= ILO_DIRTY_SCISSOR; }
static void ilo_clear_depth_stencil(struct pipe_context *pipe, struct pipe_surface *dst, unsigned clear_flags, double depth, unsigned stencil, unsigned dstx, unsigned dsty, unsigned width, unsigned height) { struct ilo_context *ilo = ilo_context(pipe); if (!width || !height || dstx >= dst->width || dsty >= dst->height) return; if (dstx + width > dst->width) width = dst->width - dstx; if (dsty + height > dst->height) height = dst->height - dsty; if (ilo_blitter_blt_clear_zs(ilo->blitter, dst, clear_flags, depth, stencil, dstx, dsty, width, height)) return; ilo_blitter_pipe_clear_zs(ilo->blitter, dst, clear_flags, depth, stencil, dstx, dsty, width, height); }
static void ilo_blit(struct pipe_context *pipe, const struct pipe_blit_info *info) { struct ilo_context *ilo = ilo_context(pipe); ilo_blitter_pipe_blit(ilo->blitter, info); }
static void ilo_context_destroy(struct pipe_context *pipe) { struct ilo_context *ilo = ilo_context(pipe); ilo_cleanup_states(ilo); if (ilo->last_cp_bo) intel_bo_unreference(ilo->last_cp_bo); if (ilo->uploader) u_upload_destroy(ilo->uploader); if (ilo->blitter) ilo_blitter_destroy(ilo->blitter); if (ilo->hw3d) ilo_3d_destroy(ilo->hw3d); if (ilo->shader_cache) ilo_shader_cache_destroy(ilo->shader_cache); if (ilo->cp) ilo_cp_destroy(ilo->cp); util_slab_destroy(&ilo->transfer_mempool); FREE(ilo); }
static void ilo_bind_sampler_states(struct pipe_context *pipe, unsigned shader, unsigned start, unsigned count, void **samplers) { struct ilo_context *ilo = ilo_context(pipe); struct ilo_sampler_state *dst = &ilo->sampler[shader]; bool changed = false; unsigned i; assert(start + count <= Elements(dst->cso)); if (samplers) { for (i = 0; i < count; i++) { if (dst->cso[start + i] != samplers[i]) { dst->cso[start + i] = samplers[i]; /* * This function is sometimes called to reduce the number of bound * samplers. Do not consider that as a state change (and create a * new array of SAMPLER_STATE). */ if (samplers[i]) changed = true; } } } else { for (i = 0; i < count; i++) dst->cso[start + i] = NULL; } if (dst->count <= start + count) { if (samplers) count += start; else count = start; while (count > 0 && !dst->cso[count - 1]) count--; dst->count = count; } if (changed) { switch (shader) { case PIPE_SHADER_VERTEX: ilo->dirty |= ILO_DIRTY_SAMPLER_VS; break; case PIPE_SHADER_GEOMETRY: ilo->dirty |= ILO_DIRTY_SAMPLER_GS; break; case PIPE_SHADER_FRAGMENT: ilo->dirty |= ILO_DIRTY_SAMPLER_FS; break; case PIPE_SHADER_COMPUTE: ilo->dirty |= ILO_DIRTY_SAMPLER_CS; break; } } }
static boolean ilo_get_query_result(struct pipe_context *pipe, struct pipe_query *query, boolean wait, union pipe_query_result *result) { struct ilo_context *ilo = ilo_context(pipe); struct ilo_query *q = ilo_query(query); if (q->active) return false; if (q->bo) { if (intel_bo_has_reloc(ilo->cp->bo, q->bo)) ilo_cp_flush(ilo->cp, "syncing for queries"); if (!wait && intel_bo_is_busy(q->bo)) return false; query_info[q->type].process(ilo, q); } if (result) serialize_query_data(q->type, &q->data, (void *) result); return true; }
static void ilo_set_stream_output_targets(struct pipe_context *pipe, unsigned num_targets, struct pipe_stream_output_target **targets, unsigned append_bitmask) { struct ilo_context *ilo = ilo_context(pipe); unsigned i; if (!targets) num_targets = 0; /* util_blitter may set this unnecessarily */ if (!ilo->so.count && !num_targets) return; for (i = 0; i < num_targets; i++) pipe_so_target_reference(&ilo->so.states[i], targets[i]); for (; i < ilo->so.count; i++) pipe_so_target_reference(&ilo->so.states[i], NULL); ilo->so.count = num_targets; ilo->so.append_bitmask = append_bitmask; ilo->so.enabled = (ilo->so.count > 0); ilo->dirty |= ILO_DIRTY_SO; }
static void ilo_set_shader_resources(struct pipe_context *pipe, unsigned start, unsigned count, struct pipe_surface **surfaces) { struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector; struct ilo_resource_state *dst = &vec->resource; unsigned i; assert(start + count <= Elements(dst->states)); if (surfaces) { for (i = 0; i < count; i++) pipe_surface_reference(&dst->states[start + i], surfaces[i]); } else { for (i = 0; i < count; i++) pipe_surface_reference(&dst->states[start + i], NULL); } if (dst->count <= start + count) { if (surfaces) count += start; else count = start; while (count > 0 && !dst->states[count - 1]) count--; dst->count = count; } vec->dirty |= ILO_DIRTY_RESOURCE; }
static void ilo_set_stream_output_targets(struct pipe_context *pipe, unsigned num_targets, struct pipe_stream_output_target **targets, const unsigned *offset) { struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector; unsigned i; unsigned append_bitmask = 0; if (!targets) num_targets = 0; /* util_blitter may set this unnecessarily */ if (!vec->so.count && !num_targets) return; for (i = 0; i < num_targets; i++) { pipe_so_target_reference(&vec->so.states[i], targets[i]); if (offset[i] == (unsigned)-1) append_bitmask |= 1 << i; } for (; i < vec->so.count; i++) pipe_so_target_reference(&vec->so.states[i], NULL); vec->so.count = num_targets; vec->so.append_bitmask = append_bitmask; vec->so.enabled = (vec->so.count > 0); vec->dirty |= ILO_DIRTY_SO; }
static void ilo_set_global_binding(struct pipe_context *pipe, unsigned start, unsigned count, struct pipe_resource **resources, uint32_t **handles) { struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector; struct ilo_global_binding *dst = &vec->global_binding; unsigned i; assert(start + count <= Elements(dst->resources)); if (resources) { for (i = 0; i < count; i++) pipe_resource_reference(&dst->resources[start + i], resources[i]); } else { for (i = 0; i < count; i++) pipe_resource_reference(&dst->resources[start + i], NULL); } if (dst->count <= start + count) { if (resources) count += start; else count = start; while (count > 0 && !dst->resources[count - 1]) count--; dst->count = count; } vec->dirty |= ILO_DIRTY_GLOBAL_BINDING; }
static void ilo_context_cp_submitted(struct ilo_cp *cp, void *data) { struct ilo_context *ilo = ilo_context(data); /* builder buffers are reallocated */ ilo_render_invalidate_builder(ilo->render); }
static void ilo_bind_compute_state(struct pipe_context *pipe, void *state) { struct ilo_context *ilo = ilo_context(pipe); ilo->cs = state; ilo->dirty |= ILO_DIRTY_CS; }
static void ilo_bind_vertex_elements_state(struct pipe_context *pipe, void *state) { struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector; vec->ve = state; vec->dirty |= ILO_DIRTY_VE; }
static void ilo_delete_gs_state(struct pipe_context *pipe, void *state) { struct ilo_context *ilo = ilo_context(pipe); struct ilo_shader_state *gs = (struct ilo_shader_state *) state; ilo_shader_cache_remove(ilo->shader_cache, gs); ilo_shader_destroy(gs); }
static void ilo_bind_vs_state(struct pipe_context *pipe, void *state) { struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector; vec->vs = state; vec->dirty |= ILO_DIRTY_VS; }
static void ilo_bind_depth_stencil_alpha_state(struct pipe_context *pipe, void *state) { struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector; vec->dsa = state; vec->dirty |= ILO_DIRTY_DSA; }
static void ilo_bind_blend_state(struct pipe_context *pipe, void *state) { struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector; vec->blend = state; vec->dirty |= ILO_DIRTY_BLEND; }
static void ilo_bind_blend_state(struct pipe_context *pipe, void *state) { struct ilo_context *ilo = ilo_context(pipe); ilo->blend = state; ilo->dirty |= ILO_DIRTY_BLEND; }
static void ilo_bind_vertex_elements_state(struct pipe_context *pipe, void *state) { struct ilo_context *ilo = ilo_context(pipe); ilo->ve = state; ilo->dirty |= ILO_DIRTY_VE; }
static void ilo_bind_vs_state(struct pipe_context *pipe, void *state) { struct ilo_context *ilo = ilo_context(pipe); ilo->vs = state; ilo->dirty |= ILO_DIRTY_VS; }
static void ilo_bind_depth_stencil_alpha_state(struct pipe_context *pipe, void *state) { struct ilo_context *ilo = ilo_context(pipe); ilo->dsa = state; ilo->dirty |= ILO_DIRTY_DSA; }
static void ilo_bind_rasterizer_state(struct pipe_context *pipe, void *state) { struct ilo_context *ilo = ilo_context(pipe); ilo->rasterizer = state; ilo->dirty |= ILO_DIRTY_RASTERIZER; }
static void ilo_bind_rasterizer_state(struct pipe_context *pipe, void *state) { struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector; vec->rasterizer = state; vec->dirty |= ILO_DIRTY_RASTERIZER; }
static void ilo_set_global_binding(struct pipe_context *pipe, unsigned start, unsigned count, struct pipe_resource **resources, uint32_t **handles) { struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector; struct ilo_global_binding_cso *dst; unsigned i; /* make room */ if (vec->global_binding.count < start + count) { if (resources) { const unsigned old_size = vec->global_binding.bindings.size; const unsigned new_size = sizeof(*dst) * (start + count); if (old_size < new_size) { util_dynarray_resize(&vec->global_binding.bindings, new_size); memset(vec->global_binding.bindings.data + old_size, 0, new_size - old_size); } } else { count = vec->global_binding.count - start; } } dst = util_dynarray_element(&vec->global_binding.bindings, struct ilo_global_binding_cso, start); if (resources) { for (i = 0; i < count; i++) { pipe_resource_reference(&dst[i].resource, resources[i]); dst[i].handle = handles[i]; } } else { for (i = 0; i < count; i++) { pipe_resource_reference(&dst[i].resource, NULL); dst[i].handle = NULL; } } if (vec->global_binding.count <= start + count) { dst = util_dynarray_begin(&vec->global_binding.bindings); if (resources) count += start; else count = start; while (count > 0 && !dst[count - 1].resource) count--; vec->global_binding.count = count; } vec->dirty |= ILO_DIRTY_GLOBAL_BINDING; }
static void ilo_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) { struct ilo_context *ilo = ilo_context(pipe); int vs_scratch_size, gs_scratch_size, fs_scratch_size; if (ilo_debug & ILO_DEBUG_DRAW) { if (info->indexed) { ilo_printf("indexed draw %s: " "index start %d, count %d, vertex range [%d, %d]\n", u_prim_name(info->mode), info->start, info->count, info->min_index, info->max_index); } else { ilo_printf("draw %s: vertex start %d, count %d\n", u_prim_name(info->mode), info->start, info->count); } ilo_state_vector_dump_dirty(&ilo->state_vector); } if (ilo_skip_rendering(ilo)) return; if (info->primitive_restart && info->indexed && draw_vbo_need_sw_restart(ilo, info)) { draw_vbo_with_sw_restart(ilo, info); return; } ilo_finalize_3d_states(ilo, info); /* upload kernels */ ilo_shader_cache_upload(ilo->shader_cache, &ilo->cp->builder); /* prepare scratch spaces */ ilo_shader_cache_get_max_scratch_sizes(ilo->shader_cache, &vs_scratch_size, &gs_scratch_size, &fs_scratch_size); ilo_render_prepare_scratch_spaces(ilo->render, vs_scratch_size, gs_scratch_size, fs_scratch_size); ilo_blit_resolve_framebuffer(ilo); /* If draw_vbo ever fails, return immediately. */ if (!draw_vbo(ilo, &ilo->state_vector)) return; /* clear dirty status */ ilo->state_vector.dirty = 0x0; /* avoid dangling pointer reference */ ilo->state_vector.draw = NULL; if (ilo_debug & ILO_DEBUG_NOCACHE) ilo_render_emit_flush(ilo->render); }
static void ilo_begin_query(struct pipe_context *pipe, struct pipe_query *query) { struct ilo_context *ilo = ilo_context(pipe); struct ilo_query *q = ilo_query(query); q->active = true; query_info[q->type].begin(ilo, q); }
static void ilo_set_clip_state(struct pipe_context *pipe, const struct pipe_clip_state *state) { struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector; vec->clip = *state; vec->dirty |= ILO_DIRTY_CLIP; }
static void ilo_set_polygon_stipple(struct pipe_context *pipe, const struct pipe_poly_stipple *state) { struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector; vec->poly_stipple = *state; vec->dirty |= ILO_DIRTY_POLY_STIPPLE; }