cube.c revision 71fcc2dae2f302fd2e52836b4098b233762d56f8
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_UINT num_mem; 216 XGL_GPU_MEMORY *mem; 217 XGL_DEPTH_STENCIL_VIEW view; 218 } depth; 219 220 struct { 221 XGL_SAMPLER sampler; 222 223 char *filename; 224 XGL_IMAGE image; 225 XGL_UINT num_mem; 226 XGL_GPU_MEMORY *mem; 227 XGL_IMAGE_VIEW view; 228 } textures[DEMO_TEXTURE_COUNT]; 229 230 struct { 231 XGL_BUFFER buf; 232 XGL_UINT num_mem; 233 XGL_GPU_MEMORY *mem; 234 XGL_BUFFER_VIEW view; 235 XGL_BUFFER_VIEW_ATTACH_INFO attach; 236 } uniform_data; 237 238 XGL_DESCRIPTOR_SET_LAYOUT desc_layout_vs; 239 XGL_DESCRIPTOR_SET_LAYOUT desc_layout_fs; 240 XGL_DESCRIPTOR_SET_LAYOUT *desc_layout_last; 241 XGL_PIPELINE pipeline; 242 243 XGL_DYNAMIC_VP_STATE_OBJECT viewport; 244 XGL_DYNAMIC_RS_STATE_OBJECT raster; 245 XGL_DYNAMIC_CB_STATE_OBJECT color_blend; 246 XGL_DYNAMIC_DS_STATE_OBJECT depth_stencil; 247 248 mat4x4 projection_matrix; 249 mat4x4 view_matrix; 250 mat4x4 model_matrix; 251 252 XGL_FLOAT spin_angle; 253 XGL_FLOAT spin_increment; 254 bool pause; 255 256 XGL_CMD_BUFFER cmd; 257 258 XGL_DESCRIPTOR_REGION desc_region; 259 XGL_DESCRIPTOR_SET desc_set; 260 261 xcb_window_t window; 262 xcb_intern_atom_reply_t *atom_wm_delete_window; 263 264 bool quit; 265 XGL_UINT current_buffer; 266}; 267 268static void demo_draw_build_cmd(struct demo *demo) 269{ 270 const XGL_COLOR_ATTACHMENT_BIND_INFO color_attachment = { 271 .view = demo->buffers[demo->current_buffer].view, 272 .layout = XGL_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 273 }; 274 const XGL_DEPTH_STENCIL_BIND_INFO depth_stencil = { 275 .view = demo->depth.view, 276 .layout = XGL_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 277 }; 278 const XGL_FLOAT clear_color[4] = { 0.2f, 0.2f, 0.2f, 0.2f }; 279 const XGL_FLOAT clear_depth = 1.0f; 280 XGL_IMAGE_SUBRESOURCE_RANGE clear_range; 281 XGL_CMD_BUFFER_GRAPHICS_BEGIN_INFO graphics_cmd_buf_info = { 282 .sType = XGL_STRUCTURE_TYPE_CMD_BUFFER_GRAPHICS_BEGIN_INFO, 283 .pNext = NULL, 284 .operation = XGL_RENDER_PASS_OPERATION_BEGIN_AND_END, 285 }; 286 XGL_CMD_BUFFER_BEGIN_INFO cmd_buf_info = { 287 .sType = XGL_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO, 288 .pNext = &graphics_cmd_buf_info, 289 .flags = XGL_CMD_BUFFER_OPTIMIZE_GPU_SMALL_BATCH_BIT | 290 XGL_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT, 291 }; 292 XGL_RESULT err; 293 XGL_ATTACHMENT_LOAD_OP load_op = XGL_ATTACHMENT_LOAD_OP_DONT_CARE; 294 XGL_ATTACHMENT_STORE_OP store_op = XGL_ATTACHMENT_STORE_OP_DONT_CARE; 295 const XGL_FRAMEBUFFER_CREATE_INFO fb_info = { 296 .sType = XGL_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, 297 .pNext = NULL, 298 .colorAttachmentCount = 1, 299 .pColorAttachments = (XGL_COLOR_ATTACHMENT_BIND_INFO*) &color_attachment, 300 .pDepthStencilAttachment = (XGL_DEPTH_STENCIL_BIND_INFO*) &depth_stencil, 301 .sampleCount = 1, 302 .width = demo->width, 303 .height = demo->height, 304 .layers = 1, 305 }; 306 XGL_RENDER_PASS_CREATE_INFO rp_info; 307 308 memset(&rp_info, 0 , sizeof(rp_info)); 309 err = xglCreateFramebuffer(demo->device, &fb_info, &(rp_info.framebuffer)); 310 assert(!err); 311 rp_info.sType = XGL_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; 312 rp_info.renderArea.extent.width = demo->width; 313 rp_info.renderArea.extent.height = demo->height; 314 rp_info.pColorLoadOps = &load_op; 315 rp_info.pColorStoreOps = &store_op; 316 rp_info.depthLoadOp = XGL_ATTACHMENT_LOAD_OP_DONT_CARE; 317 rp_info.depthStoreOp = XGL_ATTACHMENT_STORE_OP_DONT_CARE; 318 rp_info.stencilLoadOp = XGL_ATTACHMENT_LOAD_OP_DONT_CARE; 319 rp_info.stencilStoreOp = XGL_ATTACHMENT_STORE_OP_DONT_CARE; 320 err = xglCreateRenderPass(demo->device, &rp_info, &(graphics_cmd_buf_info.renderPass)); 321 assert(!err); 322 323 err = xglBeginCommandBuffer(demo->cmd, &cmd_buf_info); 324 assert(!err); 325 326 xglCmdBindPipeline(demo->cmd, XGL_PIPELINE_BIND_POINT_GRAPHICS, 327 demo->pipeline); 328 xglCmdBindDescriptorSet(demo->cmd, XGL_PIPELINE_BIND_POINT_GRAPHICS, 329 demo->desc_set, NULL); 330 331 xglCmdBindDynamicStateObject(demo->cmd, XGL_STATE_BIND_VIEWPORT, demo->viewport); 332 xglCmdBindDynamicStateObject(demo->cmd, XGL_STATE_BIND_RASTER, demo->raster); 333 xglCmdBindDynamicStateObject(demo->cmd, XGL_STATE_BIND_COLOR_BLEND, 334 demo->color_blend); 335 xglCmdBindDynamicStateObject(demo->cmd, XGL_STATE_BIND_DEPTH_STENCIL, 336 demo->depth_stencil); 337 338 clear_range.aspect = XGL_IMAGE_ASPECT_COLOR; 339 clear_range.baseMipLevel = 0; 340 clear_range.mipLevels = 1; 341 clear_range.baseArraySlice = 0; 342 clear_range.arraySize = 1; 343 xglCmdClearColorImage(demo->cmd, 344 demo->buffers[demo->current_buffer].image, 345 clear_color, 1, &clear_range); 346 347 clear_range.aspect = XGL_IMAGE_ASPECT_DEPTH; 348 xglCmdClearDepthStencil(demo->cmd, demo->depth.image, 349 clear_depth, 0, 1, &clear_range); 350 351 xglCmdDraw(demo->cmd, 0, 12 * 3, 0, 1); 352 353 err = xglEndCommandBuffer(demo->cmd); 354 assert(!err); 355} 356 357 358void demo_update_data_buffer(struct demo *demo) 359{ 360 mat4x4 MVP, Model, VP; 361 int matrixSize = sizeof(MVP); 362 XGL_UINT8 *pData; 363 XGL_RESULT err; 364 365 mat4x4_mul(VP, demo->projection_matrix, demo->view_matrix); 366 367 // Rotate 22.5 degrees around the Y axis 368 mat4x4_dup(Model, demo->model_matrix); 369 mat4x4_rotate(demo->model_matrix, Model, 0.0f, 1.0f, 0.0f, degreesToRadians(demo->spin_angle)); 370 mat4x4_mul(MVP, VP, demo->model_matrix); 371 372 assert(demo->uniform_data.num_mem == 1); 373 err = xglMapMemory(demo->uniform_data.mem[0], 0, (XGL_VOID **) &pData); 374 assert(!err); 375 376 memcpy(pData, (const void*) &MVP[0][0], matrixSize); 377 378 err = xglUnmapMemory(demo->uniform_data.mem[0]); 379 assert(!err); 380} 381 382static void demo_draw(struct demo *demo) 383{ 384 const XGL_WSI_X11_PRESENT_INFO present = { 385 .destWindow = demo->window, 386 .srcImage = demo->buffers[demo->current_buffer].image, 387 .async = true, 388 .flip = false, 389 }; 390 XGL_FENCE fence = demo->buffers[demo->current_buffer].fence; 391 XGL_RESULT err; 392 393 demo_draw_build_cmd(demo); 394 395 err = xglWaitForFences(demo->device, 1, &fence, XGL_TRUE, ~((XGL_UINT64) 0)); 396 assert(err == XGL_SUCCESS || err == XGL_ERROR_UNAVAILABLE); 397 398 err = xglQueueSubmit(demo->queue, 1, &demo->cmd, 399 0, NULL, XGL_NULL_HANDLE); 400 assert(!err); 401 402 err = xglWsiX11QueuePresent(demo->queue, &present, fence); 403 assert(!err); 404 405 demo->current_buffer = (demo->current_buffer + 1) % DEMO_BUFFER_COUNT; 406} 407 408static void demo_prepare_buffers(struct demo *demo) 409{ 410 const XGL_WSI_X11_PRESENTABLE_IMAGE_CREATE_INFO presentable_image = { 411 .format = demo->format, 412 .usage = XGL_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 413 .extent = { 414 .width = demo->width, 415 .height = demo->height, 416 }, 417 .flags = 0, 418 }; 419 const XGL_FENCE_CREATE_INFO fence = { 420 .sType = XGL_STRUCTURE_TYPE_FENCE_CREATE_INFO, 421 .pNext = NULL, 422 .flags = 0, 423 }; 424 XGL_RESULT err; 425 XGL_UINT i; 426 427 for (i = 0; i < DEMO_BUFFER_COUNT; i++) { 428 XGL_COLOR_ATTACHMENT_VIEW_CREATE_INFO color_attachment_view = { 429 .sType = XGL_STRUCTURE_TYPE_COLOR_ATTACHMENT_VIEW_CREATE_INFO, 430 .pNext = NULL, 431 .format = demo->format, 432 .mipLevel = 0, 433 .baseArraySlice = 0, 434 .arraySize = 1, 435 }; 436 437 err = xglWsiX11CreatePresentableImage(demo->device, &presentable_image, 438 &demo->buffers[i].image, &demo->buffers[i].mem); 439 assert(!err); 440 441 color_attachment_view.image = demo->buffers[i].image; 442 443 err = xglCreateColorAttachmentView(demo->device, 444 &color_attachment_view, &demo->buffers[i].view); 445 assert(!err); 446 447 err = xglCreateFence(demo->device, 448 &fence, &demo->buffers[i].fence); 449 assert(!err); 450 } 451} 452 453static void demo_prepare_depth(struct demo *demo) 454{ 455 const XGL_FORMAT depth_format = XGL_FMT_D16_UNORM; 456 const XGL_IMAGE_CREATE_INFO image = { 457 .sType = XGL_STRUCTURE_TYPE_IMAGE_CREATE_INFO, 458 .pNext = NULL, 459 .imageType = XGL_IMAGE_2D, 460 .format = depth_format, 461 .extent = { demo->width, demo->height, 1 }, 462 .mipLevels = 1, 463 .arraySize = 1, 464 .samples = 1, 465 .tiling = XGL_OPTIMAL_TILING, 466 .usage = XGL_IMAGE_USAGE_DEPTH_STENCIL_BIT, 467 .flags = 0, 468 }; 469 XGL_MEMORY_ALLOC_IMAGE_INFO img_alloc = { 470 .sType = XGL_STRUCTURE_TYPE_MEMORY_ALLOC_IMAGE_INFO, 471 .pNext = NULL, 472 }; 473 XGL_MEMORY_ALLOC_INFO mem_alloc = { 474 .sType = XGL_STRUCTURE_TYPE_MEMORY_ALLOC_INFO, 475 .pNext = &img_alloc, 476 .allocationSize = 0, 477 .memProps = XGL_MEMORY_PROPERTY_GPU_ONLY, 478 .memType = XGL_MEMORY_TYPE_IMAGE, 479 .memPriority = XGL_MEMORY_PRIORITY_NORMAL, 480 }; 481 XGL_DEPTH_STENCIL_VIEW_CREATE_INFO view = { 482 .sType = XGL_STRUCTURE_TYPE_DEPTH_STENCIL_VIEW_CREATE_INFO, 483 .pNext = NULL, 484 .image = XGL_NULL_HANDLE, 485 .mipLevel = 0, 486 .baseArraySlice = 0, 487 .arraySize = 1, 488 .flags = 0, 489 }; 490 XGL_MEMORY_REQUIREMENTS *mem_reqs; 491 XGL_SIZE mem_reqs_size = sizeof(XGL_MEMORY_REQUIREMENTS); 492 XGL_IMAGE_MEMORY_REQUIREMENTS img_reqs; 493 XGL_SIZE img_reqs_size = sizeof(XGL_IMAGE_MEMORY_REQUIREMENTS); 494 XGL_RESULT err; 495 XGL_UINT num_allocations = 0; 496 XGL_SIZE num_alloc_size = sizeof(num_allocations); 497 498 demo->depth.format = depth_format; 499 500 /* create image */ 501 err = xglCreateImage(demo->device, &image, 502 &demo->depth.image); 503 assert(!err); 504 505 506 err = xglGetObjectInfo(demo->depth.image, XGL_INFO_TYPE_MEMORY_ALLOCATION_COUNT, &num_alloc_size, &num_allocations); 507 assert(!err && num_alloc_size == sizeof(num_allocations)); 508 mem_reqs = malloc(num_allocations * sizeof(XGL_MEMORY_REQUIREMENTS)); 509 demo->depth.mem = malloc(num_allocations * sizeof(XGL_GPU_MEMORY)); 510 demo->depth.num_mem = num_allocations; 511 err = xglGetObjectInfo(demo->depth.image, 512 XGL_INFO_TYPE_MEMORY_REQUIREMENTS, 513 &mem_reqs_size, mem_reqs); 514 assert(!err && mem_reqs_size == num_allocations * sizeof(XGL_MEMORY_REQUIREMENTS)); 515 err = xglGetObjectInfo(demo->depth.image, 516 XGL_INFO_TYPE_IMAGE_MEMORY_REQUIREMENTS, 517 &img_reqs_size, &img_reqs); 518 assert(!err && img_reqs_size == sizeof(XGL_IMAGE_MEMORY_REQUIREMENTS)); 519 img_alloc.usage = img_reqs.usage; 520 img_alloc.formatClass = img_reqs.formatClass; 521 img_alloc.samples = img_reqs.samples; 522 for (XGL_UINT i = 0; i < num_allocations; i ++) { 523 mem_alloc.allocationSize = mem_reqs[i].size; 524 525 /* allocate memory */ 526 err = xglAllocMemory(demo->device, &mem_alloc, 527 &(demo->depth.mem[i])); 528 assert(!err); 529 530 /* bind memory */ 531 err = xglBindObjectMemory(demo->depth.image, i, 532 demo->depth.mem[i], 0); 533 assert(!err); 534 } 535 536 /* create image view */ 537 view.image = demo->depth.image; 538 err = xglCreateDepthStencilView(demo->device, &view, 539 &demo->depth.view); 540 assert(!err); 541} 542 543/** loadTexture 544 * loads a png file into an memory object, using cstdio , libpng. 545 * 546 * \param demo : Needed to access XGL calls 547 * \param filename : the png file to be loaded 548 * \param width : width of png, to be updated as a side effect of this function 549 * \param height : height of png, to be updated as a side effect of this function 550 * 551 * \return bool : an opengl texture id. true if successful?, 552 * should be validated by the client of this function. 553 * 554 * Source: http://en.wikibooks.org/wiki/OpenGL_Programming/Intermediate/Textures 555 * Modified to copy image to memory 556 * 557 */ 558bool loadTexture(char *filename, XGL_UINT8 *rgba_data, 559 XGL_SUBRESOURCE_LAYOUT *layout, 560 XGL_INT *width, XGL_INT *height) 561{ 562 //header for testing if it is a png 563 png_byte header[8]; 564 int i, is_png, bit_depth, color_type,rowbytes; 565 png_uint_32 twidth, theight; 566 png_structp png_ptr; 567 png_infop info_ptr, end_info; 568 png_byte *image_data; 569 png_bytep *row_pointers; 570 571 //open file as binary 572 FILE *fp = fopen(filename, "rb"); 573 if (!fp) { 574 return false; 575 } 576 577 //read the header 578 fread(header, 1, 8, fp); 579 580 //test if png 581 is_png = !png_sig_cmp(header, 0, 8); 582 if (!is_png) { 583 fclose(fp); 584 return false; 585 } 586 587 //create png struct 588 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, 589 NULL, NULL); 590 if (!png_ptr) { 591 fclose(fp); 592 return (false); 593 } 594 595 //create png info struct 596 info_ptr = png_create_info_struct(png_ptr); 597 if (!info_ptr) { 598 png_destroy_read_struct(&png_ptr, (png_infopp) NULL, (png_infopp) NULL); 599 fclose(fp); 600 return (false); 601 } 602 603 //create png info struct 604 end_info = png_create_info_struct(png_ptr); 605 if (!end_info) { 606 png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL); 607 fclose(fp); 608 return (false); 609 } 610 611 //png error stuff, not sure libpng man suggests this. 612 if (setjmp(png_jmpbuf(png_ptr))) { 613 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); 614 fclose(fp); 615 return (false); 616 } 617 618 //init png reading 619 png_init_io(png_ptr, fp); 620 621 //let libpng know you already read the first 8 bytes 622 png_set_sig_bytes(png_ptr, 8); 623 624 // read all the info up to the image data 625 png_read_info(png_ptr, info_ptr); 626 627 // get info about png 628 png_get_IHDR(png_ptr, info_ptr, &twidth, &theight, &bit_depth, &color_type, 629 NULL, NULL, NULL); 630 631 //update width and height based on png info 632 *width = twidth; 633 *height = theight; 634 635 // Require that incoming texture be 8bits per color component 636 // and 4 components (RGBA). 637 if (png_get_bit_depth(png_ptr, info_ptr) != 8 || 638 png_get_channels(png_ptr, info_ptr) != 4) { 639 return false; 640 } 641 642 if (rgba_data == NULL) { 643 // If data pointer is null, we just want the width & height 644 // clean up memory and close stuff 645 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); 646 fclose(fp); 647 648 return true; 649 } 650 651 // Update the png info struct. 652 png_read_update_info(png_ptr, info_ptr); 653 654 // Row size in bytes. 655 rowbytes = png_get_rowbytes(png_ptr, info_ptr); 656 657 // Allocate the image_data as a big block, to be given to opengl 658 image_data = (png_byte *)malloc(rowbytes * theight * sizeof(png_byte)); 659 if (!image_data) { 660 //clean up memory and close stuff 661 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); 662 fclose(fp); 663 return false; 664 } 665 666 // row_pointers is for pointing to image_data for reading the png with libpng 667 row_pointers = (png_bytep *)malloc(theight * sizeof(png_bytep)); 668 if (!row_pointers) { 669 //clean up memory and close stuff 670 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); 671 // delete[] image_data; 672 fclose(fp); 673 return false; 674 } 675 // set the individual row_pointers to point at the correct offsets of image_data 676 for (i = 0; i < theight; ++i) 677 row_pointers[theight - 1 - i] = rgba_data + i * rowbytes; 678 679 // read the png into image_data through row_pointers 680 png_read_image(png_ptr, row_pointers); 681 682 // clean up memory and close stuff 683 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); 684 free(row_pointers); 685 free(image_data); 686 fclose(fp); 687 688 return true; 689} 690 691static void demo_prepare_textures(struct demo *demo) 692{ 693 const XGL_FORMAT tex_format = XGL_FMT_R8G8B8A8_UNORM; 694 XGL_INT tex_width; 695 XGL_INT tex_height; 696 XGL_RESULT err; 697 XGL_UINT i; 698 699 for (i = 0; i < DEMO_TEXTURE_COUNT; i++) { 700 const XGL_SAMPLER_CREATE_INFO sampler = { 701 .sType = XGL_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, 702 .pNext = NULL, 703 .magFilter = XGL_TEX_FILTER_NEAREST, 704 .minFilter = XGL_TEX_FILTER_NEAREST, 705 .mipMode = XGL_TEX_MIPMAP_BASE, 706 .addressU = XGL_TEX_ADDRESS_CLAMP, 707 .addressV = XGL_TEX_ADDRESS_CLAMP, 708 .addressW = XGL_TEX_ADDRESS_CLAMP, 709 .mipLodBias = 0.0f, 710 .maxAnisotropy = 0, 711 .compareFunc = XGL_COMPARE_NEVER, 712 .minLod = 0.0f, 713 .maxLod = 0.0f, 714 .borderColorType = XGL_BORDER_COLOR_OPAQUE_WHITE, 715 }; 716 717 assert(loadTexture(tex_files[i], NULL, NULL, &tex_width, &tex_height)); 718 719 const XGL_IMAGE_CREATE_INFO image = { 720 .sType = XGL_STRUCTURE_TYPE_IMAGE_CREATE_INFO, 721 .pNext = NULL, 722 .imageType = XGL_IMAGE_2D, 723 .format = tex_format, 724 .extent = { tex_width, tex_height, 1 }, 725 .mipLevels = 1, 726 .arraySize = 1, 727 .samples = 1, 728 .tiling = XGL_LINEAR_TILING, 729 .usage = XGL_IMAGE_USAGE_SHADER_ACCESS_READ_BIT, 730 .flags = 0, 731 }; 732 XGL_MEMORY_ALLOC_IMAGE_INFO img_alloc = { 733 .sType = XGL_STRUCTURE_TYPE_MEMORY_ALLOC_IMAGE_INFO, 734 .pNext = NULL, 735 }; 736 XGL_MEMORY_ALLOC_INFO mem_alloc = { 737 .sType = XGL_STRUCTURE_TYPE_MEMORY_ALLOC_INFO, 738 .pNext = &img_alloc, 739 .allocationSize = 0, 740 .memProps = XGL_MEMORY_PROPERTY_GPU_ONLY, 741 .memType = XGL_MEMORY_TYPE_IMAGE, 742 .memPriority = XGL_MEMORY_PRIORITY_NORMAL, 743 }; 744 XGL_IMAGE_VIEW_CREATE_INFO view = { 745 .sType = XGL_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, 746 .pNext = NULL, 747 .image = XGL_NULL_HANDLE, 748 .viewType = XGL_IMAGE_VIEW_2D, 749 .format = image.format, 750 .channels = { XGL_CHANNEL_SWIZZLE_R, 751 XGL_CHANNEL_SWIZZLE_G, 752 XGL_CHANNEL_SWIZZLE_B, 753 XGL_CHANNEL_SWIZZLE_A, }, 754 .subresourceRange = { XGL_IMAGE_ASPECT_COLOR, 0, 1, 0, 1 }, 755 .minLod = 0.0f, 756 }; 757 758 XGL_MEMORY_REQUIREMENTS *mem_reqs; 759 XGL_SIZE mem_reqs_size = sizeof(XGL_MEMORY_REQUIREMENTS); 760 XGL_IMAGE_MEMORY_REQUIREMENTS img_reqs; 761 XGL_SIZE img_reqs_size = sizeof(XGL_IMAGE_MEMORY_REQUIREMENTS); 762 XGL_UINT num_allocations = 0; 763 XGL_SIZE num_alloc_size = sizeof(num_allocations); 764 765 /* create sampler */ 766 err = xglCreateSampler(demo->device, &sampler, 767 &demo->textures[i].sampler); 768 assert(!err); 769 770 /* create image */ 771 err = xglCreateImage(demo->device, &image, 772 &demo->textures[i].image); 773 assert(!err); 774 775 err = xglGetObjectInfo(demo->textures[i].image, 776 XGL_INFO_TYPE_MEMORY_ALLOCATION_COUNT, 777 &num_alloc_size, &num_allocations); 778 assert(!err && num_alloc_size == sizeof(num_allocations)); 779 mem_reqs = malloc(num_allocations * sizeof(XGL_MEMORY_REQUIREMENTS)); 780 demo->textures[i].mem = malloc(num_allocations * sizeof(XGL_GPU_MEMORY)); 781 demo->textures[i].num_mem = num_allocations; 782 err = xglGetObjectInfo(demo->textures[i].image, 783 XGL_INFO_TYPE_MEMORY_REQUIREMENTS, 784 &mem_reqs_size, mem_reqs); 785 assert(!err && mem_reqs_size == num_allocations * sizeof(XGL_MEMORY_REQUIREMENTS)); 786 err = xglGetObjectInfo(demo->textures[i].image, 787 XGL_INFO_TYPE_IMAGE_MEMORY_REQUIREMENTS, 788 &img_reqs_size, &img_reqs); 789 assert(!err && img_reqs_size == sizeof(XGL_IMAGE_MEMORY_REQUIREMENTS)); 790 img_alloc.usage = img_reqs.usage; 791 img_alloc.formatClass = img_reqs.formatClass; 792 img_alloc.samples = img_reqs.samples; 793 for (XGL_UINT j = 0; j < num_allocations; j ++) { 794 mem_alloc.allocationSize = mem_reqs[j].size; 795 796 /* allocate memory */ 797 err = xglAllocMemory(demo->device, &mem_alloc, 798 &(demo->textures[i].mem[j])); 799 assert(!err); 800 801 /* bind memory */ 802 err = xglBindObjectMemory(demo->textures[i].image, j, 803 demo->textures[i].mem[j], 0); 804 assert(!err); 805 } 806 807 /* create image view */ 808 view.image = demo->textures[i].image; 809 err = xglCreateImageView(demo->device, &view, 810 &demo->textures[i].view); 811 assert(!err); 812 } 813 814 for (i = 0; i < DEMO_TEXTURE_COUNT; i++) { 815 const XGL_IMAGE_SUBRESOURCE subres = { 816 .aspect = XGL_IMAGE_ASPECT_COLOR, 817 .mipLevel = 0, 818 .arraySlice = 0, 819 }; 820 XGL_SUBRESOURCE_LAYOUT layout; 821 XGL_SIZE layout_size = sizeof(layout); 822 XGL_VOID *data; 823 824 err = xglGetImageSubresourceInfo(demo->textures[i].image, &subres, 825 XGL_INFO_TYPE_SUBRESOURCE_LAYOUT, &layout_size, &layout); 826 assert(!err && layout_size == sizeof(layout)); 827 assert(demo->textures[i].num_mem == 1); 828 829 err = xglMapMemory(demo->textures[i].mem[0], 0, &data); 830 assert(!err); 831 832 loadTexture(tex_files[i], data, &layout, &tex_width, &tex_height); 833 834 err = xglUnmapMemory(demo->textures[i].mem[0]); 835 assert(!err); 836 } 837} 838 839void demo_prepare_cube_data_buffer(struct demo *demo) 840{ 841 XGL_BUFFER_CREATE_INFO buf_info; 842 XGL_BUFFER_VIEW_CREATE_INFO view_info; 843 XGL_MEMORY_ALLOC_BUFFER_INFO buf_alloc = { 844 .sType = XGL_STRUCTURE_TYPE_MEMORY_ALLOC_BUFFER_INFO, 845 .pNext = NULL, 846 }; 847 XGL_MEMORY_ALLOC_INFO alloc_info = { 848 .sType = XGL_STRUCTURE_TYPE_MEMORY_ALLOC_INFO, 849 .pNext = &buf_alloc, 850 .allocationSize = 0, 851 .memProps = XGL_MEMORY_PROPERTY_CPU_VISIBLE_BIT, 852 .memType = XGL_MEMORY_TYPE_BUFFER, 853 .memPriority = XGL_MEMORY_PRIORITY_NORMAL, 854 }; 855 XGL_MEMORY_REQUIREMENTS *mem_reqs; 856 XGL_SIZE mem_reqs_size = sizeof(XGL_MEMORY_REQUIREMENTS); 857 XGL_BUFFER_MEMORY_REQUIREMENTS buf_reqs; 858 XGL_SIZE buf_reqs_size = sizeof(XGL_BUFFER_MEMORY_REQUIREMENTS); 859 XGL_UINT num_allocations = 0; 860 XGL_SIZE num_alloc_size = sizeof(num_allocations); 861 XGL_UINT8 *pData; 862 int i; 863 mat4x4 MVP, VP; 864 XGL_RESULT err; 865 struct xgltexcube_vs_uniform data; 866 867 mat4x4_mul(VP, demo->projection_matrix, demo->view_matrix); 868 mat4x4_mul(MVP, VP, demo->model_matrix); 869 memcpy(data.mvp, MVP, sizeof(MVP)); 870// dumpMatrix("MVP", MVP); 871 872 for (i=0; i<12*3; i++) { 873 data.position[i][0] = g_vertex_buffer_data[i*3]; 874 data.position[i][1] = g_vertex_buffer_data[i*3+1]; 875 data.position[i][2] = g_vertex_buffer_data[i*3+2]; 876 data.position[i][3] = 1.0f; 877 data.attr[i][0] = g_uv_buffer_data[2*i]; 878 data.attr[i][1] = g_uv_buffer_data[2*i + 1]; 879 data.attr[i][2] = 0; 880 data.attr[i][3] = 0; 881 } 882 883 memset(&buf_info, 0, sizeof(buf_info)); 884 buf_info.sType = XGL_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 885 buf_info.size = sizeof(data); 886 buf_info.usage = XGL_BUFFER_USAGE_UNIFORM_READ_BIT; 887 err = xglCreateBuffer(demo->device, &buf_info, &demo->uniform_data.buf); 888 assert(!err); 889 890 err = xglGetObjectInfo(demo->uniform_data.buf, 891 XGL_INFO_TYPE_MEMORY_ALLOCATION_COUNT, 892 &num_alloc_size, &num_allocations); 893 assert(!err && num_alloc_size == sizeof(num_allocations)); 894 mem_reqs = malloc(num_allocations * sizeof(XGL_MEMORY_REQUIREMENTS)); 895 demo->uniform_data.mem = malloc(num_allocations * sizeof(XGL_GPU_MEMORY)); 896 demo->uniform_data.num_mem = num_allocations; 897 err = xglGetObjectInfo(demo->uniform_data.buf, 898 XGL_INFO_TYPE_MEMORY_REQUIREMENTS, 899 &mem_reqs_size, mem_reqs); 900 assert(!err && mem_reqs_size == num_allocations * sizeof(*mem_reqs)); 901 err = xglGetObjectInfo(demo->uniform_data.buf, 902 XGL_INFO_TYPE_BUFFER_MEMORY_REQUIREMENTS, 903 &buf_reqs_size, &buf_reqs); 904 assert(!err && buf_reqs_size == sizeof(XGL_BUFFER_MEMORY_REQUIREMENTS)); 905 buf_alloc.usage = buf_reqs.usage; 906 for (XGL_UINT i = 0; i < num_allocations; i ++) { 907 alloc_info.allocationSize = mem_reqs[i].size; 908 909 err = xglAllocMemory(demo->device, &alloc_info, &(demo->uniform_data.mem[i])); 910 assert(!err); 911 912 err = xglMapMemory(demo->uniform_data.mem[i], 0, (XGL_VOID **) &pData); 913 assert(!err); 914 915 memcpy(pData, &data, alloc_info.allocationSize); 916 917 err = xglUnmapMemory(demo->uniform_data.mem[i]); 918 assert(!err); 919 920 err = xglBindObjectMemory(demo->uniform_data.buf, i, 921 demo->uniform_data.mem[i], 0); 922 assert(!err); 923 } 924 925 memset(&view_info, 0, sizeof(view_info)); 926 view_info.sType = XGL_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO; 927 view_info.buffer = demo->uniform_data.buf; 928 view_info.viewType = XGL_BUFFER_VIEW_RAW; 929 view_info.offset = 0; 930 view_info.range = sizeof(data); 931 932 err = xglCreateBufferView(demo->device, &view_info, &demo->uniform_data.view); 933 assert(!err); 934 935 demo->uniform_data.attach.sType = XGL_STRUCTURE_TYPE_BUFFER_VIEW_ATTACH_INFO; 936 demo->uniform_data.attach.view = demo->uniform_data.view; 937} 938 939static void demo_prepare_descriptor_layout(struct demo *demo) 940{ 941 const XGL_DESCRIPTOR_SET_LAYOUT_CREATE_INFO descriptor_layout_vs = { 942 .sType = XGL_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, 943 .pNext = NULL, 944 .descriptorType = XGL_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 945 .count = 1, 946 .stageFlags = XGL_SHADER_STAGE_FLAGS_VERTEX_BIT, 947 .immutableSampler = XGL_NULL_HANDLE, 948 }; 949 const XGL_DESCRIPTOR_SET_LAYOUT_CREATE_INFO descriptor_layout_fs = { 950 .sType = XGL_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, 951 .pNext = NULL, 952 .descriptorType = XGL_DESCRIPTOR_TYPE_SAMPLER_TEXTURE, 953 .count = DEMO_TEXTURE_COUNT, 954 .stageFlags = XGL_SHADER_STAGE_FLAGS_FRAGMENT_BIT, 955 .immutableSampler = XGL_NULL_HANDLE, 956 }; 957 const uint32_t bind_point = 0; 958 XGL_RESULT err; 959 960 err = xglCreateDescriptorSetLayout(demo->device, 961 XGL_SHADER_STAGE_FLAGS_VERTEX_BIT, &bind_point, 962 XGL_NULL_HANDLE, &descriptor_layout_vs, 963 &demo->desc_layout_vs); 964 assert(!err); 965 966 err = xglCreateDescriptorSetLayout(demo->device, 967 XGL_SHADER_STAGE_FLAGS_FRAGMENT_BIT, &bind_point, 968 demo->desc_layout_vs, &descriptor_layout_fs, 969 &demo->desc_layout_fs); 970 assert(!err); 971 972 demo->desc_layout_last = &demo->desc_layout_fs; 973} 974 975static XGL_SHADER demo_prepare_shader(struct demo *demo, 976 XGL_PIPELINE_SHADER_STAGE stage, 977 const void *code, 978 XGL_SIZE size) 979{ 980 XGL_SHADER_CREATE_INFO createInfo; 981 XGL_SHADER shader; 982 XGL_RESULT err; 983 984 985 createInfo.sType = XGL_STRUCTURE_TYPE_SHADER_CREATE_INFO; 986 createInfo.pNext = NULL; 987 988#ifdef EXTERNAL_BIL 989 createInfo.codeSize = size; 990 createInfo.pCode = code; 991 createInfo.flags = 0; 992 993 err = xglCreateShader(demo->device, &createInfo, &shader); 994 if (err) { 995 free((void *) createInfo.pCode); 996 } 997#else 998 // Create fake BIL structure to feed GLSL 999 // to the driver "under the covers" 1000 createInfo.codeSize = 3 * sizeof(uint32_t) + size + 1; 1001 createInfo.pCode = malloc(createInfo.codeSize); 1002 createInfo.flags = 0; 1003 1004 /* try version 0 first: XGL_PIPELINE_SHADER_STAGE followed by GLSL */ 1005 ((uint32_t *) createInfo.pCode)[0] = ICD_BIL_MAGIC; 1006 ((uint32_t *) createInfo.pCode)[1] = 0; 1007 ((uint32_t *) createInfo.pCode)[2] = stage; 1008 memcpy(((uint32_t *) createInfo.pCode + 3), code, size + 1); 1009 1010 err = xglCreateShader(demo->device, &createInfo, &shader); 1011 if (err) { 1012 free((void *) createInfo.pCode); 1013 return NULL; 1014 } 1015#endif 1016 1017 return shader; 1018} 1019 1020char *demo_read_bil(const char *filename, XGL_SIZE *psize) 1021{ 1022 long int size; 1023 void *shader_code; 1024 1025 FILE *fp = fopen(filename, "rb"); 1026 if (!fp) return NULL; 1027 1028 fseek(fp, 0L, SEEK_END); 1029 size = ftell(fp); 1030 1031 fseek(fp, 0L, SEEK_SET); 1032 1033 shader_code = malloc(size); 1034 fread(shader_code, size, 1, fp); 1035 1036 *psize = size; 1037 1038 return shader_code; 1039} 1040 1041static XGL_SHADER demo_prepare_vs(struct demo *demo) 1042{ 1043#ifdef EXTERNAL_BIL 1044 void *vertShaderCode; 1045 XGL_SIZE size; 1046 1047 vertShaderCode = demo_read_bil("cube-vert.bil", &size); 1048 1049 return demo_prepare_shader(demo, XGL_SHADER_STAGE_VERTEX, 1050 vertShaderCode, size); 1051#else 1052 static const char *vertShaderText = 1053 "#version 140\n" 1054 "#extension GL_ARB_separate_shader_objects : enable\n" 1055 "#extension GL_ARB_shading_language_420pack : enable\n" 1056 "\n" 1057 "layout(binding = 0) uniform buf {\n" 1058 " mat4 MVP;\n" 1059 " vec4 position[12*3];\n" 1060 " vec4 attr[12*3];\n" 1061 "} ubuf;\n" 1062 "\n" 1063 "layout (location = 0) out vec4 texcoord;\n" 1064 "\n" 1065 "void main() \n" 1066 "{\n" 1067 " texcoord = ubuf.attr[gl_VertexID];\n" 1068 " gl_Position = ubuf.MVP * ubuf.position[gl_VertexID];\n" 1069 "}\n"; 1070 1071 return demo_prepare_shader(demo, XGL_SHADER_STAGE_VERTEX, 1072 (const void *) vertShaderText, 1073 strlen(vertShaderText)); 1074#endif 1075} 1076 1077static XGL_SHADER demo_prepare_fs(struct demo *demo) 1078{ 1079#ifdef EXTERNAL_BIL 1080 void *fragShaderCode; 1081 XGL_SIZE size; 1082 1083 fragShaderCode = demo_read_bil("cube-frag.bil", &size); 1084 1085 return demo_prepare_shader(demo, XGL_SHADER_STAGE_FRAGMENT, 1086 fragShaderCode, size); 1087#else 1088 static const char *fragShaderText = 1089 "#version 140\n" 1090 "#extension GL_ARB_separate_shader_objects : enable\n" 1091 "#extension GL_ARB_shading_language_420pack : enable\n" 1092 "layout (binding = 0) uniform sampler2D tex;\n" 1093 "\n" 1094 "layout (location = 0) in vec4 texcoord;\n" 1095 "void main() {\n" 1096 " gl_FragColor = texture(tex, texcoord.xy);\n" 1097 "}\n"; 1098 1099 return demo_prepare_shader(demo, XGL_SHADER_STAGE_FRAGMENT, 1100 (const void *) fragShaderText, 1101 strlen(fragShaderText)); 1102#endif 1103} 1104 1105static void demo_prepare_pipeline(struct demo *demo) 1106{ 1107 XGL_GRAPHICS_PIPELINE_CREATE_INFO pipeline; 1108 XGL_PIPELINE_IA_STATE_CREATE_INFO ia; 1109 XGL_PIPELINE_RS_STATE_CREATE_INFO rs; 1110 XGL_PIPELINE_CB_STATE_CREATE_INFO cb; 1111 XGL_PIPELINE_DS_STATE_CREATE_INFO ds; 1112 XGL_PIPELINE_SHADER_STAGE_CREATE_INFO vs; 1113 XGL_PIPELINE_SHADER_STAGE_CREATE_INFO fs; 1114 XGL_PIPELINE_VP_STATE_CREATE_INFO vp; 1115 XGL_PIPELINE_MS_STATE_CREATE_INFO ms; 1116 XGL_RESULT err; 1117 1118 memset(&pipeline, 0, sizeof(pipeline)); 1119 pipeline.sType = XGL_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; 1120 pipeline.lastSetLayout = *demo->desc_layout_last; 1121 1122 memset(&ia, 0, sizeof(ia)); 1123 ia.sType = XGL_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO; 1124 ia.topology = XGL_TOPOLOGY_TRIANGLE_LIST; 1125 1126 memset(&rs, 0, sizeof(rs)); 1127 rs.sType = XGL_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO; 1128 rs.fillMode = XGL_FILL_SOLID; 1129 rs.cullMode = XGL_CULL_NONE; 1130 rs.frontFace = XGL_FRONT_FACE_CCW; 1131 1132 memset(&cb, 0, sizeof(cb)); 1133 cb.sType = XGL_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO; 1134 XGL_PIPELINE_CB_ATTACHMENT_STATE att_state[1]; 1135 memset(att_state, 0, sizeof(att_state)); 1136 att_state[0].format = demo->format; 1137 att_state[0].channelWriteMask = 0xf; 1138 att_state[0].blendEnable = XGL_FALSE; 1139 cb.attachmentCount = 1; 1140 cb.pAttachments = att_state; 1141 1142 memset(&vp, 0, sizeof(vp)); 1143 vp.sType = XGL_STRUCTURE_TYPE_PIPELINE_VP_STATE_CREATE_INFO; 1144 vp.scissorEnable = XGL_FALSE; 1145 1146 memset(&ds, 0, sizeof(ds)); 1147 ds.sType = XGL_STRUCTURE_TYPE_PIPELINE_DS_STATE_CREATE_INFO; 1148 ds.format = demo->depth.format; 1149 ds.depthTestEnable = XGL_TRUE; 1150 ds.depthWriteEnable = XGL_TRUE; 1151 ds.depthFunc = XGL_COMPARE_LESS_EQUAL; 1152 ds.depthBoundsEnable = XGL_FALSE; 1153 ds.back.stencilFailOp = XGL_STENCIL_OP_KEEP; 1154 ds.back.stencilPassOp = XGL_STENCIL_OP_KEEP; 1155 ds.back.stencilFunc = XGL_COMPARE_ALWAYS; 1156 ds.stencilTestEnable = XGL_FALSE; 1157 ds.front = ds.back; 1158 1159 memset(&vs, 0, sizeof(vs)); 1160 vs.sType = XGL_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; 1161 vs.shader.stage = XGL_SHADER_STAGE_VERTEX; 1162 vs.shader.shader = demo_prepare_vs(demo); 1163 assert(vs.shader.shader != NULL); 1164 1165 memset(&fs, 0, sizeof(fs)); 1166 fs.sType = XGL_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; 1167 fs.shader.stage = XGL_SHADER_STAGE_FRAGMENT; 1168 fs.shader.shader = demo_prepare_fs(demo); 1169 assert(fs.shader.shader != NULL); 1170 1171 memset(&ms, 0, sizeof(ms)); 1172 ms.sType = XGL_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO; 1173 ms.sampleMask = 1; 1174 ms.multisampleEnable = XGL_FALSE; 1175 ms.samples = 1; 1176 1177 pipeline.pNext = (const XGL_VOID *) &ia; 1178 ia.pNext = (const XGL_VOID *) &rs; 1179 rs.pNext = (const XGL_VOID *) &cb; 1180 cb.pNext = (const XGL_VOID *) &ms; 1181 ms.pNext = (const XGL_VOID *) &vp; 1182 vp.pNext = (const XGL_VOID *) &ds; 1183 ds.pNext = (const XGL_VOID *) &vs; 1184 vs.pNext = (const XGL_VOID *) &fs; 1185 1186 err = xglCreateGraphicsPipeline(demo->device, &pipeline, &demo->pipeline); 1187 assert(!err); 1188 1189 xglDestroyObject(vs.shader.shader); 1190 xglDestroyObject(fs.shader.shader); 1191} 1192 1193static void demo_prepare_dynamic_states(struct demo *demo) 1194{ 1195 XGL_DYNAMIC_VP_STATE_CREATE_INFO viewport_create; 1196 XGL_DYNAMIC_RS_STATE_CREATE_INFO raster; 1197 XGL_DYNAMIC_CB_STATE_CREATE_INFO color_blend; 1198 XGL_DYNAMIC_DS_STATE_CREATE_INFO depth_stencil; 1199 XGL_RESULT err; 1200 1201 memset(&viewport_create, 0, sizeof(viewport_create)); 1202 viewport_create.sType = XGL_STRUCTURE_TYPE_DYNAMIC_VP_STATE_CREATE_INFO; 1203 viewport_create.viewportCount = 1; 1204 XGL_VIEWPORT viewport; 1205 viewport.height = (XGL_FLOAT) demo->height; 1206 viewport.width = (XGL_FLOAT) demo->width; 1207 viewport.minDepth = (XGL_FLOAT) 0.0f; 1208 viewport.maxDepth = (XGL_FLOAT) 1.0f; 1209 viewport_create.pViewports = &viewport; 1210 1211 memset(&raster, 0, sizeof(raster)); 1212 raster.sType = XGL_STRUCTURE_TYPE_DYNAMIC_RS_STATE_CREATE_INFO; 1213 1214 memset(&color_blend, 0, sizeof(color_blend)); 1215 color_blend.sType = XGL_STRUCTURE_TYPE_DYNAMIC_CB_STATE_CREATE_INFO; 1216 1217 memset(&depth_stencil, 0, sizeof(depth_stencil)); 1218 depth_stencil.sType = XGL_STRUCTURE_TYPE_DYNAMIC_DS_STATE_CREATE_INFO; 1219 depth_stencil.stencilBackRef = 0; 1220 depth_stencil.stencilFrontRef = 0; 1221 depth_stencil.stencilReadMask = 0xff; 1222 depth_stencil.stencilWriteMask = 0xff; 1223 1224 err = xglCreateDynamicViewportState(demo->device, &viewport_create, &demo->viewport); 1225 assert(!err); 1226 1227 err = xglCreateDynamicRasterState(demo->device, &raster, &demo->raster); 1228 assert(!err); 1229 1230 err = xglCreateDynamicColorBlendState(demo->device, 1231 &color_blend, &demo->color_blend); 1232 assert(!err); 1233 1234 err = xglCreateDynamicDepthStencilState(demo->device, 1235 &depth_stencil, &demo->depth_stencil); 1236 assert(!err); 1237} 1238 1239static void demo_prepare_descriptor_region(struct demo *demo) 1240{ 1241 const XGL_DESCRIPTOR_TYPE_COUNT type_counts[2] = { 1242 [0] = { 1243 .type = XGL_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1244 .count = 1, 1245 }, 1246 [1] = { 1247 .type = XGL_DESCRIPTOR_TYPE_SAMPLER_TEXTURE, 1248 .count = DEMO_TEXTURE_COUNT, 1249 }, 1250 }; 1251 const XGL_DESCRIPTOR_REGION_CREATE_INFO descriptor_region = { 1252 .sType = XGL_STRUCTURE_TYPE_DESCRIPTOR_REGION_CREATE_INFO, 1253 .pNext = NULL, 1254 .count = 2, 1255 .pTypeCount = type_counts, 1256 }; 1257 XGL_RESULT err; 1258 1259 err = xglCreateDescriptorRegion(demo->device, 1260 XGL_DESCRIPTOR_REGION_USAGE_ONE_SHOT, 1, 1261 &descriptor_region, &demo->desc_region); 1262 assert(!err); 1263} 1264 1265static void demo_prepare_descriptor_set(struct demo *demo) 1266{ 1267 const XGL_BUFFER_VIEW_ATTACH_INFO *view_info_vs = 1268 &demo->uniform_data.attach; 1269 XGL_IMAGE_VIEW_ATTACH_INFO view_info[DEMO_TEXTURE_COUNT]; 1270 XGL_SAMPLER_IMAGE_VIEW_INFO combined_info[DEMO_TEXTURE_COUNT]; 1271 XGL_UPDATE_SAMPLER_TEXTURES update_fs; 1272 XGL_UPDATE_BUFFERS update_vs; 1273 XGL_RESULT err; 1274 uint32_t count; 1275 XGL_UINT i; 1276 1277 for (i = 0; i < DEMO_TEXTURE_COUNT; i++) { 1278 view_info[i].sType = XGL_STRUCTURE_TYPE_IMAGE_VIEW_ATTACH_INFO; 1279 view_info[i].pNext = NULL; 1280 view_info[i].view = demo->textures[i].view, 1281 view_info[i].layout = XGL_IMAGE_LAYOUT_GENERAL; 1282 1283 combined_info[i].pSampler = demo->textures[i].sampler; 1284 combined_info[i].pImageView = &view_info[i]; 1285 } 1286 1287 memset(&update_vs, 0, sizeof(update_vs)); 1288 update_vs.sType = XGL_STRUCTURE_TYPE_UPDATE_BUFFERS; 1289 update_vs.pNext = &update_fs; 1290 update_vs.descriptorType = XGL_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 1291 update_vs.count = 1; 1292 update_vs.pBufferViews = &view_info_vs; 1293 1294 memset(&update_fs, 0, sizeof(update_fs)); 1295 update_fs.sType = XGL_STRUCTURE_TYPE_UPDATE_SAMPLER_TEXTURES; 1296 update_fs.index = 1; 1297 update_fs.count = DEMO_TEXTURE_COUNT; 1298 update_fs.pSamplerImageViews = combined_info; 1299 1300 err = xglAllocDescriptorSets(demo->desc_region, 1301 XGL_DESCRIPTOR_SET_USAGE_STATIC, 1302 1, demo->desc_layout_last, 1303 &demo->desc_set, &count); 1304 assert(!err && count == 1); 1305 1306 xglBeginDescriptorRegionUpdate(demo->device, 1307 XGL_DESCRIPTOR_UPDATE_MODE_FASTEST); 1308 1309 xglClearDescriptorSets(demo->desc_region, 1, &demo->desc_set); 1310 xglUpdateDescriptors(demo->desc_set, &update_vs); 1311 1312 xglEndDescriptorRegionUpdate(demo->device, demo->cmd); 1313} 1314 1315static void demo_prepare(struct demo *demo) 1316{ 1317 const XGL_CMD_BUFFER_CREATE_INFO cmd = { 1318 .sType = XGL_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO, 1319 .pNext = NULL, 1320 .queueType = XGL_QUEUE_TYPE_GRAPHICS, 1321 .flags = 0, 1322 }; 1323 XGL_RESULT err; 1324 1325 demo_prepare_buffers(demo); 1326 demo_prepare_depth(demo); 1327 demo_prepare_textures(demo); 1328 demo_prepare_cube_data_buffer(demo); 1329 1330 demo_prepare_descriptor_layout(demo); 1331 demo_prepare_pipeline(demo); 1332 demo_prepare_dynamic_states(demo); 1333 1334 err = xglCreateCommandBuffer(demo->device, &cmd, &demo->cmd); 1335 assert(!err); 1336 1337 demo_prepare_descriptor_region(demo); 1338 demo_prepare_descriptor_set(demo); 1339} 1340 1341static void demo_handle_event(struct demo *demo, 1342 const xcb_generic_event_t *event) 1343{ 1344 u_int8_t event_code = event->response_type & 0x7f; 1345 switch (event_code) { 1346 case XCB_EXPOSE: 1347 // TODO: Resize window 1348 break; 1349 case XCB_CLIENT_MESSAGE: 1350 if((*(xcb_client_message_event_t*)event).data.data32[0] == 1351 (*demo->atom_wm_delete_window).atom) { 1352 demo->quit = true; 1353 } 1354 break; 1355 case XCB_KEY_RELEASE: 1356 { 1357 const xcb_key_release_event_t *key = 1358 (const xcb_key_release_event_t *) event; 1359 1360 switch (key->detail) { 1361 case 0x9: // Escape 1362 demo->quit = true; 1363 break; 1364 case 0x71: // left arrow key 1365 demo->spin_angle += demo->spin_increment; 1366 break; 1367 case 0x72: // right arrow key 1368 demo->spin_angle -= demo->spin_increment; 1369 break; 1370 case 0x41: 1371 demo->pause = !demo->pause; 1372 break; 1373 } 1374 } 1375 break; 1376 default: 1377 break; 1378 } 1379} 1380 1381static void demo_run(struct demo *demo) 1382{ 1383 xcb_flush(demo->connection); 1384 1385 while (!demo->quit) { 1386 xcb_generic_event_t *event; 1387 1388 if (demo->pause) { 1389 event = xcb_wait_for_event(demo->connection); 1390 } else { 1391 event = xcb_poll_for_event(demo->connection); 1392 } 1393 if (event) { 1394 demo_handle_event(demo, event); 1395 free(event); 1396 } 1397 1398 // Wait for work to finish before updating MVP. 1399 xglDeviceWaitIdle(demo->device); 1400 demo_update_data_buffer(demo); 1401 1402 demo_draw(demo); 1403 1404 // Wait for work to finish before updating MVP. 1405 xglDeviceWaitIdle(demo->device); 1406 } 1407} 1408 1409static void demo_create_window(struct demo *demo) 1410{ 1411 uint32_t value_mask, value_list[32]; 1412 1413 demo->window = xcb_generate_id(demo->connection); 1414 1415 value_mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK; 1416 value_list[0] = demo->screen->black_pixel; 1417 value_list[1] = XCB_EVENT_MASK_KEY_RELEASE | 1418 XCB_EVENT_MASK_EXPOSURE; 1419 1420 xcb_create_window(demo->connection, 1421 XCB_COPY_FROM_PARENT, 1422 demo->window, demo->screen->root, 1423 0, 0, demo->width, demo->height, 0, 1424 XCB_WINDOW_CLASS_INPUT_OUTPUT, 1425 demo->screen->root_visual, 1426 value_mask, value_list); 1427 1428 /* Magic code that will send notification when window is destroyed */ 1429 xcb_intern_atom_cookie_t cookie = xcb_intern_atom(demo->connection, 1, 12, 1430 "WM_PROTOCOLS"); 1431 xcb_intern_atom_reply_t* reply = xcb_intern_atom_reply(demo->connection, cookie, 0); 1432 1433 xcb_intern_atom_cookie_t cookie2 = xcb_intern_atom(demo->connection, 0, 16, "WM_DELETE_WINDOW"); 1434 demo->atom_wm_delete_window = xcb_intern_atom_reply(demo->connection, cookie2, 0); 1435 1436 xcb_change_property(demo->connection, XCB_PROP_MODE_REPLACE, 1437 demo->window, (*reply).atom, 4, 32, 1, 1438 &(*demo->atom_wm_delete_window).atom); 1439 free(reply); 1440 1441 xcb_map_window(demo->connection, demo->window); 1442} 1443 1444static void demo_init_xgl(struct demo *demo) 1445{ 1446 const XGL_APPLICATION_INFO app = { 1447 .sType = XGL_STRUCTURE_TYPE_APPLICATION_INFO, 1448 .pNext = NULL, 1449 .pAppName = "cube", 1450 .appVersion = 0, 1451 .pEngineName = "cube", 1452 .engineVersion = 0, 1453 .apiVersion = XGL_MAKE_VERSION(0, 22, 0), 1454 }; 1455 const XGL_WSI_X11_CONNECTION_INFO connection = { 1456 .pConnection = demo->connection, 1457 .root = demo->screen->root, 1458 .provider = 0, 1459 }; 1460 const XGL_DEVICE_QUEUE_CREATE_INFO queue = { 1461 .queueNodeIndex = 0, 1462 .queueCount = 1, 1463 }; 1464 const XGL_CHAR *ext_names[] = { 1465 "XGL_WSI_X11", 1466 }; 1467 const XGL_DEVICE_CREATE_INFO device = { 1468 .sType = XGL_STRUCTURE_TYPE_DEVICE_CREATE_INFO, 1469 .pNext = NULL, 1470 .queueRecordCount = 1, 1471 .pRequestedQueues = &queue, 1472 .extensionCount = 1, 1473 .ppEnabledExtensionNames = ext_names, 1474 .maxValidationLevel = XGL_VALIDATION_LEVEL_END_RANGE, 1475 .flags = XGL_DEVICE_CREATE_VALIDATION_BIT, 1476 }; 1477 XGL_RESULT err; 1478 XGL_UINT gpu_count; 1479 XGL_UINT i; 1480 1481 err = xglInitAndEnumerateGpus(&app, NULL, 1, &gpu_count, &demo->gpu); 1482 assert(!err && gpu_count == 1); 1483 1484 for (i = 0; i < device.extensionCount; i++) { 1485 err = xglGetExtensionSupport(demo->gpu, ext_names[i]); 1486 assert(!err); 1487 } 1488 1489 err = xglWsiX11AssociateConnection(demo->gpu, &connection); 1490 assert(!err); 1491 1492 err = xglCreateDevice(demo->gpu, &device, &demo->device); 1493 assert(!err); 1494 1495 err = xglGetDeviceQueue(demo->device, XGL_QUEUE_TYPE_GRAPHICS, 1496 0, &demo->queue); 1497 assert(!err); 1498} 1499 1500static void demo_init_connection(struct demo *demo) 1501{ 1502 const xcb_setup_t *setup; 1503 xcb_screen_iterator_t iter; 1504 int scr; 1505 1506 demo->connection = xcb_connect(NULL, &scr); 1507 1508 setup = xcb_get_setup(demo->connection); 1509 iter = xcb_setup_roots_iterator(setup); 1510 while (scr-- > 0) 1511 xcb_screen_next(&iter); 1512 1513 demo->screen = iter.data; 1514} 1515 1516static void demo_init(struct demo *demo) 1517{ 1518 vec3 eye = {0.0f, 3.0f, 5.0f}; 1519 vec3 origin = {0, 0, 0}; 1520 vec3 up = {0.0f, -1.0f, 0.0}; 1521 1522 memset(demo, 0, sizeof(*demo)); 1523 1524 demo_init_connection(demo); 1525 demo_init_xgl(demo); 1526 1527 demo->width = 500; 1528 demo->height = 500; 1529 demo->format = XGL_FMT_B8G8R8A8_UNORM; 1530 1531 demo->spin_angle = 0.01f; 1532 demo->spin_increment = 0.01f; 1533 demo->pause = false; 1534 1535 mat4x4_perspective(demo->projection_matrix, degreesToRadians(45.0f), 1.0f, 0.1f, 100.0f); 1536 mat4x4_look_at(demo->view_matrix, eye, origin, up); 1537 mat4x4_identity(demo->model_matrix); 1538} 1539 1540static void demo_cleanup(struct demo *demo) 1541{ 1542 XGL_UINT i, j; 1543 1544 xglDestroyObject(demo->desc_set); 1545 xglDestroyObject(demo->desc_region); 1546 1547 xglDestroyObject(demo->cmd); 1548 1549 xglDestroyObject(demo->viewport); 1550 xglDestroyObject(demo->raster); 1551 xglDestroyObject(demo->color_blend); 1552 xglDestroyObject(demo->depth_stencil); 1553 1554 xglDestroyObject(demo->pipeline); 1555 xglDestroyObject(demo->desc_layout_fs); 1556 xglDestroyObject(demo->desc_layout_vs); 1557 1558// xglFreeMemory(demo->vertices.mem); 1559 1560 for (i = 0; i < DEMO_TEXTURE_COUNT; i++) { 1561 xglDestroyObject(demo->textures[i].view); 1562 xglDestroyObject(demo->textures[i].image); 1563 for (j = 0; j < demo->textures[i].num_mem; j++) 1564 xglFreeMemory(demo->textures[i].mem[j]); 1565 xglDestroyObject(demo->textures[i].sampler); 1566 } 1567 1568 xglDestroyObject(demo->depth.view); 1569 xglDestroyObject(demo->depth.image); 1570 for (j = 0; j < demo->depth.num_mem; j++) 1571 xglFreeMemory(demo->depth.mem[j]); 1572 xglDestroyObject(demo->uniform_data.buf); 1573 for (j = 0; j < demo->uniform_data.num_mem; j++) 1574 xglFreeMemory(demo->uniform_data.mem[j]); 1575 1576 for (i = 0; i < DEMO_BUFFER_COUNT; i++) { 1577 xglDestroyObject(demo->buffers[i].fence); 1578 xglDestroyObject(demo->buffers[i].view); 1579 xglDestroyObject(demo->buffers[i].image); 1580 } 1581 1582 xglDestroyDevice(demo->device); 1583 1584 xcb_destroy_window(demo->connection, demo->window); 1585 xcb_disconnect(demo->connection); 1586} 1587 1588int main(void) 1589{ 1590 struct demo demo; 1591 1592 demo_init(&demo); 1593 1594 demo_prepare(&demo); 1595 demo_create_window(&demo); 1596 demo_run(&demo); 1597 1598 demo_cleanup(&demo); 1599 1600 return 0; 1601} 1602