1b8e80941Smrg/* 2b8e80941Smrg * Copyright 2012-2014, Haiku, Inc. All Rights Reserved. 3b8e80941Smrg * Distributed under the terms of the MIT License. 4b8e80941Smrg * 5b8e80941Smrg * Authors: 6b8e80941Smrg * Artur Wyszynski, harakash@gmail.com 7b8e80941Smrg * Alexander von Gluck IV, kallisti5@unixzen.com 8b8e80941Smrg */ 9b8e80941Smrg 10b8e80941Smrg#include "hgl_context.h" 11b8e80941Smrg 12b8e80941Smrg#include <stdio.h> 13b8e80941Smrg 14b8e80941Smrg#include "pipe/p_format.h" 15b8e80941Smrg#include "util/u_atomic.h" 16b8e80941Smrg#include "util/u_format.h" 17b8e80941Smrg#include "util/u_memory.h" 18b8e80941Smrg#include "util/u_inlines.h" 19b8e80941Smrg#include "state_tracker/st_gl_api.h" /* for st_gl_api_create */ 20b8e80941Smrg 21b8e80941Smrg#include "GLView.h" 22b8e80941Smrg 23b8e80941Smrg 24b8e80941Smrg#ifdef DEBUG 25b8e80941Smrg# define TRACE(x...) printf("hgl:state_tracker: " x) 26b8e80941Smrg# define CALLED() TRACE("CALLED: %s\n", __PRETTY_FUNCTION__) 27b8e80941Smrg#else 28b8e80941Smrg# define TRACE(x...) 29b8e80941Smrg# define CALLED() 30b8e80941Smrg#endif 31b8e80941Smrg#define ERROR(x...) printf("hgl:state_tracker: " x) 32b8e80941Smrg 33b8e80941Smrg 34b8e80941Smrg// Perform a safe void to hgl_context cast 35b8e80941Smrgstatic inline struct hgl_context* 36b8e80941Smrghgl_st_context(struct st_context_iface *stctxi) 37b8e80941Smrg{ 38b8e80941Smrg struct hgl_context* context; 39b8e80941Smrg assert(stctxi); 40b8e80941Smrg context = (struct hgl_context*)stctxi->st_manager_private; 41b8e80941Smrg assert(context); 42b8e80941Smrg return context; 43b8e80941Smrg} 44b8e80941Smrg 45b8e80941Smrg 46b8e80941Smrg// Perform a safe void to hgl_buffer cast 47b8e80941Smrgstatic inline struct hgl_buffer* 48b8e80941Smrghgl_st_framebuffer(struct st_framebuffer_iface *stfbi) 49b8e80941Smrg{ 50b8e80941Smrg struct hgl_buffer* buffer; 51b8e80941Smrg assert(stfbi); 52b8e80941Smrg buffer = (struct hgl_buffer*)stfbi->st_manager_private; 53b8e80941Smrg assert(buffer); 54b8e80941Smrg return buffer; 55b8e80941Smrg} 56b8e80941Smrg 57b8e80941Smrg 58b8e80941Smrgstatic boolean 59b8e80941Smrghgl_st_framebuffer_flush_front(struct st_context_iface *stctxi, 60b8e80941Smrg struct st_framebuffer_iface* stfbi, enum st_attachment_type statt) 61b8e80941Smrg{ 62b8e80941Smrg CALLED(); 63b8e80941Smrg 64b8e80941Smrg //struct hgl_context* context = hgl_st_context(stctxi); 65b8e80941Smrg //struct hgl_buffer* buffer = hgl_st_context(stfbi); 66b8e80941Smrg 67b8e80941Smrg #if 0 68b8e80941Smrg struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb); 69b8e80941Smrg mtx_lock(&stwfb->fb->mutex); 70b8e80941Smrg 71b8e80941Smrg struct pipe_resource* resource = textures[statt]; 72b8e80941Smrg if (resource) 73b8e80941Smrg stw_framebuffer_present_locked(...); 74b8e80941Smrg #endif 75b8e80941Smrg 76b8e80941Smrg return TRUE; 77b8e80941Smrg} 78b8e80941Smrg 79b8e80941Smrg 80b8e80941Smrgstatic boolean 81b8e80941Smrghgl_st_framebuffer_validate_textures(struct st_framebuffer_iface *stfbi, 82b8e80941Smrg unsigned width, unsigned height, unsigned mask) 83b8e80941Smrg{ 84b8e80941Smrg struct hgl_buffer* buffer; 85b8e80941Smrg enum st_attachment_type i; 86b8e80941Smrg struct pipe_resource templat; 87b8e80941Smrg 88b8e80941Smrg CALLED(); 89b8e80941Smrg 90b8e80941Smrg buffer = hgl_st_framebuffer(stfbi); 91b8e80941Smrg 92b8e80941Smrg if (buffer->width != width || buffer->height != height) { 93b8e80941Smrg for (i = 0; i < ST_ATTACHMENT_COUNT; i++) 94b8e80941Smrg pipe_resource_reference(&buffer->textures[i], NULL); 95b8e80941Smrg } 96b8e80941Smrg 97b8e80941Smrg memset(&templat, 0, sizeof(templat)); 98b8e80941Smrg templat.target = buffer->target; 99b8e80941Smrg templat.width0 = width; 100b8e80941Smrg templat.height0 = height; 101b8e80941Smrg templat.depth0 = 1; 102b8e80941Smrg templat.array_size = 1; 103b8e80941Smrg templat.last_level = 0; 104b8e80941Smrg 105b8e80941Smrg for (i = 0; i < ST_ATTACHMENT_COUNT; i++) { 106b8e80941Smrg enum pipe_format format; 107b8e80941Smrg unsigned bind; 108b8e80941Smrg 109b8e80941Smrg switch (i) { 110b8e80941Smrg case ST_ATTACHMENT_FRONT_LEFT: 111b8e80941Smrg case ST_ATTACHMENT_BACK_LEFT: 112b8e80941Smrg case ST_ATTACHMENT_FRONT_RIGHT: 113b8e80941Smrg case ST_ATTACHMENT_BACK_RIGHT: 114b8e80941Smrg format = buffer->visual->color_format; 115b8e80941Smrg bind = PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_RENDER_TARGET; 116b8e80941Smrg break; 117b8e80941Smrg case ST_ATTACHMENT_DEPTH_STENCIL: 118b8e80941Smrg format = buffer->visual->depth_stencil_format; 119b8e80941Smrg bind = PIPE_BIND_DEPTH_STENCIL; 120b8e80941Smrg break; 121b8e80941Smrg default: 122b8e80941Smrg format = PIPE_FORMAT_NONE; 123b8e80941Smrg bind = 0; 124b8e80941Smrg break; 125b8e80941Smrg } 126b8e80941Smrg 127b8e80941Smrg if (format != PIPE_FORMAT_NONE) { 128b8e80941Smrg templat.format = format; 129b8e80941Smrg templat.bind = bind; 130b8e80941Smrg buffer->textures[i] = buffer->screen->resource_create(buffer->screen, 131b8e80941Smrg &templat); 132b8e80941Smrg if (!buffer->textures[i]) 133b8e80941Smrg return FALSE; 134b8e80941Smrg } 135b8e80941Smrg } 136b8e80941Smrg 137b8e80941Smrg buffer->width = width; 138b8e80941Smrg buffer->height = height; 139b8e80941Smrg buffer->mask = mask; 140b8e80941Smrg 141b8e80941Smrg return TRUE; 142b8e80941Smrg} 143b8e80941Smrg 144b8e80941Smrg 145b8e80941Smrg/** 146b8e80941Smrg * Called by the st manager to validate the framebuffer (allocate 147b8e80941Smrg * its resources). 148b8e80941Smrg */ 149b8e80941Smrgstatic boolean 150b8e80941Smrghgl_st_framebuffer_validate(struct st_context_iface *stctxi, 151b8e80941Smrg struct st_framebuffer_iface *stfbi, const enum st_attachment_type *statts, 152b8e80941Smrg unsigned count, struct pipe_resource **out) 153b8e80941Smrg{ 154b8e80941Smrg struct hgl_context* context; 155b8e80941Smrg struct hgl_buffer* buffer; 156b8e80941Smrg unsigned stAttachmentMask, newMask; 157b8e80941Smrg unsigned i; 158b8e80941Smrg boolean resized; 159b8e80941Smrg 160b8e80941Smrg CALLED(); 161b8e80941Smrg 162b8e80941Smrg context = hgl_st_context(stctxi); 163b8e80941Smrg buffer = hgl_st_framebuffer(stfbi); 164b8e80941Smrg 165b8e80941Smrg //int32 width = 0; 166b8e80941Smrg //int32 height = 0; 167b8e80941Smrg //get_bitmap_size(context->bitmap, &width, &height); 168b8e80941Smrg 169b8e80941Smrg // Build mask of current attachments 170b8e80941Smrg stAttachmentMask = 0; 171b8e80941Smrg for (i = 0; i < count; i++) 172b8e80941Smrg stAttachmentMask |= 1 << statts[i]; 173b8e80941Smrg 174b8e80941Smrg newMask = stAttachmentMask & ~buffer->mask; 175b8e80941Smrg 176b8e80941Smrg resized = (buffer->width != context->width) 177b8e80941Smrg || (buffer->height != context->height); 178b8e80941Smrg 179b8e80941Smrg if (resized || newMask) { 180b8e80941Smrg boolean ret; 181b8e80941Smrg TRACE("%s: resize event. old: %d x %d; new: %d x %d\n", __func__, 182b8e80941Smrg buffer->width, buffer->height, context->width, context->height); 183b8e80941Smrg 184b8e80941Smrg ret = hgl_st_framebuffer_validate_textures(stfbi, 185b8e80941Smrg context->width, context->height, stAttachmentMask); 186b8e80941Smrg 187b8e80941Smrg if (!ret) 188b8e80941Smrg return ret; 189b8e80941Smrg 190b8e80941Smrg // TODO: Simply update attachments 191b8e80941Smrg //if (!resized) { 192b8e80941Smrg 193b8e80941Smrg //} 194b8e80941Smrg } 195b8e80941Smrg 196b8e80941Smrg for (i = 0; i < count; i++) 197b8e80941Smrg pipe_resource_reference(&out[i], buffer->textures[statts[i]]); 198b8e80941Smrg 199b8e80941Smrg return TRUE; 200b8e80941Smrg} 201b8e80941Smrg 202b8e80941Smrg 203b8e80941Smrgstatic int 204b8e80941Smrghgl_st_manager_get_param(struct st_manager *smapi, enum st_manager_param param) 205b8e80941Smrg{ 206b8e80941Smrg CALLED(); 207b8e80941Smrg 208b8e80941Smrg switch (param) { 209b8e80941Smrg case ST_MANAGER_BROKEN_INVALIDATE: 210b8e80941Smrg return 1; 211b8e80941Smrg } 212b8e80941Smrg 213b8e80941Smrg return 0; 214b8e80941Smrg} 215b8e80941Smrg 216b8e80941Smrg 217b8e80941Smrg/** 218b8e80941Smrg * Create new framebuffer 219b8e80941Smrg */ 220b8e80941Smrgstruct hgl_buffer * 221b8e80941Smrghgl_create_st_framebuffer(struct hgl_context* context) 222b8e80941Smrg{ 223b8e80941Smrg struct hgl_buffer *buffer; 224b8e80941Smrg CALLED(); 225b8e80941Smrg 226b8e80941Smrg // Our requires before creating a framebuffer 227b8e80941Smrg assert(context); 228b8e80941Smrg assert(context->screen); 229b8e80941Smrg assert(context->stVisual); 230b8e80941Smrg 231b8e80941Smrg buffer = CALLOC_STRUCT(hgl_buffer); 232b8e80941Smrg assert(buffer); 233b8e80941Smrg 234b8e80941Smrg // calloc and configure our st_framebuffer interface 235b8e80941Smrg buffer->stfbi = CALLOC_STRUCT(st_framebuffer_iface); 236b8e80941Smrg assert(buffer->stfbi); 237b8e80941Smrg 238b8e80941Smrg // Prepare our buffer 239b8e80941Smrg buffer->visual = context->stVisual; 240b8e80941Smrg buffer->screen = context->screen; 241b8e80941Smrg 242b8e80941Smrg if (context->screen->get_param(buffer->screen, PIPE_CAP_NPOT_TEXTURES)) 243b8e80941Smrg buffer->target = PIPE_TEXTURE_2D; 244b8e80941Smrg else 245b8e80941Smrg buffer->target = PIPE_TEXTURE_RECT; 246b8e80941Smrg 247b8e80941Smrg // Prepare our state_tracker interface 248b8e80941Smrg buffer->stfbi->flush_front = hgl_st_framebuffer_flush_front; 249b8e80941Smrg buffer->stfbi->validate = hgl_st_framebuffer_validate; 250b8e80941Smrg buffer->stfbi->visual = context->stVisual; 251b8e80941Smrg 252b8e80941Smrg p_atomic_set(&buffer->stfbi->stamp, 1); 253b8e80941Smrg buffer->stfbi->st_manager_private = (void*)buffer; 254b8e80941Smrg 255b8e80941Smrg return buffer; 256b8e80941Smrg} 257b8e80941Smrg 258b8e80941Smrg 259b8e80941Smrgstruct st_api* 260b8e80941Smrghgl_create_st_api() 261b8e80941Smrg{ 262b8e80941Smrg CALLED(); 263b8e80941Smrg return st_gl_api_create(); 264b8e80941Smrg} 265b8e80941Smrg 266b8e80941Smrg 267b8e80941Smrgstruct st_manager * 268b8e80941Smrghgl_create_st_manager(struct hgl_context* context) 269b8e80941Smrg{ 270b8e80941Smrg struct st_manager* manager; 271b8e80941Smrg 272b8e80941Smrg CALLED(); 273b8e80941Smrg 274b8e80941Smrg // Required things 275b8e80941Smrg assert(context); 276b8e80941Smrg assert(context->screen); 277b8e80941Smrg 278b8e80941Smrg manager = CALLOC_STRUCT(st_manager); 279b8e80941Smrg assert(manager); 280b8e80941Smrg 281b8e80941Smrg //manager->display = dpy; 282b8e80941Smrg manager->screen = context->screen; 283b8e80941Smrg manager->get_param = hgl_st_manager_get_param; 284b8e80941Smrg 285b8e80941Smrg return manager; 286b8e80941Smrg} 287b8e80941Smrg 288b8e80941Smrg 289b8e80941Smrgvoid 290b8e80941Smrghgl_destroy_st_manager(struct st_manager *manager) 291b8e80941Smrg{ 292b8e80941Smrg CALLED(); 293b8e80941Smrg 294b8e80941Smrg FREE(manager); 295b8e80941Smrg} 296b8e80941Smrg 297b8e80941Smrg 298b8e80941Smrgstruct st_visual* 299b8e80941Smrghgl_create_st_visual(ulong options) 300b8e80941Smrg{ 301b8e80941Smrg struct st_visual* visual; 302b8e80941Smrg 303b8e80941Smrg CALLED(); 304b8e80941Smrg 305b8e80941Smrg visual = CALLOC_STRUCT(st_visual); 306b8e80941Smrg assert(visual); 307b8e80941Smrg 308b8e80941Smrg // Determine color format 309b8e80941Smrg if ((options & BGL_INDEX) != 0) { 310b8e80941Smrg // Index color 311b8e80941Smrg visual->color_format = PIPE_FORMAT_B5G6R5_UNORM; 312b8e80941Smrg // TODO: Indexed color depth buffer? 313b8e80941Smrg visual->depth_stencil_format = PIPE_FORMAT_NONE; 314b8e80941Smrg } else { 315b8e80941Smrg // RGB color 316b8e80941Smrg visual->color_format = (options & BGL_ALPHA) 317b8e80941Smrg ? PIPE_FORMAT_BGRA8888_UNORM : PIPE_FORMAT_BGRX8888_UNORM; 318b8e80941Smrg // TODO: Determine additional stencil formats 319b8e80941Smrg visual->depth_stencil_format = (options & BGL_DEPTH) 320b8e80941Smrg ? PIPE_FORMAT_Z24_UNORM_S8_UINT : PIPE_FORMAT_NONE; 321b8e80941Smrg } 322b8e80941Smrg 323b8e80941Smrg visual->accum_format = (options & BGL_ACCUM) 324b8e80941Smrg ? PIPE_FORMAT_R16G16B16A16_SNORM : PIPE_FORMAT_NONE; 325b8e80941Smrg 326b8e80941Smrg visual->buffer_mask |= ST_ATTACHMENT_FRONT_LEFT_MASK; 327b8e80941Smrg visual->render_buffer = ST_ATTACHMENT_FRONT_LEFT; 328b8e80941Smrg 329b8e80941Smrg if ((options & BGL_DOUBLE) != 0) { 330b8e80941Smrg visual->buffer_mask |= ST_ATTACHMENT_BACK_LEFT_MASK; 331b8e80941Smrg visual->render_buffer = ST_ATTACHMENT_BACK_LEFT; 332b8e80941Smrg } 333b8e80941Smrg 334b8e80941Smrg #if 0 335b8e80941Smrg if ((options & BGL_STEREO) != 0) { 336b8e80941Smrg visual->buffer_mask |= ST_ATTACHMENT_FRONT_RIGHT_MASK; 337b8e80941Smrg if ((options & BGL_DOUBLE) != 0) 338b8e80941Smrg visual->buffer_mask |= ST_ATTACHMENT_BACK_RIGHT_MASK; 339b8e80941Smrg } 340b8e80941Smrg #endif 341b8e80941Smrg 342b8e80941Smrg if ((options & BGL_DEPTH) || (options & BGL_STENCIL)) 343b8e80941Smrg visual->buffer_mask |= ST_ATTACHMENT_DEPTH_STENCIL_MASK; 344b8e80941Smrg 345b8e80941Smrg TRACE("%s: Visual color format: %s\n", __func__, 346b8e80941Smrg util_format_name(visual->color_format)); 347b8e80941Smrg 348b8e80941Smrg return visual; 349b8e80941Smrg} 350b8e80941Smrg 351b8e80941Smrg 352b8e80941Smrgvoid 353b8e80941Smrghgl_destroy_st_visual(struct st_visual* visual) 354b8e80941Smrg{ 355b8e80941Smrg CALLED(); 356b8e80941Smrg 357b8e80941Smrg FREE(visual); 358b8e80941Smrg} 359