|
|
@@ -38,9 +38,7 @@ |
|
|
|
#include "util/u_memory.h" |
|
|
|
#include "util/u_string.h" |
|
|
|
#include "util/u_math.h" |
|
|
|
#include "util/u_tile.h" |
|
|
|
#include "util/u_prim.h" |
|
|
|
#include "util/u_surface.h" |
|
|
|
#include <inttypes.h> |
|
|
|
|
|
|
|
#include <stdio.h> |
|
|
@@ -489,315 +487,6 @@ debug_funclog_enter_exit(const char* f, const int line, const char* file) |
|
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG |
|
|
|
/** |
|
|
|
* Dump an image to .ppm file. |
|
|
|
* \param format PIPE_FORMAT_x |
|
|
|
* \param cpp bytes per pixel |
|
|
|
* \param width width in pixels |
|
|
|
* \param height height in pixels |
|
|
|
* \param stride row stride in bytes |
|
|
|
*/ |
|
|
|
void |
|
|
|
debug_dump_image(const char *prefix, |
|
|
|
enum pipe_format format, unsigned cpp, |
|
|
|
unsigned width, unsigned height, |
|
|
|
unsigned stride, |
|
|
|
const void *data) |
|
|
|
{ |
|
|
|
/* write a ppm file */ |
|
|
|
char filename[256]; |
|
|
|
unsigned char *rgb8; |
|
|
|
FILE *f; |
|
|
|
|
|
|
|
util_snprintf(filename, sizeof(filename), "%s.ppm", prefix); |
|
|
|
|
|
|
|
rgb8 = MALLOC(height * width * 3); |
|
|
|
if (!rgb8) { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
util_format_translate( |
|
|
|
PIPE_FORMAT_R8G8B8_UNORM, |
|
|
|
rgb8, width * 3, |
|
|
|
0, 0, |
|
|
|
format, |
|
|
|
data, stride, |
|
|
|
0, 0, width, height); |
|
|
|
|
|
|
|
/* Must be opened in binary mode or DOS line ending causes data |
|
|
|
* to be read with one byte offset. |
|
|
|
*/ |
|
|
|
f = fopen(filename, "wb"); |
|
|
|
if (f) { |
|
|
|
fprintf(f, "P6\n"); |
|
|
|
fprintf(f, "# ppm-file created by gallium\n"); |
|
|
|
fprintf(f, "%i %i\n", width, height); |
|
|
|
fprintf(f, "255\n"); |
|
|
|
fwrite(rgb8, 1, height * width * 3, f); |
|
|
|
fclose(f); |
|
|
|
} |
|
|
|
else { |
|
|
|
fprintf(stderr, "Can't open %s for writing\n", filename); |
|
|
|
} |
|
|
|
|
|
|
|
FREE(rgb8); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* FIXME: dump resources, not surfaces... */ |
|
|
|
void |
|
|
|
debug_dump_surface(struct pipe_context *pipe, |
|
|
|
const char *prefix, |
|
|
|
struct pipe_surface *surface) |
|
|
|
{ |
|
|
|
struct pipe_resource *texture; |
|
|
|
struct pipe_transfer *transfer; |
|
|
|
void *data; |
|
|
|
|
|
|
|
if (!surface) |
|
|
|
return; |
|
|
|
|
|
|
|
/* XXX: this doesn't necessarily work, as the driver may be using |
|
|
|
* temporary storage for the surface which hasn't been propagated |
|
|
|
* back into the texture. Need to nail down the semantics of views |
|
|
|
* and transfers a bit better before we can say if extra work needs |
|
|
|
* to be done here: |
|
|
|
*/ |
|
|
|
texture = surface->texture; |
|
|
|
|
|
|
|
data = pipe_transfer_map(pipe, texture, surface->u.tex.level, |
|
|
|
surface->u.tex.first_layer, |
|
|
|
PIPE_TRANSFER_READ, |
|
|
|
0, 0, surface->width, surface->height, &transfer); |
|
|
|
if (!data) |
|
|
|
return; |
|
|
|
|
|
|
|
debug_dump_image(prefix, |
|
|
|
texture->format, |
|
|
|
util_format_get_blocksize(texture->format), |
|
|
|
util_format_get_nblocksx(texture->format, surface->width), |
|
|
|
util_format_get_nblocksy(texture->format, surface->height), |
|
|
|
transfer->stride, |
|
|
|
data); |
|
|
|
|
|
|
|
pipe->transfer_unmap(pipe, transfer); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
|
debug_dump_texture(struct pipe_context *pipe, |
|
|
|
const char *prefix, |
|
|
|
struct pipe_resource *texture) |
|
|
|
{ |
|
|
|
struct pipe_surface *surface, surf_tmpl; |
|
|
|
|
|
|
|
if (!texture) |
|
|
|
return; |
|
|
|
|
|
|
|
/* XXX for now, just dump image for layer=0, level=0 */ |
|
|
|
u_surface_default_template(&surf_tmpl, texture); |
|
|
|
surface = pipe->create_surface(pipe, texture, &surf_tmpl); |
|
|
|
if (surface) { |
|
|
|
debug_dump_surface(pipe, prefix, surface); |
|
|
|
pipe->surface_destroy(pipe, surface); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#pragma pack(push,2) |
|
|
|
struct bmp_file_header { |
|
|
|
uint16_t bfType; |
|
|
|
uint32_t bfSize; |
|
|
|
uint16_t bfReserved1; |
|
|
|
uint16_t bfReserved2; |
|
|
|
uint32_t bfOffBits; |
|
|
|
}; |
|
|
|
#pragma pack(pop) |
|
|
|
|
|
|
|
struct bmp_info_header { |
|
|
|
uint32_t biSize; |
|
|
|
int32_t biWidth; |
|
|
|
int32_t biHeight; |
|
|
|
uint16_t biPlanes; |
|
|
|
uint16_t biBitCount; |
|
|
|
uint32_t biCompression; |
|
|
|
uint32_t biSizeImage; |
|
|
|
int32_t biXPelsPerMeter; |
|
|
|
int32_t biYPelsPerMeter; |
|
|
|
uint32_t biClrUsed; |
|
|
|
uint32_t biClrImportant; |
|
|
|
}; |
|
|
|
|
|
|
|
struct bmp_rgb_quad { |
|
|
|
uint8_t rgbBlue; |
|
|
|
uint8_t rgbGreen; |
|
|
|
uint8_t rgbRed; |
|
|
|
uint8_t rgbAlpha; |
|
|
|
}; |
|
|
|
|
|
|
|
void |
|
|
|
debug_dump_surface_bmp(struct pipe_context *pipe, |
|
|
|
const char *filename, |
|
|
|
struct pipe_surface *surface) |
|
|
|
{ |
|
|
|
struct pipe_transfer *transfer; |
|
|
|
struct pipe_resource *texture = surface->texture; |
|
|
|
void *ptr; |
|
|
|
|
|
|
|
ptr = pipe_transfer_map(pipe, texture, surface->u.tex.level, |
|
|
|
surface->u.tex.first_layer, PIPE_TRANSFER_READ, |
|
|
|
0, 0, surface->width, surface->height, &transfer); |
|
|
|
|
|
|
|
debug_dump_transfer_bmp(pipe, filename, transfer, ptr); |
|
|
|
|
|
|
|
pipe->transfer_unmap(pipe, transfer); |
|
|
|
} |
|
|
|
|
|
|
|
void |
|
|
|
debug_dump_transfer_bmp(struct pipe_context *pipe, |
|
|
|
const char *filename, |
|
|
|
struct pipe_transfer *transfer, void *ptr) |
|
|
|
{ |
|
|
|
float *rgba; |
|
|
|
|
|
|
|
if (!transfer) |
|
|
|
goto error1; |
|
|
|
|
|
|
|
rgba = MALLOC(transfer->box.width * |
|
|
|
transfer->box.height * |
|
|
|
transfer->box.depth * |
|
|
|
4*sizeof(float)); |
|
|
|
if (!rgba) |
|
|
|
goto error1; |
|
|
|
|
|
|
|
pipe_get_tile_rgba(transfer, ptr, 0, 0, |
|
|
|
transfer->box.width, transfer->box.height, |
|
|
|
rgba); |
|
|
|
|
|
|
|
debug_dump_float_rgba_bmp(filename, |
|
|
|
transfer->box.width, transfer->box.height, |
|
|
|
rgba, transfer->box.width); |
|
|
|
|
|
|
|
FREE(rgba); |
|
|
|
error1: |
|
|
|
; |
|
|
|
} |
|
|
|
|
|
|
|
void |
|
|
|
debug_dump_float_rgba_bmp(const char *filename, |
|
|
|
unsigned width, unsigned height, |
|
|
|
float *rgba, unsigned stride) |
|
|
|
{ |
|
|
|
FILE *stream; |
|
|
|
struct bmp_file_header bmfh; |
|
|
|
struct bmp_info_header bmih; |
|
|
|
unsigned x, y; |
|
|
|
|
|
|
|
if (!rgba) |
|
|
|
goto error1; |
|
|
|
|
|
|
|
bmfh.bfType = 0x4d42; |
|
|
|
bmfh.bfSize = 14 + 40 + height*width*4; |
|
|
|
bmfh.bfReserved1 = 0; |
|
|
|
bmfh.bfReserved2 = 0; |
|
|
|
bmfh.bfOffBits = 14 + 40; |
|
|
|
|
|
|
|
bmih.biSize = 40; |
|
|
|
bmih.biWidth = width; |
|
|
|
bmih.biHeight = height; |
|
|
|
bmih.biPlanes = 1; |
|
|
|
bmih.biBitCount = 32; |
|
|
|
bmih.biCompression = 0; |
|
|
|
bmih.biSizeImage = height*width*4; |
|
|
|
bmih.biXPelsPerMeter = 0; |
|
|
|
bmih.biYPelsPerMeter = 0; |
|
|
|
bmih.biClrUsed = 0; |
|
|
|
bmih.biClrImportant = 0; |
|
|
|
|
|
|
|
stream = fopen(filename, "wb"); |
|
|
|
if (!stream) |
|
|
|
goto error1; |
|
|
|
|
|
|
|
fwrite(&bmfh, 14, 1, stream); |
|
|
|
fwrite(&bmih, 40, 1, stream); |
|
|
|
|
|
|
|
y = height; |
|
|
|
while (y--) { |
|
|
|
float *ptr = rgba + (stride * y * 4); |
|
|
|
for (x = 0; x < width; ++x) { |
|
|
|
struct bmp_rgb_quad pixel; |
|
|
|
pixel.rgbRed = float_to_ubyte(ptr[x*4 + 0]); |
|
|
|
pixel.rgbGreen = float_to_ubyte(ptr[x*4 + 1]); |
|
|
|
pixel.rgbBlue = float_to_ubyte(ptr[x*4 + 2]); |
|
|
|
pixel.rgbAlpha = float_to_ubyte(ptr[x*4 + 3]); |
|
|
|
fwrite(&pixel, 1, 4, stream); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
fclose(stream); |
|
|
|
error1: |
|
|
|
; |
|
|
|
} |
|
|
|
|
|
|
|
void |
|
|
|
debug_dump_ubyte_rgba_bmp(const char *filename, |
|
|
|
unsigned width, unsigned height, |
|
|
|
const ubyte *rgba, unsigned stride) |
|
|
|
{ |
|
|
|
FILE *stream; |
|
|
|
struct bmp_file_header bmfh; |
|
|
|
struct bmp_info_header bmih; |
|
|
|
unsigned x, y; |
|
|
|
|
|
|
|
assert(rgba); |
|
|
|
if (!rgba) |
|
|
|
goto error1; |
|
|
|
|
|
|
|
bmfh.bfType = 0x4d42; |
|
|
|
bmfh.bfSize = 14 + 40 + height*width*4; |
|
|
|
bmfh.bfReserved1 = 0; |
|
|
|
bmfh.bfReserved2 = 0; |
|
|
|
bmfh.bfOffBits = 14 + 40; |
|
|
|
|
|
|
|
bmih.biSize = 40; |
|
|
|
bmih.biWidth = width; |
|
|
|
bmih.biHeight = height; |
|
|
|
bmih.biPlanes = 1; |
|
|
|
bmih.biBitCount = 32; |
|
|
|
bmih.biCompression = 0; |
|
|
|
bmih.biSizeImage = height*width*4; |
|
|
|
bmih.biXPelsPerMeter = 0; |
|
|
|
bmih.biYPelsPerMeter = 0; |
|
|
|
bmih.biClrUsed = 0; |
|
|
|
bmih.biClrImportant = 0; |
|
|
|
|
|
|
|
stream = fopen(filename, "wb"); |
|
|
|
assert(stream); |
|
|
|
if (!stream) |
|
|
|
goto error1; |
|
|
|
|
|
|
|
fwrite(&bmfh, 14, 1, stream); |
|
|
|
fwrite(&bmih, 40, 1, stream); |
|
|
|
|
|
|
|
y = height; |
|
|
|
while (y--) { |
|
|
|
const ubyte *ptr = rgba + (stride * y * 4); |
|
|
|
for (x = 0; x < width; ++x) { |
|
|
|
struct bmp_rgb_quad pixel; |
|
|
|
pixel.rgbRed = ptr[x*4 + 0]; |
|
|
|
pixel.rgbGreen = ptr[x*4 + 1]; |
|
|
|
pixel.rgbBlue = ptr[x*4 + 2]; |
|
|
|
pixel.rgbAlpha = ptr[x*4 + 3]; |
|
|
|
fwrite(&pixel, 1, 4, stream); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
fclose(stream); |
|
|
|
error1: |
|
|
|
; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* Print PIPE_TRANSFER_x flags with a message. |
|
|
|
*/ |