OpenGL storage reuse with glBufferSubData

This commit is contained in:
Jack Andersen 2016-01-07 14:04:37 -10:00
parent 45fb66540f
commit 5485e7d2b1
2 changed files with 55 additions and 57 deletions

View File

@ -66,16 +66,20 @@ class GLGraphicsBufferD : public IGraphicsBufferD
{ {
friend class GLDataFactory; friend class GLDataFactory;
friend struct GLCommandQueue; friend struct GLCommandQueue;
struct GLCommandQueue* m_q;
GLuint m_bufs[3]; GLuint m_bufs[3];
GLenum m_target; GLenum m_target;
std::unique_ptr<uint8_t[]> m_cpuBuf; std::unique_ptr<uint8_t[]> m_cpuBuf;
size_t m_cpuSz = 0; size_t m_cpuSz = 0;
int m_validMask = 0; int m_validMask = 0;
GLGraphicsBufferD(GLCommandQueue* q, BufferUse use, size_t sz) GLGraphicsBufferD(BufferUse use, size_t sz)
: m_q(q), m_target(USE_TABLE[int(use)]), m_cpuBuf(new uint8_t[sz]), m_cpuSz(sz) : m_target(USE_TABLE[int(use)]), m_cpuBuf(new uint8_t[sz]), m_cpuSz(sz)
{ {
glGenBuffers(3, m_bufs); glGenBuffers(3, m_bufs);
for (int i=0 ; i<3 ; ++i)
{
glBindBuffer(m_target, m_bufs[i]);
glBufferData(m_target, m_cpuSz, nullptr, GL_STREAM_DRAW);
}
} }
void update(int b); void update(int b);
public: public:
@ -193,7 +197,6 @@ class GLTextureD : public ITextureD
{ {
friend class GLDataFactory; friend class GLDataFactory;
friend struct GLCommandQueue; friend struct GLCommandQueue;
struct GLCommandQueue* m_q;
GLuint m_texs[3]; GLuint m_texs[3];
std::unique_ptr<uint8_t[]> m_cpuBuf; std::unique_ptr<uint8_t[]> m_cpuBuf;
size_t m_cpuSz = 0; size_t m_cpuSz = 0;
@ -201,7 +204,7 @@ class GLTextureD : public ITextureD
size_t m_width = 0; size_t m_width = 0;
size_t m_height = 0; size_t m_height = 0;
int m_validMask = 0; int m_validMask = 0;
GLTextureD(GLCommandQueue* q, size_t width, size_t height, TextureFormat fmt); GLTextureD(size_t width, size_t height, TextureFormat fmt);
void update(int b); void update(int b);
public: public:
~GLTextureD(); ~GLTextureD();
@ -223,6 +226,7 @@ class GLTextureR : public ITextureR
size_t m_width = 0; size_t m_width = 0;
size_t m_height = 0; size_t m_height = 0;
size_t m_samples = 0; size_t m_samples = 0;
GLenum m_target;
GLTextureR(GLCommandQueue* q, size_t width, size_t height, size_t samples); GLTextureR(GLCommandQueue* q, size_t width, size_t height, size_t samples);
public: public:
~GLTextureR(); ~GLTextureR();
@ -230,17 +234,28 @@ public:
void bind(size_t idx) const void bind(size_t idx) const
{ {
glActiveTexture(GL_TEXTURE0 + idx); glActiveTexture(GL_TEXTURE0 + idx);
glBindTexture(GL_TEXTURE_2D, m_texs[0]); glBindTexture(m_target, m_texs[0]);
} }
void resize(size_t width, size_t height) void resize(size_t width, size_t height)
{ {
m_width = width; m_width = width;
m_height = height; m_height = height;
glBindTexture(GL_TEXTURE_2D, m_texs[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); if (m_samples > 1)
glBindTexture(GL_TEXTURE_2D, m_texs[1]); {
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr); glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_texs[0]);
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, m_samples, GL_RGBA, width, height, GL_FALSE);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_texs[1]);
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, m_samples, GL_DEPTH_COMPONENT24, width, height, GL_FALSE);
}
else
{
glBindTexture(GL_TEXTURE_2D, m_texs[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
glBindTexture(GL_TEXTURE_2D, m_texs[1]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr);
}
} }
}; };
@ -1142,7 +1157,7 @@ void GLGraphicsBufferD::update(int b)
if ((slot & m_validMask) == 0) if ((slot & m_validMask) == 0)
{ {
glBindBuffer(m_target, m_bufs[b]); glBindBuffer(m_target, m_bufs[b]);
glBufferData(m_target, m_cpuSz, m_cpuBuf.get(), GL_DYNAMIC_DRAW); glBufferSubData(m_target, 0, m_cpuSz, m_cpuBuf.get());
m_validMask |= slot; m_validMask |= slot;
} }
} }
@ -1173,18 +1188,17 @@ void GLGraphicsBufferD::bindUniform(size_t idx, int b)
IGraphicsBufferD* IGraphicsBufferD*
GLDataFactory::newDynamicBuffer(BufferUse use, size_t stride, size_t count) GLDataFactory::newDynamicBuffer(BufferUse use, size_t stride, size_t count)
{ {
GLCommandQueue* q = static_cast<GLCommandQueue*>(m_parent->getCommandQueue()); GLGraphicsBufferD* retval = new GLGraphicsBufferD(use, stride * count);
GLGraphicsBufferD* retval = new GLGraphicsBufferD(q, use, stride * count);
if (!m_deferredData.get()) if (!m_deferredData.get())
m_deferredData.reset(new struct GLData()); m_deferredData.reset(new struct GLData());
m_deferredData->m_DBufs.emplace_back(retval); m_deferredData->m_DBufs.emplace_back(retval);
return retval; return retval;
} }
GLTextureD::GLTextureD(GLCommandQueue* q, size_t width, size_t height, TextureFormat fmt) GLTextureD::GLTextureD(size_t width, size_t height, TextureFormat fmt)
: m_q(q), m_width(width), m_height(height) : m_width(width), m_height(height)
{ {
int pxPitch; int pxPitch = 4;
switch (fmt) switch (fmt)
{ {
case TextureFormat::RGBA8: case TextureFormat::RGBA8:
@ -1250,8 +1264,7 @@ void GLTextureD::bind(size_t idx, int b)
ITextureD* ITextureD*
GLDataFactory::newDynamicTexture(size_t width, size_t height, TextureFormat fmt) GLDataFactory::newDynamicTexture(size_t width, size_t height, TextureFormat fmt)
{ {
GLCommandQueue* q = static_cast<GLCommandQueue*>(m_parent->getCommandQueue()); GLTextureD* retval = new GLTextureD(width, height, fmt);
GLTextureD* retval = new GLTextureD(q, width, height, fmt);
if (!m_deferredData.get()) if (!m_deferredData.get())
m_deferredData.reset(new struct GLData()); m_deferredData.reset(new struct GLData());
m_deferredData->m_DTexs.emplace_back(retval); m_deferredData->m_DTexs.emplace_back(retval);
@ -1262,10 +1275,22 @@ GLTextureR::GLTextureR(GLCommandQueue* q, size_t width, size_t height, size_t sa
: m_q(q), m_width(width), m_height(height), m_samples(samples) : m_q(q), m_width(width), m_height(height), m_samples(samples)
{ {
glGenTextures(2, m_texs); glGenTextures(2, m_texs);
glBindTexture(GL_TEXTURE_2D, m_texs[0]); if (samples > 1)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); {
glBindTexture(GL_TEXTURE_2D, m_texs[1]); m_target = GL_TEXTURE_2D_MULTISAMPLE;
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr); glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_texs[0]);
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, GL_RGBA, width, height, GL_FALSE);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_texs[1]);
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, GL_DEPTH_COMPONENT24, width, height, GL_FALSE);
}
else
{
m_target = GL_TEXTURE_2D;
glBindTexture(GL_TEXTURE_2D, m_texs[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
glBindTexture(GL_TEXTURE_2D, m_texs[1]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr);
}
m_q->addFBO(this); m_q->addFBO(this);
} }
GLTextureR::~GLTextureR() {glDeleteTextures(2, m_texs); m_q->delFBO(this);} GLTextureR::~GLTextureR() {glDeleteTextures(2, m_texs); m_q->delFBO(this);}

View File

@ -16,7 +16,6 @@ namespace boo {class ApplicationCocoa;}
{ {
boo::ApplicationCocoa* m_app; boo::ApplicationCocoa* m_app;
@public @public
NSPanel* aboutPanel;
} }
- (id)initWithApp:(boo::ApplicationCocoa*)app; - (id)initWithApp:(boo::ApplicationCocoa*)app;
@end @end
@ -69,36 +68,20 @@ public:
[[NSApplication sharedApplication] setDelegate:m_appDelegate]; [[NSApplication sharedApplication] setDelegate:m_appDelegate];
/* App menu */ /* App menu */
NSMenu* appMenu = [[NSMenu alloc] initWithTitle:@"main"]; NSMenu* rootMenu = [[NSMenu alloc] initWithTitle:@"main"];
NSMenu* rwkMenu = [[NSMenu alloc] initWithTitle:[NSString stringWithUTF8String:m_friendlyName.c_str()]]; NSMenu* appMenu = [[NSMenu alloc] initWithTitle:[NSString stringWithUTF8String:m_friendlyName.c_str()]];
[rwkMenu addItemWithTitle:[NSString stringWithFormat:@"About %s", m_friendlyName.c_str()] NSMenuItem* fsItem = [appMenu addItemWithTitle:@"Toggle Full Screen"
action:@selector(aboutApp:)
keyEquivalent:@""];
NSMenuItem* fsItem = [rwkMenu addItemWithTitle:@"Toggle Full Screen"
action:@selector(toggleFs:) action:@selector(toggleFs:)
keyEquivalent:@"f"]; keyEquivalent:@"f"];
[fsItem setKeyEquivalentModifierMask:NSCommandKeyMask]; [fsItem setKeyEquivalentModifierMask:NSCommandKeyMask];
[rwkMenu addItem:[NSMenuItem separatorItem]]; [appMenu addItem:[NSMenuItem separatorItem]];
NSMenuItem* quit_item = [rwkMenu addItemWithTitle:[NSString stringWithFormat:@"Quit %s", m_friendlyName.c_str()] NSMenuItem* quit_item = [appMenu addItemWithTitle:[NSString stringWithFormat:@"Quit %s", m_friendlyName.c_str()]
action:@selector(quitApp:) action:@selector(quitApp:)
keyEquivalent:@"q"]; keyEquivalent:@"q"];
[quit_item setKeyEquivalentModifierMask:NSCommandKeyMask]; [quit_item setKeyEquivalentModifierMask:NSCommandKeyMask];
[[appMenu addItemWithTitle:[NSString stringWithUTF8String:m_friendlyName.c_str()] [[rootMenu addItemWithTitle:[NSString stringWithUTF8String:m_friendlyName.c_str()]
action:nil keyEquivalent:@""] setSubmenu:rwkMenu]; action:nil keyEquivalent:@""] setSubmenu:appMenu];
[[NSApplication sharedApplication] setMainMenu:appMenu]; [[NSApplication sharedApplication] setMainMenu:rootMenu];
/* About panel */
NSRect aboutCr = NSMakeRect(0, 0, 300, 220);
aboutPanel = [[NSPanel alloc] initWithContentRect:aboutCr
styleMask:NSUtilityWindowMask|NSTitledWindowMask|NSClosableWindowMask
backing:NSBackingStoreBuffered defer:YES];
[aboutPanel setTitle:[NSString stringWithFormat:@"About %s", m_friendlyName.c_str()]];
NSText* aboutText = [[NSText alloc] initWithFrame:aboutCr];
[aboutText setEditable:NO];
[aboutText setAlignment:NSCenterTextAlignment];
[aboutText setString:@"\nBoo Authors\n\nJackoalan\nAntidote\n"];
[aboutPanel setContentView:aboutText];
m_appDelegate->aboutPanel = aboutPanel;
/* Determine which graphics API to use */ /* Determine which graphics API to use */
#if BOO_HAS_METAL #if BOO_HAS_METAL
@ -245,16 +228,6 @@ int ApplicationRun(IApplication::EPlatformType platform,
(void)sender; (void)sender;
return YES; return YES;
} }
- (IBAction)aboutApp:(id)sender
{
(void)sender;
NSRect screenFrame = [[aboutPanel screen] frame];
CGFloat xPos = NSWidth(screenFrame)/2 - 300/2;
CGFloat yPos = NSHeight(screenFrame)/2 - 220/2;
NSRect aboutCr = NSMakeRect(xPos, yPos, 300, 220);
[aboutPanel setFrame:aboutCr display:NO];
[aboutPanel makeKeyAndOrderFront:self];
}
- (IBAction)toggleFs:(id)sender - (IBAction)toggleFs:(id)sender
{ {
(void)sender; (void)sender;