static void i915_set_fragment_sampler_views(struct pipe_context *pipe, unsigned num, struct pipe_sampler_view **views) { struct i915_context *i915 = i915_context(pipe); uint i; assert(num <= PIPE_MAX_SAMPLERS); /* Check for no-op */ if (num == i915->num_fragment_sampler_views && !memcmp(i915->fragment_sampler_views, views, num * sizeof(struct pipe_sampler_view *))) return; /* Fixes wrong texture in texobj with VBUF */ draw_flush(i915->draw); for (i = 0; i < num; i++) pipe_sampler_view_reference(&i915->fragment_sampler_views[i], views[i]); for (i = num; i < i915->num_fragment_sampler_views; i++) pipe_sampler_view_reference(&i915->fragment_sampler_views[i], NULL); i915->num_fragment_sampler_views = num; i915->dirty |= I915_NEW_SAMPLER_VIEW; }
static void i915_set_vertex_buffers(struct pipe_context *pipe, unsigned count, const struct pipe_vertex_buffer *buffers) { struct i915_context *i915 = i915_context(pipe); struct draw_context *draw = i915->draw; int i; util_copy_vertex_buffers(i915->saved_vertex_buffers, &i915->saved_nr_vertex_buffers, buffers, count); #if 0 /* XXX doesn't look like this is needed */ /* unmap old */ for (i = 0; i < i915->num_vertex_buffers; i++) { draw_set_mapped_vertex_buffer(draw, i, NULL); } #endif /* pass-through to draw module */ draw_set_vertex_buffers(draw, count, buffers); /* map new */ for (i = 0; i < count; i++) { void *buf = i915_buffer(buffers[i].buffer)->data; draw_set_mapped_vertex_buffer(draw, i, buf); } }
static void i915_bind_fragment_sampler_states(struct pipe_context *pipe, unsigned start, unsigned num, void **samplers) { struct i915_context *i915 = i915_context(pipe); unsigned i; /* Check for no-op */ if (num == i915->num_samplers && !memcmp(i915->fragment_sampler + start, samplers, num * sizeof(void *))) return; for (i = 0; i < num; ++i) i915->fragment_sampler[i + start] = samplers[i]; /* find highest non-null samplers[] entry */ { unsigned j = MAX2(i915->num_samplers, start + num); while (j > 0 && i915->fragment_sampler[j - 1] == NULL) j--; i915->num_samplers = j; } i915->dirty |= I915_NEW_SAMPLER; }
static void i915_delete_vs_state(struct pipe_context *pipe, void *shader) { struct i915_context *i915 = i915_context(pipe); /* just pass-through to draw module */ draw_delete_vertex_shader(i915->draw, (struct draw_vertex_shader *) shader); }
static void i915_transfer_destroy(struct pipe_context *pipe, struct pipe_transfer *transfer) { struct i915_context *i915 = i915_context(pipe); util_slab_free(&i915->transfer_pool, transfer); }
static void i915_set_vertex_sampler_views(struct pipe_context *pipe, unsigned num, struct pipe_sampler_view **views) { struct i915_context *i915 = i915_context(pipe); uint i; assert(num <= Elements(i915->vertex_sampler_views)); /* Check for no-op */ if (num == i915->num_vertex_sampler_views && !memcmp(i915->vertex_sampler_views, views, num * sizeof(struct pipe_sampler_view *))) { return; } for (i = 0; i < Elements(i915->vertex_sampler_views); i++) { struct pipe_sampler_view *view = i < num ? views[i] : NULL; pipe_sampler_view_reference(&i915->vertex_sampler_views[i], view); } i915->num_vertex_sampler_views = num; draw_set_sampler_views(i915->draw, PIPE_SHADER_VERTEX, i915->vertex_sampler_views, i915->num_vertex_sampler_views); }
static struct pipe_transfer * i915_get_transfer(struct pipe_context *pipe, struct pipe_resource *resource, unsigned level, unsigned usage, const struct pipe_box *box) { struct i915_context *i915 = i915_context(pipe); struct pipe_transfer *transfer; if (usage & PIPE_TRANSFER_MAP_PERMANENTLY) { return NULL; } transfer = util_slab_alloc(&i915->transfer_pool); if (transfer == NULL) return NULL; transfer->resource = resource; transfer->level = level; transfer->usage = usage; transfer->box = *box; /* Note strides are zero, this is ok for buffers, but not for * textures 2d & higher at least. */ return transfer; }
static void i915_clear_depth_stencil_render(struct pipe_context *pipe, struct pipe_surface *dst, unsigned clear_flags, double depth, unsigned stencil, unsigned dstx, unsigned dsty, unsigned width, unsigned height) { struct i915_context *i915 = i915_context(pipe); struct pipe_framebuffer_state fb_state; util_blitter_save_framebuffer(i915->blitter, &i915->framebuffer); fb_state.width = dst->width; fb_state.height = dst->height; fb_state.nr_cbufs = 0; fb_state.zsbuf = dst; pipe->set_framebuffer_state(pipe, &fb_state); if (i915->dirty) i915_update_derived(i915); i915_clear_emit(pipe, clear_flags & PIPE_CLEAR_DEPTHSTENCIL, NULL, depth, stencil, dstx, dsty, width, height); pipe->set_framebuffer_state(pipe, &i915->blitter->saved_fb_state); util_unreference_framebuffer_state(&i915->blitter->saved_fb_state); i915->blitter->saved_fb_state.nr_cbufs = ~0; }
static void i915_surface_copy_render(struct pipe_context *pipe, struct pipe_resource *dst, unsigned dst_level, unsigned dstx, unsigned dsty, unsigned dstz, struct pipe_resource *src, unsigned src_level, const struct pipe_box *src_box) { struct i915_context *i915 = i915_context(pipe); /* Fallback for buffers. */ if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) { util_resource_copy_region(pipe, dst, dst_level, dstx, dsty, dstz, src, src_level, src_box); return; } if (!util_blitter_is_copy_supported(i915->blitter, dst, src, PIPE_MASK_RGBAZS)) { util_resource_copy_region(pipe, dst, dst_level, dstx, dsty, dstz, src, src_level, src_box); return; } i915_util_blitter_save_states(i915); util_blitter_copy_texture(i915->blitter, dst, dst_level, dstx, dsty, dstz, src, src_level, src_box, PIPE_MASK_RGBAZS, TRUE); }
/** * Clear the given buffers to the specified values. * No masking, no scissor (clear entire buffer). */ void i915_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba, double depth, unsigned stencil) { util_clear(pipe, &i915_context(pipe)->framebuffer, buffers, rgba, depth, stencil); }
static void i915_set_sampler_textures(struct pipe_context *pipe, unsigned num, struct pipe_texture **texture) { struct i915_context *i915 = i915_context(pipe); uint i; assert(num <= PIPE_MAX_SAMPLERS); /* Check for no-op */ if (num == i915->num_textures && !memcmp(i915->texture, texture, num * sizeof(struct pipe_texture *))) return; /* Fixes wrong texture in texobj with VBUF */ draw_flush(i915->draw); for (i = 0; i < num; i++) pipe_texture_reference((struct pipe_texture **) &i915->texture[i], texture[i]); for (i = num; i < i915->num_textures; i++) pipe_texture_reference((struct pipe_texture **) &i915->texture[i], NULL); i915->num_textures = num; i915->dirty |= I915_NEW_TEXTURE; }
static void i915_blit(struct pipe_context *pipe, const struct pipe_blit_info *blit_info) { struct i915_context *i915 = i915_context(pipe); struct pipe_blit_info info = *blit_info; if (util_try_blit_via_copy_region(pipe, &info)) { return; /* done */ } if (info.mask & PIPE_MASK_S) { debug_printf("i915: cannot blit stencil, skipping\n"); info.mask &= ~PIPE_MASK_S; } if (!util_blitter_is_blit_supported(i915->blitter, &info)) { debug_printf("i915: blit unsupported %s -> %s\n", util_format_short_name(info.src.resource->format), util_format_short_name(info.dst.resource->format)); return; } i915_util_blitter_save_states(i915); util_blitter_blit(i915->blitter, &info); }
static void i915_set_fragment_sampler_views(struct pipe_context *pipe, unsigned num, struct pipe_sampler_view **views) { struct i915_context *i915 = i915_context(pipe); uint i; assert(num <= PIPE_MAX_SAMPLERS); /* Check for no-op */ if (num == i915->num_fragment_sampler_views && !memcmp(i915->fragment_sampler_views, views, num * sizeof(struct pipe_sampler_view *))) return; for (i = 0; i < num; i++) { /* Note: we're using pipe_sampler_view_release() here to work around * a possible crash when the old view belongs to another context that * was already destroyed. */ pipe_sampler_view_release(pipe, &i915->fragment_sampler_views[i]); pipe_sampler_view_reference(&i915->fragment_sampler_views[i], views[i]); } for (i = num; i < i915->num_fragment_sampler_views; i++) pipe_sampler_view_release(pipe, &i915->fragment_sampler_views[i]); i915->num_fragment_sampler_views = num; i915->dirty |= I915_NEW_SAMPLER_VIEW; }
static void i915_clear_render_target_render(struct pipe_context *pipe, struct pipe_surface *dst, const union pipe_color_union *color, unsigned dstx, unsigned dsty, unsigned width, unsigned height) { struct i915_context *i915 = i915_context(pipe); struct pipe_framebuffer_state fb_state; util_blitter_save_framebuffer(i915->blitter, &i915->framebuffer); fb_state.width = dst->width; fb_state.height = dst->height; fb_state.nr_cbufs = 1; fb_state.cbufs[0] = dst; fb_state.zsbuf = NULL; pipe->set_framebuffer_state(pipe, &fb_state); if (i915->dirty) i915_update_derived(i915); i915_clear_emit(pipe, PIPE_CLEAR_COLOR, color, 0.0, 0x0, dstx, dsty, width, height); pipe->set_framebuffer_state(pipe, &i915->blitter->saved_fb_state); util_unreference_framebuffer_state(&i915->blitter->saved_fb_state); i915->blitter->saved_fb_state.nr_cbufs = ~0; }
static void i915_bind_vertex_sampler_states(struct pipe_context *pipe, unsigned num_samplers, void **samplers) { struct i915_context *i915 = i915_context(pipe); unsigned i; assert(num_samplers <= Elements(i915->vertex_samplers)); /* Check for no-op */ if (num_samplers == i915->num_vertex_samplers && !memcmp(i915->vertex_samplers, samplers, num_samplers * sizeof(void *))) return; for (i = 0; i < num_samplers; ++i) i915->vertex_samplers[i] = samplers[i]; for (i = num_samplers; i < Elements(i915->vertex_samplers); ++i) i915->vertex_samplers[i] = NULL; i915->num_vertex_samplers = num_samplers; draw_set_samplers(i915->draw, PIPE_SHADER_VERTEX, i915->vertex_samplers, i915->num_vertex_samplers); }
static void i915_bind_vertex_sampler_states(struct pipe_context *pipe, unsigned start, unsigned num, void **samplers) { struct i915_context *i915 = i915_context(pipe); unsigned i; assert(start + num <= ARRAY_SIZE(i915->vertex_samplers)); /* Check for no-op */ if (num == i915->num_vertex_samplers && !memcmp(i915->vertex_samplers + start, samplers, num * sizeof(void *))) return; for (i = 0; i < num; ++i) i915->vertex_samplers[i + start] = samplers[i]; /* find highest non-null samplers[] entry */ { unsigned j = MAX2(i915->num_vertex_samplers, start + num); while (j > 0 && i915->vertex_samplers[j - 1] == NULL) j--; i915->num_vertex_samplers = j; } draw_set_samplers(i915->draw, PIPE_SHADER_VERTEX, i915->vertex_samplers, i915->num_vertex_samplers); }
static void i915_destroy(struct pipe_context *pipe) { struct i915_context *i915 = i915_context(pipe); int i; if (i915->blitter) util_blitter_destroy(i915->blitter); draw_destroy(i915->draw); if(i915->batch) i915->iws->batchbuffer_destroy(i915->batch); /* unbind framebuffer */ for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { pipe_surface_reference(&i915->framebuffer.cbufs[i], NULL); } pipe_surface_reference(&i915->framebuffer.zsbuf, NULL); /* unbind constant buffers */ for (i = 0; i < PIPE_SHADER_TYPES; i++) { pipe_resource_reference(&i915->constants[i], NULL); } FREE(i915); }
static void i915_render_prevalidate(struct intel_context *intel) { struct i915_context *i915 = i915_context(&intel->ctx); i915ValidateFragmentProgram(i915); }
static void i915_reduced_primitive_state(struct intel_context *intel, GLenum rprim) { struct i915_context *i915 = i915_context(&intel->ctx); GLuint st1 = i915->state.Stipple[I915_STPREG_ST1]; st1 &= ~ST1_ENABLE; switch (rprim) { case GL_QUADS: /* from RASTERIZE(GL_QUADS) in t_dd_tritemp.h */ case GL_TRIANGLES: if (intel->ctx.Polygon.StippleFlag && intel->hw_stipple) st1 |= ST1_ENABLE; break; case GL_LINES: case GL_POINTS: default: break; } i915->intel.reduced_primitive = rprim; if (st1 != i915->state.Stipple[I915_STPREG_ST1]) { INTEL_FIREVERTICES(intel); I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE); i915->state.Stipple[I915_STPREG_ST1] = st1; } }
static void i915_clear_render_target_blitter(struct pipe_context *pipe, struct pipe_surface *dst, const union pipe_color_union *color, unsigned dstx, unsigned dsty, unsigned width, unsigned height) { struct i915_texture *tex = i915_texture(dst->texture); struct pipe_resource *pt = &tex->b.b; union util_color uc; unsigned offset = i915_texture_offset(tex, dst->u.tex.level, dst->u.tex.first_layer); assert(util_format_get_blockwidth(pt->format) == 1); assert(util_format_get_blockheight(pt->format) == 1); util_pack_color(color->f, dst->format, &uc); i915_fill_blit( i915_context(pipe), util_format_get_blocksize(pt->format), XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB, (unsigned short) tex->stride, tex->buffer, offset, (short) dstx, (short) dsty, (short) width, (short) height, uc.ui ); }
static void * i915_create_vs_state(struct pipe_context *pipe, const struct pipe_shader_state *templ) { struct i915_context *i915 = i915_context(pipe); /* just pass-through to draw module */ return draw_create_vertex_shader(i915->draw, templ); }
static void i915_set_stencil_ref( struct pipe_context *pipe, const struct pipe_stencil_ref *stencil_ref ) { struct i915_context *i915 = i915_context(pipe); i915->stencil_ref = *stencil_ref; i915->dirty |= I915_NEW_DEPTH_STENCIL; }
static void i915_set_scissor_state( struct pipe_context *pipe, const struct pipe_scissor_state *scissor ) { struct i915_context *i915 = i915_context(pipe); draw_flush(i915->draw); memcpy( &i915->scissor, scissor, sizeof(*scissor) ); i915->dirty |= I915_NEW_SCISSOR; }
static void i915_bind_vs_state(struct pipe_context *pipe, void *shader) { struct i915_context *i915 = i915_context(pipe); /* just pass-through to draw module */ draw_bind_vertex_shader(i915->draw, (struct draw_vertex_shader *) shader); i915->dirty |= I915_NEW_VS; }
static void i915_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) { struct i915_context *i915 = i915_context(pipe); struct draw_context *draw = i915->draw; const void *mapped_indices = NULL; /* * Ack vs contants here, helps ipers a lot. */ i915->dirty &= ~I915_NEW_VS_CONSTANTS; if (i915->dirty) i915_update_derived(i915); /* * Map index buffer, if present */ if (info->indexed) { mapped_indices = i915->index_buffer.user_buffer; if (!mapped_indices) mapped_indices = i915_buffer(i915->index_buffer.buffer)->data; draw_set_indexes(draw, (ubyte *) mapped_indices + i915->index_buffer.offset, i915->index_buffer.index_size); } if (i915->constants[PIPE_SHADER_VERTEX]) draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0, i915_buffer(i915->constants[PIPE_SHADER_VERTEX])->data, (i915->current.num_user_constants[PIPE_SHADER_VERTEX] * 4 * sizeof(float))); else draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0, NULL, 0); if (i915->num_vertex_sampler_views > 0) i915_prepare_vertex_sampling(i915); /* * Do the drawing */ draw_vbo(i915->draw, info); if (mapped_indices) draw_set_indexes(draw, NULL, 0); if (i915->num_vertex_sampler_views > 0) i915_cleanup_vertex_sampling(i915); /* * Instead of flushing on every state change, we flush once here * when we fire the vbo. */ draw_flush(i915->draw); }
static void i915_set_index_buffer(struct pipe_context *pipe, const struct pipe_index_buffer *ib) { struct i915_context *i915 = i915_context(pipe); if (ib) memcpy(&i915->index_buffer, ib, sizeof(i915->index_buffer)); else memset(&i915->index_buffer, 0, sizeof(i915->index_buffer)); }
static void i915_set_framebuffer_state(struct pipe_context *pipe, const struct pipe_framebuffer_state *fb) { struct i915_context *i915 = i915_context(pipe); draw_flush(i915->draw); i915->framebuffer = *fb; /* struct copy */ i915->dirty |= I915_NEW_FRAMEBUFFER; }
static void i915_set_clip_state( struct pipe_context *pipe, const struct pipe_clip_state *clip ) { struct i915_context *i915 = i915_context(pipe); draw_flush(i915->draw); draw_set_clip_state(i915->draw, clip); i915->dirty |= I915_NEW_CLIP; }
static void i915_set_scissor_states( struct pipe_context *pipe, unsigned start_slot, unsigned num_scissors, const struct pipe_scissor_state *scissor ) { struct i915_context *i915 = i915_context(pipe); memcpy( &i915->scissor, scissor, sizeof(*scissor) ); i915->dirty |= I915_NEW_SCISSOR; }
static void i915_bind_fs_state(struct pipe_context *pipe, void *shader) { struct i915_context *i915 = i915_context(pipe); draw_flush(i915->draw); i915->fs = (struct i915_fragment_shader*) shader; i915->dirty |= I915_NEW_FS; }