void FTesselatedScreenRectangleIndexBuffer::InitRHI() { TResourceArray<uint16, INDEXBUFFER_ALIGNMENT> IndexBuffer; uint32 NumIndices = NumPrimitives() * 3; IndexBuffer.AddUninitialized(NumIndices); uint16* Out = (uint16*)IndexBuffer.GetData(); for(uint32 y = 0; y < Height; ++y) { for(uint32 x = 0; x < Width; ++x) { // left top to bottom right in reading order uint16 Index00 = x + y * (Width + 1); uint16 Index10 = Index00 + 1; uint16 Index01 = Index00 + (Width + 1); uint16 Index11 = Index01 + 1; // todo: diagonal can be flipped on parts of the screen // triangle A *Out++ = Index00; *Out++ = Index01; *Out++ = Index10; // triangle B *Out++ = Index11; *Out++ = Index10; *Out++ = Index01; } } // Create index buffer. Fill buffer with initial data upon creation FRHIResourceCreateInfo CreateInfo(&IndexBuffer); IndexBufferRHI = RHICreateIndexBuffer(sizeof(uint16), IndexBuffer.GetResourceDataSize(), BUF_Static, CreateInfo); }
/** * Initialize the RHI for this rendering resource */ void InitRHI() override { const int32 NumVerts = 8; TResourceArray<FVector4, VERTEXBUFFER_ALIGNMENT> Verts; Verts.SetNumUninitialized(NumVerts); for (uint32 Z = 0; Z < 2; Z++) { for (uint32 Y = 0; Y < 2; Y++) { for (uint32 X = 0; X < 2; X++) { const FVector4 Vertex = FVector4( (X ? -1 : 1), (Y ? -1 : 1), (Z ? -1 : 1), 1.0f ); Verts[GetCubeVertexIndex(X, Y, Z)] = Vertex; } } } uint32 Size = Verts.GetResourceDataSize(); // Create vertex buffer. Fill buffer with initial data upon creation FRHIResourceCreateInfo CreateInfo(&Verts); VertexBufferRHI = RHICreateVertexBuffer(Size, BUF_Static, CreateInfo); }
/** Initialize the RHI for this rendering resource */ void InitRHI() override { TResourceArray<FFilterVertex, VERTEXBUFFER_ALIGNMENT> Vertices; Vertices.SetNumUninitialized(6); Vertices[0].Position = FVector4(1, 1, 0, 1); Vertices[0].UV = FVector2D(1, 1); Vertices[1].Position = FVector4(0, 1, 0, 1); Vertices[1].UV = FVector2D(0, 1); Vertices[2].Position = FVector4(1, 0, 0, 1); Vertices[2].UV = FVector2D(1, 0); Vertices[3].Position = FVector4(0, 0, 0, 1); Vertices[3].UV = FVector2D(0, 0); //The final two vertices are used for the triangle optimization (a single triangle spans the entire viewport ) Vertices[4].Position = FVector4(-1, 1, 0, 1); Vertices[4].UV = FVector2D(-1, 1); Vertices[5].Position = FVector4(1, -1, 0, 1); Vertices[5].UV = FVector2D(1, -1); // Create vertex buffer. Fill buffer with initial data upon creation FRHIResourceCreateInfo CreateInfo(&Vertices); VertexBufferRHI = RHICreateVertexBuffer(Vertices.GetResourceDataSize(), BUF_Static, CreateInfo); }
StuInfo* FileToInfo() { FILE *open; open=fopen("STU_INFO.txt","r"); StuInfo *L=CreateInfo(); STU temp; STU *read; read=L->head; double a=1.0*1.0; while(fscanf(open,"%d%s%d%lf%lf%lf%lf%lf",&(temp.id),temp.name,&(temp.sex),&(temp.score[0]),\ &(temp.score[1]),&(temp.score[2]),&(temp.score[3]),&(temp.score[4]))==8) { STU *p=CreateSTU(); p->id=temp.id; p->sex=temp.sex; strcpy(p->name,temp.name); double sum=0; for(int i=0;i<5;i++) { sum+=temp.score[i]; p->score[i]=temp.score[i]; } p->total=sum; L->num++; read->next=p; L->tail=p; read=read->next; } fclose(open); return L; }
virtual void InitRHI() override { const uint32 SizeInBytes = Vertices.Num() * sizeof(FDynamicMeshVertex); FProcMeshVertexResourceArray ResourceArray(Vertices.GetData(), SizeInBytes); FRHIResourceCreateInfo CreateInfo(&ResourceArray); VertexBufferRHI = RHICreateVertexBuffer(SizeInBytes, BUF_Static, CreateInfo); }
void FPaperSpriteVertexBuffer::InitRHI() { const uint32 SizeInBytes = Vertices.Num() * sizeof(FPaperSpriteVertex); FDummyResourceArrayWrapper Wrapper(Vertices.GetData(), SizeInBytes); FRHIResourceCreateInfo CreateInfo(&Wrapper); VertexBufferRHI = RHICreateVertexBuffer(SizeInBytes, BUF_Static, CreateInfo); Vertices.Empty(); }
void FPositionVertexBuffer::InitRHI() { check(VertexData); FResourceArrayInterface* ResourceArray = VertexData->GetResourceArray(); if(ResourceArray->GetResourceDataSize()) { // Create the vertex buffer. FRHIResourceCreateInfo CreateInfo(ResourceArray); VertexBufferRHI = RHICreateVertexBuffer(ResourceArray->GetResourceDataSize(),BUF_Static,CreateInfo); } }
void FRawStaticIndexBuffer::InitRHI() { uint32 IndexStride = b32Bit ? sizeof(uint32) : sizeof(uint16); uint32 SizeInBytes = IndexStorage.Num(); if (SizeInBytes > 0) { // Create the index buffer. FRHIResourceCreateInfo CreateInfo(&IndexStorage); IndexBufferRHI = RHICreateIndexBuffer(IndexStride,SizeInBytes,BUF_Static,CreateInfo); } }
int main() {//已经全部转换成小写。's会被统计成s, 连字符-没考虑 FILE *f_open; f_open=fopen("lower.txt","rb"); FILE *write[26]; FILE *INDEX; INDEX=fopen("index.txt","wb"); char name[26][6]; Info *hash[26]; for(int i=0;i<26;i++) { name[i][0]=i+'A'; strncpy(name[i]+1,".txt\0",5); write[i]=fopen(name[i],"wb"); hash[i]=CreateInfo(); } char c; char word[20]; char *p; int words=0; while((c=fgetc(f_open))!=EOF) { while(!isalpha(c)) if((c=fgetc(f_open))==EOF) goto toend; words++; p=word; while(isalpha(c)) { *p++=c; if((c=fgetc(f_open))==EOF) { *p='\0'; break; } } *p='\0'; assert(isalpha(word[0])); IfExsist(hash[word[0]-'a'],word); } toend:; PrintHash(hash,INDEX); for(int i=0;i<26;i++) { WordQsort(hash[i]); PrintResult(hash[i],write[i],i); } fclose(f_open); for(int i=0;i<26;i++) fclose(write[i]); fclose(INDEX); return 0; }
bool ds::Texture::CreateFromMem( char* Data, int Length, DWORD Type ) { Release( ); if( !ds::Render::GetDevice( ) ) { dsPushMessage( ErrD3DeviceNotCreated ); return false; } D3DX10_IMAGE_LOAD_INFO l_Info = D3DX10_IMAGE_LOAD_INFO( ); CreateInfo( Type, l_Info); ID3D10Resource* l_Resource = nullptr; HRESULT l_Result = D3DX10CreateTextureFromMemory( ds::Render::Device, Data, Length, &l_Info, nullptr, &l_Resource, nullptr ); if( FAILED( l_Result ) ) { dsPushError( ErrTextureCreate); return false; } l_Resource->QueryInterface( __uuidof( ID3D10Texture2D ), ( LPVOID* )&Texture2D ); l_Resource->Release( ); D3D10_TEXTURE2D_DESC l_Desc; Texture2D->GetDesc( &l_Desc ); Size = ds::Size( l_Desc.Width, l_Desc.Height ); if( Type & RenderTarget ) { D3D10_RENDER_TARGET_VIEW_DESC l_Target; l_Target.Format = l_Info.Format; l_Target.ViewDimension = D3D10_RTV_DIMENSION_TEXTURE2D; l_Target.Texture2D.MipSlice = 0; ds::Render::Device->CreateRenderTargetView( Texture2D, &l_Target, &TargetView ); } ShaderView[ 0 ] = CreateResourceView( this ); return true; }
void FColorVertexBuffer::InitRHI() { if( VertexData != NULL ) { FResourceArrayInterface* ResourceArray = VertexData->GetResourceArray(); if(ResourceArray->GetResourceDataSize()) { // Create the vertex buffer. FRHIResourceCreateInfo CreateInfo(ResourceArray); VertexBufferRHI = RHICreateVertexBuffer(ResourceArray->GetResourceDataSize(),BUF_Static,CreateInfo); } } }
/** Initialize the RHI for this rendering resource */ void InitRHI() override { // Indices 0 - 5 are used for rendering a quad. Indices 6 - 8 are used for triangle optimization. const uint16 Indices[] = { 0, 1, 2, 2, 1, 3, 0, 4, 5 }; TResourceArray<uint16, INDEXBUFFER_ALIGNMENT> IndexBuffer; uint32 InternalNumIndices = ARRAY_COUNT(Indices); IndexBuffer.AddUninitialized(InternalNumIndices); FMemory::Memcpy(IndexBuffer.GetData(), Indices, InternalNumIndices * sizeof(uint16)); // Create index buffer. Fill buffer with initial data upon creation FRHIResourceCreateInfo CreateInfo(&IndexBuffer); IndexBufferRHI = RHICreateIndexBuffer(sizeof(uint16), IndexBuffer.GetResourceDataSize(), BUF_Static, CreateInfo); }
/** * Initialize the RHI for this rendering resource */ void InitRHI() override { TResourceArray<uint16, INDEXBUFFER_ALIGNMENT> Indices; NumIndices = ARRAY_COUNT(GCubeIndices); Indices.AddUninitialized(NumIndices); FMemory::Memcpy(Indices.GetData(), GCubeIndices, NumIndices * sizeof(uint16)); const uint32 Size = Indices.GetResourceDataSize(); const uint32 Stride = sizeof(uint16); // Create index buffer. Fill buffer with initial data upon creation FRHIResourceCreateInfo CreateInfo(&Indices); IndexBufferRHI = RHICreateIndexBuffer(Stride, Size, BUF_Static, CreateInfo); }
BOOL SaveWnd::selectExec() { int i; BOOL bSetCur = FALSE; int oldSelect = selectNum, oldBtn = btnSelect; switch(state){ case save_fadein: if(timeGetTime() >= startTime){ alpha = 1.0f; state = save_exec; }else{ alpha = 1.0f - (startTime -timeGetTime()) /500.0f; } SetAlpha(); btn[2].selectRect.top = 565; btn[2].selectRect.bottom = btn[2].selectRect.top+25; btn[2].selectRect.left = LONG(709 +(1.0f- alpha)*(47+40*4)); btn[2].selectRect.right = btn[2].selectRect.left +86; return TRUE; case save_fadeout: if(timeGetTime() >= startTime){ alpha = 0; changeExecMode(bak_mode); return FALSE; } alpha = (startTime -timeGetTime()) /500.0f; SetAlpha(); btn[2].selectRect.top = 457+4*27; btn[2].selectRect.top += LONG((1.0f-alpha)*40); btn[2].selectRect.bottom = btn[2].selectRect.top +25; return TRUE; case save_writeSure: if(keyState.push_left || keyState.push_right || keyState.push_up || keyState.push_down){ bYesNo = !bYesNo; SetWindowCursorPos(sysInf.hWnd,yesnoBtn[bYesNo].selectRect.left+43, yesnoBtn[bYesNo].selectRect.top+12); } for(i=0;i<2;i++){ if(yesnoBtn[i].CheckState(&sysInf.msPoint)){ if(i==0){ PlayEffectNum(evtHandle[11],SE_PUSH); state = save_writeExec; return TRUE; }else{ PlayEffectNum(evtHandle[11],SE_CANCEL); state = save_exec; } } } if(keyState.push_cancel){ PlayEffectNum(evtHandle[11],SE_CANCEL); state = save_exec; } return TRUE; case save_loadSure: if(keyState.push_left || keyState.push_right || keyState.push_up || keyState.push_down){ bYesNo = !bYesNo; SetWindowCursorPos(sysInf.hWnd,yesnoBtn[bYesNo].selectRect.left+43, yesnoBtn[bYesNo].selectRect.top+12); } for(i=0;i<2;i++){ if(yesnoBtn[i].CheckState(&sysInf.msPoint)){ if(i==0){ if(SAV_Load( selectNum+offsetNum+1 )){ PlayEffectNum(evtHandle[11],SE_PUSH); startTime = timeGetTime(); state = save_loadEnd; return TRUE; } startTime = timeGetTime() +500; state = save_fadeout; return TRUE; }else{ PlayEffectNum(evtHandle[11],SE_CANCEL); state = save_exec; } } } if(keyState.push_cancel){ PlayEffectNum(evtHandle[11],SE_CANCEL); state = save_exec; } return TRUE; case save_writeExec: new_time = selectNum+offsetNum+1; SAV_Save( new_time ); useTable[selectNum+offsetNum] = TRUE; struct _stat fstatus; char fname[32]; wsprintf( fname, "save_%02d.sav", new_time ); _stat(fname,&fstatus); file_time[selectNum+offsetNum] = fstatus.st_mtime; CreateInfo(); startTime = timeGetTime(); state = save_writeEnd; case save_loadEnd: case save_writeEnd: i = timeGetTime() -startTime; if(i>1000){ if(state==save_writeEnd){ changeExecMode(bak_mode); }else{ changeExecMode(event_exec_mode); } startTime = timeGetTime(); if(voicefile[0])PlayVoice(voicefile, FALSE, 255); voicefile[0] = '\0'; bFadeOut = TRUE; } return TRUE; } btnSelect = 0xff; for(i=0;i<3;i++){ if(btn[i].CheckState(&sysInf.msPoint)){ btnSelect = i; switch(i){ case 0: PlayEffectNum(evtHandle[11],SE_PUSH); if(0==offsetNum)offsetNum = 45; else offsetNum -= 5; CreateInfo(); return TRUE; case 1: PlayEffectNum(evtHandle[11],SE_PUSH); offsetNum += 5; if(offsetNum>45)offsetNum = 0; CreateInfo(); return TRUE; default: PlayEffectNum(evtHandle[11],SE_CANCEL); startTime = timeGetTime() +500; state = save_fadeout; return TRUE; } }else if(btn_onCursor==btn[i].GetState()){ btnSelect = i; if(oldBtn != btnSelect){ PlayEffectNum(evtHandle[11],SE_SELECT); } } } for(i=0;i<10;i++){ if(pageBtn[i].CheckState(&sysInf.msPoint)){ PlayEffectNum(evtHandle[11],SE_PUSH); btnSelect = i+3; offsetNum = i*5; CreateInfo(); return TRUE; }else if(btn_onCursor==pageBtn[i].GetState()){ btnSelect = i+3; if(oldBtn != btnSelect){ PlayEffectNum(evtHandle[11],SE_SELECT); } } } if(keyState.push_action){ if(selectNum<5){ if(useTable[selectNum+offsetNum]){ PlayEffectNum(evtHandle[11],SE_PUSH); SetWindowCursorPos(sysInf.hWnd,yesnoBtn[0].selectRect.left +43, yesnoBtn[0].selectRect.top +12); if(mode==save_mode) state = save_writeSure; else state = save_loadSure; return TRUE; }else if(mode==save_mode){ PlayEffectNum(evtHandle[11],SE_PUSH); state = save_writeExec; return TRUE; } } }else if(keyState.push_cancel){ PlayEffectNum(evtHandle[11],SE_CANCEL); startTime = timeGetTime() +500; state = save_fadeout; return TRUE; }else if(keyState.push_up){ for(i=0;i<5;i++){ if(selectNum==0xff){ selectNum = 0; }else if(selectNum==0){ selectNum = 4; if(0==offsetNum)offsetNum = 45; else offsetNum -= 5; CreateInfo(); }else{ selectNum --; } if(mode==save_mode || useTable[selectNum+offsetNum])break; } if(i==5){ selectNum = 0xff; }else{ bSetCur = TRUE; } }else if(keyState.push_down){ for(i=0;i<5;i++){ if(selectNum>=4){ selectNum = 0; offsetNum += 5; if(offsetNum>45)offsetNum = 0; CreateInfo(); }else{ selectNum ++; } if(mode==save_mode || useTable[selectNum+offsetNum])break; } if(i==5){ selectNum = 0xff; }else{ bSetCur = TRUE; } }else if(keyState.push_left){ if(0==offsetNum)offsetNum = 45; else offsetNum -= 5; CreateInfo(); return TRUE; }else if(keyState.push_right){ offsetNum += 5; if(offsetNum>45)offsetNum = 0; CreateInfo(); return TRUE; } if(bSetCur){ if(sysInf.msPoint.x>=20 && sysInf.msPoint.x<706){ point.x = sysInf.msPoint.x; }else{ point.x = 20 +40; } point.y = 18 +40 +selectNum*100; SetWindowCursorPos(sysInf.hWnd, point.x, point.y); }else{ selectNum = 0xff; for(i=0;i<5;i++){ rect.left = 20; rect.right = rect.left +686; rect.top = 18 +100*i; rect.bottom = rect.top +96; if(myPtInRect(&rect, &sysInf.msPoint)){ if(mode==save_mode || useTable[i+offsetNum]){ selectNum = i; break; } } } } if(0xff != selectNum){ yesnoBtn[0].selectRect.top = yesnoBtn[1].selectRect.top = 18+128+100*selectNum; yesnoBtn[0].selectRect.bottom = yesnoBtn[1].selectRect.bottom = yesnoBtn[0].selectRect.top +25; if(selectNum!=oldSelect){ PlayEffectNum(evtHandle[11],SE_SELECT); } } return TRUE; } // SaveWnd::selectExec
SaveWnd::SaveWnd(exec_mode s_mode) { int i,j; ColorBuf wallWnd; ZeroMemory(this,sizeof(SaveWnd)); mode = s_mode; EnableMenuItem( sysInf.hMenu,ID_SAVEEXEC, MF_GRAYED ); EnableMenuItem( sysInf.hMenu,ID_LOADEXEC, MF_GRAYED ); bak_mode = sysInf.execMode; panel[0].loadLGF(pack_gparts,"database00"); panel[1].loadLGF(pack_gparts,"database01"); panel[2].loadLGF(pack_gparts,"database02"); button.loadLGF(pack_gparts,"SavePageBtn"); numParts.loadLGF(pack_gparts,"saveFont"); newParts.loadLGF(pack_gparts,"saveNew"); if(mode==save_mode){ pagebutton.loadLGF(pack_gparts,"SavePageNoBtn1"); wallWnd.loadLGF(pack_gparts,"savebg"); }else{ pagebutton.loadLGF(pack_gparts,"SavePageNoBtn2"); wallWnd.loadLGF(pack_gparts,"loadbg"); } retBtnPrt.loadLGF(pack_gparts,"returnBtn"); confirmWnd.loadLGF(pack_gparts,"saveConfirm"); yesNoWnd.loadLGF(pack_gparts,"saveYesNo"); backupWnd.createColorBuf(WIN_SIZEX,WIN_SIZEY,24,FALSE); backupWnd.BltFast(0,0,&g_DibInf.colorBuf,NULL,FALSE); backWnd.createColorBuf(WIN_SIZEX,WIN_SIZEY,24,FALSE); infoWnd.createColorBuf(686,496,32,FALSE); saveBmp.createColorBuf(thumbnailW,thumbnailH,24,FALSE); backWnd.BltFast(0,0,&backColorBuf,NULL,FALSE); backWnd.BltFast(0,0,&wallWnd,NULL,TRUE); maskWnd.createColorBuf(WIN_SIZEX,WIN_SIZEY,24,TRUE); maskWnd.alpha = 0.5f; for(i=0;i<5;i++){ backWnd.BltFast(20,18+100*i,&panel[0],NULL,TRUE); } saveBmp.Blt(NULL,&g_DibInf.colorBuf,NULL,FALSE); RECT selectRect = {709,565,709+86,565+25}; RECT btnRect[7]; for(i=0;i<5;i++){ btnRect[i].left = 0; btnRect[i].right = 86; btnRect[i].top = 25*i; btnRect[i].bottom = btnRect[i].top +25; } btn[2].Create(3,&retBtnPrt,&selectRect,btnRect,&g_DibInf.colorBuf); selectRect.left = 22; selectRect.right = selectRect.left +40; selectRect.top = 528; selectRect.bottom = selectRect.top +40; for(i=0;i<5;i++){ btnRect[i].left = 0; btnRect[i].right = btnRect[i].left +40; btnRect[i].top = i*40; btnRect[i].bottom = btnRect[i].top +40; } btn[0].Create(3,&button,&selectRect,btnRect,&g_DibInf.colorBuf); selectRect.left = 190; selectRect.right = selectRect.left +40; selectRect.top = 528; selectRect.bottom = selectRect.top +40; for(i=0;i<5;i++){ btnRect[i].left = 40; btnRect[i].right = btnRect[i].left +40; btnRect[i].top = i*40; btnRect[i].bottom = btnRect[i].top +40; } btn[1].Create(3,&button,&selectRect,btnRect,&g_DibInf.colorBuf); selectRect.top = 528; selectRect.bottom = selectRect.top +40; for(j=0;j<10;j++){ selectRect.left = 286 +j*42; selectRect.right = selectRect.left +40; for(i=0;i<7;i++){ btnRect[i].left = j*40; btnRect[i].right = btnRect[i].left +40; btnRect[i].top = i*40; btnRect[i].bottom = btnRect[i].top +40; } pageBtn[j].Create(5,&pagebutton,&selectRect,btnRect,&g_DibInf.colorBuf); } selectRect.top = 18+128; selectRect.bottom = selectRect.top +25; for(j=0;j<2;j++){ if(j==0){ selectRect.left = 20+289; selectRect.right = selectRect.left +86; }else{ selectRect.left = 20+385; selectRect.right = selectRect.left +86; } for(i=0;i<5;i++){ btnRect[i].left = j*86; btnRect[i].right = btnRect[i].left +86; btnRect[i].top = i*25; btnRect[i].bottom = btnRect[i].top +25; } yesnoBtn[j].Create(3,&yesNoWnd,&selectRect,btnRect,&g_DibInf.colorBuf); } time_t tmp_time = 0; for(i=0;i<50;i++){ char fname[32]; struct _stat fstatus; wsprintf( fname, "save_%02d.sav", i+1 ); if(0==_access(fname,0)){ useTable[i] = TRUE; _stat(fname,&fstatus); file_time[i] = fstatus.st_mtime; if(tmp_time < file_time[i]){ tmp_time = file_time[i]; new_time = i+1; } } } selectNum = btnSelect = 0xff; if(new_time){ offsetNum = ((new_time-1) /5)*5; SetWindowCursorPos(sysInf.hWnd, 100, 18+45+ 100* (new_time-1-offsetNum)); selectNum = (new_time-1-offsetNum); } CreateInfo(); wallWnd.Release(); changeExecMode(mode); startTime = timeGetTime() +500; state = save_fadein; } // SaveWnd::SaveWnd
bool FVulkanPipelineStateCache::Load(const TArray<FString>& CacheFilenames, TArray<uint8>& OutDeviceCache) { bool bLoaded = false; for (const FString& CacheFilename : CacheFilenames) { TArray<uint8> MemFile; if (FFileHelper::LoadFileToArray(MemFile, *CacheFilename, FILEREAD_Silent)) { FMemoryReader Ar(MemFile); int32 Version = -1; Ar << Version; if (Version != FDiskEntry::VERSION) { UE_LOG(LogVulkanRHI, Warning, TEXT("Unable to load shader cache '%s' due to mismatched Version %d != %d"), *CacheFilename, Version, (int32)FDiskEntry::VERSION); continue; } int32 SizeOfDiskEntry = -1; Ar << SizeOfDiskEntry; if (SizeOfDiskEntry != (int32)(sizeof(FDiskEntry))) { UE_LOG(LogVulkanRHI, Warning, TEXT("Unable to load shader cache '%s' due to mismatched size of FDiskEntry %d != %d; forgot to bump up VERSION?"), *CacheFilename, SizeOfDiskEntry, (int32)sizeof(FDiskEntry)); continue; } Ar << DiskEntries; for (int32 Index = 0; Index < DiskEntries.Num(); ++Index) { FVulkanPipeline* Pipeline = new FVulkanPipeline(Device); FDiskEntry* DiskEntry = &DiskEntries[Index]; DiskEntry->bLoaded = true; CreateDiskEntryRuntimeObjects(DiskEntry); CreatePipelineFromDiskEntry(DiskEntry, Pipeline); FVulkanPipelineStateKey CreateInfo(DiskEntry->GraphicsKey, DiskEntry->VertexInputKey, DiskEntry->ShaderHashes); // Add to the cache KeyToPipelineMap.Add(CreateInfo, Pipeline); CreatedPipelines.Add(DiskEntry, Pipeline); Pipeline->AddRef(); } Ar << OutDeviceCache; if (OutDeviceCache.Num() > 4) { uint32* Data = (uint32*)OutDeviceCache.GetData(); uint32 HeaderSize = *Data++; if (HeaderSize == 16 + VK_UUID_SIZE) { uint32 HeaderVersion = *Data++; if (HeaderVersion == VK_PIPELINE_CACHE_HEADER_VERSION_ONE) { uint32 VendorID = *Data++; if (VendorID == Device->GetDeviceProperties().vendorID) { uint32 DeviceID = *Data++; if (DeviceID == Device->GetDeviceProperties().deviceID) { uint8* Uuid = (uint8*)Data; if (FMemory::Memcmp(Device->GetDeviceProperties().pipelineCacheUUID, Uuid, sizeof(VK_UUID_SIZE)) == 0) { bLoaded = true; } } } } } } UE_LOG(LogVulkanRHI, Display, TEXT("Loaded pipeline cache file '%s', %d Pipelines, %d bytes %s"), *CacheFilename, DiskEntries.Num(), MemFile.Num(), (bLoaded ? TEXT("VkPipelineCache compatible") : TEXT(""))); break; } } return bLoaded; }
bool CoImageTIF::Decode (FILE* pFile) { Release(); XFileDisk hFile(pFile); TIFF* m_tif = _TIFFOpenEx(&hFile, "rb"); uint32 height=0; uint32 width=0; uint16 bitspersample=1; uint16 samplesperpixel=1; uint32 rowsperstrip=(DWORD)-1; uint16 photometric=0; uint16 compression=1; uint16 orientation = ORIENTATION_TOPLEFT; //<vho> uint16 res_unit; //<Trifon> uint32 x, y; float resolution, offset; BOOL isRGB; BYTE *bits; //pointer to source data BYTE *bits2; //pointer to destination data try { //check if it's a tiff file if (!m_tif) throw "Error encountered while opening TIFF file"; // <Robert Abram> - 12/2002 : get NumFrames directly, instead of looping // m_Info.nNumFrames=0; // while(TIFFSetDirectory(m_tif,(uint16)m_Info.nNumFrames)) m_Info.nNumFrames++; m_Info.nNumFrames = TIFFNumberOfDirectories(m_tif); if (!TIFFSetDirectory(m_tif, (uint16)m_Info.nFrame)) throw "Error: page not present in TIFF file"; //get image info TIFFGetField(m_tif, TIFFTAG_IMAGEWIDTH, &width); TIFFGetField(m_tif, TIFFTAG_IMAGELENGTH, &height); TIFFGetField(m_tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel); TIFFGetField(m_tif, TIFFTAG_BITSPERSAMPLE, &bitspersample); TIFFGetField(m_tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); TIFFGetField(m_tif, TIFFTAG_PHOTOMETRIC, &photometric); TIFFGetField(m_tif, TIFFTAG_ORIENTATION, &orientation); if (m_Info.nEscape == -1) { // Return output dimensions only m_Head.biWidth = width; m_Head.biHeight = height; throw "output dimensions returned"; } TIFFGetFieldDefaulted(m_tif, TIFFTAG_RESOLUTIONUNIT, &res_unit); if (TIFFGetField(m_tif, TIFFTAG_XRESOLUTION, &resolution)) { if (res_unit == RESUNIT_CENTIMETER) resolution = (float)(resolution*2.54f + 0.5f); SetXDPI((long)resolution); } if (TIFFGetField(m_tif, TIFFTAG_YRESOLUTION, &resolution)) { if (res_unit == RESUNIT_CENTIMETER) resolution = (float)(resolution*2.54f + 0.5f); SetYDPI((long)resolution); } if (TIFFGetField(m_tif, TIFFTAG_XPOSITION, &offset)) m_Info.xOffset = (long)offset; if (TIFFGetField(m_tif, TIFFTAG_YPOSITION, &offset)) m_Info.yOffset = (long)offset; m_Head.biClrUsed=0; m_Info.nBkgndIndex =-1; if (rowsperstrip>height) { rowsperstrip=height; TIFFSetField(m_tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip); } isRGB = (bitspersample >= 8) && (photometric == PHOTOMETRIC_RGB) || (photometric == PHOTOMETRIC_YCBCR) || (photometric == PHOTOMETRIC_SEPARATED) || (photometric == PHOTOMETRIC_LOGL) || (photometric == PHOTOMETRIC_LOGLUV); if (isRGB) { m_Head.biBitCount=24; } else { if ((photometric==PHOTOMETRIC_MINISBLACK)||(photometric==PHOTOMETRIC_MINISWHITE)) { if (bitspersample == 1){ m_Head.biBitCount=1; //B&W image m_Head.biClrUsed =2; } else if (bitspersample == 4) { m_Head.biBitCount=4; //16 colors gray scale m_Head.biClrUsed =16; } else { m_Head.biBitCount=8; //gray scale m_Head.biClrUsed =256; } } else if (bitspersample == 4) { m_Head.biBitCount=4; // 16 colors m_Head.biClrUsed=16; } else { m_Head.biBitCount=8; //256 colors m_Head.biClrUsed=256; } } if (m_Info.nEscape) throw "Cancelled"; // <vho> - cancel decoding CreateInfo(height, width, m_Head.biBitCount, CVLIB_IMG_FORMAT_TIF); if (m_Info.pImage == NULL) m_Info.pImage = (BYTE*)malloc (m_Head.biSizeImage); if (!GetPalette()) throw "CoImageTIF can't create image"; #if CVLIB_IMG_SUPPORT_ALPHA if (samplesperpixel==4) AlphaCreate(); if (samplesperpixel==2 && bitspersample==8) AlphaCreate(); #endif //CVLIB_IMG_SUPPORT_ALPHA TIFFGetField(m_tif, TIFFTAG_COMPRESSION, &compression); SetCodecOption(compression); // <DPR> save original compression type if (isRGB) { // FromFile the whole image into one big RGBA buffer using // the traditional TIFFReadRGBAImage() API that we trust. uint32* raster; // retrieve RGBA image uint32 *row; raster = (uint32*)_TIFFmalloc(width * height * sizeof (uint32)); if (raster == NULL) throw "No space for raster buffer"; // FromFile the image in one chunk into an RGBA array if(!TIFFReadRGBAImage(m_tif, width, height, raster, 1)) { _TIFFfree(raster); throw "Corrupted TIFF file!"; } // read the raster lines and save them in the DIB // with RGB mode, we have to change the order of the 3 samples RGB row = &raster[0]; bits2 = m_Info.pImage; for (y = 0; y < height; y++) { if (m_Info.nEscape) { // <vho> - cancel decoding _TIFFfree(raster); throw "Cancelled"; } bits = bits2; for (x = 0; x < width; x++) { *bits++ = (BYTE)TIFFGetB(row[x]); *bits++ = (BYTE)TIFFGetG(row[x]); *bits++ = (BYTE)TIFFGetR(row[x]); #if CVLIB_IMG_SUPPORT_ALPHA if (samplesperpixel==4) m_matA.data.ptr[y][x] = (BYTE)TIFFGetA(row[x]); #endif //CVLIB_IMG_SUPPORT_ALPHA } row += width; bits2 += m_Info.dwEffWidth; } _TIFFfree(raster); } else { RGBQUAD1 *pal; pal=(RGBQUAD1*)calloc(256,sizeof(RGBQUAD1)); if (pal==NULL) throw "Unable to allocate TIFF palette"; // set up the colormap based on photometric switch(photometric) { case PHOTOMETRIC_MINISBLACK: // bitmap and greyscale image types case PHOTOMETRIC_MINISWHITE: if (bitspersample == 1) { // Monochrome image if (photometric == PHOTOMETRIC_MINISBLACK) pal[1].rgbRed = pal[1].rgbGreen = pal[1].rgbBlue = 255; else pal[0].rgbRed = pal[0].rgbGreen = pal[0].rgbBlue = 255; } else { // need to build the scale for greyscale images if (photometric == PHOTOMETRIC_MINISBLACK) { for (DWORD i=0; i<m_Head.biClrUsed; i++) pal[i].rgbRed = pal[i].rgbGreen = pal[i].rgbBlue = (BYTE)(i*(255/(m_Head.biClrUsed-1))); } else { for (DWORD i=0; i<m_Head.biClrUsed; i++) pal[i].rgbRed = pal[i].rgbGreen = pal[i].rgbBlue = (BYTE)(255-i*(255/(m_Head.biClrUsed-1))); } } break; case PHOTOMETRIC_PALETTE: // color map indexed uint16 *red; uint16 *green; uint16 *blue; TIFFGetField(m_tif, TIFFTAG_COLORMAP, &red, &green, &blue); // Is the palette 16 or 8 bits ? BOOL Palette16Bits = FALSE; int n=1<<bitspersample; while (n-- > 0) { if (red[n] >= 256 || green[n] >= 256 || blue[n] >= 256) { Palette16Bits=TRUE; break; } } // load the palette in the DIB for (int i = (1 << bitspersample) - 1; i >= 0; i--) { if (Palette16Bits) { pal[i].rgbRed =(BYTE) CVT(red[i]); pal[i].rgbGreen = (BYTE) CVT(green[i]); pal[i].rgbBlue = (BYTE) CVT(blue[i]); } else { pal[i].rgbRed = (BYTE) red[i]; pal[i].rgbGreen = (BYTE) green[i]; pal[i].rgbBlue = (BYTE) blue[i]; } } break; } SetPalette(pal,m_Head.biClrUsed); //palette assign free(pal); // read the tiff lines and save them in the DIB uint32 nrow; uint32 ys; int line = CalculateLine(width, bitspersample * samplesperpixel); long bitsize= TIFFStripSize(m_tif); //verify bitsize: could be wrong if StripByteCounts is missing. if (bitsize>(long)(m_Head.biSizeImage*samplesperpixel)) bitsize=m_Head.biSizeImage*samplesperpixel; int tiled_image = TIFFIsTiled(m_tif); uint32 tw, tl; BYTE* tilebuf; if (tiled_image) { TIFFGetField(m_tif, TIFFTAG_TILEWIDTH, &tw); TIFFGetField(m_tif, TIFFTAG_TILELENGTH, &tl); rowsperstrip = tl; bitsize = TIFFTileSize(m_tif) * (int)(1+width/tw); tilebuf = (BYTE*)malloc(TIFFTileSize(m_tif)); } bits = (BYTE*)malloc(bitsize); if (bits==NULL) { throw "CoImageTIF can't allocate memory"; } for (ys = 0; ys < height; ys += rowsperstrip) { if (m_Info.nEscape) { // <vho> - cancel decoding free(bits); throw "Cancelled"; } nrow = (ys + rowsperstrip > height ? height - ys : rowsperstrip); if (tiled_image) { uint32 imagew = TIFFScanlineSize(m_tif); uint32 tilew = TIFFTileRowSize(m_tif); int iskew = imagew - tilew; uint8* bufp = (uint8*) bits; uint32 colb = 0; for (uint32 col = 0; col < width; col += tw) { if (TIFFReadTile(m_tif, tilebuf, col, ys, 0, 0) < 0) { free(tilebuf); free(bits); throw "Corrupted tiled TIFF file!"; } if (colb + tw > imagew) { uint32 owidth = imagew - colb; uint32 oskew = tilew - owidth; TileToStrip(bufp + colb, tilebuf, nrow, owidth, oskew + iskew, oskew ); } else { TileToStrip(bufp + colb, tilebuf, nrow, tilew, iskew, 0); } colb += tilew; } } else { if (TIFFReadEncodedStrip(m_tif, TIFFComputeStrip(m_tif, ys, 0), bits, nrow * line) == -1) { free(bits); throw "Corrupted TIFF file!"; } } for (y = 0; y < nrow; y++) { long offset=(nrow-y-1)*line; if (bitspersample==16) for (DWORD xi=0;xi<width;xi++) bits[xi+offset]=bits[xi*2+offset+1]; if (samplesperpixel==1) { //simple 8bpp image memcpy( m_Info.pImage+m_Info.dwEffWidth*(height-ys-nrow+y), bits+offset, m_Info.dwEffWidth); } else if (samplesperpixel==2) //8bpp image with alpha layer { int xi=0; int ii=0; int yi=height-ys-nrow+y; while (ii<line) { SetPixelIndex(xi,yi,bits[ii+offset]); #if CVLIB_IMG_SUPPORT_ALPHA m_matA.data.ptr[yi][xi] = bits[ii+offset+1]; #endif //CVLIB_IMG_SUPPORT_ALPHA ii+=2; xi++; if (xi>=(int)width) { yi--; xi=0; } } } else { //photometric==PHOTOMETRIC_CIELAB if (m_Head.biBitCount!=24) { //fix image CreateInfo(height,width,24,CVLIB_IMG_FORMAT_BMP); #if CVLIB_IMG_SUPPORT_ALPHA if (samplesperpixel==4) AlphaCreate(); #endif //CVLIB_IMG_SUPPORT_ALPHA } int xi=0; int ii=0; int yi=height-ys-nrow+y; RGBQUAD1 c; int l,a,b,bitsoffset; double p,cx,cy,cz,cr,cg,cb; while (ii<line){ bitsoffset = ii*samplesperpixel+offset; l=bits[bitsoffset]; a=bits[bitsoffset+1]; b=bits[bitsoffset+2]; if (a>127) a-=256; if (b>127) b-=256; // lab to xyz p = (l/2.55 + 16) / 116.0; cx = pow( p + a * 0.002, 3); cy = pow( p, 3); cz = pow( p - b * 0.005, 3); // white point cx*=0.95047; //cy*=1.000; cz*=1.0883; // xyz to rgb cr = 3.240479 * cx - 1.537150 * cy - 0.498535 * cz; cg = -0.969256 * cx + 1.875992 * cy + 0.041556 * cz; cb = 0.055648 * cx - 0.204043 * cy + 1.057311 * cz; if ( cr > 0.00304 ) cr = 1.055 * pow(cr,0.41667) - 0.055; else cr = 12.92 * cr; if ( cg > 0.00304 ) cg = 1.055 * pow(cg,0.41667) - 0.055; else cg = 12.92 * cg; if ( cb > 0.00304 ) cb = 1.055 * pow(cb,0.41667) - 0.055; else cb = 12.92 * cb; c.rgbRed =(BYTE)max(0,min(255,(int)(cr*255))); c.rgbGreen=(BYTE)max(0,min(255,(int)(cg*255))); c.rgbBlue =(BYTE)max(0,min(255,(int)(cb*255))); SetPixelColor(xi,yi,c); #if CVLIB_IMG_SUPPORT_ALPHA if (samplesperpixel==4) m_matA.data.ptr[yi][xi] = bits[bitsoffset+3]; #endif //CVLIB_IMG_SUPPORT_ALPHA ii++; xi++; if (xi>=(int)width) { yi--; xi=0; } } } } } free(bits); if (tiled_image) free(tilebuf); // switch(orientation) // { // case ORIENTATION_TOPRIGHT: /* row 0 top, col 0 rhs */ // Mirror(); // break; // case ORIENTATION_BOTRIGHT: /* row 0 bottom, col 0 rhs */ // Flip(); // Mirror(); // break; // case ORIENTATION_BOTLEFT: /* row 0 bottom, col 0 lhs */ // Flip(); // break; // case ORIENTATION_LEFTTOP: /* row 0 lhs, col 0 top */ // RotateRight(); // Mirror(); // break; // case ORIENTATION_RIGHTTOP: /* row 0 rhs, col 0 top */ // RotateLeft(); // break; // case ORIENTATION_RIGHTBOT: /* row 0 rhs, col 0 bottom */ // RotateLeft(); // Mirror(); // break; // case ORIENTATION_LEFTBOT: /* row 0 lhs, col 0 bottom */ // RotateRight(); // break; // } } } catch (char *message) { strncpy(m_Info.szLastError,message,255); if (m_tif) TIFFClose(m_tif); if (m_Info.nEscape==-1) return true; return false; } TIFFClose(m_tif); ImageIterator iter(this); iter.BMP2XYZ(m_Info.pImage); if (m_Info.pImage) free (m_Info.pImage); m_Info.pImage = NULL; return true; }
void RendererGPUBenchmark(FRHICommandListImmediate& RHICmdList, FSynthBenchmarkResults& InOut, const FSceneView& View, float WorkScale, bool bDebugOut) { check(IsInRenderingThread()); FRenderQueryPool TimerQueryPool(RQT_AbsoluteTime); bool bValidGPUTimer = (FGPUTiming::GetTimingFrequency() / (1000 * 1000)) != 0; if(!bValidGPUTimer) { UE_LOG(LogSynthBenchmark, Warning, TEXT("RendererGPUBenchmark failed, look for \"GPU Timing Frequency\" in the log")); return; } TResourceArray<FBenchmarkVertex> Vertices; Vertices.Reserve(GBenchmarkVertices); for (uint32 Index = 0; Index < GBenchmarkVertices; ++Index) { Vertices.Emplace(Index); } FRHIResourceCreateInfo CreateInfo(&Vertices); FVertexBufferRHIRef VertexBuffer = RHICreateVertexBuffer(GBenchmarkVertices * sizeof(FBenchmarkVertex), BUF_Static, CreateInfo); // two RT to ping pong so we force the GPU to flush it's pipeline TRefCountPtr<IPooledRenderTarget> RTItems[3]; { FPooledRenderTargetDesc Desc(FPooledRenderTargetDesc::Create2DDesc(FIntPoint(GBenchmarkResolution, GBenchmarkResolution), PF_B8G8R8A8, FClearValueBinding::None, TexCreate_None, TexCreate_RenderTargetable | TexCreate_ShaderResource, false)); Desc.AutoWritable = false; GRenderTargetPool.FindFreeElement(RHICmdList, Desc, RTItems[0], TEXT("Benchmark0")); GRenderTargetPool.FindFreeElement(RHICmdList, Desc, RTItems[1], TEXT("Benchmark1")); Desc.Extent = FIntPoint(1, 1); Desc.Flags = TexCreate_CPUReadback; // needs TexCreate_ResolveTargetable? Desc.TargetableFlags = TexCreate_None; GRenderTargetPool.FindFreeElement(RHICmdList, Desc, RTItems[2], TEXT("BenchmarkReadback")); } // set the state RHICmdList.SetBlendState(TStaticBlendState<>::GetRHI()); RHICmdList.SetRasterizerState(TStaticRasterizerState<>::GetRHI()); RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false,CF_Always>::GetRHI()); { // larger number means more accuracy but slower, some slower GPUs might timeout with a number to large const uint32 IterationCount = 70; const uint32 MethodCount = ARRAY_COUNT(InOut.GPUStats); enum class EMethodType { Vertex, Pixel }; struct FBenchmarkMethod { const TCHAR* Desc; float IndexNormalizedTime; const TCHAR* ValueType; float Weight; EMethodType Type; }; const FBenchmarkMethod Methods[] = { // e.g. on NV670: Method3 (mostly fill rate )-> 26GP/s (seems realistic) // reference: http://en.wikipedia.org/wiki/Comparison_of_Nvidia_graphics_processing_units theoretical: 29.3G/s { TEXT("ALUHeavyNoise"), 1.0f / 4.601f, TEXT("s/GigaPix"), 1.0f, EMethodType::Pixel }, { TEXT("TexHeavy"), 1.0f / 7.447f, TEXT("s/GigaPix"), 0.1f, EMethodType::Pixel }, { TEXT("DepTexHeavy"), 1.0f / 3.847f, TEXT("s/GigaPix"), 0.1f, EMethodType::Pixel }, { TEXT("FillOnly"), 1.0f / 25.463f, TEXT("s/GigaPix"), 3.0f, EMethodType::Pixel }, { TEXT("Bandwidth"), 1.0f / 1.072f, TEXT("s/GigaPix"), 1.0f, EMethodType::Pixel }, { TEXT("VertThroughPut1"), 1.0f / 1.537f, TEXT("s/GigaVert"), 0.0f, EMethodType::Vertex }, // TODO: Set weights { TEXT("VertThroughPut2"), 1.0f / 1.767f, TEXT("s/GigaVert"), 0.0f, EMethodType::Vertex }, // TODO: Set weights }; static_assert(ARRAY_COUNT(Methods) == ARRAY_COUNT(InOut.GPUStats), "Benchmark methods descriptor array lengths should match."); // Initialize the GPU benchmark stats for (int32 Index = 0; Index < ARRAY_COUNT(Methods); ++Index) { auto& Method = Methods[Index]; InOut.GPUStats[Index] = FSynthBenchmarkStat(Method.Desc, Method.IndexNormalizedTime, Method.ValueType, Method.Weight); } // 0 / 1 uint32 DestRTIndex = 0; const uint32 TimerSampleCount = IterationCount * MethodCount + 1; static FRenderQueryRHIRef TimerQueries[TimerSampleCount]; static float LocalWorkScale[IterationCount]; for(uint32 i = 0; i < TimerSampleCount; ++i) { TimerQueries[i] = TimerQueryPool.AllocateQuery(); } const bool bSupportsTimerQueries = (TimerQueries[0] != NULL); if(!bSupportsTimerQueries) { UE_LOG(LogSynthBenchmark, Warning, TEXT("GPU driver does not support timer queries.")); // Temporary workaround for GL_TIMESTAMP being unavailable and GL_TIME_ELAPSED workaround breaking drivers #if PLATFORM_MAC GLint RendererID = 0; float PerfScale = 1.0f; [[NSOpenGLContext currentContext] getValues:&RendererID forParameter:NSOpenGLCPCurrentRendererID]; { switch((RendererID & kCGLRendererIDMatchingMask)) { case kCGLRendererATIRadeonX4000ID: // AMD 7xx0 & Dx00 series - should be pretty beefy PerfScale = 1.2f; break; case kCGLRendererATIRadeonX3000ID: // AMD 5xx0, 6xx0 series - mostly OK case kCGLRendererGeForceID: // Nvidia 6x0 & 7x0 series - mostly OK PerfScale = 2.0f; break; case kCGLRendererIntelHD5000ID: // Intel HD 5000, Iris, Iris Pro - not dreadful PerfScale = 4.2f; break; case kCGLRendererIntelHD4000ID: // Intel HD 4000 - quite slow PerfScale = 7.5f; break; case kCGLRendererATIRadeonX2000ID: // ATi 4xx0, 3xx0, 2xx0 - almost all very slow and drivers are now very buggy case kCGLRendererGeForce8xxxID: // Nvidia 3x0, 2x0, 1x0, 9xx0, 8xx0 - almost all very slow case kCGLRendererIntelHDID: // Intel HD 3000 - very, very slow and very buggy driver default: PerfScale = 10.0f; break; } } for (int32 Index = 0; Index < MethodCount; ++Index) { FSynthBenchmarkStat& Stat = InOut.GPUStats[Index]; Stat.SetMeasuredTime(FTimeSample(PerfScale, PerfScale * Methods[Index].IndexNormalizedTime)); } #endif return; } // TimingValues are in Seconds FTimingSeries TimingSeries[MethodCount]; // in 1/1000000 Seconds uint64 TotalTimes[MethodCount]; for(uint32 MethodIterator = 0; MethodIterator < MethodCount; ++MethodIterator) { TotalTimes[MethodIterator] = 0; TimingSeries[MethodIterator].Init(IterationCount); } RHICmdList.EndRenderQuery(TimerQueries[0]); // multiple iterations to see how trust able the values are for(uint32 Iteration = 0; Iteration < IterationCount; ++Iteration) { for(uint32 MethodIterator = 0; MethodIterator < MethodCount; ++MethodIterator) { // alternate between forward and backward (should give the same number) // uint32 MethodId = (Iteration % 2) ? MethodIterator : (MethodCount - 1 - MethodIterator); uint32 MethodId = MethodIterator; uint32 QueryIndex = 1 + Iteration * MethodCount + MethodId; // 0 / 1 const uint32 SrcRTIndex = 1 - DestRTIndex; GRenderTargetPool.VisualizeTexture.SetCheckPoint(RHICmdList, RTItems[DestRTIndex]); SetRenderTarget(RHICmdList, RTItems[DestRTIndex]->GetRenderTargetItem().TargetableTexture, FTextureRHIRef(), true); // decide how much work we do in this pass LocalWorkScale[Iteration] = (Iteration / 10.f + 1.f) * WorkScale; RunBenchmarkShader(RHICmdList, VertexBuffer, View, MethodId, RTItems[SrcRTIndex], LocalWorkScale[Iteration]); RHICmdList.CopyToResolveTarget(RTItems[DestRTIndex]->GetRenderTargetItem().TargetableTexture, RTItems[DestRTIndex]->GetRenderTargetItem().ShaderResourceTexture, false, FResolveParams()); /*if(bGPUCPUSync) { // more consistent timing but strangely much faster to the level that is unrealistic FResolveParams Param; Param.Rect = FResolveRect(0, 0, 1, 1); RHICmdList.CopyToResolveTarget( RTItems[DestRTIndex]->GetRenderTargetItem().TargetableTexture, RTItems[2]->GetRenderTargetItem().ShaderResourceTexture, false, Param); void* Data = 0; int Width = 0; int Height = 0; RHIMapStagingSurface(RTItems[2]->GetRenderTargetItem().ShaderResourceTexture, Data, Width, Height); RHIUnmapStagingSurface(RTItems[2]->GetRenderTargetItem().ShaderResourceTexture); }*/ RHICmdList.EndRenderQuery(TimerQueries[QueryIndex]); // ping pong DestRTIndex = 1 - DestRTIndex; } } { uint64 OldAbsTime = 0; // flushes the RHI thread to make sure all RHICmdList.EndRenderQuery() commands got executed. RHICmdList.ImmediateFlush(EImmediateFlushType::FlushRHIThread); RHICmdList.GetRenderQueryResult(TimerQueries[0], OldAbsTime, true); TimerQueryPool.ReleaseQuery(TimerQueries[0]); for(uint32 Iteration = 0; Iteration < IterationCount; ++Iteration) { uint32 Results[MethodCount]; for(uint32 MethodId = 0; MethodId < MethodCount; ++MethodId) { uint32 QueryIndex = 1 + Iteration * MethodCount + MethodId; uint64 AbsTime; RHICmdList.GetRenderQueryResult(TimerQueries[QueryIndex], AbsTime, true); TimerQueryPool.ReleaseQuery(TimerQueries[QueryIndex]); uint64 RelTime = FMath::Max(AbsTime - OldAbsTime, 1ull); TotalTimes[MethodId] += RelTime; Results[MethodId] = RelTime; OldAbsTime = AbsTime; } for(uint32 MethodId = 0; MethodId < MethodCount; ++MethodId) { float TimeInSec = Results[MethodId] / 1000000.0f; if (Methods[MethodId].Type == EMethodType::Vertex) { // to normalize from seconds to seconds per GVert float SamplesInGVert = LocalWorkScale[Iteration] * GBenchmarkVertices / 1000000000.0f; TimingSeries[MethodId].SetEntry(Iteration, TimeInSec / SamplesInGVert); } else { check(Methods[MethodId].Type == EMethodType::Pixel); // to normalize from seconds to seconds per GPixel float SamplesInGPix = LocalWorkScale[Iteration] * GBenchmarkResolution * GBenchmarkResolution / 1000000000.0f; // TimingValue in Seconds per GPixel TimingSeries[MethodId].SetEntry(Iteration, TimeInSec / SamplesInGPix); } } } if(bSupportsTimerQueries) { for(uint32 MethodId = 0; MethodId < MethodCount; ++MethodId) { float Confidence = 0.0f; // in seconds per GPixel float NormalizedTime = TimingSeries[MethodId].ComputeValue(Confidence); if(Confidence > 0) { FTimeSample TimeSample(TotalTimes[MethodId] / 1000000.0f, NormalizedTime); InOut.GPUStats[MethodId].SetMeasuredTime(TimeSample, Confidence); } } } } }
/************************************************************************ Function: WORD GOLDrawCallback() Overview: This function must be implemented by user. GOLDraw() function calls it each time when GOL objects drawing is completed. User drawing should be done here. GOL will not change color, line type and clipping region settings while this function returns zero. Input: none Output: If the function returns non-zero the draw control will be passed to GOL. GOLDraw() can proceed and re-draw objects that needs to be redrawn. ************************************************************************/ bool GFX_GOL_DrawCallback(void) { static uint32_t timeClock = 0; // GFX_GOL_ANALOGCLOCK *pAc; switch(screenState) { case CREATE_BACKGROUND: screenState = DISPLAY_BACKGROUND; // switch to next state return (1); case DISPLAY_BACKGROUND: CreatePreLoadScreen(); screenState = CREATE_MAIN; return(1); case CREATE_MAIN: while(GFX_Layer(PIP1, DISABLE, 0, 0) == GFX_STATUS_FAILURE); CreateMainScreen(1); screenState = DISPLAY_MAIN; // switch to next state timeClock =0; return (1); // draw objects created case DISPLAY_MAIN: if((TimerTick_GetTick() - timeClock) >= 5000) { timeClock = TimerTick_GetTick(); // pAc = (GFX_GOL_ANALOGCLOCK *)GFX_GOL_ObjectFind(MAIN_SCREEN_ID_ANALOG_CLOCK); // GFX_GOL_ObjectStateSet(pAc, GFX_GOL_ANALOGCLOCK_TICK); } return (1); case CREATE_INFO: //Use PIP for this screen CreateInfo(); while(GFX_Layer(PIP1, SET_PAGE_START, 164,0) == GFX_STATUS_FAILURE); while(GFX_Layer(PIP1, SET_SIZE, GFX_MaxXGet()-164,GFX_MaxYGet()) == GFX_STATUS_FAILURE); while(GFX_Layer(PIP1, SET_PAGE, PIP_PAGE_BUFFER, 0) == GFX_STATUS_FAILURE); while(GFX_Layer(PIP1, SET_LAYER_START, 160,0) == GFX_STATUS_FAILURE); while(GFX_Layer(PIP1, ENABLE, 0, 0) == GFX_STATUS_FAILURE); screenState = DISPLAY_INFO; // switch to next state return (0); case CREATE_SPEED: while(GFX_Layer(PIP1, DISABLE, 0, 0) == GFX_STATUS_FAILURE); CreateSpeed(); screenState = CREATE_MAIN; // switch to next state return (1); // draw objects created case CREATE_COMFORT: while(GFX_Layer(PIP1, DISABLE, 0, 0) == GFX_STATUS_FAILURE); CreateComfortScreen(); // create window and sliders screenState = DISPLAY_COMFORT; // switch to next state return (1); // draw objects created case CREATE_SCROLLING: while(GFX_Layer(PIP1, DISABLE, 0, 0) == GFX_STATUS_FAILURE); GFX_TransitionParametersSet(0,0,PUSH, GFX_ActivePageGet(), BACKGROUND_BUFFER, 1,16,LEFT_TO_RIGHT); while(GFX_Transition(&GFX_Primitive_instance.transitionParams,GFX_MaxXGet(),GFX_MaxYGet()) == GFX_STATUS_FAILURE); GFX_TransitionParametersSet(0,0,PUSH,BACKGROUND_BUFFER,GFX_ActivePageGet(), 1,10,TOP_TO_BOTTOM); while(GFX_Transition(&GFX_Primitive_instance.transitionParams,GFX_MaxXGet(),GFX_MaxYGet()) == GFX_STATUS_FAILURE); GFX_TransitionParametersSet(0,0,PUSH,GFX_ActivePageGet(),BACKGROUND_BUFFER, 1,8,RIGHT_TO_LEFT); while(GFX_Transition(&GFX_Primitive_instance.transitionParams,GFX_MaxXGet(),GFX_MaxYGet()) == GFX_STATUS_FAILURE); GFX_TransitionParametersSet(0,0,PUSH,BACKGROUND_BUFFER,GFX_ActivePageGet(), 1,5,BOTTOM_TO_TOP); while(GFX_Transition(&GFX_Primitive_instance.transitionParams,GFX_MaxXGet(),GFX_MaxYGet()) == GFX_STATUS_FAILURE); screenState = CREATE_MAIN; return(1); // draw objects created case CREATE_GRADIENT: while(GFX_Layer(PIP1, DISABLE, 0, 0) == GFX_STATUS_FAILURE); CreateGradientScreen(); // create window screenState = DISPLAY_GRADIENT; // switch to next state return (1); // draw objects created case DISPLAY_SCROLLING: case DISPLAY_GRADIENT: case DISPLAY_COMFORT: case DISPLAY_SPEED: case DISPLAY_INFO: return (1); // redraw objects if needed case CREATE_ALPHABLEND: while(GFX_Layer(PIP1, DISABLE, 0, 0) == GFX_STATUS_FAILURE); CreateAlphaBlendScreen(); screenState = DISPLAY_ALPHABLEND; return(1); case DISPLAY_ALPHABLEND: if((TimerTick_GetTick() - timeClock) >= 500) { if(DisplayAlphaBlendScreen() == true) screenState = CREATE_MAIN; } return (1); // redraw objects if needed default: break; } return (1); // release drawing control to GOL }