summaryrefslogtreecommitdiffstats
path: root/src/gallium/auxiliary
diff options
context:
space:
mode:
authorRoland Scheidegger <[email protected]>2010-05-04 15:58:29 +0200
committerRoland Scheidegger <[email protected]>2010-05-04 15:58:29 +0200
commit0ae2f59c0287f4baec6c7de5f2f0fdf736fba26d (patch)
treeee14bf3e8bba80649541c4e13fc07c60baf6c248 /src/gallium/auxiliary
parent7662e3519bef3802024da3050b886068281e02b1 (diff)
parent1c920c61764b17fd9fb4a89d2db7355fbe1d7565 (diff)
Merge commit 'origin/master' into gallium-msaa
Diffstat (limited to 'src/gallium/auxiliary')
-rw-r--r--src/gallium/auxiliary/Makefile1
-rw-r--r--src/gallium/auxiliary/SConscript1
-rw-r--r--src/gallium/auxiliary/cso_cache/cso_context.c48
-rw-r--r--src/gallium/auxiliary/draw/draw_llvm.c6
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c36
-rw-r--r--src/gallium/auxiliary/draw/draw_vs.c16
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_arit.c29
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_limits.h53
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_sample.h5
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c207
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_tgsi.h5
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c142
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_dump.c25
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_exec.c7
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_exec.h4
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_sanity.c4
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_text.c41
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_ureg.c22
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_ureg.h3
-rw-r--r--src/gallium/auxiliary/translate/translate_generic.c391
-rw-r--r--src/gallium/auxiliary/util/u_blitter.c1
-rw-r--r--src/gallium/auxiliary/util/u_caps.c1
-rw-r--r--src/gallium/auxiliary/util/u_clear.h1
-rw-r--r--src/gallium/auxiliary/util/u_format.h28
-rw-r--r--src/gallium/auxiliary/util/u_format_s3tc.c4
-rw-r--r--src/gallium/auxiliary/util/u_framebuffer.c111
-rw-r--r--src/gallium/auxiliary/util/u_framebuffer.h49
-rw-r--r--src/gallium/auxiliary/util/u_rect.c158
-rw-r--r--src/gallium/auxiliary/util/u_rect.h19
-rw-r--r--src/gallium/auxiliary/util/u_surface.c188
-rw-r--r--src/gallium/auxiliary/util/u_surface.h19
31 files changed, 843 insertions, 782 deletions
diff --git a/src/gallium/auxiliary/Makefile b/src/gallium/auxiliary/Makefile
index 2daed382cf3..e0d9b313544 100644
--- a/src/gallium/auxiliary/Makefile
+++ b/src/gallium/auxiliary/Makefile
@@ -113,6 +113,7 @@ C_SOURCES = \
util/u_format_tests.c \
util/u_format_yuv.c \
util/u_format_zs.c \
+ util/u_framebuffer.c \
util/u_gen_mipmap.c \
util/u_half.c \
util/u_handle_table.c \
diff --git a/src/gallium/auxiliary/SConscript b/src/gallium/auxiliary/SConscript
index a0673df8a8e..29a1bd0ecba 100644
--- a/src/gallium/auxiliary/SConscript
+++ b/src/gallium/auxiliary/SConscript
@@ -162,6 +162,7 @@ source = [
'util/u_format_tests.c',
'util/u_format_yuv.c',
'util/u_format_zs.c',
+ 'util/u_framebuffer.c',
'util/u_gen_mipmap.c',
'util/u_half.c',
'util/u_handle_table.c',
diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c
index 55e0ded1b30..20a8612dcae 100644
--- a/src/gallium/auxiliary/cso_cache/cso_context.c
+++ b/src/gallium/auxiliary/cso_cache/cso_context.c
@@ -36,6 +36,7 @@
*/
#include "pipe/p_state.h"
+#include "util/u_framebuffer.h"
#include "util/u_inlines.h"
#include "util/u_math.h"
#include "util/u_memory.h"
@@ -103,10 +104,6 @@ struct cso_context {
};
-static void
-free_framebuffer_state(struct pipe_framebuffer_state *fb);
-
-
static boolean delete_blend_state(struct cso_context *ctx, void *state)
{
struct cso_blend *cso = (struct cso_blend *)state;
@@ -304,8 +301,8 @@ void cso_release_all( struct cso_context *ctx )
pipe_sampler_view_reference(&ctx->vertex_sampler_views_saved[i], NULL);
}
- free_framebuffer_state(&ctx->fb);
- free_framebuffer_state(&ctx->fb_saved);
+ util_unreference_framebuffer_state(&ctx->fb);
+ util_unreference_framebuffer_state(&ctx->fb_saved);
if (ctx->cache) {
cso_cache_delete( ctx->cache );
@@ -897,42 +894,11 @@ void cso_restore_vertex_shader(struct cso_context *ctx)
}
-/**
- * Copy framebuffer state from src to dst with refcounting of surfaces.
- */
-static void
-copy_framebuffer_state(struct pipe_framebuffer_state *dst,
- const struct pipe_framebuffer_state *src)
-{
- uint i;
-
- dst->width = src->width;
- dst->height = src->height;
- dst->nr_cbufs = src->nr_cbufs;
- for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
- pipe_surface_reference(&dst->cbufs[i], src->cbufs[i]);
- }
- pipe_surface_reference(&dst->zsbuf, src->zsbuf);
-}
-
-
-static void
-free_framebuffer_state(struct pipe_framebuffer_state *fb)
-{
- uint i;
-
- for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
- pipe_surface_reference(&fb->cbufs[i], NULL);
- }
- pipe_surface_reference(&fb->zsbuf, NULL);
-}
-
-
enum pipe_error cso_set_framebuffer(struct cso_context *ctx,
const struct pipe_framebuffer_state *fb)
{
if (memcmp(&ctx->fb, fb, sizeof(*fb)) != 0) {
- copy_framebuffer_state(&ctx->fb, fb);
+ util_copy_framebuffer_state(&ctx->fb, fb);
ctx->pipe->set_framebuffer_state(ctx->pipe, fb);
}
return PIPE_OK;
@@ -940,15 +906,15 @@ enum pipe_error cso_set_framebuffer(struct cso_context *ctx,
void cso_save_framebuffer(struct cso_context *ctx)
{
- copy_framebuffer_state(&ctx->fb_saved, &ctx->fb);
+ util_copy_framebuffer_state(&ctx->fb_saved, &ctx->fb);
}
void cso_restore_framebuffer(struct cso_context *ctx)
{
if (memcmp(&ctx->fb, &ctx->fb_saved, sizeof(ctx->fb))) {
- copy_framebuffer_state(&ctx->fb, &ctx->fb_saved);
+ util_copy_framebuffer_state(&ctx->fb, &ctx->fb_saved);
ctx->pipe->set_framebuffer_state(ctx->pipe, &ctx->fb);
- free_framebuffer_state(&ctx->fb_saved);
+ util_unreference_framebuffer_state(&ctx->fb_saved);
}
}
diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c
index 3b2df054c3c..ea9b7c90a51 100644
--- a/src/gallium/auxiliary/draw/draw_llvm.c
+++ b/src/gallium/auxiliary/draw/draw_llvm.c
@@ -182,6 +182,8 @@ draw_llvm_create(struct draw_context *draw)
/* These are the passes currently listed in llvm-c/Transforms/Scalar.h,
* but there are more on SVN. */
/* TODO: Add more passes */
+ LLVMAddCFGSimplificationPass(llvm->pass);
+ LLVMAddPromoteMemoryToRegisterPass(llvm->pass);
LLVMAddConstantPropagationPass(llvm->pass);
if(util_cpu_caps.has_sse4_1) {
/* FIXME: There is a bug in this pass, whereby the combination of fptosi
@@ -190,9 +192,7 @@ draw_llvm_create(struct draw_context *draw)
*/
LLVMAddInstructionCombiningPass(llvm->pass);
}
- LLVMAddPromoteMemoryToRegisterPass(llvm->pass);
LLVMAddGVNPass(llvm->pass);
- LLVMAddCFGSimplificationPass(llvm->pass);
init_globals(llvm);
@@ -207,6 +207,8 @@ draw_llvm_create(struct draw_context *draw)
void
draw_llvm_destroy(struct draw_llvm *llvm)
{
+ LLVMDisposePassManager(llvm->pass);
+
FREE(llvm);
}
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c
index d2a492f2b4c..6d00b0fbd44 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c
@@ -66,7 +66,6 @@ llvm_middle_end_prepare( struct draw_pt_middle_end *middle,
struct llvm_middle_end *fpme = (struct llvm_middle_end *)middle;
struct draw_context *draw = fpme->draw;
struct draw_vertex_shader *vs = draw->vs.vertex_shader;
- struct draw_geometry_shader *gs = draw->gs.geometry_shader;
struct draw_llvm_variant_key key;
struct draw_llvm_variant *variant = NULL;
unsigned i;
@@ -97,17 +96,6 @@ llvm_middle_end_prepare( struct draw_pt_middle_end *middle,
fpme->vertex_size = sizeof(struct vertex_header) + nr * 4 * sizeof(float);
-
- draw_pt_fetch_prepare( fpme->fetch,
- vs->info.num_inputs,
- fpme->vertex_size,
- instance_id_index );
- if (opt & PT_SHADE) {
- vs->prepare(vs, draw);
- draw_geometry_shader_prepare(gs, draw);
- }
-
-
/* XXX: it's not really gl rasterization rules we care about here,
* but gl vs dx9 clip spaces.
*/
@@ -349,7 +337,31 @@ static void llvm_middle_end_finish( struct draw_pt_middle_end *middle )
static void llvm_middle_end_destroy( struct draw_pt_middle_end *middle )
{
struct llvm_middle_end *fpme = (struct llvm_middle_end *)middle;
+ struct draw_context *draw = fpme->draw;
+ struct draw_llvm_variant *variant = NULL;
+ variant = fpme->variants;
+ while(variant) {
+ struct draw_llvm_variant *next = variant->next;
+
+ if (variant->function_elts) {
+ if (variant->function_elts)
+ LLVMFreeMachineCodeForFunction(draw->engine,
+ variant->function_elts);
+ LLVMDeleteFunction(variant->function_elts);
+ }
+
+ if (variant->function) {
+ if (variant->function)
+ LLVMFreeMachineCodeForFunction(draw->engine,
+ variant->function);
+ LLVMDeleteFunction(variant->function);
+ }
+
+ FREE(variant);
+
+ variant = next;
+ }
if (fpme->fetch)
draw_pt_fetch_destroy( fpme->fetch );
diff --git a/src/gallium/auxiliary/draw/draw_vs.c b/src/gallium/auxiliary/draw/draw_vs.c
index c2832eefa2a..b9db886a24d 100644
--- a/src/gallium/auxiliary/draw/draw_vs.c
+++ b/src/gallium/auxiliary/draw/draw_vs.c
@@ -85,18 +85,22 @@ struct draw_vertex_shader *
draw_create_vertex_shader(struct draw_context *draw,
const struct pipe_shader_state *shader)
{
- struct draw_vertex_shader *vs;
+ struct draw_vertex_shader *vs = NULL;
if (draw->dump_vs) {
tgsi_dump(shader->tokens, 0);
}
- vs = draw_create_vs_sse( draw, shader );
- if (!vs) {
+ if (!draw->pt.middle.llvm) {
+#if defined(PIPE_ARCH_X86)
+ vs = draw_create_vs_sse( draw, shader );
+#elif defined(PIPE_ARCH_PPC)
vs = draw_create_vs_ppc( draw, shader );
- if (!vs) {
- vs = draw_create_vs_exec( draw, shader );
- }
+#endif
+ }
+
+ if (!vs) {
+ vs = draw_create_vs_exec( draw, shader );
}
if (vs)
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_arit.c b/src/gallium/auxiliary/gallivm/lp_bld_arit.c
index 20ae958714b..f372a48846f 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_arit.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_arit.c
@@ -1177,9 +1177,34 @@ lp_build_rcp(struct lp_build_context *bld,
if(LLVMIsConstant(a))
return LLVMConstFDiv(bld->one, a);
- if(util_cpu_caps.has_sse && type.width == 32 && type.length == 4)
- /* FIXME: improve precision */
+ if(util_cpu_caps.has_sse && type.width == 32 && type.length == 4) {
+ /*
+ * XXX: Added precision is not always necessary, so only enable this
+ * when we have a better system in place to track minimum precision.
+ */
+
+#if 0
+ /*
+ * Do one Newton-Raphson step to improve precision:
+ *
+ * x1 = (2 - a * rcp(a)) * rcp(a)
+ */
+
+ LLVMValueRef two = lp_build_const_vec(bld->type, 2.0);
+ LLVMValueRef rcp_a;
+ LLVMValueRef res;
+
+ rcp_a = lp_build_intrinsic_unary(bld->builder, "llvm.x86.sse.rcp.ps", lp_build_vec_type(type), a);
+
+ res = LLVMBuildMul(bld->builder, a, rcp_a, "");
+ res = LLVMBuildSub(bld->builder, two, res, "");
+ res = LLVMBuildMul(bld->builder, res, rcp_a, "");
+
+ return rcp_a;
+#else
return lp_build_intrinsic_unary(bld->builder, "llvm.x86.sse.rcp.ps", lp_build_vec_type(type), a);
+#endif
+ }
return LLVMBuildFDiv(bld->builder, bld->one, a, "");
}
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_limits.h b/src/gallium/auxiliary/gallivm/lp_bld_limits.h
new file mode 100644
index 00000000000..e095a0abe3a
--- /dev/null
+++ b/src/gallium/auxiliary/gallivm/lp_bld_limits.h
@@ -0,0 +1,53 @@
+/**************************************************************************
+ *
+ * Copyright 2010 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 LP_BLD_LIMITS_H_
+#define LP_BLD_LIMITS_H_
+
+/*
+ * TGSI translation limits.
+ *
+ * Some are slightly above SM 3.0 requirements to give some wiggle room to
+ * the state trackers.
+ */
+
+#define LP_MAX_TGSI_TEMPS 256
+
+#define LP_MAX_TGSI_ADDRS 16
+
+#define LP_MAX_TGSI_IMMEDIATES 256
+
+/**
+ * Maximum control flow nesting
+ *
+ * SM3.0 requires 24
+ */
+#define LP_MAX_TGSI_NESTING 32
+
+
+#endif /* LP_BLD_LIMITS_H_ */
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.h b/src/gallium/auxiliary/gallivm/lp_bld_sample.h
index 8ceb20473d5..955b1d21ee5 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_sample.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.h
@@ -173,7 +173,10 @@ lp_build_sample_soa(LLVMBuilderRef builder,
unsigned unit,
unsigned num_coords,
const LLVMValueRef *coords,
- LLVMValueRef lodbias,
+ const LLVMValueRef *ddx,
+ const LLVMValueRef *ddy,
+ LLVMValueRef lod_bias,
+ LLVMValueRef explicit_lod,
LLVMValueRef *texel);
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
index 74dc9e1d812..3f0ea05b795 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
@@ -30,6 +30,7 @@
* Texture sampling -- SoA.
*
* @author Jose Fonseca <[email protected]>
+ * @author Brian Paul <[email protected]>
*/
#include "pipe/p_defines.h"
@@ -325,6 +326,18 @@ lp_build_sample_texel_soa(struct lp_build_sample_context *bld,
bld->format_desc,
x, y, z, y_stride, z_stride);
+ if (use_border) {
+ /* If we can sample the border color, it means that texcoords may
+ * lie outside the bounds of the texture image. We need to do
+ * something to prevent reading out of bounds and causing a segfault.
+ *
+ * Simply AND the texture coords with !use_border. This will cause
+ * coords which are out of bounds to become zero. Zero's guaranteed
+ * to be inside the texture image.
+ */
+ offset = lp_build_andc(&bld->uint_coord_bld, offset, use_border);
+ }
+
lp_build_fetch_rgba_soa(bld->builder,
bld->format_desc,
bld->texel_type,
@@ -891,17 +904,24 @@ lp_build_minify(struct lp_build_sample_context *bld,
* \param s vector of texcoord s values
* \param t vector of texcoord t values
* \param r vector of texcoord r values
- * \param shader_lod_bias vector float with the shader lod bias,
+ * \param lod_bias optional float vector with the shader lod bias
+ * \param explicit_lod optional float vector with the explicit lod
* \param width scalar int texture width
* \param height scalar int texture height
* \param depth scalar int texture depth
+ *
+ * XXX: The resulting lod is scalar, so ignore all but the first element of
+ * derivatives, lod_bias, etc that are passed by the shader.
*/
static LLVMValueRef
lp_build_lod_selector(struct lp_build_sample_context *bld,
LLVMValueRef s,
LLVMValueRef t,
LLVMValueRef r,
- LLVMValueRef shader_lod_bias,
+ const LLVMValueRef *ddx,
+ const LLVMValueRef *ddy,
+ LLVMValueRef lod_bias, /* optional */
+ LLVMValueRef explicit_lod, /* optional */
LLVMValueRef width,
LLVMValueRef height,
LLVMValueRef depth)
@@ -914,7 +934,6 @@ lp_build_lod_selector(struct lp_build_sample_context *bld,
return LLVMConstReal(LLVMFloatType(), bld->static_state->min_lod);
}
else {
- const int dims = texture_dims(bld->static_state->target);
struct lp_build_context *float_bld = &bld->float_bld;
LLVMValueRef sampler_lod_bias = LLVMConstReal(LLVMFloatType(),
bld->static_state->lod_bias);
@@ -922,83 +941,76 @@ lp_build_lod_selector(struct lp_build_sample_context *bld,
bld->static_state->min_lod);
LLVMValueRef max_lod = LLVMConstReal(LLVMFloatType(),
bld->static_state->max_lod);
-
LLVMValueRef index0 = LLVMConstInt(LLVMInt32Type(), 0, 0);
- LLVMValueRef index1 = LLVMConstInt(LLVMInt32Type(), 1, 0);
- LLVMValueRef index2 = LLVMConstInt(LLVMInt32Type(), 2, 0);
-
- LLVMValueRef s0, s1, s2;
- LLVMValueRef t0, t1, t2;
- LLVMValueRef r0, r1, r2;
- LLVMValueRef dsdx, dsdy, dtdx, dtdy, drdx, drdy;
- LLVMValueRef rho, lod;
-
- /*
- * dsdx = abs(s[1] - s[0]);
- * dsdy = abs(s[2] - s[0]);
- * dtdx = abs(t[1] - t[0]);
- * dtdy = abs(t[2] - t[0]);
- * drdx = abs(r[1] - r[0]);
- * drdy = abs(r[2] - r[0]);
- * XXX we're assuming a four-element quad in 2x2 layout here.
- */
- s0 = LLVMBuildExtractElement(bld->builder, s, index0, "s0");
- s1 = LLVMBuildExtractElement(bld->builder, s, index1, "s1");
- s2 = LLVMBuildExtractElement(bld->builder, s, index2, "s2");
- dsdx = LLVMBuildSub(bld->builder, s1, s0, "");
- dsdx = lp_build_abs(float_bld, dsdx);
- dsdy = LLVMBuildSub(bld->builder, s2, s0, "");
- dsdy = lp_build_abs(float_bld, dsdy);
- if (dims > 1) {
- t0 = LLVMBuildExtractElement(bld->builder, t, index0, "t0");
- t1 = LLVMBuildExtractElement(bld->builder, t, index1, "t1");
- t2 = LLVMBuildExtractElement(bld->builder, t, index2, "t2");
- dtdx = LLVMBuildSub(bld->builder, t1, t0, "");
- dtdx = lp_build_abs(float_bld, dtdx);
- dtdy = LLVMBuildSub(bld->builder, t2, t0, "");
- dtdy = lp_build_abs(float_bld, dtdy);
- if (dims > 2) {
- r0 = LLVMBuildExtractElement(bld->builder, r, index0, "r0");
- r1 = LLVMBuildExtractElement(bld->builder, r, index1, "r1");
- r2 = LLVMBuildExtractElement(bld->builder, r, index2, "r2");
- drdx = LLVMBuildSub(bld->builder, r1, r0, "");
- drdx = lp_build_abs(float_bld, drdx);
- drdy = LLVMBuildSub(bld->builder, r2, r0, "");
- drdy = lp_build_abs(float_bld, drdy);
- }
+ LLVMValueRef lod;
+
+ if (explicit_lod) {
+ lod = LLVMBuildExtractElement(bld->builder, explicit_lod,
+ index0, "");
}
+ else {
+ const int dims = texture_dims(bld->static_state->target);
+ LLVMValueRef dsdx, dsdy, dtdx, dtdy, drdx, drdy;
+ LLVMValueRef rho;
+
+ /*
+ * dsdx = abs(s[1] - s[0]);
+ * dsdy = abs(s[2] - s[0]);
+ * dtdx = abs(t[1] - t[0]);
+ * dtdy = abs(t[2] - t[0]);
+ * drdx = abs(r[1] - r[0]);
+ * drdy = abs(r[2] - r[0]);
+ */
+ dsdx = LLVMBuildExtractElement(bld->builder, ddx[0], index0, "dsdx");
+ dsdx = lp_build_abs(float_bld, dsdx);
+ dsdy = LLVMBuildExtractElement(bld->builder, ddy[0], index0, "dsdy");
+ dsdy = lp_build_abs(float_bld, dsdy);
+ if (dims > 1) {
+ dtdx = LLVMBuildExtractElement(bld->builder, ddx[1], index0, "dtdx");
+ dtdx = lp_build_abs(float_bld, dtdx);
+ dtdy = LLVMBuildExtractElement(bld->builder, ddy[1], index0, "dtdy");
+ dtdy = lp_build_abs(float_bld, dtdy);
+ if (dims > 2) {
+ drdx = LLVMBuildExtractElement(bld->builder, ddx[2], index0, "drdx");
+ drdx = lp_build_abs(float_bld, drdx);
+ drdy = LLVMBuildExtractElement(bld->builder, ddy[2], index0, "drdy");
+ drdy = lp_build_abs(float_bld, drdy);
+ }
+ }
- /* Compute rho = max of all partial derivatives scaled by texture size.
- * XXX this could be vectorized somewhat
- */
- rho = LLVMBuildMul(bld->builder,
- lp_build_max(float_bld, dsdx, dsdy),
- lp_build_int_to_float(float_bld, width), "");
- if (dims > 1) {
- LLVMValueRef max;
- max = LLVMBuildMul(bld->builder,
- lp_build_max(float_bld, dtdx, dtdy),
- lp_build_int_to_float(float_bld, height), "");
- rho = lp_build_max(float_bld, rho, max);
- if (dims > 2) {
+ /* Compute rho = max of all partial derivatives scaled by texture size.
+ * XXX this could be vectorized somewhat
+ */
+ rho = LLVMBuildMul(bld->builder,
+ lp_build_max(float_bld, dsdx, dsdy),
+ lp_build_int_to_float(float_bld, width), "");
+ if (dims > 1) {
+ LLVMValueRef max;
max = LLVMBuildMul(bld->builder,
- lp_build_max(float_bld, drdx, drdy),
- lp_build_int_to_float(float_bld, depth), "");
+ lp_build_max(float_bld, dtdx, dtdy),
+ lp_build_int_to_float(float_bld, height), "");
rho = lp_build_max(float_bld, rho, max);
+ if (dims > 2) {
+ max = LLVMBuildMul(bld->builder,
+ lp_build_max(float_bld, drdx, drdy),
+ lp_build_int_to_float(float_bld, depth), "");
+ rho = lp_build_max(float_bld, rho, max);
+ }
}
- }
- /* compute lod = log2(rho) */
- lod = lp_build_log2(float_bld, rho);
+ /* compute lod = log2(rho) */
+ lod = lp_build_log2(float_bld, rho);
- /* add sampler lod bias */
- lod = LLVMBuildAdd(bld->builder, lod, sampler_lod_bias, "sampler LOD bias");
+ /* add shader lod bias */
+ if (lod_bias) {
+ lod_bias = LLVMBuildExtractElement(bld->builder, lod_bias,
+ index0, "");
+ lod = LLVMBuildAdd(bld->builder, lod, lod_bias, "shader_lod_bias");
+ }
+ }
- /* add shader lod bias */
- /* XXX for now we take only the first element since our lod is scalar */
- shader_lod_bias = LLVMBuildExtractElement(bld->builder, shader_lod_bias,
- LLVMConstInt(LLVMInt32Type(), 0, 0), "");
- lod = LLVMBuildAdd(bld->builder, lod, shader_lod_bias, "shader LOD bias");
+ /* add sampler lod bias */
+ lod = LLVMBuildAdd(bld->builder, lod, sampler_lod_bias, "sampler_lod_bias");
/* clamp lod */
lod = lp_build_clamp(float_bld, lod, min_lod, max_lod);
@@ -1584,7 +1596,10 @@ lp_build_sample_general(struct lp_build_sample_context *bld,
LLVMValueRef s,
LLVMValueRef t,
LLVMValueRef r,
- LLVMValueRef lodbias,
+ const LLVMValueRef *ddx,
+ const LLVMValueRef *ddy,
+ LLVMValueRef lod_bias, /* optional */
+ LLVMValueRef explicit_lod, /* optional */
LLVMValueRef width,
LLVMValueRef height,
LLVMValueRef depth,
@@ -1622,7 +1637,9 @@ lp_build_sample_general(struct lp_build_sample_context *bld,
/* Need to compute lod either to choose mipmap levels or to
* distinguish between minification/magnification with one mipmap level.
*/
- lod = lp_build_lod_selector(bld, s, t, r, lodbias, width, height, depth);
+ lod = lp_build_lod_selector(bld, s, t, r, ddx, ddy,
+ lod_bias, explicit_lod,
+ width, height, depth);
}
/*
@@ -2049,6 +2066,24 @@ lp_build_sample_compare(struct lp_build_sample_context *bld,
/**
+ * Just set texels to white instead of actually sampling the texture.
+ * For debugging.
+ */
+static void
+lp_build_sample_nop(struct lp_build_sample_context *bld,
+ LLVMValueRef *texel)
+{
+ struct lp_build_context *texel_bld = &bld->texel_bld;
+ unsigned chan;
+
+ for (chan = 0; chan < 4; chan++) {
+ /*lp_bld_mov(texel_bld, texel, texel_bld->one);*/
+ texel[chan] = texel_bld->one;
+ }
+}
+
+
+/**
* Build texture sampling code.
* 'texel' will return a vector of four LLVMValueRefs corresponding to
* R, G, B, A.
@@ -2062,7 +2097,10 @@ lp_build_sample_soa(LLVMBuilderRef builder,
unsigned unit,
unsigned num_coords,
const LLVMValueRef *coords,
- LLVMValueRef lodbias,
+ const LLVMValueRef *ddx,
+ const LLVMValueRef *ddy,
+ LLVMValueRef lod_bias, /* optional */
+ LLVMValueRef explicit_lod, /* optional */
LLVMValueRef *texel)
{
struct lp_build_sample_context bld;
@@ -2113,19 +2151,24 @@ lp_build_sample_soa(LLVMBuilderRef builder,
height_vec = lp_build_broadcast_scalar(&bld.uint_coord_bld, height);
depth_vec = lp_build_broadcast_scalar(&bld.uint_coord_bld, depth);
- if (util_format_is_rgba8_variant(bld.format_desc) &&
- static_state->target == PIPE_TEXTURE_2D &&
- static_state->min_img_filter == PIPE_TEX_FILTER_LINEAR &&
- static_state->mag_img_filter == PIPE_TEX_FILTER_LINEAR &&
- static_state->min_mip_filter == PIPE_TEX_MIPFILTER_NONE &&
- is_simple_wrap_mode(static_state->wrap_s) &&
- is_simple_wrap_mode(static_state->wrap_t)) {
+ if (0) {
+ /* For debug: no-op texture sampling */
+ lp_build_sample_nop(&bld, texel);
+ }
+ else if (util_format_is_rgba8_variant(bld.format_desc) &&
+ static_state->target == PIPE_TEXTURE_2D &&
+ static_state->min_img_filter == PIPE_TEX_FILTER_LINEAR &&
+ static_state->mag_img_filter == PIPE_TEX_FILTER_LINEAR &&
+ static_state->min_mip_filter == PIPE_TEX_MIPFILTER_NONE &&
+ is_simple_wrap_mode(static_state->wrap_s) &&
+ is_simple_wrap_mode(static_state->wrap_t)) {
/* special case */
lp_build_sample_2d_linear_aos(&bld, s, t, width_vec, height_vec,
row_stride_array, data_array, texel);
}
else {
- lp_build_sample_general(&bld, unit, s, t, r, lodbias,
+ lp_build_sample_general(&bld, unit, s, t, r, ddx, ddy,
+ lod_bias, explicit_lod,
width, height, depth,
width_vec, height_vec, depth_vec,
row_stride_array, img_stride_array,
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
index 2eac5da6c69..5ce1385c480 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
@@ -65,7 +65,10 @@ struct lp_build_sampler_soa
unsigned unit,
unsigned num_coords,
const LLVMValueRef *coords,
- LLVMValueRef lodbias,
+ const LLVMValueRef *ddx,
+ const LLVMValueRef *ddy,
+ LLVMValueRef lod_bias, /* optional */
+ LLVMValueRef explicit_lod, /* optional */
LLVMValueRef *texel);
};
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
index d3c769e28b8..0b1a28a7ab7 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
@@ -54,13 +54,10 @@
#include "lp_bld_swizzle.h"
#include "lp_bld_flow.h"
#include "lp_bld_tgsi.h"
+#include "lp_bld_limits.h"
#include "lp_bld_debug.h"
-#define LP_MAX_TEMPS 256
-#define LP_MAX_IMMEDIATES 256
-
-
#define FOR_EACH_CHANNEL( CHAN )\
for (CHAN = 0; CHAN < NUM_CHANNELS; CHAN++)
@@ -84,7 +81,6 @@
#define QUAD_BOTTOM_LEFT 2
#define QUAD_BOTTOM_RIGHT 3
-#define LP_TGSI_MAX_NESTING 16
struct lp_exec_mask {
struct lp_build_context *bld;
@@ -93,19 +89,19 @@ struct lp_exec_mask {
LLVMTypeRef int_vec_type;
- LLVMValueRef cond_stack[LP_TGSI_MAX_NESTING];
+ LLVMValueRef cond_stack[LP_MAX_TGSI_NESTING];
int cond_stack_size;
LLVMValueRef cond_mask;
- LLVMValueRef break_stack[LP_TGSI_MAX_NESTING];
+ LLVMValueRef break_stack[LP_MAX_TGSI_NESTING];
int break_stack_size;
LLVMValueRef break_mask;
- LLVMValueRef cont_stack[LP_TGSI_MAX_NESTING];
+ LLVMValueRef cont_stack[LP_MAX_TGSI_NESTING];
int cont_stack_size;
LLVMValueRef cont_mask;
- LLVMBasicBlockRef loop_stack[LP_TGSI_MAX_NESTING];
+ LLVMBasicBlockRef loop_stack[LP_MAX_TGSI_NESTING];
int loop_stack_size;
LLVMBasicBlockRef loop_block;
@@ -124,9 +120,9 @@ struct lp_build_tgsi_soa_context
struct lp_build_sampler_soa *sampler;
- LLVMValueRef immediates[LP_MAX_IMMEDIATES][NUM_CHANNELS];
- LLVMValueRef temps[LP_MAX_TEMPS][NUM_CHANNELS];
- LLVMValueRef addr[LP_MAX_TEMPS][NUM_CHANNELS];
+ LLVMValueRef immediates[LP_MAX_TGSI_IMMEDIATES][NUM_CHANNELS];
+ LLVMValueRef temps[LP_MAX_TGSI_TEMPS][NUM_CHANNELS];
+ LLVMValueRef addr[LP_MAX_TGSI_ADDRS][NUM_CHANNELS];
/* we allocate an array of temps if we have indirect
* addressing and then the temps above is unused */
@@ -198,6 +194,7 @@ static void lp_exec_mask_update(struct lp_exec_mask *mask)
static void lp_exec_mask_cond_push(struct lp_exec_mask *mask,
LLVMValueRef val)
{
+ assert(mask->cond_stack_size < LP_MAX_TGSI_NESTING);
mask->cond_stack[mask->cond_stack_size++] = mask->cond_mask;
mask->cond_mask = LLVMBuildBitCast(mask->bld->builder, val,
mask->int_vec_type, "");
@@ -239,6 +236,10 @@ static void lp_exec_bgnloop(struct lp_exec_mask *mask)
if (mask->cond_stack_size == 0)
mask->cond_mask = LLVMConstAllOnes(mask->int_vec_type);
+ assert(mask->break_stack_size < LP_MAX_TGSI_NESTING);
+ assert(mask->cont_stack_size < LP_MAX_TGSI_NESTING);
+ assert(mask->break_stack_size < LP_MAX_TGSI_NESTING);
+
mask->break_stack[mask->break_stack_size++] = mask->break_mask;
mask->cont_stack[mask->cont_stack_size++] = mask->cont_mask;
mask->loop_stack[mask->loop_stack_size++] = mask->loop_block;
@@ -255,16 +256,9 @@ static void lp_exec_break(struct lp_exec_mask *mask)
mask->exec_mask,
"break");
- /* mask->break_stack_size > 1 implies that we encountered a break
- * statemant already and if that's the case we want to make sure
- * our mask is a combination of the previous break and the current
- * execution mask */
- if (mask->break_stack_size > 1) {
- mask->break_mask = LLVMBuildAnd(mask->bld->builder,
- mask->break_mask,
- exec_mask, "break_full");
- } else
- mask->break_mask = exec_mask;
+ mask->break_mask = LLVMBuildAnd(mask->bld->builder,
+ mask->break_mask,
+ exec_mask, "break_full");
lp_exec_mask_update(mask);
}
@@ -275,12 +269,9 @@ static void lp_exec_continue(struct lp_exec_mask *mask)
mask->exec_mask,
"");
- if (mask->cont_stack_size > 1) {
- mask->cont_mask = LLVMBuildAnd(mask->bld->builder,
- mask->cont_mask,
- exec_mask, "");
- } else
- mask->cont_mask = exec_mask;
+ mask->cont_mask = LLVMBuildAnd(mask->bld->builder,
+ mask->cont_mask,
+ exec_mask, "");
lp_exec_mask_update(mask);
}
@@ -589,7 +580,6 @@ emit_store(
case TGSI_FILE_PREDICATE:
/* FIXME */
- assert(0);
break;
default:
@@ -602,21 +592,37 @@ emit_store(
* High-level instruction translators.
*/
+enum tex_modifier {
+ TEX_MODIFIER_NONE = 0,
+ TEX_MODIFIER_PROJECTED,
+ TEX_MODIFIER_LOD_BIAS,
+ TEX_MODIFIER_EXPLICIT_LOD,
+ TEX_MODIFIER_EXPLICIT_DERIV
+};
static void
emit_tex( struct lp_build_tgsi_soa_context *bld,
const struct tgsi_full_instruction *inst,
- boolean apply_lodbias,
- boolean projected,
+ enum tex_modifier modifier,
LLVMValueRef *texel)
{
- const uint unit = inst->Src[1].Register.Index;
- LLVMValueRef lodbias;
+ unsigned unit;
+ LLVMValueRef lod_bias, explicit_lod;
LLVMValueRef oow = NULL;
LLVMValueRef coords[3];
+ LLVMValueRef ddx[3];
+ LLVMValueRef ddy[3];
unsigned num_coords;
unsigned i;
+ if (!bld->sampler) {
+ _debug_printf("warning: found texture instruction but no sampler generator supplied\n");
+ for (i = 0; i < 4; i++) {
+ texel[i] = bld->base.undef;
+ }
+ return;
+ }
+
switch (inst->Texture.Texture) {
case TGSI_TEXTURE_1D:
num_coords = 1;
@@ -637,29 +643,57 @@ emit_tex( struct lp_build_tgsi_soa_context *bld,
return;
}
- if(apply_lodbias)
- lodbias = emit_fetch( bld, inst, 0, 3 );
- else
- lodbias = bld->base.zero;
+ if (modifier == TEX_MODIFIER_LOD_BIAS) {
+ lod_bias = emit_fetch( bld, inst, 0, 3 );
+ explicit_lod = NULL;
+ }
+ else if (modifier == TEX_MODIFIER_EXPLICIT_LOD) {
+ lod_bias = NULL;
+ explicit_lod = emit_fetch( bld, inst, 0, 3 );
+ }
+ else {
+ lod_bias = NULL;
+ explicit_lod = NULL;
+ }
- if (projected) {
+ if (modifier == TEX_MODIFIER_PROJECTED) {
oow = emit_fetch( bld, inst, 0, 3 );
oow = lp_build_rcp(&bld->base, oow);
}
for (i = 0; i < num_coords; i++) {
coords[i] = emit_fetch( bld, inst, 0, i );
- if (projected)
+ if (modifier == TEX_MODIFIER_PROJECTED)
coords[i] = lp_build_mul(&bld->base, coords[i], oow);
}
for (i = num_coords; i < 3; i++) {
coords[i] = bld->base.undef;
}
+ if (modifier == TEX_MODIFIER_EXPLICIT_DERIV) {
+ for (i = 0; i < num_coords; i++) {
+ ddx[i] = emit_fetch( bld, inst, 1, i );
+ ddy[i] = emit_fetch( bld, inst, 2, i );
+ }
+ unit = inst->Src[3].Register.Index;
+ } else {
+ for (i = 0; i < num_coords; i++) {
+ ddx[i] = emit_ddx( bld, coords[i] );
+ ddy[i] = emit_ddy( bld, coords[i] );
+ }
+ unit = inst->Src[1].Register.Index;
+ }
+ for (i = num_coords; i < 3; i++) {
+ ddx[i] = bld->base.undef;
+ ddy[i] = bld->base.undef;
+ }
+
bld->sampler->emit_fetch_texel(bld->sampler,
bld->base.builder,
bld->base.type,
- unit, num_coords, coords, lodbias,
+ unit, num_coords, coords,
+ ddx, ddy,
+ lod_bias, explicit_lod,
texel);
}
@@ -739,7 +773,7 @@ emit_kilp(struct lp_build_tgsi_soa_context *bld,
lp_build_mask_update(bld->mask, mask);
}
-static int
+static void
emit_declaration(
struct lp_build_tgsi_soa_context *bld,
const struct tgsi_full_declaration *decl)
@@ -753,6 +787,7 @@ emit_declaration(
for (idx = first; idx <= last; ++idx) {
switch (decl->Declaration.File) {
case TGSI_FILE_TEMPORARY:
+ assert(idx < LP_MAX_TGSI_TEMPS);
if (bld->has_indirect_addressing) {
LLVMValueRef val = LLVMConstInt(LLVMInt32Type(),
last*4 + 4, 0);
@@ -772,18 +807,21 @@ emit_declaration(
break;
case TGSI_FILE_ADDRESS:
+ assert(idx < LP_MAX_TGSI_ADDRS);
for (i = 0; i < NUM_CHANNELS; i++)
bld->addr[idx][i] = lp_build_alloca(bld->base.builder,
vec_type, "");
break;
+ case TGSI_FILE_PREDICATE:
+ _debug_printf("warning: predicate registers not yet implemented\n");
+ break;
+
default:
/* don't need to declare other vars */
break;
}
}
-
- return TRUE;
}
@@ -1359,12 +1397,11 @@ emit_instruction(
break;
case TGSI_OPCODE_TEX:
- emit_tex( bld, inst, FALSE, FALSE, dst0 );
+ emit_tex( bld, inst, TEX_MODIFIER_NONE, dst0 );
break;
case TGSI_OPCODE_TXD:
- /* FIXME */
- return FALSE;
+ emit_tex( bld, inst, TEX_MODIFIER_EXPLICIT_DERIV, dst0 );
break;
case TGSI_OPCODE_UP2H:
@@ -1466,7 +1503,7 @@ emit_instruction(
break;
case TGSI_OPCODE_TXB:
- emit_tex( bld, inst, TRUE, FALSE, dst0 );
+ emit_tex( bld, inst, TEX_MODIFIER_LOD_BIAS, dst0 );
break;
case TGSI_OPCODE_NRM:
@@ -1571,11 +1608,11 @@ emit_instruction(
break;
case TGSI_OPCODE_TXL:
- emit_tex( bld, inst, TRUE, FALSE, dst0 );
+ emit_tex( bld, inst, TEX_MODIFIER_EXPLICIT_LOD, dst0 );
break;
case TGSI_OPCODE_TXP:
- emit_tex( bld, inst, FALSE, TRUE, dst0 );
+ emit_tex( bld, inst, TEX_MODIFIER_PROJECTED, dst0 );
break;
case TGSI_OPCODE_BRK:
@@ -1765,10 +1802,7 @@ lp_build_tgsi_soa(LLVMBuilderRef builder,
switch( parse.FullToken.Token.Type ) {
case TGSI_TOKEN_TYPE_DECLARATION:
/* Inputs already interpolated */
- {
- if (!emit_declaration( &bld, &parse.FullToken.FullDeclaration ))
- _debug_printf("warning: failed to define LLVM variable\n");
- }
+ emit_declaration( &bld, &parse.FullToken.FullDeclaration );
break;
case TGSI_TOKEN_TYPE_INSTRUCTION:
@@ -1787,7 +1821,7 @@ lp_build_tgsi_soa(LLVMBuilderRef builder,
{
const uint size = parse.FullToken.FullImmediate.Immediate.NrTokens - 1;
assert(size <= 4);
- assert(num_immediates < LP_MAX_IMMEDIATES);
+ assert(num_immediates < LP_MAX_TGSI_IMMEDIATES);
for( i = 0; i < size; ++i )
bld.immediates[num_immediates][i] =
lp_build_const_vec(type, parse.FullToken.FullImmediate.u[i].Float);
diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.c b/src/gallium/auxiliary/tgsi/tgsi_dump.c
index 83000200189..1ad183b8dd4 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_dump.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_dump.c
@@ -100,7 +100,6 @@ static const char *file_names[TGSI_FILE_COUNT] =
"SAMP",
"ADDR",
"IMM",
- "LOOP",
"PRED",
"SV"
};
@@ -494,6 +493,30 @@ iter_instruction(
TXT( " " );
ctx->indent += info->post_indent;
+ if (inst->Instruction.Predicate) {
+ CHR( '(' );
+
+ if (inst->Predicate.Negate)
+ CHR( '!' );
+
+ TXT( "PRED[" );
+ SID( inst->Predicate.Index );
+ CHR( ']' );
+
+ if (inst->Predicate.SwizzleX != TGSI_SWIZZLE_X ||
+ inst->Predicate.SwizzleY != TGSI_SWIZZLE_Y ||
+ inst->Predicate.SwizzleZ != TGSI_SWIZZLE_Z ||
+ inst->Predicate.SwizzleW != TGSI_SWIZZLE_W) {
+ CHR( '.' );
+ ENM( inst->Predicate.SwizzleX, swizzle_names );
+ ENM( inst->Predicate.SwizzleY, swizzle_names );
+ ENM( inst->Predicate.SwizzleZ, swizzle_names );
+ ENM( inst->Predicate.SwizzleW, swizzle_names );
+ }
+
+ TXT( ") " );
+ }
+
TXT( info->mnemonic );
switch (inst->Instruction.Saturate) {
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c
index 82eac05dc4d..9b1ca7fa851 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c
@@ -1346,13 +1346,6 @@ store_dest(struct tgsi_exec_machine *mach,
dst = &mach->Addrs[index].xyzw[chan_index];
break;
- case TGSI_FILE_LOOP:
- assert(reg->Register.Index == 0);
- assert(mach->LoopCounterStackTop > 0);
- assert(chan_index == CHAN_X);
- dst = &mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[chan_index];
- break;
-
case TGSI_FILE_PREDICATE:
index = reg->Register.Index;
assert(index < TGSI_EXEC_NUM_PREDS);
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.h b/src/gallium/auxiliary/tgsi/tgsi_exec.h
index a22873e4c2b..11bbaf6722e 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.h
@@ -299,10 +299,6 @@ struct tgsi_exec_machine
uint LoopLabelStack[TGSI_EXEC_MAX_LOOP_NESTING];
int LoopLabelStackTop;
- /** Loop counter stack (x = index, y = counter, z = step) */
- struct tgsi_exec_vector LoopCounterStack[TGSI_EXEC_MAX_LOOP_NESTING];
- int LoopCounterStackTop;
-
/** Loop continue mask stack (see comments in tgsi_exec.c) */
uint ContStack[TGSI_EXEC_MAX_LOOP_NESTING];
int ContStackTop;
diff --git a/src/gallium/auxiliary/tgsi/tgsi_sanity.c b/src/gallium/auxiliary/tgsi/tgsi_sanity.c
index 76b7564cc36..ce0a92f7fb3 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_sanity.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_sanity.c
@@ -235,8 +235,8 @@ static const char *file_names[TGSI_FILE_COUNT] =
"SAMP",
"ADDR",
"IMM",
- "LOOP",
- "PRED"
+ "PRED",
+ "SV"
};
static boolean
diff --git a/src/gallium/auxiliary/tgsi/tgsi_text.c b/src/gallium/auxiliary/tgsi/tgsi_text.c
index 0b468a9184e..71a0d96331a 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_text.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_text.c
@@ -278,7 +278,6 @@ static const char *file_names[TGSI_FILE_COUNT] =
"SAMP",
"ADDR",
"IMM",
- "LOOP",
"PRED",
"SV"
};
@@ -816,6 +815,45 @@ parse_instruction(
struct tgsi_full_instruction inst;
uint advance;
+ inst = tgsi_default_full_instruction();
+
+ /* Parse predicate.
+ */
+ eat_opt_white( &ctx->cur );
+ if (*ctx->cur == '(') {
+ uint file;
+ int index;
+ uint swizzle[4];
+ boolean parsed_swizzle;
+
+ inst.Instruction.Predicate = 1;
+
+ ctx->cur++;
+ if (*ctx->cur == '!') {
+ ctx->cur++;
+ inst.Predicate.Negate = 1;
+ }
+
+ if (!parse_register_dst( ctx, &file, &index ))
+ return FALSE;
+
+ if (parse_optional_swizzle( ctx, swizzle, &parsed_swizzle )) {
+ if (parsed_swizzle) {
+ inst.Predicate.SwizzleX = swizzle[0];
+ inst.Predicate.SwizzleY = swizzle[1];
+ inst.Predicate.SwizzleZ = swizzle[2];
+ inst.Predicate.SwizzleW = swizzle[3];
+ }
+ }
+
+ if (*ctx->cur != ')') {
+ report_error( ctx, "Expected `)'" );
+ return FALSE;
+ }
+
+ ctx->cur++;
+ }
+
/* Parse instruction name.
*/
eat_opt_white( &ctx->cur );
@@ -849,7 +887,6 @@ parse_instruction(
return FALSE;
}
- inst = tgsi_default_full_instruction();
inst.Instruction.Opcode = i;
inst.Instruction.Saturate = saturate;
inst.Instruction.NumDstRegs = info->num_dst;
diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.c b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
index f725405ade1..49b854b1234 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_ureg.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
@@ -74,7 +74,6 @@ struct ureg_tokens {
#define UREG_MAX_IMMEDIATE 32
#define UREG_MAX_TEMP 256
#define UREG_MAX_ADDR 2
-#define UREG_MAX_LOOP 1
#define UREG_MAX_PRED 1
struct const_decl {
@@ -151,7 +150,6 @@ struct ureg_program
unsigned nr_addrs;
unsigned nr_preds;
- unsigned nr_loops;
unsigned nr_instructions;
struct ureg_tokens domain[2];
@@ -537,19 +535,6 @@ struct ureg_dst ureg_DECL_address( struct ureg_program *ureg )
return ureg_dst_register( TGSI_FILE_ADDRESS, 0 );
}
-/* Allocate a new loop register.
- */
-struct ureg_dst
-ureg_DECL_loop(struct ureg_program *ureg)
-{
- if (ureg->nr_loops < UREG_MAX_LOOP) {
- return ureg_dst_register(TGSI_FILE_LOOP, ureg->nr_loops++);
- }
-
- assert(0);
- return ureg_dst_register(TGSI_FILE_LOOP, 0);
-}
-
/* Allocate a new predicate register.
*/
struct ureg_dst
@@ -1356,13 +1341,6 @@ static void emit_decls( struct ureg_program *ureg )
0, ureg->nr_addrs );
}
- if (ureg->nr_loops) {
- emit_decl_range(ureg,
- TGSI_FILE_LOOP,
- 0,
- ureg->nr_loops);
- }
-
if (ureg->nr_preds) {
emit_decl_range(ureg,
TGSI_FILE_PREDICATE,
diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.h b/src/gallium/auxiliary/tgsi/tgsi_ureg.h
index 0130a77aadb..f32420dd872 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_ureg.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.h
@@ -231,9 +231,6 @@ struct ureg_dst
ureg_DECL_address( struct ureg_program * );
struct ureg_dst
-ureg_DECL_loop( struct ureg_program * );
-
-struct ureg_dst
ureg_DECL_predicate(struct ureg_program *);
/* Supply an index to the sampler declaration as this is the hook to
diff --git a/src/gallium/auxiliary/translate/translate_generic.c b/src/gallium/auxiliary/translate/translate_generic.c
index a9272fbb491..f8dbd2b36a1 100644
--- a/src/gallium/auxiliary/translate/translate_generic.c
+++ b/src/gallium/auxiliary/translate/translate_generic.c
@@ -31,6 +31,7 @@
*/
#include "util/u_memory.h"
+#include "util/u_format.h"
#include "util/u_math.h"
#include "pipe/p_state.h"
#include "translate.h"
@@ -38,7 +39,9 @@
#define DRAW_DBG 0
-typedef void (*fetch_func)(const void *ptr, float *attrib);
+typedef void (*fetch_func)(float *dst,
+ const uint8_t *src,
+ unsigned i, unsigned j);
typedef void (*emit_func)(const float *attrib, void *ptr);
@@ -57,7 +60,7 @@ struct translate_generic {
emit_func emit;
unsigned output_offset;
- char *input_ptr;
+ const uint8_t *input_ptr;
unsigned input_stride;
unsigned max_index;
@@ -79,22 +82,7 @@ static struct translate_generic *translate_generic( struct translate *translate
* This is probably needed/dupliocated elsewhere, eg format
* conversion, texture sampling etc.
*/
-#define ATTRIB( NAME, SZ, TYPE, FROM, TO ) \
-static void \
-fetch_##NAME(const void *ptr, float *attrib) \
-{ \
- const float defaults[4] = { 0.0f,0.0f,0.0f,1.0f }; \
- unsigned i; \
- \
- for (i = 0; i < SZ; i++) { \
- attrib[i] = FROM(i); \
- } \
- \
- for (; i < 4; i++) { \
- attrib[i] = defaults[i]; \
- } \
-} \
- \
+#define ATTRIB( NAME, SZ, TYPE, TO ) \
static void \
emit_##NAME(const float *attrib, void *ptr) \
{ \
@@ -107,27 +95,6 @@ emit_##NAME(const float *attrib, void *ptr) \
}
-#define FROM_64_FLOAT(i) ((float) ((double *) ptr)[i])
-#define FROM_32_FLOAT(i) (((float *) ptr)[i])
-
-#define FROM_8_USCALED(i) ((float) ((unsigned char *) ptr)[i])
-#define FROM_16_USCALED(i) ((float) ((unsigned short *) ptr)[i])
-#define FROM_32_USCALED(i) ((float) ((unsigned int *) ptr)[i])
-
-#define FROM_8_SSCALED(i) ((float) ((char *) ptr)[i])
-#define FROM_16_SSCALED(i) ((float) ((short *) ptr)[i])
-#define FROM_32_SSCALED(i) ((float) ((int *) ptr)[i])
-
-#define FROM_8_UNORM(i) ((float) ((unsigned char *) ptr)[i] / 255.0f)
-#define FROM_16_UNORM(i) ((float) ((unsigned short *) ptr)[i] / 65535.0f)
-#define FROM_32_UNORM(i) ((float) ((unsigned int *) ptr)[i] / 4294967295.0f)
-
-#define FROM_8_SNORM(i) ((float) ((char *) ptr)[i] / 127.0f)
-#define FROM_16_SNORM(i) ((float) ((short *) ptr)[i] / 32767.0f)
-#define FROM_32_SNORM(i) ((float) ((int *) ptr)[i] / 2147483647.0f)
-
-#define FROM_32_FIXED(i) (((int *) ptr)[i] / 65536.0f)
-
#define TO_64_FLOAT(x) ((double) x)
#define TO_32_FLOAT(x) (x)
@@ -150,95 +117,79 @@ emit_##NAME(const float *attrib, void *ptr) \
#define TO_32_FIXED(x) ((int) (x * 65536.0f))
+ATTRIB( R64G64B64A64_FLOAT, 4, double, TO_64_FLOAT )
+ATTRIB( R64G64B64_FLOAT, 3, double, TO_64_FLOAT )
+ATTRIB( R64G64_FLOAT, 2, double, TO_64_FLOAT )
+ATTRIB( R64_FLOAT, 1, double, TO_64_FLOAT )
+
+ATTRIB( R32G32B32A32_FLOAT, 4, float, TO_32_FLOAT )
+ATTRIB( R32G32B32_FLOAT, 3, float, TO_32_FLOAT )
+ATTRIB( R32G32_FLOAT, 2, float, TO_32_FLOAT )
+ATTRIB( R32_FLOAT, 1, float, TO_32_FLOAT )
+
+ATTRIB( R32G32B32A32_USCALED, 4, unsigned, TO_32_USCALED )
+ATTRIB( R32G32B32_USCALED, 3, unsigned, TO_32_USCALED )
+ATTRIB( R32G32_USCALED, 2, unsigned, TO_32_USCALED )
+ATTRIB( R32_USCALED, 1, unsigned, TO_32_USCALED )
+
+ATTRIB( R32G32B32A32_SSCALED, 4, int, TO_32_SSCALED )
+ATTRIB( R32G32B32_SSCALED, 3, int, TO_32_SSCALED )
+ATTRIB( R32G32_SSCALED, 2, int, TO_32_SSCALED )
+ATTRIB( R32_SSCALED, 1, int, TO_32_SSCALED )
+
+ATTRIB( R32G32B32A32_UNORM, 4, unsigned, TO_32_UNORM )
+ATTRIB( R32G32B32_UNORM, 3, unsigned, TO_32_UNORM )
+ATTRIB( R32G32_UNORM, 2, unsigned, TO_32_UNORM )
+ATTRIB( R32_UNORM, 1, unsigned, TO_32_UNORM )
+
+ATTRIB( R32G32B32A32_SNORM, 4, int, TO_32_SNORM )
+ATTRIB( R32G32B32_SNORM, 3, int, TO_32_SNORM )
+ATTRIB( R32G32_SNORM, 2, int, TO_32_SNORM )
+ATTRIB( R32_SNORM, 1, int, TO_32_SNORM )
+
+ATTRIB( R16G16B16A16_USCALED, 4, ushort, TO_16_USCALED )
+ATTRIB( R16G16B16_USCALED, 3, ushort, TO_16_USCALED )
+ATTRIB( R16G16_USCALED, 2, ushort, TO_16_USCALED )
+ATTRIB( R16_USCALED, 1, ushort, TO_16_USCALED )
+
+ATTRIB( R16G16B16A16_SSCALED, 4, short, TO_16_SSCALED )
+ATTRIB( R16G16B16_SSCALED, 3, short, TO_16_SSCALED )
+ATTRIB( R16G16_SSCALED, 2, short, TO_16_SSCALED )
+ATTRIB( R16_SSCALED, 1, short, TO_16_SSCALED )
+
+ATTRIB( R16G16B16A16_UNORM, 4, ushort, TO_16_UNORM )
+ATTRIB( R16G16B16_UNORM, 3, ushort, TO_16_UNORM )
+ATTRIB( R16G16_UNORM, 2, ushort, TO_16_UNORM )
+ATTRIB( R16_UNORM, 1, ushort, TO_16_UNORM )
+
+ATTRIB( R16G16B16A16_SNORM, 4, short, TO_16_SNORM )
+ATTRIB( R16G16B16_SNORM, 3, short, TO_16_SNORM )
+ATTRIB( R16G16_SNORM, 2, short, TO_16_SNORM )
+ATTRIB( R16_SNORM, 1, short, TO_16_SNORM )
+
+ATTRIB( R8G8B8A8_USCALED, 4, ubyte, TO_8_USCALED )
+ATTRIB( R8G8B8_USCALED, 3, ubyte, TO_8_USCALED )
+ATTRIB( R8G8_USCALED, 2, ubyte, TO_8_USCALED )
+ATTRIB( R8_USCALED, 1, ubyte, TO_8_USCALED )
+
+ATTRIB( R8G8B8A8_SSCALED, 4, char, TO_8_SSCALED )
+ATTRIB( R8G8B8_SSCALED, 3, char, TO_8_SSCALED )
+ATTRIB( R8G8_SSCALED, 2, char, TO_8_SSCALED )
+ATTRIB( R8_SSCALED, 1, char, TO_8_SSCALED )
+
+ATTRIB( R8G8B8A8_UNORM, 4, ubyte, TO_8_UNORM )
+ATTRIB( R8G8B8_UNORM, 3, ubyte, TO_8_UNORM )
+ATTRIB( R8G8_UNORM, 2, ubyte, TO_8_UNORM )
+ATTRIB( R8_UNORM, 1, ubyte, TO_8_UNORM )
+
+ATTRIB( R8G8B8A8_SNORM, 4, char, TO_8_SNORM )
+ATTRIB( R8G8B8_SNORM, 3, char, TO_8_SNORM )
+ATTRIB( R8G8_SNORM, 2, char, TO_8_SNORM )
+ATTRIB( R8_SNORM, 1, char, TO_8_SNORM )
+
+ATTRIB( A8R8G8B8_UNORM, 4, ubyte, TO_8_UNORM )
+/*ATTRIB( R8G8B8A8_UNORM, 4, ubyte, TO_8_UNORM )*/
-ATTRIB( R64G64B64A64_FLOAT, 4, double, FROM_64_FLOAT, TO_64_FLOAT )
-ATTRIB( R64G64B64_FLOAT, 3, double, FROM_64_FLOAT, TO_64_FLOAT )
-ATTRIB( R64G64_FLOAT, 2, double, FROM_64_FLOAT, TO_64_FLOAT )
-ATTRIB( R64_FLOAT, 1, double, FROM_64_FLOAT, TO_64_FLOAT )
-
-ATTRIB( R32G32B32A32_FLOAT, 4, float, FROM_32_FLOAT, TO_32_FLOAT )
-ATTRIB( R32G32B32_FLOAT, 3, float, FROM_32_FLOAT, TO_32_FLOAT )
-ATTRIB( R32G32_FLOAT, 2, float, FROM_32_FLOAT, TO_32_FLOAT )
-ATTRIB( R32_FLOAT, 1, float, FROM_32_FLOAT, TO_32_FLOAT )
-
-ATTRIB( R32G32B32A32_USCALED, 4, unsigned, FROM_32_USCALED, TO_32_USCALED )
-ATTRIB( R32G32B32_USCALED, 3, unsigned, FROM_32_USCALED, TO_32_USCALED )
-ATTRIB( R32G32_USCALED, 2, unsigned, FROM_32_USCALED, TO_32_USCALED )
-ATTRIB( R32_USCALED, 1, unsigned, FROM_32_USCALED, TO_32_USCALED )
-
-ATTRIB( R32G32B32A32_SSCALED, 4, int, FROM_32_SSCALED, TO_32_SSCALED )
-ATTRIB( R32G32B32_SSCALED, 3, int, FROM_32_SSCALED, TO_32_SSCALED )
-ATTRIB( R32G32_SSCALED, 2, int, FROM_32_SSCALED, TO_32_SSCALED )
-ATTRIB( R32_SSCALED, 1, int, FROM_32_SSCALED, TO_32_SSCALED )
-
-ATTRIB( R32G32B32A32_UNORM, 4, unsigned, FROM_32_UNORM, TO_32_UNORM )
-ATTRIB( R32G32B32_UNORM, 3, unsigned, FROM_32_UNORM, TO_32_UNORM )
-ATTRIB( R32G32_UNORM, 2, unsigned, FROM_32_UNORM, TO_32_UNORM )
-ATTRIB( R32_UNORM, 1, unsigned, FROM_32_UNORM, TO_32_UNORM )
-
-ATTRIB( R32G32B32A32_SNORM, 4, int, FROM_32_SNORM, TO_32_SNORM )
-ATTRIB( R32G32B32_SNORM, 3, int, FROM_32_SNORM, TO_32_SNORM )
-ATTRIB( R32G32_SNORM, 2, int, FROM_32_SNORM, TO_32_SNORM )
-ATTRIB( R32_SNORM, 1, int, FROM_32_SNORM, TO_32_SNORM )
-
-ATTRIB( R16G16B16A16_USCALED, 4, ushort, FROM_16_USCALED, TO_16_USCALED )
-ATTRIB( R16G16B16_USCALED, 3, ushort, FROM_16_USCALED, TO_16_USCALED )
-ATTRIB( R16G16_USCALED, 2, ushort, FROM_16_USCALED, TO_16_USCALED )
-ATTRIB( R16_USCALED, 1, ushort, FROM_16_USCALED, TO_16_USCALED )
-
-ATTRIB( R16G16B16A16_SSCALED, 4, short, FROM_16_SSCALED, TO_16_SSCALED )
-ATTRIB( R16G16B16_SSCALED, 3, short, FROM_16_SSCALED, TO_16_SSCALED )
-ATTRIB( R16G16_SSCALED, 2, short, FROM_16_SSCALED, TO_16_SSCALED )
-ATTRIB( R16_SSCALED, 1, short, FROM_16_SSCALED, TO_16_SSCALED )
-
-ATTRIB( R16G16B16A16_UNORM, 4, ushort, FROM_16_UNORM, TO_16_UNORM )
-ATTRIB( R16G16B16_UNORM, 3, ushort, FROM_16_UNORM, TO_16_UNORM )
-ATTRIB( R16G16_UNORM, 2, ushort, FROM_16_UNORM, TO_16_UNORM )
-ATTRIB( R16_UNORM, 1, ushort, FROM_16_UNORM, TO_16_UNORM )
-
-ATTRIB( R16G16B16A16_SNORM, 4, short, FROM_16_SNORM, TO_16_SNORM )
-ATTRIB( R16G16B16_SNORM, 3, short, FROM_16_SNORM, TO_16_SNORM )
-ATTRIB( R16G16_SNORM, 2, short, FROM_16_SNORM, TO_16_SNORM )
-ATTRIB( R16_SNORM, 1, short, FROM_16_SNORM, TO_16_SNORM )
-
-ATTRIB( R8G8B8A8_USCALED, 4, ubyte, FROM_8_USCALED, TO_8_USCALED )
-ATTRIB( R8G8B8_USCALED, 3, ubyte, FROM_8_USCALED, TO_8_USCALED )
-ATTRIB( R8G8_USCALED, 2, ubyte, FROM_8_USCALED, TO_8_USCALED )
-ATTRIB( R8_USCALED, 1, ubyte, FROM_8_USCALED, TO_8_USCALED )
-
-ATTRIB( R8G8B8A8_SSCALED, 4, char, FROM_8_SSCALED, TO_8_SSCALED )
-ATTRIB( R8G8B8_SSCALED, 3, char, FROM_8_SSCALED, TO_8_SSCALED )
-ATTRIB( R8G8_SSCALED, 2, char, FROM_8_SSCALED, TO_8_SSCALED )
-ATTRIB( R8_SSCALED, 1, char, FROM_8_SSCALED, TO_8_SSCALED )
-
-ATTRIB( R8G8B8A8_UNORM, 4, ubyte, FROM_8_UNORM, TO_8_UNORM )
-ATTRIB( R8G8B8_UNORM, 3, ubyte, FROM_8_UNORM, TO_8_UNORM )
-ATTRIB( R8G8_UNORM, 2, ubyte, FROM_8_UNORM, TO_8_UNORM )
-ATTRIB( R8_UNORM, 1, ubyte, FROM_8_UNORM, TO_8_UNORM )
-
-ATTRIB( R8G8B8A8_SNORM, 4, char, FROM_8_SNORM, TO_8_SNORM )
-ATTRIB( R8G8B8_SNORM, 3, char, FROM_8_SNORM, TO_8_SNORM )
-ATTRIB( R8G8_SNORM, 2, char, FROM_8_SNORM, TO_8_SNORM )
-ATTRIB( R8_SNORM, 1, char, FROM_8_SNORM, TO_8_SNORM )
-
-ATTRIB( A8R8G8B8_UNORM, 4, ubyte, FROM_8_UNORM, TO_8_UNORM )
-/*ATTRIB( R8G8B8A8_UNORM, 4, ubyte, FROM_8_UNORM, TO_8_UNORM )*/
-
-ATTRIB( R32G32B32A32_FIXED, 4, int, FROM_32_FIXED, TO_32_FIXED )
-ATTRIB( R32G32B32_FIXED, 3, int, FROM_32_FIXED, TO_32_FIXED )
-ATTRIB( R32G32_FIXED, 2, int, FROM_32_FIXED, TO_32_FIXED )
-ATTRIB( R32_FIXED, 1, int, FROM_32_FIXED, TO_32_FIXED )
-
-
-
-static void
-fetch_B8G8R8A8_UNORM(const void *ptr, float *attrib)
-{
- attrib[2] = FROM_8_UNORM(0);
- attrib[1] = FROM_8_UNORM(1);
- attrib[0] = FROM_8_UNORM(2);
- attrib[3] = FROM_8_UNORM(3);
-}
static void
emit_B8G8R8A8_UNORM( const float *attrib, void *ptr)
@@ -251,181 +202,13 @@ emit_B8G8R8A8_UNORM( const float *attrib, void *ptr)
}
static void
-fetch_NULL( const void *ptr, float *attrib )
-{
- attrib[0] = 0;
- attrib[1] = 0;
- attrib[2] = 0;
- attrib[3] = 1;
-}
-
-static void
emit_NULL( const float *attrib, void *ptr )
{
/* do nothing is the only sensible option */
}
-static fetch_func get_fetch_func( enum pipe_format format )
-{
- switch (format) {
- case PIPE_FORMAT_R64_FLOAT:
- return &fetch_R64_FLOAT;
- case PIPE_FORMAT_R64G64_FLOAT:
- return &fetch_R64G64_FLOAT;
- case PIPE_FORMAT_R64G64B64_FLOAT:
- return &fetch_R64G64B64_FLOAT;
- case PIPE_FORMAT_R64G64B64A64_FLOAT:
- return &fetch_R64G64B64A64_FLOAT;
-
- case PIPE_FORMAT_R32_FLOAT:
- return &fetch_R32_FLOAT;
- case PIPE_FORMAT_R32G32_FLOAT:
- return &fetch_R32G32_FLOAT;
- case PIPE_FORMAT_R32G32B32_FLOAT:
- return &fetch_R32G32B32_FLOAT;
- case PIPE_FORMAT_R32G32B32A32_FLOAT:
- return &fetch_R32G32B32A32_FLOAT;
-
- case PIPE_FORMAT_R32_UNORM:
- return &fetch_R32_UNORM;
- case PIPE_FORMAT_R32G32_UNORM:
- return &fetch_R32G32_UNORM;
- case PIPE_FORMAT_R32G32B32_UNORM:
- return &fetch_R32G32B32_UNORM;
- case PIPE_FORMAT_R32G32B32A32_UNORM:
- return &fetch_R32G32B32A32_UNORM;
-
- case PIPE_FORMAT_R32_USCALED:
- return &fetch_R32_USCALED;
- case PIPE_FORMAT_R32G32_USCALED:
- return &fetch_R32G32_USCALED;
- case PIPE_FORMAT_R32G32B32_USCALED:
- return &fetch_R32G32B32_USCALED;
- case PIPE_FORMAT_R32G32B32A32_USCALED:
- return &fetch_R32G32B32A32_USCALED;
-
- case PIPE_FORMAT_R32_SNORM:
- return &fetch_R32_SNORM;
- case PIPE_FORMAT_R32G32_SNORM:
- return &fetch_R32G32_SNORM;
- case PIPE_FORMAT_R32G32B32_SNORM:
- return &fetch_R32G32B32_SNORM;
- case PIPE_FORMAT_R32G32B32A32_SNORM:
- return &fetch_R32G32B32A32_SNORM;
-
- case PIPE_FORMAT_R32_SSCALED:
- return &fetch_R32_SSCALED;
- case PIPE_FORMAT_R32G32_SSCALED:
- return &fetch_R32G32_SSCALED;
- case PIPE_FORMAT_R32G32B32_SSCALED:
- return &fetch_R32G32B32_SSCALED;
- case PIPE_FORMAT_R32G32B32A32_SSCALED:
- return &fetch_R32G32B32A32_SSCALED;
-
- case PIPE_FORMAT_R16_UNORM:
- return &fetch_R16_UNORM;
- case PIPE_FORMAT_R16G16_UNORM:
- return &fetch_R16G16_UNORM;
- case PIPE_FORMAT_R16G16B16_UNORM:
- return &fetch_R16G16B16_UNORM;
- case PIPE_FORMAT_R16G16B16A16_UNORM:
- return &fetch_R16G16B16A16_UNORM;
-
- case PIPE_FORMAT_R16_USCALED:
- return &fetch_R16_USCALED;
- case PIPE_FORMAT_R16G16_USCALED:
- return &fetch_R16G16_USCALED;
- case PIPE_FORMAT_R16G16B16_USCALED:
- return &fetch_R16G16B16_USCALED;
- case PIPE_FORMAT_R16G16B16A16_USCALED:
- return &fetch_R16G16B16A16_USCALED;
-
- case PIPE_FORMAT_R16_SNORM:
- return &fetch_R16_SNORM;
- case PIPE_FORMAT_R16G16_SNORM:
- return &fetch_R16G16_SNORM;
- case PIPE_FORMAT_R16G16B16_SNORM:
- return &fetch_R16G16B16_SNORM;
- case PIPE_FORMAT_R16G16B16A16_SNORM:
- return &fetch_R16G16B16A16_SNORM;
-
- case PIPE_FORMAT_R16_SSCALED:
- return &fetch_R16_SSCALED;
- case PIPE_FORMAT_R16G16_SSCALED:
- return &fetch_R16G16_SSCALED;
- case PIPE_FORMAT_R16G16B16_SSCALED:
- return &fetch_R16G16B16_SSCALED;
- case PIPE_FORMAT_R16G16B16A16_SSCALED:
- return &fetch_R16G16B16A16_SSCALED;
-
- case PIPE_FORMAT_R8_UNORM:
- return &fetch_R8_UNORM;
- case PIPE_FORMAT_R8G8_UNORM:
- return &fetch_R8G8_UNORM;
- case PIPE_FORMAT_R8G8B8_UNORM:
- return &fetch_R8G8B8_UNORM;
- case PIPE_FORMAT_R8G8B8A8_UNORM:
- return &fetch_R8G8B8A8_UNORM;
-
- case PIPE_FORMAT_R8_USCALED:
- return &fetch_R8_USCALED;
- case PIPE_FORMAT_R8G8_USCALED:
- return &fetch_R8G8_USCALED;
- case PIPE_FORMAT_R8G8B8_USCALED:
- return &fetch_R8G8B8_USCALED;
- case PIPE_FORMAT_R8G8B8A8_USCALED:
- return &fetch_R8G8B8A8_USCALED;
-
- case PIPE_FORMAT_R8_SNORM:
- return &fetch_R8_SNORM;
- case PIPE_FORMAT_R8G8_SNORM:
- return &fetch_R8G8_SNORM;
- case PIPE_FORMAT_R8G8B8_SNORM:
- return &fetch_R8G8B8_SNORM;
- case PIPE_FORMAT_R8G8B8A8_SNORM:
- return &fetch_R8G8B8A8_SNORM;
-
- case PIPE_FORMAT_R8_SSCALED:
- return &fetch_R8_SSCALED;
- case PIPE_FORMAT_R8G8_SSCALED:
- return &fetch_R8G8_SSCALED;
- case PIPE_FORMAT_R8G8B8_SSCALED:
- return &fetch_R8G8B8_SSCALED;
- case PIPE_FORMAT_R8G8B8A8_SSCALED:
- return &fetch_R8G8B8A8_SSCALED;
-
- case PIPE_FORMAT_B8G8R8A8_UNORM:
- return &fetch_B8G8R8A8_UNORM;
-
- case PIPE_FORMAT_A8R8G8B8_UNORM:
- return &fetch_A8R8G8B8_UNORM;
-
- case PIPE_FORMAT_R32_FIXED:
- return &fetch_R32_FIXED;
- case PIPE_FORMAT_R32G32_FIXED:
- return &fetch_R32G32_FIXED;
- case PIPE_FORMAT_R32G32B32_FIXED:
- return &fetch_R32G32B32_FIXED;
- case PIPE_FORMAT_R32G32B32A32_FIXED:
- return &fetch_R32G32B32A32_FIXED;
-
- default:
- assert(0);
- return &fetch_NULL;
- }
-}
-
-
-
-
static emit_func get_emit_func( enum pipe_format format )
{
- /* silence warnings */
- (void) emit_R32G32B32A32_FIXED;
- (void) emit_R32G32B32_FIXED;
- (void) emit_R32G32_FIXED;
- (void) emit_R32_FIXED;
-
switch (format) {
case PIPE_FORMAT_R64_FLOAT:
return &emit_R64_FLOAT;
@@ -589,7 +372,7 @@ static void PIPE_CDECL generic_run_elts( struct translate *translate,
for (attr = 0; attr < nr_attrs; attr++) {
float data[4];
- const char *src;
+ const uint8_t *src;
unsigned index;
char *dst = (vert +
@@ -606,7 +389,7 @@ static void PIPE_CDECL generic_run_elts( struct translate *translate,
src = tg->attrib[attr].input_ptr +
tg->attrib[attr].input_stride * index;
- tg->attrib[attr].fetch( src, data );
+ tg->attrib[attr].fetch( data, src, 0, 0 );
if (0) debug_printf("vert %d/%d attr %d: %f %f %f %f\n",
i, elt, attr, data[0], data[1], data[2], data[3]);
@@ -644,7 +427,7 @@ static void PIPE_CDECL generic_run( struct translate *translate,
tg->attrib[attr].output_offset);
if (tg->attrib[attr].type == TRANSLATE_ELEMENT_NORMAL) {
- const char *src;
+ const uint8_t *src;
if (tg->attrib[attr].instance_divisor) {
src = tg->attrib[attr].input_ptr +
@@ -655,7 +438,7 @@ static void PIPE_CDECL generic_run( struct translate *translate,
tg->attrib[attr].input_stride * elt;
}
- tg->attrib[attr].fetch( src, data );
+ tg->attrib[attr].fetch( data, src, 0, 0 );
} else {
data[0] = (float)instance_id;
}
@@ -683,7 +466,7 @@ static void generic_set_buffer( struct translate *translate,
for (i = 0; i < tg->nr_attrib; i++) {
if (tg->attrib[i].buffer == buf) {
- tg->attrib[i].input_ptr = ((char *)ptr +
+ tg->attrib[i].input_ptr = ((const uint8_t *)ptr +
tg->attrib[i].input_offset);
tg->attrib[i].input_stride = stride;
tg->attrib[i].max_index = max_index;
@@ -714,9 +497,15 @@ struct translate *translate_generic_create( const struct translate_key *key )
tg->translate.run = generic_run;
for (i = 0; i < key->nr_elements; i++) {
+ const struct util_format_description *format_desc =
+ util_format_description(key->element[i].input_format);
+
+ assert(format_desc);
+ assert(format_desc->fetch_rgba_float);
+
tg->attrib[i].type = key->element[i].type;
- tg->attrib[i].fetch = get_fetch_func(key->element[i].input_format);
+ tg->attrib[i].fetch = format_desc->fetch_rgba_float;
tg->attrib[i].buffer = key->element[i].input_buffer;
tg->attrib[i].input_offset = key->element[i].input_offset;
tg->attrib[i].instance_divisor = key->element[i].instance_divisor;
diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c
index 956aedc8a15..1abe31db466 100644
--- a/src/gallium/auxiliary/util/u_blitter.c
+++ b/src/gallium/auxiliary/util/u_blitter.c
@@ -47,6 +47,7 @@
#include "util/u_rect.h"
#include "util/u_sampler.h"
#include "util/u_simple_shaders.h"
+#include "util/u_surface.h"
#include "util/u_texture.h"
#define INVALID_PTR ((void*)~0)
diff --git a/src/gallium/auxiliary/util/u_caps.c b/src/gallium/auxiliary/util/u_caps.c
index 048bd5c34da..c7c1e830e01 100644
--- a/src/gallium/auxiliary/util/u_caps.c
+++ b/src/gallium/auxiliary/util/u_caps.c
@@ -73,6 +73,7 @@ util_check_caps_out(struct pipe_screen *screen, const unsigned *list, int *out)
*out = i - 2;
return FALSE;
}
+ break;
case UTIL_CAPS_CHECK_UNIMPLEMENTED:
*out = i - 1;
return FALSE;
diff --git a/src/gallium/auxiliary/util/u_clear.h b/src/gallium/auxiliary/util/u_clear.h
index 2c32db61756..40da2d75a72 100644
--- a/src/gallium/auxiliary/util/u_clear.h
+++ b/src/gallium/auxiliary/util/u_clear.h
@@ -33,6 +33,7 @@
#include "pipe/p_state.h"
#include "util/u_pack_color.h"
#include "util/u_rect.h"
+#include "util/u_surface.h"
/**
diff --git a/src/gallium/auxiliary/util/u_format.h b/src/gallium/auxiliary/util/u_format.h
index fb6ade5c06b..8ba076949b6 100644
--- a/src/gallium/auxiliary/util/u_format.h
+++ b/src/gallium/auxiliary/util/u_format.h
@@ -338,6 +338,34 @@ util_format_name(enum pipe_format format)
return desc->name;
}
+static INLINE const char *
+util_format_short_name(enum pipe_format format)
+{
+ const struct util_format_description *desc = util_format_description(format);
+
+ assert(desc);
+ if (!desc) {
+ return "???";
+ }
+
+ return desc->short_name;
+}
+
+/**
+ * Whether this format is plain, see UTIL_FORMAT_LAYOUT_PLAIN for more info.
+ */
+static INLINE boolean
+util_format_is_plain(enum pipe_format format)
+{
+ const struct util_format_description *desc = util_format_description(format);
+
+ if (!format) {
+ return FALSE;
+ }
+
+ return desc->layout == UTIL_FORMAT_LAYOUT_PLAIN ? TRUE : FALSE;
+}
+
static INLINE boolean
util_format_is_s3tc(enum pipe_format format)
{
diff --git a/src/gallium/auxiliary/util/u_format_s3tc.c b/src/gallium/auxiliary/util/u_format_s3tc.c
index 5b279b8fe26..bb989c29d81 100644
--- a/src/gallium/auxiliary/util/u_format_s3tc.c
+++ b/src/gallium/auxiliary/util/u_format_s3tc.c
@@ -120,7 +120,7 @@ util_format_s3tc_init(void)
library = util_dl_open(DXTN_LIBNAME);
if (!library) {
debug_printf("couldn't open " DXTN_LIBNAME ", software DXTn "
- "compression/decompression unavailable");
+ "compression/decompression unavailable\n");
return;
}
@@ -142,7 +142,7 @@ util_format_s3tc_init(void)
!util_format_dxtn_pack) {
debug_printf("couldn't reference all symbols in " DXTN_LIBNAME
", software DXTn compression/decompression "
- "unavailable");
+ "unavailable\n");
util_dl_close(library);
return;
}
diff --git a/src/gallium/auxiliary/util/u_framebuffer.c b/src/gallium/auxiliary/util/u_framebuffer.c
new file mode 100644
index 00000000000..bdac12dbca2
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_framebuffer.c
@@ -0,0 +1,111 @@
+/**************************************************************************
+ *
+ * Copyright 2009-2010 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 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 VMWARE 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
+ * Framebuffer utility functions.
+ *
+ * @author Brian Paul
+ */
+
+
+#include "pipe/p_screen.h"
+#include "pipe/p_state.h"
+#include "pipe/p_defines.h"
+#include "util/u_inlines.h"
+
+#include "util/u_memory.h"
+#include "util/u_framebuffer.h"
+
+
+/**
+ * Compare pipe_framebuffer_state objects.
+ * \return TRUE if same, FALSE if different
+ */
+boolean
+util_framebuffer_state_equal(const struct pipe_framebuffer_state *dst,
+ const struct pipe_framebuffer_state *src)
+{
+ unsigned i;
+
+ if (dst->width != src->width ||
+ dst->height != src->height)
+ return FALSE;
+
+ for (i = 0; i < Elements(src->cbufs); i++) {
+ if (dst->cbufs[i] != src->cbufs[i]) {
+ return FALSE;
+ }
+ }
+
+ if (dst->nr_cbufs != src->nr_cbufs) {
+ return FALSE;
+ }
+
+ if (dst->zsbuf != src->zsbuf) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/**
+ * Copy framebuffer state from src to dst, updating refcounts.
+ */
+void
+util_copy_framebuffer_state(struct pipe_framebuffer_state *dst,
+ const struct pipe_framebuffer_state *src)
+{
+ unsigned i;
+
+ dst->width = src->width;
+ dst->height = src->height;
+
+ for (i = 0; i < Elements(src->cbufs); i++) {
+ pipe_surface_reference(&dst->cbufs[i], src->cbufs[i]);
+ }
+
+ dst->nr_cbufs = src->nr_cbufs;
+
+ pipe_surface_reference(&dst->zsbuf, src->zsbuf);
+}
+
+
+void
+util_unreference_framebuffer_state(struct pipe_framebuffer_state *fb)
+{
+ unsigned i;
+
+ for (i = 0; i < fb->nr_cbufs; i++) {
+ pipe_surface_reference(&fb->cbufs[i], NULL);
+ }
+
+ pipe_surface_reference(&fb->zsbuf, NULL);
+
+ fb->width = fb->height = 0;
+ fb->nr_cbufs = 0;
+}
diff --git a/src/gallium/auxiliary/util/u_framebuffer.h b/src/gallium/auxiliary/util/u_framebuffer.h
new file mode 100644
index 00000000000..adf1254e1b6
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_framebuffer.h
@@ -0,0 +1,49 @@
+/**************************************************************************
+ *
+ * Copyright 2009-2010 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 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 VMWARE 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_FRAMEBUFFER_H
+#define U_FRAMEBUFFER_H
+
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_state.h"
+
+
+extern boolean
+util_framebuffer_state_equal(const struct pipe_framebuffer_state *dst,
+ const struct pipe_framebuffer_state *src);
+
+extern void
+util_copy_framebuffer_state(struct pipe_framebuffer_state *dst,
+ const struct pipe_framebuffer_state *src);
+
+
+extern void
+util_unreference_framebuffer_state(struct pipe_framebuffer_state *fb);
+
+
+#endif /* U_FRAMEBUFFER_H */
diff --git a/src/gallium/auxiliary/util/u_rect.c b/src/gallium/auxiliary/util/u_rect.c
index 098cdfd58b1..9bbcf1c8c49 100644
--- a/src/gallium/auxiliary/util/u_rect.c
+++ b/src/gallium/auxiliary/util/u_rect.c
@@ -30,12 +30,7 @@
*/
-#include "pipe/p_defines.h"
-#include "pipe/p_format.h"
-#include "pipe/p_context.h"
-#include "pipe/p_screen.h"
#include "util/u_format.h"
-#include "util/u_inlines.h"
#include "util/u_rect.h"
@@ -152,156 +147,3 @@ util_fill_rect(ubyte * dst,
break;
}
}
-
-
-
-/**
- * Fallback function for pipe->surface_copy().
- * Note: (X,Y)=(0,0) is always the upper-left corner.
- * if do_flip, flip the image vertically on its way from src rect to dst rect.
- * XXX should probably put this in new u_surface.c file...
- */
-void
-util_surface_copy(struct pipe_context *pipe,
- boolean do_flip,
- struct pipe_surface *dst,
- unsigned dst_x, unsigned dst_y,
- struct pipe_surface *src,
- unsigned src_x, unsigned src_y,
- unsigned w, unsigned h)
-{
- struct pipe_transfer *src_trans, *dst_trans;
- void *dst_map;
- const void *src_map;
- enum pipe_format src_format, dst_format;
-
- assert(src->texture && dst->texture);
- if (!src->texture || !dst->texture)
- return;
-
- src_format = src->texture->format;
- dst_format = dst->texture->format;
-
- src_trans = pipe_get_transfer(pipe,
- src->texture,
- src->face,
- src->level,
- src->zslice,
- PIPE_TRANSFER_READ,
- src_x, src_y, w, h);
-
- dst_trans = pipe_get_transfer(pipe,
- dst->texture,
- dst->face,
- dst->level,
- dst->zslice,
- PIPE_TRANSFER_WRITE,
- dst_x, dst_y, w, h);
-
- 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->transfer_map(pipe, src_trans);
- dst_map = pipe->transfer_map(pipe, dst_trans);
-
- assert(src_map);
- assert(dst_map);
-
- if (src_map && dst_map) {
- /* If do_flip, invert src_y position and pass negative src stride */
- util_copy_rect(dst_map,
- dst_format,
- dst_trans->stride,
- 0, 0,
- w, h,
- src_map,
- do_flip ? -(int) src_trans->stride : src_trans->stride,
- 0,
- do_flip ? h - 1 : 0);
- }
-
- pipe->transfer_unmap(pipe, src_trans);
- pipe->transfer_unmap(pipe, dst_trans);
-
- pipe->transfer_destroy(pipe, src_trans);
- pipe->transfer_destroy(pipe, dst_trans);
-}
-
-
-
-#define UBYTE_TO_USHORT(B) ((B) | ((B) << 8))
-
-
-/**
- * Fallback for pipe->surface_fill() function.
- * XXX should probably put this in new u_surface.c file...
- */
-void
-util_surface_fill(struct pipe_context *pipe,
- struct pipe_surface *dst,
- unsigned dstx, unsigned dsty,
- unsigned width, unsigned height, unsigned value)
-{
- struct pipe_transfer *dst_trans;
- void *dst_map;
-
- assert(dst->texture);
- if (!dst->texture)
- return;
- dst_trans = pipe_get_transfer(pipe,
- dst->texture,
- dst->face,
- dst->level,
- dst->zslice,
- PIPE_TRANSFER_WRITE,
- dstx, dsty, width, height);
-
- dst_map = pipe->transfer_map(pipe, dst_trans);
-
- assert(dst_map);
-
- if (dst_map) {
- assert(dst_trans->stride > 0);
-
- switch (util_format_get_blocksize(dst->texture->format)) {
- case 1:
- case 2:
- case 4:
- util_fill_rect(dst_map, dst->texture->format,
- dst_trans->stride,
- 0, 0, width, height, value);
- break;
- case 8:
- {
- /* expand the 4-byte clear value to an 8-byte value */
- ushort *row = (ushort *) dst_map;
- ushort val0 = UBYTE_TO_USHORT((value >> 0) & 0xff);
- ushort val1 = UBYTE_TO_USHORT((value >> 8) & 0xff);
- ushort val2 = UBYTE_TO_USHORT((value >> 16) & 0xff);
- ushort val3 = UBYTE_TO_USHORT((value >> 24) & 0xff);
- unsigned i, j;
- val0 = (val0 << 8) | val0;
- val1 = (val1 << 8) | val1;
- val2 = (val2 << 8) | val2;
- val3 = (val3 << 8) | val3;
- for (i = 0; i < height; i++) {
- for (j = 0; j < width; j++) {
- row[j*4+0] = val0;
- row[j*4+1] = val1;
- row[j*4+2] = val2;
- row[j*4+3] = val3;
- }
- row += dst_trans->stride/2;
- }
- }
- break;
- default:
- assert(0);
- break;
- }
- }
-
- pipe->transfer_unmap(pipe, dst_trans);
- pipe->transfer_destroy(pipe, dst_trans);
-}
diff --git a/src/gallium/auxiliary/util/u_rect.h b/src/gallium/auxiliary/util/u_rect.h
index b44d821904b..40d57e662d7 100644
--- a/src/gallium/auxiliary/util/u_rect.h
+++ b/src/gallium/auxiliary/util/u_rect.h
@@ -37,9 +37,6 @@
#include "pipe/p_format.h"
-struct pipe_context;
-struct pipe_surface;
-
extern void
util_copy_rect(ubyte * dst, enum pipe_format format,
@@ -53,20 +50,4 @@ util_fill_rect(ubyte * dst, enum pipe_format format,
unsigned width, unsigned height, uint32_t value);
-extern void
-util_surface_copy(struct pipe_context *pipe,
- boolean do_flip,
- struct pipe_surface *dst,
- unsigned dst_x, unsigned dst_y,
- struct pipe_surface *src,
- unsigned src_x, unsigned src_y,
- unsigned w, unsigned h);
-
-extern void
-util_surface_fill(struct pipe_context *pipe,
- struct pipe_surface *dst,
- unsigned dstx, unsigned dsty,
- unsigned width, unsigned height, unsigned value);
-
-
#endif /* U_RECT_H */
diff --git a/src/gallium/auxiliary/util/u_surface.c b/src/gallium/auxiliary/util/u_surface.c
index 42440d0d673..b47c92ca28f 100644
--- a/src/gallium/auxiliary/util/u_surface.c
+++ b/src/gallium/auxiliary/util/u_surface.c
@@ -32,12 +32,14 @@
*/
+#include "pipe/p_defines.h"
#include "pipe/p_screen.h"
#include "pipe/p_state.h"
-#include "pipe/p_defines.h"
-#include "util/u_inlines.h"
+#include "util/u_format.h"
+#include "util/u_inlines.h"
#include "util/u_memory.h"
+#include "util/u_rect.h"
#include "util/u_surface.h"
@@ -118,70 +120,150 @@ util_destroy_rgba_surface(struct pipe_resource *texture,
/**
- * Compare pipe_framebuffer_state objects.
- * \return TRUE if same, FALSE if different
+ * Fallback function for pipe->surface_copy().
+ * Note: (X,Y)=(0,0) is always the upper-left corner.
+ * if do_flip, flip the image vertically on its way from src rect to dst rect.
*/
-boolean
-util_framebuffer_state_equal(const struct pipe_framebuffer_state *dst,
- const struct pipe_framebuffer_state *src)
+void
+util_surface_copy(struct pipe_context *pipe,
+ boolean do_flip,
+ struct pipe_surface *dst,
+ unsigned dst_x, unsigned dst_y,
+ struct pipe_surface *src,
+ unsigned src_x, unsigned src_y,
+ unsigned w, unsigned h)
{
- unsigned i;
-
- if (dst->width != src->width ||
- dst->height != src->height)
- return FALSE;
-
- for (i = 0; i < Elements(src->cbufs); i++) {
- if (dst->cbufs[i] != src->cbufs[i]) {
- return FALSE;
- }
- }
-
- if (dst->nr_cbufs != src->nr_cbufs) {
- return FALSE;
+ struct pipe_transfer *src_trans, *dst_trans;
+ void *dst_map;
+ const void *src_map;
+ enum pipe_format src_format, dst_format;
+
+ assert(src->texture && dst->texture);
+ if (!src->texture || !dst->texture)
+ return;
+
+ src_format = src->texture->format;
+ dst_format = dst->texture->format;
+
+ src_trans = pipe_get_transfer(pipe,
+ src->texture,
+ src->face,
+ src->level,
+ src->zslice,
+ PIPE_TRANSFER_READ,
+ src_x, src_y, w, h);
+
+ dst_trans = pipe_get_transfer(pipe,
+ dst->texture,
+ dst->face,
+ dst->level,
+ dst->zslice,
+ PIPE_TRANSFER_WRITE,
+ dst_x, dst_y, w, h);
+
+ 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->transfer_map(pipe, src_trans);
+ dst_map = pipe->transfer_map(pipe, dst_trans);
+
+ assert(src_map);
+ assert(dst_map);
+
+ if (src_map && dst_map) {
+ /* If do_flip, invert src_y position and pass negative src stride */
+ util_copy_rect(dst_map,
+ dst_format,
+ dst_trans->stride,
+ 0, 0,
+ w, h,
+ src_map,
+ do_flip ? -(int) src_trans->stride : src_trans->stride,
+ 0,
+ do_flip ? h - 1 : 0);
}
- if (dst->zsbuf != src->zsbuf) {
- return FALSE;
- }
+ pipe->transfer_unmap(pipe, src_trans);
+ pipe->transfer_unmap(pipe, dst_trans);
- return TRUE;
+ pipe->transfer_destroy(pipe, src_trans);
+ pipe->transfer_destroy(pipe, dst_trans);
}
-/**
- * Copy framebuffer state from src to dst, updating refcounts.
- */
-void
-util_copy_framebuffer_state(struct pipe_framebuffer_state *dst,
- const struct pipe_framebuffer_state *src)
-{
- unsigned i;
-
- dst->width = src->width;
- dst->height = src->height;
- for (i = 0; i < Elements(src->cbufs); i++) {
- pipe_surface_reference(&dst->cbufs[i], src->cbufs[i]);
- }
-
- dst->nr_cbufs = src->nr_cbufs;
-
- pipe_surface_reference(&dst->zsbuf, src->zsbuf);
-}
+#define UBYTE_TO_USHORT(B) ((B) | ((B) << 8))
+/**
+ * Fallback for pipe->surface_fill() function.
+ */
void
-util_unreference_framebuffer_state(struct pipe_framebuffer_state *fb)
+util_surface_fill(struct pipe_context *pipe,
+ struct pipe_surface *dst,
+ unsigned dstx, unsigned dsty,
+ unsigned width, unsigned height, unsigned value)
{
- unsigned i;
-
- for (i = 0; i < fb->nr_cbufs; i++) {
- pipe_surface_reference(&fb->cbufs[i], NULL);
+ struct pipe_transfer *dst_trans;
+ void *dst_map;
+
+ assert(dst->texture);
+ if (!dst->texture)
+ return;
+ dst_trans = pipe_get_transfer(pipe,
+ dst->texture,
+ dst->face,
+ dst->level,
+ dst->zslice,
+ PIPE_TRANSFER_WRITE,
+ dstx, dsty, width, height);
+
+ dst_map = pipe->transfer_map(pipe, dst_trans);
+
+ assert(dst_map);
+
+ if (dst_map) {
+ assert(dst_trans->stride > 0);
+
+ switch (util_format_get_blocksize(dst->texture->format)) {
+ case 1:
+ case 2:
+ case 4:
+ util_fill_rect(dst_map, dst->texture->format,
+ dst_trans->stride,
+ 0, 0, width, height, value);
+ break;
+ case 8:
+ {
+ /* expand the 4-byte clear value to an 8-byte value */
+ ushort *row = (ushort *) dst_map;
+ ushort val0 = UBYTE_TO_USHORT((value >> 0) & 0xff);
+ ushort val1 = UBYTE_TO_USHORT((value >> 8) & 0xff);
+ ushort val2 = UBYTE_TO_USHORT((value >> 16) & 0xff);
+ ushort val3 = UBYTE_TO_USHORT((value >> 24) & 0xff);
+ unsigned i, j;
+ val0 = (val0 << 8) | val0;
+ val1 = (val1 << 8) | val1;
+ val2 = (val2 << 8) | val2;
+ val3 = (val3 << 8) | val3;
+ for (i = 0; i < height; i++) {
+ for (j = 0; j < width; j++) {
+ row[j*4+0] = val0;
+ row[j*4+1] = val1;
+ row[j*4+2] = val2;
+ row[j*4+3] = val3;
+ }
+ row += dst_trans->stride/2;
+ }
+ }
+ break;
+ default:
+ assert(0);
+ break;
+ }
}
- pipe_surface_reference(&fb->zsbuf, NULL);
-
- fb->width = fb->height = 0;
- fb->nr_cbufs = 0;
+ pipe->transfer_unmap(pipe, dst_trans);
+ pipe->transfer_destroy(pipe, dst_trans);
}
diff --git a/src/gallium/auxiliary/util/u_surface.h b/src/gallium/auxiliary/util/u_surface.h
index 119fcd4ce8e..c43169b5278 100644
--- a/src/gallium/auxiliary/util/u_surface.h
+++ b/src/gallium/auxiliary/util/u_surface.h
@@ -62,17 +62,22 @@ util_destroy_rgba_surface(struct pipe_resource *texture,
struct pipe_surface *surface);
-extern boolean
-util_framebuffer_state_equal(const struct pipe_framebuffer_state *dst,
- const struct pipe_framebuffer_state *src);
extern void
-util_copy_framebuffer_state(struct pipe_framebuffer_state *dst,
- const struct pipe_framebuffer_state *src);
-
+util_surface_copy(struct pipe_context *pipe,
+ boolean do_flip,
+ struct pipe_surface *dst,
+ unsigned dst_x, unsigned dst_y,
+ struct pipe_surface *src,
+ unsigned src_x, unsigned src_y,
+ unsigned w, unsigned h);
extern void
-util_unreference_framebuffer_state(struct pipe_framebuffer_state *fb);
+util_surface_fill(struct pipe_context *pipe,
+ struct pipe_surface *dst,
+ unsigned dstx, unsigned dsty,
+ unsigned width, unsigned height, unsigned value);
+
#endif /* U_SURFACE_H */