Example #1
0
static void SetUndergroundSys()
{
	AcStringArray Name_Sys,is_Runing,resons;
	ReadDataFromFile(TEMPGAS_OBJCT_NAME,Name_Sys,is_Runing,resons);
	GoToBMark(_T("GasSysBookTemp"));
	int Num_Sys = Name_Sys.length();
	if( 0 >= Num_Sys )
	{
		MyWord->InsertSymbol(_T("Wingdings"),-3843);//×
		Num_Sys = 0;
	}
	else
	{
		MyWord->InsertSymbol(_T("Wingdings"),-3842);//√
	}

	CString strNum;
	strNum.Format(_T("%d"),Num_Sys);
	MyWord->FindWord(_T("{{Num_Temp_Sys}}"),strNum);

	GoToBMark(_T("GasSysTableTemp"));
	if(CreatTable(Name_Sys,is_Runing,resons,Num_Sys))
	{
		DeleteExcludeLine(_T("GasSys_Ret"));
	}

}
clsProjectFile::clsProjectFile(bool isSaveFile, bool *pStartDebugging, QString projectFile) :
	m_pMainWindow(qtDLGNanomite::GetInstance())
{
	if(isSaveFile)
	{
		if(projectFile.length() <= 0)
		{
			projectFile = QFileDialog::getSaveFileName(m_pMainWindow, "Please select a save path", QDir::currentPath(), "Nanomite Project Files (*.ndb)");

			if(projectFile.length() <= 0)
			{
				QMessageBox::critical(m_pMainWindow, "Nanomite", "Invalid file selected!", QMessageBox::Ok, QMessageBox::Ok);
				return;
			}
		}

		if(!WriteDataToFile(projectFile))
		{
			QMessageBox::critical(m_pMainWindow, "Nanomite", "Error while saving the data!", QMessageBox::Ok, QMessageBox::Ok);
		}
		else
		{
			QMessageBox::information(m_pMainWindow, "Nanomite", "Data has been saved!", QMessageBox::Ok, QMessageBox::Ok);
		}
	}
	else
	{
		if(projectFile.length() <= 0)
		{
			projectFile = QFileDialog::getOpenFileName(m_pMainWindow, "Please select a file to load", QDir::currentPath(), "Nanomite Project Files (*.ndb)");

			if(projectFile.length() <= 0)
			{
				QMessageBox::critical(m_pMainWindow, "Nanomite", "Invalid file selected!", QMessageBox::Ok, QMessageBox::Ok);
				return;
			}
		}

		if(!ReadDataFromFile(projectFile))
		{
			QMessageBox::critical(m_pMainWindow, "Nanomite", "Error while reading the data!", QMessageBox::Ok, QMessageBox::Ok);
			return;
		}
		else
		{
			QMessageBox::information(m_pMainWindow, "Nanomite", "Data has been loaded!", QMessageBox::Ok, QMessageBox::Ok);
		}

		*pStartDebugging = true;

	}
}
Example #3
0
STDMETHODIMP CTextObject::SetData(FORMATETC* pFormatEtc, STGMEDIUM* pMedium, BOOL fRelease)
{
	if (pMedium == NULL)
		return E_INVALIDARG;
	HRESULT hRes;
	if (pFormatEtc != NULL)
	{
		if (pFormatEtc->cfFormat == CF_TEXT || pFormatEtc->cfFormat == CF_UNICODETEXT)
		{
			switch (pMedium->tymed)
			{
			case TYMED_HGLOBAL:
				{
					HGLOBAL hGlobal = pMedium->hGlobal;
					if (hGlobal != NULL)
						hRes = ReadDataFromHGlobal(hGlobal, pFormatEtc->cfFormat) ? S_OK : E_OUTOFMEMORY;
					else
						hRes = DV_E_FORMATETC;
				}
				break;
			case TYMED_FILE:
				{
					PWSTR pszFileName = pMedium->lpszFileName;
					if (pszFileName != NULL)
						hRes = ReadDataFromFile(CW2TEX<MAX_PATH>(pszFileName), pFormatEtc->cfFormat) ? S_OK : E_OUTOFMEMORY;
					else
						hRes = DV_E_FORMATETC;
				}
				break;
			case TYMED_ISTREAM:
				{
					IStream* pStream = pMedium->pstm;
					if (pStream != NULL)
						hRes = ReadDataFromStream(pStream, pFormatEtc->cfFormat) ? S_OK : E_OUTOFMEMORY;
					else
						hRes = DV_E_FORMATETC;
				}
				break;
			default:
				hRes = DV_E_TYMED;
			}
		}
		else
			hRes = DV_E_FORMATETC;
	}
	else
		hRes = E_INVALIDARG;
	if (fRelease)
		ReleaseStgMedium(pMedium);
	return hRes;
}
Example #4
0
//---------------------------------------------------------------------------
bool __fastcall TIdentity::VerifyPassWord(AnsiString ansiPassword)
{
    bool bRet = false;
    BYTE key[10]="03055030";
    AnsiString asPath = asSetupPath+"\\"+asPasswordName;
    unsigned char password[LOGIN_PASSWORD_MAX];

    if(ReadDataFromFile(password,LOGIN_PASSWORD_MAX, key, asPath.c_str()) == S_DES_SUCCESS)
    {
        if(strcmp(password+2, ansiPassword.c_str())== 0)
        {
            bRet = true;
        }
    }

    return bRet;
}
TInt CSimulateMessageServerSession::RemoveTask(const SimMsgData& aTask)
	{
	RSimMsgDataArray array;
	ReadDataFromFile(array);
	TBool duplicate = EFalse;
	for (TInt i = array.Count() - 1; i >= 0; i--)
		{
		SimMsgData* task = array[i];
		if (IsSameTask(*task, aTask))
			{
			array.Remove(i);
			break;
			}
		}
	WriteDataToFile(array);
	array.Close();
	}
Example #6
0
void CMsregPacket::ReadFromFile(CFile& cfFile)
{
	// Call the top level object in the derivation chain to actually
	// read the data from the file. A checksum will be accumulated as
	// the reading progresses. Note that the header will not be included
	// in the checksum.

	DWORD dwChecksum = 0;

	ReadDataFromFile(cfFile, dwChecksum);

	// Check that the header read matches the accumulated values.

	if (m_Header.dwChecksum != dwChecksum)
	{
		AfxThrowFileException(CFileException::invalidFile);
	}
}
// Test if MusicBrainzClient::Start() parses a track correctly.
TEST_F(MusicBrainzClientTest, ParseTrack) {
  QByteArray data = ReadDataFromFile(":testdata/recording.xml");
  ASSERT_FALSE(data.isEmpty());

  // Expected results from the test file recording.xml:
  const int expected_track_number = 6;
  const QString expected_title = "Victoria und ihr Husar: Pardon Madame";
  const QString expected_artist = "Paul Abraham";
  const QString expected_album = "An Evening at the Operetta";

  // Create a MusicBrainzClient instance with mock_network_.
  MusicBrainzClient musicbrainz_client(nullptr, mock_network_.get());

  // Hook the data as the response to a query of a given type.
  QMap<QString, QString> params;
  params["inc"] = "artists+releases+media";
  MockNetworkReply* discid_reply =
      mock_network_->ExpectGet("recording", params, 200, data);

  QSignalSpy spy(&musicbrainz_client,
                 SIGNAL(Finished(int, const MusicBrainzClient::ResultList&)));
  ASSERT_TRUE(spy.isValid());
  EXPECT_EQ(0, spy.count());

  // Start the request and get a result.
  // The mbid argument doesn't matter in the test.
  const int sent_id = 0;
  musicbrainz_client.Start(sent_id, QStringList() << "fooMbid");
  discid_reply->Done();
  QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
  EXPECT_EQ(1, spy.count());

  QList<QVariant> result = spy.takeFirst();
  int id = result.takeFirst().toInt();
  EXPECT_EQ(sent_id, id);

  ResultList tracks = result.takeFirst().value<ResultList>();
  for (const MusicBrainzClient::Result& track : tracks) {
    EXPECT_EQ(expected_track_number, track.track_);
    EXPECT_EQ(expected_title, track.title_);
    EXPECT_EQ(expected_artist, track.artist_);
    EXPECT_EQ(expected_album, track.album_);
  }
}
Example #8
0
//---------------------------------------------------------------------------
Login_Mode __fastcall TIdentity::GetLoginMode()
{
    Login_Mode loginMode = LM_LONGIN_MODE_UNKNOWN;
    BYTE key[10]="03055030";
    unsigned char password[LOGIN_PASSWORD_MAX];
    AnsiString asPath = asSetupPath+"\\"+asPasswordName;
    if(ReadDataFromFile(password,LOGIN_PASSWORD_MAX, key, asPath.c_str()) == S_DES_SUCCESS)
    {
         if(password[0] =='0' && password[1] =='0'){
            loginMode = LM_OPERATOR;
        }else if(password[0] =='0' && password[1] =='1'){
            loginMode = LM_ENGINEER;
        }else{
            loginMode = LM_LONGIN_MODE_UNKNOWN;
        }
    }

    return loginMode;
}
Example #9
0
void injectApploader(char *sourcePath) {
	/*
	**  this doesn't work, yet... requires some serious shifting of other data...
	*/
	
	verbosePrint("Injecting the apploader...");
	
	//first, load the file into memory...
	
	u32 length = GetFilesizeFromPath(sourcePath);
	char *data = (char*)malloc(length);
	
	if (ReadDataFromFile(sourcePath, data) != length) {
		printf("An error occurred reading the file (%s)", sourcePath);
		free(data);
		return;
	}
	
	free(data);
}
Example #10
0
/////////////////////////////////////////////////////////////////////////
//                                          
// SetAlgorithm
// 
// Description 
//  Set algorithm from file. If file has been previously used in another instance
// then data is shared between instances
// Parameters:
//	lpDataFile : [in] file name
//	ulId        : [in] optional Id to identify the data
//
// Return Values:
//	S_OK, 
//  E_INVALIDARG E_OUTOFMEMORY, E_FAIL
///////////////////////////////////////////////////////////////////////////
HRESULT Classifier::SetAlgorithm(LPCTSTR lpDataFile, ULONG ulId)
{
    HRESULT		hRet = -1;

    LogAssert(NULL != lpDataFile);

    if (NULL == lpDataFile)
    {
        return -2;
    }

    // Clear any existing algorithm data
    ResetData();

    LogAssert(ShareTable::s_cInitialize > 0);
    pthread_mutex_lock(&ShareTable::s_MutexLock);
    {
        // Check if data is available in the shared cache (multithreaded apps)
        hRet = s_ShareTable.GetEntry(lpDataFile, &m_pDatabuf, &m_cDatabuf, &m_lpDataFileName);

        if (!SUCCEEDED(hRet))
        {
            // Should be no data
        	LogAssert(NULL == m_pDatabuf);

            hRet = ReadDataFromFile(lpDataFile, ulId);
        }
    }
    pthread_mutex_unlock(&ShareTable::s_MutexLock);

    if (SUCCEEDED(hRet) && m_cDatabuf > 0)
    {
        hRet =  LoadClassifierData(m_pDatabuf, m_cDatabuf);
    }

    return hRet;
}
Example #11
0
int __fastcall TIdentity::SetLoginMode(Login_Mode loginMode)
{
    BYTE key[10]="03055030";
    int iRet = -1;
    unsigned char password[LOGIN_PASSWORD_MAX];
    AnsiString asPath = asSetupPath+"\\"+asPasswordName;

    if(ReadDataFromFile(password,LOGIN_PASSWORD_MAX, key, asPath.c_str()) == S_DES_SUCCESS)
    {
        if(loginMode == LM_OPERATOR){
            password[0] = '0';
            password[1] = '0';
        }else if(loginMode == LM_ENGINEER){
            password[0] = '0';
            password[1] = '1';
        }else{
           goto Finish;
        }
        iRet = WriteDataToFile(password,LOGIN_PASSWORD_MAX, key, asPath.c_str());
    }

Finish:
    return iRet;
}
TInt CSimulateMessageServerSession::AddTask(SimMsgData* aTask)
	{
	RSimMsgDataArray array;
	ReadDataFromFile(array);
	TBool duplicate = EFalse;
	for (TInt i = 0; i < array.Count(); i++)
		{
		SimMsgData* task = array[i];
		if (IsSameTask(*task, *aTask))
			{
			duplicate = ETrue;
			break;
			}
		}
	if (!duplicate)
		{
//		array.Append(aTask);
		AddTaskToArray(aTask,array);
		}
	WriteDataToFile(array);
	array.Close();

	return duplicate;
	}
Example #13
0
void injectDiskHeaderInfo(char *sourcePath) {
	/*
	**  take a diskHeaderInfo (bi2.bin) from sourcePath and inject it into gcmFile.
	*/
	
	verbosePrint("Injecting the disk header info...");
	
	char *buf = (char*)malloc(GetFilesizeFromPath(sourcePath));
	
	if (ReadDataFromFile(buf, sourcePath) != GCM_DISK_HEADER_INFO_LENGTH) {
		free(buf);
		printf("This does not appear to be a diskheaderinfo (%s)\n", sourcePath);
		exit(EXIT_FAILURE);
	}
	
	if (GCMPutDiskHeaderInfo(gcmFile, buf) != GCM_SUCCESS) {
		free(buf);
		printf("An error occurred when writing the disk header info! (%d)\n", GCMErrno);
		exit(EXIT_FAILURE);
	}
	
	free(buf);
	return;
}
// For a recording with multiple releases, we should get them all.
TEST_F(MusicBrainzClientTest, ParseTrackWithMultipleReleases) {
  QByteArray data =
      ReadDataFromFile(":testdata/recording_with_multiple_releases.xml");
  ASSERT_FALSE(data.isEmpty());

  const int expected_number_of_releases = 7;

  // Create a MusicBrainzClient instance with mock_network_.
  MusicBrainzClient musicbrainz_client(nullptr, mock_network_.get());

  // Hook the data as the response to a query of a given type.
  QMap<QString, QString> params;
  params["inc"] = "artists+releases+media";
  MockNetworkReply* discid_reply =
      mock_network_->ExpectGet("recording", params, 200, data);

  QSignalSpy spy(&musicbrainz_client,
                 SIGNAL(Finished(int, const MusicBrainzClient::ResultList&)));
  ASSERT_TRUE(spy.isValid());
  EXPECT_EQ(0, spy.count());

  // Start the request and get a result.
  // The mbid argument doesn't matter in the test.
  const int sent_id = 0;
  musicbrainz_client.Start(sent_id, QStringList() << "fooMbid");
  discid_reply->Done();
  QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
  EXPECT_EQ(1, spy.count());

  QList<QVariant> result = spy.takeFirst();
  int id = result.takeFirst().toInt();
  EXPECT_EQ(sent_id, id);

  ResultList tracks = result.takeFirst().value<ResultList>();
  EXPECT_EQ(expected_number_of_releases, tracks.count());
}
Example #15
0
int main(int argc, char **argv) {

	char *newName = NULL;
	char *newDeveloper = NULL;
	char *newFullName = NULL;
	char *newFullDeveloper = NULL;
	char *newDescription = NULL;
	
	char *extractIconPath = NULL;
	char *injectIconPath = NULL;

	int modIndex = 0;
	
	int extractFormat = RAW_FORMAT;
	int injectFormat = RAW_FORMAT;

	char *currentArg = NULL;
	do {
		currentArg = GET_NEXT_ARG;
		if (!currentArg) {
			//eek, there's no arg! must be an argument error... print usage...
			
			printUsage();
			exit(1);
		} else if (CHECK_ARG(ARG_HELP)) {
			//they want the extended usage, so print it and bail...
			
			printExtendedUsage();
			exit(1);
		} else if (CHECK_ARG(ARG_MOD_NTH)) {
			//they only want the nth record to be printed...
		
			modIndex = atoi(GET_NEXT_ARG);
			
			if (modIndex < 1) {
				printf(" index is out of bounds! (%d)\n", modIndex);
				exit(1);
			}
		} else if (CHECK_ARG(ARG_SET_NAME)) {
			//they want to set the name...
			if (PEEK_ARG) {
				//if there is a next argument...
				newName = GET_NEXT_ARG;
			}
		} else if (CHECK_ARG(ARG_SET_DEVELOPER)) {
			//they want to set the developer...
			if (PEEK_ARG) {
				//if there's a next argument
				newDeveloper = GET_NEXT_ARG;
			}
		} else if (CHECK_ARG(ARG_SET_FULL_NAME)) {
			//the want to set the full name
			if (PEEK_ARG) {
				//if there's a next argument
				newFullName = GET_NEXT_ARG;
			}
		} else if (CHECK_ARG(ARG_SET_FULL_DEVELOPER)) {
			//they want to set the full developer
			if (PEEK_ARG) {
				//if there's a next argument
				newFullDeveloper = GET_NEXT_ARG;
			}
		} else if (CHECK_ARG(ARG_SET_DESCRIPTION)) {
			//they want to set the description...
			if (PEEK_ARG) {
				//if there's a next argument
				newDescription = GET_NEXT_ARG;
			}
		} else if (CHECK_ARG(ARG_GET_ICON)) {
			//they want to extract the icon
			if (PEEK_ARG) {
				//make sure there's at least one more argument
				if (strcmp(PEEK_ARG, OPT_FORMAT_RAW) == 0) {
					extractFormat = RAW_FORMAT;
					SKIP_NARG(1);
				} else if (strcmp(PEEK_ARG, OPT_FORMAT_PPM) == 0) {
					extractFormat = PPM_FORMAT;
					SKIP_NARG(1);
				}
				
				if (PEEK_ARG) {
					extractIconPath = GET_NEXT_ARG;
				}
			}
		} else if (CHECK_ARG(ARG_SET_ICON)) {
			//they want to inject the icon...
			
			if (PEEK_ARG) {
				//make sure there's at least one more argument...
				if (strcmp(PEEK_ARG, OPT_FORMAT_RAW) == 0) {
					injectFormat = RAW_FORMAT;
					SKIP_NARG(1);
				} else if (strcmp(PEEK_ARG, OPT_FORMAT_PPM) == 0) {
					injectFormat = PPM_FORMAT;
					SKIP_NARG(1);
				}
				
				if (PEEK_ARG) {
					injectIconPath = GET_NEXT_ARG;
				}
			}
		} else {
			//if the argument doesn't fit anything else... it must be the filename.
			// set the filename and stop looping... start processing!
			filename = currentArg;
			
			break;
		}
	}while (*argv);
	
	openBnr();

	//read the file into a buffer...
	unsigned long len = GetFilesizeFromStream(bnrFile);

	char *data = (char*)malloc(len);
	
	if (ReadDataFromFile(data, filename) != len) {
		perror(filename);
		exit(1);
	}

	GCMBnrStruct *b = GCMRawBnrToStruct(data, len);
	
	if (!b) {
		printf("error opening banner!\n");
		exit(1);
	}
	
	printBnr(b);
	
	int fileChanged = 0;
	
	GCMBnrInfoStruct *mod = NULL;
	if (b->version != '1') {
		mod = GCMBnrGetNthInfo(b->info, modIndex - 1);
	} else {
		mod = b->info;
	}
	
	if (!mod) {
		printf("ERROR! mod == NULL (this shouldn't happen!)\n");
		exit(1);
	}
	
	if (newName != NULL) {
		//let's set the name...
		bzero(mod->name, GCM_BNR_GAME_NAME_LENGTH);
		strcpy(mod->name, newName);
		fileChanged = 1;
	}
	
	if (newDeveloper != NULL) {
		//let's set the developer...
		bzero(mod->developer, GCM_BNR_DEVELOPER_LENGTH);
		strcpy(mod->developer, newDeveloper);
		fileChanged = 1;
	}
	
	if (newFullName != NULL) {
		bzero(mod->fullName, GCM_BNR_FULL_TITLE_LENGTH);
		strcpy(mod->fullName, newFullName);
		fileChanged = 1;
	}
	
	if (newFullDeveloper != NULL) {
		bzero(mod->fullDeveloper, GCM_BNR_FULL_DEVELOPER_LENGTH);
		strcpy(mod->fullDeveloper, newFullDeveloper);
		fileChanged = 1;
	}
	
	if (newDescription != NULL) {
		bzero(mod->description, GCM_BNR_DESCRIPTION_LENGTH);
		strcpy(mod->description, newDescription);
		fileChanged = 1;
	}
	
	if (extractIconPath != NULL) {
		char *imageData = NULL;
		u32 len;
		
		if (extractFormat == RAW_FORMAT) {
			//if we're extracting to a .raw file... (default)
			len = GCM_BNR_GRAPHIC_RAW_FILE_LENGTH;
			imageData = (char*)malloc(len);
			GCMBnrGetImageRaw(b, imageData);
		} else {
			//if we're extracting to a .ppm file...
			len = GCM_BNR_GRAPHIC_PPM_FILE_LENGTH;
			imageData = (char*)malloc(len);
			GCMBnrGetImagePPM(b, imageData);
		}
		
		WriteDataToFile(imageData, len, extractIconPath);
	}
	
	if (injectIconPath != NULL) {
		//printf("going to inject...\n");
		u32 len = GetFilesizeFromPath(injectIconPath);
		char *imageData = (char*)malloc(len);
		
		if (injectFormat == RAW_FORMAT) {
			//if the file we're injecting is in raw format (default)
			if (ReadDataFromFile(imageData, injectIconPath) != len) {
				perror(injectIconPath);
				exit(1);
			}
		} else {
			//if the file we're injecting is in ppm format...
			//this isn't implemented yet... so tell the user and bail
			printf("PPM IMPORT IS NOT IMPLEMENTED! (file not affected)\n\n");
			exit(1);
		}
		
		char *iconData = (char*)malloc(GCM_BNR_GRAPHIC_DATA_LENGTH);
		GCMBnrRawImageToGraphic(imageData, iconData);
		
		memcpy(b->graphic, iconData, GCM_BNR_GRAPHIC_DATA_LENGTH);
		
		free(iconData);
		fileChanged = 1;
	}
	
	if (fileChanged) {
		//printf("Writing bnr file...\n");
		rewind(bnrFile);
		u32 bnrSize = GCMBnrRawSize(b);
		char *buf = (char*)malloc(bnrSize);
		GCMBnrStructToRaw(b, buf);
		if (fwrite(buf, 1, bnrSize, bnrFile) != bnrSize) {
			perror(filename);
			//printf("error writing to bnr! (%s)\n", filename);
			exit(1);
		}
	}

	GCMFreeBnrInfoStruct(b->info);
	closeBnr();
	
	return 0;
}
bool Test_CheckObjects_Main(std::vector<std::string>& errors)
{
	const char_t* szWorkingFolder = "CheckObjects_Main";
	const char_t* szAssoc = "main.ass";
	const char_t* szKLMasterPrivate = "../master.prv";
	const char_t* szKLPublic = "kl_public.rgk";
	const char_t* szKLOperablePublic = "kl_operable_public.rgk";
	const char_t* szObjHashReg1 = "objects1.rgo";
	const char_t* szObjHashReg1_special = "objects1_special.rgo";
	const char_t* szObjHashReg2 = "objects2.rgo";
	const char_t* szLicenseKey = "license.key";

	FolderGuard grd(szWorkingFolder, true);

	DeleteFile(szAssoc);
	DeleteFile(szKLPublic);
	DeleteFile(szKLOperablePublic);
	DeleteFile(szObjHashReg1);
	DeleteFile(szObjHashReg1_special);
	DeleteFile(szObjHashReg2);
	DeleteFile(szLicenseKey);

	DskmLibWrapper<DefaultAllocator> dskm_wrapper(true);

	// создаем файл ассоциаций
	{
		ParList list1;
		list1.AddParam(1, 1);
		list1.AddParam(2, 2);
		dskm_wrapper.SaveTypeAssociationToFile(1, list1, szAssoc);
		ParList list2;
		list2.AddParam(1, 3);
		dskm_wrapper.SaveTypeAssociationToFile(2, list2, szAssoc);
	}

	// создаем ключ ЛК
	KeyPairAP pKLKeyPair(dskm_wrapper.GenerateKeyPair());
	dskm_wrapper.SaveKeyToKeyReg(
							KeyType::KLPublic, 
							pKLKeyPair->PublicKey(), 
							ObjectType::KeyOperablePublic, 
							ParList(), 
							szKLPublic
							);
	// подписываем публичный ключ ЛК мастер-ключом
	dskm_wrapper.SignRegFileIntoItself(
							szKLPublic, 
							ObjectType::KeyKLPublic,
							szKLMasterPrivate
							);
	// создаем операбельный ключ (1)
	KeyPairAP pOperKeyPair1(dskm_wrapper.GenerateKeyPair());
	{
		ParList params;
		params.AddParam(1, 1);
		params.AddParam(2, 2);
		dskm_wrapper.SaveKeyToKeyReg(
								KeyType::OperablePublic, 
								pOperKeyPair1->PublicKey(), 
								1, 
								params, 
								szKLOperablePublic
								);
	}
	// создаем операбельный ключ (2)
	KeyPairAP pOperKeyPair2(dskm_wrapper.GenerateKeyPair());
	{
		ParList params;
		params.AddParam(3, 3);
		dskm_wrapper.SaveKeyToKeyReg(
								KeyType::OperablePublic, 
								pOperKeyPair2->PublicKey(), 
								2, 
								params, 
								szKLOperablePublic
								);
	}
	// подписываем рееестр операльных ключей ключом ЛК
	dskm_wrapper.SignRegFileIntoItself(
							szKLOperablePublic,
							ObjectType::KeyOperablePublic,
							pKLKeyPair->PrivateKey()
							);

	// создаем объекты для проверки
	ParList object1_ok, 
			object1_ok_special,
			object1_ok_hash,
			object1_invalid,
			object2_ok, 
			object2_invalid,
			object2_invalid_param_value, 
			object2_missed_params, 
			object2_another_params,
			object1_partial_params,
			object1_partial_invalid_params;
	{
		char buffer[] = "abcdefgh";
		object1_ok.AddBufferedObject(1, buffer, sizeof(buffer) / sizeof(buffer[0]));
		object1_ok.AddParam(1, 1);
		object1_ok.AddParam(2, 2);
		{
			HashAP pHash = dskm_wrapper.HashObjectByBuffer(buffer, sizeof(buffer) / sizeof(buffer[0]));
			object1_ok_hash.AddObjectHash(1, *(pHash.get()));
			object1_ok_hash.AddParam(1, 1);
			object1_ok_hash.AddParam(2, 2);
		}
		object1_invalid.AddBufferedObject(1, buffer, sizeof(buffer) / sizeof(buffer[0]) - 1);
		object1_invalid.AddParam(1, 1);
		object1_invalid.AddParam(2, 2);
		object1_partial_params.AddBufferedObject(1, buffer, sizeof(buffer) / sizeof(buffer[0]));
		object1_partial_params.AddParam(1, 1);
		object1_partial_invalid_params.AddBufferedObject(1, buffer, sizeof(buffer) / sizeof(buffer[0]));
		object1_partial_invalid_params.AddParam(1, 1);
		object1_partial_invalid_params.AddParam(2, 1);
	}
	{
		char buffer[] = "ABCDEFGH";
		object1_ok_special.AddBufferedObject(1, buffer, sizeof(buffer) / sizeof(buffer[0]));
	}
	{
		char buffer[] = "abcdefghijklmno";
		object2_ok.AddBufferedObject(2, buffer, sizeof(buffer) / sizeof(buffer[0]));
		object2_ok.AddParam(3, 3);
		object2_invalid.AddBufferedObject(2, &buffer[0] + 1, sizeof(buffer) / sizeof(buffer[0]) - 1);
		object2_invalid.AddParam(3, 3);
		object2_invalid_param_value.AddBufferedObject(2, buffer, sizeof(buffer) / sizeof(buffer[0]));
		object2_invalid_param_value.AddParam(3, 4);
		object2_missed_params.AddBufferedObject(2, buffer, sizeof(buffer) / sizeof(buffer[0]));
		object2_another_params.AddBufferedObject(2, buffer, sizeof(buffer) / sizeof(buffer[0]));
		object2_another_params.AddParam(5, 5);
	}

	// создаем реестр хэшей объектов
	dskm_wrapper.SignObjectsToRegFileByKey(object1_ok, 1, false, pOperKeyPair1->PrivateKey(), szObjHashReg1);
	dskm_wrapper.SignObjectsToRegFileByKey(object1_ok_special, 1, true, pOperKeyPair1->PrivateKey(), szObjHashReg1_special);
	dskm_wrapper.SignObjectsToRegFileByKey(object2_ok, 2, false, pOperKeyPair2->PrivateKey(), szObjHashReg2);

	// создаем файл псевдо-лицензионного ключа
	{
		char buf[] = "License key file";
		CreateFileAndWriteData(szLicenseKey, buf, sizeof(buf) / sizeof(buf[0]));
	}

	// подписываем файл псевдо-лицензионного ключа
	dskm_wrapper.SignRegFileIntoItself(
							szLicenseKey,
							ObjectType::LicenseKey,
							pOperKeyPair1->PrivateKey()
							);

	bool bResult = true;

	// проверяем объекты
	if (!dskm_wrapper.CheckObjectsUsingHashRegsFolder(object1_ok, 1, "."))
	{
		errors.push_back("Object1 checking failed");
		bResult = false;
	}
	if (!dskm_wrapper.CheckObjectsUsingHashRegsFolder(object1_ok_special, 1, "."))
	{
		errors.push_back("Special Object1 checking failed");
		bResult = false;
	}
	if (!dskm_wrapper.CheckObjectsUsingHashRegsFolder(object1_ok_hash, 1, "."))
	{
		errors.push_back("Object1 hash checking failed");
		bResult = false;
	}
	if (!dskm_wrapper.CheckObjectsUsingHashRegsFolder(object2_ok, 2, "."))
	{
		errors.push_back("Object2 checking failed");
		bResult = false;
	}
	if (dskm_wrapper.CheckObjectsUsingHashRegsFolder(object1_invalid, 1, "."))
	{
		errors.push_back("Invalid Object1 checking returns ok");
		bResult = false;
	}
	if (dskm_wrapper.CheckObjectsUsingHashRegsFolder(object2_invalid, 2, "."))
	{
		errors.push_back("Invalid Object2 checking returns ok");
		bResult = false;
	}
	if (dskm_wrapper.CheckObjectsUsingHashRegsFolder(object1_ok, 3, "."))
	{
		errors.push_back("Checking object with incorrect type returned ok");
		bResult = false;
	}
	if (dskm_wrapper.CheckObjectsUsingHashRegsFolder(object2_invalid_param_value, 2, "."))
	{
		errors.push_back("Checking object with invalid parameter value returned ok");
		bResult = false;
	}
	if (!dskm_wrapper.CheckObjectsUsingHashRegsFolder(object2_missed_params, 2, "."))
	{
		errors.push_back("Checking object with missed parameters failed");
		bResult = false;
	}
	if (!dskm_wrapper.CheckObjectsUsingHashRegsFolder(object2_another_params, 2, "."))
	{
		errors.push_back("Checking object with another parameters failed");
		bResult = false;
	}
	if (!dskm_wrapper.CheckObjectsUsingHashRegsFolder(object1_partial_params, 1, "."))
	{
		errors.push_back("Checking object with incomplete parameters list failed");
		bResult = false;
	}
	if (dskm_wrapper.CheckObjectsUsingHashRegsFolder(object1_partial_invalid_params, 1, "."))
	{
		errors.push_back("Checking object with partial invalid parameters values returns ok");
		bResult = false;
	}

	if (!dskm_wrapper.CheckRegFileUsingInsideSign(
										szLicenseKey,
										ObjectType::LicenseKey,
										szKLOperablePublic
										))
	{
		errors.push_back("License key checking failed");
	}

	// портим файл с публичным ключом ЛК
	const int data_size = 5;
	char data_orig[data_size];
	ReadDataFromFile(szKLPublic, 10, data_orig, data_size*sizeof(char));
	char data[data_size];
	std::fill(data, data + data_size, '\0');
	WriteDataToFile(szKLPublic, 10, data, data_size*sizeof(char));

	// проверяем объекты после восстановления файла (на всякий случай)
	if (dskm_wrapper.CheckObjectsUsingHashRegsFolder(object1_ok, 1, ".") ||
		dskm_wrapper.CheckObjectsUsingHashRegsFolder(object2_ok, 2, "."))
	{
		errors.push_back("Object checking returns ok while KL public key file is invalid");
		bResult = false;
	}

	if (dskm_wrapper.CheckRegFileUsingInsideSign(
										szLicenseKey,
										ObjectType::LicenseKey,
										szKLOperablePublic
										))
	{
		errors.push_back("License key checking returns ok while KL public key file is invalid");
		bResult = false;
	}

	// восстанавливаем файл с публичным ключом ЛК
	WriteDataToFile(szKLPublic, 10, data_orig, data_size*sizeof(char));

	// проверяем объекты
	if (!dskm_wrapper.CheckObjectsUsingHashRegsFolder(object1_ok, 1, ".") ||
		!dskm_wrapper.CheckObjectsUsingHashRegsFolder(object2_ok, 2, "."))
	{
		errors.push_back("Object checking failed with edited KL public key file");
		bResult = false;
	}

	// портим файл с публичным операбельным ключом
	ReadDataFromFile(szKLOperablePublic, 10, data_orig, data_size*sizeof(char));
	WriteDataToFile(szKLOperablePublic, 10, data, data_size*sizeof(char));

	// проверяем объекты
	if (dskm_wrapper.CheckObjectsUsingHashRegsFolder(object1_ok, 1, ".") ||
		dskm_wrapper.CheckObjectsUsingHashRegsFolder(object2_ok, 2, "."))
	{
		errors.push_back("Object checking returns ok while KL operable public key file is invalid");
		bResult = false;
	}

	// портим файл лицензионного ключа
	{
		char ch = '\0';
		WriteDataToFile(szLicenseKey, 0, &ch, 1);
	}

	if (dskm_wrapper.CheckRegFileUsingInsideSign(
										szLicenseKey,
										ObjectType::LicenseKey,
										szKLOperablePublic
										))
	{
		errors.push_back("Checking corrupted license key file returned ok");
		bResult = false;
	}

	return bResult;
}
// Load the sample assets.
void D3D12Bundles::LoadAssets()
{
	// These upload heaps are only needed during loading.
	ComPtr<ID3D12Resource> vertexBufferUploadHeap;
	ComPtr<ID3D12Resource> indexBufferUploadHeap;
	ComPtr<ID3D12Resource> textureUploadHeap;

	// Create the root signature.
	{
		CD3DX12_DESCRIPTOR_RANGE ranges[3];
		ranges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 0);
		ranges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, 1, 0);
		ranges[2].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0);

		CD3DX12_ROOT_PARAMETER rootParameters[3];
		rootParameters[0].InitAsDescriptorTable(1, &ranges[0], D3D12_SHADER_VISIBILITY_PIXEL);
		rootParameters[1].InitAsDescriptorTable(1, &ranges[1], D3D12_SHADER_VISIBILITY_PIXEL);
		rootParameters[2].InitAsDescriptorTable(1, &ranges[2], D3D12_SHADER_VISIBILITY_ALL);

		CD3DX12_ROOT_SIGNATURE_DESC rootSignatureDesc;
		rootSignatureDesc.Init(_countof(rootParameters), rootParameters, 0, nullptr, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);

		ComPtr<ID3DBlob> signature;
		ComPtr<ID3DBlob> error;
		ThrowIfFailed(D3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error));
		ThrowIfFailed(m_device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&m_rootSignature)));
	}

	// Create the pipeline state, which includes loading shaders.
	{
		UINT8* pVertexShaderData;
		UINT8* pPixelShaderData1;
		UINT8* pPixelShaderData2;
		UINT vertexShaderDataLength;
		UINT pixelShaderDataLength1;
		UINT pixelShaderDataLength2;

		// Load pre-compiled shaders.
		ThrowIfFailed(ReadDataFromFile(GetAssetFullPath(L"shader_mesh_simple_vert.cso").c_str(), &pVertexShaderData, &vertexShaderDataLength));
		ThrowIfFailed(ReadDataFromFile(GetAssetFullPath(L"shader_mesh_simple_pixel.cso").c_str(), &pPixelShaderData1, &pixelShaderDataLength1));
		ThrowIfFailed(ReadDataFromFile(GetAssetFullPath(L"shader_mesh_alt_pixel.cso").c_str(), &pPixelShaderData2, &pixelShaderDataLength2));

		CD3DX12_RASTERIZER_DESC rasterizerStateDesc(D3D12_DEFAULT);
		rasterizerStateDesc.CullMode = D3D12_CULL_MODE_NONE;

		// Describe and create the graphics pipeline state objects (PSO).
		D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {};
		psoDesc.InputLayout = { SampleAssets::StandardVertexDescription, SampleAssets::StandardVertexDescriptionNumElements };
		psoDesc.pRootSignature = m_rootSignature.Get();
		psoDesc.VS = { pVertexShaderData, vertexShaderDataLength };
		psoDesc.PS = { pPixelShaderData1, pixelShaderDataLength1 };
		psoDesc.RasterizerState = rasterizerStateDesc;
		psoDesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT);
		psoDesc.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC(D3D12_DEFAULT);
		psoDesc.SampleMask = UINT_MAX;
		psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
		psoDesc.NumRenderTargets = 1;
		psoDesc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM;
		psoDesc.DSVFormat = DXGI_FORMAT_D32_FLOAT;
		psoDesc.SampleDesc.Count = 1;

		ThrowIfFailed(m_device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&m_pipelineState1)));

		// Modify the description to use an alternate pixel shader and create
		// a second PSO.
		psoDesc.PS = { pPixelShaderData2, pixelShaderDataLength2 };
		ThrowIfFailed(m_device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&m_pipelineState2)));

		delete pVertexShaderData;
		delete pPixelShaderData1;
		delete pPixelShaderData2;
	}

	ThrowIfFailed(m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_commandAllocator.Get(), nullptr, IID_PPV_ARGS(&m_commandList)));

	// Create render target views (RTVs).
	CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle(m_rtvHeap->GetCPUDescriptorHandleForHeapStart());
	for (UINT i = 0; i < FrameCount; i++)
	{
		ThrowIfFailed(m_swapChain->GetBuffer(i, IID_PPV_ARGS(&m_renderTargets[i])));
		m_device->CreateRenderTargetView(m_renderTargets[i].Get(), nullptr, rtvHandle);
		rtvHandle.Offset(1, m_rtvDescriptorSize);
	}

	// Read in mesh data for vertex/index buffers.
	UINT8* pMeshData;
	UINT meshDataLength;
	ThrowIfFailed(ReadDataFromFile(GetAssetFullPath(SampleAssets::DataFileName).c_str(), &pMeshData, &meshDataLength));

	// Create the vertex buffer.
	{
		ThrowIfFailed(m_device->CreateCommittedResource(
			&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
			D3D12_HEAP_FLAG_NONE,
			&CD3DX12_RESOURCE_DESC::Buffer(SampleAssets::VertexDataSize),
			D3D12_RESOURCE_STATE_COPY_DEST,
			nullptr,
			IID_PPV_ARGS(&m_vertexBuffer)));

		ThrowIfFailed(m_device->CreateCommittedResource(
			&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
			D3D12_HEAP_FLAG_NONE,
			&CD3DX12_RESOURCE_DESC::Buffer(SampleAssets::VertexDataSize),
			D3D12_RESOURCE_STATE_GENERIC_READ,
			nullptr,
			IID_PPV_ARGS(&vertexBufferUploadHeap)));

		// Copy data to the intermediate upload heap and then schedule a copy 
		// from the upload heap to the vertex buffer.
		D3D12_SUBRESOURCE_DATA vertexData = {};
		vertexData.pData = pMeshData + SampleAssets::VertexDataOffset;
		vertexData.RowPitch = SampleAssets::VertexDataSize;
		vertexData.SlicePitch = vertexData.RowPitch;

		UpdateSubresources<1>(m_commandList.Get(), m_vertexBuffer.Get(), vertexBufferUploadHeap.Get(), 0, 0, 1, &vertexData);
		m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_vertexBuffer.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER));

		// Initialize the vertex buffer view.
		m_vertexBufferView.BufferLocation = m_vertexBuffer->GetGPUVirtualAddress();
		m_vertexBufferView.StrideInBytes = SampleAssets::StandardVertexStride;
		m_vertexBufferView.SizeInBytes = SampleAssets::VertexDataSize;
	}

	// Create the index buffer.
	{
		ThrowIfFailed(m_device->CreateCommittedResource(
			&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
			D3D12_HEAP_FLAG_NONE,
			&CD3DX12_RESOURCE_DESC::Buffer(SampleAssets::IndexDataSize),
			D3D12_RESOURCE_STATE_COPY_DEST,
			nullptr,
			IID_PPV_ARGS(&m_indexBuffer)));

		ThrowIfFailed(m_device->CreateCommittedResource(
			&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
			D3D12_HEAP_FLAG_NONE,
			&CD3DX12_RESOURCE_DESC::Buffer(SampleAssets::IndexDataSize),
			D3D12_RESOURCE_STATE_GENERIC_READ,
			nullptr,
			IID_PPV_ARGS(&indexBufferUploadHeap)));

		// Copy data to the intermediate upload heap and then schedule a copy 
		// from the upload heap to the index buffer.
		D3D12_SUBRESOURCE_DATA indexData = {};
		indexData.pData = pMeshData + SampleAssets::IndexDataOffset;
		indexData.RowPitch = SampleAssets::IndexDataSize;
		indexData.SlicePitch = indexData.RowPitch;

		UpdateSubresources<1>(m_commandList.Get(), m_indexBuffer.Get(), indexBufferUploadHeap.Get(), 0, 0, 1, &indexData);
		m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_indexBuffer.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_INDEX_BUFFER));

		// Describe the index buffer view.
		m_indexBufferView.BufferLocation = m_indexBuffer->GetGPUVirtualAddress();
		m_indexBufferView.Format = SampleAssets::StandardIndexFormat;
		m_indexBufferView.SizeInBytes = SampleAssets::IndexDataSize;

		m_numIndices = SampleAssets::IndexDataSize / 4;	// R32_UINT (SampleAssets::StandardIndexFormat) = 4 bytes each.
	}

	// Create the texture and sampler.
	{
		// Describe and create a Texture2D.
		D3D12_RESOURCE_DESC textureDesc = {};
		textureDesc.MipLevels = SampleAssets::Textures[0].MipLevels;
		textureDesc.Format = SampleAssets::Textures[0].Format;
		textureDesc.Width = SampleAssets::Textures[0].Width;
		textureDesc.Height = SampleAssets::Textures[0].Height;
		textureDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
		textureDesc.DepthOrArraySize = 1;
		textureDesc.SampleDesc.Count = 1;
		textureDesc.SampleDesc.Quality = 0;
		textureDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;

		ThrowIfFailed(m_device->CreateCommittedResource(
			&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
			D3D12_HEAP_FLAG_NONE,
			&textureDesc,
			D3D12_RESOURCE_STATE_COPY_DEST,
			nullptr,
			IID_PPV_ARGS(&m_texture)));

		const UINT subresourceCount = textureDesc.DepthOrArraySize * textureDesc.MipLevels;
		const UINT64 uploadBufferSize = GetRequiredIntermediateSize(m_texture.Get(), 0, subresourceCount);

		ThrowIfFailed(m_device->CreateCommittedResource(
			&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
			D3D12_HEAP_FLAG_NONE,
			&CD3DX12_RESOURCE_DESC::Buffer(uploadBufferSize),
			D3D12_RESOURCE_STATE_GENERIC_READ,
			nullptr,
			IID_PPV_ARGS(&textureUploadHeap)));

		// Copy data to the intermediate upload heap and then schedule a copy 
		// from the upload heap to the Texture2D.
		D3D12_SUBRESOURCE_DATA textureData = {};
		textureData.pData = pMeshData + SampleAssets::Textures[0].Data[0].Offset;
		textureData.RowPitch = SampleAssets::Textures[0].Data[0].Pitch;
		textureData.SlicePitch = SampleAssets::Textures[0].Data[0].Size;

		UpdateSubresources(m_commandList.Get(), m_texture.Get(), textureUploadHeap.Get(), 0, 0, subresourceCount, &textureData);
		m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_texture.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE));

		// Describe and create a sampler.
		D3D12_SAMPLER_DESC samplerDesc = {};
		samplerDesc.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR;
		samplerDesc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
		samplerDesc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
		samplerDesc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
		samplerDesc.MinLOD = 0;
		samplerDesc.MaxLOD = D3D12_FLOAT32_MAX;
		samplerDesc.MipLODBias = 0.0f;
		samplerDesc.MaxAnisotropy = 1;
		samplerDesc.ComparisonFunc = D3D12_COMPARISON_FUNC_ALWAYS;
		m_device->CreateSampler(&samplerDesc, m_samplerHeap->GetCPUDescriptorHandleForHeapStart());

		// Describe and create a SRV for the texture.
		D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
		srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
		srvDesc.Format = SampleAssets::Textures->Format;
		srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
		srvDesc.Texture2D.MipLevels = 1;
		m_device->CreateShaderResourceView(m_texture.Get(), &srvDesc, m_cbvSrvHeap->GetCPUDescriptorHandleForHeapStart());
	}

	delete pMeshData;

	// Create the depth stencil view.
	{
		D3D12_DEPTH_STENCIL_VIEW_DESC depthStencilDesc = {};
		depthStencilDesc.Format = DXGI_FORMAT_D32_FLOAT;
		depthStencilDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
		depthStencilDesc.Flags = D3D12_DSV_FLAG_NONE;

		D3D12_CLEAR_VALUE depthOptimizedClearValue = {};
		depthOptimizedClearValue.Format = DXGI_FORMAT_D32_FLOAT;
		depthOptimizedClearValue.DepthStencil.Depth = 1.0f;
		depthOptimizedClearValue.DepthStencil.Stencil = 0;

		ThrowIfFailed(m_device->CreateCommittedResource(
			&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
			D3D12_HEAP_FLAG_NONE,
			&CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_D32_FLOAT, m_width, m_height, 1, 0, 1, 0, D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL),
			D3D12_RESOURCE_STATE_DEPTH_WRITE,
			&depthOptimizedClearValue,
			IID_PPV_ARGS(&m_depthStencil)
			));

		m_device->CreateDepthStencilView(m_depthStencil.Get(), &depthStencilDesc, m_dsvHeap->GetCPUDescriptorHandleForHeapStart());
	}

	// Close the command list and execute it to begin the initial GPU setup.
	ThrowIfFailed(m_commandList->Close());
	ID3D12CommandList* ppCommandLists[] = { m_commandList.Get() };
	m_commandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists);

	CreateFrameResources();

	// Create synchronization objects and wait until assets have been uploaded to the GPU.
	{
		ThrowIfFailed(m_device->CreateFence(m_fenceValue, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&m_fence)));
		m_fenceValue++;

		// Create an event handle to use for frame synchronization.
		m_fenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
		if (m_fenceEvent == nullptr)
		{
			ThrowIfFailed(HRESULT_FROM_WIN32(GetLastError()));
		}

		// Wait for the command list to execute; we are reusing the same command 
		// list in our main loop but for now, we just want to wait for setup to 
		// complete before continuing.

		// Signal and increment the fence value.
		const UINT64 fenceToWaitFor = m_fenceValue;
		ThrowIfFailed(m_commandQueue->Signal(m_fence.Get(), fenceToWaitFor));
		m_fenceValue++;

		// Wait until the fence is completed.
		ThrowIfFailed(m_fence->SetEventOnCompletion(fenceToWaitFor, m_fenceEvent));
		WaitForSingleObject(m_fenceEvent, INFINITE);
	}
}
TInt CSimulateMessageServerSession::QueryAllTasks(RSimMsgDataArray& aArray)
	{
	ReadDataFromFile(aArray);
	}
Example #19
0
// Main function
int main(int argc, char *argv[])
{
	bool Successful;

	printf("Event Based Scalar TLM Model for Urban Environments\n\n");
	
	if (InputData.PrintTimingInformation.Flag == true) {
		SetStartTime();	
	}	

	// Parse command line input 
	ParseCommandLine(argc,argv);
	
	// Retrieve the setup data
	Successful = ReadDataFromFile();
	
	if (Successful == true) {
		// Display the configuration parameters read from the input file
		DisplayConfigParameters();
		// Perform the relevant actions based on the input file
		Successful = ProcessConfigParameters();
	}

	if (Successful == true) {
		// Read in the scene information from the scene file, and initialise the TLM grid
		if (InputData.PrintTimingInformation.Flag == true) {
			SetSceneParsingStartTime();
		}
		Successful = ReadSceneFile();
		if (InputData.PrintTimingInformation.Flag == true) {
			SetSceneParsingFinishTime();
		}
		PrintImpedances();
	}
	
	// Print the initial grid layout to the display
	if (Successful == true) {

		// Print the timing information
		if (InputData.PrintTimingInformation.Flag == true) {
			SetAlgorithmStartTime();
		}
		// Run the main loop of the TLM algorithm
		MainLoop();

		// Print the timing information
		if (InputData.PrintTimingInformation.Flag == true) {
			SetAlgorithmFinishTime();
		}

		if (InputData.PrintTimeVariation.Flag == true) {
			//Print time variation to output file
			PrintTimeVariation();
			free(TimeVariation);
		}
		
		// Print the path loss values to the path loss file
		if (PathLossParameters.Type != NONE) {
			PrintPathLossToFile();
		}

		if (InputData.PrintTimingInformation.Flag == true) {
			SetFinishTime();
		}

		if (InputData.PrintTimingInformation.Flag == true) {
			PrintTimingInformation();
		}

		// Deallocate memory for the grid
		free(Grid);

		printf("\nTLM algorithm complete.\n");
	}

	return 0;
}
Example #20
0
BOOL CWavFile::Combine(CString strPathL, CString strPathR, CString strPathObj)
{
	int nPackNo = 0;
	int nPackSize = 0;
	int nDataSize = 0;
	const int nLen = 65536;
	BYTE byDataL[nLen * 2] = {0};
	BYTE byDataR[nLen * 2] = {0};
	BYTE byDataC[nLen * 4] = {0};
	HMMIO hWaveFile = NULL;
	LPTSTR pszFilePath = strdup(strPathObj);

	if(!m_hWaveFileL || !m_hWaveFileR)
	{
		return FALSE;
	}

	// They can combine or not
	nDataSize = IsCanCombine(strPathL, strPathR);
	if(nDataSize == -1)
	{
		return FALSE;
	}

	// Create an object wave file
	m_formatL.nChannels = 2;
	m_formatL.nBlockAlign *= 2;
	m_formatL.nAvgBytesPerSec *= 2;
	if(!CreateWaveFile(hWaveFile, pszFilePath, m_formatL))
	{
		MyMessageBox(_T("Create object file failed: ") + strPathObj, eERR_ERROR);
		return FALSE;	
	}

	// Combine them one packet by one
	nPackSize = nLen;
	nPackNo = (nDataSize + nLen - 1) / nLen;
	for(int i = 0; i < nPackNo; i++)
	{
		// Case of the last packet
		if(i == (nPackNo - 1))	
		{
			nPackSize = nDataSize - i * nLen;
		}

		// Read data from left channel
		int nSizeL = nPackSize;
		if(ReadDataFromFile(m_hWaveFileL, byDataL, nSizeL))
		{
			if(nSizeL != nPackSize)
			{
				memset(byDataL + nSizeL, 0, nPackSize - nSizeL);
			}
		}
		else
		{
			MyMessageBox(_T("Read sound data from L file failed"), eERR_ERROR);
		}
		
		// Read data from right channel
		int nSizeR = nPackSize;
		if(ReadDataFromFile(m_hWaveFileR, byDataR, nSizeR))
		{
			if(nSizeR != nPackSize)
			{
				memset(byDataR + nSizeR, 0, nPackSize - nSizeR);
			}
		}
		else
		{
			MyMessageBox(_T("Read sound data from R file failed"), eERR_ERROR);
		}

		// Re-combine left channel data and right channel data
		int nCoef = m_formatL.wBitsPerSample / 8;
		for(int i = 0; i < (nPackSize / nCoef); i++)
		{
			if(nCoef == 1)
			{
				byDataC[2 * i + 0] = byDataL[i];
				byDataC[2 * i + 1] = byDataR[i];
			}
			else
			{
				byDataC[4 * i + 0] = byDataL[2 * i];
				byDataC[4 * i + 2] = byDataR[2 * i];
				byDataC[4 * i + 1] = byDataL[2 * i + 1];
				byDataC[4 * i + 3] = byDataR[2 * i + 1];
			}
		}

		// Write to object file
		if(mmioWrite(hWaveFile, (char*)byDataC, nPackSize * 2) != nPackSize * 2)
		{
			MyMessageBox(_T("Write object file failed"), eERR_ERROR);
			return FALSE;
		}
	}

	// Call mmioAscend function to mark the end of the chunk
	// And mmioAscend will corrects the chunk size
	mmioAscend(hWaveFile, &m_mmckinfoParent, 0);
	mmioAscend(hWaveFile, &m_mmckinfoSubChunk, 0);
	mmioClose(hWaveFile, 0);
	mmioClose(m_hWaveFileL, 0);
	mmioClose(m_hWaveFileR, 0);
	
	return TRUE;
}
void __cdecl main(int argc, char **argv)
{
    RPC_STATUS status;

    unsigned char * pbPicklingBuffer = NULL;

    char * pszStyle      = NULL;
    char * pszFileName   = "pickle.dat";
    int i;
    int fEncode = 1;
    int fFixedStyle = 1;

    /* allow the user to override settings with command line switches */
    for (i = 1; i < argc; i++) {
        if ((*argv[i] == '-') || (*argv[i] == '/')) {
            switch (tolower(*(argv[i]+1))) {
            case 'd':
                fEncode = 0;
                break;
            case 'e':
                fEncode = 1;
                break;
            case 'i':
                fFixedStyle = 0;
                break;
            case 'f':
                pszFileName = argv[i] + 2;
                break;
            case 'h':
            case '?':
            default:
                Usage(argv[0]);
            }
        }
        else
            Usage(argv[0]);
    }

    /* Fixed buffer style: the buffer should be big enough.  */
    /* Please note that the buffer has to be aligned at 8.   */

    pbPicklingBuffer = (unsigned char *)
            midl_user_allocate( BUFSIZE * sizeof(unsigned char));

    if ( pbPicklingBuffer == NULL ) {
        printf_s("Cannot allocate the pickling buffer\n");
        exit(1);
        }
    else
        memset( pbPicklingBuffer, 0xdd, BUFSIZE );

    /*
        Set the pickling handle that will be used for data serialization.
        The global ImplicitPicHandle is used, but it has to be set up.
    */

    if ( fEncode ) {

        unsigned char * pszNameId;
        OBJECT1         Object1;
        OBJECT2   *     pObject2;
        unsigned long   ulEncodedSize = 0;

        printf_s("\nEncoding run: use -d for decoding\n\n");

        if ( fFixedStyle ) {

            printf_s("Creating a fixed buffer encoding handle\n");
            status = MesEncodeFixedBufferHandleCreate( pbPicklingBuffer,
                                                       BUFSIZE,
                                                       & ulEncodedSize,
                                                       & ImplicitPicHandle );
            printf_s("MesEncodeFixedBufferHandleCreate returned 0x%x\n", status);
            if (status) {
                exit(status);
            }
        }
        else {

            pUserState->LastSize = 0;
            pUserState->pMemBuffer = (char *)pbPicklingBuffer;
            pUserState->pBufferStart = (char *)pbPicklingBuffer;

            printf_s("Creating an incremental encoding handle\n");
            status = MesEncodeIncrementalHandleCreate( pUserState,
                                                       PicAlloc,
                                                       PicWrite,
                                                       & ImplicitPicHandle );
            printf_s("MesEncodeIncrementalHandleCreate returned 0x%x\n", status);
            if (status) {
                exit(status);
            }
        }

        /* Creating objects to manipulate */

        pszNameId = "Procedure pickling sample";

        for (i = 0; i < ARR_SIZE; i++)
            Object1.al[i] = 0x37370000 + i;
        Object1.s = 0x4646;

        pObject2 = midl_user_allocate( sizeof(OBJECT2) + ARR_SIZE*sizeof(short) );
        if (pObject2 == NULL ) {
            printf_s("Out of memory for Object2\n");
            exit(1);
        }

        pObject2->sSize = ARR_SIZE;
        for (i = 0; i < ARR_SIZE; i++)
            pObject2->as[i] = 0x7700 + i;

        DumpData( "Data to be encoded", pszNameId, &Object1, pObject2 );

        printf_s("\nEncoding all the arguments to the buffer\n\n");
        ProcPickle( pszNameId, & Object1, pObject2 );

        printf_s("Writing the data to the file: %s\n", pszFileName);
        WriteDataToFile( pszFileName,
                         pbPicklingBuffer,
                         fFixedStyle  ? ulEncodedSize
                                      : pUserState->LastSize);

        midl_user_free( pObject2 );
    }
    else {
        char            acNameBuffer[50];
        OBJECT1         Object1;
        OBJECT2   *     pObject2;

        printf_s("\nDecoding run: use -e for encoding\n\n");

        printf_s("Reading the data from the file: %s\n\n", pszFileName );
        ReadDataFromFile( pszFileName,
                          pbPicklingBuffer,
                          BUFSIZE );

        if ( fFixedStyle ) {

            printf_s("Creating a decoding handle\n");
            status = MesDecodeBufferHandleCreate( pbPicklingBuffer,
                                                  BUFSIZE,
                                                  & ImplicitPicHandle );
            printf_s("MesDecodeFixedBufferHandleCreate returned 0x%x\n", status);
            if (status) {
                exit(status);
            }
        }
        else {

            pUserState->LastSize = 0;
            pUserState->pMemBuffer = (char *)pbPicklingBuffer;
            pUserState->pBufferStart = (char *)pbPicklingBuffer;

            printf_s("Creating an incremental decoding handle\n");
            status = MesDecodeIncrementalHandleCreate( pUserState,
                                                       PicRead,
                                                       & ImplicitPicHandle );
            printf_s("MesDecodeIncrementalHandleCreate returned 0x%x\n", status);
            if (status) {
                exit(status);
            }
        }


        /* Creating objects to manipulate */

        pObject2 = midl_user_allocate( sizeof(OBJECT2) + ARR_SIZE*sizeof(short));
        if (pObject2 == NULL ) {
            printf_s("Out of memory for Object2\n");
            exit(1);
        }

        printf_s("\nDecoding all the arguments from the buffer\n");
        ProcPickle( acNameBuffer, & Object1, pObject2 );

        DumpData( "Decoded data", acNameBuffer, &Object1, pObject2 );

        midl_user_free( pObject2 );
    }

    printf_s("\nData serialization done.\n");

    midl_user_free( pbPicklingBuffer );

    printf_s("\nFreeing the serialization handle.\n");
    status = MesHandleFree( ImplicitPicHandle );
    printf_s("MesHandleFree returned 0x%x\n", status);

    exit(0);

}  // end main()
// Load the sample assets.
void D3D12DynamicIndexing::LoadAssets()
{
	// Note: ComPtr's are CPU objects but these resources need to stay in scope until
	// the command list that references them has finished executing on the GPU.
	// We will flush the GPU at the end of this method to ensure the resources are not
	// prematurely destroyed.
	ComPtr<ID3D12Resource> vertexBufferUploadHeap;
	ComPtr<ID3D12Resource> indexBufferUploadHeap;
	ComPtr<ID3D12Resource> textureUploadHeap;
	ComPtr<ID3D12Resource> materialsUploadHeap;

	// Create the root signature.
	{
		CD3DX12_DESCRIPTOR_RANGE ranges[3];
		ranges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1 + CityMaterialCount, 0);  // Diffuse texture + array of materials.
		ranges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, 1, 0);
		ranges[2].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0);

		CD3DX12_ROOT_PARAMETER rootParameters[4];
		rootParameters[0].InitAsDescriptorTable(1, &ranges[0], D3D12_SHADER_VISIBILITY_PIXEL);
		rootParameters[1].InitAsDescriptorTable(1, &ranges[1], D3D12_SHADER_VISIBILITY_PIXEL);
		rootParameters[2].InitAsDescriptorTable(1, &ranges[2], D3D12_SHADER_VISIBILITY_VERTEX);
		rootParameters[3].InitAsConstants(1, 0, 0, D3D12_SHADER_VISIBILITY_PIXEL);

		CD3DX12_ROOT_SIGNATURE_DESC rootSignatureDesc;
		rootSignatureDesc.Init(_countof(rootParameters), rootParameters, 0, nullptr, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);

		ComPtr<ID3DBlob> signature;
		ComPtr<ID3DBlob> error;
		ThrowIfFailed(D3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error));
		ThrowIfFailed(m_device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&m_rootSignature)));
		NAME_D3D12_OBJECT(m_rootSignature);
	}

	// Create the pipeline state, which includes loading shaders.
	{
		UINT8* pVertexShaderData;
		UINT8* pPixelShaderData;
		UINT vertexShaderDataLength;
		UINT pixelShaderDataLength;

		ThrowIfFailed(ReadDataFromFile(GetAssetFullPath(L"shader_mesh_simple_vert.cso").c_str(), &pVertexShaderData, &vertexShaderDataLength));
		ThrowIfFailed(ReadDataFromFile(GetAssetFullPath(L"shader_mesh_dynamic_indexing_pixel.cso").c_str(), &pPixelShaderData, &pixelShaderDataLength));

		CD3DX12_RASTERIZER_DESC rasterizerStateDesc(D3D12_DEFAULT);
		rasterizerStateDesc.CullMode = D3D12_CULL_MODE_NONE;

		// Describe and create the graphics pipeline state object (PSO).
		D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {};
		psoDesc.InputLayout = { SampleAssets::StandardVertexDescription, SampleAssets::StandardVertexDescriptionNumElements };
		psoDesc.pRootSignature = m_rootSignature.Get();
		psoDesc.VS = CD3DX12_SHADER_BYTECODE(pVertexShaderData, vertexShaderDataLength);
		psoDesc.PS = CD3DX12_SHADER_BYTECODE(pPixelShaderData, pixelShaderDataLength);
		psoDesc.RasterizerState = rasterizerStateDesc;
		psoDesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT);
		psoDesc.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC(D3D12_DEFAULT);
		psoDesc.SampleMask = UINT_MAX;
		psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
		psoDesc.NumRenderTargets = 1;
		psoDesc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM;
		psoDesc.DSVFormat = DXGI_FORMAT_D32_FLOAT;
		psoDesc.SampleDesc.Count = 1;

		ThrowIfFailed(m_device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&m_pipelineState)));
		NAME_D3D12_OBJECT(m_pipelineState);

		delete pVertexShaderData;
		delete pPixelShaderData;
	}

	ThrowIfFailed(m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_commandAllocator.Get(), nullptr, IID_PPV_ARGS(&m_commandList)));
	NAME_D3D12_OBJECT(m_commandList);

	// Create render target views (RTVs).
	CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle(m_rtvHeap->GetCPUDescriptorHandleForHeapStart());
	for (UINT i = 0; i < FrameCount; i++)
	{
		ThrowIfFailed(m_swapChain->GetBuffer(i, IID_PPV_ARGS(&m_renderTargets[i])));
		m_device->CreateRenderTargetView(m_renderTargets[i].Get(), nullptr, rtvHandle);
		rtvHandle.Offset(1, m_rtvDescriptorSize);

		NAME_D3D12_OBJECT_INDEXED(m_renderTargets, i);
	}

	// Read in mesh data for vertex/index buffers.
	UINT8* pMeshData;
	UINT meshDataLength;
	ThrowIfFailed(ReadDataFromFile(GetAssetFullPath(SampleAssets::DataFileName).c_str(), &pMeshData, &meshDataLength));

	// Create the vertex buffer.
	{
		ThrowIfFailed(m_device->CreateCommittedResource(
			&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
			D3D12_HEAP_FLAG_NONE,
			&CD3DX12_RESOURCE_DESC::Buffer(SampleAssets::VertexDataSize),
			D3D12_RESOURCE_STATE_COPY_DEST,
			nullptr,
			IID_PPV_ARGS(&m_vertexBuffer)));

		ThrowIfFailed(m_device->CreateCommittedResource(
			&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
			D3D12_HEAP_FLAG_NONE,
			&CD3DX12_RESOURCE_DESC::Buffer(SampleAssets::VertexDataSize),
			D3D12_RESOURCE_STATE_GENERIC_READ,
			nullptr,
			IID_PPV_ARGS(&vertexBufferUploadHeap)));

		NAME_D3D12_OBJECT(m_vertexBuffer);

		// Copy data to the intermediate upload heap and then schedule a copy 
		// from the upload heap to the vertex buffer.
		D3D12_SUBRESOURCE_DATA vertexData = {};
		vertexData.pData = pMeshData + SampleAssets::VertexDataOffset;
		vertexData.RowPitch = SampleAssets::VertexDataSize;
		vertexData.SlicePitch = vertexData.RowPitch;

		UpdateSubresources<1>(m_commandList.Get(), m_vertexBuffer.Get(), vertexBufferUploadHeap.Get(), 0, 0, 1, &vertexData);
		m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_vertexBuffer.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER));

		// Initialize the vertex buffer view.
		m_vertexBufferView.BufferLocation = m_vertexBuffer->GetGPUVirtualAddress();
		m_vertexBufferView.StrideInBytes = SampleAssets::StandardVertexStride;
		m_vertexBufferView.SizeInBytes = SampleAssets::VertexDataSize;
	}

	// Create the index buffer.
	{
		ThrowIfFailed(m_device->CreateCommittedResource(
			&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
			D3D12_HEAP_FLAG_NONE,
			&CD3DX12_RESOURCE_DESC::Buffer(SampleAssets::IndexDataSize),
			D3D12_RESOURCE_STATE_COPY_DEST,
			nullptr,
			IID_PPV_ARGS(&m_indexBuffer)));

		ThrowIfFailed(m_device->CreateCommittedResource(
			&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
			D3D12_HEAP_FLAG_NONE,
			&CD3DX12_RESOURCE_DESC::Buffer(SampleAssets::IndexDataSize),
			D3D12_RESOURCE_STATE_GENERIC_READ,
			nullptr,
			IID_PPV_ARGS(&indexBufferUploadHeap)));

		NAME_D3D12_OBJECT(m_indexBuffer);

		// Copy data to the intermediate upload heap and then schedule a copy 
		// from the upload heap to the index buffer.
		D3D12_SUBRESOURCE_DATA indexData = {};
		indexData.pData = pMeshData + SampleAssets::IndexDataOffset;
		indexData.RowPitch = SampleAssets::IndexDataSize;
		indexData.SlicePitch = indexData.RowPitch;

		UpdateSubresources<1>(m_commandList.Get(), m_indexBuffer.Get(), indexBufferUploadHeap.Get(), 0, 0, 1, &indexData);
		m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_indexBuffer.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_INDEX_BUFFER));

		// Describe the index buffer view.
		m_indexBufferView.BufferLocation = m_indexBuffer->GetGPUVirtualAddress();
		m_indexBufferView.Format = SampleAssets::StandardIndexFormat;
		m_indexBufferView.SizeInBytes = SampleAssets::IndexDataSize;

		m_numIndices = SampleAssets::IndexDataSize / 4;	// R32_UINT (SampleAssets::StandardIndexFormat) = 4 bytes each.
	}

	// Create the textures and sampler.
	{
		// Procedurally generate an array of textures to use as city materials.
		{
			// All of these materials use the same texture desc.
			D3D12_RESOURCE_DESC textureDesc = {};
			textureDesc.MipLevels = 1;
			textureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
			textureDesc.Width = CityMaterialTextureWidth;
			textureDesc.Height = CityMaterialTextureHeight;
			textureDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
			textureDesc.DepthOrArraySize = 1;
			textureDesc.SampleDesc.Count = 1;
			textureDesc.SampleDesc.Quality = 0;
			textureDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;

			// The textures evenly span the color rainbow so that each city gets
			// a different material.
			float materialGradStep = (1.0f / static_cast<float>(CityMaterialCount));

			// Generate texture data.
			std::vector<std::vector<unsigned char>> cityTextureData;
			cityTextureData.resize(CityMaterialCount);
			for (UINT i = 0; i < CityMaterialCount; ++i)
			{
				ThrowIfFailed(m_device->CreateCommittedResource(
					&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
					D3D12_HEAP_FLAG_NONE,
					&textureDesc,
					D3D12_RESOURCE_STATE_COPY_DEST,
					nullptr,
					IID_PPV_ARGS(&m_cityMaterialTextures[i])));

				NAME_D3D12_OBJECT_INDEXED(m_cityMaterialTextures, i);

				// Fill the texture.
				float t = i * materialGradStep;
				cityTextureData[i].resize(CityMaterialTextureWidth * CityMaterialTextureHeight * CityMaterialTextureChannelCount);
				for (int x = 0; x < CityMaterialTextureWidth; ++x)
				{
					for (int y = 0; y < CityMaterialTextureHeight; ++y)
					{
						// Compute the appropriate index into the buffer based on the x/y coordinates.
						int pixelIndex = (y * CityMaterialTextureChannelCount * CityMaterialTextureWidth) + (x * CityMaterialTextureChannelCount);

						// Determine this row's position along the rainbow gradient.
						float tPrime = t + ((static_cast<float>(y) / static_cast<float>(CityMaterialTextureHeight)) * materialGradStep);

						// Compute the RGB value for this position along the rainbow
						// and pack the pixel value.
						XMVECTOR hsl = XMVectorSet(tPrime, 0.5f, 0.5f, 1.0f);
						XMVECTOR rgb = XMColorHSLToRGB(hsl);
						cityTextureData[i][pixelIndex + 0] = static_cast<unsigned char>((255 * XMVectorGetX(rgb)));
						cityTextureData[i][pixelIndex + 1] = static_cast<unsigned char>((255 * XMVectorGetY(rgb)));
						cityTextureData[i][pixelIndex + 2] = static_cast<unsigned char>((255 * XMVectorGetZ(rgb)));
						cityTextureData[i][pixelIndex + 3] = 255;
					}
				}
			}

			// Upload texture data to the default heap resources.
			{
				const UINT subresourceCount = textureDesc.DepthOrArraySize * textureDesc.MipLevels;
				const UINT64 uploadBufferStep = GetRequiredIntermediateSize(m_cityMaterialTextures[0].Get(), 0, subresourceCount); // All of our textures are the same size in this case.
				const UINT64 uploadBufferSize = uploadBufferStep * CityMaterialCount;
				ThrowIfFailed(m_device->CreateCommittedResource(
					&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
					D3D12_HEAP_FLAG_NONE,
					&CD3DX12_RESOURCE_DESC::Buffer(uploadBufferSize),
					D3D12_RESOURCE_STATE_GENERIC_READ,
					nullptr,
					IID_PPV_ARGS(&materialsUploadHeap)));

				for (int i = 0; i < CityMaterialCount; ++i)
				{
					// Copy data to the intermediate upload heap and then schedule 
					// a copy from the upload heap to the appropriate texture.
					D3D12_SUBRESOURCE_DATA textureData = {};
					textureData.pData = &cityTextureData[i][0];
					textureData.RowPitch = static_cast<LONG_PTR>((CityMaterialTextureChannelCount * textureDesc.Width));
					textureData.SlicePitch = textureData.RowPitch * textureDesc.Height;

					UpdateSubresources(m_commandList.Get(), m_cityMaterialTextures[i].Get(), materialsUploadHeap.Get(), i * uploadBufferStep, 0, subresourceCount, &textureData);
					m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_cityMaterialTextures[i].Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE));
				}
			}
		}

		// Load the occcity diffuse texture with baked-in ambient lighting.
		// This texture will be blended with a texture from the materials
		// array in the pixel shader.
		{
			D3D12_RESOURCE_DESC textureDesc = {};
			textureDesc.MipLevels = SampleAssets::Textures[0].MipLevels;
			textureDesc.Format = SampleAssets::Textures[0].Format;
			textureDesc.Width = SampleAssets::Textures[0].Width;
			textureDesc.Height = SampleAssets::Textures[0].Height;
			textureDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
			textureDesc.DepthOrArraySize = 1;
			textureDesc.SampleDesc.Count = 1;
			textureDesc.SampleDesc.Quality = 0;
			textureDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;

			ThrowIfFailed(m_device->CreateCommittedResource(
				&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
				D3D12_HEAP_FLAG_NONE,
				&textureDesc,
				D3D12_RESOURCE_STATE_COPY_DEST,
				nullptr,
				IID_PPV_ARGS(&m_cityDiffuseTexture)));

			const UINT subresourceCount = textureDesc.DepthOrArraySize * textureDesc.MipLevels;
			const UINT64 uploadBufferSize = GetRequiredIntermediateSize(m_cityDiffuseTexture.Get(), 0, subresourceCount);
			ThrowIfFailed(m_device->CreateCommittedResource(
				&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
				D3D12_HEAP_FLAG_NONE,
				&CD3DX12_RESOURCE_DESC::Buffer(uploadBufferSize),
				D3D12_RESOURCE_STATE_GENERIC_READ,
				nullptr,
				IID_PPV_ARGS(&textureUploadHeap)));

			NAME_D3D12_OBJECT(m_cityDiffuseTexture);

			// Copy data to the intermediate upload heap and then schedule 
			// a copy from the upload heap to the diffuse texture.
			D3D12_SUBRESOURCE_DATA textureData = {};
			textureData.pData = pMeshData + SampleAssets::Textures[0].Data[0].Offset;
			textureData.RowPitch = SampleAssets::Textures[0].Data[0].Pitch;
			textureData.SlicePitch = SampleAssets::Textures[0].Data[0].Size;

			UpdateSubresources(m_commandList.Get(), m_cityDiffuseTexture.Get(), textureUploadHeap.Get(), 0, 0, subresourceCount, &textureData);
			m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_cityDiffuseTexture.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE));
		}

		// Describe and create a sampler.
		D3D12_SAMPLER_DESC samplerDesc = {};
		samplerDesc.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR;
		samplerDesc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
		samplerDesc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
		samplerDesc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
		samplerDesc.MinLOD = 0;
		samplerDesc.MaxLOD = D3D12_FLOAT32_MAX;
		samplerDesc.MipLODBias = 0.0f;
		samplerDesc.MaxAnisotropy = 1;
		samplerDesc.ComparisonFunc = D3D12_COMPARISON_FUNC_ALWAYS;
		m_device->CreateSampler(&samplerDesc, m_samplerHeap->GetCPUDescriptorHandleForHeapStart());

		// Create SRV for the city's diffuse texture.
		CD3DX12_CPU_DESCRIPTOR_HANDLE srvHandle(m_cbvSrvHeap->GetCPUDescriptorHandleForHeapStart(), 0, m_cbvSrvDescriptorSize);
		D3D12_SHADER_RESOURCE_VIEW_DESC diffuseSrvDesc = {};
		diffuseSrvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
		diffuseSrvDesc.Format = SampleAssets::Textures->Format;
		diffuseSrvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
		diffuseSrvDesc.Texture2D.MipLevels = 1;
		m_device->CreateShaderResourceView(m_cityDiffuseTexture.Get(), &diffuseSrvDesc, srvHandle);
		srvHandle.Offset(m_cbvSrvDescriptorSize);

		// Create SRVs for each city material.
		for (int i = 0; i < CityMaterialCount; ++i)
		{
			D3D12_SHADER_RESOURCE_VIEW_DESC materialSrvDesc = {};
			materialSrvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
			materialSrvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
			materialSrvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
			materialSrvDesc.Texture2D.MipLevels = 1;
			m_device->CreateShaderResourceView(m_cityMaterialTextures[i].Get(), &materialSrvDesc, srvHandle);

			srvHandle.Offset(m_cbvSrvDescriptorSize);
		}
	}

	delete pMeshData;

	// Create the depth stencil view.
	{
		D3D12_DEPTH_STENCIL_VIEW_DESC depthStencilDesc = {};
		depthStencilDesc.Format = DXGI_FORMAT_D32_FLOAT;
		depthStencilDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
		depthStencilDesc.Flags = D3D12_DSV_FLAG_NONE;

		D3D12_CLEAR_VALUE depthOptimizedClearValue = {};
		depthOptimizedClearValue.Format = DXGI_FORMAT_D32_FLOAT;
		depthOptimizedClearValue.DepthStencil.Depth = 1.0f;
		depthOptimizedClearValue.DepthStencil.Stencil = 0;

		ThrowIfFailed(m_device->CreateCommittedResource(
			&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
			D3D12_HEAP_FLAG_NONE,
			&CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_D32_FLOAT, m_width, m_height, 1, 0, 1, 0, D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL),
			D3D12_RESOURCE_STATE_DEPTH_WRITE,
			&depthOptimizedClearValue,
			IID_PPV_ARGS(&m_depthStencil)
			));

		NAME_D3D12_OBJECT(m_depthStencil);

		m_device->CreateDepthStencilView(m_depthStencil.Get(), &depthStencilDesc, m_dsvHeap->GetCPUDescriptorHandleForHeapStart());
	}

	// Close the command list and execute it to begin the initial GPU setup.
	ThrowIfFailed(m_commandList->Close());
	ID3D12CommandList* ppCommandLists[] = { m_commandList.Get() };
	m_commandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists);

	CreateFrameResources();

	// Create synchronization objects and wait until assets have been uploaded to the GPU.
	{
		ThrowIfFailed(m_device->CreateFence(m_fenceValue, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&m_fence)));
		m_fenceValue++;

		// Create an event handle to use for frame synchronization.
		m_fenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
		if (m_fenceEvent == nullptr)
		{
			ThrowIfFailed(HRESULT_FROM_WIN32(GetLastError()));
		}

		// Wait for the command list to execute; we are reusing the same command 
		// list in our main loop but for now, we just want to wait for setup to 
		// complete before continuing.

		// Signal and increment the fence value.
		const UINT64 fenceToWaitFor = m_fenceValue;
		ThrowIfFailed(m_commandQueue->Signal(m_fence.Get(), fenceToWaitFor));
		m_fenceValue++;

		// Wait until the fence is completed.
		ThrowIfFailed(m_fence->SetEventOnCompletion(fenceToWaitFor, m_fenceEvent));
		WaitForSingleObject(m_fenceEvent, INFINITE);
	}
}
// Load the sample assets.
void D3D12Multithreading::LoadAssets()
{
	// Create the root signature.
	{
		CD3DX12_DESCRIPTOR_RANGE ranges[4]; // Perfomance TIP: Order from most frequent to least frequent.
		ranges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 2, 1);		// 2 frequently changed diffuse + normal textures - using registers t1 and t2.
		ranges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0);		// 1 frequently changed constant buffer.
		ranges[2].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 0);		// 1 infrequently changed shadow texture - starting in register t0.
		ranges[3].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, 2, 0);	// 2 static samplers.

		CD3DX12_ROOT_PARAMETER rootParameters[4];
		rootParameters[0].InitAsDescriptorTable(1, &ranges[0], D3D12_SHADER_VISIBILITY_PIXEL);
		rootParameters[1].InitAsDescriptorTable(1, &ranges[1], D3D12_SHADER_VISIBILITY_ALL);
		rootParameters[2].InitAsDescriptorTable(1, &ranges[2], D3D12_SHADER_VISIBILITY_PIXEL);
		rootParameters[3].InitAsDescriptorTable(1, &ranges[3], D3D12_SHADER_VISIBILITY_PIXEL);

		CD3DX12_ROOT_SIGNATURE_DESC rootSignatureDesc;
		rootSignatureDesc.Init(_countof(rootParameters), rootParameters, 0, nullptr, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);

		ComPtr<ID3DBlob> signature;
		ComPtr<ID3DBlob> error;
		ThrowIfFailed(D3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error));
		ThrowIfFailed(m_device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&m_rootSignature)));
	}

	// Create the pipeline state, which includes loading shaders.
	{
		ComPtr<ID3DBlob> vertexShader;
		ComPtr<ID3DBlob> pixelShader;

#ifdef _DEBUG
		// Enable better shader debugging with the graphics debugging tools.
		UINT compileFlags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION;
#else
		UINT compileFlags = D3DCOMPILE_OPTIMIZATION_LEVEL3;
#endif

		ThrowIfFailed(D3DCompileFromFile(GetAssetFullPath(L"shaders.hlsl").c_str(), nullptr, nullptr, "VSMain", "vs_5_0", compileFlags, 0, &vertexShader, nullptr));
		ThrowIfFailed(D3DCompileFromFile(GetAssetFullPath(L"shaders.hlsl").c_str(), nullptr, nullptr, "PSMain", "ps_5_0", compileFlags, 0, &pixelShader, nullptr));

		D3D12_INPUT_LAYOUT_DESC inputLayoutDesc;
		inputLayoutDesc.pInputElementDescs = SampleAssets::StandardVertexDescription;
		inputLayoutDesc.NumElements = _countof(SampleAssets::StandardVertexDescription);

		CD3DX12_DEPTH_STENCIL_DESC depthStencilDesc(D3D12_DEFAULT);
		depthStencilDesc.DepthEnable = true;
		depthStencilDesc.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL;
		depthStencilDesc.DepthFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL;
		depthStencilDesc.StencilEnable = FALSE;

		// Describe and create the PSO for rendering the scene.
		D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {};
		psoDesc.InputLayout = inputLayoutDesc;
		psoDesc.pRootSignature = m_rootSignature.Get();
		psoDesc.VS = { reinterpret_cast<UINT8*>(vertexShader->GetBufferPointer()), vertexShader->GetBufferSize() };
		psoDesc.PS = { reinterpret_cast<UINT8*>(pixelShader->GetBufferPointer()), pixelShader->GetBufferSize() };
		psoDesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT);
		psoDesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT);
		psoDesc.DepthStencilState = depthStencilDesc;
		psoDesc.SampleMask = UINT_MAX;
		psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
		psoDesc.NumRenderTargets = 1;
		psoDesc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM;
		psoDesc.DSVFormat = DXGI_FORMAT_D32_FLOAT;
		psoDesc.SampleDesc.Count = 1;

		ThrowIfFailed(m_device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&m_pipelineState)));

		// Alter the description and create the PSO for rendering
		// the shadow map.  The shadow map does not use a pixel
		// shader or render targets.
		psoDesc.PS.pShaderBytecode = 0;
		psoDesc.PS.BytecodeLength = 0;
		psoDesc.RTVFormats[0] = DXGI_FORMAT_UNKNOWN;
		psoDesc.NumRenderTargets = 0;

		ThrowIfFailed(m_device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&m_pipelineStateShadowMap)));
	}

	// Create temporary command list for initial GPU setup.
	ComPtr<ID3D12GraphicsCommandList> commandList;
	ThrowIfFailed(m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_commandAllocator.Get(), m_pipelineState.Get(), IID_PPV_ARGS(&commandList)));

	// Create render target views (RTVs).
	CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle(m_rtvHeap->GetCPUDescriptorHandleForHeapStart());
	for (UINT i = 0; i < FrameCount; i++)
	{
		ThrowIfFailed(m_swapChain->GetBuffer(i, IID_PPV_ARGS(&m_renderTargets[i])));
		m_device->CreateRenderTargetView(m_renderTargets[i].Get(), nullptr, rtvHandle);
		rtvHandle.Offset(1, m_rtvDescriptorSize);
	}

	// Create the depth stencil.
	{
		CD3DX12_RESOURCE_DESC shadowTextureDesc(
			D3D12_RESOURCE_DIMENSION_TEXTURE2D,
			0,
			static_cast<UINT>(m_viewport.Width), 
			static_cast<UINT>(m_viewport.Height), 
			1,
			1,
			DXGI_FORMAT_D32_FLOAT,
			1, 
			0,
			D3D12_TEXTURE_LAYOUT_UNKNOWN,
			D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL | D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE);

		D3D12_CLEAR_VALUE clearValue;	// Performance tip: Tell the runtime at resource creation the desired clear value.
		clearValue.Format = DXGI_FORMAT_D32_FLOAT;
		clearValue.DepthStencil.Depth = 1.0f;
		clearValue.DepthStencil.Stencil = 0;

		ThrowIfFailed(m_device->CreateCommittedResource(
			&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
			D3D12_HEAP_FLAG_NONE,
			&shadowTextureDesc,
			D3D12_RESOURCE_STATE_DEPTH_WRITE,
			&clearValue,
			IID_PPV_ARGS(&m_depthStencil)));

		// Create the depth stencil view.
		m_device->CreateDepthStencilView(m_depthStencil.Get(), nullptr, m_dsvHeap->GetCPUDescriptorHandleForHeapStart());
	}

	// Load scene assets.
	UINT fileSize = 0;
	UINT8* pAssetData;
	ThrowIfFailed(ReadDataFromFile(GetAssetFullPath(SampleAssets::DataFileName).c_str(), &pAssetData, &fileSize));

	// Create the vertex buffer.
	{
		ThrowIfFailed(m_device->CreateCommittedResource(
			&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
			D3D12_HEAP_FLAG_NONE,
			&CD3DX12_RESOURCE_DESC::Buffer(SampleAssets::VertexDataSize),
			D3D12_RESOURCE_STATE_COPY_DEST,
			nullptr,
			IID_PPV_ARGS(&m_vertexBuffer)));

		{
			ThrowIfFailed(m_device->CreateCommittedResource(
				&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
				D3D12_HEAP_FLAG_NONE,
				&CD3DX12_RESOURCE_DESC::Buffer(SampleAssets::VertexDataSize),
				D3D12_RESOURCE_STATE_GENERIC_READ,
				nullptr,
				IID_PPV_ARGS(&m_vertexBufferUpload)));

			// Copy data to the upload heap and then schedule a copy 
			// from the upload heap to the vertex buffer.
			D3D12_SUBRESOURCE_DATA vertexData = {};
			vertexData.pData = pAssetData + SampleAssets::VertexDataOffset;
			vertexData.RowPitch = SampleAssets::VertexDataSize;
			vertexData.SlicePitch = vertexData.RowPitch;

			PIXBeginEvent(commandList.Get(), 0, L"Copy vertex buffer data to default resource...");

			UpdateSubresources<1>(commandList.Get(), m_vertexBuffer.Get(), m_vertexBufferUpload.Get(), 0, 0, 1, &vertexData);
			commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_vertexBuffer.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER));

			PIXEndEvent(commandList.Get());
		}

		// Initialize the vertex buffer view.
		m_vertexBufferView.BufferLocation = m_vertexBuffer->GetGPUVirtualAddress();
		m_vertexBufferView.SizeInBytes = SampleAssets::VertexDataSize;
		m_vertexBufferView.StrideInBytes = SampleAssets::StandardVertexStride;
	}

	// Create the index buffer.
	{
		ThrowIfFailed(m_device->CreateCommittedResource(
			&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
			D3D12_HEAP_FLAG_NONE,
			&CD3DX12_RESOURCE_DESC::Buffer(SampleAssets::IndexDataSize),
			D3D12_RESOURCE_STATE_COPY_DEST,
			nullptr,
			IID_PPV_ARGS(&m_indexBuffer)));

		{
			ThrowIfFailed(m_device->CreateCommittedResource(
				&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
				D3D12_HEAP_FLAG_NONE,
				&CD3DX12_RESOURCE_DESC::Buffer(SampleAssets::IndexDataSize),
				D3D12_RESOURCE_STATE_GENERIC_READ,
				nullptr,
				IID_PPV_ARGS(&m_indexBufferUpload)));

			// Copy data to the upload heap and then schedule a copy 
			// from the upload heap to the index buffer.
			D3D12_SUBRESOURCE_DATA indexData = {};
			indexData.pData = pAssetData + SampleAssets::IndexDataOffset;
			indexData.RowPitch = SampleAssets::IndexDataSize;
			indexData.SlicePitch = indexData.RowPitch;

			PIXBeginEvent(commandList.Get(), 0, L"Copy index buffer data to default resource...");

			UpdateSubresources<1>(commandList.Get(), m_indexBuffer.Get(), m_indexBufferUpload.Get(), 0, 0, 1, &indexData);
			commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_indexBuffer.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_INDEX_BUFFER));

			PIXEndEvent(commandList.Get());
		}

		// Initialize the index buffer view.
		m_indexBufferView.BufferLocation = m_indexBuffer->GetGPUVirtualAddress();
		m_indexBufferView.SizeInBytes = SampleAssets::IndexDataSize;
		m_indexBufferView.Format = SampleAssets::StandardIndexFormat;
	}

	// Create shader resources.
	{
		// Get the CBV SRV descriptor size for the current device.
		const UINT cbvSrvDescriptorSize = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);

		// Get a handle to the start of the descriptor heap.
		CD3DX12_CPU_DESCRIPTOR_HANDLE cbvSrvHandle(m_cbvSrvHeap->GetCPUDescriptorHandleForHeapStart());

		{
			// Describe and create 2 null SRVs. Null descriptors are needed in order 
			// to achieve the effect of an "unbound" resource.
			D3D12_SHADER_RESOURCE_VIEW_DESC nullSrvDesc = {};
			nullSrvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
			nullSrvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
			nullSrvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
			nullSrvDesc.Texture2D.MipLevels = 1;
			nullSrvDesc.Texture2D.MostDetailedMip = 0;
			nullSrvDesc.Texture2D.ResourceMinLODClamp = 0.0f;

			m_device->CreateShaderResourceView(nullptr, &nullSrvDesc, cbvSrvHandle);
			cbvSrvHandle.Offset(cbvSrvDescriptorSize);

			m_device->CreateShaderResourceView(nullptr, &nullSrvDesc, cbvSrvHandle);
			cbvSrvHandle.Offset(cbvSrvDescriptorSize);
		}

		// Create each texture and SRV descriptor.
		const UINT srvCount = _countof(SampleAssets::Textures);
		PIXBeginEvent(commandList.Get(), 0, L"Copy diffuse and normal texture data to default resources...");
		for (int i = 0; i < srvCount; i++)
		{
			// Describe and create a Texture2D.
			const SampleAssets::TextureResource &tex = SampleAssets::Textures[i];
			CD3DX12_RESOURCE_DESC texDesc(
				D3D12_RESOURCE_DIMENSION_TEXTURE2D,
				0,
				tex.Width, 
				tex.Height, 
				1,
				static_cast<UINT16>(tex.MipLevels),
				tex.Format,
				1, 
				0,
				D3D12_TEXTURE_LAYOUT_UNKNOWN,
				D3D12_RESOURCE_FLAG_NONE);

			ThrowIfFailed(m_device->CreateCommittedResource(
				&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
				D3D12_HEAP_FLAG_NONE,
				&texDesc,
				D3D12_RESOURCE_STATE_COPY_DEST,
				nullptr,
				IID_PPV_ARGS(&m_textures[i])));

			{
				const UINT subresourceCount = texDesc.DepthOrArraySize * texDesc.MipLevels;
				UINT64 uploadBufferSize = GetRequiredIntermediateSize(m_textures[i].Get(), 0, subresourceCount);
				ThrowIfFailed(m_device->CreateCommittedResource(
					&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
					D3D12_HEAP_FLAG_NONE,
					&CD3DX12_RESOURCE_DESC::Buffer(uploadBufferSize),
					D3D12_RESOURCE_STATE_GENERIC_READ,
					nullptr,
					IID_PPV_ARGS(&m_textureUploads[i])));

				// Copy data to the intermediate upload heap and then schedule a copy 
				// from the upload heap to the Texture2D.
				D3D12_SUBRESOURCE_DATA textureData = {};
				textureData.pData = pAssetData + tex.Data->Offset;
				textureData.RowPitch = tex.Data->Pitch;
				textureData.SlicePitch = tex.Data->Size;

				UpdateSubresources(commandList.Get(), m_textures[i].Get(), m_textureUploads[i].Get(), 0, 0, subresourceCount, &textureData);
				commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_textures[i].Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE));
			}

			// Describe and create an SRV.
			D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
			srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
			srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
			srvDesc.Format = tex.Format;
			srvDesc.Texture2D.MipLevels = tex.MipLevels;
			srvDesc.Texture2D.MostDetailedMip = 0;
			srvDesc.Texture2D.ResourceMinLODClamp = 0.0f;
			m_device->CreateShaderResourceView(m_textures[i].Get(), &srvDesc, cbvSrvHandle);

			// Move to the next descriptor slot.
			cbvSrvHandle.Offset(cbvSrvDescriptorSize);
		}
		PIXEndEvent(commandList.Get());
	}

	free(pAssetData);

	// Create the samplers.
	{
		// Get the sampler descriptor size for the current device.
		const UINT samplerDescriptorSize = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER);

		// Get a handle to the start of the descriptor heap.
		CD3DX12_CPU_DESCRIPTOR_HANDLE samplerHandle(m_samplerHeap->GetCPUDescriptorHandleForHeapStart());

		// Describe and create the wrapping sampler, which is used for 
		// sampling diffuse/normal maps.
		D3D12_SAMPLER_DESC wrapSamplerDesc = {};
		wrapSamplerDesc.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR;
		wrapSamplerDesc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
		wrapSamplerDesc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
		wrapSamplerDesc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
		wrapSamplerDesc.MinLOD = 0;
		wrapSamplerDesc.MaxLOD = D3D12_FLOAT32_MAX;
		wrapSamplerDesc.MipLODBias = 0.0f;
		wrapSamplerDesc.MaxAnisotropy = 1;
		wrapSamplerDesc.ComparisonFunc = D3D12_COMPARISON_FUNC_ALWAYS;
		wrapSamplerDesc.BorderColor[0] = wrapSamplerDesc.BorderColor[1] = wrapSamplerDesc.BorderColor[2] = wrapSamplerDesc.BorderColor[3] = 0;
		m_device->CreateSampler(&wrapSamplerDesc, samplerHandle);

		// Move the handle to the next slot in the descriptor heap.
		samplerHandle.Offset(samplerDescriptorSize);

		// Describe and create the point clamping sampler, which is 
		// used for the shadow map.
		D3D12_SAMPLER_DESC clampSamplerDesc = {};
		clampSamplerDesc.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT;
		clampSamplerDesc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
		clampSamplerDesc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
		clampSamplerDesc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
		clampSamplerDesc.MipLODBias = 0.0f;
		clampSamplerDesc.MaxAnisotropy = 1;
		clampSamplerDesc.ComparisonFunc = D3D12_COMPARISON_FUNC_ALWAYS;
		clampSamplerDesc.BorderColor[0] = clampSamplerDesc.BorderColor[1] = clampSamplerDesc.BorderColor[2] = clampSamplerDesc.BorderColor[3] = 0;
		clampSamplerDesc.MinLOD = 0;
		clampSamplerDesc.MaxLOD = D3D12_FLOAT32_MAX;
		m_device->CreateSampler(&clampSamplerDesc, samplerHandle);
	}

	// Create lights.
	for (int i = 0; i < NumLights; i++)
	{
		// Set up each of the light positions and directions (they all start 
		// in the same place).
		m_lights[i].position = { 0.0f, 15.0f, -30.0f, 1.0f };
		m_lights[i].direction = { 0.0, 0.0f, 1.0f, 0.0f };
		m_lights[i].falloff = { 800.0f, 1.0f, 0.0f, 1.0f };
		m_lights[i].color = { 0.7f, 0.7f, 0.7f, 1.0f };

		XMVECTOR eye = XMLoadFloat4(&m_lights[i].position);
		XMVECTOR at = XMVectorAdd(eye, XMLoadFloat4(&m_lights[i].direction));
		XMVECTOR up = { 0, 1, 0 };

		m_lightCameras[i].Set(eye, at, up);
	}

	// Close the command list and use it to execute the initial GPU setup.
	ThrowIfFailed(commandList->Close());
	ID3D12CommandList* ppCommandLists[] = { commandList.Get() };
	m_commandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists);

	// Create frame resources.
	for (int i = 0; i < FrameCount; i++)
	{
		m_frameResources[i] = new FrameResource(m_device.Get(), m_pipelineState.Get(), m_pipelineStateShadowMap.Get(), m_dsvHeap.Get(), m_cbvSrvHeap.Get(), &m_viewport, i);
		m_frameResources[i]->WriteConstantBuffers(&m_viewport, &m_camera, m_lightCameras, m_lights);
	}
	m_currentFrameResourceIndex = 0;
	m_pCurrentFrameResource = m_frameResources[m_currentFrameResourceIndex];

	// Create synchronization objects and wait until assets have been uploaded to the GPU.
	{
		ThrowIfFailed(m_device->CreateFence(m_fenceValue, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&m_fence)));
		m_fenceValue++;

		// Create an event handle to use for frame synchronization.
		m_fenceEvent = CreateEventEx(nullptr, FALSE, FALSE, EVENT_ALL_ACCESS);
		if (m_fenceEvent == nullptr)
		{
			ThrowIfFailed(HRESULT_FROM_WIN32(GetLastError()));
		}

		// Wait for the command list to execute; we are reusing the same command 
		// list in our main loop but for now, we just want to wait for setup to 
		// complete before continuing.

		// Signal and increment the fence value.
		const UINT64 fenceToWaitFor = m_fenceValue;
		ThrowIfFailed(m_commandQueue->Signal(m_fence.Get(), fenceToWaitFor));
		m_fenceValue++;

		// Wait until the fence is completed.
		ThrowIfFailed(m_fence->SetEventOnCompletion(fenceToWaitFor, m_fenceEvent));
		WaitForSingleObject(m_fenceEvent, INFINITE);
	}
}
// Test if MusicBrainzClient::StartDiscIdRequest() parses a discid
// correctly.
TEST_F(MusicBrainzClientTest, ParseDiscID) {
  QByteArray data = ReadDataFromFile(":testdata/discid_2cd.xml");
  ASSERT_FALSE(data.isEmpty());

  // The following are the expected values given for the test file
  // discid_2cd.xml. The discid corresponds to the 2nd disc in the
  // set. The test file contains two releases but we only parse the first.
  const QString expected_artist = "Symphony X";
  const QString expected_title = "Live on the Edge of Forever";
  const int expected_number_of_tracks = 6;

  // Create a MusicBrainzClient instance with mock_network_.
  MusicBrainzClient musicbrainz_client(nullptr, mock_network_.get());

  // Hook the data as the response to a query of a given type.
  QMap<QString, QString> params;
  params["inc"] = "artists+recordings";
  MockNetworkReply* discid_reply =
      mock_network_->ExpectGet("discid", params, 200, data);

  // Set up a QSignalSpy which stores the result.
  QSignalSpy spy(&musicbrainz_client,
                 SIGNAL(Finished(const QString&, const QString,
                                 const MusicBrainzClient::ResultList&)));
  ASSERT_TRUE(spy.isValid());
  EXPECT_EQ(0, spy.count());

  // Start the request and get a result. The argument doesn't matter
  // in the test. It is here set to the discid of the requested disc.
  musicbrainz_client.StartDiscIdRequest("lvcH9_vbw_rJAbXieTOo1CbyNmQ-");
  discid_reply->Done();
  QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
  EXPECT_EQ(1, spy.count());

  QList<QVariant> result = spy.takeFirst();
  QString artist = result.takeFirst().toString();
  QString album = result.takeFirst().toString();
  ResultList tracks = result.takeFirst().value<ResultList>();

  // Check that title and artist are correct.
  EXPECT_EQ(expected_artist, artist);
  EXPECT_EQ(expected_title, album);

  // Check that we get the correct number of tracks, i.e. that the
  // correct disc is chosen in a multi-disc release.
  EXPECT_EQ(expected_number_of_tracks, tracks.count());

  // Check that the tracks is ordered by track number in ascending
  // order.
  for (int i = 0; i < tracks.count(); ++i) {
    EXPECT_EQ(i + 1, tracks[i].track_);
  }

  // Check some track information.
  EXPECT_EQ("Smoke and Mirrors", tracks[0].title_);
  EXPECT_EQ(1, tracks[0].track_);
  EXPECT_EQ(394600, tracks[0].duration_msec_);

  EXPECT_EQ("Church of the Machine", tracks[1].title_);
  EXPECT_EQ(2, tracks[1].track_);
  EXPECT_EQ(441866, tracks[1].duration_msec_);
}