/** * Allocate space for and store data in a buffer object. Any data that was * previously stored in the buffer object is lost. If data is NULL, * memory will be allocated, but no copy will occur. * Called via glBufferDataARB(). */ static void st_bufferobj_data(GLcontext *ctx, GLenum target, GLsizeiptrARB size, const GLvoid * data, GLenum usage, struct gl_buffer_object *obj) { struct st_context *st = st_context(ctx); struct pipe_context *pipe = st->pipe; struct st_buffer_object *st_obj = st_buffer_object(obj); unsigned buffer_usage; st_obj->Base.Size = size; st_obj->Base.Usage = usage; switch(target) { case GL_PIXEL_PACK_BUFFER_ARB: case GL_PIXEL_UNPACK_BUFFER_ARB: buffer_usage = PIPE_BUFFER_USAGE_PIXEL; break; case GL_ARRAY_BUFFER_ARB: buffer_usage = PIPE_BUFFER_USAGE_VERTEX; break; case GL_ELEMENT_ARRAY_BUFFER_ARB: buffer_usage = PIPE_BUFFER_USAGE_INDEX; break; default: buffer_usage = 0; } pipe_buffer_reference( &st_obj->buffer, NULL ); st_obj->buffer = pipe_buffer_create( pipe->screen, 32, buffer_usage, size ); if (!st_obj->buffer) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBufferDataARB"); return; } st_obj->size = size; if (data) st_no_flush_pipe_buffer_write(st_context(ctx), st_obj->buffer, 0, size, data); }
/** * Pass the given program parameters to the graphics pipe as a * constant buffer. * \param id either PIPE_SHADER_VERTEX or PIPE_SHADER_FRAGMENT */ void st_upload_constants( struct st_context *st, struct gl_program_parameter_list *params, unsigned id) { struct pipe_context *pipe = st->pipe; struct pipe_constant_buffer *cbuf = &st->state.constants[id]; assert(id == PIPE_SHADER_VERTEX || id == PIPE_SHADER_FRAGMENT); /* update constants */ if (params && params->NumParameters) { const uint paramBytes = params->NumParameters * sizeof(GLfloat) * 4; _mesa_load_state_parameters(st->ctx, params); /* We always need to get a new buffer, to keep the drivers simple and * avoid gratuitous rendering synchronization. */ pipe_buffer_reference(&cbuf->buffer, NULL ); cbuf->buffer = pipe_buffer_create(pipe->screen, 16, PIPE_BUFFER_USAGE_CONSTANT, paramBytes ); if (0) { printf("%s(shader=%d, numParams=%d, stateFlags=0x%x)\n", __FUNCTION__, id, params->NumParameters, params->StateFlags); _mesa_print_parameter_list(params); } /* load Mesa constants into the constant buffer */ if (cbuf->buffer) st_no_flush_pipe_buffer_write(st, cbuf->buffer, 0, paramBytes, params->ParameterValues); st->pipe->set_constant_buffer(st->pipe, id, 0, cbuf); } else { st->constants.tracked_state[id].dirty.mesa = 0; // st->pipe->set_constant_buffer(st->pipe, id, 0, NULL); } }
void vg_validate_state(struct vg_context *ctx) { vg_manager_validate_framebuffer(ctx); if ((ctx->state.dirty & BLEND_DIRTY)) { struct pipe_blend_state *blend = &ctx->state.g3d.blend; memset(blend, 0, sizeof(struct pipe_blend_state)); blend->rt[0].blend_enable = 1; blend->rt[0].colormask = PIPE_MASK_RGBA; switch (ctx->state.vg.blend_mode) { case VG_BLEND_SRC: blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; blend->rt[0].blend_enable = 0; break; case VG_BLEND_SRC_OVER: blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA; blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA; blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA; break; case VG_BLEND_DST_OVER: blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_INV_DST_ALPHA; blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_INV_DST_ALPHA; blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_DST_ALPHA; blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_DST_ALPHA; break; case VG_BLEND_SRC_IN: blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_DST_ALPHA; blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_DST_ALPHA; blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; break; case VG_BLEND_DST_IN: blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ZERO; blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ZERO; blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_SRC_ALPHA; blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_SRC_ALPHA; break; case VG_BLEND_MULTIPLY: case VG_BLEND_SCREEN: case VG_BLEND_DARKEN: case VG_BLEND_LIGHTEN: blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; blend->rt[0].blend_enable = 0; break; case VG_BLEND_ADDITIVE: blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ONE; blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE; break; default: assert(!"not implemented blend mode"); } cso_set_blend(ctx->cso_context, &ctx->state.g3d.blend); } if ((ctx->state.dirty & RASTERIZER_DIRTY)) { struct pipe_rasterizer_state *raster = &ctx->state.g3d.rasterizer; memset(raster, 0, sizeof(struct pipe_rasterizer_state)); raster->gl_rasterization_rules = 1; cso_set_rasterizer(ctx->cso_context, &ctx->state.g3d.rasterizer); } if ((ctx->state.dirty & VIEWPORT_DIRTY)) { struct pipe_framebuffer_state *fb = &ctx->state.g3d.fb; const VGint param_bytes = 8 * sizeof(VGfloat); VGfloat vs_consts[8] = { 2.f/fb->width, 2.f/fb->height, 1, 1, -1, -1, 0, 0 }; struct pipe_resource **cbuf = &ctx->vs_const_buffer; vg_set_viewport(ctx, VEGA_Y0_BOTTOM); pipe_resource_reference(cbuf, NULL); *cbuf = pipe_buffer_create(ctx->pipe->screen, PIPE_BIND_CONSTANT_BUFFER, param_bytes); if (*cbuf) { st_no_flush_pipe_buffer_write(ctx, *cbuf, 0, param_bytes, vs_consts); } ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_VERTEX, 0, *cbuf); } if ((ctx->state.dirty & VS_DIRTY)) { cso_set_vertex_shader_handle(ctx->cso_context, vg_plain_vs(ctx)); } /* must be last because it renders to the depth buffer*/ if ((ctx->state.dirty & DEPTH_STENCIL_DIRTY)) { update_clip_state(ctx); cso_set_depth_stencil_alpha(ctx->cso_context, &ctx->state.g3d.dsa); } shader_set_masking(ctx->shader, ctx->state.vg.masking); shader_set_image_mode(ctx->shader, ctx->state.vg.image_mode); ctx->state.dirty = NONE_DIRTY; }
/** * Draw quad with texcoords and optional color. * Coords are window coords with y=0=bottom. * \param color may be null * \param invertTex if true, flip texcoords vertically */ static void draw_quad(GLcontext *ctx, GLfloat x0, GLfloat y0, GLfloat z, GLfloat x1, GLfloat y1, const GLfloat *color, GLboolean invertTex) { struct st_context *st = ctx->st; struct pipe_context *pipe = ctx->st->pipe; GLfloat verts[4][3][4]; /* four verts, three attribs, XYZW */ /* setup vertex data */ { const struct gl_framebuffer *fb = st->ctx->DrawBuffer; const GLfloat fb_width = (GLfloat) fb->Width; const GLfloat fb_height = (GLfloat) fb->Height; const GLfloat clip_x0 = x0 / fb_width * 2.0f - 1.0f; const GLfloat clip_y0 = y0 / fb_height * 2.0f - 1.0f; const GLfloat clip_x1 = x1 / fb_width * 2.0f - 1.0f; const GLfloat clip_y1 = y1 / fb_height * 2.0f - 1.0f; const GLfloat sLeft = 0.0f, sRight = 1.0f; const GLfloat tTop = invertTex, tBot = 1.0f - tTop; GLuint tex, i; /* upper-left */ verts[0][0][0] = clip_x0; /* v[0].attr[0].x */ verts[0][0][1] = clip_y0; /* v[0].attr[0].y */ /* upper-right */ verts[1][0][0] = clip_x1; verts[1][0][1] = clip_y0; /* lower-right */ verts[2][0][0] = clip_x1; verts[2][0][1] = clip_y1; /* lower-left */ verts[3][0][0] = clip_x0; verts[3][0][1] = clip_y1; tex = color ? 2 : 1; verts[0][tex][0] = sLeft; /* v[0].attr[tex].s */ verts[0][tex][1] = tTop; /* v[0].attr[tex].t */ verts[1][tex][0] = sRight; verts[1][tex][1] = tTop; verts[2][tex][0] = sRight; verts[2][tex][1] = tBot; verts[3][tex][0] = sLeft; verts[3][tex][1] = tBot; /* same for all verts: */ if (color) { for (i = 0; i < 4; i++) { verts[i][0][2] = z; /*Z*/ verts[i][0][3] = 1.0f; /*W*/ verts[i][1][0] = color[0]; verts[i][1][1] = color[1]; verts[i][1][2] = color[2]; verts[i][1][3] = color[3]; verts[i][2][2] = 0.0f; /*R*/ verts[i][2][3] = 1.0f; /*Q*/ } } else { for (i = 0; i < 4; i++) { verts[i][0][2] = z; /*Z*/ verts[i][0][3] = 1.0f; /*W*/ verts[i][1][2] = 0.0f; /*R*/ verts[i][1][3] = 1.0f; /*Q*/ } } } { struct pipe_buffer *buf; /* allocate/load buffer object with vertex data */ buf = pipe_buffer_create(pipe->screen, 32, PIPE_BUFFER_USAGE_VERTEX, sizeof(verts)); st_no_flush_pipe_buffer_write(st, buf, 0, sizeof(verts), verts); util_draw_vertex_buffer(pipe, buf, 0, PIPE_PRIM_QUADS, 4, /* verts */ 3); /* attribs/vert */ pipe_buffer_reference(&buf, NULL); } }