swpipe: Add Framebuffer management

* It's painfully obvious to me now that we will
  need to manage our own framebuffers still in
  the latest gallium code.
* GalliumFramebuffer works pretty cleanly as a
  class.. we have to remember to lock and unlock
  the Framebuffer object however when we access
  fBuffer directly. (which needs to occur by design)
* I'm really starting to have problems with the
  amount of downcasting Gallium3D does now.
This commit is contained in:
Alexander von Gluck IV
2012-12-05 15:37:43 +00:00
parent d6137548a0
commit 2574bdfcc7
5 changed files with 175 additions and 5 deletions
+23 -2
View File
@@ -235,7 +235,7 @@ GalliumContext::CreateContext(Bitmap *bitmap)
return 0;
}
// Set up the initial things out context needs
// Set up the initial things our context needs
context->bitmap = bitmap;
context->colorSpace = get_bitmap_color_space(bitmap);
context->draw = NULL;
@@ -295,6 +295,15 @@ GalliumContext::CreateContext(Bitmap *bitmap)
struct st_visual stVisual;
hgl_fill_st_visual(&stVisual, glVisual);
context->draw = new GalliumFramebuffer(&stVisual);
context->read = new GalliumFramebuffer(&stVisual);
if (!context->draw || !context->read) {
ERROR("%s: Problem allocating framebuffer!\n", __func__);
_mesa_destroy_visual(glVisual);
return -1;
}
// We need to assign the screen *before* calling st_api create_context
context->manager->screen = fScreen;
@@ -403,6 +412,12 @@ GalliumContext::DestroyContext(context_id contextID)
if (fContext[contextID]->postProcess)
pp_free(fContext[contextID]->postProcess);
// Delete framebuffer objects
if (fContext[contextID]->read)
delete fContext[contextID]->read;
if (fContext[contextID]->draw)
delete fContext[contextID]->draw;
if (fContext[contextID]->manager)
FREE(fContext[contextID]->manager);
@@ -446,7 +461,13 @@ GalliumContext::SetCurrentContext(Bitmap *bitmap, context_id contextID)
ST_FLUSH_FRONT, NULL);
}
api->make_current(context->api, context->st, context->draw, context->read);
// We need to lock and unlock framebuffers before accessing them
context->draw->Lock();
context->read->Lock();
api->make_current(context->api, context->st, context->draw->fBuffer,
context->read->fBuffer);
context->draw->Unlock();
context->read->Unlock();
// TODO: Init textures before post-processing them
#if 0
+5 -3
View File
@@ -16,8 +16,8 @@ extern "C" {
#include "postprocess/filters.h"
#include "os/os_thread.h"
}
#include "bitmap_wrapper.h"
#include "GalliumFramebuffer.h"
#define CONTEXT_MAX 32
@@ -38,6 +38,8 @@ struct hgl_context
// State Tracker Manager
struct st_context_iface* st;
// State Tracker Interface Object
struct st_visual* stVisual;
// State Tracker Visual
struct pipe_resource* textures[ST_ATTACHMENT_COUNT];
@@ -48,8 +50,8 @@ struct hgl_context
Bitmap* bitmap;
color_space colorSpace;
struct st_framebuffer_iface* draw;
struct st_framebuffer_iface* read;
GalliumFramebuffer* draw;
GalliumFramebuffer* read;
};
@@ -0,0 +1,113 @@
/*
* Copyright 2012, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Artur Wyszynski, [email protected]
* Alexander von Gluck IV, [email protected]
*/
#include "GalliumFramebuffer.h"
extern "C" {
#include "main/context.h"
#include "main/framebuffer.h"
#include "main/renderbuffer.h"
#include "pipe/p_format.h"
}
#define TRACE_FRAMEBUFFER
#ifdef TRACE_FRAEMBUFFER
# define TRACE(x...) printf("GalliumFramebuffer: " x)
# define CALLED() TRACE("CALLED: %s\n", __PRETTY_FUNCTION__)
#else
# define TRACE(x...)
# define CALLED()
#endif
#define ERROR(x...) printf("GalliumFramebuffer: " x)
static boolean
hgl_framebuffer_flush_front(struct st_framebuffer_iface* stfb,
enum st_attachment_type statt)
{
CALLED();
// TODO: I have *NO* idea how we are going to access this data...
#if 0
struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb);
pipe_mutex_lock(stwfb->fb->mutex);
struct pipe_resource* resource = textures[statt];
if (resource)
stw_framebuffer_present_locked(...);
#endif
return TRUE;
}
static boolean
hgl_framebuffer_validate(struct st_framebuffer_iface* stfb,
const enum st_attachment_type* statts, unsigned count,
struct pipe_resource** out)
{
CALLED();
return TRUE;
}
GalliumFramebuffer::GalliumFramebuffer(struct st_visual* visual)
:
fBuffer(NULL)
{
CALLED();
fBuffer = CALLOC_STRUCT(st_framebuffer_iface);
if (!fBuffer) {
ERROR("%s: Couldn't calloc framebuffer!\n", __func__);
return;
}
fBuffer->visual = visual;
fBuffer->flush_front = hgl_framebuffer_flush_front;
fBuffer->validate = hgl_framebuffer_validate;
pipe_mutex_init(fMutex);
}
GalliumFramebuffer::~GalliumFramebuffer()
{
CALLED();
// We lock and unlock to try and make sure we wait for anything
// using the framebuffer to finish
Lock();
if (!fBuffer) {
ERROR("%s: Strange, no Gallium Framebuffer to free?\n", __func__);
return;
}
FREE(fBuffer);
Unlock();
pipe_mutex_destroy(fMutex);
}
status_t
GalliumFramebuffer::Lock()
{
CALLED();
pipe_mutex_lock(fMutex);
return B_OK;
}
status_t
GalliumFramebuffer::Unlock()
{
CALLED();
pipe_mutex_unlock(fMutex);
return B_OK;
}
@@ -0,0 +1,33 @@
/*
* Copyright 2012, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Alexander von Gluck IV, [email protected]
*/
#ifndef GALLIUMFRAMEBUFFER_H
#define GALLIUMFRAMEBUFFER_H
extern "C" {
#include "os/os_thread.h"
#include "pipe/p_screen.h"
#include "state_tracker/st_api.h"
}
class GalliumFramebuffer {
public:
GalliumFramebuffer(struct st_visual* visual);
~GalliumFramebuffer();
status_t Lock();
status_t Unlock();
struct st_framebuffer_iface* fBuffer;
private:
pipe_mutex fMutex;
};
#endif /* GALLIUMFRAMEBUFFER_H */
+1
View File
@@ -10,6 +10,7 @@ local sources =
SoftwareRenderer.cpp
SoftwareWinsys.cpp
GalliumContext.cpp
GalliumFramebuffer.cpp
bitmap_wrapper.cpp ;
if $(HAIKU_LLVM_PRESENT) {