Ejemplo n.º 1
0
/* Function `f_cat`
 *
 * Behavs: Append text string `str` to file `file`
 * Params:
 *  `file`: Name of the file to be appended with
 *   `str`: NULL terminated string as appendage
 * Return:
 *       0: Success
 *       -: Failed for file open error
 *       +: Failed for file write error
 *
*/
int f_cat(const char *file,const char *str) {
    int fd,len,ret;
    const void *p;
    if((fd=open(file,O_WRONLY|O_CREAT|O_APPEND,FMASK))==-1)
        return -1;
    for(p=str,len=strlen(str),ret=0; len>0&&ret!=-1; vpm(p,ret),len-=ret)
        ret=write(fd,p,len);
    close(fd);
    return len;
}
void Vc4Shader::Emit_Prologue_VS()
{
    assert(this->uShaderType == D3D10_SB_VERTEX_SHADER);

    VC4_ASSERT(cInput < 16); // VR_SETUP:NUM limitation, vpm only can read up to 16 values.

    {
        Vc4Instruction Vc4Inst(vc4_load_immediate_32);
        Vc4Register vr_setup(VC4_QPU_ALU_REG_A, VC4_QPU_WADDR_VPMVCD_RD_SETUP);
        Vc4Register value; value.SetImmediateI(MAKE_VR_SETUP(cInput, 1, true, false, VC4_QPU_32BIT_VECTOR, 0));
        Vc4Inst.Vc4_a_LOAD32(vr_setup, value);
        Vc4Inst.Emit(CurrentStorage);
    }

    {
        Vc4Instruction Vc4Inst(vc4_load_immediate_32);
        Vc4Register vw_setup(VC4_QPU_ALU_REG_B, VC4_QPU_WADDR_VPMVCD_WR_SETUP);
        Vc4Register value; value.SetImmediateI(MAKE_VW_SETUP(1, true, false, VC4_QPU_32BIT_VECTOR, 0));
        Vc4Inst.Vc4_a_LOAD32(vw_setup, value);
        Vc4Inst.Emit(CurrentStorage);
    }

    for (uint8_t iRegUsed = 0, iRegIndex = 0; iRegUsed < this->cInput; iRegIndex++)
    {
        Vc4Instruction Vc4Inst;
        Vc4Register raX = this->InputRegister[iRegIndex / 4][iRegIndex % 4];
        if (raX.GetFlags().valid)
        {
            assert(raX.GetMux() == VC4_QPU_ALU_REG_A || raX.GetMux() == VC4_QPU_ALU_REG_B);
            Vc4Register vpm(raX.GetMux(), VC4_QPU_RADDR_VPM);
            Vc4Inst.Vc4_a_MOV(raX, vpm);
            Vc4Inst.Emit(CurrentStorage);
            iRegUsed++;
        }
    }

    { // Emit a NOP
        Vc4Instruction Vc4Inst;
        Vc4Inst.Emit(CurrentStorage);
    }
}
Ejemplo n.º 3
0
/* Function `f_append_file`
 *
 * Behavs: Append content of file `src` to file `dst`
 * Params:
 *   `src`: Name of the file holding the data to be appended
 *   `dst`: Name of the file to be appended with
 *  `mode`: Mode for opening the destination file
 * Return:
 *       0: Success
 *      -1: Failed for file read error
 *      -2: Failed for file `src` open error
 *      -4: Failed for file `dst` open error
 *      -8: Failed for memory allocation error
 *       +: Failed for file write error
 *
*/
static int f_append_file(const char *src,const char *dst,int mode) {
#ifndef BUFFER_IN_STACK
    char *buf;
#else
    char buf[READ_BUFFER_SIZE];
#endif
    int sfd,dfd,len,ret;
    const void *p;
#ifndef BUFFER_IN_STACK
    if(!(buf=(char*)malloc(READ_BUFFER_SIZE*sizeof(char)))) {
        return -8;
    }
#endif
    if((sfd=open(src,O_RDONLY,FMASK))==-1) {
#ifndef BUFFER_IN_STACK
        free(buf);
#endif
        return -2;
    }
    if((dfd=open(dst,O_WRONLY|mode,FMASK))==-1) {
#ifndef BUFFER_IN_STACK
        free(buf);
#endif
        close(sfd);
        return -4;
    }
    while((len=read(sfd,buf,READ_BUFFER_SIZE))>0) {
        for(p=buf,ret=0; len>0&&ret!=-1; vpm(p,ret),len-=ret)
            ret=write(dfd,p,len);
        if(len)
            break;
    }
#ifndef BUFFER_IN_STACK
    free(buf);
#endif
    close(sfd);
    close(dfd);
    return len;
}
int
main(int argc, char **argv)
{
	return vpm(argc, argv);
}
void Vc4Shader::Emit_ShaderOutput_VS(boolean bVS)
{
    assert(this->uShaderType == D3D10_SB_VERTEX_SHADER);
    
    Vc4Register vpm(VC4_QPU_ALU_REG_B, VC4_QPU_WADDR_VPM);

    Vc4Register pos[4]; // X/Y/Z/W.
    for (uint8_t iPos = 0; iPos < this->cOutput; iPos++)
    {
        if (this->OutputRegister[iPos / 4][iPos % 4].GetFlags().position)
        {
            for (uint8_t i = iPos; i < iPos + 4; i++)
            {
                Vc4Register reg = this->OutputRegister[i / 4][i % 4];
                assert(reg.GetFlags().position);
                pos[this->SwizzleMaskToIndex(reg.GetSwizzleMask())] = reg;
            }
            break;
        }
    }

    // Only CS emits raw coordinates.
    if (!bVS)
    {
        // Xc, Yc, Zc, Wc
        for (uint8_t i = 0; i < 4; i++)
        {
            Vc4Register src = pos[i];
            Vc4Instruction Vc4Inst;
            Vc4Inst.Vc4_m_MOV(vpm, src);
            Vc4Inst.Emit(CurrentStorage);
        }
    }

    // calculate 1/W
    {
        // send W to sfu_recip.
        {
            Vc4Register sfu_recip((pos[3].GetMux() == VC4_QPU_ALU_REG_A ? VC4_QPU_ALU_REG_B : VC4_QPU_ALU_REG_A), VC4_QPU_WADDR_SFU_RECIP);
            Vc4Instruction Vc4Inst;
            Vc4Inst.Vc4_a_MOV(sfu_recip, pos[3]);
            Vc4Inst.Emit(CurrentStorage);
        }

        // Issue 2 NOPs to wait result of sfu_recip.
        for (uint8_t i = 0; i < 2; i++)
        {
            Vc4Instruction Vc4Inst;
            Vc4Inst.Emit(CurrentStorage);
        }
    }

    // Now, r4 is 1/W.
    Vc4Register r4(VC4_QPU_ALU_R4);
    
    // Ys/Xs
    {
        // scale by RT dimension (read from uniform). Result in r0/r1.
        {
            for (uint8_t i = 0; i < 2; i++)
            {
                Vc4Register rX(VC4_QPU_ALU_R0 + i, VC4_QPU_WADDR_ACC0 + i); // r0 and r1.
                
                { // divide Xc/Yc by W.
                    Vc4Instruction Vc4Inst;
                    Vc4Inst.Vc4_m_FMUL(rX, pos[i], r4);
                    Vc4Inst.Emit(CurrentStorage);
                }

                { // Scale Xc/Yc with viewport.
                    Vc4Instruction Vc4Inst;
                    Vc4Register unif((rX.GetMux() == VC4_QPU_ALU_REG_A ? VC4_QPU_ALU_REG_B : VC4_QPU_ALU_REG_A), VC4_QPU_RADDR_UNIFORM); // use opossit register file.
                    Vc4Inst.Vc4_m_FMUL(rX, rX, unif);
                    Vc4Inst.Emit(CurrentStorage);
                    {
                        VC4_UNIFORM_FORMAT u;
                        u.Type = (i == 0 ? VC4_UNIFORM_TYPE_VIEWPORT_SCALE_X : VC4_UNIFORM_TYPE_VIEWPORT_SCALE_Y);
                        this->AddUniformReference(u);
                    }
                }
            }
        }

        // Convert r0/r1 to 16bits float and pack them into ra16, then output to vpm.
        {
            Vc4Register ra16(VC4_QPU_ALU_REG_A, 16);

            for (uint8_t i = 0; i < 2; i++)
            {
                Vc4Register rX(VC4_QPU_ALU_R0 + i); // r0 and r1.
                Vc4Instruction Vc4Inst;
                Vc4Inst.Vc4_a_FTOI(ra16, rX); // REUSE ra16 as temp is no longer needed.
                Vc4Inst.Vc4_a_Pack(VC4_QPU_PACK_A_16a + i); // Pack to 16a or 16b.
                Vc4Inst.Emit(CurrentStorage);
            }

            // Issue NOP as ra16 is just written.
            {
                Vc4Instruction Vc4Inst;
                Vc4Inst.Emit(CurrentStorage);
            }

            // Output to vpm.
            {
                Vc4Instruction Vc4Inst;
                Vc4Inst.Vc4_m_MOV(vpm, ra16);
                Vc4Inst.Emit(CurrentStorage);
            }
        }
    }

    // Zs
    { // Zs = Zc / W // TODO: Z offset
        Vc4Instruction Vc4Inst;
        Vc4Inst.Vc4_m_FMUL(vpm, pos[2], r4);
        Vc4Inst.Emit(CurrentStorage);
    }

    // 1/Wc
    {
        // Move result of sfu_recip (come up at r4) to vpm.
        {
            Vc4Instruction Vc4Inst;
            Vc4Inst.Vc4_m_MOV(vpm, r4);
            Vc4Inst.Emit(CurrentStorage);
        }
    }

    // Only VS emits "varying" (everything read from vpm except position data).
    if (bVS)
    {
        for (uint8_t i = 0, iRegUsed = 0; iRegUsed < this->cOutput; i++ )
        {
            Vc4Register src = this->OutputRegister[i / 4][i % 4];
            if (src.GetFlags().valid)
            {
                if (src.GetFlags().linkage)
                {
                    Vc4Instruction Vc4Inst;
                    Vc4Inst.Vc4_m_MOV(vpm, src);
                    // Vc4Inst.Vc4_m_FMUL(vpm, src, r4);
                    Vc4Inst.Emit(CurrentStorage);
                }
                iRegUsed++;
            }
        }
    }
}