tri.c revision aa86e0e5e5838279bcc0415bef887292d7d42383
1/* 2 * Draw a textured triangle with depth testing. This is written against Intel 3 * ICD. It does not do state transition nor object memory binding like it 4 * should. It also does no error checking. 5 */ 6 7#include <stdio.h> 8#include <stdlib.h> 9#include <string.h> 10#include <stdbool.h> 11#include <assert.h> 12 13#include <xcb/xcb.h> 14#include <xgl.h> 15#include <xglDbg.h> 16#include <xglWsiX11Ext.h> 17 18#include "icd-spv.h" 19 20#define DEMO_BUFFER_COUNT 2 21#define DEMO_TEXTURE_COUNT 1 22 23struct texture_objects { 24 XGL_SAMPLER sampler; 25 26 XGL_IMAGE image; 27 uint32_t num_mem; 28 XGL_GPU_MEMORY *mem; 29 XGL_IMAGE_VIEW view; 30 int32_t tex_width, tex_height; 31}; 32 33struct demo { 34 xcb_connection_t *connection; 35 xcb_screen_t *screen; 36 37 XGL_INSTANCE inst; 38 XGL_PHYSICAL_GPU gpu; 39 XGL_DEVICE device; 40 XGL_QUEUE queue; 41 XGL_PHYSICAL_GPU_QUEUE_PROPERTIES *queue_props; 42 uint32_t graphics_queue_node_index; 43 44 int width, height; 45 XGL_FORMAT format; 46 47 struct { 48 XGL_IMAGE image; 49 XGL_GPU_MEMORY mem; 50 51 XGL_COLOR_ATTACHMENT_VIEW view; 52 XGL_FENCE fence; 53 } buffers[DEMO_BUFFER_COUNT]; 54 55 struct { 56 XGL_FORMAT format; 57 58 XGL_IMAGE image; 59 uint32_t num_mem; 60 XGL_GPU_MEMORY *mem; 61 XGL_DEPTH_STENCIL_VIEW view; 62 } depth; 63 64 struct texture_objects textures[DEMO_TEXTURE_COUNT]; 65 66 struct { 67 XGL_BUFFER buf; 68 uint32_t num_mem; 69 XGL_GPU_MEMORY *mem; 70 71 XGL_PIPELINE_VERTEX_INPUT_CREATE_INFO vi; 72 XGL_VERTEX_INPUT_BINDING_DESCRIPTION vi_bindings[1]; 73 XGL_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION vi_attrs[2]; 74 } vertices; 75 76 XGL_DESCRIPTOR_SET_LAYOUT desc_layout; 77 XGL_PIPELINE pipeline; 78 79 XGL_DYNAMIC_VP_STATE_OBJECT viewport; 80 XGL_DYNAMIC_RS_STATE_OBJECT raster; 81 XGL_DYNAMIC_CB_STATE_OBJECT color_blend; 82 XGL_DYNAMIC_DS_STATE_OBJECT depth_stencil; 83 84 XGL_CMD_BUFFER cmd; 85 86 XGL_DESCRIPTOR_REGION desc_region; 87 XGL_DESCRIPTOR_SET desc_set; 88 89 xcb_window_t window; 90 xcb_intern_atom_reply_t *atom_wm_delete_window; 91 92 bool quit; 93 bool use_staging_buffer; 94 uint32_t current_buffer; 95}; 96 97static void demo_draw_build_cmd(struct demo *demo) 98{ 99 const XGL_COLOR_ATTACHMENT_BIND_INFO color_attachment = { 100 .view = demo->buffers[demo->current_buffer].view, 101 .layout = XGL_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 102 }; 103 const XGL_DEPTH_STENCIL_BIND_INFO depth_stencil = { 104 .view = demo->depth.view, 105 .layout = XGL_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 106 }; 107 const XGL_CLEAR_COLOR clear_color = { 108 .color.floatColor = { 0.2f, 0.2f, 0.2f, 0.2f }, 109 .useRawValue = false, 110 }; 111 const float clear_depth = 0.9f; 112 XGL_IMAGE_SUBRESOURCE_RANGE clear_range; 113 XGL_CMD_BUFFER_BEGIN_INFO cmd_buf_info = { 114 .sType = XGL_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO, 115 .pNext = NULL, 116 .flags = XGL_CMD_BUFFER_OPTIMIZE_GPU_SMALL_BATCH_BIT | 117 XGL_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT, 118 }; 119 XGL_RESULT err; 120 XGL_ATTACHMENT_LOAD_OP load_op = XGL_ATTACHMENT_LOAD_OP_DONT_CARE; 121 XGL_ATTACHMENT_STORE_OP store_op = XGL_ATTACHMENT_STORE_OP_DONT_CARE; 122 const XGL_FRAMEBUFFER_CREATE_INFO fb_info = { 123 .sType = XGL_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, 124 .pNext = NULL, 125 .colorAttachmentCount = 1, 126 .pColorAttachments = (XGL_COLOR_ATTACHMENT_BIND_INFO*) &color_attachment, 127 .pDepthStencilAttachment = (XGL_DEPTH_STENCIL_BIND_INFO*) &depth_stencil, 128 .sampleCount = 1, 129 .width = demo->width, 130 .height = demo->height, 131 .layers = 1, 132 }; 133 XGL_RENDER_PASS_CREATE_INFO rp_info; 134 XGL_RENDER_PASS_BEGIN rp_begin; 135 136 memset(&rp_info, 0 , sizeof(rp_info)); 137 err = xglCreateFramebuffer(demo->device, &fb_info, &rp_begin.framebuffer); 138 assert(!err); 139 rp_info.sType = XGL_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; 140 rp_info.renderArea.extent.width = demo->width; 141 rp_info.renderArea.extent.height = demo->height; 142 rp_info.colorAttachmentCount = fb_info.colorAttachmentCount; 143 rp_info.pColorFormats = &demo->format; 144 rp_info.pColorLayouts = &color_attachment.layout; 145 rp_info.pColorLoadOps = &load_op; 146 rp_info.pColorStoreOps = &store_op; 147 rp_info.pColorLoadClearValues = &clear_color; 148 rp_info.depthStencilFormat = XGL_FMT_D16_UNORM; 149 rp_info.depthStencilLayout = depth_stencil.layout; 150 rp_info.depthLoadOp = XGL_ATTACHMENT_LOAD_OP_DONT_CARE; 151 rp_info.depthLoadClearValue = clear_depth; 152 rp_info.depthStoreOp = XGL_ATTACHMENT_STORE_OP_DONT_CARE; 153 rp_info.stencilLoadOp = XGL_ATTACHMENT_LOAD_OP_DONT_CARE; 154 rp_info.stencilLoadClearValue = 0; 155 rp_info.stencilStoreOp = XGL_ATTACHMENT_STORE_OP_DONT_CARE; 156 err = xglCreateRenderPass(demo->device, &rp_info, &(rp_begin.renderPass)); 157 assert(!err); 158 159 err = xglBeginCommandBuffer(demo->cmd, &cmd_buf_info); 160 assert(!err); 161 162 xglCmdBindPipeline(demo->cmd, XGL_PIPELINE_BIND_POINT_GRAPHICS, 163 demo->pipeline); 164 xglCmdBindDescriptorSet(demo->cmd, XGL_PIPELINE_BIND_POINT_GRAPHICS, 165 demo->desc_set, NULL); 166 167 xglCmdBindDynamicStateObject(demo->cmd, XGL_STATE_BIND_VIEWPORT, demo->viewport); 168 xglCmdBindDynamicStateObject(demo->cmd, XGL_STATE_BIND_RASTER, demo->raster); 169 xglCmdBindDynamicStateObject(demo->cmd, XGL_STATE_BIND_COLOR_BLEND, 170 demo->color_blend); 171 xglCmdBindDynamicStateObject(demo->cmd, XGL_STATE_BIND_DEPTH_STENCIL, 172 demo->depth_stencil); 173 174 175 xglCmdBindVertexBuffer(demo->cmd, demo->vertices.buf, 0, 0); 176 177 xglCmdBeginRenderPass(demo->cmd, &rp_begin); 178 clear_range.aspect = XGL_IMAGE_ASPECT_COLOR; 179 clear_range.baseMipLevel = 0; 180 clear_range.mipLevels = 1; 181 clear_range.baseArraySlice = 0; 182 clear_range.arraySize = 1; 183 xglCmdClearColorImage(demo->cmd, 184 demo->buffers[demo->current_buffer].image, 185 clear_color, 1, &clear_range); 186 187 clear_range.aspect = XGL_IMAGE_ASPECT_DEPTH; 188 xglCmdClearDepthStencil(demo->cmd, demo->depth.image, 189 clear_depth, 0, 1, &clear_range); 190 191 xglCmdDraw(demo->cmd, 0, 3, 0, 1); 192 xglCmdEndRenderPass(demo->cmd, rp_begin.renderPass); 193 194 err = xglEndCommandBuffer(demo->cmd); 195 assert(!err); 196 197 xglDestroyObject(rp_begin.renderPass); 198 xglDestroyObject(rp_begin.framebuffer); 199} 200 201static void demo_draw(struct demo *demo) 202{ 203 const XGL_WSI_X11_PRESENT_INFO present = { 204 .destWindow = demo->window, 205 .srcImage = demo->buffers[demo->current_buffer].image, 206 }; 207 XGL_FENCE fence = demo->buffers[demo->current_buffer].fence; 208 XGL_RESULT err; 209 210 demo_draw_build_cmd(demo); 211 212 err = xglWaitForFences(demo->device, 1, &fence, XGL_TRUE, ~((uint64_t) 0)); 213 assert(err == XGL_SUCCESS || err == XGL_ERROR_UNAVAILABLE); 214 215 uint32_t i, idx = 0; 216 XGL_MEMORY_REF *memRefs = 0; 217 memRefs = malloc(sizeof(XGL_MEMORY_REF) * (DEMO_BUFFER_COUNT + 218 demo->depth.num_mem + demo->textures[0].num_mem + 219 demo->vertices.num_mem)); 220 for (i = 0; i < demo->depth.num_mem; i++, idx++) { 221 memRefs[idx].mem = demo->depth.mem[i]; 222 memRefs[idx].flags = 0; 223 } 224 for (i = 0; i < demo->textures[0].num_mem; i++, idx++) { 225 memRefs[idx].mem = demo->textures[0].mem[i]; 226 memRefs[idx].flags = 0; 227 } 228 for (i = 0; i < DEMO_BUFFER_COUNT; i++) { 229 memRefs[idx].mem = demo->buffers[i].mem; 230 memRefs[idx++].flags = 0; 231 } 232 for (i = 0; i < demo->vertices.num_mem; i++, idx++) { 233 memRefs[idx].mem = demo->vertices.mem[i]; 234 memRefs[idx].flags = 0; 235 } 236 err = xglQueueSubmit(demo->queue, 1, &demo->cmd, 237 idx, memRefs, XGL_NULL_HANDLE); 238 assert(!err); 239 240 err = xglWsiX11QueuePresent(demo->queue, &present, fence); 241 assert(!err); 242 243 demo->current_buffer = (demo->current_buffer + 1) % DEMO_BUFFER_COUNT; 244} 245 246static void demo_prepare_buffers(struct demo *demo) 247{ 248 const XGL_WSI_X11_PRESENTABLE_IMAGE_CREATE_INFO presentable_image = { 249 .format = demo->format, 250 .usage = XGL_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 251 .extent = { 252 .width = demo->width, 253 .height = demo->height, 254 }, 255 .flags = 0, 256 }; 257 const XGL_FENCE_CREATE_INFO fence = { 258 .sType = XGL_STRUCTURE_TYPE_FENCE_CREATE_INFO, 259 .pNext = NULL, 260 .flags = 0, 261 }; 262 XGL_RESULT err; 263 uint32_t i; 264 265 for (i = 0; i < DEMO_BUFFER_COUNT; i++) { 266 XGL_COLOR_ATTACHMENT_VIEW_CREATE_INFO color_attachment_view = { 267 .sType = XGL_STRUCTURE_TYPE_COLOR_ATTACHMENT_VIEW_CREATE_INFO, 268 .pNext = NULL, 269 .format = demo->format, 270 .mipLevel = 0, 271 .baseArraySlice = 0, 272 .arraySize = 1, 273 }; 274 275 err = xglWsiX11CreatePresentableImage(demo->device, &presentable_image, 276 &demo->buffers[i].image, &demo->buffers[i].mem); 277 assert(!err); 278 279 color_attachment_view.image = demo->buffers[i].image; 280 281 err = xglCreateColorAttachmentView(demo->device, 282 &color_attachment_view, &demo->buffers[i].view); 283 assert(!err); 284 285 err = xglCreateFence(demo->device, 286 &fence, &demo->buffers[i].fence); 287 assert(!err); 288 } 289 290 demo->current_buffer = 0; 291} 292 293static void demo_prepare_depth(struct demo *demo) 294{ 295 const XGL_FORMAT depth_format = XGL_FMT_D16_UNORM; 296 const XGL_IMAGE_CREATE_INFO image = { 297 .sType = XGL_STRUCTURE_TYPE_IMAGE_CREATE_INFO, 298 .pNext = NULL, 299 .imageType = XGL_IMAGE_2D, 300 .format = depth_format, 301 .extent = { demo->width, demo->height, 1 }, 302 .mipLevels = 1, 303 .arraySize = 1, 304 .samples = 1, 305 .tiling = XGL_OPTIMAL_TILING, 306 .usage = XGL_IMAGE_USAGE_DEPTH_STENCIL_BIT, 307 .flags = 0, 308 }; 309 XGL_MEMORY_ALLOC_IMAGE_INFO img_alloc = { 310 .sType = XGL_STRUCTURE_TYPE_MEMORY_ALLOC_IMAGE_INFO, 311 .pNext = NULL, 312 }; 313 XGL_MEMORY_ALLOC_INFO mem_alloc = { 314 .sType = XGL_STRUCTURE_TYPE_MEMORY_ALLOC_INFO, 315 .pNext = &img_alloc, 316 .allocationSize = 0, 317 .memProps = XGL_MEMORY_PROPERTY_GPU_ONLY, 318 .memType = XGL_MEMORY_TYPE_IMAGE, 319 .memPriority = XGL_MEMORY_PRIORITY_NORMAL, 320 }; 321 XGL_DEPTH_STENCIL_VIEW_CREATE_INFO view = { 322 .sType = XGL_STRUCTURE_TYPE_DEPTH_STENCIL_VIEW_CREATE_INFO, 323 .pNext = NULL, 324 .image = XGL_NULL_HANDLE, 325 .mipLevel = 0, 326 .baseArraySlice = 0, 327 .arraySize = 1, 328 .flags = 0, 329 }; 330 331 XGL_MEMORY_REQUIREMENTS *mem_reqs; 332 size_t mem_reqs_size = sizeof(XGL_MEMORY_REQUIREMENTS); 333 XGL_IMAGE_MEMORY_REQUIREMENTS img_reqs; 334 size_t img_reqs_size = sizeof(XGL_IMAGE_MEMORY_REQUIREMENTS); 335 XGL_RESULT err; 336 uint32_t num_allocations = 0; 337 size_t num_alloc_size = sizeof(num_allocations); 338 339 demo->depth.format = depth_format; 340 341 /* create image */ 342 err = xglCreateImage(demo->device, &image, 343 &demo->depth.image); 344 assert(!err); 345 346 347 err = xglGetObjectInfo(demo->depth.image, XGL_INFO_TYPE_MEMORY_ALLOCATION_COUNT, &num_alloc_size, &num_allocations); 348 assert(!err && num_alloc_size == sizeof(num_allocations)); 349 mem_reqs = malloc(num_allocations * sizeof(XGL_MEMORY_REQUIREMENTS)); 350 demo->depth.mem = malloc(num_allocations * sizeof(XGL_GPU_MEMORY)); 351 demo->depth.num_mem = num_allocations; 352 err = xglGetObjectInfo(demo->depth.image, 353 XGL_INFO_TYPE_MEMORY_REQUIREMENTS, 354 &mem_reqs_size, mem_reqs); 355 assert(!err && mem_reqs_size == num_allocations * sizeof(XGL_MEMORY_REQUIREMENTS)); 356 err = xglGetObjectInfo(demo->depth.image, 357 XGL_INFO_TYPE_IMAGE_MEMORY_REQUIREMENTS, 358 &img_reqs_size, &img_reqs); 359 assert(!err && img_reqs_size == sizeof(XGL_IMAGE_MEMORY_REQUIREMENTS)); 360 img_alloc.usage = img_reqs.usage; 361 img_alloc.formatClass = img_reqs.formatClass; 362 img_alloc.samples = img_reqs.samples; 363 for (uint32_t i = 0; i < num_allocations; i ++) { 364 mem_alloc.allocationSize = mem_reqs[i].size; 365 366 /* allocate memory */ 367 err = xglAllocMemory(demo->device, &mem_alloc, 368 &(demo->depth.mem[i])); 369 assert(!err); 370 371 /* bind memory */ 372 err = xglBindObjectMemory(demo->depth.image, i, 373 demo->depth.mem[i], 0); 374 assert(!err); 375 } 376 377 /* create image view */ 378 view.image = demo->depth.image; 379 err = xglCreateDepthStencilView(demo->device, &view, 380 &demo->depth.view); 381 assert(!err); 382} 383 384static void demo_prepare_texture_image(struct demo *demo, 385 const uint32_t *tex_colors, 386 struct texture_objects *tex_objs, 387 XGL_IMAGE_TILING tiling, 388 XGL_FLAGS mem_props) 389{ 390 const XGL_FORMAT tex_format = XGL_FMT_B8G8R8A8_UNORM; 391 const int32_t tex_width = 2; 392 const int32_t tex_height = 2; 393 XGL_RESULT err; 394 395 tex_objs->tex_width = tex_width; 396 tex_objs->tex_height = tex_height; 397 398 const XGL_IMAGE_CREATE_INFO image_create_info = { 399 .sType = XGL_STRUCTURE_TYPE_IMAGE_CREATE_INFO, 400 .pNext = NULL, 401 .imageType = XGL_IMAGE_2D, 402 .format = tex_format, 403 .extent = { tex_width, tex_height, 1 }, 404 .mipLevels = 1, 405 .arraySize = 1, 406 .samples = 1, 407 .tiling = tiling, 408 .usage = XGL_IMAGE_USAGE_TRANSFER_SOURCE_BIT, 409 .flags = 0, 410 }; 411 XGL_MEMORY_ALLOC_IMAGE_INFO img_alloc = { 412 .sType = XGL_STRUCTURE_TYPE_MEMORY_ALLOC_IMAGE_INFO, 413 .pNext = NULL, 414 }; 415 XGL_MEMORY_ALLOC_INFO mem_alloc = { 416 .sType = XGL_STRUCTURE_TYPE_MEMORY_ALLOC_INFO, 417 .pNext = &img_alloc, 418 .allocationSize = 0, 419 .memProps = mem_props, 420 .memType = XGL_MEMORY_TYPE_IMAGE, 421 .memPriority = XGL_MEMORY_PRIORITY_NORMAL, 422 }; 423 424 XGL_MEMORY_REQUIREMENTS *mem_reqs; 425 size_t mem_reqs_size = sizeof(XGL_MEMORY_REQUIREMENTS); 426 XGL_IMAGE_MEMORY_REQUIREMENTS img_reqs; 427 size_t img_reqs_size = sizeof(XGL_IMAGE_MEMORY_REQUIREMENTS); 428 uint32_t num_allocations = 0; 429 size_t num_alloc_size = sizeof(num_allocations); 430 431 err = xglCreateImage(demo->device, &image_create_info, 432 &tex_objs->image); 433 assert(!err); 434 435 err = xglGetObjectInfo(tex_objs->image, 436 XGL_INFO_TYPE_MEMORY_ALLOCATION_COUNT, 437 &num_alloc_size, &num_allocations); 438 assert(!err && num_alloc_size == sizeof(num_allocations)); 439 mem_reqs = malloc(num_allocations * sizeof(XGL_MEMORY_REQUIREMENTS)); 440 tex_objs->mem = malloc(num_allocations * sizeof(XGL_GPU_MEMORY)); 441 err = xglGetObjectInfo(tex_objs->image, 442 XGL_INFO_TYPE_MEMORY_REQUIREMENTS, 443 &mem_reqs_size, mem_reqs); 444 assert(!err && mem_reqs_size == num_allocations * sizeof(XGL_MEMORY_REQUIREMENTS)); 445 err = xglGetObjectInfo(tex_objs->image, 446 XGL_INFO_TYPE_IMAGE_MEMORY_REQUIREMENTS, 447 &img_reqs_size, &img_reqs); 448 assert(!err && img_reqs_size == sizeof(XGL_IMAGE_MEMORY_REQUIREMENTS)); 449 img_alloc.usage = img_reqs.usage; 450 img_alloc.formatClass = img_reqs.formatClass; 451 img_alloc.samples = img_reqs.samples; 452 mem_alloc.memProps = XGL_MEMORY_PROPERTY_CPU_VISIBLE_BIT; 453 for (uint32_t j = 0; j < num_allocations; j ++) { 454 mem_alloc.allocationSize = mem_reqs[j].size; 455 mem_alloc.memType = mem_reqs[j].memType; 456 457 /* allocate memory */ 458 err = xglAllocMemory(demo->device, &mem_alloc, 459 &(tex_objs->mem[j])); 460 assert(!err); 461 462 /* bind memory */ 463 err = xglBindObjectMemory(tex_objs->image, j, tex_objs->mem[j], 0); 464 assert(!err); 465 } 466 free(mem_reqs); 467 mem_reqs = NULL; 468 469 tex_objs->num_mem = num_allocations; 470 471 if (mem_props & XGL_MEMORY_PROPERTY_CPU_VISIBLE_BIT) { 472 const XGL_IMAGE_SUBRESOURCE subres = { 473 .aspect = XGL_IMAGE_ASPECT_COLOR, 474 .mipLevel = 0, 475 .arraySlice = 0, 476 }; 477 XGL_SUBRESOURCE_LAYOUT layout; 478 size_t layout_size = sizeof(XGL_SUBRESOURCE_LAYOUT); 479 void *data; 480 int32_t x, y; 481 482 err = xglGetImageSubresourceInfo(tex_objs->image, &subres, 483 XGL_INFO_TYPE_SUBRESOURCE_LAYOUT, 484 &layout_size, &layout); 485 assert(!err && layout_size == sizeof(layout)); 486 /* Linear texture must be within a single memory object */ 487 assert(num_allocations == 1); 488 489 err = xglMapMemory(tex_objs->mem[0], 0, &data); 490 assert(!err); 491 492 for (y = 0; y < tex_height; y++) { 493 uint32_t *row = (uint32_t *) ((char *) data + layout.rowPitch * y); 494 for (x = 0; x < tex_width; x++) 495 row[x] = tex_colors[(x & 1) ^ (y & 1)]; 496 } 497 498 err = xglUnmapMemory(tex_objs->mem[0]); 499 assert(!err); 500 } 501} 502 503static void demo_destroy_texture_image(struct texture_objects *tex_objs) 504{ 505 /* clean up staging resources */ 506 for (uint32_t j = 0; j < tex_objs->num_mem; j ++) { 507 xglBindObjectMemory(tex_objs->image, j, XGL_NULL_HANDLE, 0); 508 xglFreeMemory(tex_objs->mem[j]); 509 } 510 511 free(tex_objs->mem); 512 xglDestroyObject(tex_objs->image); 513} 514 515static void demo_prepare_textures(struct demo *demo) 516{ 517 const XGL_FORMAT tex_format = XGL_FMT_B8G8R8A8_UNORM; 518 XGL_FORMAT_PROPERTIES props; 519 size_t size = sizeof(props); 520 const uint32_t tex_colors[DEMO_TEXTURE_COUNT][2] = { 521 { 0xffff0000, 0xff00ff00 }, 522 }; 523 XGL_RESULT err; 524 uint32_t i; 525 526 err = xglGetFormatInfo(demo->device, tex_format, 527 XGL_INFO_TYPE_FORMAT_PROPERTIES, 528 &size, &props); 529 assert(!err); 530 531 for (i = 0; i < DEMO_TEXTURE_COUNT; i++) { 532 if ((props.linearTilingFeatures & XGL_FORMAT_IMAGE_SHADER_READ_BIT) && !demo->use_staging_buffer) { 533 /* Device can texture using linear textures */ 534 demo_prepare_texture_image(demo, tex_colors[i], &demo->textures[i], 535 XGL_LINEAR_TILING, XGL_MEMORY_PROPERTY_CPU_VISIBLE_BIT); 536 } else if (props.optimalTilingFeatures & XGL_FORMAT_IMAGE_SHADER_READ_BIT){ 537 /* Must use staging buffer to copy linear texture to optimized */ 538 struct texture_objects staging_texture; 539 540 memset(&staging_texture, 0, sizeof(staging_texture)); 541 demo_prepare_texture_image(demo, tex_colors[i], &staging_texture, 542 XGL_LINEAR_TILING, XGL_MEMORY_PROPERTY_CPU_VISIBLE_BIT); 543 544 demo_prepare_texture_image(demo, tex_colors[i], &demo->textures[i], 545 XGL_OPTIMAL_TILING, XGL_MEMORY_PROPERTY_GPU_ONLY); 546 547 XGL_CMD_BUFFER staging_cmd_buf; 548 XGL_CMD_BUFFER_CREATE_INFO cmd_buf_create_info = { 549 .sType = XGL_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO, 550 .pNext = NULL, 551 .queueNodeIndex = demo->graphics_queue_node_index, 552 .flags = 0 553 }; 554 555 err = xglCreateCommandBuffer(demo->device, &cmd_buf_create_info, &staging_cmd_buf); 556 assert(!err); 557 558 /* Copy staging texture to usable texture */ 559 XGL_CMD_BUFFER_BEGIN_INFO cmd_buf_begin_info = { 560 .sType = XGL_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO, 561 .pNext = NULL, 562 .flags = 0 563 }; 564 565 err = xglResetCommandBuffer(staging_cmd_buf); 566 assert(!err); 567 568 err = xglBeginCommandBuffer(staging_cmd_buf, &cmd_buf_begin_info); 569 assert(!err); 570 571 XGL_IMAGE_COPY copy_region = { 572 .srcSubresource = { XGL_IMAGE_ASPECT_COLOR, 0, 0 }, 573 .srcOffset = { 0, 0, 0 }, 574 .destSubresource = { XGL_IMAGE_ASPECT_COLOR, 0, 0 }, 575 .destOffset = { 0, 0, 0 }, 576 .extent = { staging_texture.tex_width, staging_texture.tex_height, 1 }, 577 }; 578 xglCmdCopyImage(staging_cmd_buf, staging_texture.image, demo->textures[i].image, 1, ©_region); 579 580 XGL_IMAGE_MEMORY_BARRIER image_memory_barrier = { 581 .sType = XGL_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, 582 .pNext = NULL, 583 .outputMask = XGL_MEMORY_OUTPUT_COPY_BIT, 584 .inputMask = XGL_MEMORY_INPUT_SHADER_READ_BIT | XGL_MEMORY_INPUT_COPY_BIT, 585 .oldLayout = XGL_IMAGE_LAYOUT_GENERAL, 586 .newLayout = XGL_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL, 587 .image = staging_texture.image, 588 .subresourceRange = { XGL_IMAGE_ASPECT_COLOR, 0, 1, 0, 0 } 589 }; 590 XGL_IMAGE_MEMORY_BARRIER *pmemory_barrier = &image_memory_barrier; 591 592 XGL_PIPE_EVENT set_events[] = { XGL_PIPE_EVENT_GPU_COMMANDS_COMPLETE }; 593 XGL_PIPELINE_BARRIER pipeline_barrier; 594 pipeline_barrier.sType = XGL_STRUCTURE_TYPE_PIPELINE_BARRIER; 595 pipeline_barrier.pNext = NULL; 596 pipeline_barrier.eventCount = 1; 597 pipeline_barrier.pEvents = set_events; 598 pipeline_barrier.waitEvent = XGL_WAIT_EVENT_TOP_OF_PIPE; 599 pipeline_barrier.memBarrierCount = 1; 600 pipeline_barrier.ppMemBarriers = (const void **)&pmemory_barrier; 601 602 // write barrier to the command buffer 603 xglCmdPipelineBarrier(staging_cmd_buf, &pipeline_barrier); 604 605 err = xglEndCommandBuffer(staging_cmd_buf); 606 assert(!err); 607 608 const XGL_CMD_BUFFER cmd_bufs[] = { staging_cmd_buf }; 609 XGL_MEMORY_REF mem_refs[16]; 610 uint32_t num_refs = 0; 611 612 for (uint32_t j = 0; j < staging_texture.num_mem; j++) { 613 mem_refs[num_refs].flags = XGL_MEMORY_REF_READ_ONLY_BIT; 614 mem_refs[num_refs].mem = staging_texture.mem[j]; 615 num_refs++; 616 assert(num_refs < 16); 617 } 618 619 for (uint32_t j = 0; j < demo->textures[i].num_mem; j++) { 620 mem_refs[num_refs].flags = XGL_MEMORY_REF_READ_ONLY_BIT; 621 mem_refs[num_refs].mem = demo->textures[i].mem[j]; 622 num_refs++; 623 assert(num_refs < 16); 624 } 625 626 err = xglQueueSubmit(demo->queue, 1, cmd_bufs, 627 num_refs, mem_refs, XGL_NULL_HANDLE); 628 assert(!err); 629 630 err = xglQueueWaitIdle(demo->queue); 631 assert(!err); 632 633 demo_destroy_texture_image(&staging_texture); 634 635 xglDestroyObject(staging_cmd_buf); 636 } else { 637 /* Can't support XGL_FMT_B8G8R8A8_UNORM !? */ 638 assert(!"No support for B8G8R8A8_UNORM as texture image format"); 639 } 640 641 const XGL_SAMPLER_CREATE_INFO sampler = { 642 .sType = XGL_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, 643 .pNext = NULL, 644 .magFilter = XGL_TEX_FILTER_NEAREST, 645 .minFilter = XGL_TEX_FILTER_NEAREST, 646 .mipMode = XGL_TEX_MIPMAP_BASE, 647 .addressU = XGL_TEX_ADDRESS_WRAP, 648 .addressV = XGL_TEX_ADDRESS_WRAP, 649 .addressW = XGL_TEX_ADDRESS_WRAP, 650 .mipLodBias = 0.0f, 651 .maxAnisotropy = 1, 652 .compareFunc = XGL_COMPARE_NEVER, 653 .minLod = 0.0f, 654 .maxLod = 0.0f, 655 .borderColorType = XGL_BORDER_COLOR_OPAQUE_WHITE, 656 }; 657 XGL_IMAGE_VIEW_CREATE_INFO view = { 658 .sType = XGL_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, 659 .pNext = NULL, 660 .image = XGL_NULL_HANDLE, 661 .viewType = XGL_IMAGE_VIEW_2D, 662 .format = tex_format, 663 .channels = { XGL_CHANNEL_SWIZZLE_R, 664 XGL_CHANNEL_SWIZZLE_G, 665 XGL_CHANNEL_SWIZZLE_B, 666 XGL_CHANNEL_SWIZZLE_A, }, 667 .subresourceRange = { XGL_IMAGE_ASPECT_COLOR, 0, 1, 0, 1 }, 668 .minLod = 0.0f, 669 }; 670 671 /* create sampler */ 672 err = xglCreateSampler(demo->device, &sampler, 673 &demo->textures[i].sampler); 674 assert(!err); 675 676 /* create image view */ 677 view.image = demo->textures[i].image; 678 err = xglCreateImageView(demo->device, &view, 679 &demo->textures[i].view); 680 assert(!err); 681 } 682} 683 684static void demo_prepare_vertices(struct demo *demo) 685{ 686 const float vb[3][5] = { 687 /* position texcoord */ 688 { -1.0f, -1.0f, -0.6f, 0.0f, 0.0f }, 689 { 1.0f, -1.0f, -0.5f, 1.0f, 0.0f }, 690 { 0.0f, 1.0f, 1.0f, 0.5f, 1.0f }, 691 }; 692 const XGL_BUFFER_CREATE_INFO buf_info = { 693 .sType = XGL_STRUCTURE_TYPE_BUFFER_CREATE_INFO, 694 .pNext = NULL, 695 .size = sizeof(vb), 696 .usage = XGL_BUFFER_USAGE_VERTEX_FETCH_BIT, 697 .flags = 0, 698 }; 699 XGL_MEMORY_ALLOC_BUFFER_INFO buf_alloc = { 700 .sType = XGL_STRUCTURE_TYPE_MEMORY_ALLOC_BUFFER_INFO, 701 .pNext = NULL, 702 }; 703 XGL_MEMORY_ALLOC_INFO mem_alloc = { 704 .sType = XGL_STRUCTURE_TYPE_MEMORY_ALLOC_INFO, 705 .pNext = &buf_alloc, 706 .allocationSize = 0, 707 .memProps = XGL_MEMORY_PROPERTY_CPU_VISIBLE_BIT, 708 .memType = XGL_MEMORY_TYPE_BUFFER, 709 .memPriority = XGL_MEMORY_PRIORITY_NORMAL, 710 }; 711 XGL_MEMORY_REQUIREMENTS *mem_reqs; 712 size_t mem_reqs_size = sizeof(XGL_MEMORY_REQUIREMENTS); 713 XGL_BUFFER_MEMORY_REQUIREMENTS buf_reqs; 714 size_t buf_reqs_size = sizeof(XGL_BUFFER_MEMORY_REQUIREMENTS); 715 uint32_t num_allocations = 0; 716 size_t num_alloc_size = sizeof(num_allocations); 717 XGL_RESULT err; 718 void *data; 719 720 memset(&demo->vertices, 0, sizeof(demo->vertices)); 721 722 err = xglCreateBuffer(demo->device, &buf_info, &demo->vertices.buf); 723 assert(!err); 724 725 err = xglGetObjectInfo(demo->vertices.buf, 726 XGL_INFO_TYPE_MEMORY_ALLOCATION_COUNT, 727 &num_alloc_size, &num_allocations); 728 assert(!err && num_alloc_size == sizeof(num_allocations)); 729 mem_reqs = malloc(num_allocations * sizeof(XGL_MEMORY_REQUIREMENTS)); 730 demo->vertices.mem = malloc(num_allocations * sizeof(XGL_GPU_MEMORY)); 731 demo->vertices.num_mem = num_allocations; 732 err = xglGetObjectInfo(demo->vertices.buf, 733 XGL_INFO_TYPE_MEMORY_REQUIREMENTS, 734 &mem_reqs_size, mem_reqs); 735 assert(!err && mem_reqs_size == sizeof(*mem_reqs)); 736 err = xglGetObjectInfo(demo->vertices.buf, 737 XGL_INFO_TYPE_BUFFER_MEMORY_REQUIREMENTS, 738 &buf_reqs_size, &buf_reqs); 739 assert(!err && buf_reqs_size == sizeof(XGL_BUFFER_MEMORY_REQUIREMENTS)); 740 buf_alloc.usage = buf_reqs.usage; 741 for (uint32_t i = 0; i < num_allocations; i ++) { 742 mem_alloc.allocationSize = mem_reqs[i].size; 743 744 err = xglAllocMemory(demo->device, &mem_alloc, &demo->vertices.mem[i]); 745 assert(!err); 746 747 err = xglMapMemory(demo->vertices.mem[i], 0, &data); 748 assert(!err); 749 750 memcpy(data, vb, sizeof(vb)); 751 752 err = xglUnmapMemory(demo->vertices.mem[i]); 753 assert(!err); 754 755 err = xglBindObjectMemory(demo->vertices.buf, i, demo->vertices.mem[i], 0); 756 assert(!err); 757 } 758 759 demo->vertices.vi.sType = XGL_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_CREATE_INFO; 760 demo->vertices.vi.pNext = NULL; 761 demo->vertices.vi.bindingCount = 1; 762 demo->vertices.vi.pVertexBindingDescriptions = demo->vertices.vi_bindings; 763 demo->vertices.vi.attributeCount = 2; 764 demo->vertices.vi.pVertexAttributeDescriptions = demo->vertices.vi_attrs; 765 766 demo->vertices.vi_bindings[0].strideInBytes = sizeof(vb[0]); 767 demo->vertices.vi_bindings[0].stepRate = XGL_VERTEX_INPUT_STEP_RATE_VERTEX; 768 769 demo->vertices.vi_attrs[0].binding = 0; 770 demo->vertices.vi_attrs[0].format = XGL_FMT_R32G32B32_SFLOAT; 771 demo->vertices.vi_attrs[0].offsetInBytes = 0; 772 773 demo->vertices.vi_attrs[1].binding = 0; 774 demo->vertices.vi_attrs[1].format = XGL_FMT_R32G32_SFLOAT; 775 demo->vertices.vi_attrs[1].offsetInBytes = sizeof(float) * 3; 776} 777 778static void demo_prepare_descriptor_layout(struct demo *demo) 779{ 780 const XGL_DESCRIPTOR_SET_LAYOUT_CREATE_INFO descriptor_layout = { 781 .sType = XGL_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, 782 .pNext = NULL, 783 .descriptorType = XGL_DESCRIPTOR_TYPE_SAMPLER_TEXTURE, 784 .count = DEMO_TEXTURE_COUNT, 785 .stageFlags = XGL_SHADER_STAGE_FLAGS_FRAGMENT_BIT, 786 .immutableSampler = XGL_NULL_HANDLE, 787 }; 788 const uint32_t bind_point = 0; 789 XGL_RESULT err; 790 791 err = xglCreateDescriptorSetLayout(demo->device, 792 XGL_SHADER_STAGE_FLAGS_ALL, &bind_point, 793 XGL_NULL_HANDLE, &descriptor_layout, 794 &demo->desc_layout); 795 assert(!err); 796} 797 798static XGL_SHADER demo_prepare_shader(struct demo *demo, 799 XGL_PIPELINE_SHADER_STAGE stage, 800 const void *code, 801 size_t size) 802{ 803 XGL_SHADER_CREATE_INFO createInfo; 804 XGL_SHADER shader; 805 XGL_RESULT err; 806 807 createInfo.sType = XGL_STRUCTURE_TYPE_SHADER_CREATE_INFO; 808 createInfo.pNext = NULL; 809 810 // Create fake SPV structure to feed GLSL 811 // to the driver "under the covers" 812 createInfo.codeSize = 3 * sizeof(uint32_t) + size + 1; 813 createInfo.pCode = malloc(createInfo.codeSize); 814 createInfo.flags = 0; 815 816 /* try version 0 first: XGL_PIPELINE_SHADER_STAGE followed by GLSL */ 817 ((uint32_t *) createInfo.pCode)[0] = ICD_SPV_MAGIC; 818 ((uint32_t *) createInfo.pCode)[1] = 0; 819 ((uint32_t *) createInfo.pCode)[2] = stage; 820 memcpy(((uint32_t *) createInfo.pCode + 3), code, size + 1); 821 822 err = xglCreateShader(demo->device, &createInfo, &shader); 823 if (err) { 824 free((void *) createInfo.pCode); 825 return NULL; 826 } 827 828 return shader; 829} 830 831static XGL_SHADER demo_prepare_vs(struct demo *demo) 832{ 833 static const char *vertShaderText = 834 "#version 140\n" 835 "#extension GL_ARB_explicit_attrib_location : require\n" 836 "layout(location = 0) in vec4 pos;\n" 837 "layout(location = 1) in vec2 attr;\n" 838 "out vec2 texcoord;\n" 839 "void main() {\n" 840 " texcoord = attr;\n" 841 " gl_Position = pos;\n" 842 "}\n"; 843 844 return demo_prepare_shader(demo, XGL_SHADER_STAGE_VERTEX, 845 (const void *) vertShaderText, 846 strlen(vertShaderText)); 847} 848 849static XGL_SHADER demo_prepare_fs(struct demo *demo) 850{ 851 static const char *fragShaderText = 852 "#version 140\n" 853 "uniform sampler2D tex;\n" 854 "in vec2 texcoord;\n" 855 "void main() {\n" 856 " gl_FragColor = texture(tex, texcoord);\n" 857 "}\n"; 858 859 return demo_prepare_shader(demo, XGL_SHADER_STAGE_FRAGMENT, 860 (const void *) fragShaderText, 861 strlen(fragShaderText)); 862} 863 864static void demo_prepare_pipeline(struct demo *demo) 865{ 866 XGL_GRAPHICS_PIPELINE_CREATE_INFO pipeline; 867 XGL_PIPELINE_VERTEX_INPUT_CREATE_INFO vi; 868 XGL_PIPELINE_IA_STATE_CREATE_INFO ia; 869 XGL_PIPELINE_RS_STATE_CREATE_INFO rs; 870 XGL_PIPELINE_CB_STATE_CREATE_INFO cb; 871 XGL_PIPELINE_DS_STATE_CREATE_INFO ds; 872 XGL_PIPELINE_SHADER_STAGE_CREATE_INFO vs; 873 XGL_PIPELINE_SHADER_STAGE_CREATE_INFO fs; 874 XGL_PIPELINE_VP_STATE_CREATE_INFO vp; 875 XGL_PIPELINE_MS_STATE_CREATE_INFO ms; 876 XGL_RESULT err; 877 878 memset(&pipeline, 0, sizeof(pipeline)); 879 pipeline.sType = XGL_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; 880 pipeline.lastSetLayout = demo->desc_layout; 881 882 vi = demo->vertices.vi; 883 884 memset(&ia, 0, sizeof(ia)); 885 ia.sType = XGL_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO; 886 ia.topology = XGL_TOPOLOGY_TRIANGLE_LIST; 887 888 memset(&rs, 0, sizeof(rs)); 889 rs.sType = XGL_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO; 890 rs.fillMode = XGL_FILL_SOLID; 891 rs.cullMode = XGL_CULL_NONE; 892 rs.frontFace = XGL_FRONT_FACE_CCW; 893 894 memset(&cb, 0, sizeof(cb)); 895 cb.sType = XGL_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO; 896 XGL_PIPELINE_CB_ATTACHMENT_STATE att_state[1]; 897 memset(att_state, 0, sizeof(att_state)); 898 att_state[0].format = demo->format; 899 att_state[0].channelWriteMask = 0xf; 900 att_state[0].blendEnable = XGL_FALSE; 901 cb.attachmentCount = 1; 902 cb.pAttachments = att_state; 903 904 905 memset(&vp, 0, sizeof(vp)); 906 vp.sType = XGL_STRUCTURE_TYPE_PIPELINE_VP_STATE_CREATE_INFO; 907 vp.numViewports = 1; 908 vp.clipOrigin = XGL_COORDINATE_ORIGIN_UPPER_LEFT; 909 910 memset(&ds, 0, sizeof(ds)); 911 ds.sType = XGL_STRUCTURE_TYPE_PIPELINE_DS_STATE_CREATE_INFO; 912 ds.format = demo->depth.format; 913 ds.depthTestEnable = XGL_TRUE; 914 ds.depthWriteEnable = XGL_TRUE; 915 ds.depthFunc = XGL_COMPARE_LESS_EQUAL; 916 ds.depthBoundsEnable = XGL_FALSE; 917 ds.back.stencilFailOp = XGL_STENCIL_OP_KEEP; 918 ds.back.stencilPassOp = XGL_STENCIL_OP_KEEP; 919 ds.back.stencilFunc = XGL_COMPARE_ALWAYS; 920 ds.stencilTestEnable = XGL_FALSE; 921 ds.front = ds.back; 922 923 memset(&vs, 0, sizeof(vs)); 924 vs.sType = XGL_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; 925 vs.shader.stage = XGL_SHADER_STAGE_VERTEX; 926 vs.shader.shader = demo_prepare_vs(demo); 927 vs.shader.linkConstBufferCount = 0; 928 929 memset(&fs, 0, sizeof(fs)); 930 fs.sType = XGL_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; 931 fs.shader.stage = XGL_SHADER_STAGE_FRAGMENT; 932 fs.shader.shader = demo_prepare_fs(demo); 933 934 memset(&ms, 0, sizeof(ms)); 935 ms.sType = XGL_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO; 936 ms.sampleMask = 1; 937 ms.multisampleEnable = XGL_FALSE; 938 ms.samples = 1; 939 940 pipeline.pNext = (const void *) &vi; 941 vi.pNext = (void *) &ia; 942 ia.pNext = (const void *) &rs; 943 rs.pNext = (const void *) &cb; 944 cb.pNext = (const void *) &ms; 945 ms.pNext = (const void *) &vp; 946 vp.pNext = (const void *) &ds; 947 ds.pNext = (const void *) &vs; 948 vs.pNext = (const void *) &fs; 949 950 err = xglCreateGraphicsPipeline(demo->device, &pipeline, &demo->pipeline); 951 assert(!err); 952 953 xglDestroyObject(vs.shader.shader); 954 xglDestroyObject(fs.shader.shader); 955} 956 957static void demo_prepare_dynamic_states(struct demo *demo) 958{ 959 XGL_DYNAMIC_VP_STATE_CREATE_INFO viewport_create; 960 XGL_DYNAMIC_RS_STATE_CREATE_INFO raster; 961 XGL_DYNAMIC_CB_STATE_CREATE_INFO color_blend; 962 XGL_DYNAMIC_DS_STATE_CREATE_INFO depth_stencil; 963 XGL_RESULT err; 964 965 memset(&viewport_create, 0, sizeof(viewport_create)); 966 viewport_create.sType = XGL_STRUCTURE_TYPE_DYNAMIC_VP_STATE_CREATE_INFO; 967 viewport_create.viewportAndScissorCount = 1; 968 XGL_VIEWPORT viewport; 969 memset(&viewport, 0, sizeof(viewport)); 970 viewport.height = (float) demo->height; 971 viewport.width = (float) demo->width; 972 viewport.minDepth = (float) 0.0f; 973 viewport.maxDepth = (float) 1.0f; 974 viewport_create.pViewports = &viewport; 975 XGL_RECT scissor; 976 memset(&scissor, 0, sizeof(scissor)); 977 scissor.extent.width = demo->width; 978 scissor.extent.height = demo->height; 979 scissor.offset.x = 0; 980 scissor.offset.y = 0; 981 viewport_create.pScissors = &scissor; 982 983 memset(&raster, 0, sizeof(raster)); 984 raster.sType = XGL_STRUCTURE_TYPE_DYNAMIC_RS_STATE_CREATE_INFO; 985 raster.pointSize = 1.0; 986 raster.lineWidth = 1.0; 987 988 memset(&color_blend, 0, sizeof(color_blend)); 989 color_blend.sType = XGL_STRUCTURE_TYPE_DYNAMIC_CB_STATE_CREATE_INFO; 990 color_blend.blendConst[0] = 1.0f; 991 color_blend.blendConst[1] = 1.0f; 992 color_blend.blendConst[2] = 1.0f; 993 color_blend.blendConst[3] = 1.0f; 994 995 memset(&depth_stencil, 0, sizeof(depth_stencil)); 996 depth_stencil.sType = XGL_STRUCTURE_TYPE_DYNAMIC_DS_STATE_CREATE_INFO; 997 depth_stencil.minDepth = 0.0f; 998 depth_stencil.maxDepth = 1.0f; 999 depth_stencil.stencilBackRef = 0; 1000 depth_stencil.stencilFrontRef = 0; 1001 depth_stencil.stencilReadMask = 0xff; 1002 depth_stencil.stencilWriteMask = 0xff; 1003 1004 err = xglCreateDynamicViewportState(demo->device, &viewport_create, &demo->viewport); 1005 assert(!err); 1006 1007 err = xglCreateDynamicRasterState(demo->device, &raster, &demo->raster); 1008 assert(!err); 1009 1010 err = xglCreateDynamicColorBlendState(demo->device, 1011 &color_blend, &demo->color_blend); 1012 assert(!err); 1013 1014 err = xglCreateDynamicDepthStencilState(demo->device, 1015 &depth_stencil, &demo->depth_stencil); 1016 assert(!err); 1017} 1018 1019static void demo_prepare_descriptor_region(struct demo *demo) 1020{ 1021 const XGL_DESCRIPTOR_TYPE_COUNT type_count = { 1022 .type = XGL_DESCRIPTOR_TYPE_SAMPLER_TEXTURE, 1023 .count = DEMO_TEXTURE_COUNT, 1024 }; 1025 const XGL_DESCRIPTOR_REGION_CREATE_INFO descriptor_region = { 1026 .sType = XGL_STRUCTURE_TYPE_DESCRIPTOR_REGION_CREATE_INFO, 1027 .pNext = NULL, 1028 .count = 1, 1029 .pTypeCount = &type_count, 1030 }; 1031 XGL_RESULT err; 1032 1033 err = xglCreateDescriptorRegion(demo->device, 1034 XGL_DESCRIPTOR_REGION_USAGE_ONE_SHOT, 1, 1035 &descriptor_region, &demo->desc_region); 1036 assert(!err); 1037} 1038 1039static void demo_prepare_descriptor_set(struct demo *demo) 1040{ 1041 XGL_IMAGE_VIEW_ATTACH_INFO view_info[DEMO_TEXTURE_COUNT]; 1042 XGL_SAMPLER_IMAGE_VIEW_INFO combined_info[DEMO_TEXTURE_COUNT]; 1043 XGL_UPDATE_SAMPLER_TEXTURES update; 1044 XGL_RESULT err; 1045 uint32_t count; 1046 uint32_t i; 1047 1048 for (i = 0; i < DEMO_TEXTURE_COUNT; i++) { 1049 view_info[i].sType = XGL_STRUCTURE_TYPE_IMAGE_VIEW_ATTACH_INFO; 1050 view_info[i].pNext = NULL; 1051 view_info[i].view = demo->textures[i].view, 1052 view_info[i].layout = XGL_IMAGE_LAYOUT_GENERAL; 1053 1054 combined_info[i].pSampler = demo->textures[i].sampler; 1055 combined_info[i].pImageView = &view_info[i]; 1056 } 1057 1058 memset(&update, 0, sizeof(update)); 1059 update.sType = XGL_STRUCTURE_TYPE_UPDATE_SAMPLER_TEXTURES; 1060 update.count = DEMO_TEXTURE_COUNT; 1061 update.pSamplerImageViews = combined_info; 1062 1063 err = xglAllocDescriptorSets(demo->desc_region, 1064 XGL_DESCRIPTOR_SET_USAGE_STATIC, 1065 1, &demo->desc_layout, 1066 &demo->desc_set, &count); 1067 assert(!err && count == 1); 1068 1069 xglBeginDescriptorRegionUpdate(demo->device, 1070 XGL_DESCRIPTOR_UPDATE_MODE_FASTEST); 1071 1072 xglClearDescriptorSets(demo->desc_region, 1, &demo->desc_set); 1073 xglUpdateDescriptors(demo->desc_set, &update); 1074 1075 xglEndDescriptorRegionUpdate(demo->device, demo->cmd); 1076} 1077 1078static void demo_prepare(struct demo *demo) 1079{ 1080 const XGL_CMD_BUFFER_CREATE_INFO cmd = { 1081 .sType = XGL_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO, 1082 .pNext = NULL, 1083 .queueNodeIndex = demo->graphics_queue_node_index, 1084 .flags = 0, 1085 }; 1086 XGL_RESULT err; 1087 1088 demo_prepare_buffers(demo); 1089 demo_prepare_depth(demo); 1090 demo_prepare_textures(demo); 1091 demo_prepare_vertices(demo); 1092 demo_prepare_descriptor_layout(demo); 1093 demo_prepare_pipeline(demo); 1094 demo_prepare_dynamic_states(demo); 1095 1096 err = xglCreateCommandBuffer(demo->device, &cmd, &demo->cmd); 1097 assert(!err); 1098 1099 demo_prepare_descriptor_region(demo); 1100 demo_prepare_descriptor_set(demo); 1101} 1102 1103static void demo_handle_event(struct demo *demo, 1104 const xcb_generic_event_t *event) 1105{ 1106 switch (event->response_type & 0x7f) { 1107 case XCB_EXPOSE: 1108 demo_draw(demo); 1109 break; 1110 case XCB_CLIENT_MESSAGE: 1111 if((*(xcb_client_message_event_t*)event).data.data32[0] == 1112 (*demo->atom_wm_delete_window).atom) { 1113 demo->quit = true; 1114 } 1115 break; 1116 case XCB_KEY_RELEASE: 1117 { 1118 const xcb_key_release_event_t *key = 1119 (const xcb_key_release_event_t *) event; 1120 1121 if (key->detail == 0x9) 1122 demo->quit = true; 1123 } 1124 break; 1125 case XCB_DESTROY_NOTIFY: 1126 demo->quit = true; 1127 break; 1128 default: 1129 break; 1130 } 1131} 1132 1133static void demo_run(struct demo *demo) 1134{ 1135 xcb_flush(demo->connection); 1136 1137 while (!demo->quit) { 1138 xcb_generic_event_t *event; 1139 1140 event = xcb_wait_for_event(demo->connection); 1141 if (event) { 1142 demo_handle_event(demo, event); 1143 free(event); 1144 } 1145 } 1146} 1147 1148static void demo_create_window(struct demo *demo) 1149{ 1150 uint32_t value_mask, value_list[32]; 1151 1152 demo->window = xcb_generate_id(demo->connection); 1153 1154 value_mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK; 1155 value_list[0] = demo->screen->black_pixel; 1156 value_list[1] = XCB_EVENT_MASK_KEY_RELEASE | 1157 XCB_EVENT_MASK_EXPOSURE | 1158 XCB_EVENT_MASK_STRUCTURE_NOTIFY; 1159 1160 xcb_create_window(demo->connection, 1161 XCB_COPY_FROM_PARENT, 1162 demo->window, demo->screen->root, 1163 0, 0, demo->width, demo->height, 0, 1164 XCB_WINDOW_CLASS_INPUT_OUTPUT, 1165 demo->screen->root_visual, 1166 value_mask, value_list); 1167 1168 /* Magic code that will send notification when window is destroyed */ 1169 xcb_intern_atom_cookie_t cookie = xcb_intern_atom(demo->connection, 1, 12, 1170 "WM_PROTOCOLS"); 1171 xcb_intern_atom_reply_t* reply = xcb_intern_atom_reply(demo->connection, cookie, 0); 1172 1173 xcb_intern_atom_cookie_t cookie2 = xcb_intern_atom(demo->connection, 0, 16, "WM_DELETE_WINDOW"); 1174 demo->atom_wm_delete_window = xcb_intern_atom_reply(demo->connection, cookie2, 0); 1175 1176 xcb_change_property(demo->connection, XCB_PROP_MODE_REPLACE, 1177 demo->window, (*reply).atom, 4, 32, 1, 1178 &(*demo->atom_wm_delete_window).atom); 1179 free(reply); 1180 1181 xcb_map_window(demo->connection, demo->window); 1182} 1183 1184static void demo_init_xgl(struct demo *demo) 1185{ 1186 const XGL_APPLICATION_INFO app = { 1187 .sType = XGL_STRUCTURE_TYPE_APPLICATION_INFO, 1188 .pNext = NULL, 1189 .pAppName = "tri", 1190 .appVersion = 0, 1191 .pEngineName = "tri", 1192 .engineVersion = 0, 1193 .apiVersion = XGL_API_VERSION, 1194 }; 1195 const XGL_WSI_X11_CONNECTION_INFO connection = { 1196 .pConnection = demo->connection, 1197 .root = demo->screen->root, 1198 .provider = 0, 1199 }; 1200 const XGL_DEVICE_QUEUE_CREATE_INFO queue = { 1201 .queueNodeIndex = 0, 1202 .queueCount = 1, 1203 }; 1204 const char *ext_names[] = { 1205 "XGL_WSI_X11", 1206 }; 1207 const XGL_DEVICE_CREATE_INFO device = { 1208 .sType = XGL_STRUCTURE_TYPE_DEVICE_CREATE_INFO, 1209 .pNext = NULL, 1210 .queueRecordCount = 1, 1211 .pRequestedQueues = &queue, 1212 .extensionCount = 1, 1213 .ppEnabledExtensionNames = ext_names, 1214 .maxValidationLevel = XGL_VALIDATION_LEVEL_END_RANGE, 1215 .flags = XGL_DEVICE_CREATE_VALIDATION_BIT, 1216 }; 1217 XGL_RESULT err; 1218 uint32_t gpu_count; 1219 uint32_t i; 1220 size_t data_size; 1221 uint32_t queue_count; 1222 1223 err = xglCreateInstance(&app, NULL, &demo->inst); 1224 if (err == XGL_ERROR_INCOMPATIBLE_DRIVER) { 1225 printf("Cannot find a compatible Vulkan installable client driver " 1226 "(ICD).\nExiting ...\n"); 1227 fflush(stdout); 1228 exit(1); 1229 } else { 1230 assert(!err); 1231 } 1232 err = xglEnumerateGpus(demo->inst, 1, &gpu_count, &demo->gpu); 1233 assert(!err && gpu_count == 1); 1234 1235 for (i = 0; i < device.extensionCount; i++) { 1236 err = xglGetExtensionSupport(demo->gpu, ext_names[i]); 1237 assert(!err); 1238 } 1239 1240 err = xglWsiX11AssociateConnection(demo->gpu, &connection); 1241 assert(!err); 1242 1243 err = xglCreateDevice(demo->gpu, &device, &demo->device); 1244 assert(!err); 1245 1246 err = xglGetGpuInfo(demo->gpu, XGL_INFO_TYPE_PHYSICAL_GPU_QUEUE_PROPERTIES, 1247 &data_size, NULL); 1248 assert(!err); 1249 1250 demo->queue_props = (XGL_PHYSICAL_GPU_QUEUE_PROPERTIES *) malloc(data_size); 1251 err = xglGetGpuInfo(demo->gpu, XGL_INFO_TYPE_PHYSICAL_GPU_QUEUE_PROPERTIES, 1252 &data_size, demo->queue_props); 1253 assert(!err); 1254 queue_count = data_size / sizeof(XGL_PHYSICAL_GPU_QUEUE_PROPERTIES); 1255 assert(queue_count >= 1); 1256 1257 for (i = 0; i < queue_count; i++) { 1258 if (demo->queue_props[i].queueFlags & XGL_QUEUE_GRAPHICS_BIT) 1259 break; 1260 } 1261 assert(i < queue_count); 1262 demo->graphics_queue_node_index = i; 1263 1264 err = xglGetDeviceQueue(demo->device, demo->graphics_queue_node_index, 1265 0, &demo->queue); 1266 assert(!err); 1267} 1268 1269static void demo_init_connection(struct demo *demo) 1270{ 1271 const xcb_setup_t *setup; 1272 xcb_screen_iterator_t iter; 1273 int scr; 1274 1275 demo->connection = xcb_connect(NULL, &scr); 1276 if (demo->connection == NULL) { 1277 printf("Cannot find a compatible Vulkan installable client driver " 1278 "(ICD).\nExiting ...\n"); 1279 fflush(stdout); 1280 exit(1); 1281 } 1282 1283 setup = xcb_get_setup(demo->connection); 1284 iter = xcb_setup_roots_iterator(setup); 1285 while (scr-- > 0) 1286 xcb_screen_next(&iter); 1287 1288 demo->screen = iter.data; 1289} 1290 1291static void demo_init(struct demo *demo, const int argc, const char *argv[]) 1292{ 1293 memset(demo, 0, sizeof(*demo)); 1294 1295 for (int i = 0; i < argc; i++) { 1296 if (strncmp(argv[i], "--use_staging", strlen("--use_staging")) == 0) 1297 demo->use_staging_buffer = true; 1298 } 1299 1300 demo_init_connection(demo); 1301 demo_init_xgl(demo); 1302 1303 demo->width = 300; 1304 demo->height = 300; 1305 demo->format = XGL_FMT_B8G8R8A8_UNORM; 1306} 1307 1308static void demo_cleanup(struct demo *demo) 1309{ 1310 uint32_t i, j; 1311 1312 xglDestroyObject(demo->desc_set); 1313 xglDestroyObject(demo->desc_region); 1314 1315 xglDestroyObject(demo->cmd); 1316 1317 xglDestroyObject(demo->viewport); 1318 xglDestroyObject(demo->raster); 1319 xglDestroyObject(demo->color_blend); 1320 xglDestroyObject(demo->depth_stencil); 1321 1322 xglDestroyObject(demo->pipeline); 1323 xglDestroyObject(demo->desc_layout); 1324 1325 xglBindObjectMemory(demo->vertices.buf, 0, XGL_NULL_HANDLE, 0); 1326 xglDestroyObject(demo->vertices.buf); 1327 for (j = 0; j < demo->vertices.num_mem; j++) 1328 xglFreeMemory(demo->vertices.mem[j]); 1329 1330 for (i = 0; i < DEMO_TEXTURE_COUNT; i++) { 1331 xglDestroyObject(demo->textures[i].view); 1332 xglBindObjectMemory(demo->textures[i].image, 0, XGL_NULL_HANDLE, 0); 1333 xglDestroyObject(demo->textures[i].image); 1334 for (j = 0; j < demo->textures[i].num_mem; j++) 1335 xglFreeMemory(demo->textures[i].mem[j]); 1336 free(demo->textures[i].mem); 1337 xglDestroyObject(demo->textures[i].sampler); 1338 } 1339 1340 xglDestroyObject(demo->depth.view); 1341 xglBindObjectMemory(demo->depth.image, 0, XGL_NULL_HANDLE, 0); 1342 xglDestroyObject(demo->depth.image); 1343 for (j = 0; j < demo->depth.num_mem; j++) 1344 xglFreeMemory(demo->depth.mem[j]); 1345 1346 for (i = 0; i < DEMO_BUFFER_COUNT; i++) { 1347 xglDestroyObject(demo->buffers[i].fence); 1348 xglDestroyObject(demo->buffers[i].view); 1349 xglDestroyObject(demo->buffers[i].image); 1350 } 1351 1352 xglDestroyDevice(demo->device); 1353 xglDestroyInstance(demo->inst); 1354 1355 xcb_destroy_window(demo->connection, demo->window); 1356 xcb_disconnect(demo->connection); 1357} 1358 1359int main(const int argc, const char *argv[]) 1360{ 1361 struct demo demo; 1362 1363 demo_init(&demo, argc, argv); 1364 1365 demo_prepare(&demo); 1366 demo_create_window(&demo); 1367 demo_run(&demo); 1368 1369 demo_cleanup(&demo); 1370 1371 return 0; 1372} 1373