On 12/14/2010 12:36 PM, Keith Whitwell wrote:
> On Mon, 2010-12-13 at 12:01 -0800, Christoph Bumiller wrote:
>> I want to warm this up again adding nvc0 and
>> GL_ARB_separate_shader_objects to the picture.
>>
>> The latter extends GL_EXT_separate_shader_objects to support user
>> defined varyings and guarantees well defined behaviour only if
>> - varyings are declared inside the gl_PerVertex/gl_PerFragment block the
>> blocks match exactly in name, type, qualification, and (most
>> significantly) declaration order.
>> - varyings are assigned matching location qualifiers:
>> like: layout(location = 3) in vec4 normal
>> "The number of input locations available to a shader is limited."
>>
>> So, I propose to (loosely) identify GENERIC semantic indices with these
>> location qualifiers and let the pipe driver set a limit on the allowed
>> maximum (e.g PIPE_SHADER_CAP_MAX_INPUTS, and not demand to at least
>> support 219 of them - nvc0 offsers 0x200 bytes for generic inputs/outputs).
> 
> This sounds fine actually.  We kicked this around before & I was
> basically ok with the last iteration of the proposal, but this seems ok
> too.
> 
> As far as I can tell from a gallium perspective you're really just
> proposing a new pipe cap _MAX_INPUTS (actually _MAX_GENERIC_INDEX would
> be clearer), which the state tracker thereafter has to respect?
> 
> That would be fine with me.
First attempt at a patch introducing such a cap attached.

> 
>> My motivation is mostly that the hardware routing table for shader
>> varyings that was present on nv50 has been removed with nvc0 (Fermi).
>> And I'm glad, because filling 4 routing tables (since we have 5 shader
>> types now) is somewhat annoying. And so applying relocations to shaders
>> - it can be done, it's probably not too time consuming, but it's just
>> plain *unnecessary* (and thus stupid) for OpenGL.
>>
>> Now about d3d9 ...
>> 1. don't care, I don't see a d3d9 state tracker
>> 2. http://msdn.microsoft.com/en-us/library/bb509647%28v=VS.85%29.aspx
>> says "n is an optional integer between 0 and the number of resources
>> supported" - what "supported" means here isn't clear to me, but, I
>> didn't find any example where someone used something OpenGL doesn't have
>> (like COLOR2).
>> 3.
>> http://msdn.microsoft.com/en-us/library/bb944006%28v=vs.85%29.aspx#Varying_Shader_Inputs_and_Semantics
>> says "Input semantics are similar to the values in the D3DDECLUSAGE."
>> and
>> DECLUSAGE sounds like you're limited to sane values.
> 
> I think you're on the right track with (1)...  It's fairly pointless
> trying to discuss code here which isn't public & I don't think people
> need to be worrying about what may or may not be important for code they
> can't see.
> 
> I know this idea previously got tied up with speculation about what a
> DX9 state tracker might or might not require, but in retrospect I wish
> I'd been able to steer conversation away from that.
> 
> The work on closed components may drive a lot of the feature development
> and new interfaces, but there's usually enough flexibility that this
> sort of cleanup isn't a big deal.
> 
> 
> Keith
> 
>> Not sure if anyone wants to think about this issue at this time (since
>> implementation of ARB_separate_shader_objects is probably far in the GL4
>> future), but I'd be happy about any comments.
>>
>> Regards,
>> Christoph
>>
>> On 04/13/2010 12:55 PM, Luca Barbieri wrote:
>>> This patch series is intended to resolve the issue of semantic-based shader 
>>> linkage in Gallium.
>>> It can also be found in the RFC-gallium-semantics branch.
>>>
>>> It does not change the current Gallium design, but rather formalizes some 
>>> limitations to it, and provides infrastructure to implement this model more 
>>> easily in drivers, along with a full nv30/nv40 implementation.
>>>
>>> These limitations are added to allow an efficient implementation for both 
>>> hardware lacking special support and hardware having support but also 
>>> special constraints.
>>>
>>> Note that this does NOT resolve all issues, and there are quite a bit left 
>>> to future refinement.
>>>
>>> In particular, the following issues are still open:
>>> 1. COLOR clamping (and floating point framebuffers)
>>> 2. A linkage table CSO allowing to specify non-identity linkage
>>> 3. BCOLOR/FACE-related issues
>>> 4. Adding a cap to inform the state tracker that more than 219 generic 
>>> indices are provided
>>>
>>> This topic was already very extensively discussed.
>>> See 
>>> http://www.mail-archive.com/mesa3d-dev@lists.sourceforge.net/msg10865.html 
>>> for some early inconclusive discussion around an early implementation that 
>>> modified the GLSL linker (which is NOT being proposed here)
>>> See 
>>> http://www.mail-archive.com/mesa3d-dev@lists.sourceforge.net/msg12016.html 
>>> for some more discussion that seemed to mostly reach a consensus over the 
>>> approach proposed here.
>>> See in particular 
>>> http://www.mail-archive.com/mesa3d-dev@lists.sourceforge.net/msg12041.html .
>>>
>>> That said, I'm going to try to repeat all information here, partially by 
>>> copy&pasting from earlier messages.
>>> This message should probably be adapted into gallium/docs if/when this is 
>>> accepted.
>>>
>>> Here is the short summary; the long rationale follows after it.
>>>
>>> The proposal here is to add the following limitations to Gallium, for the 
>>> intermediate semantics:
>>> 1. TGSI_SEMANTIC_NORMAL is removed, using a commit by Michal Krol that was 
>>> never merged
>>> 2. Every semantic except GENERIC, COLOR and BCOLOR can only be used with 
>>> semantic index 0
>>> 3. COLOR and BCOLOR can only be used with semantic index 0-1 (note that 
>>> this doesn't apply to fragment outputs)
>>> 4. GENERIC can be used with semantic indices 0-218 on any driver, if BCOLOR 
>>> is not used
>>> 5. GENERIC can be used with semantic indices 0-216 on any driver, if BCOLOR 
>>> IS used
>>> 6. GENERIC can be used with semantic indices 0-255 on almost all drivers 
>>> (those that don't need the 0-218 limitation)
>>> 7. Some drivers may also choose to support GENERIC with arbitrary indices, 
>>> but that should generally not happen
>>>
>>> The reason of this, in short, is that this maps directly to DirectX 9 SM3, 
>>> which is the most problematic interface of all.
>>>
>>> The peculiar problem we have here is that we have two competing constraints 
>>> that force us into choosing the exact SM3 value:
>>> 1. The VMware SVGA driver must deal with an SM3 host interface and would 
>>> ideally want to directly feed the Gallium semantics to the host
>>> 2. An hypotetical DirectX 9 state tracker needs to support SM3 and would 
>>> ideally want to directly feed the SM3 semantics to Gallium
>>>
>>> Note that this is not a reference to the VMware DirectX 9 state tracker, 
>>> since its authors haven't provided details about its handling of shader 
>>> semantics.
>>>
>>> SM3 ends up supporting 219 generic indices: 16 indices in 14 classes, minus 
>>> POSITION0, PSIZE0, COLOR0, COLOR1 and FOG0 which are the only ones that 
>>> wouldn't be mapped to GENERIC.
>>> However, Gallium drivers that don't benefit from having specific contraints 
>>> (like svga and r600) are supposed to support 256 indices, and my nv30/nv40 
>>> work does that.
>>>
>>> The expected implementation, if no hardware support exists, is to build a 
>>> list of relocations to apply to either the fragment or the vertex shader, 
>>> and patch one of them at validation time to match the other.
>>> Data structures are provided in gallium/auxiliary to ease this, and try to 
>>> minimize the number of times where this needs to be performed.
>>>
>>> Let's now proceed to the discussion and detailed rationale, mostly 
>>> constructed by copy&pasting older messages.
>>> ...
From 6812804170cdefaf5d2351688182a17ffaa68394 Mon Sep 17 00:00:00 2001
From: Christoph Bumiller <e0425...@student.tuwien.ac.at>
Date: Thu, 16 Dec 2010 16:30:26 +0100
Subject: [PATCH] gallium: introduce PIPE_SHADER_CAP_MAX_GENERIC_INDEX

This cap indicates the highest supported semantic index for inputs
of the TGSI_SEMANTIC_GENERIC to a specific shader stage.

It is meant to prevent state trackers from using arbitrarily high
indices which might force some pipe drivers to perform potentially
expensive linkage steps when the shader configuration changes.

In particular, drivers should be able to interpret GENERIC indices
like GLSL location qualifiers.

Setting the default maximum to 255 since tgsi_shader_info uses
bytes to store semantic indices.
---
 src/gallium/docs/source/screen.rst     |  100 ++++++++++++++++++++------------
 src/gallium/drivers/i915/i915_screen.c |    2 +
 src/gallium/drivers/i965/brw_screen.c  |    2 +
 src/gallium/drivers/noop/noop_pipe.c   |    2 +
 src/gallium/drivers/nv50/nv50_screen.c |    2 +
 src/gallium/drivers/nvfx/nvfx_screen.c |    2 +
 src/gallium/drivers/r300/r300_screen.c |    2 +
 src/gallium/drivers/r600/r600_pipe.c   |    2 +
 src/gallium/drivers/svga/svga_screen.c |    2 +
 src/gallium/include/pipe/p_defines.h   |    1 +
 10 files changed, 79 insertions(+), 38 deletions(-)

diff --git a/src/gallium/docs/source/screen.rst 
b/src/gallium/docs/source/screen.rst
index 09edbaa..e36e770 100644
--- a/src/gallium/docs/source/screen.rst
+++ b/src/gallium/docs/source/screen.rst
@@ -52,37 +52,12 @@ The integer capabilities:
 * ``MAX_VERTEX_TEXTURE_UNITS``: The maximum number of samplers addressable
   inside the vertex shader. If this is 0, then the vertex shader cannot
   sample textures.
-* ``TGSI_CONT_SUPPORTED``: Whether the TGSI CONT opcode is supported.
 * ``BLEND_EQUATION_SEPARATE``: Whether alpha blend equations may be different
   from color blend equations, in :ref:`Blend` state.
 * ``SM3``: Whether the vertex shader and fragment shader support equivalent
   opcodes to the Shader Model 3 specification. XXX oh god this is horrible
-* ``MAX_PREDICATE_REGISTERS``: indicates the number of predicate registers
-  available.  Predicate register may be set as a side-effect of ALU
-  instructions to indicate less than, greater than or equal to zero.
-  Later instructions can use a predicate register to control writing to
-  each channel of destination registers.  NOTE: predicate registers have
-  not been fully implemented in Gallium at this time.  See the
-  GL_NV_fragment_program extension for more info (look for "condition codes").
 * ``MAX_COMBINED_SAMPLERS``: The total number of samplers accessible from
   the vertex and fragment shader, inclusive.
-* ``MAX_CONST_BUFFERS``: Maximum number of constant buffers that can be bound
-  to any shader stage using ``set_constant_buffer``. If 0 or 1, the pipe will
-  only permit binding one constant buffer per shader, and the shaders will
-  not permit two-dimensional access to constants.
-
-If a value greater than 0 is returned, the driver can have multiple
-constant buffers bound to shader stages. The CONST register file can
-be accessed with two-dimensional indices, like in the example below.
-
-DCL CONST[0][0..7]       # declare first 8 vectors of constbuf 0
-DCL CONST[3][0]          # declare first vector of constbuf 3
-MOV OUT[0], CONST[0][3]  # copy vector 3 of constbuf 0
-
-For backwards compatibility, one-dimensional access to CONST register
-file is still supported. In that case, the constbuf index is assumed
-to be 0.
-
 * ``MAX_CONST_BUFFER_SIZE``: Maximum byte size of a single constant buffer.
 * ``INDEP_BLEND_ENABLE``: Whether per-rendertarget blend enabling and channel
   masks are supported. If 0, then the first rendertarget's blend mask is
@@ -112,22 +87,71 @@ The floating-point capabilities:
 * ``GUARD_BAND_LEFT``, ``GUARD_BAND_TOP``, ``GUARD_BAND_RIGHT``,
   ``GUARD_BAND_BOTTOM``: XXX
 
-Fragment shader limits:
 
-* ``PIPE_CAP_MAX_FS_INSTRUCTIONS``: The maximum number of instructions.
-* ``PIPE_CAP_MAX_FS_ALU_INSTRUCTIONS``: The maximum number of arithmetic 
instructions.
-* ``PIPE_CAP_MAX_FS_TEX_INSTRUCTIONS``: The maximum number of texture 
instructions.
-* ``PIPE_CAP_MAX_FS_TEX_INDIRECTIONS``: The maximum number of texture 
indirections.
-* ``PIPE_CAP_MAX_FS_CONTROL_FLOW_DEPTH``: The maximum nested control flow 
depth.
-* ``PIPE_CAP_MAX_FS_INPUTS``: The maximum number of input registers.
-* ``PIPE_CAP_MAX_FS_CONSTS``: The maximum number of constants.
-* ``PIPE_CAP_MAX_FS_TEMPS``: The maximum number of temporary registers.
-* ``PIPE_CAP_MAX_FS_ADDRS``: The maximum number of address registers.
-* ``PIPE_CAP_MAX_FS_PREDS``: The maximum number of predicate registers.
+.. _pipe_shader_cap:
 
-Vertex shader limits:
+PIPE_SHADER_CAP_*
+^^^^^^^^^^^^^^^^^
 
-* ``PIPE_CAP_MAX_VS_*``: Identical to ``PIPE_CAP_MAX_FS_*``.
+Capability queries about shader features and limits of the driver/GPU
+by shader stage. All of them are integer values, use :ref:`get_shader_param`.
+
+* ``PIPE_SHADER_CAP_MAX_INSTRUCTIONS``: The maximum number of (native ?)
+  instructions. Will be 0 if the shader stage is unsupported.
+* ``PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS``: The maximum number of
+  arithmetic instructions.
+* ``PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS``: The maximum number of
+  texture instructions.
+* ``PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS``: The maximum number of
+  texture indirections.
+* ``PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH``: The maximum nested
+  control flow depth.
+* ``PIPE_SHADER_CAP_MAX_INPUTS``: The maximum number of input registers.
+* ``PIPE_SHADER_CAP_MAX_CONSTS``: The maximum number of constants (in vectors
+  of 4 floats).
+* ``PIPE_SHADER_CAP_MAX_CONST_BUFFERS``: Maximum number of constant buffers 
that
+  can be bound to any shader stage using ``set_constant_buffer``.
+  If 0 or 1, the pipe will only permit binding one constant buffer per shader,
+  and the shaders will not permit two-dimensional access to constants.
+
+If a value greater than 0 is returned, the driver can have multiple
+constant buffers bound to shader stages. The CONST register file can
+be accessed with two-dimensional indices, like in the example below.
+
+DCL CONST[0][0..7]       # declare first 8 vectors of constbuf 0
+DCL CONST[3][0]          # declare first vector of constbuf 3
+MOV OUT[0], CONST[0][3]  # copy vector 3 of constbuf 0
+
+For backwards compatibility, one-dimensional access to CONST register
+file is still supported. In that case, the constbuf index is assumed
+to be 0.
+
+* ``PIPE_SHADER_CAP_MAX_TEMPS``: The maximum number of temporary registers.
+* ``PIPE_SHADER_CAP_MAX_ADDRS``: The maximum number of address registers.
+* ``PIPE_SHADER_CAP_MAX_PREDS``: Indicates the number of predicate registers
+  available.  Predicate register may be set as a side-effect of ALU
+  instructions to indicate less than, greater than or equal to zero.
+  Later instructions can use a predicate register to control writing to
+  each channel of destination registers.  NOTE: predicate registers have
+  not been fully implemented in Gallium at this time.  See the
+  GL_NV_fragment_program extension for more info (look for "condition codes").
+* ``PIPE_SHADER_CAP_MAX_GENERIC_INDEX``: The highest supported semantic index
+  for inputs of the ``TGSI_SEMANTIC_GENERIC`` to the specified (and thus
+  outputs of the previous) shader stage. Not applicable for vertex shaders.
+  This limit is meant to enable pipe drivers to interpret a GENERIC index as
+  an address and avoid an extra linkage step between shader stages.
+* ``PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED``: Whether the TGSI CONT opcode
+  is supported.
+* ``PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR``: Whether indirect addressing of input
+  registers is supported.
+* ``PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR``: Whether indirect addressing of
+  output registers is supported.
+* ``PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR``: Whether indirect addressing of
+  temporary registers is supported.
+* ``PIPE_SHADER_CAP_INDIRECT_CONST_ADDR``: Whether indirect addressing of the
+  constants register file is supported.
+* ``PIPE_SHADER_CAP_SUBROUTINES``: Indicates whether the BGNSUB, ENDSUB, CAL 
and
+  RET opcodes are supported.
 
 
 .. _pipe_bind:
diff --git a/src/gallium/drivers/i915/i915_screen.c 
b/src/gallium/drivers/i915/i915_screen.c
index f66478e..e5dd503 100644
--- a/src/gallium/drivers/i915/i915_screen.c
+++ b/src/gallium/drivers/i915/i915_screen.c
@@ -182,6 +182,8 @@ i915_get_shader_param(struct pipe_screen *screen, unsigned 
shader, enum pipe_sha
          return 0;
       case PIPE_SHADER_CAP_MAX_PREDS:
          return 0;
+      case PIPE_SHADER_CAP_MAX_GENERIC_INDEX:
+         return 7;
       case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
          return 0;
       case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
diff --git a/src/gallium/drivers/i965/brw_screen.c 
b/src/gallium/drivers/i965/brw_screen.c
index f5b75b1..2524028 100644
--- a/src/gallium/drivers/i965/brw_screen.c
+++ b/src/gallium/drivers/i965/brw_screen.c
@@ -233,6 +233,8 @@ brw_get_shader_param(struct pipe_screen *screen, unsigned 
shader, enum pipe_shad
          return 0;
       case PIPE_SHADER_CAP_MAX_PREDS:
          return 0;
+      case PIPE_SHADER_CAP_MAX_GENERIC_INDEX:
+         return 255;
       case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
          return 1;
       case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
diff --git a/src/gallium/drivers/noop/noop_pipe.c 
b/src/gallium/drivers/noop/noop_pipe.c
index c9c463f..d7060f1 100644
--- a/src/gallium/drivers/noop/noop_pipe.c
+++ b/src/gallium/drivers/noop/noop_pipe.c
@@ -459,6 +459,8 @@ static int noop_get_shader_param(struct pipe_screen* 
pscreen, unsigned shader, e
                return 1;
        case PIPE_SHADER_CAP_MAX_PREDS:
                return 0;
+       case PIPE_SHADER_CAP_MAX_GENERIC_INDEX:
+               return 255;
        case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
                return 1;
        case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
diff --git a/src/gallium/drivers/nv50/nv50_screen.c 
b/src/gallium/drivers/nv50/nv50_screen.c
index 1b7fceb..502b1ce 100644
--- a/src/gallium/drivers/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nv50/nv50_screen.c
@@ -163,6 +163,8 @@ nv50_screen_get_shader_param(struct pipe_screen *pscreen, 
unsigned shader,
                        return 128 / 4;
                else
                        return 64 / 4;
+       case PIPE_SHADER_CAP_MAX_GENERIC_INDEX:
+               return 255;
        case PIPE_SHADER_CAP_MAX_CONSTS:
                return 65536 / 16;
        case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: /* 16 - 1, but not implemented 
*/
diff --git a/src/gallium/drivers/nvfx/nvfx_screen.c 
b/src/gallium/drivers/nvfx/nvfx_screen.c
index 92e1d33..21a59ce 100644
--- a/src/gallium/drivers/nvfx/nvfx_screen.c
+++ b/src/gallium/drivers/nvfx/nvfx_screen.c
@@ -116,6 +116,8 @@ nvfx_screen_get_shader_param(struct pipe_screen *pscreen, 
unsigned shader, enum
                        return screen->use_nv4x ? 1 : 0;
                case PIPE_SHADER_CAP_MAX_PREDS:
                        return 0; /* we could expose these, but nothing uses 
them */
+               case PIPE_SHADER_CAP_MAX_GENERIC_INDEX:
+                       return 255;
                case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
                    return 0;
                case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
diff --git a/src/gallium/drivers/r300/r300_screen.c 
b/src/gallium/drivers/r300/r300_screen.c
index 921d6f1..1b132e5 100644
--- a/src/gallium/drivers/r300/r300_screen.c
+++ b/src/gallium/drivers/r300/r300_screen.c
@@ -208,6 +208,8 @@ static int r300_get_shader_param(struct pipe_screen 
*pscreen, unsigned shader, e
             return 0;
         case PIPE_SHADER_CAP_MAX_PREDS:
             return is_r500 ? 1 : 0;
+        case PIPE_SHADER_CAP_MAX_GENERIC_INDEX:
+            return 30; /* (ATTR_GENERIC_COUNT - 1) - 1 for WPOS */
         case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
             return 1;
         case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
diff --git a/src/gallium/drivers/r600/r600_pipe.c 
b/src/gallium/drivers/r600/r600_pipe.c
index 72988b9..01aa253 100644
--- a/src/gallium/drivers/r600/r600_pipe.c
+++ b/src/gallium/drivers/r600/r600_pipe.c
@@ -374,6 +374,8 @@ static int r600_get_shader_param(struct pipe_screen* 
pscreen, unsigned shader, e
                return 1;
        case PIPE_SHADER_CAP_MAX_PREDS:
                return 0; /* FIXME */
+       case PIPE_SHADER_CAP_MAX_GENERIC_INDEX:
+               return 255;
        case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
                return 1;
        case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
diff --git a/src/gallium/drivers/svga/svga_screen.c 
b/src/gallium/drivers/svga/svga_screen.c
index 0781903..ee07fe0 100644
--- a/src/gallium/drivers/svga/svga_screen.c
+++ b/src/gallium/drivers/svga/svga_screen.c
@@ -229,6 +229,8 @@ static int svga_get_shader_param(struct pipe_screen 
*screen, unsigned shader, en
          return svgascreen->use_ps30 ? 1 : 0;
       case PIPE_SHADER_CAP_MAX_PREDS:
          return svgascreen->use_ps30 ? 1 : 0;
+      case PIPE_SHADER_CAP_MAX_GENERIC_INDEX:
+         return 255;
       case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
          return 1;
       case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
diff --git a/src/gallium/include/pipe/p_defines.h 
b/src/gallium/include/pipe/p_defines.h
index f5af15f..8a81561 100644
--- a/src/gallium/include/pipe/p_defines.h
+++ b/src/gallium/include/pipe/p_defines.h
@@ -478,6 +478,7 @@ enum pipe_shader_cap
    PIPE_SHADER_CAP_MAX_TEMPS,
    PIPE_SHADER_CAP_MAX_ADDRS,
    PIPE_SHADER_CAP_MAX_PREDS,
+   PIPE_SHADER_CAP_MAX_GENERIC_INDEX,
    /* boolean caps */
    PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED,
    PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR,
-- 
1.7.2.2

------------------------------------------------------------------------------
Lotusphere 2011
Register now for Lotusphere 2011 and learn how
to connect the dots, take your collaborative environment
to the next level, and enter the era of Social Business.
http://p.sf.net/sfu/lotusphere-d2d
_______________________________________________
Mesa3d-dev mailing list
Mesa3d-dev@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mesa3d-dev

Reply via email to