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