mirror of
https://github.com/scratchfoundation/bgfx.git
synced 2024-12-02 20:36:50 -05:00
Added texture update batching. Added rect packing.
This commit is contained in:
parent
c3cef2bb5b
commit
435b83f1ac
8 changed files with 466 additions and 71 deletions
|
@ -11,9 +11,11 @@
|
||||||
#include "../common/dbg.h"
|
#include "../common/dbg.h"
|
||||||
#include "../common/math.h"
|
#include "../common/math.h"
|
||||||
#include "../common/processevents.h"
|
#include "../common/processevents.h"
|
||||||
|
#include "../common/packrect.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
struct PosColorVertex
|
struct PosColorVertex
|
||||||
{
|
{
|
||||||
|
@ -205,11 +207,7 @@ int _main_(int _argc, char** _argv)
|
||||||
bgfx::destroyFragmentShader(fsh);
|
bgfx::destroyFragmentShader(fsh);
|
||||||
|
|
||||||
uint32_t blockSide = 0;
|
uint32_t blockSide = 0;
|
||||||
uint32_t blockX = 0;
|
const uint32_t textureSide = 2048;
|
||||||
uint32_t blockY = 0;
|
|
||||||
const uint32_t blockWidth = 8;
|
|
||||||
const uint32_t blockHeight = 8;
|
|
||||||
const uint32_t textureSide = 256;
|
|
||||||
|
|
||||||
bgfx::TextureHandle textureCube =
|
bgfx::TextureHandle textureCube =
|
||||||
bgfx::createTextureCube(6
|
bgfx::createTextureCube(6
|
||||||
|
@ -219,15 +217,18 @@ int _main_(int _argc, char** _argv)
|
||||||
, BGFX_TEXTURE_MIN_POINT|BGFX_TEXTURE_MAG_POINT|BGFX_TEXTURE_MIP_POINT
|
, BGFX_TEXTURE_MIN_POINT|BGFX_TEXTURE_MAG_POINT|BGFX_TEXTURE_MIP_POINT
|
||||||
);
|
);
|
||||||
|
|
||||||
bgfx::TextureInfo ti;
|
|
||||||
bgfx::calcTextureSize(ti, blockWidth, blockHeight, 1, 1, bgfx::TextureFormat::BGRA8);
|
|
||||||
|
|
||||||
uint8_t rr = rand()%255;
|
uint8_t rr = rand()%255;
|
||||||
uint8_t gg = rand()%255;
|
uint8_t gg = rand()%255;
|
||||||
uint8_t bb = rand()%255;
|
uint8_t bb = rand()%255;
|
||||||
|
|
||||||
int64_t updateTime = 0;
|
int64_t updateTime = 0;
|
||||||
|
|
||||||
|
RectPackCubeT<256> cube(textureSide);
|
||||||
|
|
||||||
|
uint32_t hit = 0;
|
||||||
|
uint32_t miss = 0;
|
||||||
|
std::list<PackCube> quads;
|
||||||
|
|
||||||
while (!processEvents(width, height, debug, reset) )
|
while (!processEvents(width, height, debug, reset) )
|
||||||
{
|
{
|
||||||
// Set view 0 default viewport.
|
// Set view 0 default viewport.
|
||||||
|
@ -252,6 +253,20 @@ int _main_(int _argc, char** _argv)
|
||||||
|
|
||||||
if (now > updateTime)
|
if (now > updateTime)
|
||||||
{
|
{
|
||||||
|
PackCube face;
|
||||||
|
|
||||||
|
uint32_t bw = bx::uint16_max(1, rand()%(textureSide/4) );
|
||||||
|
uint32_t bh = bx::uint16_max(1, rand()%(textureSide/4) );
|
||||||
|
|
||||||
|
if (cube.find(bw, bh, face) )
|
||||||
|
{
|
||||||
|
quads.push_back(face);
|
||||||
|
|
||||||
|
++hit;
|
||||||
|
bgfx::TextureInfo ti;
|
||||||
|
const Pack2D& rect = face.m_rect;
|
||||||
|
bgfx::calcTextureSize(ti, rect.m_width, rect.m_height, 1, 1, bgfx::TextureFormat::BGRA8);
|
||||||
|
|
||||||
// updateTime = now + freq/10;
|
// updateTime = now + freq/10;
|
||||||
const bgfx::Memory* mem = bgfx::alloc(ti.storageSize);
|
const bgfx::Memory* mem = bgfx::alloc(ti.storageSize);
|
||||||
uint8_t* data = (uint8_t*)mem->data;
|
uint8_t* data = (uint8_t*)mem->data;
|
||||||
|
@ -264,31 +279,27 @@ int _main_(int _argc, char** _argv)
|
||||||
data += 4;
|
data += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
bgfx::updateTextureCube(textureCube, blockSide, 0, blockX, blockY, blockWidth, blockHeight, mem);
|
bgfx::updateTextureCube(textureCube, face.m_side, 0, rect.m_x, rect.m_y, rect.m_width, rect.m_height, mem);
|
||||||
|
|
||||||
blockX += 8;
|
|
||||||
if (blockX >= textureSide)
|
|
||||||
{
|
|
||||||
blockX = 0;
|
|
||||||
blockY += 8;
|
|
||||||
|
|
||||||
if (blockY >= textureSide)
|
|
||||||
{
|
|
||||||
rr = rand()%255;
|
rr = rand()%255;
|
||||||
gg = rand()%255;
|
gg = rand()%255;
|
||||||
bb = rand()%255;
|
bb = rand()%255;
|
||||||
|
}
|
||||||
blockY = 0;
|
else
|
||||||
++blockSide;
|
|
||||||
|
|
||||||
if (blockSide > 5)
|
|
||||||
{
|
{
|
||||||
blockSide = 0;
|
++miss;
|
||||||
}
|
|
||||||
|
for (uint32_t ii = 0, num = bx::uint32_min(10, (uint32_t)quads.size() ); ii < num; ++ii)
|
||||||
|
{
|
||||||
|
const PackCube& face = quads.front();
|
||||||
|
cube.clear(face);
|
||||||
|
quads.pop_front();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bgfx::dbgTextPrintf(0, 4, 0x0f, "hit: %d, miss %d", hit, miss);
|
||||||
|
|
||||||
float at[3] = { 0.0f, 0.0f, 0.0f };
|
float at[3] = { 0.0f, 0.0f, 0.0f };
|
||||||
float eye[3] = { 0.0f, 0.0f, -5.0f };
|
float eye[3] = { 0.0f, 0.0f, -5.0f };
|
||||||
|
|
||||||
|
|
177
examples/common/packrect.h
Normal file
177
examples/common/packrect.h
Normal file
|
@ -0,0 +1,177 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2011-2013 Branimir Karadzic. All rights reserved.
|
||||||
|
* License: http://www.opensource.org/licenses/BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __RECTPACK_H__
|
||||||
|
#define __RECTPACK_H__
|
||||||
|
|
||||||
|
#include <bx/uint32_t.h>
|
||||||
|
|
||||||
|
struct Pack2D
|
||||||
|
{
|
||||||
|
uint16_t m_x;
|
||||||
|
uint16_t m_y;
|
||||||
|
uint16_t m_width;
|
||||||
|
uint16_t m_height;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PackCube
|
||||||
|
{
|
||||||
|
Pack2D m_rect;
|
||||||
|
uint8_t m_side;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <uint16_t numBlocks>
|
||||||
|
class RectPackCubeT;
|
||||||
|
|
||||||
|
template <uint16_t numBlocks>
|
||||||
|
class RectPack2DT
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RectPack2DT(uint16_t _width, uint16_t _height)
|
||||||
|
{
|
||||||
|
reset(_width, _height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset(uint16_t _width, uint16_t _height)
|
||||||
|
{
|
||||||
|
m_bw = _width/64;
|
||||||
|
m_bh = _height/numBlocks;
|
||||||
|
memset(m_mem, 0xff, sizeof(m_mem) );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool find(uint16_t _width, uint16_t _height, Pack2D& _pack)
|
||||||
|
{
|
||||||
|
uint16_t width = bx::uint16_min(64, (_width + m_bw - 1) / m_bw);
|
||||||
|
uint16_t height = bx::uint16_min(numBlocks, (_height + m_bh - 1) / m_bh);
|
||||||
|
uint16_t numx = 64-width;
|
||||||
|
uint16_t numy = numBlocks-height;
|
||||||
|
|
||||||
|
const uint64_t scan = width == 64 ? UINT64_MAX : (UINT64_C(1)<<width)-1;
|
||||||
|
|
||||||
|
for (uint16_t starty = 0; starty <= numy; ++starty)
|
||||||
|
{
|
||||||
|
uint64_t mem = m_mem[starty];
|
||||||
|
uint16_t ntz = (uint16_t)bx::uint64_cnttz(mem);
|
||||||
|
uint64_t mask = scan<<ntz;
|
||||||
|
|
||||||
|
for (uint16_t xx = ntz; xx <= numx; ++xx, mask <<= 1)
|
||||||
|
{
|
||||||
|
uint16_t yy = starty;
|
||||||
|
if ( (mem&mask) == mask)
|
||||||
|
{
|
||||||
|
uint16_t endy = starty + height;
|
||||||
|
while (yy < endy && (m_mem[yy]&mask) == mask)
|
||||||
|
{
|
||||||
|
++yy;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (yy == endy)
|
||||||
|
{
|
||||||
|
uint64_t cmask = ~mask;
|
||||||
|
for (yy = starty; yy < endy; ++yy)
|
||||||
|
{
|
||||||
|
m_mem[yy] &= cmask;
|
||||||
|
}
|
||||||
|
|
||||||
|
_pack.m_x = xx * m_bw;
|
||||||
|
_pack.m_y = starty * m_bh;
|
||||||
|
_pack.m_width = width * m_bw;
|
||||||
|
_pack.m_height = height * m_bh;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear(const Pack2D& _pack)
|
||||||
|
{
|
||||||
|
uint16_t startx = bx::uint16_min(63, _pack.m_x / m_bw);
|
||||||
|
uint16_t starty = bx::uint16_min(numBlocks-1, _pack.m_y / m_bh);
|
||||||
|
uint16_t endx = bx::uint16_min(64, (_pack.m_width + m_bw - 1) / m_bw + startx);
|
||||||
|
uint16_t endy = bx::uint16_min(numBlocks, (_pack.m_height + m_bh - 1) / m_bh + starty);
|
||||||
|
uint16_t width = endx - startx;
|
||||||
|
|
||||||
|
const uint64_t mask = (width == 64 ? UINT64_MAX : (UINT64_C(1)<<width)-1 )<<startx;
|
||||||
|
|
||||||
|
for (uint16_t yy = starty; yy < endy; ++yy)
|
||||||
|
{
|
||||||
|
m_mem[yy] |= mask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class RectPackCubeT<numBlocks>;
|
||||||
|
|
||||||
|
RectPack2DT()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t m_mem[numBlocks];
|
||||||
|
uint16_t m_bw;
|
||||||
|
uint16_t m_bh;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <uint16_t numBlocks>
|
||||||
|
class RectPackCubeT
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RectPackCubeT(uint16_t _side)
|
||||||
|
{
|
||||||
|
reset(_side);
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset(uint16_t _side)
|
||||||
|
{
|
||||||
|
for (uint32_t ii = 0; ii < 6; ++ii)
|
||||||
|
{
|
||||||
|
m_mru[ii] = ii;
|
||||||
|
m_ra[ii].reset(_side, _side);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool find(uint16_t _width, uint16_t _height, PackCube& _pack)
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
for (uint32_t ii = 0; ii < 6; ++ii)
|
||||||
|
{
|
||||||
|
uint8_t side = m_mru[ii];
|
||||||
|
found = m_ra[side].find(_width, _height, _pack.m_rect);
|
||||||
|
|
||||||
|
if (found)
|
||||||
|
{
|
||||||
|
_pack.m_side = side;
|
||||||
|
m_mru[ii] = m_mru[0];
|
||||||
|
m_mru[0] = side;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear(const PackCube& _pack)
|
||||||
|
{
|
||||||
|
uint8_t side = _pack.m_side;
|
||||||
|
|
||||||
|
uint32_t ii = 0;
|
||||||
|
for (; ii < 6 && m_mru[ii] != side; ++ii);
|
||||||
|
|
||||||
|
m_mru[ii] = m_mru[0];
|
||||||
|
m_mru[0] = side;
|
||||||
|
|
||||||
|
m_ra[side].clear(_pack.m_rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
RectPackCubeT();
|
||||||
|
|
||||||
|
RectPack2DT<numBlocks> m_ra[6];
|
||||||
|
uint8_t m_mru[6];
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __RECTPACK_H__
|
153
src/bgfx_p.h
153
src/bgfx_p.h
|
@ -194,16 +194,6 @@ namespace bgfx
|
||||||
const char* getAttribName(Attrib::Enum _attr);
|
const char* getAttribName(Attrib::Enum _attr);
|
||||||
bool renderFrame();
|
bool renderFrame();
|
||||||
|
|
||||||
inline uint16_t uint16_min(uint16_t _a, uint16_t _b)
|
|
||||||
{
|
|
||||||
return _a > _b ? _b : _a;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint16_t uint16_max(uint16_t _a, uint16_t _b)
|
|
||||||
{
|
|
||||||
return _a < _b ? _b : _a;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint32_t gcd(uint32_t _a, uint32_t _b)
|
inline uint32_t gcd(uint32_t _a, uint32_t _b)
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
|
@ -374,6 +364,49 @@ namespace bgfx
|
||||||
bool m_init;
|
bool m_init;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <uint32_t maxKeys>
|
||||||
|
struct UpdateBatchT
|
||||||
|
{
|
||||||
|
UpdateBatchT()
|
||||||
|
: m_num(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void add(uint32_t _key, uint32_t _value)
|
||||||
|
{
|
||||||
|
uint32_t num = m_num++;
|
||||||
|
m_keys[num] = _key;
|
||||||
|
m_values[num] = _value;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool sort()
|
||||||
|
{
|
||||||
|
if (0 < m_num)
|
||||||
|
{
|
||||||
|
uint32_t* tempKeys = (uint32_t*)alloca(sizeof(m_keys) );
|
||||||
|
uint32_t* tempValues = (uint32_t*)alloca(sizeof(m_values) );
|
||||||
|
bx::radixSort32(m_keys, tempKeys, m_values, tempValues, m_num);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isFull() const
|
||||||
|
{
|
||||||
|
return m_num >= maxKeys;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset()
|
||||||
|
{
|
||||||
|
m_num = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t m_num;
|
||||||
|
uint32_t m_keys[maxKeys];
|
||||||
|
uint32_t m_values[maxKeys];
|
||||||
|
};
|
||||||
|
|
||||||
struct ClearQuad
|
struct ClearQuad
|
||||||
{
|
{
|
||||||
void init();
|
void init();
|
||||||
|
@ -480,6 +513,12 @@ namespace bgfx
|
||||||
read(reinterpret_cast<uint8_t*>(&_in), sizeof(Type) );
|
read(reinterpret_cast<uint8_t*>(&_in), sizeof(Type) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void skip(uint32_t _size)
|
||||||
|
{
|
||||||
|
BX_CHECK(m_pos < m_size, "");
|
||||||
|
m_pos += _size;
|
||||||
|
}
|
||||||
|
|
||||||
void reset()
|
void reset()
|
||||||
{
|
{
|
||||||
m_pos = 0;
|
m_pos = 0;
|
||||||
|
@ -2369,7 +2408,9 @@ namespace bgfx
|
||||||
void rendererCreateProgram(ProgramHandle _handle, VertexShaderHandle _vsh, FragmentShaderHandle _fsh);
|
void rendererCreateProgram(ProgramHandle _handle, VertexShaderHandle _vsh, FragmentShaderHandle _fsh);
|
||||||
void rendererDestroyProgram(FragmentShaderHandle _handle);
|
void rendererDestroyProgram(FragmentShaderHandle _handle);
|
||||||
void rendererCreateTexture(TextureHandle _handle, Memory* _mem, uint32_t _flags);
|
void rendererCreateTexture(TextureHandle _handle, Memory* _mem, uint32_t _flags);
|
||||||
|
void rendererUpdateTextureBegin(TextureHandle _handle, uint8_t _side, uint8_t _mip);
|
||||||
void rendererUpdateTexture(TextureHandle _handle, uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, const Memory* _mem);
|
void rendererUpdateTexture(TextureHandle _handle, uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, const Memory* _mem);
|
||||||
|
void rendererUpdateTextureEnd();
|
||||||
void rendererDestroyTexture(TextureHandle _handle);
|
void rendererDestroyTexture(TextureHandle _handle);
|
||||||
void rendererCreateRenderTarget(RenderTargetHandle _handle, uint16_t _width, uint16_t _height, uint32_t _flags, uint32_t _textureFlags);
|
void rendererCreateRenderTarget(RenderTargetHandle _handle, uint16_t _width, uint16_t _height, uint32_t _flags, uint32_t _textureFlags);
|
||||||
void rendererDestroyRenderTarget(RenderTargetHandle _handle);
|
void rendererDestroyRenderTarget(RenderTargetHandle _handle);
|
||||||
|
@ -2403,6 +2444,66 @@ namespace bgfx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void flushTextureUpdateBatch(CommandBuffer& _cmdbuf)
|
||||||
|
{
|
||||||
|
if (m_textureUpdateBatch.sort() )
|
||||||
|
{
|
||||||
|
const uint32_t pos = _cmdbuf.m_pos;
|
||||||
|
|
||||||
|
uint32_t currentKey = UINT32_MAX;
|
||||||
|
|
||||||
|
for (uint32_t ii = 0, num = m_textureUpdateBatch.m_num; ii < num; ++ii)
|
||||||
|
{
|
||||||
|
_cmdbuf.m_pos = m_textureUpdateBatch.m_values[ii];
|
||||||
|
|
||||||
|
TextureHandle handle;
|
||||||
|
_cmdbuf.read(handle);
|
||||||
|
|
||||||
|
uint8_t side;
|
||||||
|
_cmdbuf.read(side);
|
||||||
|
|
||||||
|
uint8_t mip;
|
||||||
|
_cmdbuf.read(mip);
|
||||||
|
|
||||||
|
Rect rect;
|
||||||
|
_cmdbuf.read(rect);
|
||||||
|
|
||||||
|
uint16_t zz;
|
||||||
|
_cmdbuf.read(zz);
|
||||||
|
|
||||||
|
uint16_t depth;
|
||||||
|
_cmdbuf.read(depth);
|
||||||
|
|
||||||
|
Memory* mem;
|
||||||
|
_cmdbuf.read(mem);
|
||||||
|
|
||||||
|
uint32_t key = m_textureUpdateBatch.m_keys[ii];
|
||||||
|
if (key != currentKey)
|
||||||
|
{
|
||||||
|
if (currentKey != UINT32_MAX)
|
||||||
|
{
|
||||||
|
rendererUpdateTextureEnd();
|
||||||
|
}
|
||||||
|
currentKey = key;
|
||||||
|
rendererUpdateTextureBegin(handle, side, mip);
|
||||||
|
}
|
||||||
|
|
||||||
|
rendererUpdateTexture(handle, side, mip, rect, zz, depth, mem);
|
||||||
|
|
||||||
|
release(mem);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentKey != UINT32_MAX)
|
||||||
|
{
|
||||||
|
rendererUpdateTextureEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_textureUpdateBatch.reset();
|
||||||
|
|
||||||
|
_cmdbuf.m_pos = pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void rendererExecCommands(CommandBuffer& _cmdbuf)
|
void rendererExecCommands(CommandBuffer& _cmdbuf)
|
||||||
{
|
{
|
||||||
_cmdbuf.reset();
|
_cmdbuf.reset();
|
||||||
|
@ -2677,6 +2778,13 @@ namespace bgfx
|
||||||
|
|
||||||
case CommandBuffer::UpdateTexture:
|
case CommandBuffer::UpdateTexture:
|
||||||
{
|
{
|
||||||
|
if (m_textureUpdateBatch.isFull() )
|
||||||
|
{
|
||||||
|
flushTextureUpdateBatch(_cmdbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t value = _cmdbuf.m_pos;
|
||||||
|
|
||||||
TextureHandle handle;
|
TextureHandle handle;
|
||||||
_cmdbuf.read(handle);
|
_cmdbuf.read(handle);
|
||||||
|
|
||||||
|
@ -2686,21 +2794,14 @@ namespace bgfx
|
||||||
uint8_t mip;
|
uint8_t mip;
|
||||||
_cmdbuf.read(mip);
|
_cmdbuf.read(mip);
|
||||||
|
|
||||||
Rect rect;
|
_cmdbuf.skip(sizeof(Rect)+sizeof(uint16_t)+sizeof(uint16_t)+sizeof(Memory*) );
|
||||||
_cmdbuf.read(rect);
|
|
||||||
|
|
||||||
uint16_t zz;
|
uint32_t key = (handle.idx<<16)
|
||||||
_cmdbuf.read(zz);
|
| (side<<8)
|
||||||
|
| mip
|
||||||
|
;
|
||||||
|
|
||||||
uint16_t depth;
|
m_textureUpdateBatch.add(key, value);
|
||||||
_cmdbuf.read(depth);
|
|
||||||
|
|
||||||
Memory* mem;
|
|
||||||
_cmdbuf.read(mem);
|
|
||||||
|
|
||||||
rendererUpdateTexture(handle, side, mip, rect, zz, depth, mem);
|
|
||||||
|
|
||||||
release(mem);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -2794,6 +2895,8 @@ namespace bgfx
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while (!end);
|
} while (!end);
|
||||||
|
|
||||||
|
flushTextureUpdateBatch(_cmdbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rendererSubmit();
|
void rendererSubmit();
|
||||||
|
@ -2915,6 +3018,10 @@ namespace bgfx
|
||||||
|
|
||||||
bool m_rendererInitialized;
|
bool m_rendererInitialized;
|
||||||
bool m_exit;
|
bool m_exit;
|
||||||
|
|
||||||
|
BX_CACHE_LINE_ALIGN_MARKER();
|
||||||
|
typedef UpdateBatchT<256> TextureUpdateBatch;
|
||||||
|
TextureUpdateBatch m_textureUpdateBatch;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace bgfx
|
} // namespace bgfx
|
||||||
|
|
|
@ -2011,11 +2011,19 @@ namespace bgfx
|
||||||
s_renderCtx.m_textures[_handle.idx].create(_mem, _flags);
|
s_renderCtx.m_textures[_handle.idx].create(_mem, _flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Context::rendererUpdateTextureBegin(TextureHandle /*_handle*/, uint8_t /*_side*/, uint8_t /*_mip*/)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void Context::rendererUpdateTexture(TextureHandle _handle, uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, const Memory* _mem)
|
void Context::rendererUpdateTexture(TextureHandle _handle, uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, const Memory* _mem)
|
||||||
{
|
{
|
||||||
s_renderCtx.m_textures[_handle.idx].update(_side, _mip, _rect, _z, _depth, _mem);
|
s_renderCtx.m_textures[_handle.idx].update(_side, _mip, _rect, _z, _depth, _mem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Context::rendererUpdateTextureEnd()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void Context::rendererDestroyTexture(TextureHandle _handle)
|
void Context::rendererDestroyTexture(TextureHandle _handle)
|
||||||
{
|
{
|
||||||
s_renderCtx.m_textures[_handle.idx].destroy();
|
s_renderCtx.m_textures[_handle.idx].destroy();
|
||||||
|
|
|
@ -881,6 +881,12 @@ namespace bgfx
|
||||||
UniformRegistry m_uniformReg;
|
UniformRegistry m_uniformReg;
|
||||||
void* m_uniforms[BGFX_CONFIG_MAX_UNIFORMS];
|
void* m_uniforms[BGFX_CONFIG_MAX_UNIFORMS];
|
||||||
|
|
||||||
|
Texture* m_updateTexture;
|
||||||
|
uint8_t* m_updateTextureBits;
|
||||||
|
uint32_t m_updateTexturePitch;
|
||||||
|
uint8_t m_updateTextureSide;
|
||||||
|
uint8_t m_updateTextureMip;
|
||||||
|
|
||||||
TextVideoMem m_textVideoMem;
|
TextVideoMem m_textVideoMem;
|
||||||
RenderTargetHandle m_rt;
|
RenderTargetHandle m_rt;
|
||||||
bool m_rtMsaa;
|
bool m_rtMsaa;
|
||||||
|
@ -1346,6 +1352,42 @@ namespace bgfx
|
||||||
BX_CHECK(false, "You should not be here.");
|
BX_CHECK(false, "You should not be here.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Texture::dirty(uint8_t _side, const Rect& _rect)
|
||||||
|
{
|
||||||
|
switch (m_type)
|
||||||
|
{
|
||||||
|
case Texture2D:
|
||||||
|
{
|
||||||
|
RECT rect;
|
||||||
|
rect.left = _rect.m_x;
|
||||||
|
rect.top = _rect.m_y;
|
||||||
|
rect.right = rect.left + _rect.m_width;
|
||||||
|
rect.bottom = rect.top + _rect.m_height;
|
||||||
|
DX_CHECK(m_texture2d->AddDirtyRect(&rect) );
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
case Texture3D:
|
||||||
|
{
|
||||||
|
// DX_CHECK(m_texture3d->AddDirtyRect(_box) );
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
case TextureCube:
|
||||||
|
{
|
||||||
|
RECT rect;
|
||||||
|
rect.left = _rect.m_x;
|
||||||
|
rect.top = _rect.m_y;
|
||||||
|
rect.right = rect.left + _rect.m_width;
|
||||||
|
rect.bottom = rect.top + _rect.m_height;
|
||||||
|
DX_CHECK(m_textureCube->AddDirtyRect(D3DCUBEMAP_FACES(_side), &rect) );
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BX_CHECK(false, "You should not be here.");
|
||||||
|
}
|
||||||
|
|
||||||
void Texture::create(const Memory* _mem, uint32_t _flags)
|
void Texture::create(const Memory* _mem, uint32_t _flags)
|
||||||
{
|
{
|
||||||
m_tau = s_textureAddress[(_flags&BGFX_TEXTURE_U_MASK)>>BGFX_TEXTURE_U_SHIFT];
|
m_tau = s_textureAddress[(_flags&BGFX_TEXTURE_U_MASK)>>BGFX_TEXTURE_U_SHIFT];
|
||||||
|
@ -1548,22 +1590,41 @@ namespace bgfx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Texture::updateBegin(uint8_t _side, uint8_t _mip)
|
||||||
|
{
|
||||||
|
uint32_t slicePitch;
|
||||||
|
s_renderCtx.m_updateTextureSide = _side;
|
||||||
|
s_renderCtx.m_updateTextureMip = _mip;
|
||||||
|
s_renderCtx.m_updateTextureBits = lock(_side, _mip, s_renderCtx.m_updateTexturePitch, slicePitch);
|
||||||
|
}
|
||||||
|
|
||||||
void Texture::update(uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, const Memory* _mem)
|
void Texture::update(uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, const Memory* _mem)
|
||||||
{
|
{
|
||||||
uint32_t pitch;
|
uint32_t bpp = s_textureFormat[m_format].m_bpp;
|
||||||
uint32_t slicePitch;
|
uint32_t srcpitch = _rect.m_width*bpp/8;
|
||||||
uint8_t* bits = lock(_side, _mip, pitch, slicePitch, &_rect);
|
uint32_t dstpitch = s_renderCtx.m_updateTexturePitch;
|
||||||
|
uint8_t* bits = s_renderCtx.m_updateTextureBits + _rect.m_y*dstpitch + _rect.m_x*bpp/8;
|
||||||
|
|
||||||
uint32_t srcpitch = _rect.m_width*s_textureFormat[m_format].m_bpp/8;
|
if (srcpitch == dstpitch)
|
||||||
uint32_t dstpitch = pitch;
|
{
|
||||||
|
memcpy(bits, _mem->data, srcpitch*_rect.m_height);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
for (uint32_t yy = 0, height = _rect.m_height; yy < height; ++yy)
|
for (uint32_t yy = 0, height = _rect.m_height; yy < height; ++yy)
|
||||||
{
|
{
|
||||||
uint8_t* src = &_mem->data[yy*srcpitch];
|
uint8_t* src = &_mem->data[yy*srcpitch];
|
||||||
uint8_t* dst = &bits[yy*dstpitch];
|
uint8_t* dst = &bits[yy*dstpitch];
|
||||||
memcpy(dst, src, srcpitch);
|
memcpy(dst, src, srcpitch);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unlock(_side, _mip);
|
dirty(_side, _rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Texture::updateEnd()
|
||||||
|
{
|
||||||
|
unlock(s_renderCtx.m_updateTextureSide, s_renderCtx.m_updateTextureMip);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Texture::commit(uint8_t _stage)
|
void Texture::commit(uint8_t _stage)
|
||||||
|
@ -1990,9 +2051,21 @@ namespace bgfx
|
||||||
s_renderCtx.m_textures[_handle.idx].create(_mem, _flags);
|
s_renderCtx.m_textures[_handle.idx].create(_mem, _flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Context::rendererUpdateTextureBegin(TextureHandle _handle, uint8_t _side, uint8_t _mip)
|
||||||
|
{
|
||||||
|
s_renderCtx.m_updateTexture = &s_renderCtx.m_textures[_handle.idx];
|
||||||
|
s_renderCtx.m_updateTexture->updateBegin(_side, _mip);
|
||||||
|
}
|
||||||
|
|
||||||
void Context::rendererUpdateTexture(TextureHandle _handle, uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, const Memory* _mem)
|
void Context::rendererUpdateTexture(TextureHandle _handle, uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, const Memory* _mem)
|
||||||
{
|
{
|
||||||
s_renderCtx.m_textures[_handle.idx].update(_side, _mip, _rect, _z, _depth, _mem);
|
s_renderCtx.m_updateTexture->update(_side, _mip, _rect, _z, _depth, _mem);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Context::rendererUpdateTextureEnd()
|
||||||
|
{
|
||||||
|
s_renderCtx.m_updateTexture->updateEnd();
|
||||||
|
s_renderCtx.m_updateTexture = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Context::rendererDestroyTexture(TextureHandle _handle)
|
void Context::rendererDestroyTexture(TextureHandle _handle)
|
||||||
|
|
|
@ -320,6 +320,7 @@ namespace bgfx
|
||||||
|
|
||||||
uint8_t* lock(uint8_t _side, uint8_t _lod, uint32_t& _pitch, uint32_t& _slicePitch, const Rect* _rect = NULL);
|
uint8_t* lock(uint8_t _side, uint8_t _lod, uint32_t& _pitch, uint32_t& _slicePitch, const Rect* _rect = NULL);
|
||||||
void unlock(uint8_t _side, uint8_t _lod);
|
void unlock(uint8_t _side, uint8_t _lod);
|
||||||
|
void dirty(uint8_t _side, const Rect& _rect);
|
||||||
|
|
||||||
void create(const Memory* _mem, uint32_t _flags);
|
void create(const Memory* _mem, uint32_t _flags);
|
||||||
|
|
||||||
|
@ -328,7 +329,9 @@ namespace bgfx
|
||||||
DX_RELEASE(m_ptr, 0);
|
DX_RELEASE(m_ptr, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void updateBegin(uint8_t _side, uint8_t _mip);
|
||||||
void update(uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, const Memory* _mem);
|
void update(uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, const Memory* _mem);
|
||||||
|
void updateEnd();
|
||||||
void commit(uint8_t _stage);
|
void commit(uint8_t _stage);
|
||||||
|
|
||||||
union
|
union
|
||||||
|
|
|
@ -2187,11 +2187,19 @@ namespace bgfx
|
||||||
s_renderCtx.m_textures[_handle.idx].create(_mem, _flags);
|
s_renderCtx.m_textures[_handle.idx].create(_mem, _flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Context::rendererUpdateTextureBegin(TextureHandle _handle, uint8_t _side, uint8_t _mip)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void Context::rendererUpdateTexture(TextureHandle _handle, uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, const Memory* _mem)
|
void Context::rendererUpdateTexture(TextureHandle _handle, uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, const Memory* _mem)
|
||||||
{
|
{
|
||||||
s_renderCtx.m_textures[_handle.idx].update(_side, _mip, _rect, _z, _depth, _mem);
|
s_renderCtx.m_textures[_handle.idx].update(_side, _mip, _rect, _z, _depth, _mem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Context::rendererUpdateTextureEnd()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void Context::rendererDestroyTexture(TextureHandle _handle)
|
void Context::rendererDestroyTexture(TextureHandle _handle)
|
||||||
{
|
{
|
||||||
s_renderCtx.m_textures[_handle.idx].destroy();
|
s_renderCtx.m_textures[_handle.idx].destroy();
|
||||||
|
|
|
@ -124,10 +124,18 @@ namespace bgfx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Context::rendererUpdateTextureBegin(TextureHandle /*_handle*/, uint8_t /*_side*/, uint8_t /*_mip*/)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void Context::rendererUpdateTexture(TextureHandle /*_handle*/, uint8_t /*_side*/, uint8_t /*_mip*/, const Rect& /*_rect*/, uint16_t /*_z*/, uint16_t /*_depth*/, const Memory* /*_mem*/)
|
void Context::rendererUpdateTexture(TextureHandle /*_handle*/, uint8_t /*_side*/, uint8_t /*_mip*/, const Rect& /*_rect*/, uint16_t /*_z*/, uint16_t /*_depth*/, const Memory* /*_mem*/)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Context::rendererUpdateTextureEnd()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void Context::rendererDestroyTexture(TextureHandle /*_handle*/)
|
void Context::rendererDestroyTexture(TextureHandle /*_handle*/)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue