cube.c revision 7461fcf758fa133fe84da0c1b8f4abd776f3f385
1#define _GNU_SOURCE 2#include <stdio.h> 3#include <stdlib.h> 4#include <string.h> 5#include <stdbool.h> 6#include <assert.h> 7 8#include <xcb/xcb.h> 9#include <xgl.h> 10#include <xglDbg.h> 11#include <xglWsiX11Ext.h> 12 13#include "icd-bil.h" 14 15#include "linmath.h" 16#include <unistd.h> 17#include <png.h> 18 19#define DEMO_BUFFER_COUNT 2 20#define DEMO_TEXTURE_COUNT 1 21 22/* 23 * When not defined, code will use built-in GLSL compiler 24 * which may not be supported on all drivers 25 */ 26#define EXTERNAL_BIL 27 28static char *tex_files[] = { 29 "lunarg-logo-256x256-solid.png" 30}; 31 32struct xglcube_vs_uniform { 33 // Must start with MVP 34 XGL_FLOAT mvp[4][4]; 35 XGL_FLOAT position[12*3][4]; 36 XGL_FLOAT color[12*3][4]; 37}; 38 39struct xgltexcube_vs_uniform { 40 // Must start with MVP 41 XGL_FLOAT mvp[4][4]; 42 XGL_FLOAT position[12*3][4]; 43 XGL_FLOAT attr[12*3][4]; 44}; 45 46//-------------------------------------------------------------------------------------- 47// Mesh and VertexFormat Data 48//-------------------------------------------------------------------------------------- 49struct Vertex 50{ 51 XGL_FLOAT posX, posY, posZ, posW; // Position data 52 XGL_FLOAT r, g, b, a; // Color 53}; 54 55struct VertexPosTex 56{ 57 XGL_FLOAT posX, posY, posZ, posW; // Position data 58 XGL_FLOAT u, v, s, t; // Texcoord 59}; 60 61#define XYZ1(_x_, _y_, _z_) (_x_), (_y_), (_z_), 1.f 62#define UV(_u_, _v_) (_u_), (_v_), 0.f, 1.f 63 64static const XGL_FLOAT g_vertex_buffer_data[] = { 65 -1.0f,-1.0f,-1.0f, // Vertex 0 66 -1.0f,-1.0f, 1.0f, 67 -1.0f, 1.0f, 1.0f, 68 69 -1.0f, 1.0f, 1.0f, // Vertex 1 70 -1.0f, 1.0f,-1.0f, 71 -1.0f,-1.0f,-1.0f, 72 73 -1.0f,-1.0f,-1.0f, // Vertex 2 74 1.0f, 1.0f,-1.0f, 75 1.0f,-1.0f,-1.0f, 76 77 -1.0f,-1.0f,-1.0f, // Vertex 3 78 1.0f, 1.0f,-1.0f, 79 -1.0f, 1.0f,-1.0f, 80 81 -1.0f,-1.0f,-1.0f, // Vertex 4 82 1.0f,-1.0f, 1.0f, 83 1.0f,-1.0f,-1.0f, 84 85 -1.0f,-1.0f,-1.0f, // Vertex 5 86 -1.0f,-1.0f, 1.0f, 87 1.0f,-1.0f, 1.0f, 88 89 -1.0f, 1.0f,-1.0f, // Vertex 6 90 -1.0f, 1.0f, 1.0f, 91 1.0f, 1.0f, 1.0f, 92 93 -1.0f, 1.0f,-1.0f, // Vertex 7 94 1.0f, 1.0f,-1.0f, 95 1.0f, 1.0f, 1.0f, 96 97 1.0f, 1.0f,-1.0f, // Vertex 8 98 1.0f, 1.0f, 1.0f, 99 1.0f,-1.0f, 1.0f, 100 101 1.0f,-1.0f, 1.0f, // Vertex 9 102 1.0f,-1.0f,-1.0f, 103 1.0f, 1.0f,-1.0f, 104 105 -1.0f, 1.0f, 1.0f, // Vertex 10 106 1.0f, 1.0f, 1.0f, 107 -1.0f,-1.0f, 1.0f, 108 109 -1.0f,-1.0f, 1.0f, // Vertex 11 110 1.0f,-1.0f, 1.0f, 111 1.0f, 1.0f, 1.0f, 112}; 113 114static const XGL_FLOAT g_uv_buffer_data[] = { 115 1.0f, 0.0f, // Vertex 0 116 0.0f, 0.0f, 117 0.0f, 1.0f, 118 119 0.0f, 1.0f, // Vertex 1 120 1.0f, 1.0f, 121 1.0f, 0.0f, 122 123// 0.0f, 1.0f, // Vertex 2 124// 1.0f, 0.0f, 125// 0.0f, 0.0f, 126 127// 0.0f, 1.0f, // Vertex 3 128// 1.0f, 0.0f, 129// 1.0f, 1.0f, 130 131 0.0f, 0.0f, // Vertex 2 132 1.0f, 1.0f, 133 1.0f, 0.0f, 134 135 0.0f, 0.0f, // Vertex 3 136 1.0f, 1.0f, 137 0.0f, 1.0f, 138 139 0.0f, 1.0f, // Vertex 4 140 1.0f, 0.0f, 141 0.0f, 0.0f, 142 143 0.0f, 1.0f, // Vertex 5 144 1.0f, 1.0f, 145 1.0f, 0.0f, 146 147 0.0f, 1.0f, // Vertex 6 148 1.0f, 1.0f, 149 1.0f, 0.0f, 150 151 0.0f, 1.0f, // Vertex 7 152 0.0f, 0.0f, 153 1.0f, 0.0f, 154 155 0.0f, 1.0f, // Vertex 8 156 1.0f, 1.0f, 157 1.0f, 0.0f, 158 159 1.0f, 0.0f, // Vertex 9 160 0.0f, 0.0f, 161 0.0f, 1.0f, 162 163 1.0f, 1.0f, // Vertex 10 164 0.0f, 1.0f, 165 1.0f, 0.0f, 166 167 1.0f, 0.0f, // Vertex 11 168 0.0f, 0.0f, 169 0.0f, 1.0f, 170}; 171 172void dumpMatrix(const char *note, mat4x4 MVP) 173{ 174 int i; 175 176 printf("%s: \n", note); 177 for (i=0; i<4; i++) { 178 printf("%f, %f, %f, %f\n", MVP[i][0], MVP[i][1], MVP[i][2], MVP[i][3]); 179 } 180 printf("\n"); 181 fflush(stdout); 182} 183 184void dumpVec4(const char *note, vec4 vector) 185{ 186 printf("%s: \n", note); 187 printf("%f, %f, %f, %f\n", vector[0], vector[1], vector[2], vector[3]); 188 printf("\n"); 189 fflush(stdout); 190} 191 192struct demo { 193 xcb_connection_t *connection; 194 xcb_screen_t *screen; 195 196 XGL_PHYSICAL_GPU gpu; 197 XGL_DEVICE device; 198 XGL_QUEUE queue; 199 200 int width, height; 201 XGL_FORMAT format; 202 203 struct { 204 XGL_IMAGE image; 205 XGL_GPU_MEMORY mem; 206 207 XGL_COLOR_ATTACHMENT_VIEW view; 208 XGL_FENCE fence; 209 } buffers[DEMO_BUFFER_COUNT]; 210 211 struct { 212 XGL_FORMAT format; 213 214 XGL_IMAGE image; 215 XGL_GPU_MEMORY mem; 216 XGL_DEPTH_STENCIL_VIEW view; 217 } depth; 218 219 struct { 220 XGL_SAMPLER sampler; 221 222 char *filename; 223 XGL_IMAGE image; 224 XGL_GPU_MEMORY mem; 225 XGL_IMAGE_VIEW view; 226 } textures[DEMO_TEXTURE_COUNT]; 227 228 struct { 229 XGL_GPU_MEMORY mem; 230 XGL_MEMORY_VIEW_ATTACH_INFO view; 231 232 XGL_PIPELINE_VERTEX_INPUT_CREATE_INFO vi; 233 XGL_VERTEX_INPUT_BINDING_DESCRIPTION vi_bindings[1]; 234 XGL_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION vi_attrs[2]; 235 } vertices; 236 237 struct { 238 XGL_GPU_MEMORY mem; 239 XGL_MEMORY_VIEW_ATTACH_INFO view; 240 } uniform_data; 241 242 XGL_DESCRIPTOR_SET dset; 243 244 XGL_PIPELINE pipeline; 245 246 XGL_VIEWPORT_STATE_OBJECT viewport; 247 XGL_RASTER_STATE_OBJECT raster; 248 XGL_MSAA_STATE_OBJECT msaa; 249 XGL_COLOR_BLEND_STATE_OBJECT color_blend; 250 XGL_DEPTH_STENCIL_STATE_OBJECT depth_stencil; 251 252 mat4x4 projection_matrix; 253 mat4x4 view_matrix; 254 mat4x4 model_matrix; 255 256 XGL_FLOAT spin_angle; 257 XGL_FLOAT spin_increment; 258 bool pause; 259 260 XGL_CMD_BUFFER cmd; 261 262 xcb_window_t window; 263 xcb_intern_atom_reply_t *atom_wm_delete_window; 264 265 bool quit; 266 XGL_UINT current_buffer; 267}; 268 269static void demo_draw_build_cmd(struct demo *demo) 270{ 271 const XGL_COLOR_ATTACHMENT_BIND_INFO color_attachment = { 272 .view = demo->buffers[demo->current_buffer].view, 273 .colorAttachmentState = XGL_IMAGE_STATE_TARGET_RENDER_ACCESS_OPTIMAL, 274 }; 275 const XGL_DEPTH_STENCIL_BIND_INFO depth_stencil = { 276 .view = demo->depth.view, 277 .depthState = XGL_IMAGE_STATE_TARGET_RENDER_ACCESS_OPTIMAL, 278 .stencilState = XGL_IMAGE_STATE_TARGET_RENDER_ACCESS_OPTIMAL, 279 }; 280 const XGL_FLOAT clear_color[4] = { 0.2f, 0.2f, 0.2f, 0.2f }; 281 const XGL_FLOAT clear_depth = 1.0f; 282 XGL_IMAGE_SUBRESOURCE_RANGE clear_range; 283 XGL_RESULT err; 284 285 err = xglBeginCommandBuffer(demo->cmd, 286 XGL_CMD_BUFFER_OPTIMIZE_GPU_SMALL_BATCH_BIT | 287 XGL_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT); 288 assert(!err); 289 290 xglCmdBindPipeline(demo->cmd, XGL_PIPELINE_BIND_POINT_GRAPHICS, 291 demo->pipeline); 292 xglCmdBindDescriptorSet(demo->cmd, XGL_PIPELINE_BIND_POINT_GRAPHICS, 293 0, demo->dset, 0); 294 295 xglCmdBindStateObject(demo->cmd, XGL_STATE_BIND_VIEWPORT, demo->viewport); 296 xglCmdBindStateObject(demo->cmd, XGL_STATE_BIND_RASTER, demo->raster); 297 xglCmdBindStateObject(demo->cmd, XGL_STATE_BIND_MSAA, demo->msaa); 298 xglCmdBindStateObject(demo->cmd, XGL_STATE_BIND_COLOR_BLEND, 299 demo->color_blend); 300 xglCmdBindStateObject(demo->cmd, XGL_STATE_BIND_DEPTH_STENCIL, 301 demo->depth_stencil); 302 303 xglCmdBindAttachments(demo->cmd, 1, &color_attachment, &depth_stencil); 304 305 clear_range.aspect = XGL_IMAGE_ASPECT_COLOR; 306 clear_range.baseMipLevel = 0; 307 clear_range.mipLevels = 1; 308 clear_range.baseArraySlice = 0; 309 clear_range.arraySize = 1; 310 xglCmdClearColorImage(demo->cmd, 311 demo->buffers[demo->current_buffer].image, 312 clear_color, 1, &clear_range); 313 314 clear_range.aspect = XGL_IMAGE_ASPECT_DEPTH; 315 xglCmdClearDepthStencil(demo->cmd, demo->depth.image, 316 clear_depth, 0, 1, &clear_range); 317 318 xglCmdDraw(demo->cmd, 0, 12 * 3, 0, 1); 319 320 err = xglEndCommandBuffer(demo->cmd); 321 assert(!err); 322} 323 324 325void demo_update_data_buffer(struct demo *demo) 326{ 327 mat4x4 MVP, Model, VP; 328 int matrixSize = sizeof(MVP); 329 XGL_UINT8 *pData; 330 XGL_RESULT err; 331 332 mat4x4_mul(VP, demo->projection_matrix, demo->view_matrix); 333 334 // Rotate 22.5 degrees around the Y axis 335 mat4x4_dup(Model, demo->model_matrix); 336 mat4x4_rotate(demo->model_matrix, Model, 0.0f, 1.0f, 0.0f, degreesToRadians(demo->spin_angle)); 337 mat4x4_mul(MVP, VP, demo->model_matrix); 338 339 err = xglMapMemory(demo->uniform_data.mem, 0, (XGL_VOID **) &pData); 340 assert(!err); 341 342 memcpy(pData, (const void*) &MVP[0][0], matrixSize); 343 344 err = xglUnmapMemory(demo->uniform_data.mem); 345 assert(!err); 346} 347 348static void demo_draw(struct demo *demo) 349{ 350 const XGL_WSI_X11_PRESENT_INFO present = { 351 .destWindow = demo->window, 352 .srcImage = demo->buffers[demo->current_buffer].image, 353 .async = true, 354 .flip = false, 355 }; 356 XGL_FENCE fence = demo->buffers[demo->current_buffer].fence; 357 XGL_RESULT err; 358 359 demo_draw_build_cmd(demo); 360 361 err = xglWaitForFences(demo->device, 1, &fence, XGL_TRUE, ~((XGL_UINT64) 0)); 362 assert(err == XGL_SUCCESS || err == XGL_ERROR_UNAVAILABLE); 363 364 err = xglQueueSubmit(demo->queue, 1, &demo->cmd, 365 0, NULL, XGL_NULL_HANDLE); 366 assert(!err); 367 368 err = xglWsiX11QueuePresent(demo->queue, &present, fence); 369 assert(!err); 370 371 demo->current_buffer = (demo->current_buffer + 1) % DEMO_BUFFER_COUNT; 372} 373 374static void demo_prepare_buffers(struct demo *demo) 375{ 376 const XGL_WSI_X11_PRESENTABLE_IMAGE_CREATE_INFO presentable_image = { 377 .format = demo->format, 378 .usage = XGL_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 379 .extent = { 380 .width = demo->width, 381 .height = demo->height, 382 }, 383 .flags = 0, 384 }; 385 const XGL_FENCE_CREATE_INFO fence = { 386 .sType = XGL_STRUCTURE_TYPE_FENCE_CREATE_INFO, 387 .pNext = NULL, 388 .flags = 0, 389 }; 390 XGL_RESULT err; 391 XGL_UINT i; 392 393 for (i = 0; i < DEMO_BUFFER_COUNT; i++) { 394 XGL_COLOR_ATTACHMENT_VIEW_CREATE_INFO color_attachment_view = { 395 .sType = XGL_STRUCTURE_TYPE_COLOR_ATTACHMENT_VIEW_CREATE_INFO, 396 .pNext = NULL, 397 .format = demo->format, 398 .mipLevel = 0, 399 .baseArraySlice = 0, 400 .arraySize = 1, 401 }; 402 403 err = xglWsiX11CreatePresentableImage(demo->device, &presentable_image, 404 &demo->buffers[i].image, &demo->buffers[i].mem); 405 assert(!err); 406 407 color_attachment_view.image = demo->buffers[i].image; 408 409 err = xglCreateColorAttachmentView(demo->device, 410 &color_attachment_view, &demo->buffers[i].view); 411 assert(!err); 412 413 err = xglCreateFence(demo->device, 414 &fence, &demo->buffers[i].fence); 415 assert(!err); 416 } 417} 418 419static void demo_prepare_depth(struct demo *demo) 420{ 421 const XGL_FORMAT depth_format = { XGL_CH_FMT_R16, XGL_NUM_FMT_DS }; 422 const XGL_IMAGE_CREATE_INFO image = { 423 .sType = XGL_STRUCTURE_TYPE_IMAGE_CREATE_INFO, 424 .pNext = NULL, 425 .imageType = XGL_IMAGE_2D, 426 .format = depth_format, 427 .extent = { demo->width, demo->height, 1 }, 428 .mipLevels = 1, 429 .arraySize = 1, 430 .samples = 1, 431 .tiling = XGL_OPTIMAL_TILING, 432 .usage = XGL_IMAGE_USAGE_DEPTH_STENCIL_BIT, 433 .flags = 0, 434 }; 435 XGL_MEMORY_ALLOC_INFO mem_alloc = { 436 .sType = XGL_STRUCTURE_TYPE_MEMORY_ALLOC_INFO, 437 .pNext = NULL, 438 .allocationSize = 0, 439 .alignment = 0, 440 .flags = 0, 441 .heapCount = 0, 442 .memPriority = XGL_MEMORY_PRIORITY_NORMAL, 443 }; 444 XGL_DEPTH_STENCIL_VIEW_CREATE_INFO view = { 445 .sType = XGL_STRUCTURE_TYPE_DEPTH_STENCIL_VIEW_CREATE_INFO, 446 .pNext = NULL, 447 .image = XGL_NULL_HANDLE, 448 .mipLevel = 0, 449 .baseArraySlice = 0, 450 .arraySize = 1, 451 .flags = 0, 452 }; 453 XGL_MEMORY_REQUIREMENTS mem_reqs; 454 XGL_SIZE mem_reqs_size = sizeof(XGL_MEMORY_REQUIREMENTS); 455 XGL_RESULT err; 456 457 demo->depth.format = depth_format; 458 459 /* create image */ 460 err = xglCreateImage(demo->device, &image, 461 &demo->depth.image); 462 assert(!err); 463 464 err = xglGetObjectInfo(demo->depth.image, 465 XGL_INFO_TYPE_MEMORY_REQUIREMENTS, 466 &mem_reqs_size, &mem_reqs); 467 assert(!err && mem_reqs_size == sizeof(mem_reqs)); 468 469 mem_alloc.allocationSize = mem_reqs.size; 470 mem_alloc.alignment = mem_reqs.alignment; 471 mem_alloc.heapCount = mem_reqs.heapCount; 472 memcpy(mem_alloc.heaps, mem_reqs.heaps, 473 sizeof(mem_reqs.heaps[0]) * mem_reqs.heapCount); 474 475 /* allocate memory */ 476 err = xglAllocMemory(demo->device, &mem_alloc, 477 &demo->depth.mem); 478 assert(!err); 479 480 /* bind memory */ 481 err = xglBindObjectMemory(demo->depth.image, 482 demo->depth.mem, 0); 483 assert(!err); 484 485 /* create image view */ 486 view.image = demo->depth.image; 487 err = xglCreateDepthStencilView(demo->device, &view, 488 &demo->depth.view); 489 assert(!err); 490} 491 492/** loadTexture 493 * loads a png file into an memory object, using cstdio , libpng. 494 * 495 * \param demo : Needed to access XGL calls 496 * \param filename : the png file to be loaded 497 * \param width : width of png, to be updated as a side effect of this function 498 * \param height : height of png, to be updated as a side effect of this function 499 * 500 * \return bool : an opengl texture id. true if successful?, 501 * should be validated by the client of this function. 502 * 503 * Source: http://en.wikibooks.org/wiki/OpenGL_Programming/Intermediate/Textures 504 * Modified to copy image to memory 505 * 506 */ 507bool loadTexture(char *filename, XGL_UINT8 *rgba_data, 508 XGL_SUBRESOURCE_LAYOUT *layout, 509 XGL_INT *width, XGL_INT *height) 510{ 511 //header for testing if it is a png 512 png_byte header[8]; 513 int i, is_png, bit_depth, color_type,rowbytes; 514 png_uint_32 twidth, theight; 515 png_structp png_ptr; 516 png_infop info_ptr, end_info; 517 png_byte *image_data; 518 png_bytep *row_pointers; 519 520 //open file as binary 521 FILE *fp = fopen(filename, "rb"); 522 if (!fp) { 523 return false; 524 } 525 526 //read the header 527 fread(header, 1, 8, fp); 528 529 //test if png 530 is_png = !png_sig_cmp(header, 0, 8); 531 if (!is_png) { 532 fclose(fp); 533 return false; 534 } 535 536 //create png struct 537 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, 538 NULL, NULL); 539 if (!png_ptr) { 540 fclose(fp); 541 return (false); 542 } 543 544 //create png info struct 545 info_ptr = png_create_info_struct(png_ptr); 546 if (!info_ptr) { 547 png_destroy_read_struct(&png_ptr, (png_infopp) NULL, (png_infopp) NULL); 548 fclose(fp); 549 return (false); 550 } 551 552 //create png info struct 553 end_info = png_create_info_struct(png_ptr); 554 if (!end_info) { 555 png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL); 556 fclose(fp); 557 return (false); 558 } 559 560 //png error stuff, not sure libpng man suggests this. 561 if (setjmp(png_jmpbuf(png_ptr))) { 562 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); 563 fclose(fp); 564 return (false); 565 } 566 567 //init png reading 568 png_init_io(png_ptr, fp); 569 570 //let libpng know you already read the first 8 bytes 571 png_set_sig_bytes(png_ptr, 8); 572 573 // read all the info up to the image data 574 png_read_info(png_ptr, info_ptr); 575 576 // get info about png 577 png_get_IHDR(png_ptr, info_ptr, &twidth, &theight, &bit_depth, &color_type, 578 NULL, NULL, NULL); 579 580 //update width and height based on png info 581 *width = twidth; 582 *height = theight; 583 584 // Require that incoming texture be 8bits per color component 585 // and 4 components (RGBA). 586 if (png_get_bit_depth(png_ptr, info_ptr) != 8 || 587 png_get_channels(png_ptr, info_ptr) != 4) { 588 return false; 589 } 590 591 if (rgba_data == NULL) { 592 // If data pointer is null, we just want the width & height 593 // clean up memory and close stuff 594 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); 595 fclose(fp); 596 597 return true; 598 } 599 600 // Update the png info struct. 601 png_read_update_info(png_ptr, info_ptr); 602 603 // Row size in bytes. 604 rowbytes = png_get_rowbytes(png_ptr, info_ptr); 605 606 // Allocate the image_data as a big block, to be given to opengl 607 image_data = (png_byte *)malloc(rowbytes * theight * sizeof(png_byte)); 608 if (!image_data) { 609 //clean up memory and close stuff 610 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); 611 fclose(fp); 612 return false; 613 } 614 615 // row_pointers is for pointing to image_data for reading the png with libpng 616 row_pointers = (png_bytep *)malloc(theight * sizeof(png_bytep)); 617 if (!row_pointers) { 618 //clean up memory and close stuff 619 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); 620 // delete[] image_data; 621 fclose(fp); 622 return false; 623 } 624 // set the individual row_pointers to point at the correct offsets of image_data 625 for (i = 0; i < theight; ++i) 626 row_pointers[theight - 1 - i] = rgba_data + i * rowbytes; 627 628 // read the png into image_data through row_pointers 629 png_read_image(png_ptr, row_pointers); 630 631 // clean up memory and close stuff 632 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); 633 free(row_pointers); 634 free(image_data); 635 fclose(fp); 636 637 return true; 638} 639 640static void demo_prepare_textures(struct demo *demo) 641{ 642 const XGL_FORMAT tex_format = { XGL_CH_FMT_R8G8B8A8, XGL_NUM_FMT_UNORM }; 643 XGL_INT tex_width; 644 XGL_INT tex_height; 645 XGL_RESULT err; 646 XGL_UINT i; 647 648 for (i = 0; i < DEMO_TEXTURE_COUNT; i++) { 649 const XGL_SAMPLER_CREATE_INFO sampler = { 650 .sType = XGL_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, 651 .pNext = NULL, 652 .magFilter = XGL_TEX_FILTER_NEAREST, 653 .minFilter = XGL_TEX_FILTER_NEAREST, 654 .mipMode = XGL_TEX_MIPMAP_BASE, 655 .addressU = XGL_TEX_ADDRESS_CLAMP, 656 .addressV = XGL_TEX_ADDRESS_CLAMP, 657 .addressW = XGL_TEX_ADDRESS_CLAMP, 658 .mipLodBias = 0.0f, 659 .maxAnisotropy = 0, 660 .compareFunc = XGL_COMPARE_NEVER, 661 .minLod = 0.0f, 662 .maxLod = 0.0f, 663 .borderColorType = XGL_BORDER_COLOR_OPAQUE_WHITE, 664 }; 665 666 assert(loadTexture(tex_files[i], NULL, NULL, &tex_width, &tex_height)); 667 668 const XGL_IMAGE_CREATE_INFO image = { 669 .sType = XGL_STRUCTURE_TYPE_IMAGE_CREATE_INFO, 670 .pNext = NULL, 671 .imageType = XGL_IMAGE_2D, 672 .format = tex_format, 673 .extent = { tex_width, tex_height, 1 }, 674 .mipLevels = 1, 675 .arraySize = 1, 676 .samples = 1, 677 .tiling = XGL_LINEAR_TILING, 678 .usage = XGL_IMAGE_USAGE_SHADER_ACCESS_READ_BIT, 679 .flags = 0, 680 }; 681 XGL_MEMORY_ALLOC_INFO mem_alloc = { 682 .sType = XGL_STRUCTURE_TYPE_MEMORY_ALLOC_INFO, 683 .pNext = NULL, 684 .allocationSize = 0, 685 .alignment = 0, 686 .flags = 0, 687 .heapCount = 0, 688 .memPriority = XGL_MEMORY_PRIORITY_NORMAL, 689 }; 690 XGL_IMAGE_VIEW_CREATE_INFO view = { 691 .sType = XGL_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, 692 .pNext = NULL, 693 .image = XGL_NULL_HANDLE, 694 .viewType = XGL_IMAGE_VIEW_2D, 695 .format = image.format, 696 .channels = { XGL_CHANNEL_SWIZZLE_R, 697 XGL_CHANNEL_SWIZZLE_G, 698 XGL_CHANNEL_SWIZZLE_B, 699 XGL_CHANNEL_SWIZZLE_A, }, 700 .subresourceRange = { XGL_IMAGE_ASPECT_COLOR, 0, 1, 0, 1 }, 701 .minLod = 0.0f, 702 }; 703 XGL_MEMORY_REQUIREMENTS mem_reqs; 704 XGL_SIZE mem_reqs_size = sizeof(XGL_MEMORY_REQUIREMENTS); 705 706 /* create sampler */ 707 err = xglCreateSampler(demo->device, &sampler, 708 &demo->textures[i].sampler); 709 assert(!err); 710 711 /* create image */ 712 err = xglCreateImage(demo->device, &image, 713 &demo->textures[i].image); 714 assert(!err); 715 716 err = xglGetObjectInfo(demo->textures[i].image, 717 XGL_INFO_TYPE_MEMORY_REQUIREMENTS, 718 &mem_reqs_size, &mem_reqs); 719 assert(!err && mem_reqs_size == sizeof(mem_reqs)); 720 721 mem_alloc.allocationSize = mem_reqs.size; 722 mem_alloc.alignment = mem_reqs.alignment; 723 mem_alloc.heapCount = mem_reqs.heapCount; 724 memcpy(mem_alloc.heaps, mem_reqs.heaps, 725 sizeof(mem_reqs.heaps[0]) * mem_reqs.heapCount); 726 727 /* allocate memory */ 728 err = xglAllocMemory(demo->device, &mem_alloc, 729 &demo->textures[i].mem); 730 assert(!err); 731 732 /* bind memory */ 733 err = xglBindObjectMemory(demo->textures[i].image, 734 demo->textures[i].mem, 0); 735 assert(!err); 736 737 /* create image view */ 738 view.image = demo->textures[i].image; 739 err = xglCreateImageView(demo->device, &view, 740 &demo->textures[i].view); 741 assert(!err); 742 } 743 744 for (i = 0; i < DEMO_TEXTURE_COUNT; i++) { 745 const XGL_IMAGE_SUBRESOURCE subres = { 746 .aspect = XGL_IMAGE_ASPECT_COLOR, 747 .mipLevel = 0, 748 .arraySlice = 0, 749 }; 750 XGL_SUBRESOURCE_LAYOUT layout; 751 XGL_SIZE layout_size; 752 XGL_VOID *data; 753 754 err = xglGetImageSubresourceInfo(demo->textures[i].image, &subres, 755 XGL_INFO_TYPE_SUBRESOURCE_LAYOUT, &layout_size, &layout); 756 assert(!err && layout_size == sizeof(layout)); 757 758 err = xglMapMemory(demo->textures[i].mem, 0, &data); 759 assert(!err); 760 761 loadTexture(tex_files[i], data, &layout, &tex_width, &tex_height); 762 763 err = xglUnmapMemory(demo->textures[i].mem); 764 assert(!err); 765 } 766} 767 768void demo_prepare_cube_data_buffer(struct demo *demo) 769{ 770 XGL_MEMORY_ALLOC_INFO alloc_info; 771 XGL_UINT8 *pData; 772 int i; 773 mat4x4 MVP, VP; 774 XGL_RESULT err; 775 struct xgltexcube_vs_uniform data; 776 777 mat4x4_mul(VP, demo->projection_matrix, demo->view_matrix); 778 mat4x4_mul(MVP, VP, demo->model_matrix); 779 memcpy(data.mvp, MVP, sizeof(MVP)); 780// dumpMatrix("MVP", MVP); 781 782 for (i=0; i<12*3; i++) { 783 data.position[i][0] = g_vertex_buffer_data[i*3]; 784 data.position[i][1] = g_vertex_buffer_data[i*3+1]; 785 data.position[i][2] = g_vertex_buffer_data[i*3+2]; 786 data.position[i][3] = 1.0f; 787 data.attr[i][0] = g_uv_buffer_data[2*i]; 788 data.attr[i][1] = g_uv_buffer_data[2*i + 1]; 789 data.attr[i][2] = 0; 790 data.attr[i][3] = 0; 791 } 792 793 memset(&alloc_info, 0, sizeof(alloc_info)); 794 alloc_info.sType = XGL_STRUCTURE_TYPE_MEMORY_ALLOC_INFO; 795 alloc_info.allocationSize = sizeof(data); 796 alloc_info.alignment = 0; 797 alloc_info.heapCount = 1; 798 alloc_info.heaps[0] = 0; // TODO: Use known existing heap 799 800 alloc_info.flags = XGL_MEMORY_HEAP_CPU_VISIBLE_BIT; 801 alloc_info.memPriority = XGL_MEMORY_PRIORITY_NORMAL; 802 803 err = xglAllocMemory(demo->device, &alloc_info, &demo->uniform_data.mem); 804 assert(!err); 805 806 err = xglMapMemory(demo->uniform_data.mem, 0, (XGL_VOID **) &pData); 807 assert(!err); 808 809 memcpy(pData, &data, alloc_info.allocationSize); 810 811 err = xglUnmapMemory(demo->uniform_data.mem); 812 assert(!err); 813 814 // set up the memory view for the constant buffer 815 demo->uniform_data.view.sType = XGL_STRUCTURE_TYPE_MEMORY_VIEW_ATTACH_INFO; 816 demo->uniform_data.view.stride = 16; 817 demo->uniform_data.view.range = alloc_info.allocationSize; 818 demo->uniform_data.view.offset = 0; 819 demo->uniform_data.view.mem = demo->uniform_data.mem; 820 demo->uniform_data.view.format.channelFormat = XGL_CH_FMT_R32G32B32A32; 821 demo->uniform_data.view.format.numericFormat = XGL_NUM_FMT_FLOAT; 822} 823 824static void demo_prepare_descriptor_set(struct demo *demo) 825{ 826 const XGL_DESCRIPTOR_SET_CREATE_INFO descriptor_set = { 827 .sType = XGL_STRUCTURE_TYPE_DESCRIPTOR_SET_CREATE_INFO, 828 .pNext = NULL, 829 .slots = DEMO_TEXTURE_COUNT * 2 + 2, 830 }; 831 XGL_RESULT err; 832 833 err = xglCreateDescriptorSet(demo->device, &descriptor_set, &demo->dset); 834 assert(!err); 835 836 xglBeginDescriptorSetUpdate(demo->dset); 837 xglClearDescriptorSetSlots(demo->dset, 0, DEMO_TEXTURE_COUNT * 2 + 2); 838 839// xglAttachMemoryViewDescriptors(demo->dset, 0, 1, &demo->vertices.view); 840 841 xglAttachMemoryViewDescriptors(demo->dset, 0, 1, &demo->uniform_data.view); 842 843 XGL_IMAGE_VIEW_ATTACH_INFO image_view; 844 845 image_view.sType = XGL_STRUCTURE_TYPE_IMAGE_VIEW_ATTACH_INFO; 846 image_view.pNext = NULL; 847 image_view.view = demo->textures[0].view; 848 image_view.state = XGL_IMAGE_STATE_GRAPHICS_SHADER_READ_ONLY; 849 850 xglAttachSamplerDescriptors(demo->dset, 1, 1, &demo->textures[0].sampler); 851 xglAttachImageViewDescriptors(demo->dset, 2, 1, &image_view); 852 853 xglEndDescriptorSetUpdate(demo->dset); 854} 855 856static XGL_SHADER demo_prepare_shader(struct demo *demo, 857 XGL_PIPELINE_SHADER_STAGE stage, 858 const void *code, 859 XGL_SIZE size) 860{ 861 XGL_SHADER_CREATE_INFO createInfo; 862 XGL_SHADER shader; 863 XGL_RESULT err; 864 865 866 createInfo.sType = XGL_STRUCTURE_TYPE_SHADER_CREATE_INFO; 867 createInfo.pNext = NULL; 868 869#ifdef EXTERNAL_BIL 870 createInfo.codeSize = size; 871 createInfo.pCode = code; 872 createInfo.flags = 0; 873 874 err = xglCreateShader(demo->device, &createInfo, &shader); 875 if (err) { 876 free((void *) createInfo.pCode); 877 } 878#else 879 // Create fake BIL structure to feed GLSL 880 // to the driver "under the covers" 881 createInfo.codeSize = 3 * sizeof(uint32_t) + size + 1; 882 createInfo.pCode = malloc(createInfo.codeSize); 883 createInfo.flags = 0; 884 885 /* try version 0 first: XGL_PIPELINE_SHADER_STAGE followed by GLSL */ 886 ((uint32_t *) createInfo.pCode)[0] = ICD_BIL_MAGIC; 887 ((uint32_t *) createInfo.pCode)[1] = 0; 888 ((uint32_t *) createInfo.pCode)[2] = stage; 889 memcpy(((uint32_t *) createInfo.pCode + 3), code, size + 1); 890 891 err = xglCreateShader(demo->device, &createInfo, &shader); 892 if (err) { 893 free((void *) createInfo.pCode); 894 return NULL; 895 } 896#endif 897 898 return shader; 899} 900 901char *demo_read_bil(const char *filename, XGL_SIZE *psize) 902{ 903 long int size; 904 void *shader_code; 905 906 FILE *fp = fopen(filename, "rb"); 907 if (!fp) return NULL; 908 909 fseek(fp, 0L, SEEK_END); 910 size = ftell(fp); 911 912 fseek(fp, 0L, SEEK_SET); 913 914 shader_code = malloc(size); 915 fread(shader_code, size, 1, fp); 916 917 *psize = size; 918 919 return shader_code; 920} 921 922static XGL_SHADER demo_prepare_vs(struct demo *demo) 923{ 924#ifdef EXTERNAL_BIL 925 void *vertShaderCode; 926 XGL_SIZE size; 927 928 vertShaderCode = demo_read_bil("cube-vert.bil", &size); 929 930 return demo_prepare_shader(demo, XGL_SHADER_STAGE_VERTEX, 931 vertShaderCode, size); 932#else 933 static const char *vertShaderText = 934 "#version 140\n" 935 "#extension GL_ARB_separate_shader_objects : enable\n" 936 "#extension GL_ARB_shading_language_420pack : enable\n" 937 "\n" 938 "layout(binding = 0) uniform buf {\n" 939 " mat4 MVP;\n" 940 " vec4 position[12*3];\n" 941 " vec4 attr[12*3];\n" 942 "} ubuf;\n" 943 "\n" 944 "layout (location = 0) out vec4 texcoord;\n" 945 "\n" 946 "void main() \n" 947 "{\n" 948 " texcoord = ubuf.attr[gl_VertexID];\n" 949 " gl_Position = ubuf.MVP * ubuf.position[gl_VertexID];\n" 950 "}\n"; 951 952 return demo_prepare_shader(demo, XGL_SHADER_STAGE_VERTEX, 953 (const void *) vertShaderText, 954 strlen(vertShaderText)); 955#endif 956} 957 958static XGL_SHADER demo_prepare_fs(struct demo *demo) 959{ 960#ifdef EXTERNAL_BIL 961 void *fragShaderCode; 962 XGL_SIZE size; 963 964 fragShaderCode = demo_read_bil("cube-frag.bil", &size); 965 966 return demo_prepare_shader(demo, XGL_SHADER_STAGE_FRAGMENT, 967 fragShaderCode, size); 968#else 969 static const char *fragShaderText = 970 "#version 140\n" 971 "#extension GL_ARB_separate_shader_objects : enable\n" 972 "#extension GL_ARB_shading_language_420pack : enable\n" 973 "layout (binding = 0) uniform sampler2D tex;\n" 974 "\n" 975 "layout (location = 0) in vec4 texcoord;\n" 976 "void main() {\n" 977 " gl_FragColor = texture(tex, texcoord.xy);\n" 978 "}\n"; 979 980 return demo_prepare_shader(demo, XGL_SHADER_STAGE_FRAGMENT, 981 (const void *) fragShaderText, 982 strlen(fragShaderText)); 983#endif 984} 985 986static void demo_prepare_pipeline(struct demo *demo) 987{ 988 XGL_GRAPHICS_PIPELINE_CREATE_INFO pipeline; 989 XGL_PIPELINE_IA_STATE_CREATE_INFO ia; 990 XGL_PIPELINE_RS_STATE_CREATE_INFO rs; 991 XGL_PIPELINE_CB_STATE cb; 992 XGL_PIPELINE_DB_STATE_CREATE_INFO db; 993 XGL_PIPELINE_SHADER_STAGE_CREATE_INFO vs; 994 XGL_PIPELINE_SHADER_STAGE_CREATE_INFO fs; 995 XGL_DESCRIPTOR_SLOT_INFO vs_slots[3]; 996 XGL_DESCRIPTOR_SLOT_INFO fs_slots[3]; 997 XGL_RESULT err; 998 999 memset(&pipeline, 0, sizeof(pipeline)); 1000 pipeline.sType = XGL_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; 1001 1002 memset(&ia, 0, sizeof(ia)); 1003 ia.sType = XGL_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO; 1004 ia.topology = XGL_TOPOLOGY_TRIANGLE_LIST; 1005 1006 memset(&rs, 0, sizeof(rs)); 1007 rs.sType = XGL_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO; 1008 1009 memset(&cb, 0, sizeof(cb)); 1010 cb.sType = XGL_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO; 1011 cb.attachment[0].format = demo->format; 1012 cb.attachment[0].channelWriteMask = 0xf; 1013 1014 memset(&db, 0, sizeof(db)); 1015 db.sType = XGL_STRUCTURE_TYPE_PIPELINE_DB_STATE_CREATE_INFO; 1016 db.format = demo->depth.format; 1017 1018 memset(&vs_slots, 0, sizeof(vs_slots)); 1019 vs_slots[0].slotObjectType = XGL_SLOT_SHADER_RESOURCE; 1020 vs_slots[0].shaderEntityIndex = 0; 1021 1022 memset(&fs_slots, 0, sizeof(fs_slots)); 1023 fs_slots[1].slotObjectType = XGL_SLOT_SHADER_SAMPLER; 1024 fs_slots[1].shaderEntityIndex = 0; 1025 fs_slots[2].slotObjectType = XGL_SLOT_SHADER_TEXTURE_RESOURCE; 1026 fs_slots[2].shaderEntityIndex = 0; 1027 1028 memset(&vs, 0, sizeof(vs)); 1029 vs.sType = XGL_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; 1030 vs.shader.stage = XGL_SHADER_STAGE_VERTEX; 1031 vs.shader.shader = demo_prepare_vs(demo); 1032 assert(vs.shader.shader != NULL); 1033 vs.shader.descriptorSetMapping[0].descriptorCount = 3; 1034 vs.shader.descriptorSetMapping[0].pDescriptorInfo = vs_slots; 1035 1036 memset(&fs, 0, sizeof(fs)); 1037 fs.sType = XGL_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; 1038 fs.shader.stage = XGL_SHADER_STAGE_FRAGMENT; 1039 fs.shader.shader = demo_prepare_fs(demo); 1040 assert(fs.shader.shader != NULL); 1041 fs.shader.descriptorSetMapping[0].descriptorCount = 3; 1042 fs.shader.descriptorSetMapping[0].pDescriptorInfo = fs_slots; 1043 1044 pipeline.pNext = (const XGL_VOID *) &ia; 1045 ia.pNext = (const XGL_VOID *) &rs; 1046 rs.pNext = (const XGL_VOID *) &cb; 1047 cb.pNext = (const XGL_VOID *) &db; 1048 db.pNext = (const XGL_VOID *) &vs; 1049 vs.pNext = (const XGL_VOID *) &fs; 1050 1051 err = xglCreateGraphicsPipeline(demo->device, &pipeline, &demo->pipeline); 1052 assert(!err); 1053 1054 xglDestroyObject(vs.shader.shader); 1055 xglDestroyObject(fs.shader.shader); 1056} 1057 1058static void demo_prepare_dynamic_states(struct demo *demo) 1059{ 1060 XGL_VIEWPORT_STATE_CREATE_INFO viewport; 1061 XGL_RASTER_STATE_CREATE_INFO raster; 1062 XGL_MSAA_STATE_CREATE_INFO msaa; 1063 XGL_COLOR_BLEND_STATE_CREATE_INFO color_blend; 1064 XGL_DEPTH_STENCIL_STATE_CREATE_INFO depth_stencil; 1065 XGL_RESULT err; 1066 1067 memset(&viewport, 0, sizeof(viewport)); 1068 viewport.viewportCount = 1; 1069 viewport.scissorEnable = XGL_FALSE; 1070 viewport.viewports[0].width = (XGL_FLOAT) demo->width; 1071 viewport.viewports[0].height = (XGL_FLOAT) demo->height; 1072 viewport.viewports[0].minDepth = (XGL_FLOAT) 0.0f; 1073 viewport.viewports[0].maxDepth = (XGL_FLOAT) 1.0f; 1074 1075 memset(&raster, 0, sizeof(raster)); 1076 raster.sType = XGL_STRUCTURE_TYPE_RASTER_STATE_CREATE_INFO; 1077 raster.fillMode = XGL_FILL_SOLID; 1078 raster.cullMode = XGL_CULL_NONE; 1079 raster.frontFace = XGL_FRONT_FACE_CCW; 1080 1081 memset(&msaa, 0, sizeof(msaa)); 1082 msaa.sType = XGL_STRUCTURE_TYPE_MSAA_STATE_CREATE_INFO; 1083 msaa.samples = 1; 1084 msaa.sampleMask = 0x1; 1085 1086 memset(&color_blend, 0, sizeof(color_blend)); 1087 color_blend.sType = XGL_STRUCTURE_TYPE_COLOR_BLEND_STATE_CREATE_INFO; 1088 1089 memset(&depth_stencil, 0, sizeof(depth_stencil)); 1090 depth_stencil.sType = XGL_STRUCTURE_TYPE_DEPTH_STENCIL_STATE_CREATE_INFO; 1091 depth_stencil.depthTestEnable = XGL_TRUE; 1092 depth_stencil.depthWriteEnable = XGL_TRUE; 1093 depth_stencil.depthFunc = XGL_COMPARE_LESS_EQUAL; 1094 depth_stencil.depthBoundsEnable = XGL_FALSE; 1095 1096 err = xglCreateViewportState(demo->device, &viewport, &demo->viewport); 1097 assert(!err); 1098 1099 err = xglCreateRasterState(demo->device, &raster, &demo->raster); 1100 assert(!err); 1101 1102 err = xglCreateMsaaState(demo->device, &msaa, &demo->msaa); 1103 assert(!err); 1104 1105 err = xglCreateColorBlendState(demo->device, 1106 &color_blend, &demo->color_blend); 1107 assert(!err); 1108 1109 err = xglCreateDepthStencilState(demo->device, 1110 &depth_stencil, &demo->depth_stencil); 1111 assert(!err); 1112} 1113 1114static void demo_prepare(struct demo *demo) 1115{ 1116 const XGL_CMD_BUFFER_CREATE_INFO cmd = { 1117 .sType = XGL_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO, 1118 .pNext = NULL, 1119 .queueType = XGL_QUEUE_TYPE_GRAPHICS, 1120 .flags = 0, 1121 }; 1122 XGL_RESULT err; 1123 1124 demo_prepare_buffers(demo); 1125 demo_prepare_depth(demo); 1126 demo_prepare_textures(demo); 1127 demo_prepare_cube_data_buffer(demo); 1128 demo_prepare_descriptor_set(demo); 1129 1130 demo_prepare_pipeline(demo); 1131 demo_prepare_dynamic_states(demo); 1132 1133 err = xglCreateCommandBuffer(demo->device, &cmd, &demo->cmd); 1134 assert(!err); 1135} 1136 1137static void demo_handle_event(struct demo *demo, 1138 const xcb_generic_event_t *event) 1139{ 1140 u_int8_t event_code = event->response_type & 0x7f; 1141 switch (event_code) { 1142 case XCB_EXPOSE: 1143 // TODO: Resize window 1144 break; 1145 case XCB_CLIENT_MESSAGE: 1146 if((*(xcb_client_message_event_t*)event).data.data32[0] == 1147 (*demo->atom_wm_delete_window).atom) { 1148 demo->quit = true; 1149 } 1150 break; 1151 case XCB_KEY_RELEASE: 1152 { 1153 const xcb_key_release_event_t *key = 1154 (const xcb_key_release_event_t *) event; 1155 1156 switch (key->detail) { 1157 case 0x9: // Escape 1158 demo->quit = true; 1159 break; 1160 case 0x71: // left arrow key 1161 demo->spin_angle += demo->spin_increment; 1162 break; 1163 case 0x72: // right arrow key 1164 demo->spin_angle -= demo->spin_increment; 1165 break; 1166 case 0x41: 1167 demo->pause = !demo->pause; 1168 break; 1169 } 1170 } 1171 break; 1172 default: 1173 break; 1174 } 1175} 1176 1177static void demo_run(struct demo *demo) 1178{ 1179 xcb_flush(demo->connection); 1180 1181 while (!demo->quit) { 1182 xcb_generic_event_t *event; 1183 1184 if (demo->pause) { 1185 event = xcb_wait_for_event(demo->connection); 1186 } else { 1187 event = xcb_poll_for_event(demo->connection); 1188 } 1189 if (event) { 1190 demo_handle_event(demo, event); 1191 free(event); 1192 } 1193 1194 // Wait for work to finish before updating MVP. 1195 xglDeviceWaitIdle(demo->device); 1196 demo_update_data_buffer(demo); 1197 1198 demo_draw(demo); 1199 1200 // Wait for work to finish before updating MVP. 1201 xglDeviceWaitIdle(demo->device); 1202 } 1203} 1204 1205static void demo_create_window(struct demo *demo) 1206{ 1207 uint32_t value_mask, value_list[32]; 1208 1209 demo->window = xcb_generate_id(demo->connection); 1210 1211 value_mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK; 1212 value_list[0] = demo->screen->black_pixel; 1213 value_list[1] = XCB_EVENT_MASK_KEY_RELEASE | 1214 XCB_EVENT_MASK_EXPOSURE; 1215 1216 xcb_create_window(demo->connection, 1217 XCB_COPY_FROM_PARENT, 1218 demo->window, demo->screen->root, 1219 0, 0, demo->width, demo->height, 0, 1220 XCB_WINDOW_CLASS_INPUT_OUTPUT, 1221 demo->screen->root_visual, 1222 value_mask, value_list); 1223 1224 /* Magic code that will send notification when window is destroyed */ 1225 xcb_intern_atom_cookie_t cookie = xcb_intern_atom(demo->connection, 1, 12, 1226 "WM_PROTOCOLS"); 1227 xcb_intern_atom_reply_t* reply = xcb_intern_atom_reply(demo->connection, cookie, 0); 1228 1229 xcb_intern_atom_cookie_t cookie2 = xcb_intern_atom(demo->connection, 0, 16, "WM_DELETE_WINDOW"); 1230 demo->atom_wm_delete_window = xcb_intern_atom_reply(demo->connection, cookie2, 0); 1231 1232 xcb_change_property(demo->connection, XCB_PROP_MODE_REPLACE, 1233 demo->window, (*reply).atom, 4, 32, 1, 1234 &(*demo->atom_wm_delete_window).atom); 1235 free(reply); 1236 1237 xcb_map_window(demo->connection, demo->window); 1238} 1239 1240static void demo_init_xgl(struct demo *demo) 1241{ 1242 const XGL_APPLICATION_INFO app = { 1243 .sType = XGL_STRUCTURE_TYPE_APPLICATION_INFO, 1244 .pNext = NULL, 1245 .pAppName = "cube", 1246 .appVersion = 0, 1247 .pEngineName = "cube", 1248 .engineVersion = 0, 1249 .apiVersion = XGL_MAKE_VERSION(0, 22, 0), 1250 }; 1251 const XGL_WSI_X11_CONNECTION_INFO connection = { 1252 .pConnection = demo->connection, 1253 .root = demo->screen->root, 1254 .provider = 0, 1255 }; 1256 const XGL_DEVICE_QUEUE_CREATE_INFO queue = { 1257 .queueNodeIndex = 0, 1258 .queueCount = 1, 1259 }; 1260 const XGL_CHAR *ext_names[] = { 1261 "XGL_WSI_X11", 1262 }; 1263 const XGL_DEVICE_CREATE_INFO device = { 1264 .sType = XGL_STRUCTURE_TYPE_DEVICE_CREATE_INFO, 1265 .pNext = NULL, 1266 .queueRecordCount = 1, 1267 .pRequestedQueues = &queue, 1268 .extensionCount = 1, 1269 .ppEnabledExtensionNames = ext_names, 1270 .maxValidationLevel = XGL_VALIDATION_LEVEL_END_RANGE, 1271 .flags = XGL_DEVICE_CREATE_VALIDATION_BIT, 1272 }; 1273 XGL_RESULT err; 1274 XGL_UINT gpu_count; 1275 XGL_UINT i; 1276 1277 err = xglInitAndEnumerateGpus(&app, NULL, 1, &gpu_count, &demo->gpu); 1278 assert(!err && gpu_count == 1); 1279 1280 for (i = 0; i < device.extensionCount; i++) { 1281 err = xglGetExtensionSupport(demo->gpu, ext_names[i]); 1282 assert(!err); 1283 } 1284 1285 err = xglWsiX11AssociateConnection(demo->gpu, &connection); 1286 assert(!err); 1287 1288 err = xglCreateDevice(demo->gpu, &device, &demo->device); 1289 assert(!err); 1290 1291 err = xglGetDeviceQueue(demo->device, XGL_QUEUE_TYPE_GRAPHICS, 1292 0, &demo->queue); 1293 assert(!err); 1294} 1295 1296static void demo_init_connection(struct demo *demo) 1297{ 1298 const xcb_setup_t *setup; 1299 xcb_screen_iterator_t iter; 1300 int scr; 1301 1302 demo->connection = xcb_connect(NULL, &scr); 1303 1304 setup = xcb_get_setup(demo->connection); 1305 iter = xcb_setup_roots_iterator(setup); 1306 while (scr-- > 0) 1307 xcb_screen_next(&iter); 1308 1309 demo->screen = iter.data; 1310} 1311 1312static void demo_init(struct demo *demo) 1313{ 1314 vec3 eye = {0.0f, 3.0f, 5.0f}; 1315 vec3 origin = {0, 0, 0}; 1316 vec3 up = {0.0f, -1.0f, 0.0}; 1317 1318 memset(demo, 0, sizeof(*demo)); 1319 1320 demo_init_connection(demo); 1321 demo_init_xgl(demo); 1322 1323 demo->width = 500; 1324 demo->height = 500; 1325 demo->format.channelFormat = XGL_CH_FMT_B8G8R8A8; 1326 demo->format.numericFormat = XGL_NUM_FMT_UNORM; 1327 1328 demo->spin_angle = 0.01f; 1329 demo->spin_increment = 0.01f; 1330 demo->pause = false; 1331 1332 mat4x4_perspective(demo->projection_matrix, degreesToRadians(45.0f), 1.0f, 0.1f, 100.0f); 1333 mat4x4_look_at(demo->view_matrix, eye, origin, up); 1334 mat4x4_identity(demo->model_matrix); 1335} 1336 1337static void demo_cleanup(struct demo *demo) 1338{ 1339 XGL_UINT i; 1340 1341 xglDestroyObject(demo->cmd); 1342 1343 xglDestroyObject(demo->viewport); 1344 xglDestroyObject(demo->raster); 1345 xglDestroyObject(demo->msaa); 1346 xglDestroyObject(demo->color_blend); 1347 xglDestroyObject(demo->depth_stencil); 1348 1349 xglDestroyObject(demo->pipeline); 1350 1351 xglDestroyObject(demo->dset); 1352 1353// xglFreeMemory(demo->vertices.mem); 1354 1355 for (i = 0; i < DEMO_TEXTURE_COUNT; i++) { 1356 xglDestroyObject(demo->textures[i].view); 1357 xglDestroyObject(demo->textures[i].image); 1358 xglFreeMemory(demo->textures[i].mem); 1359 xglDestroyObject(demo->textures[i].sampler); 1360 } 1361 1362 xglDestroyObject(demo->depth.view); 1363 xglDestroyObject(demo->depth.image); 1364 xglFreeMemory(demo->depth.mem); 1365 1366 for (i = 0; i < DEMO_BUFFER_COUNT; i++) { 1367 xglDestroyObject(demo->buffers[i].fence); 1368 xglDestroyObject(demo->buffers[i].view); 1369 xglDestroyObject(demo->buffers[i].image); 1370 } 1371 1372 xglDestroyDevice(demo->device); 1373 1374 xcb_destroy_window(demo->connection, demo->window); 1375 xcb_disconnect(demo->connection); 1376} 1377 1378int main(void) 1379{ 1380 struct demo demo; 1381 1382 demo_init(&demo); 1383 1384 demo_prepare(&demo); 1385 demo_create_window(&demo); 1386 demo_run(&demo); 1387 1388 demo_cleanup(&demo); 1389 1390 return 0; 1391} 1392