summaryrefslogtreecommitdiff
path: root/src/gallium/auxiliary
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/auxiliary')
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_aaline.c2
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_pstipple.c1
-rw-r--r--src/gallium/auxiliary/rbug/rbug_connection.c1
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_build.c104
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_build.h28
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_dump.c70
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_dump.h5
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_exec.c27
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_iterate.c6
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_iterate.h5
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_parse.c16
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_parse.h7
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_ppc.c7
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_sanity.c12
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_scan.c21
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_scan.h8
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_sse2.c7
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_text.c139
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_transform.c25
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_transform.h4
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_ureg.c31
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_ureg.h4
-rw-r--r--src/gallium/auxiliary/util/Makefile3
-rw-r--r--src/gallium/auxiliary/util/SConscript3
-rw-r--r--src/gallium/auxiliary/util/u_blit.c8
-rw-r--r--src/gallium/auxiliary/util/u_blitter.c719
-rw-r--r--src/gallium/auxiliary/util/u_blitter.h230
-rw-r--r--src/gallium/auxiliary/util/u_debug.c34
-rw-r--r--src/gallium/auxiliary/util/u_dl.c79
-rw-r--r--src/gallium/auxiliary/util/u_dl.h61
-rw-r--r--src/gallium/auxiliary/util/u_format.c15
-rw-r--r--src/gallium/auxiliary/util/u_format.csv8
-rw-r--r--src/gallium/auxiliary/util/u_format.h252
-rw-r--r--src/gallium/auxiliary/util/u_format_access.py4
-rwxr-xr-xsrc/gallium/auxiliary/util/u_format_table.py18
-rw-r--r--src/gallium/auxiliary/util/u_gen_mipmap.c79
-rw-r--r--src/gallium/auxiliary/util/u_math.h13
-rw-r--r--src/gallium/auxiliary/util/u_pack_color.h41
-rw-r--r--src/gallium/auxiliary/util/u_prim.h2
-rw-r--r--src/gallium/auxiliary/util/u_rect.c21
-rw-r--r--src/gallium/auxiliary/util/u_simple_shaders.c70
-rw-r--r--src/gallium/auxiliary/util/u_simple_shaders.h13
-rw-r--r--src/gallium/auxiliary/util/u_surface.c1
-rw-r--r--src/gallium/auxiliary/util/u_texture.c102
-rw-r--r--src/gallium/auxiliary/util/u_texture.h54
-rw-r--r--src/gallium/auxiliary/util/u_tile.c9
-rw-r--r--src/gallium/auxiliary/util/u_upload_mgr.h2
-rw-r--r--src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c5
48 files changed, 2235 insertions, 141 deletions
diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c
index 23d8b609e1..14375426ed 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c
@@ -35,6 +35,8 @@
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "pipe/p_shader_tokens.h"
+
+#include "util/u_format.h"
#include "util/u_math.h"
#include "util/u_memory.h"
diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c
index bcb860da2e..0cc2b71864 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c
@@ -38,6 +38,7 @@
#include "pipe/p_defines.h"
#include "pipe/p_shader_tokens.h"
+#include "util/u_format.h"
#include "util/u_math.h"
#include "util/u_memory.h"
diff --git a/src/gallium/auxiliary/rbug/rbug_connection.c b/src/gallium/auxiliary/rbug/rbug_connection.c
index 52acb700af..ae4e27f9f6 100644
--- a/src/gallium/auxiliary/rbug/rbug_connection.c
+++ b/src/gallium/auxiliary/rbug/rbug_connection.c
@@ -87,6 +87,7 @@ rbug_get_message(struct rbug_connection *c, uint32_t *serial)
if (!data) {
return NULL;
}
+ data->opcode = 0;
do {
uint8_t *ptr = ((uint8_t*)data) + read;
diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.c b/src/gallium/auxiliary/tgsi/tgsi_build.c
index 4092f78f4a..92903fe57f 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_build.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_build.c
@@ -942,3 +942,107 @@ tgsi_default_full_dst_register( void )
return full_dst_register;
}
+struct tgsi_property
+tgsi_default_property( void )
+{
+ struct tgsi_property property;
+
+ property.Type = TGSI_TOKEN_TYPE_PROPERTY;
+ property.NrTokens = 1;
+ property.PropertyName = TGSI_PROPERTY_GS_INPUT_PRIM;
+ property.Padding = 0;
+
+ return property;
+}
+
+struct tgsi_property
+tgsi_build_property(unsigned property_name,
+ struct tgsi_header *header)
+{
+ struct tgsi_property property;
+
+ property = tgsi_default_property();
+ property.PropertyName = property_name;
+
+ header_bodysize_grow( header );
+
+ return property;
+}
+
+
+struct tgsi_full_property
+tgsi_default_full_property( void )
+{
+ struct tgsi_full_property full_property;
+
+ full_property.Property = tgsi_default_property();
+ memset(full_property.u, 0,
+ sizeof(struct tgsi_property_data) * 8);
+
+ return full_property;
+}
+
+static void
+property_grow(
+ struct tgsi_property *property,
+ struct tgsi_header *header )
+{
+ assert( property->NrTokens < 0xFF );
+
+ property->NrTokens++;
+
+ header_bodysize_grow( header );
+}
+
+struct tgsi_property_data
+tgsi_build_property_data(
+ unsigned value,
+ struct tgsi_property *property,
+ struct tgsi_header *header )
+{
+ struct tgsi_property_data property_data;
+
+ property_data.Data = value;
+
+ property_grow( property, header );
+
+ return property_data;
+}
+
+unsigned
+tgsi_build_full_property(
+ const struct tgsi_full_property *full_prop,
+ struct tgsi_token *tokens,
+ struct tgsi_header *header,
+ unsigned maxsize )
+{
+ unsigned size = 0, i;
+ struct tgsi_property *property;
+
+ if( maxsize <= size )
+ return 0;
+ property = (struct tgsi_property *) &tokens[size];
+ size++;
+
+ *property = tgsi_build_property(
+ TGSI_PROPERTY_GS_INPUT_PRIM,
+ header );
+
+ assert( full_prop->Property.NrTokens <= 8 + 1 );
+
+ for( i = 0; i < full_prop->Property.NrTokens - 1; i++ ) {
+ struct tgsi_property_data *data;
+
+ if( maxsize <= size )
+ return 0;
+ data = (struct tgsi_property_data *) &tokens[size];
+ size++;
+
+ *data = tgsi_build_property_data(
+ full_prop->u[i].Data,
+ property,
+ header );
+ }
+
+ return size;
+}
diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.h b/src/gallium/auxiliary/tgsi/tgsi_build.h
index ffea786770..9de2757fe4 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_build.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_build.h
@@ -127,6 +127,34 @@ tgsi_build_full_immediate(
unsigned maxsize );
/*
+ * properties
+ */
+
+struct tgsi_property
+tgsi_default_property( void );
+
+struct tgsi_property
+tgsi_build_property(
+ unsigned property_name,
+ struct tgsi_header *header );
+
+struct tgsi_full_property
+tgsi_default_full_property( void );
+
+struct tgsi_property_data
+tgsi_build_property_data(
+ unsigned value,
+ struct tgsi_property *property,
+ struct tgsi_header *header );
+
+unsigned
+tgsi_build_full_property(
+ const struct tgsi_full_property *full_prop,
+ struct tgsi_token *tokens,
+ struct tgsi_header *header,
+ unsigned maxsize );
+
+/*
* instruction
*/
diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.c b/src/gallium/auxiliary/tgsi/tgsi_dump.c
index d3a5da4b2b..5e7e5d2ff9 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_dump.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_dump.c
@@ -101,7 +101,8 @@ static const char *file_names[TGSI_FILE_COUNT] =
"ADDR",
"IMM",
"LOOP",
- "PRED"
+ "PRED",
+ "SV"
};
static const char *interpolate_names[] =
@@ -150,6 +151,27 @@ static const char *texture_names[] =
"SHADOWRECT"
};
+static const char *property_names[] =
+{
+ "GS_INPUT_PRIMITIVE",
+ "GS_OUTPUT_PRIMITIVE",
+ "GS_MAX_OUTPUT_VERTICES"
+};
+
+static const char *primitive_names[] =
+{
+ "POINTS",
+ "LINES",
+ "LINE_LOOP",
+ "LINE_STRIP",
+ "TRIANGLES",
+ "TRIANGLE_STRIP",
+ "TRIANGLE_FAN",
+ "QUADS",
+ "QUAD_STRIP",
+ "POLYGON"
+};
+
static void
_dump_register(
@@ -274,6 +296,50 @@ tgsi_dump_declaration(
}
static boolean
+iter_property(
+ struct tgsi_iterate_context *iter,
+ struct tgsi_full_property *prop )
+{
+ int i;
+ struct dump_ctx *ctx = (struct dump_ctx *)iter;
+
+ assert(Elements(property_names) == TGSI_PROPERTY_COUNT);
+
+ TXT( "PROPERTY " );
+ ENM(prop->Property.PropertyName, property_names);
+
+ if (prop->Property.NrTokens > 1)
+ TXT(" ");
+
+ for (i = 0; i < prop->Property.NrTokens - 1; ++i) {
+ switch (prop->Property.PropertyName) {
+ case TGSI_PROPERTY_GS_INPUT_PRIM:
+ case TGSI_PROPERTY_GS_OUTPUT_PRIM:
+ ENM(prop->u[i].Data, primitive_names);
+ break;
+ default:
+ SID( prop->u[i].Data );
+ break;
+ }
+ if (i < prop->Property.NrTokens - 2)
+ TXT( ", " );
+ }
+ EOL();
+
+ return TRUE;
+}
+
+void tgsi_dump_property(
+ const struct tgsi_full_property *prop )
+{
+ struct dump_ctx ctx;
+
+ ctx.printf = dump_ctx_printf;
+
+ iter_property( &ctx.iter, (struct tgsi_full_property *)prop );
+}
+
+static boolean
iter_immediate(
struct tgsi_iterate_context *iter,
struct tgsi_full_immediate *imm )
@@ -493,6 +559,7 @@ tgsi_dump(
ctx.iter.iterate_instruction = iter_instruction;
ctx.iter.iterate_declaration = iter_declaration;
ctx.iter.iterate_immediate = iter_immediate;
+ ctx.iter.iterate_property = iter_property;
ctx.iter.epilog = NULL;
ctx.instno = 0;
@@ -547,6 +614,7 @@ tgsi_dump_str(
ctx.base.iter.iterate_instruction = iter_instruction;
ctx.base.iter.iterate_declaration = iter_declaration;
ctx.base.iter.iterate_immediate = iter_immediate;
+ ctx.base.iter.iterate_property = iter_property;
ctx.base.iter.epilog = NULL;
ctx.base.instno = 0;
diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.h b/src/gallium/auxiliary/tgsi/tgsi_dump.h
index ad1e647ec9..4cd27317b3 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_dump.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_dump.h
@@ -49,6 +49,7 @@ tgsi_dump(
struct tgsi_full_immediate;
struct tgsi_full_instruction;
struct tgsi_full_declaration;
+struct tgsi_full_property;
void
tgsi_dump_immediate(
@@ -63,6 +64,10 @@ void
tgsi_dump_declaration(
const struct tgsi_full_declaration *decl );
+void
+tgsi_dump_property(
+ const struct tgsi_full_property *prop );
+
#if defined __cplusplus
}
#endif
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c
index 22984c3232..123117cb0a 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c
@@ -336,6 +336,9 @@ tgsi_exec_machine_bind_shader(
numInstructions++;
break;
+ case TGSI_TOKEN_TYPE_PROPERTY:
+ break;
+
default:
assert( 0 );
}
@@ -1158,6 +1161,7 @@ fetch_src_file_channel(
break;
case TGSI_FILE_INPUT:
+ case TGSI_FILE_SYSTEM_VALUE:
chan->u[0] = mach->Inputs[index->i[0]].xyzw[swizzle].u[0];
chan->u[1] = mach->Inputs[index->i[1]].xyzw[swizzle].u[1];
chan->u[2] = mach->Inputs[index->i[2]].xyzw[swizzle].u[2];
@@ -1302,6 +1306,7 @@ fetch_source(
*/
switch (reg->Register.File) {
case TGSI_FILE_INPUT:
+ case TGSI_FILE_SYSTEM_VALUE:
index.i[0] *= TGSI_EXEC_MAX_INPUT_ATTRIBS;
index.i[1] *= TGSI_EXEC_MAX_INPUT_ATTRIBS;
index.i[2] *= TGSI_EXEC_MAX_INPUT_ATTRIBS;
@@ -1892,7 +1897,8 @@ exec_declaration(struct tgsi_exec_machine *mach,
const struct tgsi_full_declaration *decl)
{
if (mach->Processor == TGSI_PROCESSOR_FRAGMENT) {
- if (decl->Declaration.File == TGSI_FILE_INPUT) {
+ if (decl->Declaration.File == TGSI_FILE_INPUT ||
+ decl->Declaration.File == TGSI_FILE_SYSTEM_VALUE) {
uint first, last, mask;
first = decl->Range.First;
@@ -3240,6 +3246,25 @@ exec_instruction(
case TGSI_OPCODE_NOP:
break;
+ case TGSI_OPCODE_BREAKC:
+ FETCH(&r[0], 0, CHAN_X);
+ /* update CondMask */
+ if (r[0].u[0] && (mach->ExecMask & 0x1)) {
+ mach->LoopMask &= ~0x1;
+ }
+ if (r[0].u[1] && (mach->ExecMask & 0x2)) {
+ mach->LoopMask &= ~0x2;
+ }
+ if (r[0].u[2] && (mach->ExecMask & 0x4)) {
+ mach->LoopMask &= ~0x4;
+ }
+ if (r[0].u[3] && (mach->ExecMask & 0x8)) {
+ mach->LoopMask &= ~0x8;
+ }
+ /* Todo: if mach->LoopMask == 0, jump to end of loop */
+ UPDATE_EXEC_MASK(mach);
+ break;
+
default:
assert( 0 );
}
diff --git a/src/gallium/auxiliary/tgsi/tgsi_iterate.c b/src/gallium/auxiliary/tgsi/tgsi_iterate.c
index 7b384f5e12..0ba5fe4841 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_iterate.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_iterate.c
@@ -66,6 +66,12 @@ tgsi_iterate_shader(
goto fail;
break;
+ case TGSI_TOKEN_TYPE_PROPERTY:
+ if (ctx->iterate_property)
+ if (!ctx->iterate_property( ctx, &parse.FullToken.FullProperty ))
+ goto fail;
+ break;
+
default:
assert( 0 );
}
diff --git a/src/gallium/auxiliary/tgsi/tgsi_iterate.h b/src/gallium/auxiliary/tgsi/tgsi_iterate.h
index ef5a33ebce..8d67f22c42 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_iterate.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_iterate.h
@@ -57,6 +57,11 @@ struct tgsi_iterate_context
struct tgsi_full_immediate *imm );
boolean
+ (* iterate_property)(
+ struct tgsi_iterate_context *ctx,
+ struct tgsi_full_property *prop );
+
+ boolean
(* epilog)(
struct tgsi_iterate_context *ctx );
diff --git a/src/gallium/auxiliary/tgsi/tgsi_parse.c b/src/gallium/auxiliary/tgsi/tgsi_parse.c
index 8f2b6a307d..fa65ecb997 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_parse.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_parse.c
@@ -220,6 +220,22 @@ tgsi_parse_token(
break;
}
+ case TGSI_TOKEN_TYPE_PROPERTY:
+ {
+ struct tgsi_full_property *prop = &ctx->FullToken.FullProperty;
+ uint prop_count;
+
+ memset(prop, 0, sizeof *prop);
+ copy_token(&prop->Property, &token);
+
+ prop_count = prop->Property.NrTokens - 1;
+ for (i = 0; i < prop_count; i++) {
+ next_token(ctx, &prop->u[i]);
+ }
+
+ break;
+ }
+
default:
assert( 0 );
}
diff --git a/src/gallium/auxiliary/tgsi/tgsi_parse.h b/src/gallium/auxiliary/tgsi/tgsi_parse.h
index 3aa1979a63..439a57269b 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_parse.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_parse.h
@@ -67,6 +67,12 @@ struct tgsi_full_immediate
union tgsi_immediate_data u[4];
};
+struct tgsi_full_property
+{
+ struct tgsi_property Property;
+ struct tgsi_property_data u[8];
+};
+
#define TGSI_FULL_MAX_DST_REGISTERS 2
#define TGSI_FULL_MAX_SRC_REGISTERS 4 /* TXD has 4 */
@@ -86,6 +92,7 @@ union tgsi_full_token
struct tgsi_full_declaration FullDeclaration;
struct tgsi_full_immediate FullImmediate;
struct tgsi_full_instruction FullInstruction;
+ struct tgsi_full_property FullProperty;
};
struct tgsi_parse_context
diff --git a/src/gallium/auxiliary/tgsi/tgsi_ppc.c b/src/gallium/auxiliary/tgsi/tgsi_ppc.c
index da6ad6da04..138d2d095b 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_ppc.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_ppc.c
@@ -293,6 +293,7 @@ emit_fetch(struct gen_context *gen,
case TGSI_SWIZZLE_W:
switch (reg->Register.File) {
case TGSI_FILE_INPUT:
+ case TGSI_FILE_SYSTEM_VALUE:
{
int offset = (reg->Register.Index * 4 + swizzle) * 16;
int offset_reg = emit_li_offset(gen, offset);
@@ -1173,7 +1174,8 @@ emit_declaration(
struct ppc_function *func,
struct tgsi_full_declaration *decl )
{
- if( decl->Declaration.File == TGSI_FILE_INPUT ) {
+ if( decl->Declaration.File == TGSI_FILE_INPUT ||
+ decl->Declaration.File == TGSI_FILE_SYSTEM_VALUE ) {
#if 0
unsigned first, last, mask;
unsigned i, j;
@@ -1339,6 +1341,9 @@ tgsi_emit_ppc(const struct tgsi_token *tokens,
}
break;
+ case TGSI_TOKEN_TYPE_PROPERTY:
+ break;
+
default:
ok = 0;
assert( 0 );
diff --git a/src/gallium/auxiliary/tgsi/tgsi_sanity.c b/src/gallium/auxiliary/tgsi/tgsi_sanity.c
index b5d1faa897..c27579e794 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_sanity.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_sanity.c
@@ -324,6 +324,17 @@ iter_immediate(
return TRUE;
}
+
+static boolean
+iter_property(
+ struct tgsi_iterate_context *iter,
+ struct tgsi_full_property *prop )
+{
+ /*struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter;*/
+
+ return TRUE;
+}
+
static boolean
epilog(
struct tgsi_iterate_context *iter )
@@ -367,6 +378,7 @@ tgsi_sanity_check(
ctx.iter.iterate_instruction = iter_instruction;
ctx.iter.iterate_declaration = iter_declaration;
ctx.iter.iterate_immediate = iter_immediate;
+ ctx.iter.iterate_property = iter_property;
ctx.iter.epilog = epilog;
memset( ctx.regs_decl, 0, sizeof( ctx.regs_decl ) );
diff --git a/src/gallium/auxiliary/tgsi/tgsi_scan.c b/src/gallium/auxiliary/tgsi/tgsi_scan.c
index ebee000c06..0f48b0dc3a 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_scan.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_scan.c
@@ -97,7 +97,8 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
for (i = 0; i < fullinst->Instruction.NumSrcRegs; i++) {
const struct tgsi_full_src_register *src =
&fullinst->Src[i];
- if (src->Register.File == TGSI_FILE_INPUT) {
+ if (src->Register.File == TGSI_FILE_INPUT ||
+ src->Register.File == TGSI_FILE_SYSTEM_VALUE) {
const int ind = src->Register.Index;
if (info->input_semantic_name[ind] == TGSI_SEMANTIC_FOG) {
if (src->Register.SwizzleX == TGSI_SWIZZLE_X) {
@@ -128,7 +129,7 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
info->file_count[file]++;
info->file_max[file] = MAX2(info->file_max[file], (int)reg);
- if (file == TGSI_FILE_INPUT) {
+ if (file == TGSI_FILE_INPUT || file == TGSI_FILE_SYSTEM_VALUE) {
info->input_semantic_name[reg] = (ubyte)fulldecl->Semantic.Name;
info->input_semantic_index[reg] = (ubyte)fulldecl->Semantic.Index;
info->input_interpolate[reg] = (ubyte)fulldecl->Declaration.Interpolate;
@@ -164,6 +165,19 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
info->file_max[file] = MAX2(info->file_max[file], (int)reg);
}
break;
+ case TGSI_TOKEN_TYPE_PROPERTY:
+ {
+ const struct tgsi_full_property *fullprop
+ = &parse.FullToken.FullProperty;
+
+ info->properties[info->num_properties].name =
+ fullprop->Property.PropertyName;
+ memcpy(info->properties[info->num_properties].data,
+ fullprop->u, 8 * sizeof(unsigned));;
+
+ ++info->num_properties;
+ }
+ break;
default:
assert( 0 );
@@ -216,6 +230,7 @@ tgsi_is_passthrough_shader(const struct tgsi_token *tokens)
/* Do a whole bunch of checks for a simple move */
if (fullinst->Instruction.Opcode != TGSI_OPCODE_MOV ||
src->Register.File != TGSI_FILE_INPUT ||
+ src->Register.File != TGSI_FILE_SYSTEM_VALUE ||
dst->Register.File != TGSI_FILE_OUTPUT ||
src->Register.Index != dst->Register.Index ||
@@ -239,6 +254,8 @@ tgsi_is_passthrough_shader(const struct tgsi_token *tokens)
/* fall-through */
case TGSI_TOKEN_TYPE_IMMEDIATE:
/* fall-through */
+ case TGSI_TOKEN_TYPE_PROPERTY:
+ /* fall-through */
default:
; /* no-op */
}
diff --git a/src/gallium/auxiliary/tgsi/tgsi_scan.h b/src/gallium/auxiliary/tgsi/tgsi_scan.h
index 3ce0e88e4c..dae5376c24 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_scan.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_scan.h
@@ -33,7 +33,6 @@
#include "pipe/p_state.h"
#include "pipe/p_shader_tokens.h"
-
/**
* Shader summary info
*/
@@ -62,8 +61,13 @@ struct tgsi_shader_info
boolean uses_kill; /**< KIL or KILP instruction used? */
boolean uses_fogcoord; /**< fragment shader uses fog coord? */
boolean uses_frontfacing; /**< fragment shader uses front/back-face flag? */
-};
+ struct {
+ unsigned name;
+ unsigned data[8];
+ } properties[TGSI_PROPERTY_COUNT];
+ uint num_properties;
+};
extern void
tgsi_scan_shader(const struct tgsi_token *tokens,
diff --git a/src/gallium/auxiliary/tgsi/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/tgsi_sse2.c
index 76051ea0d8..d63c75dafb 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_sse2.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_sse2.c
@@ -1288,6 +1288,7 @@ emit_fetch(
break;
case TGSI_FILE_INPUT:
+ case TGSI_FILE_SYSTEM_VALUE:
emit_inputf(
func,
xmm,
@@ -2633,7 +2634,8 @@ emit_declaration(
struct x86_function *func,
struct tgsi_full_declaration *decl )
{
- if( decl->Declaration.File == TGSI_FILE_INPUT ) {
+ if( decl->Declaration.File == TGSI_FILE_INPUT ||
+ decl->Declaration.File == TGSI_FILE_SYSTEM_VALUE ) {
unsigned first, last, mask;
unsigned i, j;
@@ -2952,6 +2954,9 @@ tgsi_emit_sse2(
num_immediates++;
}
break;
+ case TGSI_TOKEN_TYPE_PROPERTY:
+ /* we just ignore them for now */
+ break;
default:
ok = 0;
diff --git a/src/gallium/auxiliary/tgsi/tgsi_text.c b/src/gallium/auxiliary/tgsi/tgsi_text.c
index eb376fa957..f000958bfc 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_text.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_text.c
@@ -27,6 +27,7 @@
#include "util/u_debug.h"
#include "util/u_memory.h"
+#include "pipe/p_defines.h"
#include "tgsi_text.h"
#include "tgsi_build.h"
#include "tgsi_info.h"
@@ -59,6 +60,21 @@ static boolean uprcase( char c )
return c;
}
+/*
+ * Ignore case of str1 and assume str2 is already uppercase.
+ * Return TRUE iff str1 and str2 are equal.
+ */
+static int
+streq_nocase_uprcase(const char *str1,
+ const char *str2)
+{
+ while (*str1 && uprcase(*str1) == *str2) {
+ str1++;
+ str2++;
+ }
+ return *str1 == *str2;
+}
+
static boolean str_match_no_case( const char **pcur, const char *str )
{
const char *cur = *pcur;
@@ -110,6 +126,20 @@ static boolean parse_uint( const char **pcur, uint *val )
return FALSE;
}
+static boolean parse_identifier( const char **pcur, char *ret )
+{
+ const char *cur = *pcur;
+ int i = 0;
+ if (is_alpha_underscore( cur )) {
+ ret[i++] = *cur++;
+ while (is_alpha_underscore( cur ))
+ ret[i++] = *cur++;
+ *pcur = cur;
+ return TRUE;
+ }
+ return FALSE;
+}
+
/* Parse floating point.
*/
static boolean parse_float( const char **pcur, float *val )
@@ -229,7 +259,8 @@ static const char *file_names[TGSI_FILE_COUNT] =
"ADDR",
"IMM",
"LOOP",
- "PRED"
+ "PRED",
+ "SV"
};
static boolean
@@ -939,6 +970,106 @@ static boolean parse_immediate( struct translate_ctx *ctx )
return TRUE;
}
+static const char *property_names[] =
+{
+ "GS_INPUT_PRIMITIVE",
+ "GS_OUTPUT_PRIMITIVE",
+ "GS_MAX_OUTPUT_VERTICES"
+};
+
+static const char *primitive_names[] =
+{
+ "POINTS",
+ "LINES",
+ "LINE_LOOP",
+ "LINE_STRIP",
+ "TRIANGLES",
+ "TRIANGLE_STRIP",
+ "TRIANGLE_FAN",
+ "QUADS",
+ "QUAD_STRIP",
+ "POLYGON"
+};
+
+static boolean
+parse_primitive( const char **pcur, uint *primitive )
+{
+ uint i;
+
+ for (i = 0; i < PIPE_PRIM_MAX; i++) {
+ const char *cur = *pcur;
+
+ if (str_match_no_case( &cur, primitive_names[i])) {
+ *primitive = i;
+ *pcur = cur;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+
+static boolean parse_property( struct translate_ctx *ctx )
+{
+ struct tgsi_full_property prop;
+ uint property_name;
+ uint values[8];
+ uint advance;
+ char id[64];
+
+ if (!eat_white( &ctx->cur )) {
+ report_error( ctx, "Syntax error" );
+ return FALSE;
+ }
+ if (!parse_identifier( &ctx->cur, id )) {
+ report_error( ctx, "Syntax error" );
+ return FALSE;
+ }
+ for (property_name = 0; property_name < TGSI_PROPERTY_COUNT;
+ ++property_name) {
+ if (streq_nocase_uprcase(id, property_names[property_name])) {
+ break;
+ }
+ }
+ if (property_name >= TGSI_PROPERTY_COUNT) {
+ debug_printf( "\nError: Unknown property : '%s'", id );
+ return FALSE;
+ }
+
+ eat_opt_white( &ctx->cur );
+ switch(property_name) {
+ case TGSI_PROPERTY_GS_INPUT_PRIM:
+ case TGSI_PROPERTY_GS_OUTPUT_PRIM:
+ if (!parse_primitive(&ctx->cur, &values[0] )) {
+ report_error( ctx, "Unknown primitive name as property!" );
+ return FALSE;
+ }
+ break;
+ default:
+ if (!parse_uint(&ctx->cur, &values[0] )) {
+ report_error( ctx, "Expected unsigned integer as property!" );
+ return FALSE;
+ }
+ }
+
+ prop = tgsi_default_full_property();
+ prop.Property.PropertyName = property_name;
+ prop.Property.NrTokens += 1;
+ prop.u[0].Data = values[0];
+
+ advance = tgsi_build_full_property(
+ &prop,
+ ctx->tokens_cur,
+ ctx->header,
+ (uint) (ctx->tokens_end - ctx->tokens_cur) );
+ if (advance == 0)
+ return FALSE;
+ ctx->tokens_cur += advance;
+
+ return TRUE;
+}
+
+
static boolean translate( struct translate_ctx *ctx )
{
eat_opt_white( &ctx->cur );
@@ -947,7 +1078,6 @@ static boolean translate( struct translate_ctx *ctx )
while (*ctx->cur != '\0') {
uint label_val = 0;
-
if (!eat_white( &ctx->cur )) {
report_error( ctx, "Syntax error" );
return FALSE;
@@ -955,7 +1085,6 @@ static boolean translate( struct translate_ctx *ctx )
if (*ctx->cur == '\0')
break;
-
if (parse_label( ctx, &label_val )) {
if (!parse_instruction( ctx, TRUE ))
return FALSE;
@@ -968,6 +1097,10 @@ static boolean translate( struct translate_ctx *ctx )
if (!parse_immediate( ctx ))
return FALSE;
}
+ else if (str_match_no_case( &ctx->cur, "PROPERTY" )) {
+ if (!parse_property( ctx ))
+ return FALSE;
+ }
else if (!parse_instruction( ctx, FALSE )) {
return FALSE;
}
diff --git a/src/gallium/auxiliary/tgsi/tgsi_transform.c b/src/gallium/auxiliary/tgsi/tgsi_transform.c
index 8b8f489b35..ae875f29ab 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_transform.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_transform.c
@@ -79,6 +79,19 @@ emit_immediate(struct tgsi_transform_context *ctx,
}
+static void
+emit_property(struct tgsi_transform_context *ctx,
+ const struct tgsi_full_property *prop)
+{
+ uint ti = ctx->ti;
+
+ ti += tgsi_build_full_property(prop,
+ ctx->tokens_out + ti,
+ ctx->header,
+ ctx->max_tokens_out - ti);
+ ctx->ti = ti;
+}
+
/**
* Apply user-defined transformations to the input shader to produce
@@ -110,6 +123,7 @@ tgsi_transform_shader(const struct tgsi_token *tokens_in,
ctx->emit_instruction = emit_instruction;
ctx->emit_declaration = emit_declaration;
ctx->emit_immediate = emit_immediate;
+ ctx->emit_property = emit_property;
ctx->tokens_out = tokens_out;
ctx->max_tokens_out = max_tokens_out;
@@ -182,6 +196,17 @@ tgsi_transform_shader(const struct tgsi_token *tokens_in,
ctx->emit_immediate(ctx, fullimm);
}
break;
+ case TGSI_TOKEN_TYPE_PROPERTY:
+ {
+ struct tgsi_full_property *fullprop
+ = &parse.FullToken.FullProperty;
+
+ if (ctx->transform_property)
+ ctx->transform_property(ctx, fullprop);
+ else
+ ctx->emit_property(ctx, fullprop);
+ }
+ break;
default:
assert( 0 );
diff --git a/src/gallium/auxiliary/tgsi/tgsi_transform.h b/src/gallium/auxiliary/tgsi/tgsi_transform.h
index a121adbaef..818478e277 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_transform.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_transform.h
@@ -53,6 +53,8 @@ struct tgsi_transform_context
void (*transform_immediate)(struct tgsi_transform_context *ctx,
struct tgsi_full_immediate *imm);
+ void (*transform_property)(struct tgsi_transform_context *ctx,
+ struct tgsi_full_property *prop);
/**
* Called at end of input program to allow caller to append extra
@@ -73,6 +75,8 @@ struct tgsi_transform_context
const struct tgsi_full_declaration *decl);
void (*emit_immediate)(struct tgsi_transform_context *ctx,
const struct tgsi_full_immediate *imm);
+ void (*emit_property)(struct tgsi_transform_context *ctx,
+ const struct tgsi_full_property *prop);
struct tgsi_header *header;
uint max_tokens_out;
diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.c b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
index 3f943845f5..1e730e5342 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_ureg.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
@@ -90,6 +90,11 @@ struct ureg_program
unsigned vs_inputs[UREG_MAX_INPUT/32];
struct {
+ unsigned index;
+ } gs_input[UREG_MAX_INPUT];
+ unsigned nr_gs_inputs;
+
+ struct {
unsigned semantic_name;
unsigned semantic_index;
} output[UREG_MAX_OUTPUT];
@@ -278,6 +283,22 @@ ureg_DECL_vs_input( struct ureg_program *ureg,
}
+struct ureg_src
+ureg_DECL_gs_input(struct ureg_program *ureg,
+ unsigned index)
+{
+ if (ureg->nr_gs_inputs < UREG_MAX_INPUT) {
+ ureg->gs_input[ureg->nr_gs_inputs].index = index;
+ ureg->nr_gs_inputs++;
+ } else {
+ set_bad(ureg);
+ }
+
+ /* XXX: Add suport for true 2D input registers. */
+ return ureg_src_register(TGSI_FILE_INPUT, index);
+}
+
+
struct ureg_dst
ureg_DECL_output( struct ureg_program *ureg,
unsigned name,
@@ -964,8 +985,7 @@ static void emit_decls( struct ureg_program *ureg )
emit_decl_range( ureg, TGSI_FILE_INPUT, i, 1 );
}
}
- }
- else {
+ } else if (ureg->processor == TGSI_PROCESSOR_FRAGMENT) {
for (i = 0; i < ureg->nr_fs_inputs; i++) {
emit_decl( ureg,
TGSI_FILE_INPUT,
@@ -974,6 +994,13 @@ static void emit_decls( struct ureg_program *ureg )
ureg->fs_input[i].semantic_index,
ureg->fs_input[i].interp );
}
+ } else {
+ for (i = 0; i < ureg->nr_gs_inputs; i++) {
+ emit_decl_range(ureg,
+ TGSI_FILE_INPUT,
+ ureg->gs_input[i].index,
+ 1);
+ }
}
for (i = 0; i < ureg->nr_outputs; i++) {
diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.h b/src/gallium/auxiliary/tgsi/tgsi_ureg.h
index 94cc70a208..7e3e7bcf1d 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_ureg.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.h
@@ -133,6 +133,10 @@ struct ureg_src
ureg_DECL_vs_input( struct ureg_program *,
unsigned index );
+struct ureg_src
+ureg_DECL_gs_input(struct ureg_program *,
+ unsigned index);
+
struct ureg_dst
ureg_DECL_output( struct ureg_program *,
unsigned semantic_name,
diff --git a/src/gallium/auxiliary/util/Makefile b/src/gallium/auxiliary/util/Makefile
index 1d8bb55bbd..3ed90fd1b7 100644
--- a/src/gallium/auxiliary/util/Makefile
+++ b/src/gallium/auxiliary/util/Makefile
@@ -9,8 +9,10 @@ C_SOURCES = \
u_debug_symbol.c \
u_debug_stack.c \
u_blit.c \
+ u_blitter.c \
u_cache.c \
u_cpu_detect.c \
+ u_dl.c \
u_draw_quad.c \
u_format.c \
u_format_access.c \
@@ -30,6 +32,7 @@ C_SOURCES = \
u_stream_stdc.c \
u_stream_wd.c \
u_surface.c \
+ u_texture.c \
u_tile.c \
u_time.c \
u_timed_winsys.c \
diff --git a/src/gallium/auxiliary/util/SConscript b/src/gallium/auxiliary/util/SConscript
index 8d99106d0b..2a546d19dc 100644
--- a/src/gallium/auxiliary/util/SConscript
+++ b/src/gallium/auxiliary/util/SConscript
@@ -23,6 +23,7 @@ util = env.ConvenienceLibrary(
source = [
'u_bitmask.c',
'u_blit.c',
+ 'u_blitter.c',
'u_cache.c',
'u_cpu_detect.c',
'u_debug.c',
@@ -30,6 +31,7 @@ util = env.ConvenienceLibrary(
'u_debug_memory.c',
'u_debug_stack.c',
'u_debug_symbol.c',
+ 'u_dl.c',
'u_draw_quad.c',
'u_format.c',
'u_format_access.c',
@@ -48,6 +50,7 @@ util = env.ConvenienceLibrary(
'u_stream_stdc.c',
'u_stream_wd.c',
'u_surface.c',
+ 'u_texture.c',
'u_tile.c',
'u_time.c',
'u_timed_winsys.c',
diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c
index abe1de3302..3f74e2aa8b 100644
--- a/src/gallium/auxiliary/util/u_blit.c
+++ b/src/gallium/auxiliary/util/u_blit.c
@@ -42,6 +42,7 @@
#include "util/u_blit.h"
#include "util/u_draw_quad.h"
+#include "util/u_format.h"
#include "util/u_math.h"
#include "util/u_memory.h"
#include "util/u_simple_shaders.h"
@@ -126,7 +127,8 @@ util_create_blit(struct pipe_context *pipe, struct cso_context *cso)
}
/* fragment shader */
- ctx->fs[TGSI_WRITEMASK_XYZW] = util_make_fragment_tex_shader(pipe);
+ ctx->fs[TGSI_WRITEMASK_XYZW] =
+ util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_2D);
ctx->vbuf = NULL;
/* init vertex data that doesn't change */
@@ -420,7 +422,9 @@ util_blit_pixels_writemask(struct blit_state *ctx,
cso_set_sampler_textures(ctx->cso, 1, &tex);
if (ctx->fs[writemask] == NULL)
- ctx->fs[writemask] = util_make_fragment_tex_shader_writemask(pipe, writemask);
+ ctx->fs[writemask] =
+ util_make_fragment_tex_shader_writemask(pipe, TGSI_TEXTURE_2D,
+ writemask);
/* shaders */
cso_set_fragment_shader_handle(ctx->cso, ctx->fs[writemask]);
diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c
new file mode 100644
index 0000000000..1f794d39a1
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_blitter.c
@@ -0,0 +1,719 @@
+/**************************************************************************
+ *
+ * Copyright 2009 Marek Olšák <maraeo@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * Blitter utility to facilitate acceleration of the clear, surface_copy,
+ * and surface_fill functions.
+ *
+ * @author Marek Olšák
+ */
+
+#include "pipe/p_context.h"
+#include "pipe/p_defines.h"
+#include "pipe/p_inlines.h"
+#include "pipe/p_shader_tokens.h"
+#include "pipe/p_state.h"
+
+#include "util/u_format.h"
+#include "util/u_memory.h"
+#include "util/u_math.h"
+#include "util/u_blitter.h"
+#include "util/u_draw_quad.h"
+#include "util/u_pack_color.h"
+#include "util/u_rect.h"
+#include "util/u_simple_shaders.h"
+#include "util/u_texture.h"
+
+struct blitter_context_priv
+{
+ struct blitter_context blitter;
+
+ struct pipe_context *pipe; /**< pipe context */
+ struct pipe_buffer *vbuf; /**< quad */
+
+ float vertices[4][2][4]; /**< {pos, color} or {pos, texcoord} */
+
+ /* Templates for various state objects. */
+ struct pipe_depth_stencil_alpha_state template_dsa;
+ struct pipe_sampler_state template_sampler_state;
+
+ /* Constant state objects. */
+ /* Vertex shaders. */
+ void *vs_col; /**< Vertex shader which passes {pos, color} to the output */
+ void *vs_tex; /**<Vertex shader which passes {pos, texcoord} to the output.*/
+
+ /* Fragment shaders. */
+ /* FS which outputs a color to multiple color buffers. */
+ void *fs_col[PIPE_MAX_COLOR_BUFS];
+
+ /* FS which outputs a color from a texture,
+ where the index is PIPE_TEXTURE_* to be sampled. */
+ void *fs_texfetch_col[PIPE_MAX_TEXTURE_TYPES];
+
+ /* FS which outputs a depth from a texture,
+ where the index is PIPE_TEXTURE_* to be sampled. */
+ void *fs_texfetch_depth[PIPE_MAX_TEXTURE_TYPES];
+
+ /* Blend state. */
+ void *blend_write_color; /**< blend state with writemask of RGBA */
+ void *blend_keep_color; /**< blend state with writemask of 0 */
+
+ /* Depth stencil alpha state. */
+ void *dsa_write_depth_stencil[0xff]; /**< indices are stencil clear values */
+ void *dsa_write_depth_keep_stencil;
+ void *dsa_keep_depth_stencil;
+
+ /* Sampler state for clamping to a miplevel. */
+ void *sampler_state[PIPE_MAX_TEXTURE_LEVELS];
+
+ /* Rasterizer state. */
+ void *rs_state;
+};
+
+struct blitter_context *util_blitter_create(struct pipe_context *pipe)
+{
+ struct blitter_context_priv *ctx;
+ struct pipe_blend_state blend;
+ struct pipe_depth_stencil_alpha_state *dsa;
+ struct pipe_rasterizer_state rs_state;
+ struct pipe_sampler_state *sampler_state;
+ unsigned i;
+
+ ctx = CALLOC_STRUCT(blitter_context_priv);
+ if (!ctx)
+ return NULL;
+
+ ctx->pipe = pipe;
+
+ /* init state objects for them to be considered invalid */
+ ctx->blitter.saved_fb_state.nr_cbufs = ~0;
+ ctx->blitter.saved_num_textures = ~0;
+ ctx->blitter.saved_num_sampler_states = ~0;
+
+ /* blend state objects */
+ memset(&blend, 0, sizeof(blend));
+ ctx->blend_keep_color = pipe->create_blend_state(pipe, &blend);
+
+ blend.colormask = PIPE_MASK_RGBA;
+ ctx->blend_write_color = pipe->create_blend_state(pipe, &blend);
+
+ /* depth stencil alpha state objects */
+ dsa = &ctx->template_dsa;
+ ctx->dsa_keep_depth_stencil =
+ pipe->create_depth_stencil_alpha_state(pipe, dsa);
+
+ dsa->depth.enabled = 1;
+ dsa->depth.writemask = 1;
+ dsa->depth.func = PIPE_FUNC_ALWAYS;
+ ctx->dsa_write_depth_keep_stencil =
+ pipe->create_depth_stencil_alpha_state(pipe, dsa);
+
+ dsa->stencil[0].enabled = 1;
+ dsa->stencil[0].func = PIPE_FUNC_ALWAYS;
+ dsa->stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE;
+ dsa->stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
+ dsa->stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE;
+ dsa->stencil[0].valuemask = 0xff;
+ dsa->stencil[0].writemask = 0xff;
+ /* The DSA state objects which write depth and stencil are created
+ * on-demand. */
+
+ /* sampler state */
+ sampler_state = &ctx->template_sampler_state;
+ sampler_state->wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+ sampler_state->wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+ sampler_state->wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+ /* The sampler state objects which sample from a specified mipmap level
+ * are created on-demand. */
+
+ /* rasterizer state */
+ memset(&rs_state, 0, sizeof(rs_state));
+ rs_state.front_winding = PIPE_WINDING_CW;
+ rs_state.cull_mode = PIPE_WINDING_NONE;
+ rs_state.bypass_vs_clip_and_viewport = 1;
+ rs_state.gl_rasterization_rules = 1;
+ ctx->rs_state = pipe->create_rasterizer_state(pipe, &rs_state);
+
+ /* fragment shaders are created on-demand */
+
+ /* vertex shaders */
+ {
+ const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
+ TGSI_SEMANTIC_COLOR };
+ const uint semantic_indices[] = { 0, 0 };
+ ctx->vs_col =
+ util_make_vertex_passthrough_shader(pipe, 2, semantic_names,
+ semantic_indices);
+ }
+ {
+ const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
+ TGSI_SEMANTIC_GENERIC };
+ const uint semantic_indices[] = { 0, 0 };
+ ctx->vs_tex =
+ util_make_vertex_passthrough_shader(pipe, 2, semantic_names,
+ semantic_indices);
+ }
+
+ /* set invariant vertex coordinates */
+ for (i = 0; i < 4; i++)
+ ctx->vertices[i][0][3] = 1; /*v.w*/
+
+ /* create the vertex buffer */
+ ctx->vbuf = pipe_buffer_create(ctx->pipe->screen,
+ 32,
+ PIPE_BUFFER_USAGE_VERTEX,
+ sizeof(ctx->vertices));
+
+ return &ctx->blitter;
+}
+
+void util_blitter_destroy(struct blitter_context *blitter)
+{
+ struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
+ struct pipe_context *pipe = ctx->pipe;
+ int i;
+
+ pipe->delete_blend_state(pipe, ctx->blend_write_color);
+ pipe->delete_blend_state(pipe, ctx->blend_keep_color);
+ pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
+ pipe->delete_depth_stencil_alpha_state(pipe,
+ ctx->dsa_write_depth_keep_stencil);
+
+ for (i = 0; i < 0xff; i++)
+ if (ctx->dsa_write_depth_stencil[i])
+ pipe->delete_depth_stencil_alpha_state(pipe,
+ ctx->dsa_write_depth_stencil[i]);
+
+ pipe->delete_rasterizer_state(pipe, ctx->rs_state);
+ pipe->delete_vs_state(pipe, ctx->vs_col);
+ pipe->delete_vs_state(pipe, ctx->vs_tex);
+
+ for (i = 0; i < PIPE_MAX_TEXTURE_TYPES; i++) {
+ if (ctx->fs_texfetch_col[i])
+ pipe->delete_fs_state(pipe, ctx->fs_texfetch_col[i]);
+ if (ctx->fs_texfetch_depth[i])
+ pipe->delete_fs_state(pipe, ctx->fs_texfetch_depth[i]);
+ }
+
+ for (i = 0; i < PIPE_MAX_COLOR_BUFS && ctx->fs_col[i]; i++)
+ if (ctx->fs_col[i])
+ pipe->delete_fs_state(pipe, ctx->fs_col[i]);
+
+ for (i = 0; i < PIPE_MAX_TEXTURE_LEVELS; i++)
+ if (ctx->sampler_state[i])
+ pipe->delete_sampler_state(pipe, ctx->sampler_state[i]);
+
+ pipe_buffer_reference(&ctx->vbuf, NULL);
+ FREE(ctx);
+}
+
+static void blitter_check_saved_CSOs(struct blitter_context_priv *ctx)
+{
+ /* make sure these CSOs have been saved */
+ assert(ctx->blitter.saved_blend_state &&
+ ctx->blitter.saved_dsa_state &&
+ ctx->blitter.saved_rs_state &&
+ ctx->blitter.saved_fs &&
+ ctx->blitter.saved_vs);
+}
+
+static void blitter_restore_CSOs(struct blitter_context_priv *ctx)
+{
+ struct pipe_context *pipe = ctx->pipe;
+
+ /* restore the state objects which are always required to be saved */
+ pipe->bind_blend_state(pipe, ctx->blitter.saved_blend_state);
+ pipe->bind_depth_stencil_alpha_state(pipe, ctx->blitter.saved_dsa_state);
+ pipe->bind_rasterizer_state(pipe, ctx->blitter.saved_rs_state);
+ pipe->bind_fs_state(pipe, ctx->blitter.saved_fs);
+ pipe->bind_vs_state(pipe, ctx->blitter.saved_vs);
+
+ ctx->blitter.saved_blend_state = 0;
+ ctx->blitter.saved_dsa_state = 0;
+ ctx->blitter.saved_rs_state = 0;
+ ctx->blitter.saved_fs = 0;
+ ctx->blitter.saved_vs = 0;
+
+ /* restore the state objects which are required to be saved before copy/fill
+ */
+ if (ctx->blitter.saved_fb_state.nr_cbufs != ~0) {
+ pipe->set_framebuffer_state(pipe, &ctx->blitter.saved_fb_state);
+ ctx->blitter.saved_fb_state.nr_cbufs = ~0;
+ }
+
+ if (ctx->blitter.saved_num_sampler_states != ~0) {
+ pipe->bind_fragment_sampler_states(pipe,
+ ctx->blitter.saved_num_sampler_states,
+ ctx->blitter.saved_sampler_states);
+ ctx->blitter.saved_num_sampler_states = ~0;
+ }
+
+ if (ctx->blitter.saved_num_textures != ~0) {
+ pipe->set_fragment_sampler_textures(pipe,
+ ctx->blitter.saved_num_textures,
+ ctx->blitter.saved_textures);
+ ctx->blitter.saved_num_textures = ~0;
+ }
+}
+
+static void blitter_set_rectangle(struct blitter_context_priv *ctx,
+ unsigned x1, unsigned y1,
+ unsigned x2, unsigned y2,
+ float depth)
+{
+ int i;
+
+ /* set vertex positions */
+ ctx->vertices[0][0][0] = x1; /*v0.x*/
+ ctx->vertices[0][0][1] = y1; /*v0.y*/
+
+ ctx->vertices[1][0][0] = x2; /*v1.x*/
+ ctx->vertices[1][0][1] = y1; /*v1.y*/
+
+ ctx->vertices[2][0][0] = x2; /*v2.x*/
+ ctx->vertices[2][0][1] = y2; /*v2.y*/
+
+ ctx->vertices[3][0][0] = x1; /*v3.x*/
+ ctx->vertices[3][0][1] = y2; /*v3.y*/
+
+ for (i = 0; i < 4; i++)
+ ctx->vertices[i][0][2] = depth; /*z*/
+}
+
+static void blitter_set_clear_color(struct blitter_context_priv *ctx,
+ const float *rgba)
+{
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ ctx->vertices[i][1][0] = rgba[0];
+ ctx->vertices[i][1][1] = rgba[1];
+ ctx->vertices[i][1][2] = rgba[2];
+ ctx->vertices[i][1][3] = rgba[3];
+ }
+}
+
+static void blitter_set_texcoords_2d(struct blitter_context_priv *ctx,
+ struct pipe_surface *surf,
+ unsigned x1, unsigned y1,
+ unsigned x2, unsigned y2)
+{
+ int i;
+ float s1 = x1 / (float)surf->width;
+ float t1 = y1 / (float)surf->height;
+ float s2 = x2 / (float)surf->width;
+ float t2 = y2 / (float)surf->height;
+
+ ctx->vertices[0][1][0] = s1; /*t0.s*/
+ ctx->vertices[0][1][1] = t1; /*t0.t*/
+
+ ctx->vertices[1][1][0] = s2; /*t1.s*/
+ ctx->vertices[1][1][1] = t1; /*t1.t*/
+
+ ctx->vertices[2][1][0] = s2; /*t2.s*/
+ ctx->vertices[2][1][1] = t2; /*t2.t*/
+
+ ctx->vertices[3][1][0] = s1; /*t3.s*/
+ ctx->vertices[3][1][1] = t2; /*t3.t*/
+
+ for (i = 0; i < 4; i++) {
+ ctx->vertices[i][1][2] = 0; /*r*/
+ ctx->vertices[i][1][3] = 1; /*q*/
+ }
+}
+
+static void blitter_set_texcoords_3d(struct blitter_context_priv *ctx,
+ struct pipe_surface *surf,
+ unsigned x1, unsigned y1,
+ unsigned x2, unsigned y2)
+{
+ int i;
+ float depth = u_minify(surf->texture->depth0, surf->level);
+ float r = surf->zslice / depth;
+
+ blitter_set_texcoords_2d(ctx, surf, x1, y1, x2, y2);
+
+ for (i = 0; i < 4; i++)
+ ctx->vertices[i][1][2] = r; /*r*/
+}
+
+static void blitter_set_texcoords_cube(struct blitter_context_priv *ctx,
+ struct pipe_surface *surf,
+ unsigned x1, unsigned y1,
+ unsigned x2, unsigned y2)
+{
+ int i;
+ float s1 = x1 / (float)surf->width;
+ float t1 = y1 / (float)surf->height;
+ float s2 = x2 / (float)surf->width;
+ float t2 = y2 / (float)surf->height;
+ const float st[4][2] = {
+ {s1, t1}, {s2, t1}, {s2, t2}, {s1, t2}
+ };
+
+ util_map_texcoords2d_onto_cubemap(surf->face,
+ /* pointer, stride in floats */
+ &st[0][0], 2,
+ &ctx->vertices[0][1][0], 8);
+
+ for (i = 0; i < 4; i++)
+ ctx->vertices[i][1][3] = 1; /*q*/
+}
+
+static void blitter_draw_quad(struct blitter_context_priv *ctx)
+{
+ struct pipe_context *pipe = ctx->pipe;
+
+ /* write vertices and draw them */
+ pipe_buffer_write(pipe->screen, ctx->vbuf,
+ 0, sizeof(ctx->vertices), ctx->vertices);
+
+ util_draw_vertex_buffer(pipe, ctx->vbuf, 0, PIPE_PRIM_TRIANGLE_FAN,
+ 4, /* verts */
+ 2); /* attribs/vert */
+}
+
+static INLINE
+void *blitter_get_state_write_depth_stencil(
+ struct blitter_context_priv *ctx,
+ unsigned stencil)
+{
+ struct pipe_context *pipe = ctx->pipe;
+
+ stencil &= 0xff;
+
+ /* Create the DSA state on-demand. */
+ if (!ctx->dsa_write_depth_stencil[stencil]) {
+ ctx->template_dsa.stencil[0].ref_value = stencil;
+
+ ctx->dsa_write_depth_stencil[stencil] =
+ pipe->create_depth_stencil_alpha_state(pipe, &ctx->template_dsa);
+ }
+
+ return ctx->dsa_write_depth_stencil[stencil];
+}
+
+static INLINE
+void **blitter_get_sampler_state(struct blitter_context_priv *ctx,
+ int miplevel)
+{
+ struct pipe_context *pipe = ctx->pipe;
+ struct pipe_sampler_state *sampler_state = &ctx->template_sampler_state;
+
+ assert(miplevel < PIPE_MAX_TEXTURE_LEVELS);
+
+ /* Create the sampler state on-demand. */
+ if (!ctx->sampler_state[miplevel]) {
+ sampler_state->lod_bias = miplevel;
+ sampler_state->min_lod = miplevel;
+ sampler_state->max_lod = miplevel;
+
+ ctx->sampler_state[miplevel] = pipe->create_sampler_state(pipe,
+ sampler_state);
+ }
+
+ /* Return void** so that it can be passed to bind_fragment_sampler_states
+ * directly. */
+ return &ctx->sampler_state[miplevel];
+}
+
+static INLINE
+void *blitter_get_fs_col(struct blitter_context_priv *ctx, unsigned num_cbufs)
+{
+ struct pipe_context *pipe = ctx->pipe;
+ unsigned index = num_cbufs ? num_cbufs - 1 : 0;
+
+ assert(num_cbufs <= PIPE_MAX_COLOR_BUFS);
+
+ if (!ctx->fs_col[index])
+ ctx->fs_col[index] =
+ util_make_fragment_clonecolor_shader(pipe, num_cbufs);
+
+ return ctx->fs_col[index];
+}
+
+static INLINE
+void *blitter_get_fs_texfetch_col(struct blitter_context_priv *ctx,
+ unsigned tex_target)
+{
+ struct pipe_context *pipe = ctx->pipe;
+
+ assert(tex_target < PIPE_MAX_TEXTURE_TYPES);
+
+ /* Create the fragment shader on-demand. */
+ if (!ctx->fs_texfetch_col[tex_target]) {
+ switch (tex_target) {
+ case PIPE_TEXTURE_1D:
+ ctx->fs_texfetch_col[PIPE_TEXTURE_1D] =
+ util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_1D);
+ break;
+ case PIPE_TEXTURE_2D:
+ ctx->fs_texfetch_col[PIPE_TEXTURE_2D] =
+ util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_2D);
+ break;
+ case PIPE_TEXTURE_3D:
+ ctx->fs_texfetch_col[PIPE_TEXTURE_3D] =
+ util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_3D);
+ break;
+ case PIPE_TEXTURE_CUBE:
+ ctx->fs_texfetch_col[PIPE_TEXTURE_CUBE] =
+ util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_CUBE);
+ break;
+ default:;
+ }
+ }
+
+ return ctx->fs_texfetch_col[tex_target];
+}
+
+static INLINE
+void *blitter_get_fs_texfetch_depth(struct blitter_context_priv *ctx,
+ unsigned tex_target)
+{
+ struct pipe_context *pipe = ctx->pipe;
+
+ assert(tex_target < PIPE_MAX_TEXTURE_TYPES);
+
+ /* Create the fragment shader on-demand. */
+ if (!ctx->fs_texfetch_depth[tex_target]) {
+ switch (tex_target) {
+ case PIPE_TEXTURE_1D:
+ ctx->fs_texfetch_depth[PIPE_TEXTURE_1D] =
+ util_make_fragment_tex_shader_writedepth(pipe, TGSI_TEXTURE_1D);
+ break;
+ case PIPE_TEXTURE_2D:
+ ctx->fs_texfetch_depth[PIPE_TEXTURE_2D] =
+ util_make_fragment_tex_shader_writedepth(pipe, TGSI_TEXTURE_2D);
+ break;
+ case PIPE_TEXTURE_3D:
+ ctx->fs_texfetch_depth[PIPE_TEXTURE_3D] =
+ util_make_fragment_tex_shader_writedepth(pipe, TGSI_TEXTURE_3D);
+ break;
+ case PIPE_TEXTURE_CUBE:
+ ctx->fs_texfetch_depth[PIPE_TEXTURE_CUBE] =
+ util_make_fragment_tex_shader_writedepth(pipe,TGSI_TEXTURE_CUBE);
+ break;
+ default:;
+ }
+ }
+
+ return ctx->fs_texfetch_depth[tex_target];
+}
+
+void util_blitter_clear(struct blitter_context *blitter,
+ unsigned width, unsigned height,
+ unsigned num_cbufs,
+ unsigned clear_buffers,
+ const float *rgba,
+ double depth, unsigned stencil)
+{
+ struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
+ struct pipe_context *pipe = ctx->pipe;
+
+ assert(num_cbufs <= PIPE_MAX_COLOR_BUFS);
+
+ blitter_check_saved_CSOs(ctx);
+
+ /* bind CSOs */
+ if (clear_buffers & PIPE_CLEAR_COLOR)
+ pipe->bind_blend_state(pipe, ctx->blend_write_color);
+ else
+ pipe->bind_blend_state(pipe, ctx->blend_keep_color);
+
+ if (clear_buffers & PIPE_CLEAR_DEPTHSTENCIL)
+ pipe->bind_depth_stencil_alpha_state(pipe,
+ blitter_get_state_write_depth_stencil(ctx, stencil));
+ else
+ pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
+
+ pipe->bind_rasterizer_state(pipe, ctx->rs_state);
+ pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, num_cbufs));
+ pipe->bind_vs_state(pipe, ctx->vs_col);
+
+ blitter_set_clear_color(ctx, rgba);
+ blitter_set_rectangle(ctx, 0, 0, width, height, depth);
+ blitter_draw_quad(ctx);
+ blitter_restore_CSOs(ctx);
+}
+
+void util_blitter_copy(struct blitter_context *blitter,
+ struct pipe_surface *dst,
+ unsigned dstx, unsigned dsty,
+ struct pipe_surface *src,
+ unsigned srcx, unsigned srcy,
+ unsigned width, unsigned height,
+ boolean ignore_stencil)
+{
+ struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
+ struct pipe_context *pipe = ctx->pipe;
+ struct pipe_screen *screen = pipe->screen;
+ struct pipe_framebuffer_state fb_state;
+ boolean is_stencil, is_depth;
+ unsigned dst_tex_usage;
+
+ /* give up if textures are not set */
+ assert(dst->texture && src->texture);
+ if (!dst->texture || !src->texture)
+ return;
+
+ is_depth = util_format_get_component_bits(src->format, UTIL_FORMAT_COLORSPACE_ZS, 0) != 0;
+ is_stencil = util_format_get_component_bits(src->format, UTIL_FORMAT_COLORSPACE_ZS, 1) != 0;
+ dst_tex_usage = is_depth || is_stencil ? PIPE_TEXTURE_USAGE_DEPTH_STENCIL :
+ PIPE_TEXTURE_USAGE_RENDER_TARGET;
+
+ /* check if we can sample from and render to the surfaces */
+ /* (assuming copying a stencil buffer is not possible) */
+ if ((!ignore_stencil && is_stencil) ||
+ !screen->is_format_supported(screen, dst->format, dst->texture->target,
+ dst_tex_usage, 0) ||
+ !screen->is_format_supported(screen, src->format, src->texture->target,
+ PIPE_TEXTURE_USAGE_SAMPLER, 0)) {
+ util_surface_copy(pipe, FALSE, dst, dstx, dsty, src, srcx, srcy,
+ width, height);
+ return;
+ }
+
+ /* check whether the states are properly saved */
+ blitter_check_saved_CSOs(ctx);
+ assert(blitter->saved_fb_state.nr_cbufs != ~0);
+ assert(blitter->saved_num_textures != ~0);
+ assert(blitter->saved_num_sampler_states != ~0);
+ assert(src->texture->target < PIPE_MAX_TEXTURE_TYPES);
+
+ /* bind CSOs */
+ fb_state.width = dst->width;
+ fb_state.height = dst->height;
+
+ if (is_depth) {
+ pipe->bind_blend_state(pipe, ctx->blend_keep_color);
+ pipe->bind_depth_stencil_alpha_state(pipe,
+ ctx->dsa_write_depth_keep_stencil);
+ pipe->bind_fs_state(pipe,
+ blitter_get_fs_texfetch_depth(ctx, src->texture->target));
+
+ fb_state.nr_cbufs = 0;
+ fb_state.zsbuf = dst;
+ } else {
+ pipe->bind_blend_state(pipe, ctx->blend_write_color);
+ pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
+ pipe->bind_fs_state(pipe,
+ blitter_get_fs_texfetch_col(ctx, src->texture->target));
+
+ fb_state.nr_cbufs = 1;
+ fb_state.cbufs[0] = dst;
+ fb_state.zsbuf = 0;
+ }
+
+ pipe->bind_rasterizer_state(pipe, ctx->rs_state);
+ pipe->bind_vs_state(pipe, ctx->vs_tex);
+ pipe->bind_fragment_sampler_states(pipe, 1,
+ blitter_get_sampler_state(ctx, src->level));
+ pipe->set_fragment_sampler_textures(pipe, 1, &src->texture);
+ pipe->set_framebuffer_state(pipe, &fb_state);
+
+ /* set texture coordinates */
+ switch (src->texture->target) {
+ case PIPE_TEXTURE_1D:
+ case PIPE_TEXTURE_2D:
+ blitter_set_texcoords_2d(ctx, src, srcx, srcy,
+ srcx+width, srcy+height);
+ break;
+ case PIPE_TEXTURE_3D:
+ blitter_set_texcoords_3d(ctx, src, srcx, srcy,
+ srcx+width, srcy+height);
+ break;
+ case PIPE_TEXTURE_CUBE:
+ blitter_set_texcoords_cube(ctx, src, srcx, srcy,
+ srcx+width, srcy+height);
+ break;
+ default:
+ assert(0);
+ }
+
+ blitter_set_rectangle(ctx, dstx, dsty, dstx+width, dsty+height, 0);
+ blitter_draw_quad(ctx);
+ blitter_restore_CSOs(ctx);
+}
+
+void util_blitter_fill(struct blitter_context *blitter,
+ struct pipe_surface *dst,
+ unsigned dstx, unsigned dsty,
+ unsigned width, unsigned height,
+ unsigned value)
+{
+ struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
+ struct pipe_context *pipe = ctx->pipe;
+ struct pipe_screen *screen = pipe->screen;
+ struct pipe_framebuffer_state fb_state;
+ float rgba[4];
+ ubyte ub_rgba[4] = {0};
+ union util_color color;
+ int i;
+
+ assert(dst->texture);
+ if (!dst->texture)
+ return;
+
+ /* check if we can render to the surface */
+ if (util_format_is_depth_or_stencil(dst->format) || /* unlikely, but you never know */
+ !screen->is_format_supported(screen, dst->format, dst->texture->target,
+ PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) {
+ util_surface_fill(pipe, dst, dstx, dsty, width, height, value);
+ return;
+ }
+
+ /* unpack the color */
+ color.ui = value;
+ util_unpack_color_ub(dst->format, &color,
+ ub_rgba, ub_rgba+1, ub_rgba+2, ub_rgba+3);
+ for (i = 0; i < 4; i++)
+ rgba[i] = ubyte_to_float(ub_rgba[i]);
+
+ /* check the saved state */
+ blitter_check_saved_CSOs(ctx);
+ assert(blitter->saved_fb_state.nr_cbufs != ~0);
+
+ /* bind CSOs */
+ pipe->bind_blend_state(pipe, ctx->blend_write_color);
+ pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
+ pipe->bind_rasterizer_state(pipe, ctx->rs_state);
+ pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, 1));
+ pipe->bind_vs_state(pipe, ctx->vs_col);
+
+ /* set a framebuffer state */
+ fb_state.width = dst->width;
+ fb_state.height = dst->height;
+ fb_state.nr_cbufs = 1;
+ fb_state.cbufs[0] = dst;
+ fb_state.zsbuf = 0;
+ pipe->set_framebuffer_state(pipe, &fb_state);
+
+ blitter_set_clear_color(ctx, rgba);
+ blitter_set_rectangle(ctx, 0, 0, width, height, 0);
+ blitter_draw_quad(ctx);
+ blitter_restore_CSOs(ctx);
+}
diff --git a/src/gallium/auxiliary/util/u_blitter.h b/src/gallium/auxiliary/util/u_blitter.h
new file mode 100644
index 0000000000..3da5a6ca52
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_blitter.h
@@ -0,0 +1,230 @@
+/**************************************************************************
+ *
+ * Copyright 2009 Marek Olšák <maraeo@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#ifndef U_BLITTER_H
+#define U_BLITTER_H
+
+#include "util/u_memory.h"
+
+#include "pipe/p_state.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct pipe_context;
+
+struct blitter_context
+{
+ /* Private members, really. */
+ void *saved_blend_state; /**< blend state */
+ void *saved_dsa_state; /**< depth stencil alpha state */
+ void *saved_rs_state; /**< rasterizer state */
+ void *saved_fs, *saved_vs; /**< fragment shader, vertex shader */
+
+ struct pipe_framebuffer_state saved_fb_state; /**< framebuffer state */
+
+ int saved_num_sampler_states;
+ void *saved_sampler_states[32];
+
+ int saved_num_textures;
+ struct pipe_texture *saved_textures[32]; /* is 32 enough? */
+};
+
+/**
+ * Create a blitter context.
+ */
+struct blitter_context *util_blitter_create(struct pipe_context *pipe);
+
+/**
+ * Destroy a blitter context.
+ */
+void util_blitter_destroy(struct blitter_context *blitter);
+
+/*
+ * These CSOs must be saved before any of the following functions is called:
+ * - blend state
+ * - depth stencil alpha state
+ * - rasterizer state
+ * - vertex shader
+ * - fragment shader
+ */
+
+/**
+ * Clear a specified set of currently bound buffers to specified values.
+ */
+void util_blitter_clear(struct blitter_context *blitter,
+ unsigned width, unsigned height,
+ unsigned num_cbufs,
+ unsigned clear_buffers,
+ const float *rgba,
+ double depth, unsigned stencil);
+
+/**
+ * Copy a block of pixels from one surface to another.
+ *
+ * You can copy from any color format to any other color format provided
+ * the former can be sampled and the latter can be rendered to. Otherwise,
+ * a software fallback path is taken and both surfaces must be of the same
+ * format.
+ *
+ * The same holds for depth-stencil formats with the exception that stencil
+ * cannot be copied unless you set ignore_stencil to FALSE. In that case,
+ * a software fallback path is taken and both surfaces must be of the same
+ * format.
+ *
+ * Use pipe_screen->is_format_supported to know your options.
+ *
+ * These states must be saved in the blitter in addition to the state objects
+ * already required to be saved:
+ * - framebuffer state
+ * - fragment sampler states
+ * - fragment sampler textures
+ */
+void util_blitter_copy(struct blitter_context *blitter,
+ struct pipe_surface *dst,
+ unsigned dstx, unsigned dsty,
+ struct pipe_surface *src,
+ unsigned srcx, unsigned srcy,
+ unsigned width, unsigned height,
+ boolean ignore_stencil);
+
+/**
+ * Fill a region of a surface with a constant value.
+ *
+ * If the surface cannot be rendered to or it's a depth-stencil format,
+ * a software fallback path is taken.
+ *
+ * These states must be saved in the blitter in addition to the state objects
+ * already required to be saved:
+ * - framebuffer state
+ */
+void util_blitter_fill(struct blitter_context *blitter,
+ struct pipe_surface *dst,
+ unsigned dstx, unsigned dsty,
+ unsigned width, unsigned height,
+ unsigned value);
+
+/**
+ * Copy all pixels from one surface to another.
+ *
+ * The rules are the same as in util_blitter_copy with the addition that
+ * surfaces must have the same size.
+ */
+static INLINE
+void util_blitter_copy_surface(struct blitter_context *blitter,
+ struct pipe_surface *dst,
+ struct pipe_surface *src,
+ boolean ignore_stencil)
+{
+ assert(dst->width == src->width && dst->height == src->height);
+
+ util_blitter_copy(blitter, dst, 0, 0, src, 0, 0, src->width, src->height,
+ ignore_stencil);
+}
+
+
+/* The functions below should be used to save currently bound constant state
+ * objects inside a driver. The objects are automatically restored at the end
+ * of the util_blitter_{clear, fill, copy, copy_surface} functions and then
+ * forgotten.
+ *
+ * CSOs not listed here are not affected by util_blitter. */
+
+static INLINE
+void util_blitter_save_blend(struct blitter_context *blitter,
+ void *state)
+{
+ blitter->saved_blend_state = state;
+}
+
+static INLINE
+void util_blitter_save_depth_stencil_alpha(struct blitter_context *blitter,
+ void *state)
+{
+ blitter->saved_dsa_state = state;
+}
+
+static INLINE
+void util_blitter_save_rasterizer(struct blitter_context *blitter,
+ void *state)
+{
+ blitter->saved_rs_state = state;
+}
+
+static INLINE
+void util_blitter_save_fragment_shader(struct blitter_context *blitter,
+ void *fs)
+{
+ blitter->saved_fs = fs;
+}
+
+static INLINE
+void util_blitter_save_vertex_shader(struct blitter_context *blitter,
+ void *vs)
+{
+ blitter->saved_vs = vs;
+}
+
+static INLINE
+void util_blitter_save_framebuffer(struct blitter_context *blitter,
+ struct pipe_framebuffer_state *state)
+{
+ blitter->saved_fb_state = *state;
+}
+
+static INLINE
+void util_blitter_save_fragment_sampler_states(
+ struct blitter_context *blitter,
+ int num_sampler_states,
+ void **sampler_states)
+{
+ assert(num_sampler_states <= Elements(blitter->saved_sampler_states));
+
+ blitter->saved_num_sampler_states = num_sampler_states;
+ memcpy(blitter->saved_sampler_states, sampler_states,
+ num_sampler_states * sizeof(void *));
+}
+
+static INLINE
+void util_blitter_save_fragment_sampler_textures(
+ struct blitter_context *blitter,
+ int num_textures,
+ struct pipe_texture **textures)
+{
+ assert(num_textures <= Elements(blitter->saved_textures));
+
+ blitter->saved_num_textures = num_textures;
+ memcpy(blitter->saved_textures, textures,
+ num_textures * sizeof(struct pipe_texture *));
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/gallium/auxiliary/util/u_debug.c b/src/gallium/auxiliary/util/u_debug.c
index 40633574b0..4e01123fff 100644
--- a/src/gallium/auxiliary/util/u_debug.c
+++ b/src/gallium/auxiliary/util/u_debug.c
@@ -64,11 +64,13 @@
#include "pipe/p_format.h"
#include "pipe/p_state.h"
#include "pipe/p_inlines.h"
+#include "util/u_format.h"
#include "util/u_memory.h"
#include "util/u_string.h"
#include "util/u_stream.h"
#include "util/u_math.h"
#include "util/u_tile.h"
+#include "util/u_prim.h"
#ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY
@@ -600,6 +602,32 @@ const char *pf_name( enum pipe_format format )
}
+
+static const struct debug_named_value pipe_prim_names[] = {
+#ifdef DEBUG
+ DEBUG_NAMED_VALUE(PIPE_PRIM_POINTS),
+ DEBUG_NAMED_VALUE(PIPE_PRIM_LINES),
+ DEBUG_NAMED_VALUE(PIPE_PRIM_LINE_LOOP),
+ DEBUG_NAMED_VALUE(PIPE_PRIM_LINE_STRIP),
+ DEBUG_NAMED_VALUE(PIPE_PRIM_TRIANGLES),
+ DEBUG_NAMED_VALUE(PIPE_PRIM_TRIANGLE_STRIP),
+ DEBUG_NAMED_VALUE(PIPE_PRIM_TRIANGLE_FAN),
+ DEBUG_NAMED_VALUE(PIPE_PRIM_QUADS),
+ DEBUG_NAMED_VALUE(PIPE_PRIM_QUAD_STRIP),
+ DEBUG_NAMED_VALUE(PIPE_PRIM_POLYGON),
+#endif
+ DEBUG_NAMED_VALUE_END
+};
+
+
+const char *u_prim_name( unsigned prim )
+{
+ return debug_dump_enum(pipe_prim_names, prim);
+}
+
+
+
+
#ifdef DEBUG
void debug_dump_image(const char *prefix,
unsigned format, unsigned cpp,
@@ -670,9 +698,9 @@ void debug_dump_surface(const char *prefix,
debug_dump_image(prefix,
texture->format,
- pf_get_blocksize(texture->format),
- pf_get_nblocksx(texture->format, transfer->width),
- pf_get_nblocksy(texture->format, transfer->height),
+ util_format_get_blocksize(texture->format),
+ util_format_get_nblocksx(texture->format, transfer->width),
+ util_format_get_nblocksy(texture->format, transfer->height),
transfer->stride,
data);
diff --git a/src/gallium/auxiliary/util/u_dl.c b/src/gallium/auxiliary/util/u_dl.c
new file mode 100644
index 0000000000..b42b429d4d
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_dl.c
@@ -0,0 +1,79 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * Copyright 1999-2008 Brian Paul
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ **************************************************************************/
+
+
+#include "pipe/p_config.h"
+
+#if defined(PIPE_OS_UNIX)
+#include <dlfcn.h>
+#endif
+#if defined(PIPE_OS_WINDOWS)
+#include <windows.h>
+#endif
+
+#include "u_dl.h"
+
+
+struct util_dl_library *
+util_dl_open(const char *filename)
+{
+#if defined(PIPE_OS_UNIX)
+ return (struct util_dl_library *)dlopen(filename, RTLD_LAZY | RTLD_GLOBAL);
+#elif defined(PIPE_OS_WINDOWS)
+ return (struct util_dl_library *)LoadLibraryA(filename);
+#else
+ return NULL;
+#endif
+}
+
+
+util_dl_proc
+util_dl_get_proc_address(struct util_dl_library *library,
+ const char *procname)
+{
+#if defined(PIPE_OS_UNIX)
+ return (util_dl_proc)dlsym((void *)library, procname);
+#elif defined(PIPE_OS_WINDOWS)
+ return (util_dl_proc)GetProcAddress((HMODULE)library, procname);
+#else
+ return (util_dl_proc)NULL;
+#endif
+}
+
+
+void
+util_dl_close(struct util_dl_library *library)
+{
+#if defined(PIPE_OS_UNIX)
+ dlclose((void *)library);
+#elif defined(PIPE_OS_WINDOWS)
+ FreeLibrary((HMODULE)library);
+#else
+ (void)library;
+#endif
+}
diff --git a/src/gallium/auxiliary/util/u_dl.h b/src/gallium/auxiliary/util/u_dl.h
new file mode 100644
index 0000000000..018b38543b
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_dl.h
@@ -0,0 +1,61 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ **************************************************************************/
+
+
+#ifndef U_DL_H_
+#define U_DL_H_
+
+
+struct util_dl_library;
+
+
+typedef void (*util_dl_proc)(void);
+
+
+/**
+ * Open a library dynamically.
+ */
+struct util_dl_library *
+util_dl_open(const char *filename);
+
+
+/**
+ * Lookup a function in a library.
+ */
+util_dl_proc
+util_dl_get_proc_address(struct util_dl_library *library,
+ const char *procname);
+
+
+/**
+ * Close a library.
+ */
+void
+util_dl_close(struct util_dl_library *library);
+
+
+#endif /* U_DL_H_ */
diff --git a/src/gallium/auxiliary/util/u_format.c b/src/gallium/auxiliary/util/u_format.c
index 98ea13b60b..e0724a1a8b 100644
--- a/src/gallium/auxiliary/util/u_format.c
+++ b/src/gallium/auxiliary/util/u_format.c
@@ -32,15 +32,14 @@
const struct util_format_description *
util_format_description(enum pipe_format format)
{
- const struct util_format_description *desc = util_format_description_table;
+ const struct util_format_description *desc;
- while(TRUE) {
- if(desc->format == format)
- return desc;
+ if (format >= PIPE_FORMAT_COUNT) {
+ return NULL;
+ }
- if(desc->format == PIPE_FORMAT_NONE)
- return NULL;
+ desc = &util_format_description_table[format];
+ assert(desc->format == format);
- ++desc;
- };
+ return desc;
}
diff --git a/src/gallium/auxiliary/util/u_format.csv b/src/gallium/auxiliary/util/u_format.csv
index b9cc2aa716..866b18ff16 100644
--- a/src/gallium/auxiliary/util/u_format.csv
+++ b/src/gallium/auxiliary/util/u_format.csv
@@ -11,6 +11,8 @@ PIPE_FORMAT_A8_UNORM , arith , 1, 1, un8 , , , , 000x,
PIPE_FORMAT_I8_UNORM , arith , 1, 1, un8 , , , , xxxx, rgb
PIPE_FORMAT_A8L8_UNORM , arith , 1, 1, un8 , un8 , , , xxxy, rgb
PIPE_FORMAT_L16_UNORM , arith , 1, 1, un16, , , , xxx1, rgb
+PIPE_FORMAT_YCBCR , yuv , 2, 1, x32 , , , , xyz1, yuv
+PIPE_FORMAT_YCBCR_REV , yuv , 2, 1, x32 , , , , xyz1, yuv
PIPE_FORMAT_Z16_UNORM , array , 1, 1, un16, , , , x___, zs
PIPE_FORMAT_Z32_UNORM , array , 1, 1, un32, , , , x___, zs
PIPE_FORMAT_Z32_FLOAT , array , 1, 1, f32 , , , , x___, zs
@@ -97,13 +99,11 @@ PIPE_FORMAT_B8G8R8A8_SRGB , arith , 1, 1, u8 , u8 , u8 , u8 , zyxw,
PIPE_FORMAT_B8G8R8X8_SRGB , arith , 1, 1, u8 , u8 , u8 , u8 , zyx1, srgb
PIPE_FORMAT_X8UB8UG8SR8S_NORM , arith , 1, 1, sn8 , sn8 , un8 , x8 , 1zyx, rgb
PIPE_FORMAT_B6UG5SR5S_NORM , arith , 1, 1, sn5 , sn5 , un6 , , xyz1, rgb
-PIPE_FORMAT_YCBCR , yuv , 2, 1, x32 , , , , xyz1, yuv
-PIPE_FORMAT_YCBCR_REV , yuv , 2, 1, x32 , , , , xyz1, yuv
-PIPE_FORMAT_DXT1_RGBA , dxt , 4, 4, x64 , , , , xyzw, rgb
PIPE_FORMAT_DXT1_RGB , dxt , 4, 4, x64 , , , , xyz1, rgb
+PIPE_FORMAT_DXT1_RGBA , dxt , 4, 4, x64 , , , , xyzw, rgb
PIPE_FORMAT_DXT3_RGBA , dxt , 4, 4, x128, , , , xyzw, rgb
PIPE_FORMAT_DXT5_RGBA , dxt , 4, 4, x128, , , , xyzw, rgb
-PIPE_FORMAT_DXT1_SRGBA , dxt , 4, 4, x64 , , , , xyzw, srgb
PIPE_FORMAT_DXT1_SRGB , dxt , 4, 4, x64 , , , , xyz1, srgb
+PIPE_FORMAT_DXT1_SRGBA , dxt , 4, 4, x64 , , , , xyzw, srgb
PIPE_FORMAT_DXT3_SRGBA , dxt , 4, 4, x128, , , , xyzw, srgb
PIPE_FORMAT_DXT5_SRGBA , dxt , 4, 4, x128, , , , xyzw, srgb
diff --git a/src/gallium/auxiliary/util/u_format.h b/src/gallium/auxiliary/util/u_format.h
index 19b902db98..090183fb17 100644
--- a/src/gallium/auxiliary/util/u_format.h
+++ b/src/gallium/auxiliary/util/u_format.h
@@ -32,6 +32,10 @@
#include "pipe/p_format.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/**
* Describe how to best pack/unpack pixels into/from the prescribed format.
@@ -147,6 +151,250 @@ const struct util_format_description *
util_format_description(enum pipe_format format);
+/*
+ * Format query functions.
+ */
+
+static INLINE boolean
+util_format_is_compressed(enum pipe_format format)
+{
+ const struct util_format_description *desc = util_format_description(format);
+
+ assert(format);
+ if (!format) {
+ return FALSE;
+ }
+
+ return desc->layout == UTIL_FORMAT_LAYOUT_DXT ? TRUE : FALSE;
+}
+
+static INLINE boolean
+util_format_is_depth_or_stencil(enum pipe_format format)
+{
+ const struct util_format_description *desc = util_format_description(format);
+
+ assert(format);
+ if (!format) {
+ return FALSE;
+ }
+
+ return desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS ? TRUE : FALSE;
+}
+
+static INLINE boolean
+util_format_is_depth_and_stencil(enum pipe_format format)
+{
+ const struct util_format_description *desc = util_format_description(format);
+
+ assert(format);
+ if (!format) {
+ return FALSE;
+ }
+
+ if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS) {
+ return FALSE;
+ }
+
+ return (desc->swizzle[0] != UTIL_FORMAT_SWIZZLE_NONE &&
+ desc->swizzle[1] != UTIL_FORMAT_SWIZZLE_NONE) ? TRUE : FALSE;
+}
+
+
+/**
+ * Return total bits needed for the pixel format per block.
+ */
+static INLINE uint
+util_format_get_blocksizebits(enum pipe_format format)
+{
+ const struct util_format_description *desc = util_format_description(format);
+
+ assert(format);
+ if (!format) {
+ return 0;
+ }
+
+ return desc->block.bits;
+}
+
+/**
+ * Return bytes per block (not pixel) for the given format.
+ */
+static INLINE uint
+util_format_get_blocksize(enum pipe_format format)
+{
+ uint bits = util_format_get_blocksizebits(format);
+
+ assert(bits % 8 == 0);
+
+ return bits / 8;
+}
+
+static INLINE uint
+util_format_get_blockwidth(enum pipe_format format)
+{
+ const struct util_format_description *desc = util_format_description(format);
+
+ assert(format);
+ if (!format) {
+ return 1;
+ }
+
+ switch (desc->layout) {
+ case UTIL_FORMAT_LAYOUT_YUV:
+ return 2;
+ case UTIL_FORMAT_LAYOUT_DXT:
+ return 4;
+ default:
+ return 1;
+ }
+}
+
+static INLINE uint
+util_format_get_blockheight(enum pipe_format format)
+{
+ const struct util_format_description *desc = util_format_description(format);
+
+ assert(format);
+ if (!format) {
+ return 1;
+ }
+
+ switch (desc->layout) {
+ case UTIL_FORMAT_LAYOUT_DXT:
+ return 4;
+ default:
+ return 1;
+ }
+}
+
+static INLINE unsigned
+util_format_get_nblocksx(enum pipe_format format,
+ unsigned x)
+{
+ unsigned blockwidth = util_format_get_blockwidth(format);
+ return (x + blockwidth - 1) / blockwidth;
+}
+
+static INLINE unsigned
+util_format_get_nblocksy(enum pipe_format format,
+ unsigned y)
+{
+ unsigned blockheight = util_format_get_blockheight(format);
+ return (y + blockheight - 1) / blockheight;
+}
+
+static INLINE unsigned
+util_format_get_nblocks(enum pipe_format format,
+ unsigned width,
+ unsigned height)
+{
+ return util_format_get_nblocksx(format, width) * util_format_get_nblocksy(format, height);
+}
+
+static INLINE size_t
+util_format_get_stride(enum pipe_format format,
+ unsigned width)
+{
+ return util_format_get_nblocksx(format, width) * util_format_get_blocksize(format);
+}
+
+static INLINE size_t
+util_format_get_2d_size(enum pipe_format format,
+ size_t stride,
+ unsigned height)
+{
+ return util_format_get_nblocksy(format, height) * stride;
+}
+
+static INLINE uint
+util_format_get_component_bits(enum pipe_format format,
+ enum util_format_colorspace colorspace,
+ uint component)
+{
+ const struct util_format_description *desc = util_format_description(format);
+ enum util_format_colorspace desc_colorspace;
+
+ assert(format);
+ if (!format) {
+ return 0;
+ }
+
+ assert(component < 4);
+
+ /* Treat RGB and SRGB as equivalent. */
+ if (colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
+ colorspace = UTIL_FORMAT_COLORSPACE_RGB;
+ }
+ if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
+ desc_colorspace = UTIL_FORMAT_COLORSPACE_RGB;
+ } else {
+ desc_colorspace = desc->colorspace;
+ }
+
+ if (desc_colorspace != colorspace) {
+ return 0;
+ }
+
+ switch (desc->swizzle[component]) {
+ case UTIL_FORMAT_SWIZZLE_X:
+ return desc->channel[0].size;
+ case UTIL_FORMAT_SWIZZLE_Y:
+ return desc->channel[1].size;
+ case UTIL_FORMAT_SWIZZLE_Z:
+ return desc->channel[2].size;
+ case UTIL_FORMAT_SWIZZLE_W:
+ return desc->channel[3].size;
+ default:
+ return 0;
+ }
+}
+
+static INLINE boolean
+util_format_has_alpha(enum pipe_format format)
+{
+ const struct util_format_description *desc = util_format_description(format);
+
+ assert(format);
+ if (!format) {
+ return FALSE;
+ }
+
+ switch (desc->layout) {
+ case UTIL_FORMAT_LAYOUT_SCALAR:
+ case UTIL_FORMAT_LAYOUT_ARITH:
+ case UTIL_FORMAT_LAYOUT_ARRAY:
+ /* FIXME: pf_get_component_bits( PIPE_FORMAT_A8L8_UNORM, PIPE_FORMAT_COMP_A ) should not return 0 right? */
+ if (format == PIPE_FORMAT_A8_UNORM ||
+ format == PIPE_FORMAT_A8L8_UNORM ||
+ format == PIPE_FORMAT_A8L8_SRGB) {
+ return TRUE;
+ }
+ return util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 3) != 0;
+ case UTIL_FORMAT_LAYOUT_YUV:
+ return FALSE;
+ case UTIL_FORMAT_LAYOUT_DXT:
+ switch (format) {
+ case PIPE_FORMAT_DXT1_RGBA:
+ case PIPE_FORMAT_DXT3_RGBA:
+ case PIPE_FORMAT_DXT5_RGBA:
+ case PIPE_FORMAT_DXT1_SRGBA:
+ case PIPE_FORMAT_DXT3_SRGBA:
+ case PIPE_FORMAT_DXT5_SRGBA:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+ default:
+ assert(0);
+ return FALSE;
+ }
+}
+
+
+/*
+ * Format access functions.
+ */
+
void
util_format_read_4f(enum pipe_format format,
float *dst, unsigned dst_stride,
@@ -171,4 +419,8 @@ util_format_write_4ub(enum pipe_format format,
void *dst, unsigned dst_stride,
unsigned x, unsigned y, unsigned w, unsigned h);
+#ifdef __cplusplus
+} // extern "C" {
+#endif
+
#endif /* ! U_FORMAT_H */
diff --git a/src/gallium/auxiliary/util/u_format_access.py b/src/gallium/auxiliary/util/u_format_access.py
index eeb1a9657f..0b05ddb931 100644
--- a/src/gallium/auxiliary/util/u_format_access.py
+++ b/src/gallium/auxiliary/util/u_format_access.py
@@ -325,14 +325,14 @@ def generate_format_read(format, dst_type, dst_native_type, dst_suffix):
elif swizzle == SWIZZLE_0:
value = '0'
elif swizzle == SWIZZLE_1:
- value = '1'
+ value = get_one(dst_type)
else:
assert False
elif format.colorspace == 'zs':
if i < 3:
value = 'z'
else:
- value = '1'
+ value = get_one(dst_type)
else:
assert False
print ' *dst_pixel++ = %s; /* %s */' % (value, 'rgba'[i])
diff --git a/src/gallium/auxiliary/util/u_format_table.py b/src/gallium/auxiliary/util/u_format_table.py
index 2cd0f95678..571cab55dc 100755
--- a/src/gallium/auxiliary/util/u_format_table.py
+++ b/src/gallium/auxiliary/util/u_format_table.py
@@ -89,6 +89,15 @@ def write_format_table(formats):
print 'const struct util_format_description'
print 'util_format_description_table[] = '
print "{"
+ print " {"
+ print " PIPE_FORMAT_NONE,"
+ print " \"PIPE_FORMAT_NONE\","
+ print " {0, 0, 0},"
+ print " 0,"
+ print " {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},"
+ print " {0, 0, 0, 0},"
+ print " 0"
+ print " },"
for format in formats:
print " {"
print " %s," % (format.name,)
@@ -119,15 +128,6 @@ def write_format_table(formats):
print " },"
print " %s," % (colorspace_map(format.colorspace),)
print " },"
- print " {"
- print " PIPE_FORMAT_NONE,"
- print " \"PIPE_FORMAT_NONE\","
- print " {0, 0, 0},"
- print " 0,"
- print " {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},"
- print " {0, 0, 0, 0},"
- print " 0"
- print " },"
print "};"
diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c
index 83263d9fe6..76023794dc 100644
--- a/src/gallium/auxiliary/util/u_gen_mipmap.c
+++ b/src/gallium/auxiliary/util/u_gen_mipmap.c
@@ -41,11 +41,13 @@
#include "pipe/p_shader_tokens.h"
#include "pipe/p_state.h"
+#include "util/u_format.h"
#include "util/u_memory.h"
#include "util/u_draw_quad.h"
#include "util/u_gen_mipmap.h"
#include "util/u_simple_shaders.h"
#include "util/u_math.h"
+#include "util/u_texture.h"
#include "cso_cache/cso_context.h"
@@ -61,7 +63,7 @@ struct gen_mipmap_state
struct pipe_sampler_state sampler;
void *vs;
- void *fs;
+ void *fs2d, *fsCube;
struct pipe_buffer *vbuf; /**< quad vertices */
unsigned vbuf_slot;
@@ -996,7 +998,7 @@ reduce_2d(enum pipe_format pformat,
{
enum dtype datatype;
uint comps;
- const int bpt = pf_get_blocksize(pformat);
+ const int bpt = util_format_get_blocksize(pformat);
const ubyte *srcA, *srcB;
ubyte *dst;
int row;
@@ -1035,7 +1037,7 @@ reduce_3d(enum pipe_format pformat,
int dstWidth, int dstHeight, int dstDepth,
int dstRowStride, ubyte *dstPtr)
{
- const int bpt = pf_get_blocksize(pformat);
+ const int bpt = util_format_get_blocksize(pformat);
const int border = 0;
int img, row;
int bytesPerSrcImage, bytesPerDstImage;
@@ -1159,8 +1161,8 @@ make_2d_mipmap(struct gen_mipmap_state *ctx,
const uint zslice = 0;
uint dstLevel;
- assert(pf_get_blockwidth(pt->format) == 1);
- assert(pf_get_blockheight(pt->format) == 1);
+ assert(util_format_get_blockwidth(pt->format) == 1);
+ assert(util_format_get_blockheight(pt->format) == 1);
for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) {
const uint srcLevel = dstLevel - 1;
@@ -1204,8 +1206,8 @@ make_3d_mipmap(struct gen_mipmap_state *ctx,
struct pipe_screen *screen = pipe->screen;
uint dstLevel, zslice = 0;
- assert(pf_get_blockwidth(pt->format) == 1);
- assert(pf_get_blockheight(pt->format) == 1);
+ assert(util_format_get_blockwidth(pt->format) == 1);
+ assert(util_format_get_blockheight(pt->format) == 1);
for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) {
const uint srcLevel = dstLevel - 1;
@@ -1317,7 +1319,8 @@ util_create_gen_mipmap(struct pipe_context *pipe,
}
/* fragment shader */
- ctx->fs = util_make_fragment_tex_shader(pipe);
+ ctx->fs2d = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_2D);
+ ctx->fsCube = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_CUBE);
/* vertex data that doesn't change */
for (i = 0; i < 4; i++) {
@@ -1383,59 +1386,9 @@ set_vertex_data(struct gen_mipmap_state *ctx,
static const float st[4][2] = {
{0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f}
};
- float rx, ry, rz;
- uint i;
-
- /* loop over quad verts */
- for (i = 0; i < 4; i++) {
- /* Compute sc = +/-scale and tc = +/-scale.
- * Not +/-1 to avoid cube face selection ambiguity near the edges,
- * though that can still sometimes happen with this scale factor...
- */
- const float scale = 0.9999f;
- const float sc = (2.0f * st[i][0] - 1.0f) * scale;
- const float tc = (2.0f * st[i][1] - 1.0f) * scale;
-
- switch (face) {
- case PIPE_TEX_FACE_POS_X:
- rx = 1.0f;
- ry = -tc;
- rz = -sc;
- break;
- case PIPE_TEX_FACE_NEG_X:
- rx = -1.0f;
- ry = -tc;
- rz = sc;
- break;
- case PIPE_TEX_FACE_POS_Y:
- rx = sc;
- ry = 1.0f;
- rz = tc;
- break;
- case PIPE_TEX_FACE_NEG_Y:
- rx = sc;
- ry = -1.0f;
- rz = -tc;
- break;
- case PIPE_TEX_FACE_POS_Z:
- rx = sc;
- ry = -tc;
- rz = 1.0f;
- break;
- case PIPE_TEX_FACE_NEG_Z:
- rx = -sc;
- ry = -tc;
- rz = -1.0f;
- break;
- default:
- rx = ry = rz = 0.0f;
- assert(0);
- }
- ctx->vertices[i][1][0] = rx; /*s*/
- ctx->vertices[i][1][1] = ry; /*t*/
- ctx->vertices[i][1][2] = rz; /*r*/
- }
+ util_map_texcoords2d_onto_cubemap(face, &st[0][0], 2,
+ &ctx->vertices[0][1][0], 8);
}
else {
/* 1D/2D */
@@ -1475,7 +1428,8 @@ util_destroy_gen_mipmap(struct gen_mipmap_state *ctx)
struct pipe_context *pipe = ctx->pipe;
pipe->delete_vs_state(pipe, ctx->vs);
- pipe->delete_fs_state(pipe, ctx->fs);
+ pipe->delete_fs_state(pipe, ctx->fs2d);
+ pipe->delete_fs_state(pipe, ctx->fsCube);
pipe_buffer_reference(&ctx->vbuf, NULL);
@@ -1513,6 +1467,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
struct pipe_context *pipe = ctx->pipe;
struct pipe_screen *screen = pipe->screen;
struct pipe_framebuffer_state fb;
+ void *fs = (pt->target == PIPE_TEXTURE_CUBE) ? ctx->fsCube : ctx->fs2d;
uint dstLevel;
uint zslice = 0;
uint offset;
@@ -1550,7 +1505,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
cso_set_depth_stencil_alpha(ctx->cso, &ctx->depthstencil);
cso_set_rasterizer(ctx->cso, &ctx->rasterizer);
- cso_set_fragment_shader_handle(ctx->cso, ctx->fs);
+ cso_set_fragment_shader_handle(ctx->cso, fs);
cso_set_vertex_shader_handle(ctx->cso, ctx->vs);
/* init framebuffer state */
diff --git a/src/gallium/auxiliary/util/u_math.h b/src/gallium/auxiliary/util/u_math.h
index b76592d1ec..81aeb83cbb 100644
--- a/src/gallium/auxiliary/util/u_math.h
+++ b/src/gallium/auxiliary/util/u_math.h
@@ -583,6 +583,19 @@ do { \
#endif
+static INLINE uint32_t util_unsigned_fixed(float value, unsigned frac_bits)
+{
+ value *= (1<<frac_bits);
+ return value < 0 ? 0 : value;
+}
+
+static INLINE int32_t util_signed_fixed(float value, unsigned frac_bits)
+{
+ return value * (1<<frac_bits);
+}
+
+
+
#ifdef __cplusplus
}
#endif
diff --git a/src/gallium/auxiliary/util/u_pack_color.h b/src/gallium/auxiliary/util/u_pack_color.h
index a2e0f26686..43eb0153ee 100644
--- a/src/gallium/auxiliary/util/u_pack_color.h
+++ b/src/gallium/auxiliary/util/u_pack_color.h
@@ -37,6 +37,7 @@
#include "pipe/p_compiler.h"
#include "pipe/p_format.h"
+#include "util/u_format.h"
#include "util/u_math.h"
@@ -128,11 +129,18 @@ util_pack_color_ub(ubyte r, ubyte g, ubyte b, ubyte a,
}
return;
- /* XXX lots more cases to add */
+ /* Handle other cases with a generic function.
+ */
default:
- uc->ui = 0; /* keep compiler happy */
- debug_print_format("gallium: unhandled format in util_pack_color_ub()", format);
- assert(0);
+ {
+ ubyte src[4];
+
+ src[0] = r;
+ src[1] = g;
+ src[2] = b;
+ src[3] = a;
+ util_format_write_4ub(format, src, 0, uc, 0, 0, 0, 1, 1);
+ }
}
}
@@ -282,11 +290,18 @@ util_unpack_color_ub(enum pipe_format format, union util_color *uc,
}
return;
- /* XXX lots more cases to add */
+ /* Handle other cases with a generic function.
+ */
default:
- debug_print_format("gallium: unhandled format in util_unpack_color_ub()",
- format);
- assert(0);
+ {
+ ubyte dst[4];
+
+ util_format_read_4ub(format, dst, 0, uc, 0, 0, 0, 1, 1);
+ *r = dst[0];
+ *g = dst[1];
+ *b = dst[2];
+ *a = dst[3];
+ }
}
}
@@ -302,7 +317,7 @@ util_pack_color(const float rgba[4], enum pipe_format format, union util_color *
ubyte b = 0;
ubyte a = 0;
- if (pf_size_x(format) <= 8) {
+ if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0) <= 8) {
/* format uses 8-bit components or less */
r = float_to_ubyte(rgba[0]);
g = float_to_ubyte(rgba[1]);
@@ -382,11 +397,11 @@ util_pack_color(const float rgba[4], enum pipe_format format, union util_color *
uc->f[2] = rgba[2];
}
return;
- /* XXX lots more cases to add */
+
+ /* Handle other cases with a generic function.
+ */
default:
- uc->ui = 0; /* keep compiler happy */
- debug_print_format("gallium: unhandled format in util_pack_color()", format);
- assert(0);
+ util_format_write_4f(format, rgba, 0, uc, 0, 0, 0, 1, 1);
}
}
diff --git a/src/gallium/auxiliary/util/u_prim.h b/src/gallium/auxiliary/util/u_prim.h
index a9b533eea7..7434329962 100644
--- a/src/gallium/auxiliary/util/u_prim.h
+++ b/src/gallium/auxiliary/util/u_prim.h
@@ -135,4 +135,6 @@ static INLINE unsigned u_reduced_prim( unsigned pipe_prim )
}
}
+const char *u_prim_name( unsigned pipe_prim );
+
#endif
diff --git a/src/gallium/auxiliary/util/u_rect.c b/src/gallium/auxiliary/util/u_rect.c
index 72725b59d2..298fbacecb 100644
--- a/src/gallium/auxiliary/util/u_rect.c
+++ b/src/gallium/auxiliary/util/u_rect.c
@@ -34,6 +34,7 @@
#include "pipe/p_format.h"
#include "pipe/p_context.h"
#include "pipe/p_screen.h"
+#include "util/u_format.h"
#include "util/u_rect.h"
@@ -57,9 +58,9 @@ util_copy_rect(ubyte * dst,
{
unsigned i;
int src_stride_pos = src_stride < 0 ? -src_stride : src_stride;
- int blocksize = pf_get_blocksize(format);
- int blockwidth = pf_get_blockwidth(format);
- int blockheight = pf_get_blockheight(format);
+ int blocksize = util_format_get_blocksize(format);
+ int blockwidth = util_format_get_blockwidth(format);
+ int blockheight = util_format_get_blockheight(format);
assert(blocksize > 0);
assert(blockwidth > 0);
@@ -105,9 +106,9 @@ util_fill_rect(ubyte * dst,
{
unsigned i, j;
unsigned width_size;
- int blocksize = pf_get_blocksize(format);
- int blockwidth = pf_get_blockwidth(format);
- int blockheight = pf_get_blockheight(format);
+ int blocksize = util_format_get_blocksize(format);
+ int blockwidth = util_format_get_blockwidth(format);
+ int blockheight = util_format_get_blockheight(format);
assert(blocksize > 0);
assert(blockwidth > 0);
@@ -203,9 +204,9 @@ util_surface_copy(struct pipe_context *pipe,
PIPE_TRANSFER_WRITE,
dst_x, dst_y, w, h);
- assert(pf_get_blocksize(dst_format) == pf_get_blocksize(src_format));
- assert(pf_get_blockwidth(dst_format) == pf_get_blockwidth(src_format));
- assert(pf_get_blockheight(dst_format) == pf_get_blockheight(src_format));
+ assert(util_format_get_blocksize(dst_format) == util_format_get_blocksize(src_format));
+ assert(util_format_get_blockwidth(dst_format) == util_format_get_blockwidth(src_format));
+ assert(util_format_get_blockheight(dst_format) == util_format_get_blockheight(src_format));
src_map = pipe->screen->transfer_map(screen, src_trans);
dst_map = pipe->screen->transfer_map(screen, dst_trans);
@@ -270,7 +271,7 @@ util_surface_fill(struct pipe_context *pipe,
if (dst_map) {
assert(dst_trans->stride > 0);
- switch (pf_get_blocksize(dst_trans->texture->format)) {
+ switch (util_format_get_blocksize(dst_trans->texture->format)) {
case 1:
case 2:
case 4:
diff --git a/src/gallium/auxiliary/util/u_simple_shaders.c b/src/gallium/auxiliary/util/u_simple_shaders.c
index 1c8b157d91..8172ead020 100644
--- a/src/gallium/auxiliary/util/u_simple_shaders.c
+++ b/src/gallium/auxiliary/util/u_simple_shaders.c
@@ -2,6 +2,7 @@
*
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
+ * Copyright 2009 Marek Olšák <maraeo@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
@@ -30,6 +31,7 @@
* Simple vertex/fragment shader generators.
*
* @author Brian Paul
+ Marek Olšák
*/
@@ -87,6 +89,7 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe,
*/
void *
util_make_fragment_tex_shader_writemask(struct pipe_context *pipe,
+ unsigned tex_target,
unsigned writemask )
{
struct ureg_program *ureg;
@@ -116,20 +119,63 @@ util_make_fragment_tex_shader_writemask(struct pipe_context *pipe,
ureg_TEX( ureg,
ureg_writemask(out, writemask),
- TGSI_TEXTURE_2D, tex, sampler );
+ tex_target, tex, sampler );
ureg_END( ureg );
return ureg_create_shader_and_destroy( ureg, pipe );
}
void *
-util_make_fragment_tex_shader(struct pipe_context *pipe )
+util_make_fragment_tex_shader(struct pipe_context *pipe, unsigned tex_target )
{
return util_make_fragment_tex_shader_writemask( pipe,
+ tex_target,
TGSI_WRITEMASK_XYZW );
}
+/**
+ * Make a simple fragment texture shader which reads an X component from
+ * a texture and writes it as depth.
+ */
+void *
+util_make_fragment_tex_shader_writedepth(struct pipe_context *pipe,
+ unsigned tex_target)
+{
+ struct ureg_program *ureg;
+ struct ureg_src sampler;
+ struct ureg_src tex;
+ struct ureg_dst out, depth;
+ struct ureg_src imm;
+ ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT );
+ if (ureg == NULL)
+ return NULL;
+
+ sampler = ureg_DECL_sampler( ureg, 0 );
+
+ tex = ureg_DECL_fs_input( ureg,
+ TGSI_SEMANTIC_GENERIC, 0,
+ TGSI_INTERPOLATE_PERSPECTIVE );
+
+ out = ureg_DECL_output( ureg,
+ TGSI_SEMANTIC_COLOR,
+ 0 );
+
+ depth = ureg_DECL_output( ureg,
+ TGSI_SEMANTIC_POSITION,
+ 0 );
+
+ imm = ureg_imm4f( ureg, 0, 0, 0, 1 );
+
+ ureg_MOV( ureg, out, imm );
+
+ ureg_TEX( ureg,
+ ureg_writemask(depth, TGSI_WRITEMASK_Z),
+ tex_target, tex, sampler );
+ ureg_END( ureg );
+
+ return ureg_create_shader_and_destroy( ureg, pipe );
+}
/**
* Make simple fragment color pass-through shader.
@@ -137,9 +183,18 @@ util_make_fragment_tex_shader(struct pipe_context *pipe )
void *
util_make_fragment_passthrough_shader(struct pipe_context *pipe)
{
+ return util_make_fragment_clonecolor_shader(pipe, 1);
+}
+
+void *
+util_make_fragment_clonecolor_shader(struct pipe_context *pipe, int num_cbufs)
+{
struct ureg_program *ureg;
struct ureg_src src;
- struct ureg_dst dst;
+ struct ureg_dst dst[8];
+ int i;
+
+ assert(num_cbufs <= 8);
ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT );
if (ureg == NULL)
@@ -148,12 +203,13 @@ util_make_fragment_passthrough_shader(struct pipe_context *pipe)
src = ureg_DECL_fs_input( ureg, TGSI_SEMANTIC_COLOR, 0,
TGSI_INTERPOLATE_PERSPECTIVE );
- dst = ureg_DECL_output( ureg, TGSI_SEMANTIC_COLOR, 0 );
+ for (i = 0; i < num_cbufs; i++)
+ dst[i] = ureg_DECL_output( ureg, TGSI_SEMANTIC_COLOR, i );
+
+ for (i = 0; i < num_cbufs; i++)
+ ureg_MOV( ureg, dst[i], src );
- ureg_MOV( ureg, dst, src );
ureg_END( ureg );
return ureg_create_shader_and_destroy( ureg, pipe );
}
-
-
diff --git a/src/gallium/auxiliary/util/u_simple_shaders.h b/src/gallium/auxiliary/util/u_simple_shaders.h
index d2e80d6eb4..6e760942e2 100644
--- a/src/gallium/auxiliary/util/u_simple_shaders.h
+++ b/src/gallium/auxiliary/util/u_simple_shaders.h
@@ -51,16 +51,25 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe,
extern void *
util_make_fragment_tex_shader_writemask(struct pipe_context *pipe,
- unsigned writemask );
+ unsigned tex_target,
+ unsigned writemask);
extern void *
-util_make_fragment_tex_shader(struct pipe_context *pipe);
+util_make_fragment_tex_shader(struct pipe_context *pipe, unsigned tex_target);
+
+
+extern void *
+util_make_fragment_tex_shader_writedepth(struct pipe_context *pipe,
+ unsigned tex_target);
extern void *
util_make_fragment_passthrough_shader(struct pipe_context *pipe);
+extern void *
+util_make_fragment_clonecolor_shader(struct pipe_context *pipe, int num_cbufs);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/gallium/auxiliary/util/u_surface.c b/src/gallium/auxiliary/util/u_surface.c
index f828908f0b..35c4978204 100644
--- a/src/gallium/auxiliary/util/u_surface.c
+++ b/src/gallium/auxiliary/util/u_surface.c
@@ -36,6 +36,7 @@
#include "pipe/p_state.h"
#include "pipe/p_defines.h"
+#include "util/u_format.h"
#include "util/u_surface.h"
diff --git a/src/gallium/auxiliary/util/u_texture.c b/src/gallium/auxiliary/util/u_texture.c
new file mode 100644
index 0000000000..cd477ab640
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_texture.c
@@ -0,0 +1,102 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * Copyright 2008 VMware, Inc. All rights reserved.
+ * Copyright 2009 Marek Olšák <maraeo@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * Texture mapping utility functions.
+ *
+ * @author Brian Paul
+ * Marek Olšák
+ */
+
+#include "pipe/p_defines.h"
+
+#include "util/u_texture.h"
+
+void util_map_texcoords2d_onto_cubemap(unsigned face,
+ const float *in_st, unsigned in_stride,
+ float *out_str, unsigned out_stride)
+{
+ int i;
+ float rx, ry, rz;
+
+ /* loop over quad verts */
+ for (i = 0; i < 4; i++) {
+ /* Compute sc = +/-scale and tc = +/-scale.
+ * Not +/-1 to avoid cube face selection ambiguity near the edges,
+ * though that can still sometimes happen with this scale factor...
+ */
+ const float scale = 0.9999f;
+ const float sc = (2 * in_st[0] - 1) * scale;
+ const float tc = (2 * in_st[1] - 1) * scale;
+
+ switch (face) {
+ case PIPE_TEX_FACE_POS_X:
+ rx = 1;
+ ry = -tc;
+ rz = -sc;
+ break;
+ case PIPE_TEX_FACE_NEG_X:
+ rx = -1;
+ ry = -tc;
+ rz = sc;
+ break;
+ case PIPE_TEX_FACE_POS_Y:
+ rx = sc;
+ ry = 1;
+ rz = tc;
+ break;
+ case PIPE_TEX_FACE_NEG_Y:
+ rx = sc;
+ ry = -1;
+ rz = -tc;
+ break;
+ case PIPE_TEX_FACE_POS_Z:
+ rx = sc;
+ ry = -tc;
+ rz = 1;
+ break;
+ case PIPE_TEX_FACE_NEG_Z:
+ rx = -sc;
+ ry = -tc;
+ rz = -1;
+ break;
+ default:
+ rx = ry = rz = 0;
+ assert(0);
+ }
+
+ out_str[0] = rx; /*s*/
+ out_str[1] = ry; /*t*/
+ out_str[2] = rz; /*r*/
+
+ in_st += in_stride;
+ out_str += out_stride;
+ }
+}
diff --git a/src/gallium/auxiliary/util/u_texture.h b/src/gallium/auxiliary/util/u_texture.h
new file mode 100644
index 0000000000..93b2f1e4c9
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_texture.h
@@ -0,0 +1,54 @@
+/**************************************************************************
+ *
+ * Copyright 2009 Marek Olšák <maraeo@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#ifndef U_TEXTURE_H
+#define U_TEXTURE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Convert 2D texture coordinates of 4 vertices into cubemap coordinates
+ * in the given face.
+ * Coordinates must be in the range [0,1].
+ *
+ * \param face Cubemap face.
+ * \param in_st 4 pairs of 2D texture coordinates to convert.
+ * \param in_stride Stride of in_st in floats.
+ * \param out_str STR cubemap texture coordinates to compute.
+ * \param out_stride Stride of out_str in floats.
+ */
+void util_map_texcoords2d_onto_cubemap(unsigned face,
+ const float *in_st, unsigned in_stride,
+ float *out_str, unsigned out_stride);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/gallium/auxiliary/util/u_tile.c b/src/gallium/auxiliary/util/u_tile.c
index 88c9a1f097..5b8dd1abb9 100644
--- a/src/gallium/auxiliary/util/u_tile.c
+++ b/src/gallium/auxiliary/util/u_tile.c
@@ -34,6 +34,7 @@
#include "pipe/p_defines.h"
#include "pipe/p_inlines.h"
+#include "util/u_format.h"
#include "util/u_math.h"
#include "util/u_memory.h"
#include "util/u_rect.h"
@@ -52,7 +53,7 @@ pipe_get_tile_raw(struct pipe_transfer *pt,
const void *src;
if (dst_stride == 0)
- dst_stride = pf_get_stride(pt->texture->format, w);
+ dst_stride = util_format_get_stride(pt->texture->format, w);
if (pipe_clip_tile(x, y, &w, &h, pt))
return;
@@ -81,7 +82,7 @@ pipe_put_tile_raw(struct pipe_transfer *pt,
enum pipe_format format = pt->texture->format;
if (src_stride == 0)
- src_stride = pf_get_stride(format, w);
+ src_stride = util_format_get_stride(format, w);
if (pipe_clip_tile(x, y, &w, &h, pt))
return;
@@ -1275,7 +1276,7 @@ pipe_get_tile_rgba(struct pipe_transfer *pt,
if (pipe_clip_tile(x, y, &w, &h, pt))
return;
- packed = MALLOC(pf_get_nblocks(format, w, h) * pf_get_blocksize(format));
+ packed = MALLOC(util_format_get_nblocks(format, w, h) * util_format_get_blocksize(format));
if (!packed)
return;
@@ -1303,7 +1304,7 @@ pipe_put_tile_rgba(struct pipe_transfer *pt,
if (pipe_clip_tile(x, y, &w, &h, pt))
return;
- packed = MALLOC(pf_get_nblocks(format, w, h) * pf_get_blocksize(format));
+ packed = MALLOC(util_format_get_nblocks(format, w, h) * util_format_get_blocksize(format));
if (!packed)
return;
diff --git a/src/gallium/auxiliary/util/u_upload_mgr.h b/src/gallium/auxiliary/util/u_upload_mgr.h
index 745b5834af..e158bed9d0 100644
--- a/src/gallium/auxiliary/util/u_upload_mgr.h
+++ b/src/gallium/auxiliary/util/u_upload_mgr.h
@@ -32,6 +32,8 @@
#ifndef U_UPLOAD_MGR_H
#define U_UPLOAD_MGR_H
+#include "pipe/p_defines.h"
+
struct pipe_screen;
struct pipe_buffer;
struct u_upload_mgr;
diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c
index 4952e9c9f8..ab196c21f8 100644
--- a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c
+++ b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c
@@ -29,6 +29,7 @@
#include <assert.h>
#include <pipe/p_context.h>
#include <pipe/p_inlines.h>
+#include <util/u_format.h>
#include <util/u_math.h>
#include <util/u_memory.h>
#include <tgsi/tgsi_parse.h>
@@ -1443,7 +1444,7 @@ grab_blocks(struct vl_mpeg12_mc_renderer *r, unsigned mbx, unsigned mby,
assert(r);
assert(blocks);
- tex_pitch = r->tex_transfer[0]->stride / pf_get_blocksize(r->tex_transfer[0]->texture->format);
+ tex_pitch = r->tex_transfer[0]->stride / util_format_get_blocksize(r->tex_transfer[0]->texture->format);
texels = r->texels[0] + mbpy * tex_pitch + mbpx;
for (y = 0; y < 2; ++y) {
@@ -1482,7 +1483,7 @@ grab_blocks(struct vl_mpeg12_mc_renderer *r, unsigned mbx, unsigned mby,
mbpy /= 2;
for (tb = 0; tb < 2; ++tb) {
- tex_pitch = r->tex_transfer[tb + 1]->stride / pf_get_blocksize(r->tex_transfer[tb + 1]->texture->format);
+ tex_pitch = r->tex_transfer[tb + 1]->stride / util_format_get_blocksize(r->tex_transfer[tb + 1]->texture->format);
texels = r->texels[tb + 1] + mbpy * tex_pitch + mbpx;
if ((cbp >> (1 - tb)) & 1) {