#include "main/macros.h"
#include "main/texformat.h"
#include "main/texstore.h"
-#include "main/state.h"
#include "shader/program.h"
-#include "shader/prog_parameter.h"
#include "shader/prog_print.h"
#include "st_debug.h"
#include "st_context.h"
#include "st_atom.h"
#include "st_atom_constbuf.h"
-#include "st_draw.h"
#include "st_program.h"
#include "st_cb_drawpixels.h"
#include "st_cb_readpixels.h"
#include "st_cb_fbo.h"
-#include "st_cb_texture.h"
-#include "st_draw.h"
#include "st_format.h"
-#include "st_mesa_to_tgsi.h"
#include "st_texture.h"
#include "st_inlines.h"
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
-#include "pipe/p_inlines.h"
+#include "util/u_inlines.h"
#include "tgsi/tgsi_ureg.h"
#include "util/u_tile.h"
#include "util/u_draw_quad.h"
+#include "util/u_format.h"
#include "util/u_math.h"
#include "util/u_rect.h"
#include "shader/prog_instruction.h"
/**
* Make fragment shader for glDraw/CopyPixels. This shader is made
* by combining the pixel transfer shader with the user-defined shader.
+ * \return pointer to Gallium driver fragment shader
*/
-static struct st_fragment_program *
+static void *
combined_drawpix_fragment_program(GLcontext *ctx)
{
struct st_context *st = st_context(ctx);
*/
if (is_passthrough_program(&st->fp->Base)) {
stfp = (struct st_fragment_program *)
- _mesa_clone_program(ctx, &st->pixel_xfer.program->Base.Base);
+ _mesa_clone_fragment_program(ctx, &st->pixel_xfer.program->Base);
}
else {
#if 0
#endif
/* translate to TGSI tokens */
- st_translate_fragment_program(st, stfp, NULL);
+ st_translate_fragment_program(st, stfp);
/* save new program, update serial numbers */
st->pixel_xfer.xfer_prog_sn = st->pixel_xfer.program->serialNo;
*/
st_upload_constants(st, stfp->Base.Base.Parameters, PIPE_SHADER_FRAGMENT);
- return stfp;
+ return stfp->driver_shader;
}
* Create fragment shader that does a TEX() instruction to get a Z
* value, then writes to FRAG_RESULT_DEPTH.
* Pass fragment color through as-is.
+ * \return pointer to the Gallium driver fragment shader
*/
-static struct st_fragment_program *
+static void *
make_fragment_shader_z(struct st_context *st)
{
GLcontext *ctx = st->ctx;
GLuint ic = 0;
if (st->drawpix.z_shader) {
- return st->drawpix.z_shader;
+ return st->drawpix.z_shader->driver_shader;
}
/*
p->SamplersUsed = 0x1; /* sampler 0 (bit 0) is used */
st->drawpix.z_shader = (struct st_fragment_program *) p;
- st_translate_fragment_program(st, st->drawpix.z_shader, NULL);
+ st_translate_fragment_program(st, st->drawpix.z_shader);
- return st->drawpix.z_shader;
+ return st->drawpix.z_shader->driver_shader;
}
* vertex position and texcoord (and optionally, color).
*/
static void *
-st_make_passthrough_vertex_shader(struct st_context *st,
- GLboolean passColor)
+make_passthrough_vertex_shader(struct st_context *st,
+ GLboolean passColor)
{
if (!st->drawpix.vert_shaders[passColor]) {
struct ureg_program *ureg =
}
+/**
+ * Return a texture internalFormat for drawing/copying an image
+ * of the given type.
+ */
static GLenum
-_mesa_base_format(GLenum format)
+base_format(GLenum format)
{
switch (format) {
case GL_DEPTH_COMPONENT:
}
+/**
+ * Create a temporary texture to hold an image of the given size.
+ * If width, height are not POT and the driver only handles POT textures,
+ * allocate the next larger size of texture that is POT.
+ */
+static struct pipe_texture *
+alloc_texture(struct st_context *st, GLsizei width, GLsizei height,
+ enum pipe_format texFormat)
+{
+ struct pipe_context *pipe = st->pipe;
+ struct pipe_screen *screen = pipe->screen;
+ struct pipe_texture *pt;
+ int ptw, pth;
+
+ ptw = width;
+ pth = height;
+
+ /* Need to use POT texture? */
+ if (!screen->get_param(screen, PIPE_CAP_NPOT_TEXTURES)) {
+ int l2pt, maxSize;
+
+ l2pt = util_logbase2(width);
+ if (1 << l2pt != width) {
+ ptw = 1 << (l2pt + 1);
+ }
+
+ l2pt = util_logbase2(height);
+ if (1 << l2pt != height) {
+ pth = 1 << (l2pt + 1);
+ }
+
+ /* Check against maximum texture size */
+ maxSize = 1 << (pipe->screen->get_param(pipe->screen,
+ PIPE_CAP_MAX_TEXTURE_2D_LEVELS) - 1);
+ assert(ptw <= maxSize);
+ assert(pth <= maxSize);
+ }
+
+ pt = st_texture_create(st, PIPE_TEXTURE_2D, texFormat, 0,
+ ptw, pth, 1, PIPE_TEXTURE_USAGE_SAMPLER);
+
+ return pt;
+}
+
+
/**
* Make texture containing an image for glDrawPixels image.
* If 'pixels' is NULL, leave the texture image data undefined.
{
GLcontext *ctx = st->ctx;
struct pipe_context *pipe = st->pipe;
- struct pipe_screen *screen = pipe->screen;
gl_format mformat;
struct pipe_texture *pt;
enum pipe_format pipeFormat;
GLuint cpp;
GLenum baseFormat;
- int ptw, pth;
- baseFormat = _mesa_base_format(format);
+ baseFormat = base_format(format);
mformat = st_ChooseTextureFormat(ctx, baseFormat, format, type);
assert(mformat);
pipeFormat = st_mesa_format_to_pipe_format(mformat);
assert(pipeFormat);
- cpp = st_sizeof_format(pipeFormat);
+ cpp = util_format_get_blocksize(pipeFormat);
pixels = _mesa_map_pbo_source(ctx, unpack, pixels);
if (!pixels)
return NULL;
- /* Need to use POT texture? */
- ptw = width;
- pth = height;
- if (!screen->get_param(screen, PIPE_CAP_NPOT_TEXTURES)) {
- int l2pt, maxSize;
-
- l2pt = util_logbase2(width);
- if (1<<l2pt != width) {
- ptw = 1<<(l2pt+1);
- }
- l2pt = util_logbase2(height);
- if (1<<l2pt != height) {
- pth = 1<<(l2pt+1);
- }
-
- /* Check against maximum texture size */
- maxSize = 1 << (pipe->screen->get_param(pipe->screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS) - 1);
- assert(ptw <= maxSize);
- assert(pth <= maxSize);
- }
-
- pt = st_texture_create(st, PIPE_TEXTURE_2D, pipeFormat, 0, ptw, pth, 1,
- PIPE_TEXTURE_USAGE_SAMPLER);
+ /* alloc temporary texture */
+ pt = alloc_texture(st, width, height, pipeFormat);
if (!pt) {
_mesa_unmap_pbo_source(ctx, unpack);
return NULL;
width, height);
/* map texture transfer */
- dest = screen->transfer_map(screen, transfer);
+ dest = pipe->transfer_map(pipe, transfer);
/* Put image into texture transfer.
unpack);
/* unmap */
- screen->transfer_unmap(screen, transfer);
- screen->tex_transfer_destroy(transfer);
+ pipe->transfer_unmap(pipe, transfer);
+ pipe->tex_transfer_destroy(pipe, transfer);
assert(success);
/**
* Draw quad with texcoords and optional color.
- * Coords are window coords with y=0=bottom.
+ * Coords are gallium window coords with y=0=top.
* \param color may be null
* \param invertTex if true, flip texcoords vertically
*/
draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
GLsizei width, GLsizei height,
GLfloat zoomX, GLfloat zoomY,
- struct pipe_texture *pt,
+ struct pipe_sampler_view *sv,
void *driver_vp,
void *driver_fp,
const GLfloat *color,
cso_save_rasterizer(cso);
cso_save_viewport(cso);
cso_save_samplers(cso);
- cso_save_sampler_textures(cso);
+ cso_save_fragment_sampler_views(cso);
cso_save_fragment_shader(cso);
cso_save_vertex_shader(cso);
+ cso_save_vertex_elements(cso);
/* rasterizer state: just scissor */
{
struct pipe_viewport_state vp;
vp.scale[0] = 0.5f * w;
vp.scale[1] = -0.5f * h;
- vp.scale[2] = 1.0f;
+ vp.scale[2] = 0.5f;
vp.scale[3] = 1.0f;
vp.translate[0] = 0.5f * w;
vp.translate[1] = 0.5f * h;
- vp.translate[2] = 0.0f;
+ vp.translate[2] = 0.5f;
vp.translate[3] = 0.0f;
cso_set_viewport(cso, &vp);
}
+ cso_set_vertex_elements(cso, 3, st->velems_util_draw);
+
/* texture state: */
if (st->pixel_xfer.pixelmap_enabled) {
- struct pipe_texture *textures[2];
- textures[0] = pt;
- textures[1] = st->pixel_xfer.pixelmap_texture;
- pipe->set_sampler_textures(pipe, 2, textures);
+ struct pipe_sampler_view *sampler_views[2];
+ sampler_views[0] = sv;
+ sampler_views[1] = st->pixel_xfer.pixelmap_sampler_view;
+ cso_set_fragment_sampler_views(cso, 2, sampler_views);
}
else {
- pipe->set_sampler_textures(pipe, 1, &pt);
+ cso_set_fragment_sampler_views(cso, 1, &sv);
}
- /* Compute window coords (y=0=bottom) with pixel zoom.
+ /* Compute Gallium window coords (y=0=top) with pixel zoom.
* Recall that these coords are transformed by the current
* vertex shader and viewport transformation.
*/
+ if (st_fb_orientation(ctx->DrawBuffer) == Y_0_BOTTOM) {
+ y = ctx->DrawBuffer->Height - (int) (y + height * ctx->Pixel.ZoomY);
+ invertTex = !invertTex;
+ }
+
x0 = (GLfloat) x;
x1 = x + width * ctx->Pixel.ZoomX;
y0 = (GLfloat) y;
y1 = y + height * ctx->Pixel.ZoomY;
+ /* convert Z from [0,1] to [-1,-1] to match viewport Z scale/bias */
+ z = z * 2.0 - 1.0;
+
draw_quad(ctx, x0, y0, z, x1, y1, color, invertTex,
- (GLfloat) width / pt->width0,
- (GLfloat) height / pt->height0);
+ (GLfloat) width / sv->texture->width0,
+ (GLfloat) height / sv->texture->height0);
/* restore state */
cso_restore_rasterizer(cso);
cso_restore_viewport(cso);
cso_restore_samplers(cso);
- cso_restore_sampler_textures(cso);
+ cso_restore_fragment_sampler_views(cso);
cso_restore_fragment_shader(cso);
cso_restore_vertex_shader(cso);
+ cso_restore_vertex_elements(cso);
}
{
struct st_context *st = st_context(ctx);
struct pipe_context *pipe = st->pipe;
- struct pipe_screen *screen = pipe->screen;
struct st_renderbuffer *strb;
enum pipe_transfer_usage usage;
struct pipe_transfer *pt;
}
if(format != GL_DEPTH_STENCIL &&
- pf_get_component_bits( strb->format, PIPE_FORMAT_COMP_Z ) != 0)
+ util_format_get_component_bits(strb->format, UTIL_FORMAT_COLORSPACE_ZS, 0) != 0)
usage = PIPE_TRANSFER_READ_WRITE;
else
usage = PIPE_TRANSFER_WRITE;
usage, x, y,
width, height);
- stmap = screen->transfer_map(screen, pt);
+ stmap = pipe->transfer_map(pipe, pt);
pixels = _mesa_map_pbo_source(ctx, &clippedUnpack, pixels);
assert(pixels);
}
/* now pack the stencil (and Z) values in the dest format */
- switch (pt->format) {
+ switch (pt->texture->format) {
case PIPE_FORMAT_S8_UNORM:
{
ubyte *dest = stmap + spanY * pt->stride + spanX;
memcpy(dest, sValues, spanWidth);
}
break;
- case PIPE_FORMAT_S8Z24_UNORM:
+ case PIPE_FORMAT_Z24S8_UNORM:
if (format == GL_DEPTH_STENCIL) {
uint *dest = (uint *) (stmap + spanY * pt->stride + spanX*4);
GLint k;
}
}
break;
- case PIPE_FORMAT_Z24S8_UNORM:
+ case PIPE_FORMAT_S8Z24_UNORM:
if (format == GL_DEPTH_STENCIL) {
uint *dest = (uint *) (stmap + spanY * pt->stride + spanX*4);
GLint k;
_mesa_unmap_pbo_source(ctx, &clippedUnpack);
/* unmap the stencil buffer */
- screen->transfer_unmap(screen, pt);
- screen->tex_transfer_destroy(pt);
+ pipe->transfer_unmap(pipe, pt);
+ pipe->tex_transfer_destroy(pipe, pt);
}
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *unpack, const GLvoid *pixels)
{
- struct st_fragment_program *stfp;
- void *driver_vp;
+ void *driver_vp, *driver_fp;
struct st_context *st = st_context(ctx);
- struct pipe_surface *ps;
const GLfloat *color;
if (format == GL_STENCIL_INDEX ||
st_validate_state(st);
if (format == GL_DEPTH_COMPONENT) {
- ps = st->state.framebuffer.zsbuf;
- stfp = make_fragment_shader_z(st);
- driver_vp = st_make_passthrough_vertex_shader(st, GL_TRUE);
+ driver_fp = make_fragment_shader_z(st);
+ driver_vp = make_passthrough_vertex_shader(st, GL_TRUE);
color = ctx->Current.RasterColor;
}
else {
- ps = st->state.framebuffer.cbufs[0];
- stfp = combined_drawpix_fragment_program(ctx);
- driver_vp = st_make_passthrough_vertex_shader(st, GL_FALSE);
+ driver_fp = combined_drawpix_fragment_program(ctx);
+ driver_vp = make_passthrough_vertex_shader(st, GL_FALSE);
color = NULL;
}
struct pipe_texture *pt
= make_texture(st, width, height, format, type, unpack, pixels);
if (pt) {
- draw_textured_quad(ctx, x, y, ctx->Current.RasterPos[2],
- width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY,
- pt,
- driver_vp,
- stfp->driver_shader,
- color, GL_FALSE);
+ struct pipe_sampler_view *sv = st_sampler_view_from_texture(st->pipe, pt);
+
+ if (sv) {
+ draw_textured_quad(ctx, x, y, ctx->Current.RasterPos[2],
+ width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY,
+ sv,
+ driver_vp,
+ driver_fp,
+ color, GL_FALSE);
+ pipe_sampler_view_reference(&sv, NULL);
+ }
pipe_texture_reference(&pt, NULL);
}
}
GLint dstx, GLint dsty)
{
struct st_renderbuffer *rbDraw = st_renderbuffer(ctx->DrawBuffer->_StencilBuffer);
- struct pipe_screen *screen = ctx->st->pipe->screen;
+ struct pipe_context *pipe = ctx->st->pipe;
enum pipe_transfer_usage usage;
struct pipe_transfer *ptDraw;
ubyte *drawMap;
ubyte *buffer;
int i;
- buffer = _mesa_malloc(width * height * sizeof(ubyte));
+ buffer = malloc(width * height * sizeof(ubyte));
if (!buffer) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels(stencil)");
return;
GL_STENCIL_INDEX, GL_UNSIGNED_BYTE,
&ctx->DefaultPacking, buffer);
- if(pf_get_component_bits( rbDraw->format, PIPE_FORMAT_COMP_Z ) != 0)
+ if(util_format_get_component_bits(rbDraw->format, UTIL_FORMAT_COLORSPACE_ZS, 0) != 0)
usage = PIPE_TRANSFER_READ_WRITE;
else
usage = PIPE_TRANSFER_WRITE;
usage, dstx, dsty,
width, height);
- assert(ptDraw->block.width == 1);
- assert(ptDraw->block.height == 1);
+ assert(util_format_get_blockwidth(ptDraw->texture->format) == 1);
+ assert(util_format_get_blockheight(ptDraw->texture->format) == 1);
/* map the stencil buffer */
- drawMap = screen->transfer_map(screen, ptDraw);
+ drawMap = pipe->transfer_map(pipe, ptDraw);
/* draw */
/* XXX PixelZoom not handled yet */
dst = drawMap + y * ptDraw->stride;
src = buffer + i * width;
- switch (ptDraw->format) {
- case PIPE_FORMAT_S8Z24_UNORM:
+ switch (ptDraw->texture->format) {
+ case PIPE_FORMAT_Z24S8_UNORM:
{
uint *dst4 = (uint *) dst;
int j;
}
}
break;
- case PIPE_FORMAT_Z24S8_UNORM:
+ case PIPE_FORMAT_S8Z24_UNORM:
{
uint *dst4 = (uint *) dst;
int j;
}
}
- _mesa_free(buffer);
+ free(buffer);
/* unmap the stencil buffer */
- screen->transfer_unmap(screen, ptDraw);
- screen->tex_transfer_destroy(ptDraw);
+ pipe->transfer_unmap(pipe, ptDraw);
+ pipe->tex_transfer_destroy(pipe, ptDraw);
}
struct pipe_context *pipe = st->pipe;
struct pipe_screen *screen = pipe->screen;
struct st_renderbuffer *rbRead;
- void *driver_vp;
- struct st_fragment_program *stfp;
+ void *driver_vp, *driver_fp;
struct pipe_texture *pt;
+ struct pipe_sampler_view *sv;
GLfloat *color;
enum pipe_format srcFormat, texFormat;
- int ptw, pth;
+ GLboolean invertTex = GL_FALSE;
pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
if (type == GL_COLOR) {
rbRead = st_get_color_read_renderbuffer(ctx);
color = NULL;
- stfp = combined_drawpix_fragment_program(ctx);
- driver_vp = st_make_passthrough_vertex_shader(st, GL_FALSE);
+ driver_fp = combined_drawpix_fragment_program(ctx);
+ driver_vp = make_passthrough_vertex_shader(st, GL_FALSE);
}
else {
assert(type == GL_DEPTH);
rbRead = st_renderbuffer(ctx->ReadBuffer->_DepthBuffer);
color = ctx->Current.Attrib[VERT_ATTRIB_COLOR0];
- stfp = make_fragment_shader_z(st);
- driver_vp = st_make_passthrough_vertex_shader(st, GL_TRUE);
+ driver_fp = make_fragment_shader_z(st);
+ driver_vp = make_passthrough_vertex_shader(st, GL_TRUE);
}
srcFormat = rbRead->texture->format;
}
}
- if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
- srcy = ctx->DrawBuffer->Height - srcy - height;
+ if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
+ srcy = ctx->ReadBuffer->Height - srcy - height;
if (srcy < 0) {
height -= -srcy;
if (height < 0)
return;
- }
-
- /* Need to use POT texture? */
- ptw = width;
- pth = height;
- if (!screen->get_param(screen, PIPE_CAP_NPOT_TEXTURES)) {
- int l2pt, maxSize;
- l2pt = util_logbase2(width);
- if (1<<l2pt != width) {
- ptw = 1<<(l2pt+1);
- }
- l2pt = util_logbase2(height);
- if (1<<l2pt != height) {
- pth = 1<<(l2pt+1);
- }
-
- /* Check against maximum texture size */
- maxSize = 1 << (pipe->screen->get_param(pipe->screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS) - 1);
- assert(ptw <= maxSize);
- assert(pth <= maxSize);
+ invertTex = !invertTex;
}
- pt = st_texture_create(st, PIPE_TEXTURE_2D, texFormat, 0,
- ptw, pth, 1,
- PIPE_TEXTURE_USAGE_SAMPLER);
+ /* alloc temporary texture */
+ pt = alloc_texture(st, width, height, texFormat);
if (!pt)
return;
+ sv = st_sampler_view_from_texture(st->pipe, pt);
+ if (!sv) {
+ pipe_texture_reference(&pt, NULL);
+ return;
+ }
+ /* Make temporary texture which is a copy of the src region.
+ * We'll draw a quad with this texture to draw the dest image.
+ */
if (srcFormat == texFormat) {
/* copy source framebuffer surface into mipmap/texture */
struct pipe_surface *psRead = screen->get_tex_surface(screen,
psRead,
srcx, srcy, width, height);
}
+
+ if (0) {
+ /* debug */
+ debug_dump_surface(pipe, "copypixsrcsurf", psRead);
+ debug_dump_surface(pipe, "copypixtemptex", psTex);
+ }
+
pipe_surface_reference(&psRead, NULL);
pipe_surface_reference(&psTex, NULL);
}
if (ST_DEBUG & DEBUG_FALLBACK)
debug_printf("%s: fallback processing\n", __FUNCTION__);
- if (type == GL_DEPTH && pf_is_depth_and_stencil(pt->format))
+ if (type == GL_DEPTH && util_format_is_depth_and_stencil(pt->format))
transfer_usage = PIPE_TRANSFER_READ_WRITE;
else
transfer_usage = PIPE_TRANSFER_WRITE;
if (type == GL_COLOR) {
/* alternate path using get/put_tile() */
- GLfloat *buf = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));
+ GLfloat *buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
- pipe_get_tile_rgba(ptRead, 0, 0, width, height, buf);
- pipe_put_tile_rgba(ptTex, 0, 0, width, height, buf);
+ pipe_get_tile_rgba(pipe, ptRead, 0, 0, width, height, buf);
+ pipe_put_tile_rgba(pipe, ptTex, 0, 0, width, height, buf);
- _mesa_free(buf);
+ free(buf);
}
else {
/* GL_DEPTH */
- GLuint *buf = (GLuint *) _mesa_malloc(width * height * sizeof(GLuint));
- pipe_get_tile_z(ptRead, 0, 0, width, height, buf);
- pipe_put_tile_z(ptTex, 0, 0, width, height, buf);
- _mesa_free(buf);
+ GLuint *buf = (GLuint *) malloc(width * height * sizeof(GLuint));
+ pipe_get_tile_z(pipe, ptRead, 0, 0, width, height, buf);
+ pipe_put_tile_z(pipe, ptTex, 0, 0, width, height, buf);
+ free(buf);
}
- screen->tex_transfer_destroy(ptRead);
- screen->tex_transfer_destroy(ptTex);
+ pipe->tex_transfer_destroy(pipe, ptRead);
+ pipe->tex_transfer_destroy(pipe, ptTex);
}
/* draw textured quad */
draw_textured_quad(ctx, dstx, dsty, ctx->Current.RasterPos[2],
width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY,
- pt,
+ sv,
driver_vp,
- stfp->driver_shader,
- color, GL_TRUE);
+ driver_fp,
+ color, invertTex);
pipe_texture_reference(&pt, NULL);
+ pipe_sampler_view_reference(&sv, NULL);
}
{
st_reference_fragprog(st, &st->drawpix.z_shader, NULL);
st_reference_fragprog(st, &st->pixel_xfer.combined_prog, NULL);
- st_reference_vertprog(st, &st->drawpix.vert_shaders[0], NULL);
- st_reference_vertprog(st, &st->drawpix.vert_shaders[1], NULL);
+ if (st->drawpix.vert_shaders[0])
+ free(st->drawpix.vert_shaders[0]);
+ if (st->drawpix.vert_shaders[1])
+ free(st->drawpix.vert_shaders[1]);
}