// --------------------------------------------------------- // 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; }
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; }
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; }
/* 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; }
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(); }
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(§ionHeader, 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(); }
// 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_; }
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, ×tamps[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, ×tamps[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>(); } }
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; }