Path: blob/21.2-virgl/src/gallium/frontends/hgl/hgl.c
4561 views
/*1* Copyright 2012-2014, Haiku, Inc. All Rights Reserved.2* Distributed under the terms of the MIT License.3*4* Authors:5* Artur Wyszynski, [email protected]6* Alexander von Gluck IV, [email protected]7*/89#include "hgl_context.h"1011#include <stdio.h>1213#include "pipe/p_format.h"14#include "util/u_atomic.h"15#include "util/format/u_format.h"16#include "util/u_memory.h"17#include "util/u_inlines.h"18#include "state_tracker/st_gl_api.h" /* for st_gl_api_create */1920#include "GLView.h"212223#ifdef DEBUG24# define TRACE(x...) printf("hgl:frontend: " x)25# define CALLED() TRACE("CALLED: %s\n", __PRETTY_FUNCTION__)26#else27# define TRACE(x...)28# define CALLED()29#endif30#define ERROR(x...) printf("hgl:frontend: " x)313233// Perform a safe void to hgl_context cast34static inline struct hgl_context*35hgl_st_context(struct st_context_iface *stctxi)36{37struct hgl_context* context;38assert(stctxi);39context = (struct hgl_context*)stctxi->st_manager_private;40assert(context);41return context;42}434445// Perform a safe void to hgl_buffer cast46//static inline struct hgl_buffer*47struct hgl_buffer*48hgl_st_framebuffer(struct st_framebuffer_iface *stfbi)49{50struct hgl_buffer* buffer;51assert(stfbi);52buffer = (struct hgl_buffer*)stfbi->st_manager_private;53assert(buffer);54return buffer;55}565758static bool59hgl_st_framebuffer_flush_front(struct st_context_iface* stctxi,60struct st_framebuffer_iface* stfbi, enum st_attachment_type statt)61{62CALLED();6364struct hgl_buffer* buffer = hgl_st_framebuffer(stfbi);65struct pipe_resource* ptex = buffer->textures[statt];6667if (statt != ST_ATTACHMENT_FRONT_LEFT)68return false;6970if (!ptex)71return true;7273// TODO: pipe_context here??? Might be needed for hw renderers74buffer->screen->flush_frontbuffer(buffer->screen, NULL, ptex, 0, 0,75buffer->winsysContext, NULL);7677return true;78}798081static bool82hgl_st_framebuffer_validate_textures(struct st_framebuffer_iface *stfbi,83unsigned width, unsigned height, unsigned mask)84{85struct hgl_buffer* buffer;86enum st_attachment_type i;87struct pipe_resource templat;8889CALLED();9091buffer = hgl_st_framebuffer(stfbi);9293if (buffer->width != width || buffer->height != height) {94TRACE("validate_textures: size changed: %d, %d -> %d, %d\n",95buffer->width, buffer->height, width, height);96for (i = 0; i < ST_ATTACHMENT_COUNT; i++)97pipe_resource_reference(&buffer->textures[i], NULL);98}99100memset(&templat, 0, sizeof(templat));101templat.target = buffer->target;102templat.width0 = width;103templat.height0 = height;104templat.depth0 = 1;105templat.array_size = 1;106templat.last_level = 0;107108for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {109enum pipe_format format;110unsigned bind;111112if (((1 << i) & buffer->visual->buffer_mask) && buffer->textures[i] == NULL) {113switch (i) {114case ST_ATTACHMENT_FRONT_LEFT:115case ST_ATTACHMENT_BACK_LEFT:116case ST_ATTACHMENT_FRONT_RIGHT:117case ST_ATTACHMENT_BACK_RIGHT:118format = buffer->visual->color_format;119bind = PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_RENDER_TARGET;120break;121case ST_ATTACHMENT_DEPTH_STENCIL:122format = buffer->visual->depth_stencil_format;123bind = PIPE_BIND_DEPTH_STENCIL;124break;125default:126format = PIPE_FORMAT_NONE;127bind = 0;128break;129}130131if (format != PIPE_FORMAT_NONE) {132templat.format = format;133templat.bind = bind;134TRACE("resource_create(%d, %d, %d)\n", i, format, bind);135buffer->textures[i] = buffer->screen->resource_create(buffer->screen,136&templat);137if (!buffer->textures[i])138return FALSE;139}140}141}142143buffer->width = width;144buffer->height = height;145buffer->mask = mask;146147return true;148}149150151/**152* Called by the st manager to validate the framebuffer (allocate153* its resources).154*/155static bool156hgl_st_framebuffer_validate(struct st_context_iface *stctxi,157struct st_framebuffer_iface *stfbi, const enum st_attachment_type *statts,158unsigned count, struct pipe_resource **out)159{160struct hgl_context* context;161struct hgl_buffer* buffer;162unsigned stAttachmentMask, newMask;163unsigned i;164bool resized;165166CALLED();167168context = hgl_st_context(stctxi);169buffer = hgl_st_framebuffer(stfbi);170171// Build mask of current attachments172stAttachmentMask = 0;173for (i = 0; i < count; i++)174stAttachmentMask |= 1 << statts[i];175176newMask = stAttachmentMask & ~buffer->mask;177178resized = (buffer->width != context->width)179|| (buffer->height != context->height);180181if (resized || newMask) {182boolean ret;183TRACE("%s: resize event. old: %d x %d; new: %d x %d\n", __func__,184buffer->width, buffer->height, context->width, context->height);185186ret = hgl_st_framebuffer_validate_textures(stfbi,187context->width, context->height, stAttachmentMask);188189if (!ret)190return ret;191}192193for (i = 0; i < count; i++)194pipe_resource_reference(&out[i], buffer->textures[statts[i]]);195196return true;197}198199200static int201hgl_st_manager_get_param(struct st_manager *smapi, enum st_manager_param param)202{203CALLED();204205switch (param) {206case ST_MANAGER_BROKEN_INVALIDATE:207return 1;208}209210return 0;211}212213214static uint32_t hgl_fb_ID = 0;215216/**217* Create new framebuffer218*/219struct hgl_buffer *220hgl_create_st_framebuffer(struct hgl_context* context, void *winsysContext)221{222struct hgl_buffer *buffer;223CALLED();224225// Our requires before creating a framebuffer226assert(context);227assert(context->display);228assert(context->stVisual);229230buffer = CALLOC_STRUCT(hgl_buffer);231assert(buffer);232233// calloc and configure our st_framebuffer interface234buffer->stfbi = CALLOC_STRUCT(st_framebuffer_iface);235assert(buffer->stfbi);236237// Prepare our buffer238buffer->visual = context->stVisual;239buffer->screen = context->display->manager->screen;240buffer->winsysContext = winsysContext;241242if (buffer->screen->get_param(buffer->screen, PIPE_CAP_NPOT_TEXTURES))243buffer->target = PIPE_TEXTURE_2D;244else245buffer->target = PIPE_TEXTURE_RECT;246247// Prepare our frontend interface248buffer->stfbi->flush_front = hgl_st_framebuffer_flush_front;249buffer->stfbi->validate = hgl_st_framebuffer_validate;250buffer->stfbi->visual = context->stVisual;251252p_atomic_set(&buffer->stfbi->stamp, 1);253buffer->stfbi->st_manager_private = (void*)buffer;254buffer->stfbi->ID = p_atomic_inc_return(&hgl_fb_ID);255buffer->stfbi->state_manager = context->display->manager;256257return buffer;258}259260261void262hgl_destroy_st_framebuffer(struct hgl_buffer *buffer)263{264CALLED();265266int i;267for (i = 0; i < ST_ATTACHMENT_COUNT; i++)268pipe_resource_reference(&buffer->textures[i], NULL);269270FREE(buffer->stfbi);271FREE(buffer);272}273274275struct st_api*276hgl_create_st_api()277{278CALLED();279return st_gl_api_create();280}281282283struct st_visual*284hgl_create_st_visual(ulong options)285{286struct st_visual* visual;287288CALLED();289290visual = CALLOC_STRUCT(st_visual);291assert(visual);292293// Determine color format294if ((options & BGL_INDEX) != 0) {295// Index color296visual->color_format = PIPE_FORMAT_B5G6R5_UNORM;297// TODO: Indexed color depth buffer?298visual->depth_stencil_format = PIPE_FORMAT_NONE;299} else {300// RGB color301visual->color_format = (options & BGL_ALPHA)302? PIPE_FORMAT_BGRA8888_UNORM : PIPE_FORMAT_BGRX8888_UNORM;303// TODO: Determine additional stencil formats304visual->depth_stencil_format = (options & BGL_DEPTH)305? PIPE_FORMAT_Z24_UNORM_S8_UINT : PIPE_FORMAT_NONE;306}307308visual->accum_format = (options & BGL_ACCUM)309? PIPE_FORMAT_R16G16B16A16_SNORM : PIPE_FORMAT_NONE;310311visual->buffer_mask |= ST_ATTACHMENT_FRONT_LEFT_MASK;312313if ((options & BGL_DOUBLE) != 0) {314TRACE("double buffer enabled\n");315visual->buffer_mask |= ST_ATTACHMENT_BACK_LEFT_MASK;316}317318#if 0319if ((options & BGL_STEREO) != 0) {320visual->buffer_mask |= ST_ATTACHMENT_FRONT_RIGHT_MASK;321if ((options & BGL_DOUBLE) != 0)322visual->buffer_mask |= ST_ATTACHMENT_BACK_RIGHT_MASK;323}324#endif325326if ((options & BGL_DEPTH) || (options & BGL_STENCIL))327visual->buffer_mask |= ST_ATTACHMENT_DEPTH_STENCIL_MASK;328329TRACE("%s: Visual color format: %s\n", __func__,330util_format_name(visual->color_format));331332return visual;333}334335336void337hgl_destroy_st_visual(struct st_visual* visual)338{339CALLED();340341FREE(visual);342}343344345struct hgl_display*346hgl_create_display(struct pipe_screen* screen)347{348struct hgl_display* display;349350display = CALLOC_STRUCT(hgl_display);351assert(display);352display->api = st_gl_api_create();353display->manager = CALLOC_STRUCT(st_manager);354assert(display->manager);355display->manager->screen = screen;356display->manager->get_param = hgl_st_manager_get_param;357// display->manager->st_manager_private is used by llvmpipe358359return display;360}361362363void364hgl_destroy_display(struct hgl_display *display)365{366if (display->manager->destroy)367display->manager->destroy(display->manager);368FREE(display->manager);369if (display->api->destroy)370display->api->destroy(display->api);371FREE(display);372}373374375