/* Creates the Static Constant Buffer for the Device. */ static int galCreateStaticConstantBuffer(GIDevice *idevice) { struct pipe_resource buffer; memset(&buffer, 0, sizeof(buffer)); buffer.target = PIPE_BUFFER; buffer.format = PIPE_FORMAT_R8_UNORM; buffer.bind = PIPE_BIND_CONSTANT_BUFFER; buffer.usage = PIPE_USAGE_DYNAMIC; buffer.width0 = (4 * 128); buffer.height0 = 1; buffer.depth0 = 1; buffer.array_size = 1; buffer.flags = 0; idevice->constant = NULL; struct pipe_resource *handle; if ((handle = idevice->screen->resource_create(idevice->screen, &buffer)) == NULL) { printf("resource_create failed!\n"); return GI_ERROR; } pipe_set_constant_buffer(idevice->context, PIPE_SHADER_VERTEX, 0, handle); pipe_set_constant_buffer(idevice->context, PIPE_SHADER_FRAGMENT, 0, handle); idevice->constant = handle; return GI_SUCCESS; }
static void init_fs_constbuf( void ) { struct pipe_resource templat; struct pipe_box box; templat.target = PIPE_BUFFER; templat.format = PIPE_FORMAT_R8_UNORM; templat.width0 = sizeof(constants1); templat.height0 = 1; templat.depth0 = 1; templat.array_size = 1; templat.last_level = 0; templat.nr_samples = 1; templat.bind = PIPE_BIND_CONSTANT_BUFFER; constbuf1 = screen->resource_create(screen, &templat); if (constbuf1 == NULL) exit(4); constbuf2 = screen->resource_create(screen, &templat); if (constbuf2 == NULL) exit(4); { u_box_2d(0,0,sizeof(constants1),1, &box); ctx->transfer_inline_write(ctx, constbuf1, 0, PIPE_TRANSFER_WRITE, &box, constants1, sizeof constants1, sizeof constants1); pipe_set_constant_buffer(ctx, PIPE_SHADER_GEOMETRY, 0, constbuf1); } { u_box_2d(0,0,sizeof(constants2),1, &box); ctx->transfer_inline_write(ctx, constbuf2, 0, PIPE_TRANSFER_WRITE, &box, constants2, sizeof constants2, sizeof constants2); pipe_set_constant_buffer(ctx, PIPE_SHADER_GEOMETRY, 1, constbuf2); } }
void util_test_constant_buffer(struct pipe_context *ctx, struct pipe_resource *constbuf) { struct cso_context *cso; struct pipe_resource *cb; void *fs, *vs; bool pass = true; static const float zero[] = {0, 0, 0, 0}; cso = cso_create_context(ctx, 0); cb = util_create_texture2d(ctx->screen, 256, 256, PIPE_FORMAT_R8G8B8A8_UNORM, 0); util_set_common_states_and_clear(cso, ctx, cb); pipe_set_constant_buffer(ctx, PIPE_SHADER_FRAGMENT, 0, constbuf); /* Fragment shader. */ { static const char *text = /* I don't like ureg... */ "FRAG\n" "DCL CONST[0][0]\n" "DCL OUT[0], COLOR\n" "MOV OUT[0], CONST[0][0]\n" "END\n"; struct tgsi_token tokens[1000]; struct pipe_shader_state state; if (!tgsi_text_translate(text, tokens, ARRAY_SIZE(tokens))) { puts("Can't compile a fragment shader."); util_report_result(FAIL); return; } pipe_shader_state_from_tgsi(&state, tokens); fs = ctx->create_fs_state(ctx, &state); cso_set_fragment_shader_handle(cso, fs); } /* Vertex shader. */ vs = util_set_passthrough_vertex_shader(cso, ctx, false); util_draw_fullscreen_quad(cso); /* Probe pixels. */ pass = pass && util_probe_rect_rgba(ctx, cb, 0, 0, cb->width0, cb->height0, zero); /* Cleanup. */ cso_destroy_context(cso); ctx->delete_vs_state(ctx, vs); ctx->delete_fs_state(ctx, fs); pipe_resource_reference(&cb, NULL); util_report_result(pass); }
void renderer_set_constants(struct xa_context *r, int shader_type, const float *params, int param_bytes) { struct pipe_resource **cbuf = (shader_type == PIPE_SHADER_VERTEX) ? &r->vs_const_buffer : &r->fs_const_buffer; pipe_resource_reference(cbuf, NULL); *cbuf = pipe_buffer_create(r->pipe->screen, PIPE_BIND_CONSTANT_BUFFER, PIPE_USAGE_STATIC, param_bytes); if (*cbuf) { pipe_buffer_write(r->pipe, *cbuf, 0, param_bytes, params); } pipe_set_constant_buffer(r->pipe, shader_type, 0, *cbuf); }
/** * Set custom renderer fragment shader, and optionally set samplers and views * and upload the fragment constant buffer. * * This function modifies fragment_shader, samplers and fragment_sampler_views * states. */ static void renderer_set_custom_fs(struct renderer *renderer, void *fs, const struct pipe_sampler_state **samplers, struct pipe_sampler_view **views, VGint num_samplers, const void *const_buffer, VGint const_buffer_len) { cso_set_fragment_shader_handle(renderer->cso, fs); /* set samplers and views */ if (num_samplers) { cso_set_samplers(renderer->cso, PIPE_SHADER_FRAGMENT, num_samplers, samplers); cso_set_sampler_views(renderer->cso, PIPE_SHADER_FRAGMENT, num_samplers, views); } /* upload fs constant buffer */ if (const_buffer_len) { struct pipe_resource *cbuf = renderer->fs_cbuf; if (!cbuf || renderer->fs_cbuf_len != const_buffer_len || memcmp(renderer->fs_cbuf_data, const_buffer, const_buffer_len)) { pipe_resource_reference(&cbuf, NULL); cbuf = pipe_buffer_create(renderer->pipe->screen, PIPE_BIND_CONSTANT_BUFFER, PIPE_USAGE_STATIC, const_buffer_len); pipe_buffer_write(renderer->pipe, cbuf, 0, const_buffer_len, const_buffer); pipe_set_constant_buffer(renderer->pipe, PIPE_SHADER_FRAGMENT, 0, cbuf); renderer->fs_cbuf = cbuf; if (const_buffer_len <= sizeof(renderer->fs_cbuf_data)) { memcpy(renderer->fs_cbuf_data, const_buffer, const_buffer_len); renderer->fs_cbuf_len = const_buffer_len; } else { renderer->fs_cbuf_len = 0; } } } }
void vl_compositor_render(struct vl_compositor_state *s, struct vl_compositor *c, struct pipe_surface *dst_surface, struct u_rect *dirty_area, bool clear_dirty) { assert(c); assert(dst_surface); c->fb_state.width = dst_surface->width; c->fb_state.height = dst_surface->height; c->fb_state.cbufs[0] = dst_surface; if (!s->scissor_valid) { s->scissor.minx = 0; s->scissor.miny = 0; s->scissor.maxx = dst_surface->width; s->scissor.maxy = dst_surface->height; } gen_vertex_data(c, s, dirty_area); if (clear_dirty && dirty_area && (dirty_area->x0 < dirty_area->x1 || dirty_area->y0 < dirty_area->y1)) { c->pipe->clear_render_target(c->pipe, dst_surface, &s->clear_color, 0, 0, dst_surface->width, dst_surface->height); dirty_area->x0 = dirty_area->y0 = MAX_DIRTY; dirty_area->x1 = dirty_area->y1 = MIN_DIRTY; } c->pipe->set_scissor_states(c->pipe, 0, 1, &s->scissor); c->pipe->set_framebuffer_state(c->pipe, &c->fb_state); c->pipe->bind_vs_state(c->pipe, c->vs); c->pipe->set_vertex_buffers(c->pipe, 0, 1, &c->vertex_buf); c->pipe->bind_vertex_elements_state(c->pipe, c->vertex_elems_state); pipe_set_constant_buffer(c->pipe, PIPE_SHADER_FRAGMENT, 0, s->csc_matrix); c->pipe->bind_rasterizer_state(c->pipe, c->rast); draw_layers(c, s, dirty_area); }
/** * Set the model-view-projection matrix used by vertex shaders. */ static void renderer_set_mvp(struct renderer *renderer, const struct matrix *mvp) { struct matrix *cur = &renderer->mvp; struct pipe_resource *cbuf; VGfloat consts[3][4]; VGint i; /* projection only */ if (!mvp) mvp = &renderer->projection; /* re-upload only if necessary */ if (memcmp(cur, mvp, sizeof(*mvp)) == 0) return; /* 3x3 matrix to 3 constant vectors (no Z) */ for (i = 0; i < 3; i++) { consts[i][0] = mvp->m[i + 0]; consts[i][1] = mvp->m[i + 3]; consts[i][2] = 0.0f; consts[i][3] = mvp->m[i + 6]; } cbuf = renderer->vs_cbuf; pipe_resource_reference(&cbuf, NULL); cbuf = pipe_buffer_create(renderer->pipe->screen, PIPE_BIND_CONSTANT_BUFFER, PIPE_USAGE_STATIC, sizeof(consts)); if (cbuf) { pipe_buffer_write(renderer->pipe, cbuf, 0, sizeof(consts), consts); } pipe_set_constant_buffer(renderer->pipe, PIPE_SHADER_VERTEX, 0, cbuf); memcpy(cur, mvp, sizeof(*mvp)); renderer->vs_cbuf = cbuf; }
/** Run function of the MLAA filter. */ static void pp_jimenezmlaa_run(struct pp_queue_t *ppq, struct pipe_resource *in, struct pipe_resource *out, unsigned int n, bool iscolor) { struct program *p = ppq->p; struct pipe_depth_stencil_alpha_state mstencil; struct pipe_sampler_view v_tmp, *arr[3]; unsigned int w = p->framebuffer.width; unsigned int h = p->framebuffer.height; const struct pipe_stencil_ref ref = { {1} }; memset(&mstencil, 0, sizeof(mstencil)); cso_set_stencil_ref(p->cso, &ref); /* Init the pixel size constant */ if (dimensions[0] != p->framebuffer.width || dimensions[1] != p->framebuffer.height) { constants[0] = 1.0 / p->framebuffer.width; constants[1] = 1.0 / p->framebuffer.height; up_consts(p->pipe); dimensions[0] = p->framebuffer.width; dimensions[1] = p->framebuffer.height; } pipe_set_constant_buffer(p->pipe, PIPE_SHADER_VERTEX, 0, constbuf); pipe_set_constant_buffer(p->pipe, PIPE_SHADER_FRAGMENT, 0, constbuf); mstencil.stencil[0].enabled = 1; mstencil.stencil[0].valuemask = mstencil.stencil[0].writemask = ~0; mstencil.stencil[0].func = PIPE_FUNC_ALWAYS; mstencil.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP; mstencil.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP; mstencil.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE; p->framebuffer.zsbuf = ppq->stencils; /* First pass: depth edge detection */ if (iscolor) pp_filter_setup_in(p, in); else pp_filter_setup_in(p, ppq->depth); pp_filter_setup_out(p, ppq->inner_tmp[0]); pp_filter_set_fb(p); pp_filter_misc_state(p); cso_set_depth_stencil_alpha(p->cso, &mstencil); p->pipe->clear(p->pipe, PIPE_CLEAR_STENCIL | PIPE_CLEAR_COLOR, &p->clear_color, 0, 0); cso_single_sampler(p->cso, PIPE_SHADER_FRAGMENT, 0, &p->sampler_point); cso_single_sampler_done(p->cso, PIPE_SHADER_FRAGMENT); cso_set_sampler_views(p->cso, PIPE_SHADER_FRAGMENT, 1, &p->view); cso_set_vertex_shader_handle(p->cso, ppq->shaders[n][1]); /* offsetvs */ cso_set_fragment_shader_handle(p->cso, ppq->shaders[n][2]); pp_filter_draw(p); pp_filter_end_pass(p); /* Second pass: blend weights */ /* Sampler order: areamap, edgesmap, edgesmapL (reversed, thx compiler) */ mstencil.stencil[0].func = PIPE_FUNC_EQUAL; mstencil.stencil[0].zpass_op = PIPE_STENCIL_OP_KEEP; cso_set_depth_stencil_alpha(p->cso, &mstencil); pp_filter_setup_in(p, areamaptex); pp_filter_setup_out(p, ppq->inner_tmp[1]); u_sampler_view_default_template(&v_tmp, ppq->inner_tmp[0], ppq->inner_tmp[0]->format); arr[1] = arr[2] = p->pipe->create_sampler_view(p->pipe, ppq->inner_tmp[0], &v_tmp); pp_filter_set_clear_fb(p); cso_single_sampler(p->cso, PIPE_SHADER_FRAGMENT, 0, &p->sampler_point); cso_single_sampler(p->cso, PIPE_SHADER_FRAGMENT, 1, &p->sampler_point); cso_single_sampler(p->cso, PIPE_SHADER_FRAGMENT, 2, &p->sampler); cso_single_sampler_done(p->cso, PIPE_SHADER_FRAGMENT); arr[0] = p->view; cso_set_sampler_views(p->cso, PIPE_SHADER_FRAGMENT, 3, arr); cso_set_vertex_shader_handle(p->cso, ppq->shaders[n][0]); /* passvs */ cso_set_fragment_shader_handle(p->cso, ppq->shaders[n][3]); pp_filter_draw(p); pp_filter_end_pass(p); pipe_sampler_view_reference(&arr[1], NULL); /* Third pass: smoothed edges */ /* Sampler order: colormap, blendmap (wtf compiler) */ pp_filter_setup_in(p, ppq->inner_tmp[1]); pp_filter_setup_out(p, out); pp_filter_set_fb(p); /* Blit the input to the output */ util_blit_pixels(p->blitctx, in, 0, 0, 0, w, h, 0, p->framebuffer.cbufs[0], 0, 0, w, h, 0, PIPE_TEX_MIPFILTER_NEAREST, TGSI_WRITEMASK_XYZW, 0); u_sampler_view_default_template(&v_tmp, in, in->format); arr[0] = p->pipe->create_sampler_view(p->pipe, in, &v_tmp); cso_single_sampler(p->cso, PIPE_SHADER_FRAGMENT, 0, &p->sampler_point); cso_single_sampler(p->cso, PIPE_SHADER_FRAGMENT, 1, &p->sampler_point); cso_single_sampler_done(p->cso, PIPE_SHADER_FRAGMENT); arr[1] = p->view; cso_set_sampler_views(p->cso, PIPE_SHADER_FRAGMENT, 2, arr); cso_set_vertex_shader_handle(p->cso, ppq->shaders[n][1]); /* offsetvs */ cso_set_fragment_shader_handle(p->cso, ppq->shaders[n][4]); p->blend.rt[0].blend_enable = 1; cso_set_blend(p->cso, &p->blend); pp_filter_draw(p); pp_filter_end_pass(p); pipe_sampler_view_reference(&arr[0], NULL); p->blend.rt[0].blend_enable = 0; p->framebuffer.zsbuf = NULL; }