⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 baseshader.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
                swizzle_reg_chars[swizzle_r],
                swizzle_reg_chars[swizzle_g],
                swizzle_reg_chars[swizzle_b],
                swizzle_reg_chars[swizzle_a]);
            }
        }
    }
}

/** 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 shader_generate_main(
    IWineD3DBaseShader *iface,
    SHADER_BUFFER* buffer,
    shader_reg_maps* reg_maps,
    CONST DWORD* pFunction) {

    IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
    const DWORD *pToken = pFunction;
    const SHADER_OPCODE *curOpcode = NULL;
    SHADER_HANDLER hw_fct = NULL;
    DWORD i;
    SHADER_OPCODE_ARG hw_arg;

    /* Initialize current parsing state */
    hw_arg.shader = iface;
    hw_arg.buffer = buffer;
    hw_arg.reg_maps = reg_maps;
    This->baseShader.parse_state.current_row = 0;

    /* Second pass, process opcodes */
    if (NULL != pToken) {
        while (WINED3DPS_END() != *pToken) {

            /* Skip version token */
            if (shader_is_version_token(*pToken)) {
                ++pToken;
                continue;
            }

            /* Skip comment tokens */
            if (shader_is_comment(*pToken)) {
                DWORD comment_len = (*pToken & WINED3DSI_COMMENTSIZE_MASK) >> WINED3DSI_COMMENTSIZE_SHIFT;
                ++pToken;
                TRACE("#%s\n", (const char*)pToken);
                pToken += comment_len;
                continue;
            }

            /* Read opcode */
            hw_arg.opcode_token = *pToken++;
            curOpcode = shader_get_opcode(iface, hw_arg.opcode_token);

            /* Select handler */
            if (curOpcode == NULL)
                hw_fct = NULL;
            else if (This->baseShader.shader_mode == SHADER_GLSL)
                hw_fct = curOpcode->hw_glsl_fct;
            else if (This->baseShader.shader_mode == SHADER_ARB)
                hw_fct = curOpcode->hw_fct;

            /* Unknown opcode and its parameters */
            if (NULL == curOpcode) {
                FIXME("Unrecognized opcode: token=%08x\n", hw_arg.opcode_token);
                pToken += shader_skip_unrecognized(iface, pToken); 

            /* Nothing to do */
            } else if (WINED3DSIO_DCL == curOpcode->opcode ||
                       WINED3DSIO_NOP == curOpcode->opcode ||
                       WINED3DSIO_DEF == curOpcode->opcode ||
                       WINED3DSIO_DEFI == curOpcode->opcode ||
                       WINED3DSIO_DEFB == curOpcode->opcode ||
                       WINED3DSIO_PHASE == curOpcode->opcode ||
                       WINED3DSIO_RET == curOpcode->opcode) {

                pToken += shader_skip_opcode(This, curOpcode, hw_arg.opcode_token);

            /* If a generator function is set for current shader target, use it */
            } else if (hw_fct != NULL) {

                hw_arg.opcode = curOpcode;

                /* Destination token */
                if (curOpcode->dst_token) {

                    DWORD param, addr_token = 0;
                    pToken += shader_get_param(iface, pToken, &param, &addr_token);
                    hw_arg.dst = param;
                    hw_arg.dst_addr = addr_token;
                }

                /* Predication token */
                if (hw_arg.opcode_token & WINED3DSHADER_INSTRUCTION_PREDICATED) 
                    hw_arg.predicate = *pToken++;

                /* Other source tokens */
                for (i = 0; i < (curOpcode->num_params - curOpcode->dst_token); i++) {

                    DWORD param, addr_token = 0; 
                    pToken += shader_get_param(iface, pToken, &param, &addr_token);
                    hw_arg.src[i] = param;
                    hw_arg.src_addr[i] = addr_token;
                }

                /* Call appropriate function for output target */
                hw_fct(&hw_arg);

                /* Process instruction modifiers for GLSL apps ( _sat, etc. ) */
                if (This->baseShader.shader_mode == SHADER_GLSL)
                    shader_glsl_add_instruction_modifiers(&hw_arg);

            /* Unhandled opcode */
            } else {

                FIXME("Can't handle opcode %s in hwShader\n", curOpcode->name);
                pToken += shader_skip_opcode(This, curOpcode, hw_arg.opcode_token);
            }
        }
        /* TODO: What about result.depth? */

    }
}

void shader_dump_ins_modifiers(const DWORD output) {

    DWORD shift = (output & WINED3DSP_DSTSHIFT_MASK) >> WINED3DSP_DSTSHIFT_SHIFT;
    DWORD mmask = output & WINED3DSP_DSTMOD_MASK;

    switch (shift) {
        case 0: break;
        case 13: TRACE("_d8"); break;
        case 14: TRACE("_d4"); break;
        case 15: TRACE("_d2"); break;
        case 1: TRACE("_x2"); break;
        case 2: TRACE("_x4"); break;
        case 3: TRACE("_x8"); break;
        default: TRACE("_unhandled_shift(%d)", shift); break;
    }

    if (mmask & WINED3DSPDM_SATURATE)         TRACE("_sat");
    if (mmask & WINED3DSPDM_PARTIALPRECISION) TRACE("_pp");
    if (mmask & WINED3DSPDM_MSAMPCENTROID)    TRACE("_centroid");

    mmask &= ~(WINED3DSPDM_SATURATE | WINED3DSPDM_PARTIALPRECISION | WINED3DSPDM_MSAMPCENTROID);
    if (mmask)
        FIXME("_unrecognized_modifier(%#x)", mmask >> WINED3DSP_DSTMOD_SHIFT);
}

/* First pass: trace shader, initialize length and version */
void shader_trace_init(
    IWineD3DBaseShader *iface,
    const DWORD* pFunction) {

    IWineD3DBaseShaderImpl *This =(IWineD3DBaseShaderImpl *)iface;

    const DWORD* pToken = pFunction;
    const SHADER_OPCODE* curOpcode = NULL;
    DWORD opcode_token;
    unsigned int len = 0;
    DWORD i;

    TRACE("(%p) : Parsing programme\n", This);

    if (NULL != pToken) {
        while (WINED3DVS_END() != *pToken) {
            if (shader_is_version_token(*pToken)) { /** version */
                This->baseShader.hex_version = *pToken;
                TRACE("%s_%u_%u\n", shader_is_pshader_version(This->baseShader.hex_version)? "ps": "vs",
                    WINED3DSHADER_VERSION_MAJOR(This->baseShader.hex_version),
                    WINED3DSHADER_VERSION_MINOR(This->baseShader.hex_version));
                ++pToken;
                ++len;
                continue;
            }
            if (shader_is_comment(*pToken)) { /** comment */
                DWORD comment_len = (*pToken & WINED3DSI_COMMENTSIZE_MASK) >> WINED3DSI_COMMENTSIZE_SHIFT;
                ++pToken;
                TRACE("//%s\n", (const char*)pToken);
                pToken += comment_len;
                len += comment_len + 1;
                continue;
            }
            opcode_token = *pToken++;
            curOpcode = shader_get_opcode(iface, opcode_token);
            len++;

            if (NULL == curOpcode) {
                int tokens_read;
                FIXME("Unrecognized opcode: token=%08x\n", opcode_token);
                tokens_read = shader_skip_unrecognized(iface, pToken);
                pToken += tokens_read;
                len += tokens_read;

            } else {
                if (curOpcode->opcode == WINED3DSIO_DCL) {

                    DWORD usage = *pToken;
                    DWORD param = *(pToken + 1);

                    shader_dump_decl_usage(This, usage, param);
                    shader_dump_ins_modifiers(param);
                    TRACE(" ");
                    shader_dump_param(iface, param, 0, 0);
                    pToken += 2;
                    len += 2;

                } else if (curOpcode->opcode == WINED3DSIO_DEF) {

                        unsigned int offset = shader_get_float_offset(*pToken);

                        TRACE("def c%u = %f, %f, %f, %f", offset,
                            *(const float *)(pToken + 1),
                            *(const float *)(pToken + 2),
                            *(const float *)(pToken + 3),
                            *(const float *)(pToken + 4));

                        pToken += 5;
                        len += 5;
                } else if (curOpcode->opcode == WINED3DSIO_DEFI) {

                        TRACE("defi i%u = %d, %d, %d, %d", *pToken & WINED3DSP_REGNUM_MASK,
                            *(pToken + 1),
                            *(pToken + 2),
                            *(pToken + 3),
                            *(pToken + 4));

                        pToken += 5;
                        len += 5;

                } else if (curOpcode->opcode == WINED3DSIO_DEFB) {

                        TRACE("defb b%u = %s", *pToken & WINED3DSP_REGNUM_MASK,
                            *(pToken + 1)? "true": "false");

                        pToken += 2;
                        len += 2;

                } else {

                    DWORD param, addr_token;
                    int tokens_read;

                    /* Print out predication source token first - it follows
                     * the destination token. */
                    if (opcode_token & WINED3DSHADER_INSTRUCTION_PREDICATED) {
                        TRACE("(");
                        shader_dump_param(iface, *(pToken + 2), 0, 1);
                        TRACE(") ");
                    }

                    TRACE("%s", curOpcode->name);

                    if (curOpcode->opcode == WINED3DSIO_IFC ||
                        curOpcode->opcode == WINED3DSIO_BREAKC) {

                        DWORD op = (opcode_token & INST_CONTROLS_MASK) >> INST_CONTROLS_SHIFT;
                        switch (op) {
                            case COMPARISON_GT: TRACE("_gt"); break;
                            case COMPARISON_EQ: TRACE("_eq"); break;
                            case COMPARISON_GE: TRACE("_ge"); break;
                            case COMPARISON_LT: TRACE("_lt"); break;
                            case COMPARISON_NE: TRACE("_ne"); break;
                            case COMPARISON_LE: TRACE("_le"); break;
                            default:
                                TRACE("_(%u)", op);
                        }
                    } else if (curOpcode->opcode == WINED3DSIO_TEX &&
                               This->baseShader.hex_version >= WINED3DPS_VERSION(2,0)) {
                        if(opcode_token & WINED3DSI_TEXLD_PROJECT) TRACE("p");
                    }

                    /* Destination token */
                    if (curOpcode->dst_token) {

                        /* Destination token */
                        tokens_read = shader_get_param(iface, pToken, &param, &addr_token);
                        pToken += tokens_read;
                        len += tokens_read;

                        shader_dump_ins_modifiers(param);
                        TRACE(" ");
                        shader_dump_param(iface, param, addr_token, 0);
                    }

                    /* Predication token - already printed out, just skip it */
                    if (opcode_token & WINED3DSHADER_INSTRUCTION_PREDICATED) {
                        pToken++;
                        len++;
                    }

                    /* Other source tokens */
                    for (i = curOpcode->dst_token; i < curOpcode->num_params; ++i) {

                        tokens_read = shader_get_param(iface, pToken, &param, &addr_token);
                        pToken += tokens_read;
                        len += tokens_read;

                        TRACE((i == 0)? " " : ", ");
                        shader_dump_param(iface, param, addr_token, 1);
                    }
                }
                TRACE("\n");
            }
        }
        This->baseShader.functionLength = (len + 1) * sizeof(DWORD);
    } else {
        This->baseShader.functionLength = 1; /* no Function defined use fixed function vertex processing */
    }
}

void shader_delete_constant_list(
    struct list* clist) {

    struct list *ptr;
    struct local_constant* constant;

    ptr = list_head(clist);
    while (ptr) {
        constant = LIST_ENTRY(ptr, struct local_constant, entry);
        ptr = list_next(clist, ptr);
        HeapFree(GetProcessHeap(), 0, constant);
    }
}

static void shader_none_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) {}
static void shader_none_select_depth_blt(IWineD3DDevice *iface) {}
static void shader_none_load_constants(IWineD3DDevice *iface, char usePS, char useVS) {}
static void shader_none_cleanup(IWineD3DDevice *iface) {}

const shader_backend_t none_shader_backend = {
    &shader_none_select,
    &shader_none_select_depth_blt,
    &shader_none_load_constants,
    &shader_none_cleanup
};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -