/* 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); } }
/* 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++; } } } }