#include "main/image.h"
#include "main/bufferobj.h"
#include "main/macros.h"
-#include "main/mfeatures.h"
#include "main/pbo.h"
#include "program/program.h"
#include "program/prog_print.h"
#include "util/u_inlines.h"
#include "util/u_draw_quad.h"
#include "util/u_simple_shaders.h"
+#include "util/u_upload_mgr.h"
#include "program/prog_instruction.h"
#include "cso_cache/cso_context.h"
-#if FEATURE_drawpix
-
/**
* glBitmaps are drawn as textured quads. The user's bitmap pattern
* is stored in a texture image. An alpha8 texture format is used.
p->Instructions[ic].DstReg.File = PROGRAM_TEMPORARY;
p->Instructions[ic].DstReg.Index = 0;
p->Instructions[ic].SrcReg[0].File = PROGRAM_INPUT;
- p->Instructions[ic].SrcReg[0].Index = FRAG_ATTRIB_TEX0;
+ p->Instructions[ic].SrcReg[0].Index = VARYING_SLOT_TEX0;
p->Instructions[ic].TexSrcUnit = samplerIndex;
p->Instructions[ic].TexSrcTarget = TEXTURE_2D_INDEX;
ic++;
assert(ic == p->NumInstructions);
- p->InputsRead = FRAG_BIT_TEX0;
+ p->InputsRead = VARYING_BIT_TEX0;
p->OutputsWritten = 0x0;
p->SamplersUsed = (1 << samplerIndex);
* Create texture to hold bitmap pattern.
*/
pt = st_texture_create(st, st->internal_target, st->bitmap.tex_format,
- 0, width, height, 1, 1,
+ 0, width, height, 1, 1, 0,
PIPE_BIND_SAMPLER_VIEW);
if (!pt) {
_mesa_unmap_pbo_source(ctx, unpack);
return NULL;
}
- transfer = pipe_get_transfer(st->pipe, pt, 0, 0,
- PIPE_TRANSFER_WRITE,
- 0, 0, width, height);
-
- dest = pipe_transfer_map(pipe, transfer);
+ dest = pipe_transfer_map(st->pipe, pt, 0, 0,
+ PIPE_TRANSFER_WRITE,
+ 0, 0, width, height, &transfer);
/* Put image into texture transfer */
memset(dest, 0xff, height * transfer->stride);
/* Release transfer */
pipe_transfer_unmap(pipe, transfer);
- pipe->transfer_destroy(pipe, transfer);
-
return pt;
}
-static GLuint
+static void
setup_bitmap_vertex_data(struct st_context *st, bool normalized,
int x, int y, int width, int height,
- float z, const float color[4])
+ float z, const float color[4],
+ struct pipe_resource **vbuf,
+ unsigned *vbuf_offset)
{
- struct pipe_context *pipe = st->pipe;
- const struct gl_framebuffer *fb = st->ctx->DrawBuffer;
- const GLfloat fb_width = (GLfloat)fb->Width;
- const GLfloat fb_height = (GLfloat)fb->Height;
+ const GLfloat fb_width = (GLfloat)st->state.framebuffer.width;
+ const GLfloat fb_height = (GLfloat)st->state.framebuffer.height;
const GLfloat x0 = (GLfloat)x;
const GLfloat x1 = (GLfloat)(x + width);
const GLfloat y0 = (GLfloat)y;
const GLfloat clip_y0 = (GLfloat)(y0 / fb_height * 2.0 - 1.0);
const GLfloat clip_x1 = (GLfloat)(x1 / fb_width * 2.0 - 1.0);
const GLfloat clip_y1 = (GLfloat)(y1 / fb_height * 2.0 - 1.0);
- const GLuint max_slots = 1; /* 4096 / sizeof(st->bitmap.vertices); */
GLuint i;
+ float (*vertices)[3][4]; /**< vertex pos + color + texcoord */
if(!normalized)
{
tBot = (GLfloat) height;
}
- /* XXX: Need to improve buffer_write to allow NO_WAIT (as well as
- * no_flush) updates to buffers where we know there is no conflict
- * with previous data. Currently using max_slots > 1 will cause
- * synchronous rendering if the driver flushes its command buffers
- * between one bitmap and the next. Our flush hook below isn't
- * sufficient to catch this as the driver doesn't tell us when it
- * flushes its own command buffers. Until this gets fixed, pay the
- * price of allocating a new buffer for each bitmap cache-flush to
- * avoid synchronous rendering.
- */
- if (st->bitmap.vbuf_slot >= max_slots) {
- pipe_resource_reference(&st->bitmap.vbuf, NULL);
- st->bitmap.vbuf_slot = 0;
- }
-
- if (!st->bitmap.vbuf) {
- st->bitmap.vbuf = pipe_buffer_create(pipe->screen,
- PIPE_BIND_VERTEX_BUFFER,
- PIPE_USAGE_STREAM,
- max_slots *
- sizeof(st->bitmap.vertices));
- if (!st->bitmap.vbuf) {
- /* out of memory */
- return 0;
- }
+ if (u_upload_alloc(st->uploader, 0, 4 * sizeof(vertices[0]),
+ vbuf_offset, vbuf, (void **) &vertices) != PIPE_OK) {
+ return;
}
/* Positions are in clip coords since we need to do clipping in case
* the bitmap quad goes beyond the window bounds.
*/
- st->bitmap.vertices[0][0][0] = clip_x0;
- st->bitmap.vertices[0][0][1] = clip_y0;
- st->bitmap.vertices[0][2][0] = sLeft;
- st->bitmap.vertices[0][2][1] = tTop;
-
- st->bitmap.vertices[1][0][0] = clip_x1;
- st->bitmap.vertices[1][0][1] = clip_y0;
- st->bitmap.vertices[1][2][0] = sRight;
- st->bitmap.vertices[1][2][1] = tTop;
+ vertices[0][0][0] = clip_x0;
+ vertices[0][0][1] = clip_y0;
+ vertices[0][2][0] = sLeft;
+ vertices[0][2][1] = tTop;
+
+ vertices[1][0][0] = clip_x1;
+ vertices[1][0][1] = clip_y0;
+ vertices[1][2][0] = sRight;
+ vertices[1][2][1] = tTop;
- st->bitmap.vertices[2][0][0] = clip_x1;
- st->bitmap.vertices[2][0][1] = clip_y1;
- st->bitmap.vertices[2][2][0] = sRight;
- st->bitmap.vertices[2][2][1] = tBot;
+ vertices[2][0][0] = clip_x1;
+ vertices[2][0][1] = clip_y1;
+ vertices[2][2][0] = sRight;
+ vertices[2][2][1] = tBot;
- st->bitmap.vertices[3][0][0] = clip_x0;
- st->bitmap.vertices[3][0][1] = clip_y1;
- st->bitmap.vertices[3][2][0] = sLeft;
- st->bitmap.vertices[3][2][1] = tBot;
+ vertices[3][0][0] = clip_x0;
+ vertices[3][0][1] = clip_y1;
+ vertices[3][2][0] = sLeft;
+ vertices[3][2][1] = tBot;
/* same for all verts: */
for (i = 0; i < 4; i++) {
- st->bitmap.vertices[i][0][2] = z;
- st->bitmap.vertices[i][0][3] = 1.0f;
- st->bitmap.vertices[i][1][0] = color[0];
- st->bitmap.vertices[i][1][1] = color[1];
- st->bitmap.vertices[i][1][2] = color[2];
- st->bitmap.vertices[i][1][3] = color[3];
- st->bitmap.vertices[i][2][2] = 0.0; /*R*/
- st->bitmap.vertices[i][2][3] = 1.0; /*Q*/
+ vertices[i][0][2] = z;
+ vertices[i][0][3] = 1.0f;
+ vertices[i][1][0] = color[0];
+ vertices[i][1][1] = color[1];
+ vertices[i][1][2] = color[2];
+ vertices[i][1][3] = color[3];
+ vertices[i][2][2] = 0.0; /*R*/
+ vertices[i][2][3] = 1.0; /*Q*/
}
- /* put vertex data into vbuf */
- pipe_buffer_write_nooverlap(st->pipe,
- st->bitmap.vbuf,
- st->bitmap.vbuf_slot
- * sizeof(st->bitmap.vertices),
- sizeof st->bitmap.vertices,
- st->bitmap.vertices);
-
- return st->bitmap.vbuf_slot++ * sizeof st->bitmap.vertices;
+ u_upload_unmap(st->uploader);
}
struct st_fp_variant_key key;
GLuint maxSize;
GLuint offset;
+ struct pipe_resource *vbuf = NULL;
memset(&key, 0, sizeof(key));
key.st = st;
key.bitmap = GL_TRUE;
+ key.clamp_color = st->clamp_frag_color_in_shader &&
+ st->ctx->Color._ClampFragmentColor;
fpv = st_get_fp_variant(st, st->fp, &key);
assert(height <= (GLsizei)maxSize);
cso_save_rasterizer(cso);
- cso_save_samplers(cso);
- cso_save_fragment_sampler_views(cso);
+ cso_save_samplers(cso, PIPE_SHADER_FRAGMENT);
+ cso_save_sampler_views(cso, PIPE_SHADER_FRAGMENT);
cso_save_viewport(cso);
cso_save_fragment_shader(cso);
cso_save_stream_outputs(cso);
cso_save_vertex_shader(cso);
cso_save_geometry_shader(cso);
cso_save_vertex_elements(cso);
- cso_save_vertex_buffers(cso);
+ cso_save_aux_vertex_buffer_slot(cso);
/* rasterizer state: just scissor */
st->bitmap.rasterizer.scissor = ctx->Scissor.Enabled;
/* user samplers, plus our bitmap sampler */
{
struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
- uint num = MAX2(fpv->bitmap_sampler + 1, st->state.num_samplers);
+ uint num = MAX2(fpv->bitmap_sampler + 1,
+ st->state.num_samplers[PIPE_SHADER_FRAGMENT]);
uint i;
- for (i = 0; i < st->state.num_samplers; i++) {
- samplers[i] = &st->state.samplers[i];
+ for (i = 0; i < st->state.num_samplers[PIPE_SHADER_FRAGMENT]; i++) {
+ samplers[i] = &st->state.samplers[PIPE_SHADER_FRAGMENT][i];
}
samplers[fpv->bitmap_sampler] =
&st->bitmap.samplers[sv->texture->target != PIPE_TEXTURE_RECT];
- cso_set_samplers(cso, num, (const struct pipe_sampler_state **) samplers);
+ cso_set_samplers(cso, PIPE_SHADER_FRAGMENT, num,
+ (const struct pipe_sampler_state **) samplers);
}
/* user textures, plus the bitmap texture */
{
struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];
- uint num = MAX2(fpv->bitmap_sampler + 1, st->state.num_textures);
- memcpy(sampler_views, st->state.sampler_views, sizeof(sampler_views));
+ uint num = MAX2(fpv->bitmap_sampler + 1,
+ st->state.num_sampler_views[PIPE_SHADER_FRAGMENT]);
+ memcpy(sampler_views, st->state.sampler_views[PIPE_SHADER_FRAGMENT],
+ sizeof(sampler_views));
sampler_views[fpv->bitmap_sampler] = sv;
- cso_set_fragment_sampler_views(cso, num, sampler_views);
+ cso_set_sampler_views(cso, PIPE_SHADER_FRAGMENT, num, sampler_views);
}
/* viewport state: viewport matching window dims */
{
- const struct gl_framebuffer *fb = st->ctx->DrawBuffer;
- const GLboolean invert = (st_fb_orientation(fb) == Y_0_TOP);
- const GLfloat width = (GLfloat)fb->Width;
- const GLfloat height = (GLfloat)fb->Height;
+ const GLboolean invert = st->state.fb_orientation == Y_0_TOP;
+ const GLfloat width = (GLfloat)st->state.framebuffer.width;
+ const GLfloat height = (GLfloat)st->state.framebuffer.height;
struct pipe_viewport_state vp;
vp.scale[0] = 0.5f * width;
vp.scale[1] = height * (invert ? -0.5f : 0.5f);
z = z * 2.0f - 1.0f;
/* draw textured quad */
- offset = setup_bitmap_vertex_data(st,
- sv->texture->target != PIPE_TEXTURE_RECT,
- x, y, width, height, z, color);
+ setup_bitmap_vertex_data(st, sv->texture->target != PIPE_TEXTURE_RECT,
+ x, y, width, height, z, color, &vbuf, &offset);
- if (st->bitmap.vbuf) {
- util_draw_vertex_buffer(pipe, st->cso_context, st->bitmap.vbuf, offset,
+ if (vbuf) {
+ util_draw_vertex_buffer(pipe, st->cso_context, vbuf,
+ cso_get_aux_vertex_buffer_slot(st->cso_context),
+ offset,
PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */
3); /* attribs/vert */
/* restore state */
cso_restore_rasterizer(cso);
- cso_restore_samplers(cso);
- cso_restore_fragment_sampler_views(cso);
+ cso_restore_samplers(cso, PIPE_SHADER_FRAGMENT);
+ cso_restore_sampler_views(cso, PIPE_SHADER_FRAGMENT);
cso_restore_viewport(cso);
cso_restore_fragment_shader(cso);
cso_restore_vertex_shader(cso);
cso_restore_geometry_shader(cso);
cso_restore_vertex_elements(cso);
- cso_restore_vertex_buffers(cso);
+ cso_restore_aux_vertex_buffer_slot(cso);
cso_restore_stream_outputs(cso);
+
+ pipe_resource_reference(&vbuf, NULL);
}
static void
reset_cache(struct st_context *st)
{
- struct pipe_context *pipe = st->pipe;
struct bitmap_cache *cache = st->bitmap.cache;
/*memset(cache->buffer, 0xff, sizeof(cache->buffer));*/
cache->ymin = 1000000;
cache->ymax = -1000000;
- if (cache->trans) {
- pipe->transfer_destroy(pipe, cache->trans);
- cache->trans = NULL;
- }
-
assert(!cache->texture);
/* allocate a new texture */
cache->texture = st_texture_create(st, PIPE_TEXTURE_2D,
st->bitmap.tex_format, 0,
BITMAP_CACHE_WIDTH, BITMAP_CACHE_HEIGHT,
- 1, 1,
+ 1, 1, 0,
PIPE_BIND_SAMPLER_VIEW);
}
/* Map the texture transfer.
* Subsequent glBitmap calls will write into the texture image.
*/
- cache->trans = pipe_get_transfer(st->pipe, cache->texture, 0, 0,
- PIPE_TRANSFER_WRITE, 0, 0,
- BITMAP_CACHE_WIDTH,
- BITMAP_CACHE_HEIGHT);
- cache->buffer = pipe_transfer_map(pipe, cache->trans);
+ cache->buffer = pipe_transfer_map(pipe, cache->texture, 0, 0,
+ PIPE_TRANSFER_WRITE, 0, 0,
+ BITMAP_CACHE_WIDTH,
+ BITMAP_CACHE_HEIGHT, &cache->trans);
/* init image to all 0xff */
memset(cache->buffer, 0xff, cache->trans->stride * BITMAP_CACHE_HEIGHT);
if (!st->bitmap.cache->empty) {
struct bitmap_cache *cache = st->bitmap.cache;
- if (st->ctx->DrawBuffer) {
- struct pipe_context *pipe = st->pipe;
- struct pipe_sampler_view *sv;
+ struct pipe_context *pipe = st->pipe;
+ struct pipe_sampler_view *sv;
+
+ assert(cache->xmin <= cache->xmax);
- assert(cache->xmin <= cache->xmax);
-
-/* printf("flush size %d x %d at %d, %d\n",
- cache->xmax - cache->xmin,
- cache->ymax - cache->ymin,
- cache->xpos, cache->ypos);
+/* printf("flush size %d x %d at %d, %d\n",
+ cache->xmax - cache->xmin,
+ cache->ymax - cache->ymin,
+ cache->xpos, cache->ypos);
*/
- /* The texture transfer has been mapped until now.
+ /* The texture transfer has been mapped until now.
* So unmap and release the texture transfer before drawing.
*/
- if (cache->trans) {
- if (0)
- print_cache(cache);
- pipe_transfer_unmap(pipe, cache->trans);
- cache->buffer = NULL;
-
- pipe->transfer_destroy(pipe, cache->trans);
- cache->trans = NULL;
- }
-
- sv = st_create_texture_sampler_view(st->pipe, cache->texture);
- if (sv) {
- draw_bitmap_quad(st->ctx,
- cache->xpos,
- cache->ypos,
- cache->zpos,
- BITMAP_CACHE_WIDTH, BITMAP_CACHE_HEIGHT,
- sv,
- cache->color);
-
- pipe_sampler_view_reference(&sv, NULL);
- }
+ if (cache->trans && cache->buffer) {
+ if (0)
+ print_cache(cache);
+ pipe_transfer_unmap(pipe, cache->trans);
+ cache->buffer = NULL;
+ cache->trans = NULL;
+ }
+
+ sv = st_create_texture_sampler_view(st->pipe, cache->texture);
+ if (sv) {
+ draw_bitmap_quad(st->ctx,
+ cache->xpos,
+ cache->ypos,
+ cache->zpos,
+ BITMAP_CACHE_WIDTH, BITMAP_CACHE_HEIGHT,
+ sv,
+ cache->color);
+
+ pipe_sampler_view_reference(&sv, NULL);
}
/* release/free the texture */
}
-/**
- * Flush bitmap cache and release vertex buffer.
- */
-void
-st_flush_bitmap( struct st_context *st )
-{
- st_flush_bitmap_cache(st);
-
- /* Release vertex buffer to avoid synchronous rendering if we were
- * to map it in the next frame.
- */
- pipe_resource_reference(&st->bitmap.vbuf, NULL);
- st->bitmap.vbuf_slot = 0;
-}
-
-
/**
* Try to accumulate this glBitmap call in the bitmap cache.
* \return GL_TRUE for success, GL_FALSE if bitmap is too large, etc.
*/
static GLboolean
-accum_bitmap(struct st_context *st,
+accum_bitmap(struct gl_context *ctx,
GLint x, GLint y, GLsizei width, GLsizei height,
const struct gl_pixelstore_attrib *unpack,
const GLubyte *bitmap )
{
+ struct st_context *st = ctx->st;
struct bitmap_cache *cache = st->bitmap.cache;
int px = -999, py = -999;
const GLfloat z = st->ctx->Current.RasterPos[2];
/* create the transfer if needed */
create_cache_trans(st);
+ /* PBO source... */
+ bitmap = _mesa_map_pbo_source(ctx, unpack, bitmap);
+ if (!bitmap) {
+ return FALSE;
+ }
+
unpack_bitmap(st, px, py, width, height, unpack, bitmap,
cache->buffer, BITMAP_CACHE_WIDTH);
+ _mesa_unmap_pbo_source(ctx, unpack);
+
return GL_TRUE; /* accumulated */
}
/* create pass-through vertex shader now */
const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
TGSI_SEMANTIC_COLOR,
+ st->needs_texcoord_semantic ? TGSI_SEMANTIC_TEXCOORD :
TGSI_SEMANTIC_GENERIC };
const uint semantic_indexes[] = { 0, 0, 0 };
st->bitmap.vs = util_make_vertex_passthrough_shader(st->pipe, 3,
semantic_indexes);
}
- if (UseBitmapCache && accum_bitmap(st, x, y, width, height, unpack, bitmap))
+ if (UseBitmapCache && accum_bitmap(ctx, x, y, width, height, unpack, bitmap))
return;
pt = make_bitmap_texture(ctx, width, height, unpack, bitmap);
/* init baseline rasterizer state once */
memset(&st->bitmap.rasterizer, 0, sizeof(st->bitmap.rasterizer));
- st->bitmap.rasterizer.gl_rasterization_rules = 1;
+ st->bitmap.rasterizer.half_pixel_center = 1;
+ st->bitmap.rasterizer.bottom_edge_rule = 1;
st->bitmap.rasterizer.depth_clip = 1;
/* find a usable texture format */
st->bitmap.vs = NULL;
}
- if (st->bitmap.vbuf) {
- pipe_resource_reference(&st->bitmap.vbuf, NULL);
- st->bitmap.vbuf = NULL;
- }
-
if (cache) {
- if (cache->trans) {
+ if (cache->trans && cache->buffer) {
pipe_transfer_unmap(pipe, cache->trans);
- pipe->transfer_destroy(pipe, cache->trans);
}
pipe_resource_reference(&st->bitmap.cache->texture, NULL);
free(st->bitmap.cache);
st->bitmap.cache = NULL;
}
}
-
-#endif /* FEATURE_drawpix */