summaryrefslogtreecommitdiff
path: root/src/mesa
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/shader/prog_parameter.c22
-rw-r--r--src/mesa/shader/prog_parameter.h2
-rw-r--r--src/mesa/shader/program.c2
-rw-r--r--src/mesa/shader/slang/slang_codegen.c3
-rw-r--r--src/mesa/shader/slang/slang_compile.c3
-rw-r--r--src/mesa/shader/slang/slang_typeinfo.h1
-rw-r--r--src/mesa/state_tracker/st_atom.c3
-rw-r--r--src/mesa/state_tracker/st_atom.h1
-rw-r--r--src/mesa/state_tracker/st_atom_framebuffer.c65
-rw-r--r--src/mesa/state_tracker/st_atom_pixeltransfer.c12
-rw-r--r--src/mesa/state_tracker/st_atom_shader.c28
-rw-r--r--src/mesa/state_tracker/st_atom_texture.c80
-rw-r--r--src/mesa/state_tracker/st_cb_accum.c85
-rw-r--r--src/mesa/state_tracker/st_cb_bitmap.c43
-rw-r--r--src/mesa/state_tracker/st_cb_drawpixels.c107
-rw-r--r--src/mesa/state_tracker/st_cb_fbo.c189
-rw-r--r--src/mesa/state_tracker/st_cb_fbo.h6
-rw-r--r--src/mesa/state_tracker/st_cb_feedback.c7
-rw-r--r--src/mesa/state_tracker/st_cb_program.c1
-rw-r--r--src/mesa/state_tracker/st_cb_readpixels.c41
-rw-r--r--src/mesa/state_tracker/st_cb_texture.c108
-rw-r--r--src/mesa/state_tracker/st_context.h3
-rw-r--r--src/mesa/state_tracker/st_gen_mipmap.c6
-rw-r--r--src/mesa/state_tracker/st_texture.c61
-rw-r--r--src/mesa/state_tracker/st_texture.h14
25 files changed, 600 insertions, 293 deletions
diff --git a/src/mesa/shader/prog_parameter.c b/src/mesa/shader/prog_parameter.c
index 0b61bac696..152bd79f69 100644
--- a/src/mesa/shader/prog_parameter.c
+++ b/src/mesa/shader/prog_parameter.c
@@ -283,25 +283,31 @@ _mesa_add_uniform(struct gl_program_parameter_list *paramList,
* \param name uniform's name
* \param datatype GL_SAMPLER_2D, GL_SAMPLER_2D_RECT_ARB, etc.
* \param index the sampler number (as seen in TEX instructions)
+ * \return sampler index (starting at zero) or -1 if error
*/
GLint
_mesa_add_sampler(struct gl_program_parameter_list *paramList,
- const char *name, GLenum datatype, GLuint index)
+ const char *name, GLenum datatype)
{
GLint i = _mesa_lookup_parameter_index(paramList, -1, name);
if (i >= 0 && paramList->Parameters[i].Type == PROGRAM_SAMPLER) {
ASSERT(paramList->Parameters[i].Size == 1);
ASSERT(paramList->Parameters[i].DataType == datatype);
- ASSERT(paramList->ParameterValues[i][0] == index);
/* already in list */
- return i;
+ return (GLint) paramList->ParameterValues[i][0];
}
else {
- GLfloat indexf = index;
const GLint size = 1; /* a sampler is basically a texture unit number */
- i = _mesa_add_parameter(paramList, PROGRAM_SAMPLER, name,
- size, datatype, &indexf, NULL);
- return i;
+ GLfloat value;
+ GLint numSamplers = 0;
+ for (i = 0; i < paramList->NumParameters; i++) {
+ if (paramList->Parameters[i].Type == PROGRAM_SAMPLER)
+ numSamplers++;
+ }
+ value = (GLfloat) numSamplers;
+ (void) _mesa_add_parameter(paramList, PROGRAM_SAMPLER, name,
+ size, datatype, &value, NULL);
+ return numSamplers;
}
}
@@ -602,6 +608,8 @@ _mesa_clone_parameter_list(const struct gl_program_parameter_list *list)
}
}
+ clone->StateFlags = list->StateFlags;
+
return clone;
}
diff --git a/src/mesa/shader/prog_parameter.h b/src/mesa/shader/prog_parameter.h
index d6cc03448c..105f6f24de 100644
--- a/src/mesa/shader/prog_parameter.h
+++ b/src/mesa/shader/prog_parameter.h
@@ -114,7 +114,7 @@ _mesa_add_uniform(struct gl_program_parameter_list *paramList,
extern GLint
_mesa_add_sampler(struct gl_program_parameter_list *paramList,
- const char *name, GLenum datatype, GLuint index);
+ const char *name, GLenum datatype);
extern GLint
_mesa_add_varying(struct gl_program_parameter_list *paramList,
diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c
index e06ab5aa23..a0817a91ec 100644
--- a/src/mesa/shader/program.c
+++ b/src/mesa/shader/program.c
@@ -602,7 +602,7 @@ _mesa_combine_programs(GLcontext *ctx,
if ((progA->OutputsWritten & (1 << FRAG_RESULT_COLR)) &&
(progB->InputsRead & (1 << FRAG_ATTRIB_COL0))) {
GLint tempReg = _mesa_find_free_register(newProg, PROGRAM_TEMPORARY);
- if (!tempReg) {
+ if (tempReg < 0) {
_mesa_problem(ctx, "No free temp regs found in "
"_mesa_combine_programs(), using 31");
tempReg = 31;
diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index 8e4c10ff43..d19d5a0abb 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -2841,8 +2841,7 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var,
* store->Index = sampler number (0..7, typically)
* store->Size = texture type index (1D, 2D, 3D, cube, etc)
*/
- const GLint sampNum = A->numSamplers++;
- _mesa_add_sampler(prog->Parameters, varName, datatype, sampNum);
+ GLint sampNum = _mesa_add_sampler(prog->Parameters, varName, datatype);
store = _slang_new_ir_storage(PROGRAM_SAMPLER, sampNum, texIndex);
if (dbg) printf("SAMPLER ");
}
diff --git a/src/mesa/shader/slang/slang_compile.c b/src/mesa/shader/slang/slang_compile.c
index 1449888f9f..46b5c54bbe 100644
--- a/src/mesa/shader/slang/slang_compile.c
+++ b/src/mesa/shader/slang/slang_compile.c
@@ -1620,7 +1620,6 @@ parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O,
A.program = O->program;
A.vartable = O->vartable;
A.curFuncEndLabel = NULL;
- A.numSamplers = 0;
if (!_slang_codegen_global_variable(&A, var, C->type))
return 0;
}
@@ -1643,7 +1642,6 @@ parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O,
A.space.funcs = O->funs;
A.space.structs = O->structs;
A.space.vars = O->vars;
- A.numSamplers = 0;
if (!initialize_global(&A, var))
return 0;
}
@@ -1777,7 +1775,6 @@ parse_function(slang_parse_ctx * C, slang_output_ctx * O, int definition,
A.program = O->program;
A.vartable = O->vartable;
A.log = C->L;
- A.numSamplers = 0;
_slang_codegen_function(&A, *parsed_func_ret);
}
diff --git a/src/mesa/shader/slang/slang_typeinfo.h b/src/mesa/shader/slang/slang_typeinfo.h
index ad5aa3e195..587331e8b1 100644
--- a/src/mesa/shader/slang/slang_typeinfo.h
+++ b/src/mesa/shader/slang/slang_typeinfo.h
@@ -65,7 +65,6 @@ typedef struct slang_assemble_ctx_
struct slang_label_ *curFuncEndLabel;
struct slang_ir_node_ *CurLoop;
struct slang_function_ *CurFunction;
- GLuint numSamplers;
} slang_assemble_ctx;
diff --git a/src/mesa/state_tracker/st_atom.c b/src/mesa/state_tracker/st_atom.c
index 18063adc79..ecfd117918 100644
--- a/src/mesa/state_tracker/st_atom.c
+++ b/src/mesa/state_tracker/st_atom.c
@@ -45,10 +45,10 @@
*/
static const struct st_tracked_state *atoms[] =
{
- &st_update_framebuffer,
&st_update_depth_stencil_alpha,
&st_update_clip,
+ &st_finalize_textures,
&st_update_shader,
&st_update_rasterizer,
@@ -58,6 +58,7 @@ static const struct st_tracked_state *atoms[] =
&st_update_blend,
&st_update_sampler,
&st_update_texture,
+ &st_update_framebuffer,
&st_update_vs_constants,
&st_update_fs_constants,
&st_update_pixel_transfer
diff --git a/src/mesa/state_tracker/st_atom.h b/src/mesa/state_tracker/st_atom.h
index c6c6eba812..c7cffd85c8 100644
--- a/src/mesa/state_tracker/st_atom.h
+++ b/src/mesa/state_tracker/st_atom.h
@@ -55,6 +55,7 @@ extern const struct st_tracked_state st_update_scissor;
extern const struct st_tracked_state st_update_blend;
extern const struct st_tracked_state st_update_sampler;
extern const struct st_tracked_state st_update_texture;
+extern const struct st_tracked_state st_finalize_textures;
extern const struct st_tracked_state st_update_fs_constants;
extern const struct st_tracked_state st_update_vs_constants;
extern const struct st_tracked_state st_update_pixel_transfer;
diff --git a/src/mesa/state_tracker/st_atom_framebuffer.c b/src/mesa/state_tracker/st_atom_framebuffer.c
index 0a6974d8a7..d46c3ee16c 100644
--- a/src/mesa/state_tracker/st_atom_framebuffer.c
+++ b/src/mesa/state_tracker/st_atom_framebuffer.c
@@ -34,13 +34,60 @@
#include "st_context.h"
#include "st_atom.h"
#include "st_cb_fbo.h"
+#include "st_texture.h"
#include "pipe/p_context.h"
+#include "pipe/p_inlines.h"
#include "cso_cache/cso_context.h"
+
+/**
+ * When doing GL render to texture, we have to be sure that finalize_texture()
+ * didn't yank out the pipe_texture that we earlier created a surface for.
+ * Check for that here and create a new surface if needed.
+ */
+static void
+update_renderbuffer_surface(struct st_context *st,
+ struct st_renderbuffer *strb)
+{
+ struct pipe_screen *screen = st->pipe->screen;
+ struct pipe_texture *texture = strb->rtt->pt;
+ int rtt_width = strb->Base.Width;
+ int rtt_height = strb->Base.Height;
+
+ if (!strb->surface ||
+ strb->surface->texture != texture ||
+ strb->surface->width != rtt_width ||
+ strb->surface->height != rtt_height) {
+ int level;
+ /* find matching mipmap level size */
+ for (level = 0; level <= texture->last_level; level++) {
+ if (texture->width[level] == rtt_width &&
+ texture->height[level] == rtt_height) {
+
+ pipe_surface_reference(&strb->surface, NULL);
+
+ strb->surface = screen->get_tex_surface(screen,
+ texture,
+ strb->rtt_face,
+ level,
+ strb->rtt_slice,
+ PIPE_BUFFER_USAGE_GPU_READ |
+ PIPE_BUFFER_USAGE_GPU_WRITE);
+#if 0
+ printf("-- alloc new surface %d x %d into tex %p\n",
+ strb->surface->width, strb->surface->height,
+ texture);
+#endif
+ break;
+ }
+ }
+ }
+}
+
+
/**
* Update framebuffer state (color, depth, stencil, etc. buffers)
- * XXX someday: separate draw/read buffers.
*/
static void
update_framebuffer_state( struct st_context *st )
@@ -55,6 +102,8 @@ update_framebuffer_state( struct st_context *st )
framebuffer->width = fb->Width;
framebuffer->height = fb->Height;
+ /*printf("------ fb size %d x %d\n", fb->Width, fb->Height);*/
+
/* Examine Mesa's ctx->DrawBuffer->_ColorDrawBuffers state
* to determine which surfaces to draw to
*/
@@ -62,6 +111,13 @@ update_framebuffer_state( struct st_context *st )
for (j = 0; j < MAX_DRAW_BUFFERS; j++) {
for (i = 0; i < fb->_NumColorDrawBuffers[j]; i++) {
strb = st_renderbuffer(fb->_ColorDrawBuffers[j][i]);
+
+ /*printf("--------- framebuffer surface rtt %p\n", strb->rtt);*/
+ if (strb->rtt) {
+ /* rendering to a GL texture, may have to update surface */
+ update_renderbuffer_surface(st, strb);
+ }
+
assert(strb->surface);
framebuffer->cbufs[framebuffer->num_cbufs] = strb->surface;
framebuffer->num_cbufs++;
@@ -71,6 +127,11 @@ update_framebuffer_state( struct st_context *st )
strb = st_renderbuffer(fb->Attachment[BUFFER_DEPTH].Renderbuffer);
if (strb) {
strb = st_renderbuffer(strb->Base.Wrapped);
+ if (strb->rtt) {
+ /* rendering to a GL texture, may have to update surface */
+ update_renderbuffer_surface(st, strb);
+ }
+
assert(strb->surface);
framebuffer->zsbuf = strb->surface;
}
@@ -99,7 +160,7 @@ const struct st_tracked_state st_update_framebuffer = {
"st_update_framebuffer", /* name */
{ /* dirty */
_NEW_BUFFERS, /* mesa */
- 0, /* st */
+ ST_NEW_FRAMEBUFFER, /* st */
},
update_framebuffer_state /* update */
};
diff --git a/src/mesa/state_tracker/st_atom_pixeltransfer.c b/src/mesa/state_tracker/st_atom_pixeltransfer.c
index 999c148449..e500ac8684 100644
--- a/src/mesa/state_tracker/st_atom_pixeltransfer.c
+++ b/src/mesa/state_tracker/st_atom_pixeltransfer.c
@@ -126,7 +126,8 @@ create_color_map_texture(GLcontext *ctx)
/* create texture for color map/table */
pt = st_texture_create(ctx->st, PIPE_TEXTURE_2D, format, 0,
- texSize, texSize, 1, 0);
+ texSize, texSize, 1, 0,
+ PIPE_TEXTURE_USAGE_SAMPLER);
return pt;
}
@@ -148,8 +149,10 @@ load_color_map_texture(GLcontext *ctx, struct pipe_texture *pt)
uint *dest;
uint i, j;
- surface = screen->get_tex_surface(screen, pt, 0, 0, 0);
- dest = (uint *) pipe_surface_map(surface);
+ surface = screen->get_tex_surface(screen, pt, 0, 0, 0,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+ dest = (uint *) screen->surface_map(screen, surface,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
/* Pack four 1D maps into a 2D texture:
* R map is placed horizontally, indexed by S, in channel 0
@@ -168,9 +171,8 @@ load_color_map_texture(GLcontext *ctx, struct pipe_texture *pt)
}
}
- pipe_surface_unmap(surface);
+ screen->surface_unmap(screen, surface);
pipe_surface_reference(&surface, NULL);
- pipe->texture_update(pipe, pt, 0, 0x1);
}
diff --git a/src/mesa/state_tracker/st_atom_shader.c b/src/mesa/state_tracker/st_atom_shader.c
index 7745591afb..a62ea8161c 100644
--- a/src/mesa/state_tracker/st_atom_shader.c
+++ b/src/mesa/state_tracker/st_atom_shader.c
@@ -44,6 +44,8 @@
#include "pipe/p_context.h"
#include "pipe/p_shader_tokens.h"
+#include "util/u_simple_shaders.h"
+
#include "cso_cache/cso_context.h"
#include "st_context.h"
@@ -252,6 +254,22 @@ st_free_translated_vertex_programs(struct st_context *st,
}
+static void *
+get_passthrough_fs(struct st_context *st)
+{
+ struct pipe_shader_state shader;
+
+ if (!st->passthrough_fs) {
+ st->passthrough_fs =
+ util_make_fragment_passthrough_shader(st->pipe, &shader);
+#if 0 /* We actually need to keep the tokens around at this time */
+ free((void *) shader.tokens);
+#endif
+ }
+
+ return st->passthrough_fs;
+}
+
static void
update_linkage( struct st_context *st )
@@ -277,7 +295,15 @@ update_linkage( struct st_context *st )
st_reference_fragprog(st, &st->fp, stfp);
cso_set_vertex_shader_handle(st->cso_context, stvp->driver_shader);
- cso_set_fragment_shader_handle(st->cso_context, stfp->driver_shader);
+
+ if (st->missing_textures) {
+ /* use a pass-through frag shader that uses no textures */
+ void *fs = get_passthrough_fs(st);
+ cso_set_fragment_shader_handle(st->cso_context, fs);
+ }
+ else {
+ cso_set_fragment_shader_handle(st->cso_context, stfp->driver_shader);
+ }
st->vertex_result_to_slot = xvp->output_to_slot;
}
diff --git a/src/mesa/state_tracker/st_atom_texture.c b/src/mesa/state_tracker/st_atom_texture.c
index 767654f3d0..1ec671ed48 100644
--- a/src/mesa/state_tracker/st_atom_texture.c
+++ b/src/mesa/state_tracker/st_atom_texture.c
@@ -39,34 +39,13 @@
#include "pipe/p_context.h"
#include "pipe/p_inlines.h"
#include "cso_cache/cso_context.h"
-#include "util/u_simple_shaders.h"
-static void *
-get_passthrough_fs(struct st_context *st)
-{
- struct pipe_shader_state shader;
-
- if (!st->passthrough_fs) {
- st->passthrough_fs =
- util_make_fragment_passthrough_shader(st->pipe, &shader);
- free((void *) shader.tokens);
- }
-
- return st->passthrough_fs;
-}
-
-
-/**
- * XXX This needs some work yet....
- * Need to "upload" texture images at appropriate times.
- */
static void
update_textures(struct st_context *st)
{
struct gl_fragment_program *fprog = st->ctx->FragmentProgram._Current;
GLuint su;
- GLboolean missing_textures = GL_FALSE;
st->state.num_textures = 0;
@@ -85,13 +64,11 @@ update_textures(struct st_context *st)
retval = st_finalize_texture(st->ctx, st->pipe, texObj, &flush);
if (!retval) {
/* out of mem */
- missing_textures = GL_TRUE;
+ /* missing texture */
continue;
}
st->state.num_textures = su + 1;
-
- stObj->teximage_realloc = TRUE;
}
pt = st_get_stobj_texture(stObj);
@@ -103,12 +80,6 @@ update_textures(struct st_context *st)
cso_set_sampler_textures(st->cso_context,
st->state.num_textures,
st->state.sampler_texture);
-
- if (missing_textures) {
- /* use a pass-through frag shader that uses no textures */
- void *fs = get_passthrough_fs(st);
- cso_set_fragment_shader_handle(st->cso_context, fs);
- }
}
@@ -120,3 +91,52 @@ const struct st_tracked_state st_update_texture = {
},
update_textures /* update */
};
+
+
+
+
+static void
+finalize_textures(struct st_context *st)
+{
+ struct gl_fragment_program *fprog = st->ctx->FragmentProgram._Current;
+ const GLboolean prev_missing_textures = st->missing_textures;
+ GLuint su;
+
+ st->missing_textures = GL_FALSE;
+
+ for (su = 0; su < st->ctx->Const.MaxTextureCoordUnits; su++) {
+ if (fprog->Base.SamplersUsed & (1 << su)) {
+ const GLuint texUnit = fprog->Base.SamplerUnits[su];
+ struct gl_texture_object *texObj
+ = st->ctx->Texture.Unit[texUnit]._Current;
+ struct st_texture_object *stObj = st_texture_object(texObj);
+
+ if (texObj) {
+ GLboolean flush, retval;
+
+ retval = st_finalize_texture(st->ctx, st->pipe, texObj, &flush);
+ if (!retval) {
+ /* out of mem */
+ st->missing_textures = GL_TRUE;
+ continue;
+ }
+
+ stObj->teximage_realloc = TRUE;
+ }
+ }
+ }
+
+ if (prev_missing_textures != st->missing_textures)
+ st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
+}
+
+
+
+const struct st_tracked_state st_finalize_textures = {
+ "st_finalize_textures", /* name */
+ { /* dirty */
+ _NEW_TEXTURE, /* mesa */
+ 0, /* st */
+ },
+ finalize_textures /* update */
+};
diff --git a/src/mesa/state_tracker/st_cb_accum.c b/src/mesa/state_tracker/st_cb_accum.c
index 1636bed91a..8098d75e18 100644
--- a/src/mesa/state_tracker/st_cb_accum.c
+++ b/src/mesa/state_tracker/st_cb_accum.c
@@ -105,14 +105,18 @@ void
st_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
{
struct st_renderbuffer *acc_strb = st_renderbuffer(rb);
- struct pipe_surface *acc_ps = acc_strb->surface;
+ struct pipe_surface *acc_ps;
+ struct pipe_screen *screen = ctx->st->pipe->screen;
const GLint xpos = ctx->DrawBuffer->_Xmin;
const GLint ypos = ctx->DrawBuffer->_Ymin;
const GLint width = ctx->DrawBuffer->_Xmax - xpos;
const GLint height = ctx->DrawBuffer->_Ymax - ypos;
GLvoid *map;
- map = pipe_surface_map(acc_ps);
+ acc_ps = screen->get_tex_surface(screen, acc_strb->texture, 0, 0, 0,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+ map = screen->surface_map(screen, acc_ps,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
/* note acc_strb->format might not equal acc_ps->format */
switch (acc_strb->format) {
@@ -140,7 +144,8 @@ st_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
_mesa_problem(ctx, "unexpected format in st_clear_accum_buffer()");
}
- pipe_surface_unmap(acc_ps);
+ screen->surface_unmap(screen, acc_ps);
+ pipe_surface_reference(&acc_ps, NULL);
}
@@ -150,10 +155,12 @@ accum_mad(GLcontext *ctx, GLfloat scale, GLfloat bias,
GLint xpos, GLint ypos, GLint width, GLint height,
struct st_renderbuffer *acc_strb)
{
+ struct pipe_screen *screen = ctx->st->pipe->screen;
struct pipe_surface *acc_ps = acc_strb->surface;
GLvoid *map;
- map = pipe_surface_map(acc_ps);
+ map = screen->surface_map(screen, acc_ps,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
/* note acc_strb->format might not equal acc_ps->format */
switch (acc_strb->format) {
@@ -174,77 +181,107 @@ accum_mad(GLcontext *ctx, GLfloat scale, GLfloat bias,
_mesa_problem(NULL, "unexpected format in st_clear_accum_buffer()");
}
- pipe_surface_unmap(acc_ps);
+ screen->surface_unmap(screen, acc_ps);
}
static void
accum_accum(struct pipe_context *pipe, GLfloat value,
GLint xpos, GLint ypos, GLint width, GLint height,
- struct pipe_surface *acc_ps,
- struct pipe_surface *color_ps)
+ struct st_renderbuffer *acc_strb,
+ struct st_renderbuffer *color_strb)
{
+ struct pipe_screen *screen = pipe->screen;
+ struct pipe_surface *acc_surf, *color_surf;
GLfloat *colorBuf, *accBuf;
GLint i;
+ acc_surf = screen->get_tex_surface(screen, acc_strb->texture, 0, 0, 0,
+ (PIPE_BUFFER_USAGE_CPU_WRITE |
+ PIPE_BUFFER_USAGE_CPU_READ));
+
+ color_surf = screen->get_tex_surface(screen, color_strb->texture, 0, 0, 0,
+ PIPE_BUFFER_USAGE_CPU_READ);
+
colorBuf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
accBuf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
- pipe_get_tile_rgba(pipe, color_ps, xpos, ypos, width, height, colorBuf);
- acc_get_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, accBuf);
+ pipe_get_tile_rgba(pipe, color_surf, xpos, ypos, width, height, colorBuf);
+ acc_get_tile_rgba(pipe, acc_surf, xpos, ypos, width, height, accBuf);
for (i = 0; i < 4 * width * height; i++) {
accBuf[i] = accBuf[i] + colorBuf[i] * value;
}
- acc_put_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, accBuf);
+ acc_put_tile_rgba(pipe, acc_surf, xpos, ypos, width, height, accBuf);
free(colorBuf);
free(accBuf);
+ pipe_surface_reference(&acc_surf, NULL);
+ pipe_surface_reference(&color_surf, NULL);
}
static void
accum_load(struct pipe_context *pipe, GLfloat value,
GLint xpos, GLint ypos, GLint width, GLint height,
- struct pipe_surface *acc_ps,
- struct pipe_surface *color_ps)
+ struct st_renderbuffer *acc_strb,
+ struct st_renderbuffer *color_strb)
{
+ struct pipe_screen *screen = pipe->screen;
+ struct pipe_surface *acc_surf, *color_surf;
GLfloat *buf;
GLint i;
+ acc_surf = screen->get_tex_surface(screen, acc_strb->texture, 0, 0, 0,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+
+ color_surf = screen->get_tex_surface(screen, color_strb->texture, 0, 0, 0,
+ PIPE_BUFFER_USAGE_CPU_READ);
+
buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
- pipe_get_tile_rgba(pipe, color_ps, xpos, ypos, width, height, buf);
+ pipe_get_tile_rgba(pipe, color_surf, xpos, ypos, width, height, buf);
for (i = 0; i < 4 * width * height; i++) {
buf[i] = buf[i] * value;
}
- acc_put_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, buf);
+ acc_put_tile_rgba(pipe, acc_surf, xpos, ypos, width, height, buf);
free(buf);
+ pipe_surface_reference(&acc_surf, NULL);
+ pipe_surface_reference(&color_surf, NULL);
}
static void
accum_return(GLcontext *ctx, GLfloat value,
GLint xpos, GLint ypos, GLint width, GLint height,
- struct pipe_surface *acc_ps,
- struct pipe_surface *color_ps)
+ struct st_renderbuffer *acc_strb,
+ struct st_renderbuffer *color_strb)
{
struct pipe_context *pipe = ctx->st->pipe;
+ struct pipe_screen *screen = pipe->screen;
const GLubyte *colormask = ctx->Color.ColorMask;
+ struct pipe_surface *acc_surf, *color_surf;
GLfloat *abuf, *cbuf = NULL;
GLint i, ch;
abuf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
- acc_get_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, abuf);
+ acc_surf = screen->get_tex_surface(screen, acc_strb->texture, 0, 0, 0,
+ PIPE_BUFFER_USAGE_CPU_READ);
+
+ color_surf = screen->get_tex_surface(screen, color_strb->texture, 0, 0, 0,
+ (PIPE_BUFFER_USAGE_CPU_READ |
+ PIPE_BUFFER_USAGE_CPU_WRITE));
+
+ acc_get_tile_rgba(pipe, acc_surf, xpos, ypos, width, height, abuf);
if (!colormask[0] || !colormask[1] || !colormask[2] || !colormask[3]) {
cbuf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
- pipe_get_tile_rgba(pipe, color_ps, xpos, ypos, width, height, cbuf);
+ pipe_get_tile_rgba(pipe, color_surf, xpos, ypos, width, height, cbuf);
}
for (i = 0; i < width * height; i++) {
@@ -259,11 +296,13 @@ accum_return(GLcontext *ctx, GLfloat value,
}
}
- pipe_put_tile_rgba(pipe, color_ps, xpos, ypos, width, height, abuf);
+ pipe_put_tile_rgba(pipe, color_surf, xpos, ypos, width, height, abuf);
free(abuf);
if (cbuf)
free(cbuf);
+ pipe_surface_reference(&acc_surf, NULL);
+ pipe_surface_reference(&color_surf, NULL);
}
@@ -276,8 +315,6 @@ st_Accum(GLcontext *ctx, GLenum op, GLfloat value)
= st_renderbuffer(ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer);
struct st_renderbuffer *color_strb
= st_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer);
- struct pipe_surface *acc_ps = acc_strb->surface;
- struct pipe_surface *color_ps = color_strb->surface;
const GLint xpos = ctx->DrawBuffer->_Xmin;
const GLint ypos = ctx->DrawBuffer->_Ymin;
@@ -300,14 +337,14 @@ st_Accum(GLcontext *ctx, GLenum op, GLfloat value)
break;
case GL_ACCUM:
if (value != 0.0F) {
- accum_accum(pipe, value, xpos, ypos, width, height, acc_ps, color_ps);
+ accum_accum(pipe, value, xpos, ypos, width, height, acc_strb, color_strb);
}
break;
case GL_LOAD:
- accum_load(pipe, value, xpos, ypos, width, height, acc_ps, color_ps);
+ accum_load(pipe, value, xpos, ypos, width, height, acc_strb, color_strb);
break;
case GL_RETURN:
- accum_return(ctx, value, xpos, ypos, width, height, acc_ps, color_ps);
+ accum_return(ctx, value, xpos, ypos, width, height, acc_strb, color_strb);
break;
default:
assert(0);
diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c
index ce8fefe703..c8e2d7d118 100644
--- a/src/mesa/state_tracker/st_cb_bitmap.c
+++ b/src/mesa/state_tracker/st_cb_bitmap.c
@@ -321,16 +321,18 @@ make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height,
* Create texture to hold bitmap pattern.
*/
pt = st_texture_create(ctx->st, PIPE_TEXTURE_2D, ctx->st->bitmap.tex_format,
- 0, width, height, 1, 0);
+ 0, width, height, 1, 0,
+ PIPE_TEXTURE_USAGE_SAMPLER);
if (!pt) {
_mesa_unmap_bitmap_pbo(ctx, unpack);
return NULL;
}
- surface = screen->get_tex_surface(screen, pt, 0, 0, 0);
+ surface = screen->get_tex_surface(screen, pt, 0, 0, 0,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
/* map texture surface */
- dest = pipe_surface_map(surface);
+ dest = screen->surface_map(screen, surface, PIPE_BUFFER_USAGE_CPU_WRITE);
/* Put image into texture surface */
memset(dest, 0xff, height * surface->pitch);
@@ -340,9 +342,8 @@ make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height,
_mesa_unmap_bitmap_pbo(ctx, unpack);
/* Release surface */
- pipe_surface_unmap(surface);
+ screen->surface_unmap(screen, surface);
pipe_surface_reference(&surface, NULL);
- pipe->texture_update(pipe, pt, 0, 0x1);
return pt;
}
@@ -539,13 +540,16 @@ reset_cache(struct st_context *st)
cache->texture = st_texture_create(st, PIPE_TEXTURE_2D,
st->bitmap.tex_format, 0,
BITMAP_CACHE_WIDTH, BITMAP_CACHE_HEIGHT,
- 1, 0);
+ 1, 0,
+ PIPE_TEXTURE_USAGE_SAMPLER);
/* Map the texture surface.
* Subsequent glBitmap calls will write into the texture image.
*/
- cache->surf = screen->get_tex_surface(screen, cache->texture, 0, 0, 0);
- cache->buffer = pipe_surface_map(cache->surf);
+ cache->surf = screen->get_tex_surface(screen, cache->texture, 0, 0, 0,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+ cache->buffer = screen->surface_map(screen, cache->surf,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
/* init image to all 0xff */
memset(cache->buffer, 0xff, BITMAP_CACHE_WIDTH * BITMAP_CACHE_HEIGHT);
@@ -562,6 +566,7 @@ st_flush_bitmap_cache(struct st_context *st)
if (st->ctx->DrawBuffer) {
struct bitmap_cache *cache = st->bitmap.cache;
struct pipe_context *pipe = st->pipe;
+ struct pipe_screen *screen = pipe->screen;
assert(cache->xmin <= cache->xmax);
/*
@@ -574,11 +579,8 @@ st_flush_bitmap_cache(struct st_context *st)
/* The texture surface has been mapped until now.
* So unmap and release the texture surface before drawing.
*/
- pipe_surface_unmap(cache->surf);
- pipe_surface_reference(&cache->surf, NULL);
-
- /* XXX is this needed? */
- pipe->texture_update(pipe, cache->texture, 0, 0x1);
+ screen->surface_unmap(screen, cache->surf);
+ screen->tex_surface_release(screen, &cache->surf);
draw_bitmap_quad(st->ctx,
cache->xpos,
@@ -662,6 +664,9 @@ st_Bitmap(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
struct st_context *st = ctx->st;
struct pipe_texture *pt;
+ if (width == 0 || height == 0)
+ return;
+
st_validate_state(st);
if (!st->bitmap.vs) {
@@ -742,16 +747,12 @@ void
st_destroy_bitmap(struct st_context *st)
{
struct pipe_context *pipe = st->pipe;
+ struct pipe_screen *screen = pipe->screen;
+ struct bitmap_cache *cache = st->bitmap.cache;
-#if 0
- if (st->bitmap.combined_prog) {
- st_delete_program(st->ctx, &st->bitmap.combined_prog->Base.Base);
- }
+ screen->surface_unmap(screen, cache->surf);
+ screen->tex_surface_release(screen, &cache->surf);
- if (st->bitmap.program) {
- st_delete_program(st->ctx, &st->bitmap.program->Base.Base);
- }
-#endif
if (st->bitmap.vs) {
cso_delete_vertex_shader(st->cso_context, st->bitmap.vs);
st->bitmap.vs = NULL;
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
index fbbe8d2d64..a486581989 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -349,7 +349,8 @@ make_texture(struct st_context *st,
return NULL;
pt = st_texture_create(st, PIPE_TEXTURE_2D, pipeFormat, 0, width, height,
- 1, 0);
+ 1, 0,
+ PIPE_TEXTURE_USAGE_SAMPLER);
if (!pt) {
_mesa_unmap_drawpix_pbo(ctx, unpack);
return NULL;
@@ -365,10 +366,12 @@ make_texture(struct st_context *st,
/* we'll do pixel transfer in a fragment shader */
ctx->_ImageTransferState = 0x0;
- surface = screen->get_tex_surface(screen, pt, 0, 0, 0);
+ surface = screen->get_tex_surface(screen, pt, 0, 0, 0,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
/* map texture surface */
- dest = pipe_surface_map(surface);
+ dest = screen->surface_map(screen, surface,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
/* Put image into texture surface.
* Note that the image is actually going to be upside down in
@@ -387,9 +390,8 @@ make_texture(struct st_context *st,
unpack);
/* unmap */
- pipe_surface_unmap(surface);
+ screen->surface_unmap(screen, surface);
pipe_surface_reference(&surface, NULL);
- pipe->texture_update(pipe, pt, 0, 0x1);
assert(success);
@@ -485,7 +487,7 @@ draw_quad(GLcontext *ctx, GLfloat x0, GLfloat y0, GLfloat z,
ubyte *map;
/* allocate/load buffer object with vertex data */
- buf = pipe_buffer_create(pipe,32, PIPE_BUFFER_USAGE_VERTEX,
+ buf = pipe_buffer_create(pipe, 32, PIPE_BUFFER_USAGE_VERTEX,
sizeof(verts));
map = pipe_buffer_map(pipe, buf, PIPE_BUFFER_USAGE_CPU_WRITE);
memcpy(map, verts, sizeof(verts));
@@ -495,8 +497,7 @@ draw_quad(GLcontext *ctx, GLfloat x0, GLfloat y0, GLfloat z,
PIPE_PRIM_QUADS,
4, /* verts */
3); /* attribs/vert */
-
- pipe_buffer_destroy(pipe, buf);
+ pipe_buffer_reference(pipe->winsys, &buf, NULL);
}
}
@@ -603,8 +604,10 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
x1 = x + width * ctx->Pixel.ZoomX;
y0 = y;
y1 = y + height * ctx->Pixel.ZoomY;
+ //if(!color)
draw_quad(ctx, x0, y0, z, x1, y1, color, invertTex);
-
+ //else
+ //printf("skip draw quad\n");
/* restore state */
cso_restore_rasterizer(cso);
cso_restore_viewport(cso);
@@ -734,15 +737,23 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
{
struct st_context *st = ctx->st;
struct pipe_context *pipe = st->pipe;
- struct pipe_surface *ps = st->state.framebuffer.zsbuf;
+ struct pipe_screen *screen = pipe->screen;
+ struct st_renderbuffer *strb;
+ struct pipe_surface *ps;
const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0;
GLint skipPixels;
ubyte *stmap;
pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
+ strb = st_renderbuffer(ctx->DrawBuffer->
+ Attachment[BUFFER_STENCIL].Renderbuffer);
+ ps = screen->get_tex_surface(screen, strb->texture, 0, 0, 0,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+
/* map the stencil buffer */
- stmap = pipe_surface_map(ps);
+ stmap = screen->surface_map(screen, ps,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
/* if width > MAX_WIDTH, have to process image in chunks */
skipPixels = 0;
@@ -799,7 +810,8 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
}
/* unmap the stencil buffer */
- pipe_surface_unmap(ps);
+ screen->surface_unmap(screen, ps);
+ pipe_surface_reference(&ps, NULL);
}
@@ -872,7 +884,8 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
GLint dstx, GLint dsty)
{
struct st_renderbuffer *rbDraw = st_renderbuffer(ctx->DrawBuffer->_StencilBuffer);
- struct pipe_surface *psDraw = rbDraw->surface;
+ struct pipe_screen *screen = ctx->st->pipe->screen;
+ struct pipe_surface *psDraw;
ubyte *drawMap;
ubyte *buffer;
int i;
@@ -887,8 +900,11 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
st_read_stencil_pixels(ctx, srcx, srcy, width, height, GL_UNSIGNED_BYTE,
&ctx->DefaultPacking, buffer);
+ psDraw = screen->get_tex_surface(screen, rbDraw->texture, 0, 0, 0,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+
/* map the stencil buffer */
- drawMap = pipe_surface_map(psDraw);
+ drawMap = screen->surface_map(screen, psDraw, PIPE_BUFFER_USAGE_CPU_WRITE);
/* draw */
/* XXX PixelZoom not handled yet */
@@ -928,7 +944,8 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
free(buffer);
/* unmap the stencil buffer */
- pipe_surface_unmap(psDraw);
+ screen->surface_unmap(screen, psDraw);
+ pipe_surface_reference(&psDraw, NULL);
}
@@ -943,7 +960,6 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
struct st_renderbuffer *rbRead;
struct st_vertex_program *stvp;
struct st_fragment_program *stfp;
- struct pipe_surface *psRead;
struct pipe_surface *psTex;
struct pipe_texture *pt;
GLfloat *color;
@@ -974,8 +990,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
stvp = st_make_passthrough_vertex_shader(ctx->st, GL_TRUE);
}
- psRead = rbRead->surface;
- srcFormat = psRead->format;
+ srcFormat = rbRead->texture->format;
if (screen->is_format_supported(screen, srcFormat, PIPE_TEXTURE)) {
texFormat = srcFormat;
@@ -987,54 +1002,72 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
assert(texFormat != PIPE_FORMAT_NONE); /* XXX no depth texture formats??? */
}
else {
- /* todo */
- assert(0);
+ /* default color format */
+ texFormat = st_choose_format(pipe, GL_RGBA, PIPE_TEXTURE);
+ assert(texFormat != PIPE_FORMAT_NONE);
}
}
pt = st_texture_create(ctx->st, PIPE_TEXTURE_2D, texFormat, 0,
- width, height, 1, 0);
+ width, height, 1, 0,
+ PIPE_TEXTURE_USAGE_SAMPLER);
if (!pt)
return;
- psTex = screen->get_tex_surface(screen, pt, 0, 0, 0);
-
if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
srcy = ctx->DrawBuffer->Height - srcy - height;
}
if (srcFormat == texFormat) {
/* copy source framebuffer surface into mipmap/texture */
+ struct pipe_surface *psRead = screen->get_tex_surface(screen,
+ rbRead->texture, 0, 0, 0,
+ PIPE_BUFFER_USAGE_GPU_READ);
+ psTex = screen->get_tex_surface(screen, pt, 0, 0, 0,
+ PIPE_BUFFER_USAGE_GPU_WRITE );
pipe->surface_copy(pipe,
FALSE,
psTex, /* dest */
0, 0, /* destx/y */
psRead,
srcx, srcy, width, height);
+ pipe_surface_reference(&psRead, NULL);
}
- else if (type == GL_COLOR) {
- /* alternate path using get/put_tile() */
- GLfloat *buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
+ else {
+ /* CPU-based fallback/conversion */
+ struct pipe_surface *psRead = screen->get_tex_surface(screen,
+ rbRead->texture, 0, 0, 0,
+ PIPE_BUFFER_USAGE_CPU_READ);
- pipe_get_tile_rgba(pipe, psRead, srcx, srcy, width, height, buf);
- pipe_put_tile_rgba(pipe, psTex, 0, 0, width, height, buf);
+ psTex = screen->get_tex_surface(screen, pt, 0, 0, 0,
+ PIPE_BUFFER_USAGE_CPU_WRITE );
- free(buf);
- }
- else {
- /* GL_DEPTH */
- GLuint *buf = (GLuint *) malloc(width * height * sizeof(GLuint));
- pipe_get_tile_z(pipe, psRead, srcx, srcy, width, height, buf);
- pipe_put_tile_z(pipe, psTex, 0, 0, width, height, buf);
- free(buf);
+ if (type == GL_COLOR) {
+ /* alternate path using get/put_tile() */
+ GLfloat *buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
+
+ pipe_get_tile_rgba(pipe, psRead, srcx, srcy, width, height, buf);
+ pipe_put_tile_rgba(pipe, psTex, 0, 0, width, height, buf);
+
+ free(buf);
+ }
+ else {
+ /* GL_DEPTH */
+ GLuint *buf = (GLuint *) malloc(width * height * sizeof(GLuint));
+ pipe_get_tile_z(pipe, psRead, srcx, srcy, width, height, buf);
+ pipe_put_tile_z(pipe, psTex, 0, 0, width, height, buf);
+ free(buf);
+ }
+ pipe_surface_reference(&psRead, NULL);
}
+ pipe_surface_reference(&psTex, NULL);
+
/* draw textured quad */
draw_textured_quad(ctx, dstx, dsty, ctx->Current.RasterPos[2],
width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY,
pt, stvp, stfp, color, GL_TRUE);
- pipe_surface_reference(&psTex, NULL);
pipe_texture_reference(&pt, NULL);
}
diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c
index fc8a5ea7f6..3560a040c8 100644
--- a/src/mesa/state_tracker/st_cb_fbo.c
+++ b/src/mesa/state_tracker/st_cb_fbo.c
@@ -77,7 +77,6 @@ init_renderbuffer_bits(struct st_renderbuffer *strb,
return info.size;
}
-
/**
* gl_renderbuffer::AllocStorage()
* This is called to allocate the original drawing surface, and
@@ -90,80 +89,94 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
{
struct pipe_context *pipe = ctx->st->pipe;
struct st_renderbuffer *strb = st_renderbuffer(rb);
- enum pipe_format pipeFormat;
- GLbitfield flags = 0x0; /* XXX needed? */
- int ret;
-
- if (!strb->surface) {
- /* first time surface creation */
- strb->surface = pipe->winsys->surface_alloc(pipe->winsys);
- assert(strb->surface);
- assert(strb->surface->refcount);
- assert(strb->surface->winsys);
- if (!strb->surface)
- return GL_FALSE;
+ struct pipe_texture template;
+ unsigned surface_usage;
+
+ /* Free the old surface (and texture if we hold the last
+ * reference):
+ */
+ pipe_surface_reference( &strb->surface, NULL );
+
+ memset(&template, 0, sizeof(template));
+
+ if (strb->format != PIPE_FORMAT_NONE) {
+ template.format = strb->format;
}
- else if (strb->surface->buffer) {
- /* release/discard the old surface buffer */
- pipe_reference_buffer(pipe, &strb->surface->buffer, NULL);
+ else {
+ template.format = st_choose_renderbuffer_format(pipe, internalFormat);
}
- /* Determine surface format here */
- if (strb->format != PIPE_FORMAT_NONE) {
- assert(strb->format != 0);
- /* we'll hit this for front/back color bufs */
- pipeFormat = strb->format;
+ strb->Base.Width = width;
+ strb->Base.Height = height;
+ init_renderbuffer_bits(strb, template.format);
+
+ template.target = PIPE_TEXTURE_2D;
+ template.compressed = 0;
+ template.cpp = pf_get_size(template.format);
+ template.width[0] = width;
+ template.height[0] = height;
+ template.depth[0] = 1;
+ template.last_level = 0;
+
+ if (pf_is_depth_stencil(template.format)) {
+ template.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
}
else {
- pipeFormat = st_choose_renderbuffer_format(pipe, internalFormat);
+ template.tex_usage = (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
+ PIPE_TEXTURE_USAGE_RENDER_TARGET);
}
- init_renderbuffer_bits(strb, pipeFormat);
-
- ret = pipe->winsys->surface_alloc_storage(pipe->winsys,
- strb->surface,
- width,
- height,
- pipeFormat,
- flags);
- if (ret || !strb->surface->buffer) {
- if (pipeFormat == DEFAULT_ACCUM_PIPE_FORMAT) {
- /* Accum buffer. Try a different surface format. Since accum
- * buffers are s/w only for now, the surface pixel format doesn't
- * really matter, only that the buffer is large enough.
- */
- int sz, mult;
- enum pipe_format accum_format;
-
- /* allocate a buffer of (typically) double height to get 64bpp */
- accum_format = st_choose_renderbuffer_format(pipe, GL_RGBA);
- sz = pf_get_size(accum_format);
- mult = pf_get_size(DEFAULT_ACCUM_PIPE_FORMAT) / sz;
-
- ret = pipe->winsys->surface_alloc_storage(pipe->winsys,
- strb->surface,
- width, height * mult,
- accum_format, flags);
- if (ret)
- return GL_FALSE; /* we've _really_ failed */
-
- }
- else {
- return GL_FALSE; /* out of memory, try s/w buffer? */
- }
+
+ /* Probably need dedicated flags for surface usage too:
+ */
+ surface_usage = (PIPE_BUFFER_USAGE_GPU_READ |
+ PIPE_BUFFER_USAGE_GPU_WRITE);
+#if 0
+ PIPE_BUFFER_USAGE_CPU_READ |
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+#endif
+
+ strb->texture = pipe->screen->texture_create( pipe->screen,
+ &template );
+
+ /* Special path for accum buffers.
+ *
+ * Try a different surface format. Since accum buffers are s/w
+ * only for now, the surface pixel format doesn't really matter,
+ * only that the buffer is large enough.
+ */
+ if (!strb->texture && template.format == DEFAULT_ACCUM_PIPE_FORMAT)
+ {
+ /* Actually, just setting this usage value should be sufficient
+ * to tell the driver to go ahead and allocate the buffer, even
+ * if HW doesn't support the format.
+ */
+ template.tex_usage = 0;
+ surface_usage = (PIPE_BUFFER_USAGE_CPU_READ |
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+
+ strb->texture = pipe->screen->texture_create( pipe->screen,
+ &template );
+
}
- ASSERT(strb->surface->buffer);
- ASSERT(strb->surface->format);
- ASSERT(strb->surface->cpp);
- ASSERT(strb->surface->width == width);
- /*ASSERT(strb->surface->height == height);*/
- ASSERT(strb->surface->pitch);
+ if (!strb->texture)
+ return FALSE;
- strb->Base.Width = width;
- strb->Base.Height = height;
+ strb->surface = pipe->screen->get_tex_surface( pipe->screen,
+ strb->texture,
+ 0, 0, 0,
+ surface_usage );
+
+ assert(strb->surface->buffer);
+ assert(strb->surface->format);
+ assert(strb->surface->cpp);
+ assert(strb->surface->width == width);
+ assert(strb->surface->height == height);
+ assert(strb->surface->pitch);
- return GL_TRUE;
+
+ return strb->surface != NULL;
}
@@ -175,10 +188,8 @@ st_renderbuffer_delete(struct gl_renderbuffer *rb)
{
struct st_renderbuffer *strb = st_renderbuffer(rb);
ASSERT(strb);
- if (strb->surface) {
- struct pipe_winsys *ws = strb->surface->winsys;
- ws->surface_release(ws, &strb->surface);
- }
+ pipe_surface_reference(&strb->surface, NULL);
+ pipe_texture_reference(&strb->texture, NULL);
free(strb);
}
@@ -341,6 +352,10 @@ st_render_texture(GLcontext *ctx,
struct pipe_context *pipe = st->pipe;
struct pipe_screen *screen = pipe->screen;
struct pipe_texture *pt;
+ struct st_texture_object *stObj;
+ const struct gl_texture_image *texImage =
+ att->Texture->Image[att->CubeMapFace][att->TextureLevel];
+
assert(!att->Renderbuffer);
@@ -357,21 +372,27 @@ st_render_texture(GLcontext *ctx,
strb = st_renderbuffer(rb);
/* get the texture for the texture object */
+ stObj = st_texture_object(att->Texture);
+
+ /* point renderbuffer at texobject */
+ strb->rtt = stObj;
+ strb->rtt_level = att->TextureLevel;
+ strb->rtt_face = att->CubeMapFace;
+ strb->rtt_slice = att->Zoffset;
+
+ rb->Width = texImage->Width2;
+ rb->Height = texImage->Height2;
+ /*printf("***** render to texture level %d: %d x %d\n", att->TextureLevel, rb->Width, rb->Height);*/
+
pt = st_get_texobj_texture(att->Texture);
assert(pt);
- assert(pt->width[att->TextureLevel]);
+ /*printf("***** pipe texture %d x %d\n", pt->width[0], pt->height[0]);*/
+
+ pipe_texture_reference( &strb->texture, pt );
- rb->Width = pt->width[att->TextureLevel];
- rb->Height = pt->height[att->TextureLevel];
+ pipe_surface_reference(&strb->surface, NULL);
- /* the renderbuffer's surface is inside the texture */
- strb->surface = screen->get_tex_surface(screen, pt,
- att->CubeMapFace,
- att->TextureLevel,
- att->Zoffset);
- assert(strb->surface);
- assert(screen->is_format_supported(screen, strb->surface->format, PIPE_TEXTURE));
- assert(screen->is_format_supported(screen, strb->surface->format, PIPE_SURFACE));
+ /* the new surface will be created during framebuffer validation */
init_renderbuffer_bits(strb, pt->format);
@@ -396,22 +417,22 @@ static void
st_finish_render_texture(GLcontext *ctx,
struct gl_renderbuffer_attachment *att)
{
+ struct pipe_screen *screen = ctx->st->pipe->screen;
struct st_renderbuffer *strb = st_renderbuffer(att->Renderbuffer);
assert(strb);
ctx->st->pipe->flush(ctx->st->pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
- ctx->st->pipe->texture_update(ctx->st->pipe,
- st_get_texobj_texture(att->Texture),
- att->CubeMapFace, 1 << att->TextureLevel);
+ if (strb->surface)
+ screen->tex_surface_release( screen, &strb->surface );
+
+ strb->rtt = NULL;
/*
printf("FINISH RENDER TO TEXTURE surf=%p\n", strb->surface);
*/
- pipe_surface_reference(&strb->surface, NULL);
-
_mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
/* restore previous framebuffer state */
diff --git a/src/mesa/state_tracker/st_cb_fbo.h b/src/mesa/state_tracker/st_cb_fbo.h
index c1aa14f9b2..87b0734a0c 100644
--- a/src/mesa/state_tracker/st_cb_fbo.h
+++ b/src/mesa/state_tracker/st_cb_fbo.h
@@ -41,8 +41,12 @@
struct st_renderbuffer
{
struct gl_renderbuffer Base;
- struct pipe_surface *surface;
+ struct pipe_texture *texture;
+ struct pipe_surface *surface; /* temporary view into texture */
enum pipe_format format; /** preferred format, or PIPE_FORMAT_NONE */
+
+ struct st_texture_object *rtt; /**< GL render to texture's texture */
+ int rtt_level, rtt_face, rtt_slice;
};
diff --git a/src/mesa/state_tracker/st_cb_feedback.c b/src/mesa/state_tracker/st_cb_feedback.c
index 1b50792bd1..19021411cf 100644
--- a/src/mesa/state_tracker/st_cb_feedback.c
+++ b/src/mesa/state_tracker/st_cb_feedback.c
@@ -173,6 +173,12 @@ feedback_reset_stipple_counter( struct draw_stage *stage )
}
+static void
+feedback_destroy( struct draw_stage *stage )
+{
+ /* no-op */
+}
+
/**
* Create GL feedback drawing stage.
*/
@@ -188,6 +194,7 @@ draw_glfeedback_stage(GLcontext *ctx, struct draw_context *draw)
fs->stage.tri = feedback_tri;
fs->stage.flush = feedback_flush;
fs->stage.reset_stipple_counter = feedback_reset_stipple_counter;
+ fs->stage.destroy = feedback_destroy;
fs->ctx = ctx;
return &fs->stage;
diff --git a/src/mesa/state_tracker/st_cb_program.c b/src/mesa/state_tracker/st_cb_program.c
index b23e000a0b..3154fc85aa 100644
--- a/src/mesa/state_tracker/st_cb_program.c
+++ b/src/mesa/state_tracker/st_cb_program.c
@@ -171,6 +171,7 @@ st_delete_program(GLcontext *ctx, struct gl_program *prog)
assert(0); /* problem */
}
+ /* delete base class */
_mesa_delete_program( ctx, prog );
}
diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c
index 745755566e..08934af319 100644
--- a/src/mesa/state_tracker/st_cb_readpixels.c
+++ b/src/mesa/state_tracker/st_cb_readpixels.c
@@ -61,13 +61,18 @@ st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
GLvoid *pixels)
{
struct gl_framebuffer *fb = ctx->ReadBuffer;
+ struct pipe_screen *screen = ctx->st->pipe->screen;
struct st_renderbuffer *strb = st_renderbuffer(fb->_StencilBuffer);
- struct pipe_surface *ps = strb->surface;
+ struct pipe_surface *ps;
ubyte *stmap;
GLint j;
+ /* Create a CPU-READ surface/view into the renderbuffer's texture */
+ ps = screen->get_tex_surface(screen, strb->texture, 0, 0, 0,
+ PIPE_BUFFER_USAGE_CPU_READ);
+
/* map the stencil buffer */
- stmap = pipe_surface_map(ps);
+ stmap = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_READ);
/* width should never be > MAX_WIDTH since we did clipping earlier */
ASSERT(width <= MAX_WIDTH);
@@ -124,7 +129,8 @@ st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
/* unmap the stencil buffer */
- pipe_surface_unmap(ps);
+ screen->surface_unmap(screen, ps);
+ pipe_surface_reference(&ps, NULL);
}
@@ -168,12 +174,16 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
GLvoid *dest)
{
struct pipe_context *pipe = ctx->st->pipe;
+ struct pipe_screen *screen = pipe->screen;
GLfloat temp[MAX_WIDTH][4];
const GLbitfield transferOps = ctx->_ImageTransferState;
GLint i, yStep, dfStride;
GLfloat *df;
struct st_renderbuffer *strb;
struct gl_pixelstore_attrib clippedPacking = *pack;
+ struct pipe_surface *surf;
+
+ assert(ctx->ReadBuffer->Width > 0);
/* XXX convolution not done yet */
assert((transferOps & IMAGE_CONVOLUTION_BIT) == 0);
@@ -229,6 +239,10 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
yStep = 1;
}
+ /* Create a CPU-READ surface/view into the renderbuffer's texture */
+ surf = screen->get_tex_surface(screen, strb->texture, 0, 0, 0,
+ PIPE_BUFFER_USAGE_CPU_READ);
+
/*
* Copy pixels from pipe_surface to user memory
*/
@@ -240,15 +254,14 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
const GLint dstStride = _mesa_image_row_stride(&clippedPacking, width,
format, type);
- if (strb->surface->format == PIPE_FORMAT_S8Z24_UNORM ||
- strb->surface->format == PIPE_FORMAT_X8Z24_UNORM) {
+ if (surf->format == PIPE_FORMAT_S8Z24_UNORM ||
+ surf->format == PIPE_FORMAT_X8Z24_UNORM) {
if (format == GL_DEPTH_COMPONENT) {
for (i = 0; i < height; i++) {
GLuint ztemp[MAX_WIDTH], j;
GLfloat zfloat[MAX_WIDTH];
const double scale = 1.0 / ((1 << 24) - 1);
- pipe_get_tile_raw(pipe, strb->surface, x, y,
- width, 1, ztemp, 0);
+ pipe_get_tile_raw(pipe, surf, x, y, width, 1, ztemp, 0);
y += yStep;
for (j = 0; j < width; j++) {
zfloat[j] = (float) (scale * (ztemp[j] & 0xffffff));
@@ -262,18 +275,18 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
/* untested, but simple: */
assert(format == GL_DEPTH_STENCIL_EXT);
for (i = 0; i < height; i++) {
- pipe_get_tile_raw(pipe, strb->surface, x, y, width, 1, dst, 0);
+ pipe_get_tile_raw(pipe, surf, x, y, width, 1, dst, 0);
y += yStep;
dst += dstStride;
}
}
}
- else if (strb->surface->format == PIPE_FORMAT_Z16_UNORM) {
+ else if (surf->format == PIPE_FORMAT_Z16_UNORM) {
for (i = 0; i < height; i++) {
GLushort ztemp[MAX_WIDTH], j;
GLfloat zfloat[MAX_WIDTH];
const double scale = 1.0 / 0xffff;
- pipe_get_tile_raw(pipe, strb->surface, x, y, width, 1, ztemp, 0);
+ pipe_get_tile_raw(pipe, surf, x, y, width, 1, ztemp, 0);
y += yStep;
for (j = 0; j < width; j++) {
zfloat[j] = (float) (scale * ztemp[j]);
@@ -283,12 +296,12 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
dst += dstStride;
}
}
- else if (strb->surface->format == PIPE_FORMAT_Z32_UNORM) {
+ else if (surf->format == PIPE_FORMAT_Z32_UNORM) {
for (i = 0; i < height; i++) {
GLuint ztemp[MAX_WIDTH], j;
GLfloat zfloat[MAX_WIDTH];
const double scale = 1.0 / 0xffffffff;
- pipe_get_tile_raw(pipe, strb->surface, x, y, width, 1, ztemp, 0);
+ pipe_get_tile_raw(pipe, surf, x, y, width, 1, ztemp, 0);
y += yStep;
for (j = 0; j < width; j++) {
zfloat[j] = (float) (scale * ztemp[j]);
@@ -302,7 +315,7 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
/* RGBA format */
/* Do a row at a time to flip image data vertically */
for (i = 0; i < height; i++) {
- pipe_get_tile_rgba(pipe, strb->surface, x, y, width, 1, df);
+ pipe_get_tile_rgba(pipe, surf, x, y, width, 1, df);
y += yStep;
df += dfStride;
if (!dfStride) {
@@ -314,6 +327,8 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
}
}
+ pipe_surface_reference(&surf, NULL);
+
_mesa_unmap_readpix_pbo(ctx, &clippedPacking);
}
diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c
index cc17bebc6b..e15ccec89b 100644
--- a/src/mesa/state_tracker/st_cb_texture.c
+++ b/src/mesa/state_tracker/st_cb_texture.c
@@ -272,6 +272,7 @@ guess_and_alloc_texture(struct st_context *st,
GLuint height = stImage->base.Height2;
GLuint depth = stImage->base.Depth2;
GLuint i, comp_byte = 0;
+ enum pipe_format fmt;
DBG("%s\n", __FUNCTION__);
@@ -306,6 +307,11 @@ guess_and_alloc_texture(struct st_context *st,
depth <<= 1;
}
+ if (width == 0 || height == 0 || depth == 0) {
+ /* no texture needed */
+ return;
+ }
+
/* Guess a reasonable value for lastLevel. This is probably going
* to be wrong fairly often and might mean that we have to look at
* resizable buffers, or require that buffers implement lazy
@@ -326,14 +332,19 @@ guess_and_alloc_texture(struct st_context *st,
if (stImage->base.IsCompressed)
comp_byte = compressed_num_bytes(stImage->base.TexFormat->MesaFormat);
+ fmt = st_mesa_format_to_pipe_format(stImage->base.TexFormat->MesaFormat);
stObj->pt = st_texture_create(st,
gl_target_to_pipe(stObj->base.Target),
- st_mesa_format_to_pipe_format(stImage->base.TexFormat->MesaFormat),
+ fmt,
lastLevel,
width,
height,
depth,
- comp_byte);
+ comp_byte,
+ ( (pf_is_depth_stencil(fmt) ?
+ PIPE_TEXTURE_USAGE_DEPTH_STENCIL :
+ PIPE_TEXTURE_USAGE_RENDER_TARGET) |
+ PIPE_TEXTURE_USAGE_SAMPLER ));
DBG("%s - success\n", __FUNCTION__);
}
@@ -478,7 +489,6 @@ st_TexImage(GLcontext * ctx,
struct gl_texture_image *texImage,
GLsizei imageSize, int compressed)
{
- struct pipe_context *pipe = ctx->st->pipe;
struct st_texture_object *stObj = st_texture_object(texObj);
struct st_texture_image *stImage = st_texture_image(texImage);
GLint postConvWidth, postConvHeight;
@@ -637,8 +647,10 @@ st_TexImage(GLcontext * ctx,
return;
if (stImage->pt) {
- texImage->Data = st_texture_image_map(ctx->st, stImage, 0);
- dstRowStride = stImage->surface->pitch * stImage->surface->cpp;
+ texImage->Data = st_texture_image_map(ctx->st, stImage, 0,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+ if (stImage->surface)
+ dstRowStride = stImage->surface->pitch * stImage->surface->cpp;
}
else {
/* Allocate regular memory and store the image there temporarily. */
@@ -656,6 +668,11 @@ st_TexImage(GLcontext * ctx,
texImage->Data = malloc(sizeInBytes);
}
+ if (!texImage->Data) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
+ return;
+ }
+
DBG("Upload image %dx%dx%d row_len %x pitch %x\n",
width, height, depth, width * texelBytes, dstRowStride);
@@ -686,8 +703,9 @@ st_TexImage(GLcontext * ctx,
}
if (stImage->pt && i < depth) {
- st_texture_image_unmap(stImage);
- texImage->Data = st_texture_image_map(ctx->st, stImage, i);
+ st_texture_image_unmap(ctx->st, stImage);
+ texImage->Data = st_texture_image_map(ctx->st, stImage, i,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
src += srcImageStride;
}
}
@@ -696,13 +714,10 @@ st_TexImage(GLcontext * ctx,
_mesa_unmap_teximage_pbo(ctx, unpack);
if (stImage->pt) {
- st_texture_image_unmap(stImage);
+ st_texture_image_unmap(ctx->st, stImage);
texImage->Data = NULL;
}
- if (stObj->pt)
- pipe->texture_update(pipe, stObj->pt, stImage->face, (1 << level));
-
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
ctx->Driver.GenerateMipmap(ctx, target, texObj);
}
@@ -795,7 +810,8 @@ st_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
/* Image is stored in hardware format in a buffer managed by the
* kernel. Need to explicitly map and unmap it.
*/
- texImage->Data = st_texture_image_map(ctx->st, stImage, 0);
+ texImage->Data = st_texture_image_map(ctx->st, stImage, 0,
+ PIPE_BUFFER_USAGE_CPU_READ);
texImage->RowStride = stImage->surface->pitch;
}
else {
@@ -825,8 +841,9 @@ st_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
}
if (stImage->pt && i < depth) {
- st_texture_image_unmap(stImage);
- texImage->Data = st_texture_image_map(ctx->st, stImage, i);
+ st_texture_image_unmap(ctx->st, stImage);
+ texImage->Data = st_texture_image_map(ctx->st, stImage, i,
+ PIPE_BUFFER_USAGE_CPU_READ);
dest += dstImageStride;
}
}
@@ -835,7 +852,7 @@ st_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
/* Unmap */
if (stImage->pt) {
- st_texture_image_unmap(stImage);
+ st_texture_image_unmap(ctx->st, stImage);
texImage->Data = NULL;
}
}
@@ -876,8 +893,6 @@ st_TexSubimage(GLcontext * ctx,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
- struct pipe_context *pipe = ctx->st->pipe;
- struct st_texture_object *stObj = st_texture_object(texObj);
struct st_texture_image *stImage = st_texture_image(texImage);
GLuint dstRowStride;
GLuint srcImageStride = _mesa_image_image_stride(packing, width, height,
@@ -899,8 +914,10 @@ st_TexSubimage(GLcontext * ctx,
* from uploading the buffer under us.
*/
if (stImage->pt) {
- texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset);
- dstRowStride = stImage->surface->pitch * stImage->surface->cpp;
+ texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+ if (stImage->surface)
+ dstRowStride = stImage->surface->pitch * stImage->surface->cpp;
}
if (!texImage->Data) {
@@ -924,8 +941,9 @@ st_TexSubimage(GLcontext * ctx,
if (stImage->pt && i < depth) {
/* map next slice of 3D texture */
- st_texture_image_unmap(stImage);
- texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset + i);
+ st_texture_image_unmap(ctx->st, stImage);
+ texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset + i,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
src += srcImageStride;
}
}
@@ -937,11 +955,9 @@ st_TexSubimage(GLcontext * ctx,
_mesa_unmap_teximage_pbo(ctx, packing);
if (stImage->pt) {
- st_texture_image_unmap(stImage);
+ st_texture_image_unmap(ctx->st, stImage);
texImage->Data = NULL;
}
-
- pipe->texture_update(pipe, stObj->pt, stImage->face, (1 << level));
}
@@ -1059,8 +1075,11 @@ fallback_copy_texsubimage(GLcontext *ctx,
}
src_surf = strb->surface;
+ src_surf = screen->get_tex_surface(screen, strb->texture, face, level, destZ,
+ PIPE_BUFFER_USAGE_CPU_READ);
- dest_surf = screen->get_tex_surface(screen, pt, face, level, destZ);
+ dest_surf = screen->get_tex_surface(screen, pt, face, level, destZ,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
assert(width <= MAX_WIDTH);
@@ -1094,6 +1113,9 @@ fallback_copy_texsubimage(GLcontext *ctx,
pipe_put_tile_rgba(pipe, dest_surf, destX, destY, width, 1, data);
}
}
+
+ screen->tex_surface_release(screen, &dest_surf);
+ screen->tex_surface_release(screen, &src_surf);
}
@@ -1121,13 +1143,11 @@ do_copy_texsubimage(GLcontext *ctx,
struct gl_texture_image *texImage =
_mesa_select_tex_image(ctx, texObj, target, level);
struct st_texture_image *stImage = st_texture_image(texImage);
- struct st_texture_object *stObj = st_texture_object(texObj);
GLenum baseFormat = texImage->InternalFormat;
struct gl_framebuffer *fb = ctx->ReadBuffer;
struct st_renderbuffer *strb;
struct pipe_context *pipe = ctx->st->pipe;
struct pipe_screen *screen = pipe->screen;
- struct pipe_surface *dest_surface;
uint dest_format, src_format;
uint do_flip = FALSE;
GLboolean use_fallback = GL_TRUE;
@@ -1158,12 +1178,7 @@ do_copy_texsubimage(GLcontext *ctx,
src_format = strb->surface->format;
dest_format = stImage->pt->format;
- dest_surface = screen->get_tex_surface(screen, stImage->pt, stImage->face,
- stImage->level, destZ);
-
- if (ctx->_ImageTransferState == 0x0 &&
- strb->surface->buffer &&
- dest_surface->buffer) {
+ if (ctx->_ImageTransferState == 0x0) {
/* do blit-style copy */
/* XXX may need to invert image depending on window
@@ -1186,6 +1201,14 @@ do_copy_texsubimage(GLcontext *ctx,
x, y + height, dstx, dsty, width, height,
GL_COPY); /* ? */
#else
+ struct pipe_surface *dest_surface;
+
+ dest_surface = screen->get_tex_surface(screen, stImage->pt, stImage->face,
+ stImage->level, destZ,
+ PIPE_BUFFER_USAGE_GPU_WRITE);
+
+ assert(strb->surface->buffer);
+ assert(dest_surface->buffer);
if (src_format == dest_format) {
pipe->surface_copy(pipe,
@@ -1213,6 +1236,8 @@ do_copy_texsubimage(GLcontext *ctx,
0.0, PIPE_TEX_MIPFILTER_NEAREST);
use_fallback = GL_FALSE;
}
+
+ pipe_surface_reference(&dest_surface, NULL);
#endif
}
@@ -1223,10 +1248,6 @@ do_copy_texsubimage(GLcontext *ctx,
srcX, srcY, width, height);
}
- pipe_surface_reference(&dest_surface, NULL);
-
- pipe->texture_update(pipe, stObj->pt, stImage->face, (1 << level));
-
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
ctx->Driver.GenerateMipmap(ctx, target, texObj);
}
@@ -1483,20 +1504,28 @@ st_finalize_texture(GLcontext *ctx,
stObj->pt->cpp != cpp ||
stObj->pt->compressed != firstImage->base.IsCompressed) {
pipe_texture_release(&stObj->pt);
+ ctx->st->dirty.st |= ST_NEW_FRAMEBUFFER;
}
}
/* May need to create a new gallium texture:
*/
if (!stObj->pt) {
+ const enum pipe_format fmt =
+ st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat);
stObj->pt = st_texture_create(ctx->st,
gl_target_to_pipe(stObj->base.Target),
- st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat),
+ fmt,
stObj->lastLevel,
firstImage->base.Width2,
firstImage->base.Height2,
firstImage->base.Depth2,
- comp_byte);
+ comp_byte,
+ ( (pf_is_depth_stencil(fmt) ?
+ PIPE_TEXTURE_USAGE_DEPTH_STENCIL :
+ PIPE_TEXTURE_USAGE_RENDER_TARGET) |
+ PIPE_TEXTURE_USAGE_SAMPLER ));
+
if (!stObj->pt) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
return GL_FALSE;
@@ -1516,7 +1545,6 @@ st_finalize_texture(GLcontext *ctx,
if (stImage && stObj->pt != stImage->pt) {
copy_image_data_to_texture(ctx->st, stObj, level, stImage);
*needFlush = GL_TRUE;
- pipe->texture_update(pipe, stObj->pt, face, (1 << level));
}
}
}
diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h
index 46c16e45e6..96333902a9 100644
--- a/src/mesa/state_tracker/st_context.h
+++ b/src/mesa/state_tracker/st_context.h
@@ -53,6 +53,7 @@ struct bitmap_cache;
#define ST_NEW_MESA 0x1 /* Mesa state has changed */
#define ST_NEW_FRAGMENT_PROGRAM 0x2
#define ST_NEW_VERTEX_PROGRAM 0x4
+#define ST_NEW_FRAMEBUFFER 0x8
struct st_state_flags {
@@ -121,6 +122,8 @@ struct st_context
struct st_state_flags dirty;
+ GLboolean missing_textures;
+
GLfloat polygon_offset_scale; /* ?? */
/** Mapping from VERT_RESULT_x to post-transformed vertex slot */
diff --git a/src/mesa/state_tracker/st_gen_mipmap.c b/src/mesa/state_tracker/st_gen_mipmap.c
index 1a0e19c2f9..cfacfdd04c 100644
--- a/src/mesa/state_tracker/st_gen_mipmap.c
+++ b/src/mesa/state_tracker/st_gen_mipmap.c
@@ -123,8 +123,10 @@ fallback_generate_mipmap(GLcontext *ctx, GLenum target,
const ubyte *srcData;
ubyte *dstData;
- srcSurf = screen->get_tex_surface(screen, pt, face, srcLevel, zslice);
- dstSurf = screen->get_tex_surface(screen, pt, face, dstLevel, zslice);
+ srcSurf = screen->get_tex_surface(screen, pt, face, srcLevel, zslice,
+ PIPE_BUFFER_USAGE_CPU_READ);
+ dstSurf = screen->get_tex_surface(screen, pt, face, dstLevel, zslice,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
srcData = (ubyte *) pipe_buffer_map(pipe, srcSurf->buffer,
PIPE_BUFFER_USAGE_CPU_READ)
diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c
index f68bef1207..9553b34e31 100644
--- a/src/mesa/state_tracker/st_texture.c
+++ b/src/mesa/state_tracker/st_texture.c
@@ -75,7 +75,8 @@ st_texture_create(struct st_context *st,
GLuint width0,
GLuint height0,
GLuint depth0,
- GLuint compress_byte)
+ GLuint compress_byte,
+ GLuint usage )
{
struct pipe_texture pt, *newtex;
struct pipe_screen *screen = st->pipe->screen;
@@ -98,6 +99,7 @@ st_texture_create(struct st_context *st,
pt.depth[0] = depth0;
pt.compressed = compress_byte ? 1 : 0;
pt.cpp = pt.compressed ? compress_byte : st_sizeof_format(format);
+ pt.tex_usage = usage;
newtex = screen->texture_create(screen, &pt);
@@ -184,25 +186,33 @@ st_texture_image_offset(const struct pipe_texture * pt,
*/
GLubyte *
st_texture_image_map(struct st_context *st, struct st_texture_image *stImage,
- GLuint zoffset)
+ GLuint zoffset,
+ GLuint flags )
{
struct pipe_screen *screen = st->pipe->screen;
struct pipe_texture *pt = stImage->pt;
DBG("%s \n", __FUNCTION__);
stImage->surface = screen->get_tex_surface(screen, pt, stImage->face,
- stImage->level, zoffset);
+ stImage->level, zoffset,
+ flags);
- return pipe_surface_map(stImage->surface);
+ if (stImage->surface)
+ return screen->surface_map(screen, stImage->surface, flags);
+ else
+ return NULL;
}
void
-st_texture_image_unmap(struct st_texture_image *stImage)
+st_texture_image_unmap(struct st_context *st,
+ struct st_texture_image *stImage)
{
+ struct pipe_screen *screen = st->pipe->screen;
+
DBG("%s\n", __FUNCTION__);
- pipe_surface_unmap(stImage->surface);
+ screen->surface_unmap(screen, stImage->surface);
pipe_surface_reference(&stImage->surface, NULL);
}
@@ -224,12 +234,15 @@ st_surface_data(struct pipe_context *pipe,
const void *src, unsigned src_pitch,
unsigned srcx, unsigned srcy, unsigned width, unsigned height)
{
- pipe_copy_rect(pipe_surface_map(dst),
+ struct pipe_screen *screen = pipe->screen;
+ void *map = screen->surface_map(screen, dst, PIPE_BUFFER_USAGE_CPU_WRITE);
+
+ pipe_copy_rect(map,
dst->cpp,
dst->pitch,
dstx, dsty, width, height, src, src_pitch, srcx, srcy);
- pipe_surface_unmap(dst);
+ screen->surface_unmap(screen, dst);
}
@@ -256,7 +269,8 @@ st_texture_image_data(struct pipe_context *pipe,
if(dst->compressed)
height /= 4;
- dst_surface = screen->get_tex_surface(screen, dst, face, level, i);
+ dst_surface = screen->get_tex_surface(screen, dst, face, level, i,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
st_surface_data(pipe, dst_surface,
0, 0, /* dstx, dsty */
@@ -265,7 +279,7 @@ st_texture_image_data(struct pipe_context *pipe,
0, 0, /* source x, y */
dst->width[level], height); /* width, height */
- pipe_surface_reference(&dst_surface, NULL);
+ screen->tex_surface_release(screen, &dst_surface);
srcUB += src_image_pitch * dst->cpp;
}
@@ -304,8 +318,27 @@ st_texture_image_copy(struct pipe_context *pipe,
assert(src->width[srcLevel] == width);
assert(src->height[srcLevel] == height);
- dst_surface = screen->get_tex_surface(screen, dst, face, dstLevel, i);
- src_surface = screen->get_tex_surface(screen, src, face, srcLevel, i);
+#if 0
+ {
+ src_surface = screen->get_tex_surface(screen, src, face, srcLevel, i,
+ PIPE_BUFFER_USAGE_CPU_READ);
+ ubyte *map = screen->surface_map(screen, src_surface, PIPE_BUFFER_USAGE_CPU_READ);
+ map += src_surface->width * src_surface->height * 4 / 2;
+ printf("%s center pixel: %d %d %d %d (pt %p[%d] -> %p[%d])\n",
+ __FUNCTION__,
+ map[0], map[1], map[2], map[3],
+ src, srcLevel, dst, dstLevel);
+
+ screen->surface_unmap(screen, src_surface);
+ pipe_surface_reference(&src_surface, NULL);
+ }
+#endif
+
+ dst_surface = screen->get_tex_surface(screen, dst, face, dstLevel, i,
+ PIPE_BUFFER_USAGE_GPU_WRITE);
+
+ src_surface = screen->get_tex_surface(screen, src, face, srcLevel, i,
+ PIPE_BUFFER_USAGE_GPU_READ);
pipe->surface_copy(pipe,
FALSE,
@@ -315,7 +348,7 @@ st_texture_image_copy(struct pipe_context *pipe,
0, 0, /* srcX, Y */
width, copyHeight);
- pipe_surface_reference(&dst_surface, NULL);
- pipe_surface_reference(&src_surface, NULL);
+ screen->tex_surface_release(screen, &src_surface);
+ screen->tex_surface_release(screen, &dst_surface);
}
}
diff --git a/src/mesa/state_tracker/st_texture.h b/src/mesa/state_tracker/st_texture.h
index b05762113c..3febe6a7cb 100644
--- a/src/mesa/state_tracker/st_texture.h
+++ b/src/mesa/state_tracker/st_texture.h
@@ -93,6 +93,11 @@ st_get_stobj_texture(struct st_texture_object *stObj)
return stObj ? stObj->pt : NULL;
}
+static INLINE GLboolean pf_is_depth_stencil( enum pipe_format format )
+{
+ return (pf_get_component_bits( format, PIPE_FORMAT_COMP_Z ) +
+ pf_get_component_bits( format, PIPE_FORMAT_COMP_S )) != 0;
+}
extern struct pipe_texture *
@@ -103,7 +108,8 @@ st_texture_create(struct st_context *st,
GLuint width0,
GLuint height0,
GLuint depth0,
- GLuint compress_byte);
+ GLuint compress_byte,
+ GLuint tex_usage );
/* Check if an image fits into an existing texture object.
@@ -119,10 +125,12 @@ st_texture_match_image(const struct pipe_texture *pt,
extern GLubyte *
st_texture_image_map(struct st_context *st,
struct st_texture_image *stImage,
- GLuint zoffset);
+ GLuint zoffset,
+ GLuint flags);
extern void
-st_texture_image_unmap(struct st_texture_image *stImage);
+st_texture_image_unmap(struct st_context *st,
+ struct st_texture_image *stImage);
/* Return pointers to each 2d slice within an image. Indexed by depth