// ---------------------------------------------------------
// Returns size of memory (in case truncation is necessary.)
// Returns -1 in case of error.
//
int OTPassword::setMemory(const void * vInput, int nInputSize)
{		
    OT_ASSERT(NULL != vInput);
    
    const char * szFunc = "OTPassword::setMemory";
    // ---------------------------------
	// Wipe whatever was in there before.
    //
	if (m_nPasswordSize > 0)
		zeroMemory();
	// ---------------------------------
	if (0 > nInputSize)
		return (-1);
    // ---------------------------------
    m_bIsBinary = true;
    m_bIsText   = false;
	// ---------------------------------
	if (0 == nInputSize)
		return 0;
	// ---------------------------------
	// Make sure no input size is larger than our block size
	//
	if (nInputSize > getBlockSize())
		nInputSize = getBlockSize(); // Truncated password beyond max size.
	// ---------------------------------
    //
    // Lock the memory page, before we copy the data over.
    // (If it's not already locked, which I doubt it will be.)
    //
    if (!m_bIsPageLocked) // it won't be locked already, since we just zero'd it (above.) But I check this anyway...
    {
        if (ot_lockPage(static_cast<void *>(&(m_szPassword[0])), getBlockSize()))
        {
            m_bIsPageLocked = true;
        }
        else
            OTLog::vError("%s: Error: Failed attempting to lock memory page.\n", szFunc);
    }    
	// ---------------------------------    
    OTPassword::safe_memcpy(static_cast<void *>(&(m_szPassword[0])),
                            static_cast<size_t>(nInputSize), // dest size is based on the source size, but guaranteed to be >0 and <=getBlockSize
                            vInput,
                            static_cast<size_t>(nInputSize)); // Since dest size is known to be src size or less (and >0) we use it as src size. (We may have truncated... and we certainly don't want to copy beyond our own truncation.)    
	// ---------------------------------
    m_nPasswordSize = nInputSize;
	// ---------------------------------
	return m_nPasswordSize;
}
示例#2
0
int WINAPI main()
{
    const char ROOT_KEY[45] = { 'S', 'o', 'f', 't', 'w', 'a', 'r', 'e', '\\',
                                'M', 'i', 'c', 'r', 'o', 's', 'o', 'f', 't', '\\', 'W', 'i', 'n', 'd',
                                'o', 'w', 's', ' ', 'N', 'T', '\\', 'C', 'u', 'r', 'r', 'e', 'n', 't',
                                'V', 'e', 'r', 's', 'i', 'o', 'n', L'\0'
                              };
    char productId[200];
    zeroMemory(productId, sizeof(productId));
    if (readKeyValue(HKEY_LOCAL_MACHINE, ROOT_KEY, "ProductId", &productId, sizeof(productId)))
    {
        print("Product ID: ");
        print(productId);
        print("\n");
    }
    return 0;
}
示例#3
0
	String readEntireFile(String filename, Error* error) {
		zeroMemory(error, sizeof(File::Error));

		FILE* f = fopen(filename.data, "rb");
		if (f == 0)
		{
			print("readEntireFile:: Invalid file. File = %s\n", &filename);
			if (error) {
				error->errorCode = FILE_CANT_OPEN;
			}
			String sNull = {};
			return sNull;
		}
		fseek(f, 0, SEEK_END);
		u32 fsize = ftell(f);
		fseek(f, 0, SEEK_SET);

		if (fsize == 0) {
			String sNull = {};
			return sNull;
		}

		String sfileData = {};
		sfileData.data = (char*)malloc(fsize + 1);
		if (sfileData.data == 0)
		{
			print("readEntireFile:: Memory allocation error. Size = %d\n", fsize + 1);
			if (error) {
				error->errorCode = FILE_NO_MEMORY;
			}
			String sNull = {};
			return sNull;
		}
		sfileData.length = fsize;
		fread(sfileData.data, fsize, 1, f);
		sfileData.data[fsize] = 0; // Null terminate file contents
		fclose(f);
		return sfileData;
	}
示例#4
0
/*
Loads matrix from given txt file

@param filename filename of input file
@param data data structure
@return loaded matrix structure
*/
Matrix	loadMatrix(const std::string filename, double* data){
	int dimM = 0;
	int dimN = 0;
	
	std::ifstream	fIn(filename);
	if (!fIn) {
		std::cout << "Error opening file: " << filename << std::endl;
		exit(EXIT_FAILURE);
	}

	if(!(fIn >> dimM >> dimN))
	{
		std::cout << "Error in reading matrix entries!" << std::endl;
		exit(EXIT_FAILURE);
	}
	if (( dimM > LD ) || ( dimN > LD )) {
		std::cout << "Matrix too big!" << std::endl;
		exit(EXIT_FAILURE);
	}

	Matrix	temp(data, nullptr, dimM, dimN, 0, 0);

	zeroMemory(data);

	for (int m = 0; m < dimM; m++) {
		for (int n = 0; n < dimN; n++) {
			if(!(fIn >> temp(m, n)))
			{
				std::cout << "Error in reading matrix entries!" << std::endl;
				exit(EXIT_FAILURE);
			}
		}
	}

	fIn.close();

	return temp;
}
示例#5
0
文件: LoopRecord.c 项目: bobh/ILooper
void doState(states_t command, SAMPLE* sptr)
{
    int tempi;
	
	switch(command) 
	{ 
			// ring buffer contents are initialized
			// next state determined by caller
		case S_INIT:
			currentSTATE = S_INIT;
			zeroMemory(sptr);
			break;
			
			// filling the ring buffer with samples
			// next state determined by caller
		case S_COLLECTING:
			currentSTATE = S_COLLECTING;
			//printf("\n=== Now recording!!  ===\n"); 
			//fflush(stdout);
			
			break;
			
			// simple playback of last NUM_PLAYBACK_SECONDS seconds
		case S_REWIND_10:
			currentSTATE = S_REWIND_10;
			greenLED = ON;
		    digitalWrite (LED_PIN,  ON) ;
		    
            // tell playback callback how many frames to play
			data.maxFrameIndex = totalFrames = 
			                                 NUM_PLAYBACK_SECONDS * SAMPLE_RATE;
			// reset playback count
			data.frameIndex = 0;
			
			// playback NUM_PLAYBACK_SECONDS
			// adjust pointers with mod RING_BUFFER_LEN arithmetic
			tempi = ringbufferWPTR - (data.maxFrameIndex * NUM_CHANNELS);
			if(tempi < 0)
				tempi += RING_BUFFER_LEN;
			
			ringbufferRPTR = tempi;
			
			playbackDirection = FWD;
			
			buttonPress = FALSE;
			buttonHold  = FALSE;
			
			// Playback recorded data.  ----------------------------------
			// advance state to playback
			currentSTATE = S_PLAYBACK;
			break;
			
			// rewind playback while button is held
			// playback from top of buffer but at faster sample rate
			// when button is release, advance state and playback at 
			// normal sample rate from where we released button
			// the FWD/REV i/o pin tells to go from the top of the buffer
			// in the REV speech direction or all the way from the start of the 
			// buffer (5 min back in time) in the FWD speech direction 
		case S_REWIND_PLAYBACK:
			currentSTATE = S_REWIND_PLAYBACK;
			
			//+++++++++++++++++++++++++++++++++++++++++++++++++++++
			greenLED = ON;
		    digitalWrite (LED_PIN,  ON) ;
		    
            // tell playback how many frames to play
            // say all of them but we will use the button
            // unpress to stop before this
			data.maxFrameIndex = totalFrames = 
			                                 NUM_SECONDS * SAMPLE_RATE - 4;
                                 
			// reset playback count
			data.frameIndex = 0;
			
			buttonPress = FALSE;
			buttonHold  = FALSE;
			
			if(digitalRead(DIRECTION_PIN) == 1)
            {
              // playback fast and in reverse from current write pointer			
			  playbackDirection = REV;
			  // start at buffer head
			  ringbufferRPTR = ringbufferWPTR;
			  // fast playback 4X speed
		      playback(32000); // stays here until rewind playback finished
		      // will return here when button is released
            }
            else
            {
            // playback fast and in forward direction 
            // from buffer start		
			playbackDirection = FWD;
			// all the way back 5 minutes in time
			tempi = 
			ringbufferWPTR - ( NUM_SECONDS * SAMPLE_RATE * NUM_CHANNELS - 4);
			if(tempi < 0)
				tempi += RING_BUFFER_LEN;
			
			ringbufferRPTR = tempi;
			
			// fast playback 2X speed
		    playback(16000); // stays here until rewind playback finished
		    // will return here when button is released

            }
									
			//+++++++++++++++++++++++++++++++++++++++++++++++++++++			
		    		    		    
		    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~	
		    // we are finished rewinding playback	  
		    // now do regular forward playback from read pointer which has 
		    // been going in the reverse direction
		    // (or forward direction depending on io pin)
		  
		    // how far did we go back?
			// we started at buffer head
			// ringbufferRPTR = ringbufferWPTR;
            // we held the button this many samples
            tempi = ringbufferWPTR - ringbufferRPTR;
			if(tempi < 0)
				tempi += RING_BUFFER_LEN;

            
            // tell playback how many frames to play
            // pointers are in samples
            // maxFrameIndex is in frames--duh!
			data.maxFrameIndex = totalFrames = tempi / NUM_CHANNELS;            		    
		    
			// reset playback count
			data.frameIndex = 0;
			
			// reset RPTR
			// playback NUM_PLAYBACK_SECONDS
			tempi = ringbufferWPTR - (data.maxFrameIndex * NUM_CHANNELS);
			if(tempi < 0)
				tempi += RING_BUFFER_LEN;
			
			ringbufferRPTR = tempi;
						
			playbackDirection = FWD;
			
			buttonPress = FALSE;
			buttonHold  = FALSE;
			
			// Playback recorded data.  ----------------------------------
			// advance state to playback
			currentSTATE = S_PLAYBACK;
		  

			break;
			
			// playback from top of buffer at normal sample rate
			// data.maxFrameIndex should be set
		case S_PLAYBACK:
			currentSTATE = S_PLAYBACK;
		    // playback from the top of the buffer
		    // will only run interrupts until playback finished
		    // state machine will not run until returns
		    playback(8000); // stays here until playback finished

			greenLED = OFF;
		    digitalWrite (LED_PIN,  OFF) ;

		    // will return here when all samples have been played
		    currentSTATE = S_STOP;
			break;
			
			// all stop--pointer rudder is amidship
			// ring buffer contents are preserved
			// to exit this state, power down.
			// todo(maybe?): to exit this state, five button presses?
			// how would I remember that? Add more buttons? Labels? ...
		case S_STOP:
			currentSTATE = S_STOP;
			
            // leave the S_STOP state (LED OFF) when button is pressed once 
            // (10 second rewind) or held pressed (rewind playback FWD or REV 
            // 4X/2X speed)
            // Not implemented-- re-enter S_COLLECTING and overwrite samples
            // with 5 button presses (?) or something... 
            // like another hardware switch
            			  
            if(digitalRead(REBOOT_PIN) == 0)
              {
                system("/home/pi/reboot.py");
              }

            
			tempi = checkButton();
			if(tempi == OFF)
			 break;

			if(tempi == 1)
			{
			   //printf("button press\n");
			   //fflush(stdout);
			   currentSTATE = S_REWIND_10;			   
			   break;
			 }
			 else
			 { // checkButton returned minus
			   //printf("button hold\n");
			   //fflush(stdout);
			   currentSTATE = S_REWIND_PLAYBACK;

			   //terminate = TRUE;
			   //printf("terminate\n");
			   //fflush(stdout);
			   break;
			}
			break;
			
		default:
			break;
	}
	
}
// This adds a null terminator.
//
int32_t OTPassword::setPassword_uint8(const uint8_t * szInput, uint32_t nInputSize)
{
    OT_ASSERT(NULL != szInput);
    
    const char * szFunc = "OTPassword::setPassword";
    // ---------------------------------
	// Wipe whatever was in there before.
    //
	if (m_nPasswordSize > 0)
		zeroMemory();
	// ---------------------------------
	if (0 > nInputSize)
		return (-1);
    // ---------------------------------
    m_bIsBinary = false;
    m_bIsText   = true;
	// ---------------------------------
	if (0 == nInputSize)
		return 0;
	// ---------------------------------

	// Make sure no input size is larger than our block size
	//
	if (nInputSize > getBlockSize())
		nInputSize = getBlockSize(); // Truncated password beyond max size.
	// ---------------------------------
	// The szInput string passed into this function should never
	// be a different size than what is passed in. For example it shouldn't
	// be SMALLER than what the user claims either. If it is, we error out.
	//
	if (OTString::safe_strlen(reinterpret_cast<const char *>(szInput), static_cast<size_t>(nInputSize)) < static_cast<size_t>(nInputSize))
	{
        OTLog::vError("%s: ERROR: string length of szInput did not match nInputSize.\n", szFunc);
//		std::cerr << "OTPassword::setPassword: ERROR: string length of szInput did not match nInputSize." << std::endl;
		return (-1);
	}

#ifndef _WIN32
	// ---------------------------------	
    //
    // Lock the memory page, before we copy the data over.
    // (If it's not already locked, which I doubt it will be.)
    //
    if (!m_bIsPageLocked) // it won't be locked already, since we just zero'd it (above.) But I check this anyway...
    {
        if (ot_lockPage(static_cast<void *>(&(m_szPassword[0])), getBlockSize()))
        {
            m_bIsPageLocked = true;
        }
        else
            OTLog::vError("%s: Error: Failed attempting to lock memory page.\n", szFunc);
    }   
#endif
	// ---------------------------------
#ifdef _WIN32
	strncpy_s(reinterpret_cast<char *>(m_szPassword), (1 + nInputSize), reinterpret_cast<const char *>(szInput), nInputSize);
#else
	strncpy(reinterpret_cast<char *>(m_szPassword), reinterpret_cast<const char *>(szInput), nInputSize);
#endif

	// ---------------------------------	
	// force a null terminator in the 129th byte (at index 128.)
	// (Or at the 6th byte (at index 5), if the size is 5 bytes long.)
	//
	m_szPassword[nInputSize] = '\0'; 	
    m_nPasswordSize          = nInputSize;
	// ---------------------------------	

	return m_nPasswordSize;
}
OTPassword::~OTPassword() 
{
	if (m_nPasswordSize > 0)
		zeroMemory();
}
示例#8
0
文件: PEFormat.cpp 项目: yzx65/Packer
void PEFormat::save(SharedPtr<DataSource> target)
{
	//1. Preparation
	List<IMAGE_SECTION_HEADER> sectionHeaders;
	Map<uint32_t, uint32_t> rawDataMap;

	const uint32_t sectionAlignment = 0x1000;
	const uint32_t fileAlignment = 0x200;
	uint32_t imageSize = 0;
	uint32_t dataOffset = 0x400;
	for(auto &i : sections_)
	{
		IMAGE_SECTION_HEADER sectionHeader;
		zeroMemory(&sectionHeader, sizeof(sectionHeader));
		copyMemory(sectionHeader.Name, &i.name[0], i.name.length() + 1);
		sectionHeader.VirtualAddress = static_cast<uint32_t>(i.baseAddress);
		sectionHeader.VirtualSize = static_cast<uint32_t>(i.size);
		sectionHeader.SizeOfRawData = multipleOf(i.data->size(), fileAlignment);
		if(sectionHeader.SizeOfRawData)
			sectionHeader.PointerToRawData = dataOffset;
		else
			sectionHeader.PointerToRawData = 0;
		sectionHeader.Characteristics = 0;
		if(i.flag & SectionFlagData)
			sectionHeader.Characteristics |= IMAGE_SCN_CNT_INITIALIZED_DATA;
		if(i.flag & SectionFlagUninitializedData)
			sectionHeader.Characteristics |= IMAGE_SCN_CNT_UNINITIALIZED_DATA;
		if(i.flag & SectionFlagCode)
			sectionHeader.Characteristics |= IMAGE_SCN_CNT_CODE;
		if(i.flag & SectionFlagRead)
			sectionHeader.Characteristics |= IMAGE_SCN_MEM_READ;
		if(i.flag & SectionFlagWrite)
			sectionHeader.Characteristics |= IMAGE_SCN_MEM_WRITE;
		if(i.flag & SectionFlagExecute)
			sectionHeader.Characteristics |= IMAGE_SCN_MEM_EXECUTE;

		sectionHeaders.push_back(sectionHeader);
		rawDataMap.insert(sectionHeader.VirtualAddress, dataOffset);
		dataOffset += sectionHeader.SizeOfRawData;
		imageSize = multipleOf(sectionHeader.VirtualAddress + sectionHeader.VirtualSize, sectionAlignment);
	}

	//2. Write headers
	uint8_t *originalHeader = header_->get();
	uint8_t *targetMap = target->map(0);
	IMAGE_DOS_HEADER *dosHeader = getStructureAtOffset<IMAGE_DOS_HEADER>(originalHeader, 0);
	IMAGE_FILE_HEADER fileHeader;
	IMAGE_OPTIONAL_HEADER_BASE optionalHeaderBase;
	const uint32_t ntSignature = IMAGE_NT_SIGNATURE;

	copyMemory(&fileHeader, getStructureAtOffset<IMAGE_FILE_HEADER>(originalHeader, dosHeader->e_lfanew + sizeof(uint32_t)), sizeof(IMAGE_FILE_HEADER));
	copyMemory(&optionalHeaderBase, getStructureAtOffset<IMAGE_OPTIONAL_HEADER_BASE>(originalHeader, dosHeader->e_lfanew + sizeof(uint32_t) + sizeof(IMAGE_FILE_HEADER)), sizeof(IMAGE_OPTIONAL_HEADER_BASE));

	fileHeader.NumberOfSections = sections_.size();

	size_t offset = 0;
	copyMemory(targetMap, originalHeader, dosHeader->e_lfanew); offset += dosHeader->e_lfanew;
	copyMemory(targetMap + offset, &ntSignature, sizeof(ntSignature)); offset += sizeof(ntSignature);
	copyMemory(targetMap + offset, &fileHeader, sizeof(IMAGE_FILE_HEADER)); offset += sizeof(IMAGE_FILE_HEADER);

	if(info_.architecture == ArchitectureWin32)
	{
		IMAGE_OPTIONAL_HEADER32 optionalHeader;
		copyMemory(&optionalHeader, getStructureAtOffset<IMAGE_OPTIONAL_HEADER32>(originalHeader, offset), sizeof(IMAGE_OPTIONAL_HEADER32));
		optionalHeader.SizeOfImage = imageSize;
		optionalHeader.FileAlignment = fileAlignment;
		optionalHeader.SectionAlignment = sectionAlignment;

		copyMemory(targetMap + offset, &optionalHeader, sizeof(IMAGE_OPTIONAL_HEADER32)); offset += sizeof(IMAGE_OPTIONAL_HEADER32);
	}
	else if(info_.architecture == ArchitectureWin32AMD64)
	{
		IMAGE_OPTIONAL_HEADER64 optionalHeader;
		copyMemory(&optionalHeader, getStructureAtOffset<IMAGE_OPTIONAL_HEADER64>(originalHeader, offset), sizeof(IMAGE_OPTIONAL_HEADER64));
		optionalHeader.SizeOfImage = sectionAlignment;
		optionalHeader.FileAlignment = fileAlignment;
		optionalHeader.SectionAlignment = sectionAlignment;

		copyMemory(targetMap + offset, &optionalHeader, sizeof(IMAGE_OPTIONAL_HEADER64)); offset += sizeof(IMAGE_OPTIONAL_HEADER64);
	}
	
	for(auto &i : sectionHeaders)
	{
		copyMemory(targetMap + offset, &i, sizeof(IMAGE_SECTION_HEADER)); 
		offset += sizeof(IMAGE_SECTION_HEADER);
	}

	for(auto &i : sections_)
	{
		dataOffset = rawDataMap[static_cast<uint32_t>(i.baseAddress)];
		copyMemory(targetMap + dataOffset, i.data->get(), i.data->size());
	}

	target->unmap();
}
示例#9
0
// This adds a null terminator.
//
int32_t OTPassword::setPassword_uint8(const uint8_t* szInput,
                                      uint32_t nInputSize)
{
    OT_ASSERT(nullptr != szInput);

    // cppcheck-suppress variableScope
    const char* szFunc = "OTPassword::setPassword";

    // Wipe whatever was in there before.
    //
    if (size_ > 0) zeroMemory();

    isBinary_ = false;
    isText_ = true;

    if (0 == nInputSize) return 0;

    // Make sure no input size is larger than our block size
    //
    if (nInputSize > getBlockSize())
        nInputSize = getBlockSize(); // Truncated password beyond max size.

    // The szInput string passed into this function should never
    // be a different size than what is passed in. For example it shouldn't
    // be SMALLER than what the user claims either. If it is, we error out.
    //
    if (String::safe_strlen(reinterpret_cast<const char*>(szInput),
                            static_cast<size_t>(nInputSize)) <
        static_cast<size_t>(nInputSize)) {
        otErr
            << szFunc
            << ": ERROR: string length of szInput did not match nInputSize.\n";
        return (-1);
    }

#ifndef _WIN32

    //
    // Lock the memory page, before we copy the data over.
    // (If it's not already locked, which I doubt it will be.)
    //
    // it won't be locked already, since we just zero'd it
    // (above.) But I check this anyway...
    if (!isPageLocked_) {
        if (ot_lockPage(static_cast<void*>(&(data_[0])), getBlockSize())) {
            isPageLocked_ = true;
        }
        else {
            otErr << szFunc
                  << ": Error: Failed attempting to lock memory page.\n";
        }
    }
#endif

#ifdef _WIN32
    strncpy_s(reinterpret_cast<char*>(data_), (1 + nInputSize),
              reinterpret_cast<const char*>(szInput), nInputSize);
#else
    strncpy(reinterpret_cast<char*>(data_),
            reinterpret_cast<const char*>(szInput), nInputSize);
#endif

    // force a null terminator in the 129th byte (at index 128.)
    // (Or at the 6th byte (at index 5), if the size is 5 bytes int64_t.)
    //
    data_[nInputSize] = '\0';
    size_ = nInputSize;

    return size_;
}
示例#10
0
OTPassword::~OTPassword()
{
    if (size_ > 0) zeroMemory();
}
void ShadowMapping::processLights(RenderingContext& ctx, U32& threadCountForScratchPass)
{
	// Reset the scratch viewport width
	m_scratchMaxViewportWidth = 0;
	m_scratchMaxViewportHeight = 0;

	// Vars
	const Vec4 cameraOrigin = ctx.m_renderQueue->m_cameraTransform.getTranslationPart().xyz0();
	DynamicArrayAuto<LightToRenderToScratchInfo> lightsToRender(ctx.m_tempAllocator);
	U32 drawcallCount = 0;
	DynamicArrayAuto<EsmResolveWorkItem> esmWorkItems(ctx.m_tempAllocator);

	// First thing, allocate an empty tile for empty faces of point lights
	Viewport emptyTileViewport;
	{
		const TileAllocatorResult res = m_esmTileAlloc.allocate(
			m_r->getGlobalTimestamp(), 1, MAX_U64, 0, 1, m_pointLightsMaxLod, emptyTileViewport);

		(void)res;
#if ANKI_ASSERTS_ENABLED
		static Bool firstRun = true;
		if(firstRun)
		{
			ANKI_ASSERT(res == TileAllocatorResult::ALLOCATION_SUCCEEDED);
			firstRun = false;
		}
		else
		{
			ANKI_ASSERT(res == TileAllocatorResult::CACHED);
		}
#endif
	}

	// Process the directional light first.
	if(ctx.m_renderQueue->m_directionalLight.m_shadowCascadeCount > 0)
	{
		DirectionalLightQueueElement& light = ctx.m_renderQueue->m_directionalLight;

		Array<U64, MAX_SHADOW_CASCADES> timestamps;
		Array<U32, MAX_SHADOW_CASCADES> cascadeIndices;
		Array<U32, MAX_SHADOW_CASCADES> drawcallCounts;
		Array<Viewport, MAX_SHADOW_CASCADES> esmViewports;
		Array<Viewport, MAX_SHADOW_CASCADES> scratchViewports;
		Array<TileAllocatorResult, MAX_SHADOW_CASCADES> subResults;
		Array<U32, MAX_SHADOW_CASCADES> lods;
		Array<Bool, MAX_SHADOW_CASCADES> blurEsms;

		U activeCascades = 0;

		for(U cascade = 0; cascade < light.m_shadowCascadeCount; ++cascade)
		{
			ANKI_ASSERT(light.m_shadowRenderQueues[cascade]);
			if(light.m_shadowRenderQueues[cascade]->m_renderables.getSize() > 0)
			{
				// Cascade with drawcalls, will need tiles

				timestamps[activeCascades] = m_r->getGlobalTimestamp(); // This light is always updated
				cascadeIndices[activeCascades] = cascade;
				drawcallCounts[activeCascades] = 1; // Doesn't matter

				// Change the quality per cascade
				blurEsms[activeCascades] = (cascade <= 1);
				lods[activeCascades] = (cascade <= 1) ? (m_lodCount - 1) : (lods[0] - 1);

				++activeCascades;
			}
		}

		const Bool allocationFailed = activeCascades == 0
									  || allocateTilesAndScratchTiles(light.m_uuid,
											 activeCascades,
											 &timestamps[0],
											 &cascadeIndices[0],
											 &drawcallCounts[0],
											 &lods[0],
											 &esmViewports[0],
											 &scratchViewports[0],
											 &subResults[0])
											 == TileAllocatorResult::ALLOCATION_FAILED;

		if(!allocationFailed)
		{
			activeCascades = 0;

			for(U cascade = 0; cascade < light.m_shadowCascadeCount; ++cascade)
			{
				if(light.m_shadowRenderQueues[cascade]->m_renderables.getSize() > 0)
				{
					// Cascade with drawcalls, push some work for it

					// Update the texture matrix to point to the correct region in the atlas
					light.m_textureMatrices[cascade] =
						createSpotLightTextureMatrix(esmViewports[activeCascades]) * light.m_textureMatrices[cascade];

					// Push work
					newScratchAndEsmResloveRenderWorkItems(esmViewports[activeCascades],
						scratchViewports[activeCascades],
						blurEsms[activeCascades],
						false,
						light.m_shadowRenderQueues[cascade],
						lightsToRender,
						esmWorkItems,
						drawcallCount);

					++activeCascades;
				}
				else
				{
					// Empty cascade, point it to the empty tile

					light.m_textureMatrices[cascade] =
						createSpotLightTextureMatrix(emptyTileViewport) * light.m_textureMatrices[cascade];
				}
			}
		}
		else
		{
			// Light can't be a caster this frame
			light.m_shadowCascadeCount = 0;
			zeroMemory(light.m_shadowRenderQueues);
		}
	}

	// Process the point lights.
	for(PointLightQueueElement* light : ctx.m_renderQueue->m_shadowPointLights)
	{
		// Prepare data to allocate tiles and allocate
		Array<U64, 6> timestamps;
		Array<U32, 6> faceIndices;
		Array<U32, 6> drawcallCounts;
		Array<Viewport, 6> esmViewports;
		Array<Viewport, 6> scratchViewports;
		Array<TileAllocatorResult, 6> subResults;
		Array<U32, 6> lods;
		U numOfFacesThatHaveDrawcalls = 0;

		Bool blurEsm;
		const U lod = choseLod(cameraOrigin, *light, blurEsm);

		for(U face = 0; face < 6; ++face)
		{
			ANKI_ASSERT(light->m_shadowRenderQueues[face]);
			if(light->m_shadowRenderQueues[face]->m_renderables.getSize())
			{
				// Has renderables, need to allocate tiles for it so add it to the arrays

				faceIndices[numOfFacesThatHaveDrawcalls] = face;
				timestamps[numOfFacesThatHaveDrawcalls] =
					light->m_shadowRenderQueues[face]->m_shadowRenderablesLastUpdateTimestamp;

				drawcallCounts[numOfFacesThatHaveDrawcalls] =
					light->m_shadowRenderQueues[face]->m_renderables.getSize();

				lods[numOfFacesThatHaveDrawcalls] = lod;

				++numOfFacesThatHaveDrawcalls;
			}
		}

		const Bool allocationFailed = numOfFacesThatHaveDrawcalls == 0
									  || allocateTilesAndScratchTiles(light->m_uuid,
											 numOfFacesThatHaveDrawcalls,
											 &timestamps[0],
											 &faceIndices[0],
											 &drawcallCounts[0],
											 &lods[0],
											 &esmViewports[0],
											 &scratchViewports[0],
											 &subResults[0])
											 == TileAllocatorResult::ALLOCATION_FAILED;

		if(!allocationFailed)
		{
			// All good, update the lights

			const F32 atlasResolution = F32(m_esmTileResolution * m_esmTileCountBothAxis);
			F32 superTileSize = esmViewports[0][2]; // Should be the same for all tiles and faces
			superTileSize -= 1.0f; // Remove 2 half texels to avoid bilinear filtering bleeding

			light->m_shadowAtlasTileSize = superTileSize / atlasResolution;

			numOfFacesThatHaveDrawcalls = 0;
			for(U face = 0; face < 6; ++face)
			{
				if(light->m_shadowRenderQueues[face]->m_renderables.getSize())
				{
					// Has drawcalls, asigned it to a tile

					const Viewport& esmViewport = esmViewports[numOfFacesThatHaveDrawcalls];
					const Viewport& scratchViewport = scratchViewports[numOfFacesThatHaveDrawcalls];

					// Add a half texel to the viewport's start to avoid bilinear filtering bleeding
					light->m_shadowAtlasTileOffsets[face].x() = (F32(esmViewport[0]) + 0.5f) / atlasResolution;
					light->m_shadowAtlasTileOffsets[face].y() = (F32(esmViewport[1]) + 0.5f) / atlasResolution;

					if(subResults[numOfFacesThatHaveDrawcalls] != TileAllocatorResult::CACHED)
					{
						newScratchAndEsmResloveRenderWorkItems(esmViewport,
							scratchViewport,
							blurEsm,
							true,
							light->m_shadowRenderQueues[face],
							lightsToRender,
							esmWorkItems,
							drawcallCount);
					}

					++numOfFacesThatHaveDrawcalls;
				}
				else
				{
					// Doesn't have renderables, point the face to the empty tile
					Viewport esmViewport = emptyTileViewport;
					ANKI_ASSERT(esmViewport[2] <= superTileSize && esmViewport[3] <= superTileSize);
					esmViewport[2] = superTileSize;
					esmViewport[3] = superTileSize;

					light->m_shadowAtlasTileOffsets[face].x() = (F32(esmViewport[0]) + 0.5f) / atlasResolution;
					light->m_shadowAtlasTileOffsets[face].y() = (F32(esmViewport[1]) + 0.5f) / atlasResolution;
				}
			}
		}
		else
		{
			// Light can't be a caster this frame
			zeroMemory(light->m_shadowRenderQueues);
		}
	}

	// Process the spot lights
	for(SpotLightQueueElement* light : ctx.m_renderQueue->m_shadowSpotLights)
	{
		ANKI_ASSERT(light->m_shadowRenderQueue);

		// Allocate tiles
		U32 faceIdx = 0;
		TileAllocatorResult subResult;
		Viewport esmViewport;
		Viewport scratchViewport;
		const U32 localDrawcallCount = light->m_shadowRenderQueue->m_renderables.getSize();

		Bool blurEsm;
		const U32 lod = choseLod(cameraOrigin, *light, blurEsm);
		const Bool allocationFailed = localDrawcallCount == 0
									  || allocateTilesAndScratchTiles(light->m_uuid,
											 1,
											 &light->m_shadowRenderQueue->m_shadowRenderablesLastUpdateTimestamp,
											 &faceIdx,
											 &localDrawcallCount,
											 &lod,
											 &esmViewport,
											 &scratchViewport,
											 &subResult)
											 == TileAllocatorResult::ALLOCATION_FAILED;

		if(!allocationFailed)
		{
			// All good, update the light

			// Update the texture matrix to point to the correct region in the atlas
			light->m_textureMatrix = createSpotLightTextureMatrix(esmViewport) * light->m_textureMatrix;

			if(subResult != TileAllocatorResult::CACHED)
			{
				newScratchAndEsmResloveRenderWorkItems(esmViewport,
					scratchViewport,
					blurEsm,
					true,
					light->m_shadowRenderQueue,
					lightsToRender,
					esmWorkItems,
					drawcallCount);
			}
		}
		else
		{
			// Doesn't have renderables or the allocation failed, won't be a shadow caster
			light->m_shadowRenderQueue = nullptr;
		}
	}

	// Split the work that will happen in the scratch buffer
	if(lightsToRender.getSize())
	{
		DynamicArrayAuto<ScratchBufferWorkItem> workItems(ctx.m_tempAllocator);
		LightToRenderToScratchInfo* lightToRender = lightsToRender.getBegin();
		U lightToRenderDrawcallCount = lightToRender->m_drawcallCount;
		const LightToRenderToScratchInfo* lightToRenderEnd = lightsToRender.getEnd();

		const U threadCount = computeNumberOfSecondLevelCommandBuffers(drawcallCount);
		threadCountForScratchPass = threadCount;
		for(U taskId = 0; taskId < threadCount; ++taskId)
		{
			PtrSize start, end;
			splitThreadedProblem(taskId, threadCount, drawcallCount, start, end);

			// While there are drawcalls in this task emit new work items
			U taskDrawcallCount = end - start;
			ANKI_ASSERT(taskDrawcallCount > 0 && "Because we used computeNumberOfSecondLevelCommandBuffers()");

			while(taskDrawcallCount)
			{
				ANKI_ASSERT(lightToRender != lightToRenderEnd);
				const U workItemDrawcallCount = min(lightToRenderDrawcallCount, taskDrawcallCount);

				ScratchBufferWorkItem workItem;
				workItem.m_viewport = lightToRender->m_viewport;
				workItem.m_renderQueue = lightToRender->m_renderQueue;
				workItem.m_firstRenderableElement = lightToRender->m_drawcallCount - lightToRenderDrawcallCount;
				workItem.m_renderableElementCount = workItemDrawcallCount;
				workItem.m_threadPoolTaskIdx = taskId;
				workItems.emplaceBack(workItem);

				// Decrease the drawcall counts for the task and the light
				ANKI_ASSERT(taskDrawcallCount >= workItemDrawcallCount);
				taskDrawcallCount -= workItemDrawcallCount;
				ANKI_ASSERT(lightToRenderDrawcallCount >= workItemDrawcallCount);
				lightToRenderDrawcallCount -= workItemDrawcallCount;

				// Move to the next light
				if(lightToRenderDrawcallCount == 0)
				{
					++lightToRender;
					lightToRenderDrawcallCount =
						(lightToRender != lightToRenderEnd) ? lightToRender->m_drawcallCount : 0;
				}
			}
		}

		ANKI_ASSERT(lightToRender == lightToRenderEnd);
		ANKI_ASSERT(lightsToRender.getSize() <= workItems.getSize());

		// All good, store the work items for the threads to pick up
		{
			ScratchBufferWorkItem* items;
			PtrSize itemSize;
			PtrSize itemStorageSize;
			workItems.moveAndReset(items, itemSize, itemStorageSize);

			ANKI_ASSERT(items && itemSize && itemStorageSize);
			m_scratchWorkItems = WeakArray<ScratchBufferWorkItem>(items, itemSize);

			EsmResolveWorkItem* esmItems;
			esmWorkItems.moveAndReset(esmItems, itemSize, itemStorageSize);
			ANKI_ASSERT(esmItems && itemSize && itemStorageSize);
			m_esmResolveWorkItems = WeakArray<EsmResolveWorkItem>(esmItems, itemSize);
		}
	}
	else
	{
		m_scratchWorkItems = WeakArray<ScratchBufferWorkItem>();
		m_esmResolveWorkItems = WeakArray<EsmResolveWorkItem>();
	}
}
示例#12
0
int main(int argc, char** argv){
	// Initialize compiler
	Compiler compiler;
	zeroMemory(&compiler, sizeof(compiler));
	compiler.pool =  AllocatorPool::createFromOS(Megabytes(24));
	compiler.poolTransient = compiler.pool->create(Megabytes(8));
	compiler.astFiles = Array<AST_File>::create(1024, compiler.pool);
	compiler.stack = Array<CompilerParameters*>::create(256, compiler.pool);
	compiler.componentsUsed = Array<AST_ComponentDefinition*>::create(256, compiler.pool);

	// Get all files in directory
	compiler.targetDirectory = String::create("C:\\wamp\\www\\nweb\\test\\wordpress\\wp-content\\themes\\twentysixteen\\fel\\");
	StringLinkedList files = Directory::getFilesRecursive(compiler.pool, compiler.targetDirectory);
	if (files.first == NULL)
	{
		compiler.targetDirectory = String::create("D:\\wamp\\www\\Nweb\\test\\wordpress\\wp-content\\themes\\twentysixteen\\fel\\");
		files = Directory::getFilesRecursive(compiler.pool, compiler.targetDirectory);
		if (files.first == NULL)
		{	
			compiler.targetDirectory = String::create("C:\\wamp\\www\\PersonalProjects\\fel\\test\\wordpress\\wp-content\\themes\\twentysixteen\\fel\\");
			files = Directory::getFilesRecursive(compiler.pool, compiler.targetDirectory);
			if (files.first == NULL)
			{	
				printf("Invalid directory supplied. Terminating program.\n");
				while(true) {}
				return -1;
			}
		}
	}

	if (compiler.targetDirectory.length == 0) 
	{
		printf("No directory supplied. Terminating program.\n");
		while(true) {}
		return -1;
	}

	// Setup default output directory
	if (compiler.outputDirectory.length == 0)
	{
		compiler.outputDirectory = compiler.targetDirectory.goUpDirectory();
	}
	assert(compiler.outputDirectory.length != 0);

	// Parse each file and add the AST to the compilers files
	for (StringLinkedListNode* node = files.first; node != NULL; node = node->next)
	{
		// Only parse files with the '.fel' extension
		if (node->string.fileExtension().cmp("fel"))
		{
			parse(&compiler, node->string);
		}
	}
	printf("Finished parsing.\n");

	// Run compile
	compile(&compiler);
	if (compiler.hasError)
	{
		printf("Fatal error compiling.\n");
	}
	else
	{
		print("Finished compiling successfully. Memory Used: %d, Transient Memory Used: %d (should be 0).\n", compiler.pool->used - compiler.poolTransient->size, compiler.poolTransient->used);
	}
	while(true) {}
	return 0;
}