#include "st_context.h"
#include "st_atom.h"
#include "st_atom_constbuf.h"
+#include "st_draw.h"
#include "st_program.h"
#include "st_cb_bitmap.h"
#include "st_texture.h"
#include "pipe/p_shader_tokens.h"
#include "util/u_inlines.h"
#include "util/u_simple_shaders.h"
-#include "util/u_upload_mgr.h"
#include "program/prog_instruction.h"
#include "cso_cache/cso_context.h"
{
struct st_context *st = st_context(ctx);
struct pipe_context *pipe = st->pipe;
- struct pipe_vertex_buffer vb = {0};
const float fb_width = (float) st->state.framebuffer.width;
const float fb_height = (float) st->state.framebuffer.height;
const float x0 = (float) x;
const float clip_y0 = y0 / fb_height * 2.0f - 1.0f;
const float clip_x1 = x1 / fb_width * 2.0f - 1.0f;
const float clip_y1 = y1 / fb_height * 2.0f - 1.0f;
- struct st_util_vertex *verts;
/* limit checks */
{
tBot = (float) height;
}
- vb.stride = sizeof(struct st_util_vertex);
-
- u_upload_alloc(st->uploader, 0, 4 * sizeof(struct st_util_vertex), 4,
- &vb.buffer_offset, &vb.buffer, (void **) &verts);
- if (!vb.buffer) {
+ if (!st_draw_quad(st, clip_x0, clip_y0, clip_x1, clip_y1, z,
+ sLeft, tBot, sRight, tTop, color, 0)) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glBitmap");
- restore_render_state(ctx);
- return;
}
- /* Positions are in clip coords since we need to do clipping in case
- * the bitmap quad goes beyond the window bounds.
- */
- verts[0].x = clip_x0;
- verts[0].y = clip_y0;
- verts[0].z = z;
- verts[0].r = color[0];
- verts[0].g = color[1];
- verts[0].b = color[2];
- verts[0].a = color[3];
- verts[0].s = sLeft;
- verts[0].t = tTop;
-
- verts[1].x = clip_x1;
- verts[1].y = clip_y0;
- verts[1].z = z;
- verts[1].r = color[0];
- verts[1].g = color[1];
- verts[1].b = color[2];
- verts[1].a = color[3];
- verts[1].s = sRight;
- verts[1].t = tTop;
-
- verts[2].x = clip_x1;
- verts[2].y = clip_y1;
- verts[2].z = z;
- verts[2].r = color[0];
- verts[2].g = color[1];
- verts[2].b = color[2];
- verts[2].a = color[3];
- verts[2].s = sRight;
- verts[2].t = tBot;
-
- verts[3].x = clip_x0;
- verts[3].y = clip_y1;
- verts[3].z = z;
- verts[3].r = color[0];
- verts[3].g = color[1];
- verts[3].b = color[2];
- verts[3].a = color[3];
- verts[3].s = sLeft;
- verts[3].t = tBot;
-
- u_upload_unmap(st->uploader);
-
- cso_set_vertex_buffers(st->cso_context,
- cso_get_aux_vertex_buffer_slot(st->cso_context),
- 1, &vb);
-
- cso_draw_arrays(st->cso_context, PIPE_PRIM_TRIANGLE_FAN, 0, 4);
-
restore_render_state(ctx);
- pipe_resource_reference(&vb.buffer, NULL);
-
/* We uploaded modified constants, need to invalidate them. */
st->dirty.mesa |= _NEW_PROGRAM_CONSTANTS;
}
#include "st_cb_bitmap.h"
#include "st_cb_clear.h"
#include "st_cb_fbo.h"
+#include "st_draw.h"
#include "st_format.h"
#include "st_program.h"
#include "util/u_framebuffer.h"
#include "util/u_inlines.h"
#include "util/u_simple_shaders.h"
-#include "util/u_upload_mgr.h"
#include "cso_cache/cso_context.h"
}
-/**
- * Draw a screen-aligned quadrilateral.
- * Coords are clip coords with y=0=bottom.
- */
-static void
-draw_quad(struct st_context *st,
- float x0, float y0, float x1, float y1, GLfloat z,
- unsigned num_instances,
- const union pipe_color_union *color)
-{
- struct cso_context *cso = st->cso_context;
- struct pipe_vertex_buffer vb = {0};
- struct st_util_vertex *verts;
-
- vb.stride = sizeof(struct st_util_vertex);
-
- u_upload_alloc(st->uploader, 0, 4 * sizeof(struct st_util_vertex), 4,
- &vb.buffer_offset, &vb.buffer, (void **) &verts);
- if (!vb.buffer) {
- return;
- }
-
- /* Convert Z from [0,1] to [-1,1] range */
- z = z * 2.0f - 1.0f;
-
- /* Note: if we're only clearing depth/stencil we still setup vertices
- * with color, but they'll be ignored.
- */
- verts[0].x = x0;
- verts[0].y = y0;
- verts[0].z = z;
- verts[0].r = color->f[0];
- verts[0].g = color->f[1];
- verts[0].b = color->f[2];
- verts[0].a = color->f[3];
-
- verts[1].x = x1;
- verts[1].y = y0;
- verts[1].z = z;
- verts[1].r = color->f[0];
- verts[1].g = color->f[1];
- verts[1].b = color->f[2];
- verts[1].a = color->f[3];
-
- verts[2].x = x1;
- verts[2].y = y1;
- verts[2].z = z;
- verts[2].r = color->f[0];
- verts[2].g = color->f[1];
- verts[2].b = color->f[2];
- verts[2].a = color->f[3];
-
- verts[3].x = x0;
- verts[3].y = y1;
- verts[3].z = z;
- verts[3].r = color->f[0];
- verts[3].g = color->f[1];
- verts[3].b = color->f[2];
- verts[3].a = color->f[3];
-
- u_upload_unmap(st->uploader);
-
- /* draw */
- cso_set_vertex_buffers(cso, cso_get_aux_vertex_buffer_slot(cso), 1, &vb);
- cso_draw_arrays_instanced(cso, PIPE_PRIM_TRIANGLE_FAN, 0, 4,
- 0, num_instances);
- pipe_resource_reference(&vb.buffer, NULL);
-}
-
-
-
/**
* Do glClear by drawing a quadrilateral.
* The vertices of the quad will be computed from the
else
set_vertex_shader(st);
- /* We can't translate the clear color to the colorbuffer format,
+ /* draw quad matching scissor rect.
+ *
+ * Note: if we're only clearing depth/stencil we still setup vertices
+ * with color, but they'll be ignored.
+ *
+ * We can't translate the clear color to the colorbuffer format,
* because different colorbuffers may have different formats.
*/
-
- /* draw quad matching scissor rect */
- draw_quad(st, x0, y0, x1, y1, (GLfloat) ctx->Depth.Clear, num_layers,
- (union pipe_color_union*)&ctx->Color.ClearColor);
+ if (!st_draw_quad(st, x0, y0, x1, y1,
+ ctx->Depth.Clear * 2.0f - 1.0f,
+ 0.0f, 0.0f, 0.0f, 0.0f,
+ (const float *) &ctx->Color.ClearColor.f,
+ num_layers)) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glClear");
+ }
/* Restore pipe state */
cso_restore_blend(st->cso_context);
#include "st_cb_fbo.h"
#include "st_context.h"
#include "st_debug.h"
+#include "st_draw.h"
#include "st_format.h"
#include "st_program.h"
#include "st_texture.h"
#include "util/u_inlines.h"
#include "util/u_math.h"
#include "util/u_tile.h"
-#include "util/u_upload_mgr.h"
#include "cso_cache/cso_context.h"
}
-/**
- * Draw quad with texcoords and optional color.
- * Coords are gallium window coords with y=0=top.
- * \param color may be null
- * \param invertTex if true, flip texcoords vertically
- */
-static void
-draw_quad(struct gl_context *ctx, GLfloat x0, GLfloat y0, GLfloat z,
- GLfloat x1, GLfloat y1, const GLfloat *color,
- GLboolean invertTex, GLfloat maxXcoord, GLfloat maxYcoord)
-{
- struct st_context *st = st_context(ctx);
- struct pipe_vertex_buffer vb = {0};
- struct st_util_vertex *verts;
-
- vb.stride = sizeof(struct st_util_vertex);
-
- u_upload_alloc(st->uploader, 0, 4 * sizeof(struct st_util_vertex), 4,
- &vb.buffer_offset, &vb.buffer, (void **) &verts);
- if (!vb.buffer) {
- return;
- }
-
- /* 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 = maxXcoord;
- const GLfloat tTop = invertTex ? maxYcoord : 0.0f;
- const GLfloat tBot = invertTex ? 0.0f : maxYcoord;
-
- /* upper-left */
- verts[0].x = clip_x0;
- verts[0].y = clip_y0;
- verts[0].z = z;
- verts[0].r = color[0];
- verts[0].g = color[1];
- verts[0].b = color[2];
- verts[0].a = color[3];
- verts[0].s = sLeft;
- verts[0].t = tTop;
-
- /* upper-right */
- verts[1].x = clip_x1;
- verts[1].y = clip_y0;
- verts[1].z = z;
- verts[1].r = color[0];
- verts[1].g = color[1];
- verts[1].b = color[2];
- verts[1].a = color[3];
- verts[1].s = sRight;
- verts[1].t = tTop;
-
- /* lower-right */
- verts[2].x = clip_x1;
- verts[2].y = clip_y1;
- verts[2].z = z;
- verts[2].r = color[0];
- verts[2].g = color[1];
- verts[2].b = color[2];
- verts[2].a = color[3];
- verts[2].s = sRight;
- verts[2].t = tBot;
-
- /* lower-left */
- verts[3].x = clip_x0;
- verts[3].y = clip_y1;
- verts[3].z = z;
- verts[3].r = color[0];
- verts[3].g = color[1];
- verts[3].b = color[2];
- verts[3].a = color[3];
- verts[3].s = sLeft;
- verts[3].t = tBot;
- }
-
- u_upload_unmap(st->uploader);
-
- cso_set_vertex_buffers(st->cso_context,
- cso_get_aux_vertex_buffer_slot(st->cso_context),
- 1, &vb);
-
- cso_draw_arrays(st->cso_context, PIPE_PRIM_QUADS, 0, 4);
-
- pipe_resource_reference(&vb.buffer, NULL);
-}
-
-
-
static void
draw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
GLsizei width, GLsizei height,
/* convert Z from [0,1] to [-1,-1] to match viewport Z scale/bias */
z = z * 2.0f - 1.0f;
- draw_quad(ctx, x0, y0, z, x1, y1, color, invertTex,
- normalized ? ((GLfloat) width / sv[0]->texture->width0) : (GLfloat)width,
- normalized ? ((GLfloat) height / sv[0]->texture->height0) : (GLfloat)height);
+ {
+ const struct gl_framebuffer *fb = ctx->DrawBuffer;
+ const float fb_width = (float) fb->Width;
+ const float fb_height = (float) fb->Height;
+ const float clip_x0 = x0 / fb_width * 2.0f - 1.0f;
+ const float clip_y0 = y0 / fb_height * 2.0f - 1.0f;
+ const float clip_x1 = x1 / fb_width * 2.0f - 1.0f;
+ const float clip_y1 = y1 / fb_height * 2.0f - 1.0f;
+ const float maxXcoord = normalized ?
+ ((float) width / sv[0]->texture->width0) : (float) width;
+ const float maxYcoord = normalized
+ ? ((float) height / sv[0]->texture->height0) : (float) height;
+ const float sLeft = 0.0f, sRight = maxXcoord;
+ const float tTop = invertTex ? maxYcoord : 0.0f;
+ const float tBot = invertTex ? 0.0f : maxYcoord;
+
+ if (!st_draw_quad(ctx->st, clip_x0, clip_y0, clip_x1, clip_y1, z,
+ sLeft, tBot, sRight, tTop, color, 0)) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels");
+ }
+ }
/* restore state */
cso_restore_rasterizer(cso);
{
draw_destroy(st->draw);
}
+
+
+/**
+ * Draw a quad with given position, texcoords and color.
+ */
+bool
+st_draw_quad(struct st_context *st,
+ float x0, float y0, float x1, float y1, float z,
+ float s0, float t0, float s1, float t1,
+ const float *color,
+ unsigned num_instances)
+{
+ struct pipe_vertex_buffer vb = {0};
+ struct st_util_vertex *verts;
+
+ vb.stride = sizeof(struct st_util_vertex);
+
+ u_upload_alloc(st->uploader, 0, 4 * sizeof(struct st_util_vertex), 4,
+ &vb.buffer_offset, &vb.buffer, (void **) &verts);
+ if (!vb.buffer) {
+ return false;
+ }
+
+ /* lower-left */
+ verts[0].x = x0;
+ verts[0].y = y1;
+ verts[0].z = z;
+ verts[0].r = color[0];
+ verts[0].g = color[1];
+ verts[0].b = color[2];
+ verts[0].a = color[3];
+ verts[0].s = s0;
+ verts[0].t = t0;
+
+ /* lower-right */
+ verts[1].x = x1;
+ verts[1].y = y1;
+ verts[1].z = z;
+ verts[1].r = color[0];
+ verts[1].g = color[1];
+ verts[1].b = color[2];
+ verts[1].a = color[3];
+ verts[1].s = s1;
+ verts[1].t = t0;
+
+ /* upper-right */
+ verts[2].x = x1;
+ verts[2].y = y0;
+ verts[2].z = z;
+ verts[2].r = color[0];
+ verts[2].g = color[1];
+ verts[2].b = color[2];
+ verts[2].a = color[3];
+ verts[2].s = s1;
+ verts[2].t = t1;
+
+ /* upper-left */
+ verts[3].x = x0;
+ verts[3].y = y0;
+ verts[3].z = z;
+ verts[3].r = color[0];
+ verts[3].g = color[1];
+ verts[3].b = color[2];
+ verts[3].a = color[3];
+ verts[3].s = s0;
+ verts[3].t = t1;
+
+ u_upload_unmap(st->uploader);
+
+ /* At the time of writing, cso_get_aux_vertex_buffer_slot() always returns
+ * zero. If that ever changes we need to audit the calls to that function
+ * and make sure the slot number is used consistently everywhere.
+ */
+ assert(cso_get_aux_vertex_buffer_slot(st->cso_context) == 0);
+
+ cso_set_vertex_buffers(st->cso_context,
+ cso_get_aux_vertex_buffer_slot(st->cso_context),
+ 1, &vb);
+
+ if (num_instances > 1) {
+ cso_draw_arrays_instanced(st->cso_context, PIPE_PRIM_TRIANGLE_FAN, 0, 4,
+ 0, num_instances);
+ } else {
+ cso_draw_arrays(st->cso_context, PIPE_PRIM_TRIANGLE_FAN, 0, 4);
+ }
+
+ pipe_resource_reference(&vb.buffer, NULL);
+
+ return true;
+}
}
+bool
+st_draw_quad(struct st_context *st,
+ float x0, float y0, float x1, float y1, float z,
+ float s0, float t0, float s1, float t1,
+ const float *color,
+ unsigned num_instances);
+
#endif