From 8bcb176a19297bca4f55f03a5244a507f8bf9174 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 12 Apr 2014 00:04:50 +0200 Subject: Lighting reads blocktypes only for blocks under heightmap. This should theoretically speed it up, since less data is copied back and forth. Also implemented a possibly more cache-friendly blocklight starter algorithm (PrepareBlockLight2()), is disabled by default, needs perf testing. --- src/LightingThread.cpp | 92 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 78 insertions(+), 14 deletions(-) (limited to 'src/LightingThread.cpp') diff --git a/src/LightingThread.cpp b/src/LightingThread.cpp index 302473d71..f23f0c5f4 100644 --- a/src/LightingThread.cpp +++ b/src/LightingThread.cpp @@ -27,7 +27,8 @@ class cReader : ROW * OutputRows = (ROW *)m_BlockTypes; int InputIdx = 0; int OutputIdx = m_ReadingChunkX + m_ReadingChunkZ * cChunkDef::Width * 3; - for (int y = 0; y < cChunkDef::Height; y++) + int MaxHeight = std::min(cChunkDef::Height, m_MaxHeight + 16); // Need 16 blocks above the highest + for (int y = 0; y < MaxHeight; y++) { for (int z = 0; z < cChunkDef::Width; z++) { @@ -43,6 +44,7 @@ class cReader : virtual void HeightMap(const cChunkDef::HeightMap * a_Heightmap) override { + // Copy the entire heightmap, distribute it into the 3x3 chunk blob: typedef struct {HEIGHTTYPE m_Row[16]; } ROW; ROW * InputRows = (ROW *)a_Heightmap; ROW * OutputRows = (ROW *)m_HeightMap; @@ -53,13 +55,32 @@ class cReader : OutputRows[OutputIdx] = InputRows[InputIdx++]; OutputIdx += 3; } // for z + + // Find the highest block in the entire chunk, use it as a base for m_MaxHeight: + HEIGHTTYPE MaxHeight = m_MaxHeight; + for (size_t i = 0; i < ARRAYCOUNT(*a_Heightmap); i++) + { + if ((*a_Heightmap)[i] > MaxHeight) + { + MaxHeight = (*a_Heightmap)[i]; + } + } + m_MaxHeight = MaxHeight; } public: int m_ReadingChunkX; // 0, 1 or 2; x-offset of the chunk we're reading from the BlockTypes start int m_ReadingChunkZ; // 0, 1 or 2; z-offset of the chunk we're reading from the BlockTypes start + HEIGHTTYPE m_MaxHeight; // Maximum value in this chunk's heightmap BLOCKTYPE * m_BlockTypes; // 3x3 chunks of block types, organized as a single XZY blob of data (instead of 3x3 XZY blobs) HEIGHTTYPE * m_HeightMap; // 3x3 chunks of height map, organized as a single XZY blob of data (instead of 3x3 XZY blobs) + + cReader(BLOCKTYPE * a_BlockTypes, HEIGHTTYPE * a_HeightMap) : + m_BlockTypes(a_BlockTypes), + m_HeightMap(a_HeightMap), + m_MaxHeight(0) + { + } } ; @@ -225,7 +246,7 @@ void cLightingThread::LightChunk(cLightingChunkStay & a_Item) // DEBUG: Save chunk data with highlighted seeds for visual inspection: cFile f4; if ( - f4.Open(Printf("Chunk_%d_%d_seeds.grab", a_Item.x, a_Item.z), cFile::fmWrite) + f4.Open(Printf("Chunk_%d_%d_seeds.grab", a_Item.m_ChunkX, a_Item.m_ChunkZ), cFile::fmWrite) ) { for (int z = 0; z < cChunkDef::Width * 3; z++) @@ -244,6 +265,7 @@ void cLightingThread::LightChunk(cLightingChunkStay & a_Item) f4.Write(Seeds, cChunkDef::Width * 3); } } + f4.Close(); } //*/ @@ -253,9 +275,9 @@ void cLightingThread::LightChunk(cLightingChunkStay & a_Item) // DEBUG: Save XY slices of the chunk data and lighting for visual inspection: cFile f1, f2, f3; if ( - f1.Open(Printf("Chunk_%d_%d_data.grab", a_Item.x, a_Item.z), cFile::fmWrite) && - f2.Open(Printf("Chunk_%d_%d_sky.grab", a_Item.x, a_Item.z), cFile::fmWrite) && - f3.Open(Printf("Chunk_%d_%d_glow.grab", a_Item.x, a_Item.z), cFile::fmWrite) + f1.Open(Printf("Chunk_%d_%d_data.grab", a_Item.m_ChunkX, a_Item.m_ChunkZ), cFile::fmWrite) && + f2.Open(Printf("Chunk_%d_%d_sky.grab", a_Item.m_ChunkX, a_Item.m_ChunkZ), cFile::fmWrite) && + f3.Open(Printf("Chunk_%d_%d_glow.grab", a_Item.m_ChunkX, a_Item.m_ChunkZ), cFile::fmWrite) ) { for (int z = 0; z < cChunkDef::Width * 3; z++) @@ -274,6 +296,9 @@ void cLightingThread::LightChunk(cLightingChunkStay & a_Item) f3.Write(BlockLight, cChunkDef::Width * 3); } } + f1.Close(); + f2.Close(); + f3.Close(); } //*/ @@ -293,11 +318,9 @@ void cLightingThread::LightChunk(cLightingChunkStay & a_Item) -bool cLightingThread::ReadChunks(int a_ChunkX, int a_ChunkZ) +void cLightingThread::ReadChunks(int a_ChunkX, int a_ChunkZ) { - cReader Reader; - Reader.m_BlockTypes = m_BlockTypes; - Reader.m_HeightMap = m_HeightMap; + cReader Reader(m_BlockTypes, m_HeightMap); for (int z = 0; z < 3; z++) { @@ -305,16 +328,13 @@ bool cLightingThread::ReadChunks(int a_ChunkX, int a_ChunkZ) for (int x = 0; x < 3; x++) { Reader.m_ReadingChunkX = x; - if (!m_World->GetChunkData(a_ChunkX + x - 1, a_ChunkZ + z - 1, Reader)) - { - return false; - } + VERIFY(m_World->GetChunkData(a_ChunkX + x - 1, a_ChunkZ + z - 1, Reader)); } // for z } // for x memset(m_BlockLight, 0, sizeof(m_BlockLight)); memset(m_SkyLight, 0, sizeof(m_SkyLight)); - return true; + m_MaxHeight = Reader.m_MaxHeight; } @@ -405,6 +425,50 @@ void cLightingThread::PrepareBlockLight(void) +void cLightingThread::PrepareBlockLight2(void) +{ + // Clear seeds: + memset(m_IsSeed1, 0, sizeof(m_IsSeed1)); + memset(m_IsSeed2, 0, sizeof(m_IsSeed2)); + m_NumSeeds = 0; + + // Add each emissive block into the seeds: + for (int y = 0; y < m_MaxHeight; y++) + { + int BaseY = y * BlocksPerYLayer; // Partial offset into m_BlockTypes for the Y coord + for (int z = 1; z < cChunkDef::Width * 3 - 1; z++) + { + int HBaseZ = z * cChunkDef::Width * 3; // Partial offset into m_Heightmap for the Z coord + int BaseZ = BaseY + HBaseZ; // Partial offset into m_BlockTypes for the Y and Z coords + for (int x = 1; x < cChunkDef::Width * 3 - 1; x++) + { + int idx = BaseZ + x; + if (y > m_HeightMap[HBaseZ + x]) + { + // We're above the heightmap, ignore the block + continue; + } + if (cBlockInfo::GetLightValue(m_BlockTypes[idx]) == 0) + { + // Not a light-emissive block + continue; + } + + // Add current block as a seed: + m_IsSeed1[idx] = true; + m_SeedIdx1[m_NumSeeds++] = idx; + + // Light it up: + m_BlockLight[idx] = cBlockInfo::GetLightValue(m_BlockTypes[idx]); + } + } + } +} + + + + + void cLightingThread::CalcLight(NIBBLETYPE * a_Light) { int NumSeeds2 = 0; -- cgit v1.2.3 From 5bc5272a4ea5fc5685626627dff62a697415826b Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 12 Apr 2014 00:24:35 +0200 Subject: Fixed member construction order. --- src/LightingThread.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/LightingThread.cpp') diff --git a/src/LightingThread.cpp b/src/LightingThread.cpp index f23f0c5f4..f22e3933b 100644 --- a/src/LightingThread.cpp +++ b/src/LightingThread.cpp @@ -76,9 +76,9 @@ public: HEIGHTTYPE * m_HeightMap; // 3x3 chunks of height map, organized as a single XZY blob of data (instead of 3x3 XZY blobs) cReader(BLOCKTYPE * a_BlockTypes, HEIGHTTYPE * a_HeightMap) : + m_MaxHeight(0), m_BlockTypes(a_BlockTypes), - m_HeightMap(a_HeightMap), - m_MaxHeight(0) + m_HeightMap(a_HeightMap) { } } ; -- cgit v1.2.3 From e40f9d6e5b93e840e3d67e79f5ba49da1fbb75f0 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 26 Apr 2014 10:50:23 -0700 Subject: Implemented Chunk Sparsing with segments --- src/LightingThread.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'src/LightingThread.cpp') diff --git a/src/LightingThread.cpp b/src/LightingThread.cpp index 302473d71..56d5dba22 100644 --- a/src/LightingThread.cpp +++ b/src/LightingThread.cpp @@ -18,20 +18,17 @@ class cReader : public cChunkDataCallback { - virtual void BlockTypes(const BLOCKTYPE * a_Type) override + virtual void ChunkBuffer(const cChunkBuffer & a_ChunkBuffer) override { - // ROW is a block of 16 Blocks, one whole row is copied at a time (hopefully the compiler will optimize that) - // C++ doesn't permit copying arrays, but arrays as a part of a struct is ok :) - typedef struct {BLOCKTYPE m_Row[16]; } ROW; - ROW * InputRows = (ROW *)a_Type; - ROW * OutputRows = (ROW *)m_BlockTypes; + BLOCKTYPE * OutputRows = m_BlockTypes; int InputIdx = 0; int OutputIdx = m_ReadingChunkX + m_ReadingChunkZ * cChunkDef::Width * 3; for (int y = 0; y < cChunkDef::Height; y++) { for (int z = 0; z < cChunkDef::Width; z++) { - OutputRows[OutputIdx] = InputRows[InputIdx++]; + a_ChunkBuffer.CopyBlocks(OutputRows + OutputIdx * 16, InputIdx * 16, 16); + InputIdx++; OutputIdx += 3; } // for z // Skip into the next y-level in the 3x3 chunk blob; each level has cChunkDef::Width * 9 rows -- cgit v1.2.3 From 56ad2c21242b35d6c1054f0526903760c3b4e666 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 9 May 2014 09:07:54 +0200 Subject: Lighting thread disabled its chunkstays before deleting them. --- src/LightingThread.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/LightingThread.cpp') diff --git a/src/LightingThread.cpp b/src/LightingThread.cpp index 5ba2940d2..5459644af 100644 --- a/src/LightingThread.cpp +++ b/src/LightingThread.cpp @@ -106,11 +106,13 @@ void cLightingThread::Stop(void) cCSLock Lock(m_CS); for (cChunkStays::iterator itr = m_PendingQueue.begin(), end = m_PendingQueue.end(); itr != end; ++itr) { + (*itr)->Disable(); delete *itr; } m_PendingQueue.clear(); for (cChunkStays::iterator itr = m_Queue.begin(), end = m_Queue.end(); itr != end; ++itr) { + (*itr)->Disable(); delete *itr; } m_Queue.clear(); -- cgit v1.2.3 From 024027db89ca833406147b79b7be74fc92906bbe Mon Sep 17 00:00:00 2001 From: Tycho Date: Wed, 21 May 2014 19:58:48 +0100 Subject: Renamed cChunkBuffer to cChunkData --- src/LightingThread.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/LightingThread.cpp') diff --git a/src/LightingThread.cpp b/src/LightingThread.cpp index f961e35c6..879252c34 100644 --- a/src/LightingThread.cpp +++ b/src/LightingThread.cpp @@ -18,7 +18,7 @@ class cReader : public cChunkDataCallback { - virtual void ChunkBuffer(const cChunkBuffer & a_ChunkBuffer) override + virtual void ChunkData(const cChunkData & a_ChunkBuffer) override { BLOCKTYPE * OutputRows = m_BlockTypes; int InputIdx = 0; -- cgit v1.2.3 From f7777e8c7559964f126a64af7673276e356dcedc Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 29 May 2014 18:25:08 +0200 Subject: Added comments, reformatted code. --- src/LightingThread.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/LightingThread.cpp') diff --git a/src/LightingThread.cpp b/src/LightingThread.cpp index 879252c34..dc19bf500 100644 --- a/src/LightingThread.cpp +++ b/src/LightingThread.cpp @@ -27,7 +27,7 @@ class cReader : { for (int z = 0; z < cChunkDef::Width; z++) { - a_ChunkBuffer.CopyBlocks(OutputRows + OutputIdx * 16, InputIdx * 16, 16); + a_ChunkBuffer.CopyBlockTypes(OutputRows + OutputIdx * 16, InputIdx * 16, 16); InputIdx++; OutputIdx += 3; } // for z -- cgit v1.2.3 From d6979ad95d2430e78c8e3ccef376704516814da0 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 16 Jun 2014 22:53:08 +0200 Subject: Fixed GCC compilation. --- src/LightingThread.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/LightingThread.cpp') diff --git a/src/LightingThread.cpp b/src/LightingThread.cpp index d3873ab3c..33bc08467 100644 --- a/src/LightingThread.cpp +++ b/src/LightingThread.cpp @@ -23,7 +23,7 @@ class cReader : BLOCKTYPE * OutputRows = m_BlockTypes; int InputIdx = 0; int OutputIdx = m_ReadingChunkX + m_ReadingChunkZ * cChunkDef::Width * 3; - int MaxHeight = std::min(cChunkDef::Height, m_MaxHeight + 16); // Need 16 blocks above the highest + int MaxHeight = std::min(+cChunkDef::Height, m_MaxHeight + 16); // Need 16 blocks above the highest for (int y = 0; y < MaxHeight; y++) { for (int z = 0; z < cChunkDef::Width; z++) -- cgit v1.2.3 From 993fd14ddfc881cf5be951df77da0338124d68cc Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 17 Jul 2014 16:33:09 +0200 Subject: Fixed basic whitespace problems. Indenting by spaces and alignment by spaces, as well as trailing whitespace on non-empty lines. --- src/LightingThread.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/LightingThread.cpp') diff --git a/src/LightingThread.cpp b/src/LightingThread.cpp index 33bc08467..403a3e097 100644 --- a/src/LightingThread.cpp +++ b/src/LightingThread.cpp @@ -495,7 +495,7 @@ void cLightingThread::CalcLight(NIBBLETYPE * a_Light) void cLightingThread::CalcLightStep( - NIBBLETYPE * a_Light, + NIBBLETYPE * a_Light, int a_NumSeedsIn, unsigned char * a_IsSeedIn, unsigned int * a_SeedIdxIn, int & a_NumSeedsOut, unsigned char * a_IsSeedOut, unsigned int * a_SeedIdxOut ) -- cgit v1.2.3 From 2423fbf2efa39e28cc348acc11b9269e573dcdef Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 17 Jul 2014 22:15:34 +0200 Subject: Normalized comments. This was mostly done automatically and then visually inspected for obvious errors. All //-style comments should have a 2-space separation from the code, and 1 space after the comment sign. --- src/LightingThread.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/LightingThread.cpp') diff --git a/src/LightingThread.cpp b/src/LightingThread.cpp index 403a3e097..3fbbee6b5 100644 --- a/src/LightingThread.cpp +++ b/src/LightingThread.cpp @@ -84,7 +84,7 @@ public: -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// // cLightingThread: cLightingThread::cLightingThread(void) : @@ -582,7 +582,7 @@ void cLightingThread::QueueChunkStay(cLightingChunkStay & a_ChunkStay) -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// // cLightingThread::cLightingChunkStay: cLightingThread::cLightingChunkStay::cLightingChunkStay(cLightingThread & a_LightingThread, int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * a_CallbackAfter) : -- cgit v1.2.3