1/* 2 * Copyright 2009 VMware, Inc. 3 * All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * on the rights to use, copy, modify, merge, publish, distribute, sub 9 * license, and/or sell copies of the Software, and to permit persons to whom 10 * the Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 19 * VMWARE AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 22 * USE OR OTHER DEALINGS IN THE SOFTWARE. 23 */ 24 25/* 26 * This file holds the function implementation for one of the rbug extensions. 27 * Prototypes and declerations of functions and structs is in the same folder 28 * in the header file matching this file's name. 29 * 30 * The functions starting rbug_send_* encodes a call to the write format and 31 * sends that to the supplied connection, while functions starting with 32 * rbug_demarshal_* demarshal data in the wire protocol. 33 * 34 * Functions ending with _reply are replies to requests. 35 */ 36 37#include "c99_alloca.h" 38 39#include "rbug_internal.h" 40#include "rbug_texture.h" 41 42int rbug_send_texture_list(struct rbug_connection *__con, 43 uint32_t *__serial) 44{ 45 uint32_t __len = 0; 46 uint32_t __pos = 0; 47 uint8_t *__data = NULL; 48 int __ret = 0; 49 50 LEN(8); /* header */ 51 52 /* align */ 53 PAD(__len, 8); 54 55 __data = (uint8_t*)MALLOC(__len); 56 if (!__data) 57 return -ENOMEM; 58 59 WRITE(4, int32_t, ((int32_t)RBUG_OP_TEXTURE_LIST)); 60 WRITE(4, uint32_t, ((uint32_t)(__len / 4))); 61 62 /* final pad */ 63 PAD(__pos, 8); 64 65 if (__pos != __len) { 66 __ret = -EINVAL; 67 } else { 68 rbug_connection_send_start(__con, RBUG_OP_TEXTURE_LIST, __len); 69 rbug_connection_write(__con, __data, __len); 70 __ret = rbug_connection_send_finish(__con, __serial); 71 } 72 73 FREE(__data); 74 return __ret; 75} 76 77int rbug_send_texture_info(struct rbug_connection *__con, 78 rbug_texture_t texture, 79 uint32_t *__serial) 80{ 81 uint32_t __len = 0; 82 uint32_t __pos = 0; 83 uint8_t *__data = NULL; 84 int __ret = 0; 85 86 LEN(8); /* header */ 87 LEN(8); /* texture */ 88 89 /* align */ 90 PAD(__len, 8); 91 92 __data = (uint8_t*)MALLOC(__len); 93 if (!__data) 94 return -ENOMEM; 95 96 WRITE(4, int32_t, ((int32_t)RBUG_OP_TEXTURE_INFO)); 97 WRITE(4, uint32_t, ((uint32_t)(__len / 4))); 98 WRITE(8, rbug_texture_t, texture); /* texture */ 99 100 /* final pad */ 101 PAD(__pos, 8); 102 103 if (__pos != __len) { 104 __ret = -EINVAL; 105 } else { 106 rbug_connection_send_start(__con, RBUG_OP_TEXTURE_INFO, __len); 107 rbug_connection_write(__con, __data, __len); 108 __ret = rbug_connection_send_finish(__con, __serial); 109 } 110 111 FREE(__data); 112 return __ret; 113} 114 115int rbug_send_texture_write(struct rbug_connection *__con, 116 rbug_texture_t texture, 117 uint32_t face, 118 uint32_t level, 119 uint32_t zslice, 120 uint32_t x, 121 uint32_t y, 122 uint32_t w, 123 uint32_t h, 124 uint8_t *data, 125 uint32_t data_len, 126 uint32_t stride, 127 uint32_t *__serial) 128{ 129 uint32_t __len = 0; 130 uint32_t __pos = 0; 131 uint8_t *__data = NULL; 132 int __ret = 0; 133 134 LEN(8); /* header */ 135 LEN(8); /* texture */ 136 LEN(4); /* face */ 137 LEN(4); /* level */ 138 LEN(4); /* zslice */ 139 LEN(4); /* x */ 140 LEN(4); /* y */ 141 LEN(4); /* w */ 142 LEN(4); /* h */ 143 LEN_ARRAY(1, data); /* data */ 144 LEN(4); /* stride */ 145 146 /* align */ 147 PAD(__len, 8); 148 149 __data = (uint8_t*)MALLOC(__len); 150 if (!__data) 151 return -ENOMEM; 152 153 WRITE(4, int32_t, ((int32_t)RBUG_OP_TEXTURE_WRITE)); 154 WRITE(4, uint32_t, ((uint32_t)(__len / 4))); 155 WRITE(8, rbug_texture_t, texture); /* texture */ 156 WRITE(4, uint32_t, face); /* face */ 157 WRITE(4, uint32_t, level); /* level */ 158 WRITE(4, uint32_t, zslice); /* zslice */ 159 WRITE(4, uint32_t, x); /* x */ 160 WRITE(4, uint32_t, y); /* y */ 161 WRITE(4, uint32_t, w); /* w */ 162 WRITE(4, uint32_t, h); /* h */ 163 WRITE_ARRAY(1, uint8_t, data); /* data */ 164 WRITE(4, uint32_t, stride); /* stride */ 165 166 /* final pad */ 167 PAD(__pos, 8); 168 169 if (__pos != __len) { 170 __ret = -EINVAL; 171 } else { 172 rbug_connection_send_start(__con, RBUG_OP_TEXTURE_WRITE, __len); 173 rbug_connection_write(__con, __data, __len); 174 __ret = rbug_connection_send_finish(__con, __serial); 175 } 176 177 FREE(__data); 178 return __ret; 179} 180 181int rbug_send_texture_read(struct rbug_connection *__con, 182 rbug_texture_t texture, 183 uint32_t face, 184 uint32_t level, 185 uint32_t zslice, 186 uint32_t x, 187 uint32_t y, 188 uint32_t w, 189 uint32_t h, 190 uint32_t *__serial) 191{ 192 uint32_t __len = 0; 193 uint32_t __pos = 0; 194 uint8_t *__data = NULL; 195 int __ret = 0; 196 197 LEN(8); /* header */ 198 LEN(8); /* texture */ 199 LEN(4); /* face */ 200 LEN(4); /* level */ 201 LEN(4); /* zslice */ 202 LEN(4); /* x */ 203 LEN(4); /* y */ 204 LEN(4); /* w */ 205 LEN(4); /* h */ 206 207 /* align */ 208 PAD(__len, 8); 209 210 __data = (uint8_t*)MALLOC(__len); 211 if (!__data) 212 return -ENOMEM; 213 214 WRITE(4, int32_t, ((int32_t)RBUG_OP_TEXTURE_READ)); 215 WRITE(4, uint32_t, ((uint32_t)(__len / 4))); 216 WRITE(8, rbug_texture_t, texture); /* texture */ 217 WRITE(4, uint32_t, face); /* face */ 218 WRITE(4, uint32_t, level); /* level */ 219 WRITE(4, uint32_t, zslice); /* zslice */ 220 WRITE(4, uint32_t, x); /* x */ 221 WRITE(4, uint32_t, y); /* y */ 222 WRITE(4, uint32_t, w); /* w */ 223 WRITE(4, uint32_t, h); /* h */ 224 225 /* final pad */ 226 PAD(__pos, 8); 227 228 if (__pos != __len) { 229 __ret = -EINVAL; 230 } else { 231 rbug_connection_send_start(__con, RBUG_OP_TEXTURE_READ, __len); 232 rbug_connection_write(__con, __data, __len); 233 __ret = rbug_connection_send_finish(__con, __serial); 234 } 235 236 FREE(__data); 237 return __ret; 238} 239 240int rbug_send_texture_list_reply(struct rbug_connection *__con, 241 uint32_t serial, 242 rbug_texture_t *textures, 243 uint32_t textures_len, 244 uint32_t *__serial) 245{ 246 uint32_t __len = 0; 247 uint32_t __pos = 0; 248 uint8_t *__data = NULL; 249 int __ret = 0; 250 251 LEN(8); /* header */ 252 LEN(4); /* serial */ 253 LEN_ARRAY(8, textures); /* textures */ 254 255 /* align */ 256 PAD(__len, 8); 257 258 __data = (uint8_t*)MALLOC(__len); 259 if (!__data) 260 return -ENOMEM; 261 262 WRITE(4, int32_t, ((int32_t)RBUG_OP_TEXTURE_LIST_REPLY)); 263 WRITE(4, uint32_t, ((uint32_t)(__len / 4))); 264 WRITE(4, uint32_t, serial); /* serial */ 265 WRITE_ARRAY(8, rbug_texture_t, textures); /* textures */ 266 267 /* final pad */ 268 PAD(__pos, 8); 269 270 if (__pos != __len) { 271 __ret = -EINVAL; 272 } else { 273 rbug_connection_send_start(__con, RBUG_OP_TEXTURE_LIST_REPLY, __len); 274 rbug_connection_write(__con, __data, __len); 275 __ret = rbug_connection_send_finish(__con, __serial); 276 } 277 278 FREE(__data); 279 return __ret; 280} 281 282int rbug_send_texture_info_reply(struct rbug_connection *__con, 283 uint32_t serial, 284 uint32_t target, 285 uint32_t format, 286 uint32_t *width, 287 uint32_t width_len, 288 uint16_t *h16, 289 uint32_t height_len, 290 uint16_t *d16, 291 uint32_t depth_len, 292 uint32_t blockw, 293 uint32_t blockh, 294 uint32_t blocksize, 295 uint32_t last_level, 296 uint32_t nr_samples, 297 uint32_t tex_usage, 298 uint32_t *__serial) 299{ 300 uint32_t __len = 0; 301 uint32_t __pos = 0; 302 uint8_t *__data = NULL; 303 int __ret = 0; 304 uint32_t *height = alloca(sizeof(uint32_t) * height_len); 305 uint32_t *depth = alloca(sizeof(uint32_t) * height_len); 306 307 LEN(8); /* header */ 308 LEN(4); /* serial */ 309 LEN(4); /* target */ 310 LEN(4); /* format */ 311 LEN_ARRAY(4, width); /* width */ 312 LEN_ARRAY(4, height); /* height */ 313 LEN_ARRAY(4, depth); /* depth */ 314 LEN(4); /* blockw */ 315 LEN(4); /* blockh */ 316 LEN(4); /* blocksize */ 317 LEN(4); /* last_level */ 318 LEN(4); /* nr_samples */ 319 LEN(4); /* tex_usage */ 320 321 /* align */ 322 PAD(__len, 8); 323 324 __data = (uint8_t*)MALLOC(__len); 325 if (!__data) 326 return -ENOMEM; 327 328 for (int i = 0; i < height_len; i++) 329 height[i] = h16[i]; 330 for (int i = 0; i < depth_len; i++) 331 depth[i] = d16[i]; 332 333 WRITE(4, int32_t, ((int32_t)RBUG_OP_TEXTURE_INFO_REPLY)); 334 WRITE(4, uint32_t, ((uint32_t)(__len / 4))); 335 WRITE(4, uint32_t, serial); /* serial */ 336 WRITE(4, uint32_t, target); /* target */ 337 WRITE(4, uint32_t, format); /* format */ 338 WRITE_ARRAY(4, uint32_t, width); /* width */ 339 WRITE_ARRAY(4, uint32_t, height); /* height */ 340 WRITE_ARRAY(4, uint32_t, depth); /* depth */ 341 WRITE(4, uint32_t, blockw); /* blockw */ 342 WRITE(4, uint32_t, blockh); /* blockh */ 343 WRITE(4, uint32_t, blocksize); /* blocksize */ 344 WRITE(4, uint32_t, last_level); /* last_level */ 345 WRITE(4, uint32_t, nr_samples); /* nr_samples */ 346 WRITE(4, uint32_t, tex_usage); /* tex_usage */ 347 348 /* final pad */ 349 PAD(__pos, 8); 350 351 if (__pos != __len) { 352 __ret = -EINVAL; 353 } else { 354 rbug_connection_send_start(__con, RBUG_OP_TEXTURE_INFO_REPLY, __len); 355 rbug_connection_write(__con, __data, __len); 356 __ret = rbug_connection_send_finish(__con, __serial); 357 } 358 359 FREE(__data); 360 return __ret; 361} 362 363int rbug_send_texture_read_reply(struct rbug_connection *__con, 364 uint32_t serial, 365 uint32_t format, 366 uint32_t blockw, 367 uint32_t blockh, 368 uint32_t blocksize, 369 uint8_t *data, 370 uint32_t data_len, 371 uint32_t stride, 372 uint32_t *__serial) 373{ 374 uint32_t __len = 0; 375 uint32_t __pos = 0; 376 uint8_t *__data = NULL; 377 int __ret = 0; 378 379 LEN(8); /* header */ 380 LEN(4); /* serial */ 381 LEN(4); /* format */ 382 LEN(4); /* blockw */ 383 LEN(4); /* blockh */ 384 LEN(4); /* blocksize */ 385 LEN_ARRAY(1, data); /* data */ 386 LEN(4); /* stride */ 387 388 /* align */ 389 PAD(__len, 8); 390 391 __data = (uint8_t*)MALLOC(__len); 392 if (!__data) 393 return -ENOMEM; 394 395 WRITE(4, int32_t, ((int32_t)RBUG_OP_TEXTURE_READ_REPLY)); 396 WRITE(4, uint32_t, ((uint32_t)(__len / 4))); 397 WRITE(4, uint32_t, serial); /* serial */ 398 WRITE(4, uint32_t, format); /* format */ 399 WRITE(4, uint32_t, blockw); /* blockw */ 400 WRITE(4, uint32_t, blockh); /* blockh */ 401 WRITE(4, uint32_t, blocksize); /* blocksize */ 402 WRITE_ARRAY(1, uint8_t, data); /* data */ 403 WRITE(4, uint32_t, stride); /* stride */ 404 405 /* final pad */ 406 PAD(__pos, 8); 407 408 if (__pos != __len) { 409 __ret = -EINVAL; 410 } else { 411 rbug_connection_send_start(__con, RBUG_OP_TEXTURE_READ_REPLY, __len); 412 rbug_connection_write(__con, __data, __len); 413 __ret = rbug_connection_send_finish(__con, __serial); 414 } 415 416 FREE(__data); 417 return __ret; 418} 419 420struct rbug_proto_texture_list * rbug_demarshal_texture_list(struct rbug_proto_header *header) 421{ 422 struct rbug_proto_texture_list *ret; 423 424 if (!header) 425 return NULL; 426 if (header->opcode != (int32_t)RBUG_OP_TEXTURE_LIST) 427 return NULL; 428 429 ret = MALLOC(sizeof(*ret)); 430 if (!ret) 431 return NULL; 432 433 ret->header.__message = header; 434 ret->header.opcode = header->opcode; 435 436 return ret; 437} 438 439struct rbug_proto_texture_info * rbug_demarshal_texture_info(struct rbug_proto_header *header) 440{ 441 uint32_t len = 0; 442 uint32_t pos = 0; 443 uint8_t *data = NULL; 444 struct rbug_proto_texture_info *ret; 445 446 if (!header) 447 return NULL; 448 if (header->opcode != (int32_t)RBUG_OP_TEXTURE_INFO) 449 return NULL; 450 451 pos = 0; 452 len = header->length * 4; 453 data = (uint8_t*)&header[1]; 454 ret = MALLOC(sizeof(*ret)); 455 if (!ret) 456 return NULL; 457 458 ret->header.__message = header; 459 ret->header.opcode = header->opcode; 460 461 READ(8, rbug_texture_t, texture); /* texture */ 462 463 return ret; 464} 465 466struct rbug_proto_texture_write * rbug_demarshal_texture_write(struct rbug_proto_header *header) 467{ 468 uint32_t len = 0; 469 uint32_t pos = 0; 470 uint8_t *data = NULL; 471 struct rbug_proto_texture_write *ret; 472 473 if (!header) 474 return NULL; 475 if (header->opcode != (int32_t)RBUG_OP_TEXTURE_WRITE) 476 return NULL; 477 478 pos = 0; 479 len = header->length * 4; 480 data = (uint8_t*)&header[1]; 481 ret = MALLOC(sizeof(*ret)); 482 if (!ret) 483 return NULL; 484 485 ret->header.__message = header; 486 ret->header.opcode = header->opcode; 487 488 READ(8, rbug_texture_t, texture); /* texture */ 489 READ(4, uint32_t, face); /* face */ 490 READ(4, uint32_t, level); /* level */ 491 READ(4, uint32_t, zslice); /* zslice */ 492 READ(4, uint32_t, x); /* x */ 493 READ(4, uint32_t, y); /* y */ 494 READ(4, uint32_t, w); /* w */ 495 READ(4, uint32_t, h); /* h */ 496 READ_ARRAY(1, uint8_t, data); /* data */ 497 READ(4, uint32_t, stride); /* stride */ 498 499 return ret; 500} 501 502struct rbug_proto_texture_read * rbug_demarshal_texture_read(struct rbug_proto_header *header) 503{ 504 uint32_t len = 0; 505 uint32_t pos = 0; 506 uint8_t *data = NULL; 507 struct rbug_proto_texture_read *ret; 508 509 if (!header) 510 return NULL; 511 if (header->opcode != (int32_t)RBUG_OP_TEXTURE_READ) 512 return NULL; 513 514 pos = 0; 515 len = header->length * 4; 516 data = (uint8_t*)&header[1]; 517 ret = MALLOC(sizeof(*ret)); 518 if (!ret) 519 return NULL; 520 521 ret->header.__message = header; 522 ret->header.opcode = header->opcode; 523 524 READ(8, rbug_texture_t, texture); /* texture */ 525 READ(4, uint32_t, face); /* face */ 526 READ(4, uint32_t, level); /* level */ 527 READ(4, uint32_t, zslice); /* zslice */ 528 READ(4, uint32_t, x); /* x */ 529 READ(4, uint32_t, y); /* y */ 530 READ(4, uint32_t, w); /* w */ 531 READ(4, uint32_t, h); /* h */ 532 533 return ret; 534} 535 536struct rbug_proto_texture_list_reply * rbug_demarshal_texture_list_reply(struct rbug_proto_header *header) 537{ 538 uint32_t len = 0; 539 uint32_t pos = 0; 540 uint8_t *data = NULL; 541 struct rbug_proto_texture_list_reply *ret; 542 543 if (!header) 544 return NULL; 545 if (header->opcode != (int32_t)RBUG_OP_TEXTURE_LIST_REPLY) 546 return NULL; 547 548 pos = 0; 549 len = header->length * 4; 550 data = (uint8_t*)&header[1]; 551 ret = MALLOC(sizeof(*ret)); 552 if (!ret) 553 return NULL; 554 555 ret->header.__message = header; 556 ret->header.opcode = header->opcode; 557 558 READ(4, uint32_t, serial); /* serial */ 559 READ_ARRAY(8, rbug_texture_t, textures); /* textures */ 560 561 return ret; 562} 563 564struct rbug_proto_texture_info_reply * rbug_demarshal_texture_info_reply(struct rbug_proto_header *header) 565{ 566 uint32_t len = 0; 567 uint32_t pos = 0; 568 uint8_t *data = NULL; 569 struct rbug_proto_texture_info_reply *ret; 570 571 if (!header) 572 return NULL; 573 if (header->opcode != (int32_t)RBUG_OP_TEXTURE_INFO_REPLY) 574 return NULL; 575 576 pos = 0; 577 len = header->length * 4; 578 data = (uint8_t*)&header[1]; 579 ret = MALLOC(sizeof(*ret)); 580 if (!ret) 581 return NULL; 582 583 ret->header.__message = header; 584 ret->header.opcode = header->opcode; 585 586 READ(4, uint32_t, serial); /* serial */ 587 READ(4, uint32_t, target); /* target */ 588 READ(4, uint32_t, format); /* format */ 589 READ_ARRAY(4, uint32_t, width); /* width */ 590 READ_ARRAY(4, uint32_t, height); /* height */ 591 READ_ARRAY(4, uint32_t, depth); /* depth */ 592 READ(4, uint32_t, blockw); /* blockw */ 593 READ(4, uint32_t, blockh); /* blockh */ 594 READ(4, uint32_t, blocksize); /* blocksize */ 595 READ(4, uint32_t, last_level); /* last_level */ 596 READ(4, uint32_t, nr_samples); /* nr_samples */ 597 READ(4, uint32_t, tex_usage); /* tex_usage */ 598 599 return ret; 600} 601 602struct rbug_proto_texture_read_reply * rbug_demarshal_texture_read_reply(struct rbug_proto_header *header) 603{ 604 uint32_t len = 0; 605 uint32_t pos = 0; 606 uint8_t *data = NULL; 607 struct rbug_proto_texture_read_reply *ret; 608 609 if (!header) 610 return NULL; 611 if (header->opcode != (int32_t)RBUG_OP_TEXTURE_READ_REPLY) 612 return NULL; 613 614 pos = 0; 615 len = header->length * 4; 616 data = (uint8_t*)&header[1]; 617 ret = MALLOC(sizeof(*ret)); 618 if (!ret) 619 return NULL; 620 621 ret->header.__message = header; 622 ret->header.opcode = header->opcode; 623 624 READ(4, uint32_t, serial); /* serial */ 625 READ(4, uint32_t, format); /* format */ 626 READ(4, uint32_t, blockw); /* blockw */ 627 READ(4, uint32_t, blockh); /* blockh */ 628 READ(4, uint32_t, blocksize); /* blocksize */ 629 READ_ARRAY(1, uint8_t, data); /* data */ 630 READ(4, uint32_t, stride); /* stride */ 631 632 return ret; 633} 634