[WINED3D 3/8] Created generate_base_shader() which will be shared between pixel and vertex shaders to generate the bulk of the shader string.

Jason Green jave27 at gmail.com
Fri May 5 10:30:50 CDT 2006


-------------- next part --------------
Subject: [PATCH 3/8] Created generate_base_shader() which will be shared between pixel and vertex shaders to generate the bulk of the shader string.

---

 dlls/wined3d/baseshader.c |  126 +++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 126 insertions(+), 0 deletions(-)

e2dc1bb5d430af9d46939701e6a28043770adee6
diff --git a/dlls/wined3d/baseshader.c b/dlls/wined3d/baseshader.c
index 4fbfaf5..262ae5e 100644
--- a/dlls/wined3d/baseshader.c
+++ b/dlls/wined3d/baseshader.c
@@ -27,6 +27,8 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
 
+#define GLNAME_REQUIRE_GLSL  ((const char *)1)
+
 inline static BOOL shader_is_version_token(DWORD token) {
     return 0xFFFF0000 == (token & 0xFFFF0000) || 
            0xFFFE0000 == (token & 0xFFFF0000);
@@ -261,4 +263,128 @@ void shader_dump_ins_modifiers(const DWO
     }
 }
 
+/** Shared code in order to generate the bulk of the shader string.
+    Use the shader_header_fct & shader_footer_fct to add strings
+    that are specific to pixel or vertex functions
+    NOTE: A description of how to parse tokens can be found at:
+          http://msdn.microsoft.com/library/default.asp?url=/library/en-us/graphics/hh/graphics/usermodedisplaydriver_shader_cc8e4e05-f5c3-4ec0-8853-8ce07c1551b2.xml.asp */
+void generate_base_shader(
+    IWineD3DBaseShader *iface,
+    SHADER_BUFFER* buffer,
+    CONST DWORD* pFunction) {
+
+    IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
+    const DWORD *pToken = pFunction;
+    const SHADER_OPCODE *curOpcode = NULL;
+    DWORD i;
+
+    /* Initialize current parsing state */
+    This->baseShader.parse_state.current_row = 0;
+
+    /* First pass: figure out which temporary and texture registers are used */
+    shader_get_registers_used(iface, pToken);
+    TRACE("Texture/Address registers used: %#lx, Temp registers used %#lx\n",
+          This->baseShader.textures_used, This->baseShader.temps_used);
+
+    /* TODO: check register usage against GL/Directx limits, and fail if they're exceeded
+        nUseAddressRegister < = GL_MAX_PROGRAM_ADDRESS_REGISTERS_AR
+        nUseTempRegister    <=  GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB
+    */
+
+    /* Pre-declare registers */
+    for(i = 0; i < This->baseShader.limits.temporary; i++) {
+        if (This->baseShader.temps_used & (1 << i))
+             shader_addline(buffer, "TEMP R%lu;\n", i);
+    }
+
+    for (i = 0; i < This->baseShader.limits.address; i++) {
+        if (This->baseShader.textures_used & (1 << i))
+            shader_addline(buffer, "ADDRESS A%ld;\n", i);
+    }
+
+    for(i = 0; i < This->baseShader.limits.texture; i++) {
+        if (This->baseShader.textures_used & (1 << i))
+            shader_addline(buffer,"TEMP T%lu;\n", i);
+    }
+
+    /* Texture coordinate registers must be pre-loaded */
+    for (i = 0; i < This->baseShader.limits.texture; i++) {
+       if (This->baseShader.textures_used & (1 << i))
+          shader_addline(buffer, "MOV T%lu, fragment.texcoord[%lu];\n", i, i);
+    }
+
+    /* Second pass, process opcodes */
+    if (NULL != pToken) {
+        while (D3DPS_END() != *pToken) {
+
+            /* Skip version token */
+            if (shader_is_version_token(*pToken)) {
+                ++pToken;
+                continue;
+            }
+
+            /* Skip comment tokens */
+            if (shader_is_comment_token(*pToken)) {
+                DWORD comment_len = (*pToken & D3DSI_COMMENTSIZE_MASK) >> D3DSI_COMMENTSIZE_SHIFT;
+                ++pToken;
+                TRACE("#%s\n", (char*)pToken);
+                pToken += comment_len;
+                continue;
+            }
+
+            /* Read opcode */
+            curOpcode = shader_get_opcode(iface, *pToken);
+            ++pToken;
+
+            /* Unknown opcode and its parameters */
+            if (NULL == curOpcode) {
+                while (*pToken & 0x80000000) { /* TODO: Think of a sensible name for 0x80000000 */
+                    FIXME("unrecognized opcode: %08lx\n", *pToken);
+                    ++pToken;
+                }
+
+            /* Unhandled opcode */
+            } else if (GLNAME_REQUIRE_GLSL == curOpcode->glname) {
+
+                FIXME("Token %s requires greater functionality than "
+                    "Vertex or Fragment_Program_ARB supports\n", curOpcode->name);
+                pToken += curOpcode->num_params;
+
+            /* If a generator function is set, use it */
+            } else if (curOpcode->hw_fct != NULL) {
+
+                SHADER_OPCODE_ARG hw_arg;
+
+                hw_arg.shader = iface;
+                hw_arg.opcode = curOpcode;
+                hw_arg.buffer = buffer;
+                if (curOpcode->num_params > 0) {
+                    hw_arg.dst = *pToken;
+
+                    /* FIXME: this does not account for relative address tokens */
+                    for (i = 1; i < curOpcode->num_params; i++)
+                       hw_arg.src[i-1] = *(pToken + i);
+                }
+
+                curOpcode->hw_fct(&hw_arg);
+                pToken += curOpcode->num_params;
+
+            } else {
+
+                TRACE("Found opcode D3D:%s GL:%s, PARAMS:%d, \n",
+                curOpcode->name, curOpcode->glname, curOpcode->num_params);
+
+                /* Unless we encounter a no-op command, this opcode is unrecognized */
+                if (curOpcode->opcode != D3DSIO_NOP) {
+                    FIXME("Can't handle opcode %s in hwShader\n", curOpcode->name);
+                    pToken += curOpcode->num_params;
+                }
+            }
+        }
+        /* TODO: What about result.depth? */
+
+    }
+}
+
+
 /* TODO: Move other shared code here */
-- 
1.1.3


More information about the wine-patches mailing list