summaryrefslogtreecommitdiffstats
path: root/src/gallium/auxiliary/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/auxiliary/util')
-rw-r--r--src/gallium/auxiliary/util/p_debug.c18
-rw-r--r--src/gallium/auxiliary/util/u_blit.c82
-rw-r--r--src/gallium/auxiliary/util/u_draw_quad.c59
-rw-r--r--src/gallium/auxiliary/util/u_draw_quad.h16
-rw-r--r--src/gallium/auxiliary/util/u_gen_mipmap.c73
-rw-r--r--src/gallium/auxiliary/util/u_handle_table.c3
-rw-r--r--src/gallium/auxiliary/util/u_simple_shaders.c114
-rw-r--r--src/gallium/auxiliary/util/u_simple_shaders.h12
8 files changed, 333 insertions, 44 deletions
diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c
index bd3a0221eaa..c51e9e6a692 100644
--- a/src/gallium/auxiliary/util/p_debug.c
+++ b/src/gallium/auxiliary/util/p_debug.c
@@ -85,6 +85,22 @@ void debug_printf(const char *format, ...)
}
+void debug_print_blob( const char *name,
+ const void *blob,
+ unsigned size )
+{
+ const unsigned *ublob = (const unsigned *)blob;
+ unsigned i;
+
+ debug_printf("%s (%d dwords%s)\n", name, size/4,
+ size%4 ? "... plus a few bytes" : "");
+
+ for (i = 0; i < size/4; i++) {
+ debug_printf("%d:\t%08x\n", i, ublob[i]);
+ }
+}
+
+
/* TODO: implement a debug_abort that calls EngBugCheckEx on WIN32 */
@@ -240,3 +256,5 @@ debug_dump_flags(const struct debug_named_value *names,
return output;
}
+
+
diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c
index d05dae3af8f..28a404fd01f 100644
--- a/src/gallium/auxiliary/util/u_blit.c
+++ b/src/gallium/auxiliary/util/u_blit.c
@@ -61,6 +61,9 @@ struct blit_state
/*struct pipe_viewport_state viewport;*/
struct pipe_sampler_state *vs;
struct pipe_sampler_state *fs;
+
+ struct pipe_buffer *vbuf; /**< quad vertices */
+ float vertices[4][2][4]; /**< vertex/texcoords for quad */
};
@@ -72,6 +75,7 @@ struct blit_state *
util_create_blit(struct pipe_context *pipe, struct cso_context *cso)
{
struct blit_state *ctx;
+ uint i;
ctx = CALLOC_STRUCT(blit_state);
if (!ctx)
@@ -132,6 +136,24 @@ util_create_blit(struct pipe_context *pipe, struct cso_context *cso)
/* fragment shader */
ctx->fs = util_make_fragment_tex_shader(pipe);
+ ctx->vbuf = pipe->winsys->buffer_create(pipe->winsys,
+ 32,
+ PIPE_BUFFER_USAGE_VERTEX,
+ sizeof(ctx->vertices));
+ if (!ctx->vbuf) {
+ FREE(ctx);
+ ctx->pipe->delete_fs_state(ctx->pipe, ctx->fs);
+ ctx->pipe->delete_vs_state(ctx->pipe, ctx->vs);
+ return NULL;
+ }
+
+ /* init vertex data that doesn't change */
+ for (i = 0; i < 4; i++) {
+ ctx->vertices[i][0][3] = 1.0f; /* w */
+ ctx->vertices[i][1][2] = 0.0f; /* r */
+ ctx->vertices[i][1][3] = 1.0f; /* q */
+ }
+
return ctx;
}
@@ -147,11 +169,56 @@ util_destroy_blit(struct blit_state *ctx)
pipe->delete_vs_state(pipe, ctx->vs);
pipe->delete_fs_state(pipe, ctx->fs);
+ pipe->winsys->buffer_destroy(pipe->winsys, ctx->vbuf);
+
FREE(ctx);
}
/**
+ * Setup vertex data for the textured quad we'll draw.
+ * Note: y=0=top
+ */
+static void
+setup_vertex_data(struct blit_state *ctx,
+ float x0, float y0, float x1, float y1, float z)
+{
+ void *buf;
+
+ ctx->vertices[0][0][0] = x0;
+ ctx->vertices[0][0][1] = y0;
+ ctx->vertices[0][0][2] = z;
+ ctx->vertices[0][1][0] = 0.0f; /*s*/
+ ctx->vertices[0][1][1] = 0.0f; /*t*/
+
+ ctx->vertices[1][0][0] = x1;
+ ctx->vertices[1][0][1] = y0;
+ ctx->vertices[1][0][2] = z;
+ ctx->vertices[1][1][0] = 1.0f; /*s*/
+ ctx->vertices[1][1][1] = 0.0f; /*t*/
+
+ ctx->vertices[2][0][0] = x1;
+ ctx->vertices[2][0][1] = y1;
+ ctx->vertices[2][0][2] = z;
+ ctx->vertices[2][1][0] = 1.0f;
+ ctx->vertices[2][1][1] = 1.0f;
+
+ ctx->vertices[3][0][0] = x0;
+ ctx->vertices[3][0][1] = y1;
+ ctx->vertices[3][0][2] = z;
+ ctx->vertices[3][1][0] = 0.0f;
+ ctx->vertices[3][1][1] = 1.0f;
+
+ buf = ctx->pipe->winsys->buffer_map(ctx->pipe->winsys, ctx->vbuf,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+
+ memcpy(buf, ctx->vertices, sizeof(ctx->vertices));
+
+ ctx->pipe->winsys->buffer_unmap(ctx->pipe->winsys, ctx->vbuf);
+}
+
+
+/**
* Copy pixel block from src surface to dst surface.
* Overlapping regions are acceptable.
* XXX need some control over blitting Z and/or stencil.
@@ -249,16 +316,21 @@ util_blit_pixels(struct blit_state *ctx,
/* drawing dest */
memset(&fb, 0, sizeof(fb));
+ fb.width = dst->width;
+ fb.height = dst->height;
fb.num_cbufs = 1;
fb.cbufs[0] = dst;
cso_set_framebuffer(ctx->cso, &fb);
/* draw quad */
- util_draw_texquad(pipe,
- (float)dstX0,
- (float)dstY0,
- (float)dstX1,
- (float)dstY1, z);
+ setup_vertex_data(ctx,
+ (float) dstX0, (float) dstY0,
+ (float) dstX1, (float) dstY1, z);
+
+ util_draw_vertex_buffer(ctx->pipe, ctx->vbuf,
+ PIPE_PRIM_TRIANGLE_FAN,
+ 4, /* verts */
+ 2); /* attribs/vert */
/* restore state we changed */
cso_restore_blend(ctx->cso);
diff --git a/src/gallium/auxiliary/util/u_draw_quad.c b/src/gallium/auxiliary/util/u_draw_quad.c
index 79a69de633d..37e85336091 100644
--- a/src/gallium/auxiliary/util/u_draw_quad.c
+++ b/src/gallium/auxiliary/util/u_draw_quad.c
@@ -34,15 +34,51 @@
/**
+ * Draw a simple vertex buffer / primitive.
+ * Limited to float[4] vertex attribs, tightly packed.
+ */
+void
+util_draw_vertex_buffer(struct pipe_context *pipe,
+ struct pipe_buffer *vbuf,
+ uint prim_type,
+ uint num_verts,
+ uint num_attribs)
+{
+ struct pipe_vertex_buffer vbuffer;
+ struct pipe_vertex_element velement;
+ uint i;
+
+ /* tell pipe about the vertex buffer */
+ vbuffer.buffer = vbuf;
+ vbuffer.pitch = num_attribs * 4 * sizeof(float); /* vertex size */
+ vbuffer.buffer_offset = 0;
+ pipe->set_vertex_buffer(pipe, 0, &vbuffer);
+
+ /* tell pipe about the vertex attributes */
+ for (i = 0; i < num_attribs; i++) {
+ velement.src_offset = i * 4 * sizeof(float);
+ velement.vertex_buffer_index = 0;
+ velement.src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+ velement.nr_components = 4;
+ pipe->set_vertex_element(pipe, i, &velement);
+ }
+
+ /* draw */
+ pipe->draw_arrays(pipe, prim_type, 0, num_verts);
+}
+
+
+
+/**
* Draw screen-aligned textured quad.
+ * Note: this function allocs/destroys a vertex buffer and isn't especially
+ * efficient.
*/
void
util_draw_texquad(struct pipe_context *pipe,
float x0, float y0, float x1, float y1, float z)
{
struct pipe_buffer *vbuf;
- struct pipe_vertex_buffer vbuffer;
- struct pipe_vertex_element velement;
uint numAttribs = 2, vertexBytes, i, j;
float *v;
@@ -89,24 +125,7 @@ util_draw_texquad(struct pipe_context *pipe,
pipe->winsys->buffer_unmap(pipe->winsys, vbuf);
- /* tell pipe about the vertex buffer */
- vbuffer.buffer = vbuf;
- vbuffer.pitch = numAttribs * 4 * sizeof(float); /* vertex size */
- vbuffer.buffer_offset = 0;
- pipe->set_vertex_buffer(pipe, 0, &vbuffer);
-
- /* tell pipe about the vertex attributes */
- for (i = 0; i < numAttribs; i++) {
- velement.src_offset = i * 4 * sizeof(float);
- velement.vertex_buffer_index = 0;
- velement.src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
- velement.nr_components = 4;
- pipe->set_vertex_element(pipe, i, &velement);
- }
-
- /* draw */
- pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLE_FAN, 0, 4);
+ util_draw_vertex_buffer(pipe, vbuf, PIPE_PRIM_TRIANGLE_FAN, 4, 2);
- /* XXX: do one-time */
pipe_buffer_reference(pipe->winsys, &vbuf, NULL);
}
diff --git a/src/gallium/auxiliary/util/u_draw_quad.h b/src/gallium/auxiliary/util/u_draw_quad.h
index a97f55d2efd..5b6539a99ca 100644
--- a/src/gallium/auxiliary/util/u_draw_quad.h
+++ b/src/gallium/auxiliary/util/u_draw_quad.h
@@ -29,9 +29,25 @@
#define U_DRAWQUAD_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern void
+util_draw_vertex_buffer(struct pipe_context *pipe,
+ struct pipe_buffer *vbuf,
+ uint num_attribs, uint num_verts, uint prim_type);
+
+
extern void
util_draw_texquad(struct pipe_context *pipe,
float x0, float y0, float x1, float y1, float z);
+#ifdef __cplusplus
+}
+#endif
+
+
#endif
diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c
index 028b180a777..cf02f00b1b7 100644
--- a/src/gallium/auxiliary/util/u_gen_mipmap.c
+++ b/src/gallium/auxiliary/util/u_gen_mipmap.c
@@ -64,6 +64,9 @@ struct gen_mipmap_state
/*struct pipe_viewport_state viewport;*/
struct pipe_sampler_state *vs;
struct pipe_sampler_state *fs;
+
+ struct pipe_buffer *vbuf; /**< quad vertices */
+ float vertices[4][2][4]; /**< vertex/texcoords for quad */
};
@@ -683,6 +686,7 @@ util_create_gen_mipmap(struct pipe_context *pipe,
struct cso_context *cso)
{
struct gen_mipmap_state *ctx;
+ uint i;
ctx = CALLOC_STRUCT(gen_mipmap_state);
if (!ctx)
@@ -744,10 +748,62 @@ util_create_gen_mipmap(struct pipe_context *pipe,
/* fragment shader */
ctx->fs = util_make_fragment_tex_shader(pipe);
+ ctx->vbuf = pipe->winsys->buffer_create(pipe->winsys,
+ 32,
+ PIPE_BUFFER_USAGE_VERTEX,
+ sizeof(ctx->vertices));
+ if (!ctx->vbuf) {
+ FREE(ctx);
+ return NULL;
+ }
+
+ /* vertex data that doesn't change */
+ for (i = 0; i < 4; i++) {
+ ctx->vertices[i][0][2] = 0.0f; /* z */
+ ctx->vertices[i][0][3] = 1.0f; /* w */
+ ctx->vertices[i][1][2] = 0.0f; /* r */
+ ctx->vertices[i][1][3] = 1.0f; /* q */
+ }
+
return ctx;
}
+static void
+set_vertex_data(struct gen_mipmap_state *ctx, float width, float height)
+{
+ void *buf;
+
+ ctx->vertices[0][0][0] = 0.0f; /*x*/
+ ctx->vertices[0][0][1] = 0.0f; /*y*/
+ ctx->vertices[0][1][0] = 0.0f; /*s*/
+ ctx->vertices[0][1][1] = 0.0f; /*t*/
+
+ ctx->vertices[1][0][0] = width; /*x*/
+ ctx->vertices[1][0][1] = 0.0f; /*y*/
+ ctx->vertices[1][1][0] = 1.0f; /*s*/
+ ctx->vertices[1][1][1] = 0.0f; /*t*/
+
+ ctx->vertices[2][0][0] = width;
+ ctx->vertices[2][0][1] = height;
+ ctx->vertices[2][1][0] = 1.0f;
+ ctx->vertices[2][1][1] = 1.0f;
+
+ ctx->vertices[3][0][0] = 0.0f;
+ ctx->vertices[3][0][1] = height;
+ ctx->vertices[3][1][0] = 0.0f;
+ ctx->vertices[3][1][1] = 1.0f;
+
+ buf = ctx->pipe->winsys->buffer_map(ctx->pipe->winsys, ctx->vbuf,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+
+ memcpy(buf, ctx->vertices, sizeof(ctx->vertices));
+
+ ctx->pipe->winsys->buffer_unmap(ctx->pipe->winsys, ctx->vbuf);
+}
+
+
+
/**
* Destroy a mipmap generation context
*/
@@ -759,6 +815,8 @@ util_destroy_gen_mipmap(struct gen_mipmap_state *ctx)
pipe->delete_vs_state(pipe, ctx->vs);
pipe->delete_fs_state(pipe, ctx->fs);
+ pipe->winsys->buffer_destroy(pipe->winsys, ctx->vbuf);
+
FREE(ctx);
}
@@ -843,6 +901,8 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
* Setup framebuffer / dest surface
*/
fb.cbufs[0] = screen->get_tex_surface(screen, pt, face, dstLevel, zslice);
+ fb.width = pt->width[dstLevel];
+ fb.height = pt->height[dstLevel];
cso_set_framebuffer(ctx->cso, &fb);
/*
@@ -863,12 +923,13 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
pipe->set_sampler_textures(pipe, 1, &pt);
/* quad coords in window coords (bypassing clipping, viewport mapping) */
- util_draw_texquad(pipe,
- 0.0F, 0.0F, /* x0, y0 */
- (float) pt->width[dstLevel], /* x1 */
- (float) pt->height[dstLevel], /* y1 */
- 0.0F); /* z */
-
+ set_vertex_data(ctx,
+ (float) pt->width[dstLevel],
+ (float) pt->height[dstLevel]);
+ util_draw_vertex_buffer(ctx->pipe, ctx->vbuf,
+ PIPE_PRIM_TRIANGLE_FAN,
+ 4, /* verts */
+ 2); /* attribs/vert */
pipe->flush(pipe, PIPE_FLUSH_WAIT);
diff --git a/src/gallium/auxiliary/util/u_handle_table.c b/src/gallium/auxiliary/util/u_handle_table.c
index 8b0f7fca4b1..5a731a6b963 100644
--- a/src/gallium/auxiliary/util/u_handle_table.c
+++ b/src/gallium/auxiliary/util/u_handle_table.c
@@ -171,8 +171,7 @@ handle_table_set(struct handle_table *ht,
assert(ht);
assert(handle > 0);
- assert(handle <= ht->size);
- if(!handle || handle > ht->size)
+ if(!handle)
return 0;
assert(object);
diff --git a/src/gallium/auxiliary/util/u_simple_shaders.c b/src/gallium/auxiliary/util/u_simple_shaders.c
index 88e2ab05bd0..d230ddfbebc 100644
--- a/src/gallium/auxiliary/util/u_simple_shaders.c
+++ b/src/gallium/auxiliary/util/u_simple_shaders.c
@@ -68,7 +68,7 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe,
uint ti, i;
struct pipe_shader_state shader;
- tokens = (struct tgsi_token *) malloc(maxTokens * sizeof(tokens[0]));
+ tokens = (struct tgsi_token *) MALLOC(maxTokens * sizeof(tokens[0]));
/* shader header
*/
@@ -84,16 +84,15 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe,
/* declare inputs */
for (i = 0; i < num_attribs; i++) {
-
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_INPUT;
- /*
+
decl.Declaration.Semantic = 1;
- decl.Semantic.SemanticName = TGSI_SEMANTIC_POSITION;
- decl.Semantic.SemanticIndex = 0;
- */
+ decl.Semantic.SemanticName = semantic_names[i];
+ decl.Semantic.SemanticIndex = semantic_indexes[i];
+
decl.u.DeclarationRange.First =
- decl.u.DeclarationRange.Last = 0;
+ decl.u.DeclarationRange.Last = i;
ti += tgsi_build_full_declaration(&decl,
&tokens[ti],
header,
@@ -102,19 +101,17 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe,
/* declare outputs */
for (i = 0; i < num_attribs; i++) {
-
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_OUTPUT;
decl.Declaration.Semantic = 1;
decl.Semantic.SemanticName = semantic_names[i];
decl.Semantic.SemanticIndex = semantic_indexes[i];
decl.u.DeclarationRange.First =
- decl.u.DeclarationRange.Last = 0;
+ decl.u.DeclarationRange.Last = i;
ti += tgsi_build_full_declaration(&decl,
&tokens[ti],
header,
maxTokens - ti);
-
}
/* emit MOV instructions */
@@ -173,7 +170,7 @@ util_make_fragment_tex_shader(struct pipe_context *pipe)
uint ti;
struct pipe_shader_state shader;
- tokens = (struct tgsi_token *) malloc(maxTokens * sizeof(tokens[0]));
+ tokens = (struct tgsi_token *) MALLOC(maxTokens * sizeof(tokens[0]));
/* shader header
*/
@@ -261,3 +258,98 @@ util_make_fragment_tex_shader(struct pipe_context *pipe)
return pipe->create_fs_state(pipe, &shader);
}
+
+
+
+
+/**
+ * Make simple fragment color pass-through shader.
+ */
+void *
+util_make_fragment_passthrough_shader(struct pipe_context *pipe)
+{
+ uint maxTokens = 40;
+ struct tgsi_token *tokens;
+ struct tgsi_header *header;
+ struct tgsi_processor *processor;
+ struct tgsi_full_declaration decl;
+ struct tgsi_full_instruction inst;
+ const uint procType = TGSI_PROCESSOR_FRAGMENT;
+ uint ti;
+ struct pipe_shader_state shader;
+
+ tokens = (struct tgsi_token *) MALLOC(maxTokens * sizeof(tokens[0]));
+
+ /* shader header
+ */
+ *(struct tgsi_version *) &tokens[0] = tgsi_build_version();
+
+ header = (struct tgsi_header *) &tokens[1];
+ *header = tgsi_build_header();
+
+ processor = (struct tgsi_processor *) &tokens[2];
+ *processor = tgsi_build_processor( procType, header );
+
+ ti = 3;
+
+ /* declare input */
+ decl = tgsi_default_full_declaration();
+ decl.Declaration.File = TGSI_FILE_INPUT;
+ decl.Declaration.Semantic = 1;
+ decl.Semantic.SemanticName = TGSI_SEMANTIC_COLOR;
+ decl.Semantic.SemanticIndex = 0;
+ decl.u.DeclarationRange.First =
+ decl.u.DeclarationRange.Last = 0;
+ ti += tgsi_build_full_declaration(&decl,
+ &tokens[ti],
+ header,
+ maxTokens - ti);
+
+ /* declare output */
+ decl = tgsi_default_full_declaration();
+ decl.Declaration.File = TGSI_FILE_OUTPUT;
+ decl.Declaration.Semantic = 1;
+ decl.Semantic.SemanticName = TGSI_SEMANTIC_COLOR;
+ decl.Semantic.SemanticIndex = 0;
+ decl.u.DeclarationRange.First =
+ decl.u.DeclarationRange.Last = 0;
+ ti += tgsi_build_full_declaration(&decl,
+ &tokens[ti],
+ header,
+ maxTokens - ti);
+
+
+ /* MOVE out[0], in[0]; */
+ inst = tgsi_default_full_instruction();
+ inst.Instruction.Opcode = TGSI_OPCODE_MOV;
+ inst.Instruction.NumDstRegs = 1;
+ inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT;
+ inst.FullDstRegisters[0].DstRegister.Index = 0;
+ inst.Instruction.NumSrcRegs = 1;
+ inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT;
+ inst.FullSrcRegisters[0].SrcRegister.Index = 0;
+ ti += tgsi_build_full_instruction(&inst,
+ &tokens[ti],
+ header,
+ maxTokens - ti );
+
+ /* END instruction */
+ inst = tgsi_default_full_instruction();
+ inst.Instruction.Opcode = TGSI_OPCODE_END;
+ inst.Instruction.NumDstRegs = 0;
+ inst.Instruction.NumSrcRegs = 0;
+ ti += tgsi_build_full_instruction(&inst,
+ &tokens[ti],
+ header,
+ maxTokens - ti );
+
+ assert(ti < maxTokens);
+
+#if 0 /*debug*/
+ tgsi_dump(tokens, 0);
+#endif
+
+ shader.tokens = tokens;
+ return pipe->create_fs_state(pipe, &shader);
+}
+
diff --git a/src/gallium/auxiliary/util/u_simple_shaders.h b/src/gallium/auxiliary/util/u_simple_shaders.h
index 3ef4f288018..ca219a092c7 100644
--- a/src/gallium/auxiliary/util/u_simple_shaders.h
+++ b/src/gallium/auxiliary/util/u_simple_shaders.h
@@ -36,6 +36,11 @@
struct pipe_context;
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
extern void *
util_make_vertex_passthrough_shader(struct pipe_context *pipe,
uint num_attribs,
@@ -47,6 +52,13 @@ extern void *
util_make_fragment_tex_shader(struct pipe_context *pipe);
+extern void *
+util_make_fragment_passthrough_shader(struct pipe_context *pipe);
+
+
+#ifdef __cplusplus
+}
#endif
+#endif