summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>2008-12-30 17:11:32 -0700
committerBrian Paul <[email protected]>2008-12-30 17:11:32 -0700
commitc6537ac8b8130cf2271c8d1e51137a575073c762 (patch)
treed51e85841d71823d778a61ade9890af7bf4f24c2
parentca0540e25c86b8095511868b0cbe96d7e85f7437 (diff)
mesa: allow variable indexing into the predefined uniform variable arrays
This allows code such as "vec4 a = gl_LightSource[i].ambient;" to work. When a built-in uniform array is indexed with a variable index we need to "unroll" the whole array into the parameter list (aka constant buffer) because we don't know which elements may be accessed at compile-time. In the case of the gl_LightSource array of size [8], we emit 64 state references into the parameter array (8 elements times 8 vec4s per gl_LightSourceParameters struct). Previously, we only allowed constant-indexed references to uniform arrays (such as gl_LightSource[2].position) which resulted in a single state reference being added to the parameter array, not 64. We still optimize this case. Users should be aware that using "gl_LightSource[i].ambient" in their shaders is a bit expensive since state validation will involve updating all 64 light source entries in the parameter list.
-rw-r--r--src/mesa/shader/slang/library/slang_common_builtin.gc12
-rw-r--r--src/mesa/shader/slang/library/slang_common_builtin_gc.h102
-rw-r--r--src/mesa/shader/slang/slang_builtin.c299
-rw-r--r--src/mesa/shader/slang/slang_builtin.h3
-rw-r--r--src/mesa/shader/slang/slang_emit.c51
5 files changed, 376 insertions, 91 deletions
diff --git a/src/mesa/shader/slang/library/slang_common_builtin.gc b/src/mesa/shader/slang/library/slang_common_builtin.gc
index a051c53eea3..3e03b101b87 100644
--- a/src/mesa/shader/slang/library/slang_common_builtin.gc
+++ b/src/mesa/shader/slang/library/slang_common_builtin.gc
@@ -1,8 +1,9 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5
+ * Version: 7.3
*
* Copyright (C) 2006 Brian Paul All Rights Reserved.
+ * Copyright (C) 2008 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"),
@@ -98,6 +99,9 @@ struct gl_MaterialParameters {
uniform gl_MaterialParameters gl_FrontMaterial;
uniform gl_MaterialParameters gl_BackMaterial;
+/* NOTE: the order of these fields is significant!
+ * See the definition of the lighting state vars such as STATE_SPOT_DIRECTION.
+ */
struct gl_LightSourceParameters {
vec4 ambient;
vec4 diffuse;
@@ -105,12 +109,14 @@ struct gl_LightSourceParameters {
vec4 position;
vec4 halfVector;
vec3 spotDirection;
- float spotExponent;
- float spotCutoff;
float spotCosCutoff;
+
float constantAttenuation;
float linearAttenuation;
float quadraticAttenuation;
+ float spotExponent;
+
+ float spotCutoff;
};
uniform gl_LightSourceParameters gl_LightSource[gl_MaxLights];
diff --git a/src/mesa/shader/slang/library/slang_common_builtin_gc.h b/src/mesa/shader/slang/library/slang_common_builtin_gc.h
index 46632010815..759bf247d80 100644
--- a/src/mesa/shader/slang/library/slang_common_builtin_gc.h
+++ b/src/mesa/shader/slang/library/slang_common_builtin_gc.h
@@ -66,58 +66,58 @@
116,83,111,117,114,99,101,80,97,114,97,109,101,116,101,114,115,0,12,0,97,109,98,105,101,110,116,0,
0,0,1,12,0,100,105,102,102,117,115,101,0,0,0,1,12,0,115,112,101,99,117,108,97,114,0,0,0,1,12,0,112,
111,115,105,116,105,111,110,0,0,0,1,12,0,104,97,108,102,86,101,99,116,111,114,0,0,0,1,11,0,115,112,
-111,116,68,105,114,101,99,116,105,111,110,0,0,0,1,9,0,115,112,111,116,69,120,112,111,110,101,110,
-116,0,0,0,1,9,0,115,112,111,116,67,117,116,111,102,102,0,0,0,1,9,0,115,112,111,116,67,111,115,67,
-117,116,111,102,102,0,0,0,1,9,0,99,111,110,115,116,97,110,116,65,116,116,101,110,117,97,116,105,
-111,110,0,0,0,1,9,0,108,105,110,101,97,114,65,116,116,101,110,117,97,116,105,111,110,0,0,0,1,9,0,
-113,117,97,100,114,97,116,105,99,65,116,116,101,110,117,97,116,105,111,110,0,0,0,0,0,0,0,2,2,90,95,
-4,0,25,103,108,95,76,105,103,104,116,83,111,117,114,99,101,80,97,114,97,109,101,116,101,114,115,0,
-0,1,103,108,95,76,105,103,104,116,83,111,117,114,99,101,0,3,18,103,108,95,77,97,120,76,105,103,104,
-116,115,0,0,0,2,2,90,95,0,0,24,103,108,95,76,105,103,104,116,77,111,100,101,108,80,97,114,97,109,
-101,116,101,114,115,0,12,0,97,109,98,105,101,110,116,0,0,0,0,0,0,0,2,2,90,95,4,0,25,103,108,95,76,
-105,103,104,116,77,111,100,101,108,80,97,114,97,109,101,116,101,114,115,0,0,1,103,108,95,76,105,
-103,104,116,77,111,100,101,108,0,0,0,2,2,90,95,0,0,24,103,108,95,76,105,103,104,116,77,111,100,101,
-108,80,114,111,100,117,99,116,115,0,12,0,115,99,101,110,101,67,111,108,111,114,0,0,0,0,0,0,0,2,2,
-90,95,4,0,25,103,108,95,76,105,103,104,116,77,111,100,101,108,80,114,111,100,117,99,116,115,0,0,1,
-103,108,95,70,114,111,110,116,76,105,103,104,116,77,111,100,101,108,80,114,111,100,117,99,116,0,0,
-0,2,2,90,95,4,0,25,103,108,95,76,105,103,104,116,77,111,100,101,108,80,114,111,100,117,99,116,115,
-0,0,1,103,108,95,66,97,99,107,76,105,103,104,116,77,111,100,101,108,80,114,111,100,117,99,116,0,0,
-0,2,2,90,95,0,0,24,103,108,95,76,105,103,104,116,80,114,111,100,117,99,116,115,0,12,0,97,109,98,
-105,101,110,116,0,0,0,1,12,0,100,105,102,102,117,115,101,0,0,0,1,12,0,115,112,101,99,117,108,97,
-114,0,0,0,0,0,0,0,2,2,90,95,4,0,25,103,108,95,76,105,103,104,116,80,114,111,100,117,99,116,115,0,0,
-1,103,108,95,70,114,111,110,116,76,105,103,104,116,80,114,111,100,117,99,116,0,3,18,103,108,95,77,
-97,120,76,105,103,104,116,115,0,0,0,2,2,90,95,4,0,25,103,108,95,76,105,103,104,116,80,114,111,100,
-117,99,116,115,0,0,1,103,108,95,66,97,99,107,76,105,103,104,116,80,114,111,100,117,99,116,0,3,18,
-103,108,95,77,97,120,76,105,103,104,116,115,0,0,0,2,2,90,95,4,0,12,0,1,103,108,95,84,101,120,116,
-117,114,101,69,110,118,67,111,108,111,114,0,3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,
-73,109,97,103,101,85,110,105,116,115,0,0,0,2,2,90,95,4,0,12,0,1,103,108,95,69,121,101,80,108,97,
+111,116,68,105,114,101,99,116,105,111,110,0,0,0,1,9,0,115,112,111,116,67,111,115,67,117,116,111,
+102,102,0,0,0,1,9,0,99,111,110,115,116,97,110,116,65,116,116,101,110,117,97,116,105,111,110,0,0,0,
+1,9,0,108,105,110,101,97,114,65,116,116,101,110,117,97,116,105,111,110,0,0,0,1,9,0,113,117,97,100,
+114,97,116,105,99,65,116,116,101,110,117,97,116,105,111,110,0,0,0,1,9,0,115,112,111,116,69,120,112,
+111,110,101,110,116,0,0,0,1,9,0,115,112,111,116,67,117,116,111,102,102,0,0,0,0,0,0,0,2,2,90,95,4,0,
+25,103,108,95,76,105,103,104,116,83,111,117,114,99,101,80,97,114,97,109,101,116,101,114,115,0,0,1,
+103,108,95,76,105,103,104,116,83,111,117,114,99,101,0,3,18,103,108,95,77,97,120,76,105,103,104,116,
+115,0,0,0,2,2,90,95,0,0,24,103,108,95,76,105,103,104,116,77,111,100,101,108,80,97,114,97,109,101,
+116,101,114,115,0,12,0,97,109,98,105,101,110,116,0,0,0,0,0,0,0,2,2,90,95,4,0,25,103,108,95,76,105,
+103,104,116,77,111,100,101,108,80,97,114,97,109,101,116,101,114,115,0,0,1,103,108,95,76,105,103,
+104,116,77,111,100,101,108,0,0,0,2,2,90,95,0,0,24,103,108,95,76,105,103,104,116,77,111,100,101,108,
+80,114,111,100,117,99,116,115,0,12,0,115,99,101,110,101,67,111,108,111,114,0,0,0,0,0,0,0,2,2,90,95,
+4,0,25,103,108,95,76,105,103,104,116,77,111,100,101,108,80,114,111,100,117,99,116,115,0,0,1,103,
+108,95,70,114,111,110,116,76,105,103,104,116,77,111,100,101,108,80,114,111,100,117,99,116,0,0,0,2,
+2,90,95,4,0,25,103,108,95,76,105,103,104,116,77,111,100,101,108,80,114,111,100,117,99,116,115,0,0,
+1,103,108,95,66,97,99,107,76,105,103,104,116,77,111,100,101,108,80,114,111,100,117,99,116,0,0,0,2,
+2,90,95,0,0,24,103,108,95,76,105,103,104,116,80,114,111,100,117,99,116,115,0,12,0,97,109,98,105,
+101,110,116,0,0,0,1,12,0,100,105,102,102,117,115,101,0,0,0,1,12,0,115,112,101,99,117,108,97,114,0,
+0,0,0,0,0,0,2,2,90,95,4,0,25,103,108,95,76,105,103,104,116,80,114,111,100,117,99,116,115,0,0,1,103,
+108,95,70,114,111,110,116,76,105,103,104,116,80,114,111,100,117,99,116,0,3,18,103,108,95,77,97,120,
+76,105,103,104,116,115,0,0,0,2,2,90,95,4,0,25,103,108,95,76,105,103,104,116,80,114,111,100,117,99,
+116,115,0,0,1,103,108,95,66,97,99,107,76,105,103,104,116,80,114,111,100,117,99,116,0,3,18,103,108,
+95,77,97,120,76,105,103,104,116,115,0,0,0,2,2,90,95,4,0,12,0,1,103,108,95,84,101,120,116,117,114,
+101,69,110,118,67,111,108,111,114,0,3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,73,109,97,
+103,101,85,110,105,116,115,0,0,0,2,2,90,95,4,0,12,0,1,103,108,95,69,121,101,80,108,97,110,101,83,0,
+3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,67,111,111,114,100,115,0,0,0,2,2,90,95,4,0,12,
+0,1,103,108,95,69,121,101,80,108,97,110,101,84,0,3,18,103,108,95,77,97,120,84,101,120,116,117,114,
+101,67,111,111,114,100,115,0,0,0,2,2,90,95,4,0,12,0,1,103,108,95,69,121,101,80,108,97,110,101,82,0,
+3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,67,111,111,114,100,115,0,0,0,2,2,90,95,4,0,12,
+0,1,103,108,95,69,121,101,80,108,97,110,101,81,0,3,18,103,108,95,77,97,120,84,101,120,116,117,114,
+101,67,111,111,114,100,115,0,0,0,2,2,90,95,4,0,12,0,1,103,108,95,79,98,106,101,99,116,80,108,97,
110,101,83,0,3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,67,111,111,114,100,115,0,0,0,2,2,
-90,95,4,0,12,0,1,103,108,95,69,121,101,80,108,97,110,101,84,0,3,18,103,108,95,77,97,120,84,101,120,
-116,117,114,101,67,111,111,114,100,115,0,0,0,2,2,90,95,4,0,12,0,1,103,108,95,69,121,101,80,108,97,
-110,101,82,0,3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,67,111,111,114,100,115,0,0,0,2,2,
-90,95,4,0,12,0,1,103,108,95,69,121,101,80,108,97,110,101,81,0,3,18,103,108,95,77,97,120,84,101,120,
-116,117,114,101,67,111,111,114,100,115,0,0,0,2,2,90,95,4,0,12,0,1,103,108,95,79,98,106,101,99,116,
-80,108,97,110,101,83,0,3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,67,111,111,114,100,115,
-0,0,0,2,2,90,95,4,0,12,0,1,103,108,95,79,98,106,101,99,116,80,108,97,110,101,84,0,3,18,103,108,95,
-77,97,120,84,101,120,116,117,114,101,67,111,111,114,100,115,0,0,0,2,2,90,95,4,0,12,0,1,103,108,95,
-79,98,106,101,99,116,80,108,97,110,101,82,0,3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,
-67,111,111,114,100,115,0,0,0,2,2,90,95,4,0,12,0,1,103,108,95,79,98,106,101,99,116,80,108,97,110,
-101,81,0,3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,67,111,111,114,100,115,0,0,0,2,2,90,
-95,0,0,24,103,108,95,70,111,103,80,97,114,97,109,101,116,101,114,115,0,12,0,99,111,108,111,114,0,0,
-0,1,9,0,100,101,110,115,105,116,121,0,0,0,1,9,0,115,116,97,114,116,0,0,0,1,9,0,101,110,100,0,0,0,1,
-9,0,115,99,97,108,101,0,0,0,0,0,0,0,2,2,90,95,4,0,25,103,108,95,70,111,103,80,97,114,97,109,101,
-116,101,114,115,0,0,1,103,108,95,70,111,103,0,0,0,1,90,95,0,0,9,0,0,114,97,100,105,97,110,115,0,1,
-1,0,0,9,0,100,101,103,0,0,0,1,3,2,90,95,1,0,9,0,1,99,0,2,17,51,0,49,52,49,53,57,50,54,0,0,17,49,56,
-48,0,48,0,0,49,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,95,95,114,101,116,86,97,
-108,0,0,18,100,101,103,0,0,18,99,0,0,0,0,1,90,95,0,0,10,0,0,114,97,100,105,97,110,115,0,1,1,0,0,10,
-0,100,101,103,0,0,0,1,3,2,90,95,1,0,9,0,1,99,0,2,17,51,0,49,52,49,53,57,50,54,0,0,17,49,56,48,0,48,
-0,0,49,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,95,95,114,101,116,86,97,108,0,
-59,120,121,0,0,18,100,101,103,0,59,120,121,0,0,18,99,0,59,120,120,0,0,0,0,1,90,95,0,0,11,0,0,114,
-97,100,105,97,110,115,0,1,1,0,0,11,0,100,101,103,0,0,0,1,3,2,90,95,1,0,9,0,1,99,0,2,17,51,0,49,52,
-49,53,57,50,54,0,0,17,49,56,48,0,48,0,0,49,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,
-0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,100,101,103,0,59,120,121,122,0,0,18,99,0,
-59,120,120,120,0,0,0,0,1,90,95,0,0,12,0,0,114,97,100,105,97,110,115,0,1,1,0,0,12,0,100,101,103,0,0,
-0,1,3,2,90,95,1,0,9,0,1,99,0,2,17,51,0,49,52,49,53,57,50,54,0,0,17,49,56,48,0,48,0,0,49,0,0,4,118,
+90,95,4,0,12,0,1,103,108,95,79,98,106,101,99,116,80,108,97,110,101,84,0,3,18,103,108,95,77,97,120,
+84,101,120,116,117,114,101,67,111,111,114,100,115,0,0,0,2,2,90,95,4,0,12,0,1,103,108,95,79,98,106,
+101,99,116,80,108,97,110,101,82,0,3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,67,111,111,
+114,100,115,0,0,0,2,2,90,95,4,0,12,0,1,103,108,95,79,98,106,101,99,116,80,108,97,110,101,81,0,3,18,
+103,108,95,77,97,120,84,101,120,116,117,114,101,67,111,111,114,100,115,0,0,0,2,2,90,95,0,0,24,103,
+108,95,70,111,103,80,97,114,97,109,101,116,101,114,115,0,12,0,99,111,108,111,114,0,0,0,1,9,0,100,
+101,110,115,105,116,121,0,0,0,1,9,0,115,116,97,114,116,0,0,0,1,9,0,101,110,100,0,0,0,1,9,0,115,99,
+97,108,101,0,0,0,0,0,0,0,2,2,90,95,4,0,25,103,108,95,70,111,103,80,97,114,97,109,101,116,101,114,
+115,0,0,1,103,108,95,70,111,103,0,0,0,1,90,95,0,0,9,0,0,114,97,100,105,97,110,115,0,1,1,0,0,9,0,
+100,101,103,0,0,0,1,3,2,90,95,1,0,9,0,1,99,0,2,17,51,0,49,52,49,53,57,50,54,0,0,17,49,56,48,0,48,0,
+0,49,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,95,95,114,101,116,86,97,108,0,0,
+18,100,101,103,0,0,18,99,0,0,0,0,1,90,95,0,0,10,0,0,114,97,100,105,97,110,115,0,1,1,0,0,10,0,100,
+101,103,0,0,0,1,3,2,90,95,1,0,9,0,1,99,0,2,17,51,0,49,52,49,53,57,50,54,0,0,17,49,56,48,0,48,0,0,
+49,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,95,95,114,101,116,86,97,108,0,59,
+120,121,0,0,18,100,101,103,0,59,120,121,0,0,18,99,0,59,120,120,0,0,0,0,1,90,95,0,0,11,0,0,114,97,
+100,105,97,110,115,0,1,1,0,0,11,0,100,101,103,0,0,0,1,3,2,90,95,1,0,9,0,1,99,0,2,17,51,0,49,52,49,
+53,57,50,54,0,0,17,49,56,48,0,48,0,0,49,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,
+18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,100,101,103,0,59,120,121,122,0,0,18,99,0,59,
+120,120,120,0,0,0,0,1,90,95,0,0,12,0,0,114,97,100,105,97,110,115,0,1,1,0,0,12,0,100,101,103,0,0,0,
+1,3,2,90,95,1,0,9,0,1,99,0,2,17,51,0,49,52,49,53,57,50,54,0,0,17,49,56,48,0,48,0,0,49,0,0,4,118,
101,99,52,95,109,117,108,116,105,112,108,121,0,18,95,95,114,101,116,86,97,108,0,0,18,100,101,103,0,
0,18,99,0,59,120,120,120,120,0,0,0,0,1,90,95,0,0,9,0,0,100,101,103,114,101,101,115,0,1,1,0,0,9,0,
114,97,100,0,0,0,1,3,2,90,95,1,0,9,0,1,99,0,2,17,49,56,48,0,48,0,0,17,51,0,49,52,49,53,57,50,54,0,
diff --git a/src/mesa/shader/slang/slang_builtin.c b/src/mesa/shader/slang/slang_builtin.c
index db00c54b8a2..c0f4c79e136 100644
--- a/src/mesa/shader/slang/slang_builtin.c
+++ b/src/mesa/shader/slang/slang_builtin.c
@@ -1,8 +1,9 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5.3
+ * Version: 7.3
*
* Copyright (C) 2005-2007 Brian Paul All Rights Reserved.
+ * Copyright (C) 2008 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"),
@@ -39,6 +40,10 @@
#include "shader/slang/slang_builtin.h"
+/** special state token (see below) */
+#define STATE_ARRAY ((gl_state_index) 0xfffff)
+
+
/**
* Lookup GL state given a variable name, 0, 1 or 2 indexes and a field.
* Allocate room for the state in the given param list and return position
@@ -132,6 +137,8 @@ lookup_statevar(const char *var, GLint index1, GLint index2, const char *field,
}
}
else if (strcmp(var, "gl_ClipPlane") == 0) {
+ if (index1 < 0)
+ return -1;
tokens[0] = STATE_CLIPPLANE;
tokens[1] = index1;
}
@@ -196,8 +203,12 @@ lookup_statevar(const char *var, GLint index1, GLint index2, const char *field,
}
}
else if (strcmp(var, "gl_LightSource") == 0) {
+ if (!field || index1 < 0)
+ return -1;
+
tokens[0] = STATE_LIGHT;
tokens[1] = index1;
+
if (strcmp(field, "ambient") == 0) {
tokens[2] = STATE_AMBIENT;
}
@@ -272,6 +283,9 @@ lookup_statevar(const char *var, GLint index1, GLint index2, const char *field,
}
else if (strcmp(var, "gl_FrontLightProduct") == 0 ||
strcmp(var, "gl_BackLightProduct") == 0) {
+ if (index1 < 0 || !field)
+ return -1;
+
tokens[0] = STATE_LIGHTPROD;
tokens[1] = index1; /* light number */
if (strcmp(var, "gl_FrontLightProduct") == 0) {
@@ -294,45 +308,63 @@ lookup_statevar(const char *var, GLint index1, GLint index2, const char *field,
}
}
else if (strcmp(var, "gl_TextureEnvColor") == 0) {
+ if (index1 < 0)
+ return -1;
tokens[0] = STATE_TEXENV_COLOR;
tokens[1] = index1;
}
else if (strcmp(var, "gl_EyePlaneS") == 0) {
+ if (index1 < 0)
+ return -1;
tokens[0] = STATE_TEXGEN;
tokens[1] = index1; /* tex unit */
tokens[2] = STATE_TEXGEN_EYE_S;
}
else if (strcmp(var, "gl_EyePlaneT") == 0) {
+ if (index1 < 0)
+ return -1;
tokens[0] = STATE_TEXGEN;
tokens[1] = index1; /* tex unit */
tokens[2] = STATE_TEXGEN_EYE_T;
}
else if (strcmp(var, "gl_EyePlaneR") == 0) {
+ if (index1 < 0)
+ return -1;
tokens[0] = STATE_TEXGEN;
tokens[1] = index1; /* tex unit */
tokens[2] = STATE_TEXGEN_EYE_R;
}
else if (strcmp(var, "gl_EyePlaneQ") == 0) {
+ if (index1 < 0)
+ return -1;
tokens[0] = STATE_TEXGEN;
tokens[1] = index1; /* tex unit */
tokens[2] = STATE_TEXGEN_EYE_Q;
}
else if (strcmp(var, "gl_ObjectPlaneS") == 0) {
+ if (index1 < 0)
+ return -1;
tokens[0] = STATE_TEXGEN;
tokens[1] = index1; /* tex unit */
tokens[2] = STATE_TEXGEN_OBJECT_S;
}
else if (strcmp(var, "gl_ObjectPlaneT") == 0) {
+ if (index1 < 0)
+ return -1;
tokens[0] = STATE_TEXGEN;
tokens[1] = index1; /* tex unit */
tokens[2] = STATE_TEXGEN_OBJECT_T;
}
else if (strcmp(var, "gl_ObjectPlaneR") == 0) {
+ if (index1 < 0)
+ return -1;
tokens[0] = STATE_TEXGEN;
tokens[1] = index1; /* tex unit */
tokens[2] = STATE_TEXGEN_OBJECT_R;
}
else if (strcmp(var, "gl_ObjectPlaneQ") == 0) {
+ if (index1 < 0)
+ return -1;
tokens[0] = STATE_TEXGEN;
tokens[1] = index1; /* tex unit */
tokens[2] = STATE_TEXGEN_OBJECT_Q;
@@ -386,13 +418,222 @@ lookup_statevar(const char *var, GLint index1, GLint index2, const char *field,
}
+
+/**
+ * Given a variable name and datatype, emit uniform/constant buffer
+ * entries which will store that state variable.
+ * For example, if name="gl_LightSource" we'll emit 64 state variable
+ * vectors/references and return position where that data starts. This will
+ * allow run-time array indexing into the light source array.
+ *
+ * Note that this is a recursive function.
+ *
+ * \return -1 if error, else index of start of data in the program parameter list
+ */
+static GLint
+emit_statevars(const char *name, int array_len,
+ const slang_type_specifier *type,
+ gl_state_index tokens[STATE_LENGTH],
+ struct gl_program_parameter_list *paramList)
+{
+ if (type->type == SLANG_SPEC_ARRAY) {
+ GLint i, pos;
+ assert(array_len > 0);
+ if (strcmp(name, "gl_ClipPlane") == 0) {
+ tokens[0] = STATE_CLIPPLANE;
+ }
+ else if (strcmp(name, "gl_LightSource") == 0) {
+ tokens[0] = STATE_LIGHT;
+ }
+ else if (strcmp(name, "gl_FrontLightProduct") == 0) {
+ tokens[0] = STATE_LIGHTPROD;
+ tokens[2] = 0; /* front */
+ }
+ else if (strcmp(name, "gl_BackLightProduct") == 0) {
+ tokens[0] = STATE_LIGHTPROD;
+ tokens[2] = 1; /* back */
+ }
+ else if (strcmp(name, "gl_TextureEnvColor") == 0) {
+ tokens[0] = STATE_TEXENV_COLOR;
+ }
+ else if (strcmp(name, "gl_EyePlaneS") == 0) {
+ tokens[0] = STATE_TEXGEN_EYE_S;
+ }
+ else if (strcmp(name, "gl_EyePlaneT") == 0) {
+ tokens[0] = STATE_TEXGEN_EYE_T;
+ }
+ else if (strcmp(name, "gl_EyePlaneR") == 0) {
+ tokens[0] = STATE_TEXGEN_EYE_R;
+ }
+ else if (strcmp(name, "gl_EyePlaneQ") == 0) {
+ tokens[0] = STATE_TEXGEN_EYE_Q;
+ }
+ else if (strcmp(name, "gl_ObjectPlaneS") == 0) {
+ tokens[0] = STATE_TEXGEN_OBJECT_S;
+ }
+ else if (strcmp(name, "gl_ObjectPlaneT") == 0) {
+ tokens[0] = STATE_TEXGEN_OBJECT_T;
+ }
+ else if (strcmp(name, "gl_ObjectPlaneR") == 0) {
+ tokens[0] = STATE_TEXGEN_OBJECT_R;
+ }
+ else if (strcmp(name, "gl_ObjectPlaneQ") == 0) {
+ tokens[0] = STATE_TEXGEN_OBJECT_Q;
+ }
+ else {
+ return -1; /* invalid array name */
+ }
+ for (i = 0; i < array_len; i++) {
+ GLint p;
+ tokens[1] = i;
+ p = emit_statevars(NULL, 0, type->_array, tokens, paramList);
+ if (i == 0)
+ pos = p;
+ }
+ return pos;
+ }
+ else if (type->type == SLANG_SPEC_STRUCT) {
+ const slang_variable_scope *fields = type->_struct->fields;
+ GLuint i, pos;
+ for (i = 0; i < fields->num_variables; i++) {
+ const slang_variable *var = fields->variables[i];
+ GLint p = emit_statevars(var->a_name, 0, &var->type.specifier,
+ tokens, paramList);
+ if (i == 0)
+ pos = p;
+ }
+ return pos;
+ }
+ else {
+ GLint pos;
+ assert(type->type == SLANG_SPEC_VEC4 ||
+ type->type == SLANG_SPEC_VEC3 ||
+ type->type == SLANG_SPEC_VEC2 ||
+ type->type == SLANG_SPEC_FLOAT ||
+ type->type == SLANG_SPEC_IVEC4 ||
+ type->type == SLANG_SPEC_IVEC3 ||
+ type->type == SLANG_SPEC_IVEC2 ||
+ type->type == SLANG_SPEC_INT);
+ if (name) {
+ GLint t;
+
+ if (tokens[0] == STATE_LIGHT)
+ t = 2;
+ else if (tokens[0] == STATE_LIGHTPROD)
+ t = 3;
+ else
+ return -1; /* invalid array name */
+
+ if (strcmp(name, "ambient") == 0) {
+ tokens[t] = STATE_AMBIENT;
+ }
+ else if (strcmp(name, "diffuse") == 0) {
+ tokens[t] = STATE_DIFFUSE;
+ }
+ else if (strcmp(name, "specular") == 0) {
+ tokens[t] = STATE_SPECULAR;
+ }
+ else if (strcmp(name, "position") == 0) {
+ tokens[t] = STATE_POSITION;
+ }
+ else if (strcmp(name, "halfVector") == 0) {
+ tokens[t] = STATE_HALF_VECTOR;
+ }
+ else if (strcmp(name, "spotDirection") == 0) {
+ tokens[t] = STATE_SPOT_DIRECTION; /* xyz components */
+ }
+ else if (strcmp(name, "spotCosCutoff") == 0) {
+ tokens[t] = STATE_SPOT_DIRECTION; /* w component */
+ }
+
+ else if (strcmp(name, "constantAttenuation") == 0) {
+ tokens[t] = STATE_ATTENUATION; /* x component */
+ }
+ else if (strcmp(name, "linearAttenuation") == 0) {
+ tokens[t] = STATE_ATTENUATION; /* y component */
+ }
+ else if (strcmp(name, "quadraticAttenuation") == 0) {
+ tokens[t] = STATE_ATTENUATION; /* z component */
+ }
+ else if (strcmp(name, "spotExponent") == 0) {
+ tokens[t] = STATE_ATTENUATION; /* w = spot exponent */
+ }
+
+ else if (strcmp(name, "spotCutoff") == 0) {
+ tokens[t] = STATE_SPOT_CUTOFF; /* x component */
+ }
+
+ else {
+ return -1; /* invalid field name */
+ }
+ }
+
+ pos = _mesa_add_state_reference(paramList, tokens);
+ return pos;
+ }
+
+ return 1;
+}
+
+
+/**
+ * Unroll the named built-in uniform variable into a sequence of state
+ * vars in the given parameter list.
+ */
+static GLint
+alloc_state_var_array(const slang_variable *var,
+ struct gl_program_parameter_list *paramList)
+{
+ gl_state_index tokens[STATE_LENGTH];
+ GLuint i;
+ GLint pos;
+
+ /* Initialize the state tokens array. This is very important.
+ * When we call _mesa_add_state_reference() it'll searches the parameter
+ * list to see if the given statevar token sequence is already present.
+ * This is normally a good thing since it prevents redundant values in the
+ * constant buffer.
+ *
+ * But when we're building arrays of state this can be bad. For example,
+ * consider this fragment of GLSL code:
+ * foo = gl_LightSource[3].diffuse;
+ * ...
+ * bar = gl_LightSource[i].diffuse;
+ *
+ * When we unroll the gl_LightSource array (for "bar") we want to re-emit
+ * gl_LightSource[3].diffuse and not re-use the first instance (from "foo")
+ * since that would upset the array layout. We handle this situation by
+ * setting the last token in the state var token array to the special
+ * value STATE_ARRAY.
+ * This token will only be set for array state. We can hijack the last
+ * element in the array for this since it's never used for light, clipplane
+ * or texture env array state.
+ */
+ for (i = 0; i < STATE_LENGTH; i++)
+ tokens[i] = 0;
+ tokens[STATE_LENGTH - 1] = STATE_ARRAY;
+
+ pos = emit_statevars(var->a_name, var->array_len, &var->type.specifier,
+ tokens, paramList);
+
+ return pos;
+}
+
+
+
/**
* Allocate storage for a pre-defined uniform (a GL state variable).
* As a memory-saving optimization, we try to only allocate storage for
* state vars that are actually used.
- * For example, the "gl_LightSource" uniform is huge. If we only use
- * a handful of gl_LightSource fields, we don't want to allocate storage
- * for all of gl_LightSource.
+ *
+ * Arrays such as gl_LightSource are handled specially. For an expression
+ * like "gl_LightSource[2].diffuse", we can allocate a single uniform/constant
+ * slot and return the index. In this case, we return direct=TRUE.
+ *
+ * Buf for something like "gl_LightSource[i].diffuse" we don't know the value
+ * of 'i' at compile time so we need to "unroll" the gl_LightSource array
+ * into a consecutive sequence of uniform/constant slots so it can be indexed
+ * at runtime. In this case, we return direct=FALSE.
*
* Currently, all pre-defined uniforms are in one of these forms:
* var
@@ -401,52 +642,62 @@ lookup_statevar(const char *var, GLint index1, GLint index2, const char *field,
* var[i].field
* var[i][j]
*
- * \return -1 upon error, else position in paramList of the state var/data
+ * \return -1 upon error, else position in paramList of the state variable/data
*/
GLint
_slang_alloc_statevar(slang_ir_node *n,
- struct gl_program_parameter_list *paramList)
+ struct gl_program_parameter_list *paramList,
+ GLboolean *direct)
{
slang_ir_node *n0 = n;
- const char *field = NULL, *var;
- GLint index1 = -1, index2 = -1, pos;
+ const char *field = NULL;
+ GLint index1 = -1, index2 = -1;
GLuint swizzle;
+ *direct = GL_TRUE;
+
if (n->Opcode == IR_FIELD) {
field = n->Field;
n = n->Children[0];
}
if (n->Opcode == IR_ELEMENT) {
- /* XXX can only handle constant indexes for now */
if (n->Children[1]->Opcode == IR_FLOAT) {
index1 = (GLint) n->Children[1]->Value[0];
- n = n->Children[0];
}
else {
- return -1;
+ *direct = GL_FALSE;
}
+ n = n->Children[0];
}
if (n->Opcode == IR_ELEMENT) {
/* XXX can only handle constant indexes for now */
- assert(n->Children[1]->Opcode == IR_FLOAT);
- index2 = (GLint) n->Children[1]->Value[0];
+ if (n->Children[1]->Opcode == IR_FLOAT) {
+ index2 = (GLint) n->Children[1]->Value[0];
+ }
+ else {
+ *direct = GL_FALSE;
+ }
n = n->Children[0];
}
assert(n->Opcode == IR_VAR);
- var = (char *) n->Var->a_name;
- pos = lookup_statevar(var, index1, index2, field, &swizzle, paramList);
- assert(pos >= 0);
- if (pos >= 0) {
- /* newly resolved storage for the statevar/constant/uniform */
- n0->Store->File = PROGRAM_STATE_VAR;
- n0->Store->Index = pos;
- n0->Store->Swizzle = swizzle;
- n0->Store->Parent = NULL;
+ if (*direct) {
+ const char *var = (const char *) n->Var->a_name;
+ GLint pos =
+ lookup_statevar(var, index1, index2, field, &swizzle, paramList);
+ if (pos >= 0) {
+ /* newly resolved storage for the statevar/constant/uniform */
+ n0->Store->File = PROGRAM_STATE_VAR;
+ n0->Store->Index = pos;
+ n0->Store->Swizzle = swizzle;
+ n0->Store->Parent = NULL;
+ return pos;
+ }
}
- return pos;
-}
+ *direct = GL_FALSE;
+ return alloc_state_var_array(n->Var, paramList);
+}
diff --git a/src/mesa/shader/slang/slang_builtin.h b/src/mesa/shader/slang/slang_builtin.h
index 58629f4f7fe..7f6fe80fcca 100644
--- a/src/mesa/shader/slang/slang_builtin.h
+++ b/src/mesa/shader/slang/slang_builtin.h
@@ -33,7 +33,8 @@
extern GLint
_slang_alloc_statevar(slang_ir_node *n,
- struct gl_program_parameter_list *paramList);
+ struct gl_program_parameter_list *paramList,
+ GLboolean *direct);
#endif /* SLANG_BUILTIN_H */
diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c
index 6587f9cf276..4f8e694a739 100644
--- a/src/mesa/shader/slang/slang_emit.c
+++ b/src/mesa/shader/slang/slang_emit.c
@@ -348,6 +348,10 @@ storage_to_src_reg(struct prog_src_register *src, const slang_ir_storage *st)
assert(index >= 0);
while (st->Parent) {
st = st->Parent;
+ if (st->Index < 0) {
+ /* an error should have been reported already */
+ return;
+ }
assert(st->Index >= 0);
index += st->Index;
swizzle = _slang_swizzle_swizzle(fix_swizzle(st->Swizzle), swizzle);
@@ -1841,9 +1845,17 @@ emit_array_element(slang_emit_info *emitInfo, slang_ir_node *n)
root = root->Parent;
if (root->File == PROGRAM_STATE_VAR) {
- GLint index = _slang_alloc_statevar(n, emitInfo->prog->Parameters);
- assert(n->Store->Index == index);
- return NULL;
+ GLboolean direct;
+ GLint index =
+ _slang_alloc_statevar(n, emitInfo->prog->Parameters, &direct);
+ if (index < 0) {
+ /* error */
+ return NULL;
+ }
+ if (direct) {
+ n->Store->Index = index;
+ return NULL; /* all done */
+ }
}
}
@@ -1967,19 +1979,23 @@ emit_struct_field(slang_emit_info *emitInfo, slang_ir_node *n)
* space for the ones that we actually use!
*/
if (root->File == PROGRAM_STATE_VAR) {
- root->Index = _slang_alloc_statevar(n, emitInfo->prog->Parameters);
- if (root->Index < 0) {
+ GLboolean direct;
+ GLint index = _slang_alloc_statevar(n, emitInfo->prog->Parameters, &direct);
+ if (index < 0) {
slang_info_log_error(emitInfo->log, "Error parsing state variable");
return NULL;
}
- return NULL;
- }
- else {
- /* do codegen for struct */
- emit(emitInfo, n->Children[0]);
- assert(n->Children[0]->Store->Index >= 0);
+ if (direct) {
+ root->Index = index;
+ return NULL; /* all done */
+ }
}
+ /* do codegen for struct */
+ emit(emitInfo, n->Children[0]);
+ assert(n->Children[0]->Store->Index >= 0);
+
+
fieldOffset = n->Store->Index;
fieldSize = n->Store->Size;
@@ -2077,7 +2093,18 @@ emit_var_ref(slang_emit_info *emitInfo, slang_ir_node *n)
assert(n->Store->File != PROGRAM_UNDEFINED);
if (n->Store->File == PROGRAM_STATE_VAR && n->Store->Index < 0) {
- n->Store->Index = _slang_alloc_statevar(n, emitInfo->prog->Parameters);
+ GLboolean direct;
+ GLint index = _slang_alloc_statevar(n, emitInfo->prog->Parameters, &direct);
+ if (index < 0) {
+ /* error */
+ char s[100];
+ snprintf(s, sizeof(s), "Undefined variable '%s'",
+ (char *) n->Var->a_name);
+ slang_info_log_error(emitInfo->log, s);
+ return NULL;
+ }
+
+ n->Store->Index = index;
}
else if (n->Store->File == PROGRAM_UNIFORM) {
/* mark var as used */