mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-24 02:20:11 +01:00
tests/graw: Add a bunch of tests.
These were rotting in an internal branch, but contain nothing confidential, and would be much more useful if kept up-to-date with latest gallium interface changes. Several authors including Keith Whitwell, Zack Rusin, and Brian Paul.
This commit is contained in:
parent
0df14f9a55
commit
d35d3d612a
10 changed files with 1795 additions and 373 deletions
|
|
@ -16,15 +16,21 @@ if env['platform'] == 'freebsd8':
|
|||
|
||||
progs = [
|
||||
'clear',
|
||||
'tri',
|
||||
'tri-instanced',
|
||||
'quad-tex',
|
||||
'fs-fragcoord',
|
||||
'fs-frontface',
|
||||
'fs-test',
|
||||
'vs-test',
|
||||
'fs-write-z',
|
||||
'gs-test',
|
||||
'shader-leak',
|
||||
'tri-gs',
|
||||
'occlusion-query',
|
||||
'quad-sample',
|
||||
'quad-tex',
|
||||
'shader-leak',
|
||||
'tex-srgb',
|
||||
'tex-swizzle',
|
||||
'tri',
|
||||
'tri-gs',
|
||||
'tri-instanced',
|
||||
'vs-test',
|
||||
]
|
||||
|
||||
for name in progs:
|
||||
|
|
|
|||
259
src/gallium/tests/graw/fs-fragcoord.c
Normal file
259
src/gallium/tests/graw/fs-fragcoord.c
Normal file
|
|
@ -0,0 +1,259 @@
|
|||
/* Test the TGSI_SEMANTIC_POSITION fragment shader input.
|
||||
* Plus properties for upper-left vs. lower-left origin and
|
||||
* center integer vs. half-integer;
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "graw_util.h"
|
||||
|
||||
|
||||
static int width = 300;
|
||||
static int height = 300;
|
||||
|
||||
static struct graw_info info;
|
||||
|
||||
struct vertex {
|
||||
float position[4];
|
||||
float color[4];
|
||||
};
|
||||
|
||||
/* Note: the upper-left vertex is pushed to the left a bit to
|
||||
* make sure we can spot upside-down rendering.
|
||||
*/
|
||||
static struct vertex vertices[] =
|
||||
{
|
||||
{
|
||||
{-0.95, -0.95, 0.5, 1.0 },
|
||||
{ 0, 0, 0, 1 }
|
||||
},
|
||||
|
||||
{
|
||||
{ 0.85, -0.95, 0.5, 1.0 },
|
||||
{ 0, 0, 0, 1 }
|
||||
},
|
||||
|
||||
{
|
||||
{ 0.95, 0.95, 0.5, 1.0 },
|
||||
{ 0, 0, 0, 1 }
|
||||
},
|
||||
|
||||
{
|
||||
{-0.95, 0.95, 0.5, 1.0 },
|
||||
{ 0, 0, 0, 1 }
|
||||
}
|
||||
};
|
||||
|
||||
#define NUM_VERTS (sizeof(vertices) / sizeof(vertices[0]))
|
||||
|
||||
|
||||
static void
|
||||
set_vertices(void)
|
||||
{
|
||||
struct pipe_vertex_element ve[2];
|
||||
struct pipe_vertex_buffer vbuf;
|
||||
void *handle;
|
||||
|
||||
memset(ve, 0, sizeof ve);
|
||||
|
||||
ve[0].src_offset = Offset(struct vertex, position);
|
||||
ve[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
|
||||
ve[1].src_offset = Offset(struct vertex, color);
|
||||
ve[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
|
||||
|
||||
handle = info.ctx->create_vertex_elements_state(info.ctx, 2, ve);
|
||||
info.ctx->bind_vertex_elements_state(info.ctx, handle);
|
||||
|
||||
|
||||
vbuf.stride = sizeof(struct vertex);
|
||||
vbuf.buffer_offset = 0;
|
||||
vbuf.buffer = info.screen->user_buffer_create(info.screen,
|
||||
vertices,
|
||||
sizeof(vertices),
|
||||
PIPE_BIND_VERTEX_BUFFER);
|
||||
|
||||
info.ctx->set_vertex_buffers(info.ctx, 1, &vbuf);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
set_vertex_shader(void)
|
||||
{
|
||||
void *handle;
|
||||
const char *text =
|
||||
"VERT\n"
|
||||
"DCL IN[0]\n"
|
||||
"DCL IN[1]\n"
|
||||
"DCL OUT[0], POSITION\n"
|
||||
"DCL OUT[1], GENERIC[0]\n"
|
||||
" 0: MOV OUT[0], IN[0]\n"
|
||||
" 1: MOV OUT[1], IN[1]\n"
|
||||
" 2: END\n";
|
||||
|
||||
handle = graw_parse_vertex_shader(info.ctx, text);
|
||||
info.ctx->bind_vs_state(info.ctx, handle);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
set_fragment_shader(int mode)
|
||||
{
|
||||
void *handle;
|
||||
|
||||
const char *origin_upper_left_text =
|
||||
"FRAG\n"
|
||||
"PROPERTY FS_COORD_ORIGIN UPPER_LEFT\n" /* upper-left = black corner */
|
||||
"DCL IN[0], POSITION, LINEAR\n"
|
||||
"DCL OUT[0], COLOR\n"
|
||||
"DCL TEMP[0]\n"
|
||||
"IMM FLT32 { 0.003333, 0.003333, 1.0, 1.0 }\n"
|
||||
"IMM FLT32 { 0.0, 300.0, 0.0, 0.0 }\n"
|
||||
" 0: MOV TEMP[0], IN[0] \n"
|
||||
" 1: MOV TEMP[0].zw, IMM[1].xxxx \n"
|
||||
" 2: MUL OUT[0], TEMP[0], IMM[0] \n"
|
||||
" 3: END\n";
|
||||
|
||||
const char *origin_lower_left_text =
|
||||
"FRAG\n"
|
||||
"PROPERTY FS_COORD_ORIGIN LOWER_LEFT\n" /* lower-left = black corner */
|
||||
"DCL IN[0], POSITION, LINEAR\n"
|
||||
"DCL OUT[0], COLOR\n"
|
||||
"DCL TEMP[0]\n"
|
||||
"IMM FLT32 { 0.003333, 0.003333, 1.0, 1.0 }\n"
|
||||
"IMM FLT32 { 0.0, 300.0, 0.0, 0.0 }\n"
|
||||
" 0: MOV TEMP[0], IN[0] \n"
|
||||
" 1: MOV TEMP[0].zw, IMM[1].xxxx \n"
|
||||
" 2: MUL OUT[0], TEMP[0], IMM[0] \n"
|
||||
" 3: END\n";
|
||||
|
||||
/* Test fragcoord center integer vs. half integer */
|
||||
const char *center_integer_text =
|
||||
"FRAG\n"
|
||||
"PROPERTY FS_COORD_PIXEL_CENTER INTEGER \n" /* pixels are black */
|
||||
"DCL IN[0], POSITION, LINEAR \n"
|
||||
"DCL OUT[0], COLOR \n"
|
||||
"DCL TEMP[0] \n"
|
||||
"IMM FLT32 { 0.003333, 0.003333, 1.0, 1.0 } \n"
|
||||
"IMM FLT32 { 0.0, 300.0, 0.0, 0.0 } \n"
|
||||
"0: FRC TEMP[0], IN[0] \n"
|
||||
"1: MOV TEMP[0].zw, IMM[1].xxxx \n"
|
||||
"2: MOV OUT[0], TEMP[0] \n"
|
||||
"3: END \n";
|
||||
|
||||
const char *center_half_integer_text =
|
||||
"FRAG\n"
|
||||
"PROPERTY FS_COORD_PIXEL_CENTER HALF_INTEGER \n" /* pixels are olive colored */
|
||||
"DCL IN[0], POSITION, LINEAR \n"
|
||||
"DCL OUT[0], COLOR \n"
|
||||
"DCL TEMP[0] \n"
|
||||
"IMM FLT32 { 0.003333, 0.003333, 1.0, 1.0 } \n"
|
||||
"IMM FLT32 { 0.0, 300.0, 0.0, 0.0 } \n"
|
||||
"0: FRC TEMP[0], IN[0] \n"
|
||||
"1: MOV TEMP[0].zw, IMM[1].xxxx \n"
|
||||
"2: MOV OUT[0], TEMP[0] \n"
|
||||
"3: END \n";
|
||||
|
||||
const char *text;
|
||||
|
||||
if (mode == 0)
|
||||
text = origin_upper_left_text;
|
||||
else if (mode == 1)
|
||||
text = origin_lower_left_text;
|
||||
else if (mode == 2)
|
||||
text = center_integer_text;
|
||||
else
|
||||
text = center_half_integer_text;
|
||||
|
||||
handle = graw_parse_fragment_shader(info.ctx, text);
|
||||
info.ctx->bind_fs_state(info.ctx, handle);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
draw(void)
|
||||
{
|
||||
union pipe_color_union clear_color;
|
||||
|
||||
clear_color.f[0] = 0.25;
|
||||
clear_color.f[1] = 0.25;
|
||||
clear_color.f[2] = 0.25;
|
||||
clear_color.f[3] = 1.0;
|
||||
|
||||
info.ctx->clear(info.ctx,
|
||||
PIPE_CLEAR_COLOR | PIPE_CLEAR_DEPTHSTENCIL,
|
||||
&clear_color, 1.0, 0);
|
||||
util_draw_arrays(info.ctx, PIPE_PRIM_QUADS, 0, NUM_VERTS);
|
||||
info.ctx->flush(info.ctx, NULL);
|
||||
|
||||
#if 0
|
||||
/* At the moment, libgraw leaks out/makes available some of the
|
||||
* symbols from gallium/auxiliary, including these debug helpers.
|
||||
* Will eventually want to bless some of these paths, and lock the
|
||||
* others down so they aren't accessible from test programs.
|
||||
*
|
||||
* This currently just happens to work on debug builds - a release
|
||||
* build will probably fail to link here:
|
||||
*/
|
||||
debug_dump_surface_bmp(info.ctx, "result.bmp", surf);
|
||||
#endif
|
||||
|
||||
graw_util_flush_front(&info);
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
static void
|
||||
resize(int w, int h)
|
||||
{
|
||||
width = w;
|
||||
height = h;
|
||||
|
||||
set_viewport(0, 0, width, height, 30, 1000);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
init(int mode)
|
||||
{
|
||||
if (!graw_util_create_window(&info, width, height, 1, TRUE))
|
||||
exit(1);
|
||||
|
||||
graw_util_default_state(&info, TRUE);
|
||||
|
||||
graw_util_viewport(&info, 0, 0, width, height, -1.0, 1.0);
|
||||
|
||||
set_vertices();
|
||||
set_vertex_shader();
|
||||
set_fragment_shader(mode);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int mode = argc > 1 ? atoi(argv[1]) : 0;
|
||||
|
||||
switch (mode) {
|
||||
default:
|
||||
case 0:
|
||||
printf("frag coord origin upper-left (lower-left = black)\n");
|
||||
break;
|
||||
case 1:
|
||||
printf("frag coord origin lower-left (upper-left = black)\n");
|
||||
break;
|
||||
case 2:
|
||||
printf("frag coord center integer (all pixels black)\n");
|
||||
break;
|
||||
case 3:
|
||||
printf("frag coord center half-integer (all pixels olive color)\n");
|
||||
break;
|
||||
}
|
||||
|
||||
init(mode);
|
||||
|
||||
graw_set_display_func(draw);
|
||||
/*graw_set_reshape_func(resize);*/
|
||||
graw_main_loop();
|
||||
return 0;
|
||||
}
|
||||
206
src/gallium/tests/graw/fs-frontface.c
Normal file
206
src/gallium/tests/graw/fs-frontface.c
Normal file
|
|
@ -0,0 +1,206 @@
|
|||
/* Test the TGSI_SEMANTIC_FACE fragment shader input.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "graw_util.h"
|
||||
|
||||
|
||||
static int width = 300;
|
||||
static int height = 300;
|
||||
|
||||
static struct graw_info info;
|
||||
|
||||
struct vertex {
|
||||
float position[4];
|
||||
float color[4];
|
||||
};
|
||||
|
||||
#define z0 0.2
|
||||
#define z01 0.5
|
||||
#define z1 0.4
|
||||
|
||||
static struct vertex vertices[] =
|
||||
{
|
||||
/* left quad: clock-wise, front-facing, red */
|
||||
{
|
||||
{-0.8, -0.9, z0, 1.0 },
|
||||
{ 0, 0, 0, 1 }
|
||||
},
|
||||
|
||||
{
|
||||
{ -0.2, -0.9, z0, 1.0 },
|
||||
{ 0, 0, 0, 1 }
|
||||
},
|
||||
|
||||
{
|
||||
{ 0.2, 0.9, z01, 1.0 },
|
||||
{ 0, 0, 0, 1 }
|
||||
},
|
||||
|
||||
{
|
||||
{-0.9, 0.9, z01, 1.0 },
|
||||
{ 0, 0, 0, 1 }
|
||||
},
|
||||
|
||||
/* right quad : counter-clock-wise, back-facing, green */
|
||||
{
|
||||
{ 0.2, -0.9, z1, 1.0 },
|
||||
{ 1, 1, 1, -1 }
|
||||
},
|
||||
|
||||
{
|
||||
{ -0.2, 0.8, z1, 1.0 },
|
||||
{ 1, 1, 1, -1 }
|
||||
},
|
||||
|
||||
{
|
||||
{ 0.9, 0.8, z1, 1.0 },
|
||||
{ 1, 1, 1, -1 }
|
||||
},
|
||||
|
||||
{
|
||||
{ 0.8, -0.9, z1, 1.0 },
|
||||
{ 1, 1, 1, -1 }
|
||||
},
|
||||
};
|
||||
|
||||
#define NUM_VERTS (sizeof(vertices) / sizeof(vertices[0]))
|
||||
|
||||
|
||||
|
||||
static void
|
||||
set_vertices(void)
|
||||
{
|
||||
struct pipe_vertex_element ve[2];
|
||||
struct pipe_vertex_buffer vbuf;
|
||||
void *handle;
|
||||
|
||||
memset(ve, 0, sizeof ve);
|
||||
|
||||
ve[0].src_offset = Offset(struct vertex, position);
|
||||
ve[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
|
||||
ve[1].src_offset = Offset(struct vertex, color);
|
||||
ve[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
|
||||
|
||||
handle = info.ctx->create_vertex_elements_state(info.ctx, 2, ve);
|
||||
info.ctx->bind_vertex_elements_state(info.ctx, handle);
|
||||
|
||||
|
||||
vbuf.stride = sizeof(struct vertex);
|
||||
vbuf.buffer_offset = 0;
|
||||
vbuf.buffer = info.screen->user_buffer_create(info.screen,
|
||||
vertices,
|
||||
sizeof(vertices),
|
||||
PIPE_BIND_VERTEX_BUFFER);
|
||||
|
||||
info.ctx->set_vertex_buffers(info.ctx, 1, &vbuf);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
set_vertex_shader(void)
|
||||
{
|
||||
void *handle;
|
||||
const char *text =
|
||||
"VERT\n"
|
||||
"DCL IN[0]\n"
|
||||
"DCL IN[1]\n"
|
||||
"DCL OUT[0], POSITION\n"
|
||||
"DCL OUT[1], GENERIC[0]\n"
|
||||
" 0: MOV OUT[0], IN[0]\n"
|
||||
" 1: MOV OUT[1], IN[1]\n"
|
||||
" 2: END\n";
|
||||
|
||||
handle = graw_parse_vertex_shader(info.ctx, text);
|
||||
info.ctx->bind_vs_state(info.ctx, handle);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
set_fragment_shader(void)
|
||||
{
|
||||
void *handle;
|
||||
const char *text =
|
||||
"FRAG\n"
|
||||
"DCL IN[0], FACE, CONSTANT\n"
|
||||
"DCL IN[1], GENERIC, CONSTANT\n"
|
||||
"DCL OUT[0], COLOR\n"
|
||||
"DCL TEMP[0]\n"
|
||||
"IMM FLT32 { 1.0, 0.0, 0.0, 0.0 }\n"
|
||||
"IMM FLT32 { 0.0, 1.0, 0.0, 0.0 }\n"
|
||||
"IMM FLT32 { 0.5, 0.6, 0.0, 0.0 }\n"
|
||||
" 0: SGT TEMP[0].x, IN[0].xxxx, IMM[1].xxxx\n" /* TMP[0].x = IN[0].x > 0.0 */
|
||||
" 1: IF TEMP[0].xxxx :4\n"
|
||||
" 2: MOV OUT[0], IMM[0]\n" /* front-facing: red */
|
||||
" 3: ELSE :5\n"
|
||||
" 4: MOV OUT[0], IMM[1]\n" /* back-facing: green */
|
||||
" 5: ENDIF\n"
|
||||
" 6: END\n";
|
||||
|
||||
handle = graw_parse_fragment_shader(info.ctx, text);
|
||||
info.ctx->bind_fs_state(info.ctx, handle);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
draw(void)
|
||||
{
|
||||
union pipe_color_union clear_color;
|
||||
|
||||
clear_color.f[0] = 0.25;
|
||||
clear_color.f[1] = 0.25;
|
||||
clear_color.f[2] = 0.25;
|
||||
clear_color.f[3] = 1.00;
|
||||
|
||||
info.ctx->clear(info.ctx,
|
||||
PIPE_CLEAR_COLOR | PIPE_CLEAR_DEPTHSTENCIL,
|
||||
&clear_color, 1.0, 0);
|
||||
util_draw_arrays(info.ctx, PIPE_PRIM_QUADS, 0, NUM_VERTS);
|
||||
info.ctx->flush(info.ctx, NULL);
|
||||
|
||||
graw_util_flush_front(&info);
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
static void
|
||||
resize(int w, int h)
|
||||
{
|
||||
width = w;
|
||||
height = h;
|
||||
|
||||
set_viewport(0, 0, width, height, 30, 1000);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
init(void)
|
||||
{
|
||||
if (!graw_util_create_window(&info, width, height, 1, TRUE))
|
||||
exit(1);
|
||||
|
||||
graw_util_default_state(&info, TRUE);
|
||||
|
||||
graw_util_viewport(&info, 0, 0, width, height, -1.0, 1.0);
|
||||
|
||||
set_vertices();
|
||||
set_vertex_shader();
|
||||
set_fragment_shader();
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
init();
|
||||
|
||||
printf("Left quad: clock-wise, front-facing, red\n");
|
||||
printf("Right quad: counter clock-wise, back-facing, green\n");
|
||||
|
||||
graw_set_display_func(draw);
|
||||
/*graw_set_reshape_func(resize);*/
|
||||
graw_main_loop();
|
||||
return 0;
|
||||
}
|
||||
222
src/gallium/tests/graw/fs-write-z.c
Normal file
222
src/gallium/tests/graw/fs-write-z.c
Normal file
|
|
@ -0,0 +1,222 @@
|
|||
/* Test the writing Z in fragment shader.
|
||||
* The red quad should be entirely in front of the blue quad even
|
||||
* though the overlap and intersect in Z.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "graw_util.h"
|
||||
|
||||
|
||||
static int width = 300;
|
||||
static int height = 300;
|
||||
|
||||
static struct graw_info info;
|
||||
|
||||
|
||||
struct vertex {
|
||||
float position[4];
|
||||
float color[4];
|
||||
};
|
||||
|
||||
#define z0 0.2
|
||||
#define z01 0.5
|
||||
#define z1 0.4
|
||||
|
||||
|
||||
static struct vertex vertices[] =
|
||||
{
|
||||
/* left quad: clock-wise, front-facing, red */
|
||||
{
|
||||
{-0.8, -0.9, z0, 1.0 },
|
||||
{ 1, 0, 0, 1 }
|
||||
},
|
||||
|
||||
{
|
||||
{ -0.2, -0.9, z0, 1.0 },
|
||||
{ 1, 0, 0, 1 }
|
||||
},
|
||||
|
||||
{
|
||||
{ 0.2, 0.9, z01, 1.0 },
|
||||
{ 1, 0, 0, 1 }
|
||||
},
|
||||
|
||||
{
|
||||
{-0.9, 0.9, z01, 1.0 },
|
||||
{ 1, 0, 0, 1 }
|
||||
},
|
||||
|
||||
/* right quad : counter-clock-wise, back-facing, green */
|
||||
{
|
||||
{ 0.2, -0.9, z1, 1.0 },
|
||||
{ 0, 0, 1, -1 }
|
||||
},
|
||||
|
||||
{
|
||||
{ -0.2, 0.8, z1, 1.0 },
|
||||
{ 0, 0, 1, -1 }
|
||||
},
|
||||
|
||||
{
|
||||
{ 0.9, 0.8, z1, 1.0 },
|
||||
{ 0, 0, 1, -1 }
|
||||
},
|
||||
|
||||
{
|
||||
{ 0.8, -0.9, z1, 1.0 },
|
||||
{ 0, 0, 1, -1 }
|
||||
},
|
||||
};
|
||||
|
||||
#define NUM_VERTS (sizeof(vertices) / sizeof(vertices[0]))
|
||||
|
||||
|
||||
|
||||
static void
|
||||
set_vertices(void)
|
||||
{
|
||||
struct pipe_vertex_element ve[2];
|
||||
struct pipe_vertex_buffer vbuf;
|
||||
void *handle;
|
||||
|
||||
memset(ve, 0, sizeof ve);
|
||||
|
||||
ve[0].src_offset = Offset(struct vertex, position);
|
||||
ve[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
|
||||
ve[1].src_offset = Offset(struct vertex, color);
|
||||
ve[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
|
||||
|
||||
handle = info.ctx->create_vertex_elements_state(info.ctx, 2, ve);
|
||||
info.ctx->bind_vertex_elements_state(info.ctx, handle);
|
||||
|
||||
|
||||
vbuf.stride = sizeof(struct vertex);
|
||||
vbuf.buffer_offset = 0;
|
||||
vbuf.buffer = info.screen->user_buffer_create(info.screen,
|
||||
vertices,
|
||||
sizeof(vertices),
|
||||
PIPE_BIND_VERTEX_BUFFER);
|
||||
|
||||
info.ctx->set_vertex_buffers(info.ctx, 1, &vbuf);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
set_vertex_shader(void)
|
||||
{
|
||||
void *handle;
|
||||
const char *text =
|
||||
"VERT\n"
|
||||
"DCL IN[0]\n"
|
||||
"DCL IN[1]\n"
|
||||
"DCL OUT[0], POSITION\n"
|
||||
"DCL OUT[1], GENERIC[0]\n"
|
||||
" 0: MOV OUT[0], IN[0]\n"
|
||||
" 1: MOV OUT[1], IN[1]\n"
|
||||
" 2: END\n";
|
||||
|
||||
handle = graw_parse_vertex_shader(info.ctx, text);
|
||||
info.ctx->bind_vs_state(info.ctx, handle);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
set_fragment_shader(void)
|
||||
{
|
||||
void *handle;
|
||||
const char *text =
|
||||
"FRAG\n"
|
||||
"DCL IN[0], GENERIC, CONSTANT\n"
|
||||
"DCL OUT[0], COLOR\n"
|
||||
"DCL OUT[1], POSITION\n"
|
||||
"DCL TEMP[0]\n"
|
||||
"IMM FLT32 { 1.0, 0.0, 0.0, 0.0 }\n"
|
||||
"IMM FLT32 { 0.0, 1.0, 0.0, 0.0 }\n"
|
||||
"IMM FLT32 { 0.5, 0.4, 0.0, 0.0 }\n"
|
||||
" 0: MOV OUT[0], IN[0]\n" /* front-facing: red */
|
||||
" 1: IF IN[0].xxxx :3\n"
|
||||
" 2: MOV OUT[1].z, IMM[2].yyyy\n" /* red: Z = 0.4 */
|
||||
" 3: ELSE :5\n"
|
||||
" 4: MOV OUT[1].z, IMM[2].xxxx\n" /* blue: Z = 0.5 */
|
||||
" 5: ENDIF\n"
|
||||
" 6: END\n";
|
||||
|
||||
handle = graw_parse_fragment_shader(info.ctx, text);
|
||||
info.ctx->bind_fs_state(info.ctx, handle);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
draw(void)
|
||||
{
|
||||
union pipe_color_union clear_color;
|
||||
|
||||
clear_color.f[0] = 0.25;
|
||||
clear_color.f[1] = 0.25;
|
||||
clear_color.f[2] = 0.25;
|
||||
clear_color.f[3] = 1.00;
|
||||
|
||||
info.ctx->clear(info.ctx,
|
||||
PIPE_CLEAR_COLOR | PIPE_CLEAR_DEPTHSTENCIL,
|
||||
&clear_color, 1.0, 0);
|
||||
util_draw_arrays(info.ctx, PIPE_PRIM_QUADS, 0, NUM_VERTS);
|
||||
info.ctx->flush(info.ctx, NULL);
|
||||
|
||||
#if 0
|
||||
/* At the moment, libgraw leaks out/makes available some of the
|
||||
* symbols from gallium/auxiliary, including these debug helpers.
|
||||
* Will eventually want to bless some of these paths, and lock the
|
||||
* others down so they aren't accessible from test programs.
|
||||
*
|
||||
* This currently just happens to work on debug builds - a release
|
||||
* build will probably fail to link here:
|
||||
*/
|
||||
debug_dump_surface_bmp(info.ctx, "result.bmp", surf);
|
||||
#endif
|
||||
|
||||
graw_util_flush_front(&info);
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
static void
|
||||
resize(int w, int h)
|
||||
{
|
||||
width = w;
|
||||
height = h;
|
||||
|
||||
graw_util_viewport(&info, 0, 0, width, height, -1.0, 1.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
init(void)
|
||||
{
|
||||
if (!graw_util_create_window(&info, width, height, 1, TRUE))
|
||||
exit(1);
|
||||
|
||||
graw_util_default_state(&info, TRUE);
|
||||
|
||||
graw_util_viewport(&info, 0, 0, width, height, -1.0, 1.0);
|
||||
|
||||
set_vertices();
|
||||
set_vertex_shader();
|
||||
set_fragment_shader();
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
init();
|
||||
|
||||
printf("The red quad should be entirely in front of the blue quad.\n");
|
||||
|
||||
graw_set_display_func(draw);
|
||||
/*graw_set_reshape_func(resize);*/
|
||||
graw_main_loop();
|
||||
return 0;
|
||||
}
|
||||
329
src/gallium/tests/graw/graw_util.h
Normal file
329
src/gallium/tests/graw/graw_util.h
Normal file
|
|
@ -0,0 +1,329 @@
|
|||
|
||||
#include "state_tracker/graw.h"
|
||||
|
||||
#include "pipe/p_context.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_screen.h"
|
||||
#include "pipe/p_shader_tokens.h"
|
||||
#include "pipe/p_state.h"
|
||||
|
||||
#include "util/u_box.h"
|
||||
#include "util/u_debug.h"
|
||||
#include "util/u_draw_quad.h"
|
||||
#include "util/u_format.h"
|
||||
#include "util/u_inlines.h"
|
||||
#include "util/u_memory.h"
|
||||
|
||||
|
||||
struct graw_info
|
||||
{
|
||||
struct pipe_screen *screen;
|
||||
struct pipe_context *ctx;
|
||||
struct pipe_resource *color_buf[PIPE_MAX_COLOR_BUFS], *zs_buf;
|
||||
struct pipe_surface *color_surf[PIPE_MAX_COLOR_BUFS], *zs_surf;
|
||||
void *window;
|
||||
};
|
||||
|
||||
|
||||
|
||||
static INLINE boolean
|
||||
graw_util_create_window(struct graw_info *info,
|
||||
int width, int height,
|
||||
int num_cbufs, bool zstencil_buf)
|
||||
{
|
||||
static const enum pipe_format formats[] = {
|
||||
PIPE_FORMAT_R8G8B8A8_UNORM,
|
||||
PIPE_FORMAT_B8G8R8A8_UNORM,
|
||||
PIPE_FORMAT_NONE
|
||||
};
|
||||
enum pipe_format format;
|
||||
struct pipe_resource resource_temp;
|
||||
struct pipe_surface surface_temp;
|
||||
int i;
|
||||
|
||||
memset(info, 0, sizeof(*info));
|
||||
|
||||
/* It's hard to say whether window or screen should be created
|
||||
* first. Different environments would prefer one or the other.
|
||||
*
|
||||
* Also, no easy way of querying supported formats if the screen
|
||||
* cannot be created first.
|
||||
*/
|
||||
for (i = 0; info->window == NULL && formats[i] != PIPE_FORMAT_NONE; i++) {
|
||||
info->screen = graw_create_window_and_screen(0, 0, width, height,
|
||||
formats[i],
|
||||
&info->window);
|
||||
format = formats[i];
|
||||
}
|
||||
if (!info->screen || !info->window) {
|
||||
debug_printf("graw: Failed to create screen/window\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
info->ctx = info->screen->context_create(info->screen, NULL);
|
||||
if (info->ctx == NULL) {
|
||||
debug_printf("graw: Failed to create context\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_cbufs; i++) {
|
||||
/* create color texture */
|
||||
resource_temp.target = PIPE_TEXTURE_2D;
|
||||
resource_temp.format = format;
|
||||
resource_temp.width0 = width;
|
||||
resource_temp.height0 = height;
|
||||
resource_temp.depth0 = 1;
|
||||
resource_temp.array_size = 1;
|
||||
resource_temp.last_level = 0;
|
||||
resource_temp.nr_samples = 1;
|
||||
resource_temp.bind = (PIPE_BIND_RENDER_TARGET |
|
||||
PIPE_BIND_DISPLAY_TARGET);
|
||||
info->color_buf[i] = info->screen->resource_create(info->screen,
|
||||
&resource_temp);
|
||||
if (info->color_buf[i] == NULL) {
|
||||
debug_printf("graw: Failed to create color texture\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* create color surface */
|
||||
surface_temp.format = resource_temp.format;
|
||||
surface_temp.usage = PIPE_BIND_RENDER_TARGET;
|
||||
surface_temp.u.tex.level = 0;
|
||||
surface_temp.u.tex.first_layer = 0;
|
||||
surface_temp.u.tex.last_layer = 0;
|
||||
info->color_surf[i] = info->ctx->create_surface(info->ctx,
|
||||
info->color_buf[i],
|
||||
&surface_temp);
|
||||
if (info->color_surf[i] == NULL) {
|
||||
debug_printf("graw: Failed to get color surface\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* create Z texture (XXX try other Z/S formats if needed) */
|
||||
resource_temp.target = PIPE_TEXTURE_2D;
|
||||
resource_temp.format = PIPE_FORMAT_S8_UINT_Z24_UNORM;
|
||||
resource_temp.width0 = width;
|
||||
resource_temp.height0 = height;
|
||||
resource_temp.depth0 = 1;
|
||||
resource_temp.array_size = 1;
|
||||
resource_temp.last_level = 0;
|
||||
resource_temp.nr_samples = 1;
|
||||
resource_temp.bind = PIPE_BIND_DEPTH_STENCIL;
|
||||
info->zs_buf = info->screen->resource_create(info->screen, &resource_temp);
|
||||
if (!info->zs_buf) {
|
||||
debug_printf("graw: Failed to create Z texture\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* create z surface */
|
||||
surface_temp.format = resource_temp.format;
|
||||
surface_temp.usage = PIPE_BIND_DEPTH_STENCIL;
|
||||
surface_temp.u.tex.level = 0;
|
||||
surface_temp.u.tex.first_layer = 0;
|
||||
surface_temp.u.tex.last_layer = 0;
|
||||
info->zs_surf = info->ctx->create_surface(info->ctx,
|
||||
info->zs_buf,
|
||||
&surface_temp);
|
||||
if (info->zs_surf == NULL) {
|
||||
debug_printf("graw: Failed to get Z surface\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
{
|
||||
struct pipe_framebuffer_state fb;
|
||||
memset(&fb, 0, sizeof fb);
|
||||
fb.nr_cbufs = num_cbufs;
|
||||
fb.width = width;
|
||||
fb.height = height;
|
||||
for (i = 0; i < num_cbufs; i++)
|
||||
fb.cbufs[i] = info->color_surf[i];
|
||||
fb.zsbuf = info->zs_surf;
|
||||
info->ctx->set_framebuffer_state(info->ctx, &fb);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static INLINE void
|
||||
graw_util_default_state(struct graw_info *info, boolean depth_test)
|
||||
{
|
||||
{
|
||||
struct pipe_blend_state blend;
|
||||
void *handle;
|
||||
memset(&blend, 0, sizeof blend);
|
||||
blend.rt[0].colormask = PIPE_MASK_RGBA;
|
||||
handle = info->ctx->create_blend_state(info->ctx, &blend);
|
||||
info->ctx->bind_blend_state(info->ctx, handle);
|
||||
}
|
||||
|
||||
{
|
||||
struct pipe_depth_stencil_alpha_state depthStencilAlpha;
|
||||
void *handle;
|
||||
memset(&depthStencilAlpha, 0, sizeof depthStencilAlpha);
|
||||
depthStencilAlpha.depth.enabled = depth_test;
|
||||
depthStencilAlpha.depth.writemask = 1;
|
||||
depthStencilAlpha.depth.func = PIPE_FUNC_LESS;
|
||||
handle = info->ctx->create_depth_stencil_alpha_state(info->ctx,
|
||||
&depthStencilAlpha);
|
||||
info->ctx->bind_depth_stencil_alpha_state(info->ctx, handle);
|
||||
}
|
||||
|
||||
{
|
||||
struct pipe_rasterizer_state rasterizer;
|
||||
void *handle;
|
||||
memset(&rasterizer, 0, sizeof rasterizer);
|
||||
rasterizer.cull_face = PIPE_FACE_NONE;
|
||||
rasterizer.gl_rasterization_rules = 1;
|
||||
handle = info->ctx->create_rasterizer_state(info->ctx, &rasterizer);
|
||||
info->ctx->bind_rasterizer_state(info->ctx, handle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static INLINE void
|
||||
graw_util_viewport(struct graw_info *info,
|
||||
float x, float y,
|
||||
float width, float height,
|
||||
float near, float far)
|
||||
{
|
||||
float z = near;
|
||||
float half_width = width / 2.0f;
|
||||
float half_height = height / 2.0f;
|
||||
float half_depth = (far - near) / 2.0f;
|
||||
struct pipe_viewport_state vp;
|
||||
|
||||
vp.scale[0] = half_width;
|
||||
vp.scale[1] = half_height;
|
||||
vp.scale[2] = half_depth;
|
||||
vp.scale[3] = 1.0f;
|
||||
|
||||
vp.translate[0] = half_width + x;
|
||||
vp.translate[1] = half_height + y;
|
||||
vp.translate[2] = half_depth + z;
|
||||
vp.translate[3] = 0.0f;
|
||||
|
||||
info->ctx->set_viewport_state(info->ctx, &vp);
|
||||
}
|
||||
|
||||
|
||||
static INLINE void
|
||||
graw_util_flush_front(const struct graw_info *info)
|
||||
{
|
||||
info->screen->flush_frontbuffer(info->screen, info->color_buf[0],
|
||||
0, 0, info->window);
|
||||
}
|
||||
|
||||
|
||||
static INLINE struct pipe_resource *
|
||||
graw_util_create_tex2d(const struct graw_info *info,
|
||||
int width, int height, enum pipe_format format,
|
||||
const void *data)
|
||||
{
|
||||
const int row_stride = width * util_format_get_blocksize(format);
|
||||
const int image_bytes = row_stride * height;
|
||||
struct pipe_resource temp, *tex;
|
||||
struct pipe_box box;
|
||||
|
||||
temp.target = PIPE_TEXTURE_2D;
|
||||
temp.format = PIPE_FORMAT_B8G8R8A8_UNORM;
|
||||
temp.width0 = width;
|
||||
temp.height0 = height;
|
||||
temp.depth0 = 1;
|
||||
temp.last_level = 0;
|
||||
temp.array_size = 1;
|
||||
temp.nr_samples = 1;
|
||||
temp.bind = PIPE_BIND_SAMPLER_VIEW;
|
||||
|
||||
tex = info->screen->resource_create(info->screen, &temp);
|
||||
if (!tex) {
|
||||
debug_printf("graw: failed to create texture\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
u_box_2d(0, 0, width, height, &box);
|
||||
|
||||
info->ctx->transfer_inline_write(info->ctx,
|
||||
tex,
|
||||
0,
|
||||
PIPE_TRANSFER_WRITE,
|
||||
&box,
|
||||
data,
|
||||
row_stride,
|
||||
image_bytes);
|
||||
|
||||
/* Possibly read back & compare against original data:
|
||||
*/
|
||||
#if 0
|
||||
{
|
||||
struct pipe_transfer *t;
|
||||
uint32_t *ptr;
|
||||
t = pipe_get_transfer(info->ctx, samptex,
|
||||
0, 0, /* level, layer */
|
||||
PIPE_TRANSFER_READ,
|
||||
0, 0, SIZE, SIZE); /* x, y, width, height */
|
||||
|
||||
ptr = info->ctx->transfer_map(info->ctx, t);
|
||||
|
||||
if (memcmp(ptr, tex2d, sizeof tex2d) != 0) {
|
||||
assert(0);
|
||||
exit(9);
|
||||
}
|
||||
|
||||
info->ctx->transfer_unmap(info->ctx, t);
|
||||
|
||||
info->ctx->transfer_destroy(info->ctx, t);
|
||||
}
|
||||
#endif
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
||||
|
||||
static INLINE void *
|
||||
graw_util_create_simple_sampler(const struct graw_info *info,
|
||||
unsigned wrap_mode,
|
||||
unsigned img_filter)
|
||||
{
|
||||
struct pipe_sampler_state sampler_desc;
|
||||
void *sampler;
|
||||
|
||||
memset(&sampler_desc, 0, sizeof sampler_desc);
|
||||
sampler_desc.wrap_s =
|
||||
sampler_desc.wrap_t =
|
||||
sampler_desc.wrap_r = wrap_mode;
|
||||
sampler_desc.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
|
||||
sampler_desc.min_img_filter =
|
||||
sampler_desc.mag_img_filter = img_filter;
|
||||
sampler_desc.compare_mode = PIPE_TEX_COMPARE_NONE;
|
||||
sampler_desc.compare_func = 0;
|
||||
sampler_desc.normalized_coords = 1;
|
||||
sampler_desc.max_anisotropy = 0;
|
||||
|
||||
sampler = info->ctx->create_sampler_state(info->ctx, &sampler_desc);
|
||||
|
||||
return sampler;
|
||||
}
|
||||
|
||||
|
||||
static INLINE struct pipe_sampler_view *
|
||||
graw_util_create_simple_sampler_view(const struct graw_info *info,
|
||||
struct pipe_resource *texture)
|
||||
{
|
||||
struct pipe_sampler_view sv_temp;
|
||||
struct pipe_sampler_view *sv;
|
||||
|
||||
memset(&sv_temp, 0, sizeof(sv_temp));
|
||||
sv_temp.format = texture->format;
|
||||
sv_temp.texture = texture;
|
||||
sv_temp.swizzle_r = PIPE_SWIZZLE_RED;
|
||||
sv_temp.swizzle_g = PIPE_SWIZZLE_GREEN;
|
||||
sv_temp.swizzle_b = PIPE_SWIZZLE_BLUE;
|
||||
sv_temp.swizzle_a = PIPE_SWIZZLE_ALPHA;
|
||||
|
||||
sv = info->ctx->create_sampler_view(info->ctx, texture, &sv_temp);
|
||||
|
||||
return sv;
|
||||
}
|
||||
|
||||
242
src/gallium/tests/graw/occlusion-query.c
Normal file
242
src/gallium/tests/graw/occlusion-query.c
Normal file
|
|
@ -0,0 +1,242 @@
|
|||
/* Test gallium occlusion queries.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "graw_util.h"
|
||||
|
||||
|
||||
static int width = 300;
|
||||
static int height = 300;
|
||||
|
||||
/* expected results of occlusion test (depndsd on window size) */
|
||||
static int expected1 = (int) ((300 * 0.9) * (300 * 0.9));
|
||||
static int expected2 = 420;
|
||||
|
||||
|
||||
static struct graw_info info;
|
||||
|
||||
struct vertex {
|
||||
float position[4];
|
||||
float color[4];
|
||||
};
|
||||
|
||||
#define z0 0.2
|
||||
#define z1 0.6
|
||||
|
||||
static struct vertex obj1_vertices[4] =
|
||||
{
|
||||
{
|
||||
{-0.9, -0.9, z0, 1.0 },
|
||||
{ 1, 0, 0, 1 }
|
||||
},
|
||||
|
||||
{
|
||||
{ 0.9, -0.9, z0, 1.0 },
|
||||
{ 1, 0, 0, 1 }
|
||||
},
|
||||
|
||||
{
|
||||
{ 0.9, 0.9, z0, 1.0 },
|
||||
{ 1, 0, 0, 1 }
|
||||
},
|
||||
|
||||
{
|
||||
{-0.9, 0.9, z0, 1.0 },
|
||||
{ 1, 0, 0, 1 }
|
||||
}
|
||||
};
|
||||
|
||||
static struct vertex obj2_vertices[4] =
|
||||
{
|
||||
{
|
||||
{ -0.2, -0.2, z1, 1.0 },
|
||||
{ 0, 0, 1, 1 }
|
||||
},
|
||||
|
||||
{
|
||||
{ 0.95, -0.2, z1, 1.0 },
|
||||
{ 0, 0, 1, 1 }
|
||||
},
|
||||
|
||||
{
|
||||
{ 0.95, 0.2, z1, 1.0 },
|
||||
{ 0, 0, 1, 1 }
|
||||
},
|
||||
|
||||
{
|
||||
{ -0.2, 0.2, z1, 1.0 },
|
||||
{ 0, 0, 1, 1 }
|
||||
},
|
||||
};
|
||||
|
||||
#define NUM_VERTS 4
|
||||
|
||||
|
||||
|
||||
static void
|
||||
set_vertices(struct vertex *vertices, unsigned bytes)
|
||||
{
|
||||
struct pipe_vertex_element ve[2];
|
||||
struct pipe_vertex_buffer vbuf;
|
||||
void *handle;
|
||||
|
||||
memset(ve, 0, sizeof ve);
|
||||
|
||||
ve[0].src_offset = Offset(struct vertex, position);
|
||||
ve[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
|
||||
ve[1].src_offset = Offset(struct vertex, color);
|
||||
ve[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
|
||||
|
||||
handle = info.ctx->create_vertex_elements_state(info.ctx, 2, ve);
|
||||
info.ctx->bind_vertex_elements_state(info.ctx, handle);
|
||||
|
||||
|
||||
vbuf.stride = sizeof(struct vertex);
|
||||
vbuf.buffer_offset = 0;
|
||||
vbuf.buffer = info.screen->user_buffer_create(info.screen,
|
||||
vertices,
|
||||
bytes,
|
||||
PIPE_BIND_VERTEX_BUFFER);
|
||||
|
||||
info.ctx->set_vertex_buffers(info.ctx, 1, &vbuf);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
set_vertex_shader(struct graw_info *info)
|
||||
{
|
||||
void *handle;
|
||||
const char *text =
|
||||
"VERT\n"
|
||||
"DCL IN[0]\n"
|
||||
"DCL IN[1]\n"
|
||||
"DCL OUT[0], POSITION\n"
|
||||
"DCL OUT[1], GENERIC[0]\n"
|
||||
" 0: MOV OUT[0], IN[0]\n"
|
||||
" 1: MOV OUT[1], IN[1]\n"
|
||||
" 2: END\n";
|
||||
|
||||
handle = graw_parse_vertex_shader(info->ctx, text);
|
||||
if (!handle) {
|
||||
debug_printf("Failed to parse vertex shader\n");
|
||||
return;
|
||||
}
|
||||
info->ctx->bind_vs_state(info->ctx, handle);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
set_fragment_shader(struct graw_info *info)
|
||||
{
|
||||
void *handle;
|
||||
const char *text =
|
||||
"FRAG\n"
|
||||
"DCL IN[0], GENERIC, LINEAR\n"
|
||||
"DCL OUT[0], COLOR\n"
|
||||
" 0: MOV OUT[0], IN[0]\n"
|
||||
" 1: END\n";
|
||||
|
||||
handle = graw_parse_fragment_shader(info->ctx, text);
|
||||
if (!handle) {
|
||||
debug_printf("Failed to parse fragment shader\n");
|
||||
return;
|
||||
}
|
||||
info->ctx->bind_fs_state(info->ctx, handle);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
draw(void)
|
||||
{
|
||||
int expected1_min = (int) (expected1 * 0.95);
|
||||
int expected1_max = (int) (expected1 * 1.05);
|
||||
int expected2_min = (int) (expected2 * 0.95);
|
||||
int expected2_max = (int) (expected2 * 1.05);
|
||||
|
||||
union pipe_color_union clear_color;
|
||||
|
||||
struct pipe_query *q1, *q2;
|
||||
uint64_t res1, res2;
|
||||
|
||||
clear_color.f[0] = 0.25;
|
||||
clear_color.f[1] = 0.25;
|
||||
clear_color.f[2] = 0.25;
|
||||
clear_color.f[3] = 1.00;
|
||||
|
||||
info.ctx->clear(info.ctx,
|
||||
PIPE_CLEAR_COLOR | PIPE_CLEAR_DEPTHSTENCIL,
|
||||
&clear_color, 1.0, 0);
|
||||
|
||||
q1 = info.ctx->create_query(info.ctx, PIPE_QUERY_OCCLUSION_COUNTER);
|
||||
q2 = info.ctx->create_query(info.ctx, PIPE_QUERY_OCCLUSION_COUNTER);
|
||||
|
||||
/* draw first, large object */
|
||||
set_vertices(obj1_vertices, sizeof(obj1_vertices));
|
||||
info.ctx->begin_query(info.ctx, q1);
|
||||
util_draw_arrays(info.ctx, PIPE_PRIM_QUADS, 0, NUM_VERTS);
|
||||
info.ctx->end_query(info.ctx, q1);
|
||||
|
||||
/* draw second, small object behind first object */
|
||||
set_vertices(obj2_vertices, sizeof(obj2_vertices));
|
||||
info.ctx->begin_query(info.ctx, q2);
|
||||
util_draw_arrays(info.ctx, PIPE_PRIM_QUADS, 0, NUM_VERTS);
|
||||
info.ctx->end_query(info.ctx, q2);
|
||||
|
||||
info.ctx->get_query_result(info.ctx, q1, TRUE, &res1);
|
||||
info.ctx->get_query_result(info.ctx, q2, TRUE, &res2);
|
||||
|
||||
printf("result1 = %lu result2 = %lu\n", res1, res2);
|
||||
if (res1 < expected1_min || res1 > expected1_max)
|
||||
printf(" Failure: result1 should be near %d\n", expected1);
|
||||
if (res2 < expected2_min || res2 > expected2_max)
|
||||
printf(" Failure: result2 should be near %d\n", expected2);
|
||||
|
||||
info.ctx->flush(info.ctx, NULL);
|
||||
|
||||
graw_util_flush_front(&info);
|
||||
|
||||
info.ctx->destroy_query(info.ctx, q1);
|
||||
info.ctx->destroy_query(info.ctx, q2);
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
static void
|
||||
resize(int w, int h)
|
||||
{
|
||||
width = w;
|
||||
height = h;
|
||||
|
||||
graw_util_viewport(&info, 0, 0, width, height, 30, 1000);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
init(void)
|
||||
{
|
||||
if (!graw_util_create_window(&info, width, height, 1, TRUE))
|
||||
exit(1);
|
||||
|
||||
graw_util_default_state(&info, TRUE);
|
||||
|
||||
graw_util_viewport(&info, 0, 0, width, height, -1.0, 1.0);
|
||||
|
||||
set_vertex_shader(&info);
|
||||
set_fragment_shader(&info);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
init();
|
||||
|
||||
printf("The red quad should mostly occlude the blue quad.\n");
|
||||
|
||||
graw_set_display_func(draw);
|
||||
/*graw_set_reshape_func(resize);*/
|
||||
graw_main_loop();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -2,36 +2,17 @@
|
|||
* any utility code, just the graw interface and gallium.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "state_tracker/graw.h"
|
||||
#include "pipe/p_screen.h"
|
||||
#include "pipe/p_context.h"
|
||||
#include "pipe/p_shader_tokens.h"
|
||||
#include "pipe/p_state.h"
|
||||
#include "pipe/p_defines.h"
|
||||
|
||||
#include "util/u_inlines.h"
|
||||
#include "util/u_memory.h" /* Offset() */
|
||||
#include "util/u_draw_quad.h"
|
||||
#include "util/u_box.h"
|
||||
|
||||
enum pipe_format formats[] = {
|
||||
PIPE_FORMAT_R8G8B8A8_UNORM,
|
||||
PIPE_FORMAT_B8G8R8A8_UNORM,
|
||||
PIPE_FORMAT_NONE
|
||||
};
|
||||
#include "graw_util.h"
|
||||
|
||||
static const int WIDTH = 300;
|
||||
static const int HEIGHT = 300;
|
||||
|
||||
static struct pipe_screen *screen = NULL;
|
||||
static struct pipe_context *ctx = NULL;
|
||||
static struct pipe_resource *rttex = NULL;
|
||||
static struct pipe_resource *samptex = NULL;
|
||||
static struct pipe_surface *surf = NULL;
|
||||
static struct graw_info info;
|
||||
|
||||
|
||||
static struct pipe_resource *texture = NULL;
|
||||
static struct pipe_sampler_view *sv = NULL;
|
||||
static void *sampler = NULL;
|
||||
static void *window = NULL;
|
||||
|
||||
struct vertex {
|
||||
float position[4];
|
||||
|
|
@ -56,29 +37,6 @@ static struct vertex vertices[] =
|
|||
|
||||
|
||||
|
||||
static void set_viewport( float x, float y,
|
||||
float width, float height,
|
||||
float near, float far)
|
||||
{
|
||||
float z = far;
|
||||
float half_width = (float)width / 2.0f;
|
||||
float half_height = (float)height / 2.0f;
|
||||
float half_depth = ((float)far - (float)near) / 2.0f;
|
||||
struct pipe_viewport_state vp;
|
||||
|
||||
vp.scale[0] = half_width;
|
||||
vp.scale[1] = half_height;
|
||||
vp.scale[2] = half_depth;
|
||||
vp.scale[3] = 1.0f;
|
||||
|
||||
vp.translate[0] = half_width + x;
|
||||
vp.translate[1] = half_height + y;
|
||||
vp.translate[2] = half_depth + z;
|
||||
vp.translate[3] = 0.0f;
|
||||
|
||||
ctx->set_viewport_state( ctx, &vp );
|
||||
}
|
||||
|
||||
static void set_vertices( void )
|
||||
{
|
||||
struct pipe_vertex_element ve[2];
|
||||
|
|
@ -92,18 +50,18 @@ static void set_vertices( void )
|
|||
ve[1].src_offset = Offset(struct vertex, color);
|
||||
ve[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
|
||||
|
||||
handle = ctx->create_vertex_elements_state(ctx, 2, ve);
|
||||
ctx->bind_vertex_elements_state(ctx, handle);
|
||||
handle = info.ctx->create_vertex_elements_state(info.ctx, 2, ve);
|
||||
info.ctx->bind_vertex_elements_state(info.ctx, handle);
|
||||
|
||||
|
||||
vbuf.stride = sizeof( struct vertex );
|
||||
vbuf.buffer_offset = 0;
|
||||
vbuf.buffer = screen->user_buffer_create(screen,
|
||||
vbuf.buffer = info.screen->user_buffer_create(info.screen,
|
||||
vertices,
|
||||
sizeof(vertices),
|
||||
PIPE_BIND_VERTEX_BUFFER);
|
||||
|
||||
ctx->set_vertex_buffers(ctx, 1, &vbuf);
|
||||
info.ctx->set_vertex_buffers(info.ctx, 1, &vbuf);
|
||||
}
|
||||
|
||||
static void set_vertex_shader( void )
|
||||
|
|
@ -119,8 +77,8 @@ static void set_vertex_shader( void )
|
|||
" 1: MOV OUT[0], IN[0]\n"
|
||||
" 2: END\n";
|
||||
|
||||
handle = graw_parse_vertex_shader(ctx, text);
|
||||
ctx->bind_vs_state(ctx, handle);
|
||||
handle = graw_parse_vertex_shader(info.ctx, text);
|
||||
info.ctx->bind_vs_state(info.ctx, handle);
|
||||
}
|
||||
|
||||
static void set_fragment_shader( void )
|
||||
|
|
@ -136,8 +94,8 @@ static void set_fragment_shader( void )
|
|||
" 1: MOV OUT[0], TEMP[0]\n"
|
||||
" 2: END\n";
|
||||
|
||||
handle = graw_parse_fragment_shader(ctx, text);
|
||||
ctx->bind_fs_state(ctx, handle);
|
||||
handle = graw_parse_fragment_shader(info.ctx, text);
|
||||
info.ctx->bind_fs_state(info.ctx, handle);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -145,23 +103,20 @@ static void draw( void )
|
|||
{
|
||||
union pipe_color_union clear_color = { {.5,.5,.5,1} };
|
||||
|
||||
ctx->clear(ctx, PIPE_CLEAR_COLOR, &clear_color, 0, 0);
|
||||
util_draw_arrays(ctx, PIPE_PRIM_QUADS, 0, 4);
|
||||
ctx->flush(ctx, NULL);
|
||||
info.ctx->clear(info.ctx, PIPE_CLEAR_COLOR, &clear_color, 0, 0);
|
||||
util_draw_arrays(info.ctx, PIPE_PRIM_QUADS, 0, 4);
|
||||
info.ctx->flush(info.ctx, NULL);
|
||||
|
||||
graw_save_surface_to_file(ctx, surf, NULL);
|
||||
graw_save_surface_to_file(info.ctx, info.color_surf[0], NULL);
|
||||
|
||||
screen->flush_frontbuffer(screen, rttex, 0, 0, window);
|
||||
graw_util_flush_front(&info);
|
||||
}
|
||||
|
||||
|
||||
#define SIZE 16
|
||||
|
||||
static void init_tex( void )
|
||||
{
|
||||
struct pipe_sampler_view sv_template;
|
||||
struct pipe_sampler_state sampler_desc;
|
||||
struct pipe_resource templat;
|
||||
struct pipe_box box;
|
||||
ubyte tex2d[SIZE][SIZE][4];
|
||||
int s, t;
|
||||
|
||||
|
|
@ -206,168 +161,25 @@ static void init_tex( void )
|
|||
tex2d[1][1][3] = 255;
|
||||
#endif
|
||||
|
||||
templat.target = PIPE_TEXTURE_2D;
|
||||
templat.format = PIPE_FORMAT_B8G8R8A8_UNORM;
|
||||
templat.width0 = SIZE;
|
||||
templat.height0 = SIZE;
|
||||
templat.depth0 = 1;
|
||||
templat.array_size = 1;
|
||||
templat.last_level = 0;
|
||||
templat.nr_samples = 1;
|
||||
templat.bind = PIPE_BIND_SAMPLER_VIEW;
|
||||
texture = graw_util_create_tex2d(&info, SIZE, SIZE,
|
||||
PIPE_FORMAT_B8G8R8A8_UNORM, tex2d);
|
||||
|
||||
|
||||
samptex = screen->resource_create(screen,
|
||||
&templat);
|
||||
if (samptex == NULL)
|
||||
exit(4);
|
||||
sv = graw_util_create_simple_sampler_view(&info, texture);
|
||||
info.ctx->set_fragment_sampler_views(info.ctx, 1, &sv);
|
||||
|
||||
u_box_2d(0,0,SIZE,SIZE, &box);
|
||||
|
||||
ctx->transfer_inline_write(ctx,
|
||||
samptex,
|
||||
0,
|
||||
PIPE_TRANSFER_WRITE,
|
||||
&box,
|
||||
tex2d,
|
||||
sizeof tex2d[0],
|
||||
sizeof tex2d);
|
||||
|
||||
/* Possibly read back & compare against original data:
|
||||
*/
|
||||
if (0)
|
||||
{
|
||||
struct pipe_transfer *t;
|
||||
uint32_t *ptr;
|
||||
t = pipe_get_transfer(ctx, samptex,
|
||||
0, 0, /* level, layer */
|
||||
PIPE_TRANSFER_READ,
|
||||
0, 0, SIZE, SIZE); /* x, y, width, height */
|
||||
|
||||
ptr = ctx->transfer_map(ctx, t);
|
||||
|
||||
if (memcmp(ptr, tex2d, sizeof tex2d) != 0) {
|
||||
assert(0);
|
||||
exit(9);
|
||||
}
|
||||
|
||||
ctx->transfer_unmap(ctx, t);
|
||||
|
||||
ctx->transfer_destroy(ctx, t);
|
||||
}
|
||||
|
||||
memset(&sv_template, 0, sizeof sv_template);
|
||||
sv_template.format = samptex->format;
|
||||
sv_template.texture = samptex;
|
||||
sv_template.swizzle_r = 0;
|
||||
sv_template.swizzle_g = 1;
|
||||
sv_template.swizzle_b = 2;
|
||||
sv_template.swizzle_a = 3;
|
||||
sv = ctx->create_sampler_view(ctx, samptex, &sv_template);
|
||||
if (sv == NULL)
|
||||
exit(5);
|
||||
|
||||
ctx->set_fragment_sampler_views(ctx, 1, &sv);
|
||||
|
||||
|
||||
memset(&sampler_desc, 0, sizeof sampler_desc);
|
||||
sampler_desc.wrap_s = PIPE_TEX_WRAP_REPEAT;
|
||||
sampler_desc.wrap_t = PIPE_TEX_WRAP_REPEAT;
|
||||
sampler_desc.wrap_r = PIPE_TEX_WRAP_REPEAT;
|
||||
sampler_desc.min_img_filter = PIPE_TEX_FILTER_NEAREST;
|
||||
sampler_desc.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
|
||||
sampler_desc.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
|
||||
sampler_desc.compare_mode = PIPE_TEX_COMPARE_NONE;
|
||||
sampler_desc.compare_func = 0;
|
||||
sampler_desc.normalized_coords = 1;
|
||||
sampler_desc.max_anisotropy = 0;
|
||||
|
||||
sampler = ctx->create_sampler_state(ctx, &sampler_desc);
|
||||
if (sampler == NULL)
|
||||
exit(6);
|
||||
|
||||
ctx->bind_fragment_sampler_states(ctx, 1, &sampler);
|
||||
|
||||
sampler = graw_util_create_simple_sampler(&info,
|
||||
PIPE_TEX_WRAP_REPEAT,
|
||||
PIPE_TEX_FILTER_NEAREST);
|
||||
info.ctx->bind_fragment_sampler_states(info.ctx, 1, &sampler);
|
||||
}
|
||||
|
||||
|
||||
static void init( void )
|
||||
{
|
||||
struct pipe_framebuffer_state fb;
|
||||
struct pipe_resource templat;
|
||||
struct pipe_surface surf_tmpl;
|
||||
int i;
|
||||
|
||||
/* It's hard to say whether window or screen should be created
|
||||
* first. Different environments would prefer one or the other.
|
||||
*
|
||||
* Also, no easy way of querying supported formats if the screen
|
||||
* cannot be created first.
|
||||
*/
|
||||
for (i = 0; formats[i] != PIPE_FORMAT_NONE; i++) {
|
||||
screen = graw_create_window_and_screen(0, 0, 300, 300,
|
||||
formats[i],
|
||||
&window);
|
||||
if (window && screen)
|
||||
break;
|
||||
}
|
||||
if (!screen || !window) {
|
||||
fprintf(stderr, "Unable to create window\n");
|
||||
if (!graw_util_create_window(&info, WIDTH, HEIGHT, 1, FALSE))
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ctx = screen->context_create(screen, NULL);
|
||||
if (ctx == NULL)
|
||||
exit(3);
|
||||
|
||||
templat.target = PIPE_TEXTURE_2D;
|
||||
templat.format = formats[i];
|
||||
templat.width0 = WIDTH;
|
||||
templat.height0 = HEIGHT;
|
||||
templat.depth0 = 1;
|
||||
templat.array_size = 1;
|
||||
templat.last_level = 0;
|
||||
templat.nr_samples = 1;
|
||||
templat.bind = (PIPE_BIND_RENDER_TARGET |
|
||||
PIPE_BIND_DISPLAY_TARGET);
|
||||
|
||||
rttex = screen->resource_create(screen,
|
||||
&templat);
|
||||
if (rttex == NULL)
|
||||
exit(4);
|
||||
|
||||
surf_tmpl.format = templat.format;
|
||||
surf_tmpl.usage = PIPE_BIND_RENDER_TARGET;
|
||||
surf_tmpl.u.tex.level = 0;
|
||||
surf_tmpl.u.tex.first_layer = 0;
|
||||
surf_tmpl.u.tex.last_layer = 0;
|
||||
surf = ctx->create_surface(ctx, rttex, &surf_tmpl);
|
||||
if (surf == NULL)
|
||||
exit(5);
|
||||
|
||||
memset(&fb, 0, sizeof fb);
|
||||
fb.nr_cbufs = 1;
|
||||
fb.width = WIDTH;
|
||||
fb.height = HEIGHT;
|
||||
fb.cbufs[0] = surf;
|
||||
|
||||
ctx->set_framebuffer_state(ctx, &fb);
|
||||
|
||||
{
|
||||
struct pipe_blend_state blend;
|
||||
void *handle;
|
||||
memset(&blend, 0, sizeof blend);
|
||||
blend.rt[0].colormask = PIPE_MASK_RGBA;
|
||||
handle = ctx->create_blend_state(ctx, &blend);
|
||||
ctx->bind_blend_state(ctx, handle);
|
||||
}
|
||||
|
||||
{
|
||||
struct pipe_depth_stencil_alpha_state depthstencil;
|
||||
void *handle;
|
||||
memset(&depthstencil, 0, sizeof depthstencil);
|
||||
handle = ctx->create_depth_stencil_alpha_state(ctx, &depthstencil);
|
||||
ctx->bind_depth_stencil_alpha_state(ctx, handle);
|
||||
}
|
||||
graw_util_default_state(&info, FALSE);
|
||||
|
||||
{
|
||||
struct pipe_rasterizer_state rasterizer;
|
||||
|
|
@ -376,11 +188,11 @@ static void init( void )
|
|||
rasterizer.cull_face = PIPE_FACE_NONE;
|
||||
rasterizer.gl_rasterization_rules = 1;
|
||||
rasterizer.depth_clip = 1;
|
||||
handle = ctx->create_rasterizer_state(ctx, &rasterizer);
|
||||
ctx->bind_rasterizer_state(ctx, handle);
|
||||
handle = info.ctx->create_rasterizer_state(info.ctx, &rasterizer);
|
||||
info.ctx->bind_rasterizer_state(info.ctx, handle);
|
||||
}
|
||||
|
||||
set_viewport(0, 0, WIDTH, HEIGHT, 30, 1000);
|
||||
graw_util_viewport(&info, 0, 0, WIDTH, HEIGHT, 30, 1000);
|
||||
|
||||
init_tex();
|
||||
|
||||
|
|
@ -389,6 +201,7 @@ static void init( void )
|
|||
set_fragment_shader();
|
||||
}
|
||||
|
||||
|
||||
static void args(int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
|
|
|
|||
224
src/gallium/tests/graw/tex-srgb.c
Normal file
224
src/gallium/tests/graw/tex-srgb.c
Normal file
|
|
@ -0,0 +1,224 @@
|
|||
/* Test sRGB texturing.
|
||||
*/
|
||||
|
||||
#include "graw_util.h"
|
||||
|
||||
|
||||
static const int WIDTH = 600;
|
||||
static const int HEIGHT = 300;
|
||||
|
||||
static struct graw_info info;
|
||||
|
||||
static struct pipe_resource *texture;
|
||||
static struct pipe_sampler_view *linear_sv, *srgb_sv;
|
||||
|
||||
|
||||
struct vertex {
|
||||
float position[4];
|
||||
float color[4];
|
||||
};
|
||||
|
||||
static struct vertex vertices1[] =
|
||||
{
|
||||
{ { -0.1, -0.9, 0.0, 1.0 },
|
||||
{ 1, 1, 0, 1 } },
|
||||
|
||||
{ { -0.1, 0.9, 0.0, 1.0 },
|
||||
{ 1, 0, 0, 1 } },
|
||||
|
||||
{ {-0.9, 0.9, 0.0, 1.0 },
|
||||
{ 0, 0, 0, 1 } },
|
||||
|
||||
{ {-0.9, -0.9, 0.0, 1.0 },
|
||||
{ 0, 1, 0, 1 } },
|
||||
};
|
||||
|
||||
|
||||
static struct vertex vertices2[] =
|
||||
{
|
||||
{ { 0.9, -0.9, 0.0, 1.0 },
|
||||
{ 1, 1, 0, 1 } },
|
||||
|
||||
{ { 0.9, 0.9, 0.0, 1.0 },
|
||||
{ 1, 0, 0, 1 } },
|
||||
|
||||
{ { 0.1, 0.9, 0.0, 1.0 },
|
||||
{ 0, 0, 0, 1 } },
|
||||
|
||||
{ { 0.1, -0.9, 0.0, 1.0 },
|
||||
{ 0, 1, 0, 1 } },
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
static void
|
||||
set_vertices(struct vertex *verts, unsigned num_verts)
|
||||
{
|
||||
struct pipe_vertex_element ve[2];
|
||||
struct pipe_vertex_buffer vbuf;
|
||||
void *handle;
|
||||
|
||||
memset(ve, 0, sizeof ve);
|
||||
|
||||
ve[0].src_offset = Offset(struct vertex, position);
|
||||
ve[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
|
||||
ve[1].src_offset = Offset(struct vertex, color);
|
||||
ve[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
|
||||
|
||||
handle = info.ctx->create_vertex_elements_state(info.ctx, 2, ve);
|
||||
info.ctx->bind_vertex_elements_state(info.ctx, handle);
|
||||
|
||||
|
||||
vbuf.stride = sizeof(struct vertex);
|
||||
vbuf.buffer_offset = 0;
|
||||
vbuf.buffer = info.screen->user_buffer_create(info.screen,
|
||||
verts,
|
||||
num_verts *sizeof(struct vertex),
|
||||
PIPE_BIND_VERTEX_BUFFER);
|
||||
|
||||
info.ctx->set_vertex_buffers(info.ctx, 1, &vbuf);
|
||||
}
|
||||
|
||||
static void set_vertex_shader( void )
|
||||
{
|
||||
void *handle;
|
||||
const char *text =
|
||||
"VERT\n"
|
||||
"DCL IN[0]\n"
|
||||
"DCL IN[1]\n"
|
||||
"DCL OUT[0], POSITION\n"
|
||||
"DCL OUT[1], GENERIC[0]\n"
|
||||
" 0: MOV OUT[1], IN[1]\n"
|
||||
" 1: MOV OUT[0], IN[0]\n"
|
||||
" 2: END\n";
|
||||
|
||||
handle = graw_parse_vertex_shader(info.ctx, text);
|
||||
info.ctx->bind_vs_state(info.ctx, handle);
|
||||
}
|
||||
|
||||
static void set_fragment_shader( void )
|
||||
{
|
||||
void *handle;
|
||||
const char *text =
|
||||
"FRAG\n"
|
||||
"DCL IN[0], GENERIC[0], PERSPECTIVE\n"
|
||||
"DCL OUT[0], COLOR\n"
|
||||
"DCL TEMP[0]\n"
|
||||
"DCL SAMP[0]\n"
|
||||
" 0: TXP TEMP[0], IN[0], SAMP[0], 2D\n"
|
||||
" 1: MOV OUT[0], TEMP[0]\n"
|
||||
" 2: END\n";
|
||||
|
||||
handle = graw_parse_fragment_shader(info.ctx, text);
|
||||
info.ctx->bind_fs_state(info.ctx, handle);
|
||||
}
|
||||
|
||||
|
||||
static void draw( void )
|
||||
{
|
||||
union pipe_color_union clear_color;
|
||||
|
||||
clear_color.f[0] = 0.5;
|
||||
clear_color.f[1] = 0.5;
|
||||
clear_color.f[2] = 0.5;
|
||||
clear_color.f[3] = 1.0;
|
||||
|
||||
info.ctx->clear(info.ctx, PIPE_CLEAR_COLOR, &clear_color, 0, 0);
|
||||
|
||||
info.ctx->set_fragment_sampler_views(info.ctx, 1, &linear_sv);
|
||||
set_vertices(vertices1, 4);
|
||||
util_draw_arrays(info.ctx, PIPE_PRIM_QUADS, 0, 4);
|
||||
|
||||
info.ctx->set_fragment_sampler_views(info.ctx, 1, &srgb_sv);
|
||||
set_vertices(vertices2, 4);
|
||||
util_draw_arrays(info.ctx, PIPE_PRIM_QUADS, 0, 4);
|
||||
|
||||
info.ctx->flush(info.ctx, NULL);
|
||||
|
||||
graw_util_flush_front(&info);
|
||||
}
|
||||
|
||||
|
||||
static void init_tex( void )
|
||||
{
|
||||
#define SIZE 64
|
||||
ubyte tex2d[SIZE][SIZE][4];
|
||||
int s, t;
|
||||
|
||||
for (s = 0; s < SIZE; s++) {
|
||||
for (t = 0; t < SIZE; t++) {
|
||||
tex2d[t][s][0] = 0;
|
||||
tex2d[t][s][1] = s * 255 / SIZE;
|
||||
tex2d[t][s][2] = t * 255 / SIZE;
|
||||
tex2d[t][s][3] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
texture = graw_util_create_tex2d(&info, SIZE, SIZE,
|
||||
PIPE_FORMAT_B8G8R8A8_UNORM, tex2d);
|
||||
|
||||
{
|
||||
void *sampler;
|
||||
sampler = graw_util_create_simple_sampler(&info,
|
||||
PIPE_TEX_WRAP_REPEAT,
|
||||
PIPE_TEX_FILTER_NEAREST);
|
||||
info.ctx->bind_fragment_sampler_states(info.ctx, 1, &sampler);
|
||||
}
|
||||
|
||||
/* linear sampler view */
|
||||
{
|
||||
struct pipe_sampler_view sv_temp;
|
||||
memset(&sv_temp, 0, sizeof sv_temp);
|
||||
sv_temp.format = PIPE_FORMAT_B8G8R8A8_UNORM;
|
||||
sv_temp.texture = texture;
|
||||
sv_temp.swizzle_r = PIPE_SWIZZLE_RED;
|
||||
sv_temp.swizzle_g = PIPE_SWIZZLE_GREEN;
|
||||
sv_temp.swizzle_b = PIPE_SWIZZLE_BLUE;
|
||||
sv_temp.swizzle_a = PIPE_SWIZZLE_ALPHA;
|
||||
linear_sv = info.ctx->create_sampler_view(info.ctx, texture, &sv_temp);
|
||||
if (linear_sv == NULL)
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* srgb sampler view */
|
||||
{
|
||||
struct pipe_sampler_view sv_temp;
|
||||
memset(&sv_temp, 0, sizeof sv_temp);
|
||||
sv_temp.format = PIPE_FORMAT_B8G8R8A8_SRGB;
|
||||
sv_temp.texture = texture;
|
||||
sv_temp.swizzle_r = PIPE_SWIZZLE_RED;
|
||||
sv_temp.swizzle_g = PIPE_SWIZZLE_GREEN;
|
||||
sv_temp.swizzle_b = PIPE_SWIZZLE_BLUE;
|
||||
sv_temp.swizzle_a = PIPE_SWIZZLE_ALPHA;
|
||||
srgb_sv = info.ctx->create_sampler_view(info.ctx, texture, &sv_temp);
|
||||
if (srgb_sv == NULL)
|
||||
exit(0);
|
||||
}
|
||||
#undef SIZE
|
||||
}
|
||||
|
||||
static void init( void )
|
||||
{
|
||||
if (!graw_util_create_window(&info, WIDTH, HEIGHT, 1, FALSE))
|
||||
exit(1);
|
||||
|
||||
graw_util_default_state(&info, FALSE);
|
||||
|
||||
graw_util_viewport(&info, 0, 0, WIDTH, HEIGHT, 30, 10000);
|
||||
|
||||
init_tex();
|
||||
|
||||
set_vertex_shader();
|
||||
set_fragment_shader();
|
||||
}
|
||||
|
||||
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
init();
|
||||
|
||||
graw_set_display_func( draw );
|
||||
graw_main_loop();
|
||||
return 0;
|
||||
}
|
||||
226
src/gallium/tests/graw/tex-swizzle.c
Normal file
226
src/gallium/tests/graw/tex-swizzle.c
Normal file
|
|
@ -0,0 +1,226 @@
|
|||
/* Test texture swizzles */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "graw_util.h"
|
||||
|
||||
|
||||
static struct graw_info info;
|
||||
|
||||
static struct pipe_resource *texture = NULL;
|
||||
static struct pipe_sampler_view *sv = NULL;
|
||||
static void *sampler = NULL;
|
||||
|
||||
static const int WIDTH = 300;
|
||||
static const int HEIGHT = 300;
|
||||
|
||||
struct vertex {
|
||||
float position[4];
|
||||
float color[4];
|
||||
};
|
||||
|
||||
static struct vertex vertices[] =
|
||||
{
|
||||
{ { 0.9, -0.9, 0.0, 1.0 },
|
||||
{ 1, 0, 0, 1 } },
|
||||
|
||||
{ { 0.9, 0.9, 0.0, 1.0 },
|
||||
{ 1, 1, 0, 1 } },
|
||||
|
||||
{ {-0.9, 0.9, 0.0, 1.0 },
|
||||
{ 0, 1, 0, 1 } },
|
||||
|
||||
{ {-0.9, -0.9, 0.0, 1.0 },
|
||||
{ 0, 0, 0, 1 } },
|
||||
};
|
||||
|
||||
|
||||
static void set_vertices(void)
|
||||
{
|
||||
struct pipe_vertex_element ve[2];
|
||||
struct pipe_vertex_buffer vbuf;
|
||||
void *handle;
|
||||
|
||||
memset(ve, 0, sizeof ve);
|
||||
|
||||
ve[0].src_offset = Offset(struct vertex, position);
|
||||
ve[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
|
||||
ve[1].src_offset = Offset(struct vertex, color);
|
||||
ve[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
|
||||
|
||||
handle = info.ctx->create_vertex_elements_state(info.ctx, 2, ve);
|
||||
info.ctx->bind_vertex_elements_state(info.ctx, handle);
|
||||
|
||||
|
||||
vbuf.stride = sizeof(struct vertex);
|
||||
vbuf.buffer_offset = 0;
|
||||
vbuf.buffer = info.screen->user_buffer_create(info.screen,
|
||||
vertices,
|
||||
sizeof(vertices),
|
||||
PIPE_BIND_VERTEX_BUFFER);
|
||||
|
||||
info.ctx->set_vertex_buffers(info.ctx, 1, &vbuf);
|
||||
}
|
||||
|
||||
static void set_vertex_shader(void)
|
||||
{
|
||||
void *handle;
|
||||
const char *text =
|
||||
"VERT\n"
|
||||
"DCL IN[0]\n"
|
||||
"DCL IN[1]\n"
|
||||
"DCL OUT[0], POSITION\n"
|
||||
"DCL OUT[1], GENERIC[0]\n"
|
||||
" 0: MOV OUT[1], IN[1]\n"
|
||||
" 1: MOV OUT[0], IN[0]\n"
|
||||
" 2: END\n";
|
||||
|
||||
handle = graw_parse_vertex_shader(info.ctx, text);
|
||||
info.ctx->bind_vs_state(info.ctx, handle);
|
||||
}
|
||||
|
||||
static void set_fragment_shader(void)
|
||||
{
|
||||
void *handle;
|
||||
const char *text =
|
||||
"FRAG\n"
|
||||
"DCL IN[0], GENERIC[0], PERSPECTIVE\n"
|
||||
"DCL OUT[0], COLOR\n"
|
||||
"DCL SAMP[0]\n"
|
||||
" 0: TXP OUT[0], IN[0], SAMP[0], 2D\n"
|
||||
" 2: END\n";
|
||||
|
||||
handle = graw_parse_fragment_shader(info.ctx, text);
|
||||
info.ctx->bind_fs_state(info.ctx, handle);
|
||||
}
|
||||
|
||||
|
||||
static void draw(void)
|
||||
{
|
||||
union pipe_color_union clear_color;
|
||||
|
||||
clear_color.f[0] = 0.5;
|
||||
clear_color.f[1] = 0.5;
|
||||
clear_color.f[2] = 0.5;
|
||||
clear_color.f[3] = 1.0;
|
||||
|
||||
info.ctx->clear(info.ctx, PIPE_CLEAR_COLOR, &clear_color, 0, 0);
|
||||
util_draw_arrays(info.ctx, PIPE_PRIM_QUADS, 0, 4);
|
||||
info.ctx->flush(info.ctx, NULL);
|
||||
|
||||
graw_util_flush_front(&info);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
init_tex(const unsigned swizzle[4])
|
||||
{
|
||||
#define SIZE 256
|
||||
struct pipe_sampler_view sv_template;
|
||||
ubyte tex2d[SIZE][SIZE][4];
|
||||
int s, t;
|
||||
|
||||
for (s = 0; s < SIZE; s++) {
|
||||
for (t = 0; t < SIZE; t++) {
|
||||
tex2d[t][s][0] = 0; /*B*/
|
||||
tex2d[t][s][1] = t; /*G*/
|
||||
tex2d[t][s][2] = s; /*R*/
|
||||
tex2d[t][s][3] = 1; /*A*/
|
||||
}
|
||||
}
|
||||
|
||||
texture = graw_util_create_tex2d(&info, SIZE, SIZE,
|
||||
PIPE_FORMAT_B8G8R8A8_UNORM, tex2d);
|
||||
|
||||
memset(&sv_template, 0, sizeof sv_template);
|
||||
sv_template.format = texture->format;
|
||||
sv_template.texture = texture;
|
||||
sv_template.swizzle_r = swizzle[0];
|
||||
sv_template.swizzle_g = swizzle[1];
|
||||
sv_template.swizzle_b = swizzle[2];
|
||||
sv_template.swizzle_a = swizzle[3];
|
||||
sv = info.ctx->create_sampler_view(info.ctx, texture, &sv_template);
|
||||
if (sv == NULL)
|
||||
exit(5);
|
||||
|
||||
info.ctx->set_fragment_sampler_views(info.ctx, 1, &sv);
|
||||
|
||||
sampler = graw_util_create_simple_sampler(&info,
|
||||
PIPE_TEX_WRAP_REPEAT,
|
||||
PIPE_TEX_FILTER_NEAREST);
|
||||
|
||||
info.ctx->bind_fragment_sampler_states(info.ctx, 1, &sampler);
|
||||
#undef SIZE
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
init(const unsigned swizzle[4])
|
||||
{
|
||||
if (!graw_util_create_window(&info, WIDTH, HEIGHT, 1, FALSE))
|
||||
exit(1);
|
||||
|
||||
graw_util_default_state(&info, FALSE);
|
||||
|
||||
graw_util_viewport(&info, 0, 0, WIDTH, HEIGHT, 30, 10000);
|
||||
|
||||
init_tex(swizzle);
|
||||
|
||||
set_vertices();
|
||||
set_vertex_shader();
|
||||
set_fragment_shader();
|
||||
}
|
||||
|
||||
|
||||
static unsigned
|
||||
char_to_swizzle(char c)
|
||||
{
|
||||
switch (c) {
|
||||
case 'r':
|
||||
return PIPE_SWIZZLE_RED;
|
||||
case 'g':
|
||||
return PIPE_SWIZZLE_GREEN;
|
||||
case 'b':
|
||||
return PIPE_SWIZZLE_BLUE;
|
||||
case 'a':
|
||||
return PIPE_SWIZZLE_ALPHA;
|
||||
case '0':
|
||||
return PIPE_SWIZZLE_ZERO;
|
||||
case '1':
|
||||
return PIPE_SWIZZLE_ONE;
|
||||
default:
|
||||
return PIPE_SWIZZLE_RED;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
const char swizzle_names[] = "rgba01";
|
||||
uint swizzle[4];
|
||||
int i;
|
||||
|
||||
swizzle[0] = PIPE_SWIZZLE_RED;
|
||||
swizzle[1] = PIPE_SWIZZLE_GREEN;
|
||||
swizzle[2] = PIPE_SWIZZLE_BLUE;
|
||||
swizzle[3] = PIPE_SWIZZLE_ALPHA;
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
swizzle[i-1] = char_to_swizzle(argv[i][0]);
|
||||
}
|
||||
|
||||
printf("Example:\n");
|
||||
printf(" tex-swizzle r 0 g 1\n");
|
||||
printf("Current swizzle = ");
|
||||
for (i = 0; i < 4; i++) {
|
||||
printf("%c", swizzle_names[swizzle[i]]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
init(swizzle);
|
||||
|
||||
graw_set_display_func(draw);
|
||||
graw_main_loop();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -3,36 +3,22 @@
|
|||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "graw_util.h"
|
||||
|
||||
#include "state_tracker/graw.h"
|
||||
#include "pipe/p_screen.h"
|
||||
#include "pipe/p_context.h"
|
||||
#include "pipe/p_state.h"
|
||||
#include "pipe/p_defines.h"
|
||||
|
||||
#include "util/u_memory.h" /* Offset() */
|
||||
#include "util/u_draw_quad.h"
|
||||
|
||||
enum pipe_format formats[] = {
|
||||
PIPE_FORMAT_R8G8B8A8_UNORM,
|
||||
PIPE_FORMAT_B8G8R8A8_UNORM,
|
||||
PIPE_FORMAT_NONE
|
||||
};
|
||||
static struct graw_info info;
|
||||
|
||||
static const int WIDTH = 300;
|
||||
static const int HEIGHT = 300;
|
||||
|
||||
static struct pipe_screen *screen = NULL;
|
||||
static struct pipe_context *ctx = NULL;
|
||||
static struct pipe_surface *surf = NULL;
|
||||
static struct pipe_resource *tex = NULL;
|
||||
static void *window = NULL;
|
||||
|
||||
struct vertex {
|
||||
float position[4];
|
||||
float color[4];
|
||||
};
|
||||
|
||||
static boolean FlatShade = FALSE;
|
||||
|
||||
|
||||
static struct vertex vertices[3] =
|
||||
{
|
||||
{
|
||||
|
|
@ -50,31 +36,6 @@ static struct vertex vertices[3] =
|
|||
};
|
||||
|
||||
|
||||
|
||||
|
||||
static void set_viewport( float x, float y,
|
||||
float width, float height,
|
||||
float near, float far)
|
||||
{
|
||||
float z = far;
|
||||
float half_width = (float)width / 2.0f;
|
||||
float half_height = (float)height / 2.0f;
|
||||
float half_depth = ((float)far - (float)near) / 2.0f;
|
||||
struct pipe_viewport_state vp;
|
||||
|
||||
vp.scale[0] = half_width;
|
||||
vp.scale[1] = half_height;
|
||||
vp.scale[2] = half_depth;
|
||||
vp.scale[3] = 1.0f;
|
||||
|
||||
vp.translate[0] = half_width + x;
|
||||
vp.translate[1] = half_height + y;
|
||||
vp.translate[2] = half_depth + z;
|
||||
vp.translate[3] = 0.0f;
|
||||
|
||||
ctx->set_viewport_state( ctx, &vp );
|
||||
}
|
||||
|
||||
static void set_vertices( void )
|
||||
{
|
||||
struct pipe_vertex_element ve[2];
|
||||
|
|
@ -88,20 +49,21 @@ static void set_vertices( void )
|
|||
ve[1].src_offset = Offset(struct vertex, color);
|
||||
ve[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
|
||||
|
||||
handle = ctx->create_vertex_elements_state(ctx, 2, ve);
|
||||
ctx->bind_vertex_elements_state(ctx, handle);
|
||||
handle = info.ctx->create_vertex_elements_state(info.ctx, 2, ve);
|
||||
info.ctx->bind_vertex_elements_state(info.ctx, handle);
|
||||
|
||||
|
||||
vbuf.stride = sizeof( struct vertex );
|
||||
vbuf.buffer_offset = 0;
|
||||
vbuf.buffer = screen->user_buffer_create(screen,
|
||||
vertices,
|
||||
sizeof(vertices),
|
||||
PIPE_BIND_VERTEX_BUFFER);
|
||||
vbuf.buffer = info.screen->user_buffer_create(info.screen,
|
||||
vertices,
|
||||
sizeof(vertices),
|
||||
PIPE_BIND_VERTEX_BUFFER);
|
||||
|
||||
ctx->set_vertex_buffers(ctx, 1, &vbuf);
|
||||
info.ctx->set_vertex_buffers(info.ctx, 1, &vbuf);
|
||||
}
|
||||
|
||||
|
||||
static void set_vertex_shader( void )
|
||||
{
|
||||
void *handle;
|
||||
|
|
@ -115,10 +77,11 @@ static void set_vertex_shader( void )
|
|||
" 1: MOV OUT[0], IN[0]\n"
|
||||
" 2: END\n";
|
||||
|
||||
handle = graw_parse_vertex_shader(ctx, text);
|
||||
ctx->bind_vs_state(ctx, handle);
|
||||
handle = graw_parse_vertex_shader(info.ctx, text);
|
||||
info.ctx->bind_vs_state(info.ctx, handle);
|
||||
}
|
||||
|
||||
|
||||
static void set_fragment_shader( void )
|
||||
{
|
||||
void *handle;
|
||||
|
|
@ -129,8 +92,8 @@ static void set_fragment_shader( void )
|
|||
" 0: MOV OUT[0], IN[0]\n"
|
||||
" 1: END\n";
|
||||
|
||||
handle = graw_parse_fragment_shader(ctx, text);
|
||||
ctx->bind_fs_state(ctx, handle);
|
||||
handle = graw_parse_fragment_shader(info.ctx, text);
|
||||
info.ctx->bind_fs_state(info.ctx, handle);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -138,100 +101,22 @@ static void draw( void )
|
|||
{
|
||||
union pipe_color_union clear_color = { {1,0,1,1} };
|
||||
|
||||
ctx->clear(ctx, PIPE_CLEAR_COLOR, &clear_color, 0, 0);
|
||||
util_draw_arrays(ctx, PIPE_PRIM_TRIANGLES, 0, 3);
|
||||
ctx->flush(ctx, NULL);
|
||||
info.ctx->clear(info.ctx, PIPE_CLEAR_COLOR, &clear_color, 0, 0);
|
||||
util_draw_arrays(info.ctx, PIPE_PRIM_TRIANGLES, 0, 3);
|
||||
info.ctx->flush(info.ctx, NULL);
|
||||
|
||||
graw_save_surface_to_file(ctx, surf, NULL);
|
||||
graw_save_surface_to_file(info.ctx, info.color_surf[0], NULL);
|
||||
|
||||
screen->flush_frontbuffer(screen, tex, 0, 0, window);
|
||||
graw_util_flush_front(&info);
|
||||
}
|
||||
|
||||
|
||||
static void init( void )
|
||||
{
|
||||
struct pipe_framebuffer_state fb;
|
||||
struct pipe_resource templat;
|
||||
struct pipe_surface surf_tmpl;
|
||||
int i;
|
||||
|
||||
/* It's hard to say whether window or screen should be created
|
||||
* first. Different environments would prefer one or the other.
|
||||
*
|
||||
* Also, no easy way of querying supported formats if the screen
|
||||
* cannot be created first.
|
||||
*/
|
||||
for (i = 0; formats[i] != PIPE_FORMAT_NONE; i++) {
|
||||
screen = graw_create_window_and_screen(0, 0, 300, 300,
|
||||
formats[i],
|
||||
&window);
|
||||
if (window && screen)
|
||||
break;
|
||||
}
|
||||
if (!screen || !window) {
|
||||
fprintf(stderr, "Unable to create window\n");
|
||||
if (!graw_util_create_window(&info, WIDTH, HEIGHT, 1, FALSE))
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ctx = screen->context_create(screen, NULL);
|
||||
if (ctx == NULL) {
|
||||
fprintf(stderr, "Unable to create context!\n");
|
||||
exit(3);
|
||||
}
|
||||
|
||||
templat.target = PIPE_TEXTURE_2D;
|
||||
templat.format = formats[i];
|
||||
templat.width0 = WIDTH;
|
||||
templat.height0 = HEIGHT;
|
||||
templat.depth0 = 1;
|
||||
templat.array_size = 1;
|
||||
templat.last_level = 0;
|
||||
templat.nr_samples = 1;
|
||||
templat.bind = (PIPE_BIND_RENDER_TARGET |
|
||||
PIPE_BIND_DISPLAY_TARGET);
|
||||
|
||||
tex = screen->resource_create(screen,
|
||||
&templat);
|
||||
if (tex == NULL) {
|
||||
fprintf(stderr, "Unable to create screen texture!\n");
|
||||
exit(4);
|
||||
}
|
||||
|
||||
surf_tmpl.format = templat.format;
|
||||
surf_tmpl.usage = PIPE_BIND_RENDER_TARGET;
|
||||
surf_tmpl.u.tex.level = 0;
|
||||
surf_tmpl.u.tex.first_layer = 0;
|
||||
surf_tmpl.u.tex.last_layer = 0;
|
||||
surf = ctx->create_surface(ctx, tex, &surf_tmpl);
|
||||
if (surf == NULL) {
|
||||
fprintf(stderr, "Unable to create tex surface!\n");
|
||||
exit(5);
|
||||
}
|
||||
|
||||
memset(&fb, 0, sizeof fb);
|
||||
fb.nr_cbufs = 1;
|
||||
fb.width = WIDTH;
|
||||
fb.height = HEIGHT;
|
||||
fb.cbufs[0] = surf;
|
||||
|
||||
ctx->set_framebuffer_state(ctx, &fb);
|
||||
|
||||
{
|
||||
struct pipe_blend_state blend;
|
||||
void *handle;
|
||||
memset(&blend, 0, sizeof blend);
|
||||
blend.rt[0].colormask = PIPE_MASK_RGBA;
|
||||
handle = ctx->create_blend_state(ctx, &blend);
|
||||
ctx->bind_blend_state(ctx, handle);
|
||||
}
|
||||
|
||||
{
|
||||
struct pipe_depth_stencil_alpha_state depthstencil;
|
||||
void *handle;
|
||||
memset(&depthstencil, 0, sizeof depthstencil);
|
||||
handle = ctx->create_depth_stencil_alpha_state(ctx, &depthstencil);
|
||||
ctx->bind_depth_stencil_alpha_state(ctx, handle);
|
||||
}
|
||||
graw_util_default_state(&info, FALSE);
|
||||
|
||||
{
|
||||
struct pipe_rasterizer_state rasterizer;
|
||||
|
|
@ -239,12 +124,15 @@ static void init( void )
|
|||
memset(&rasterizer, 0, sizeof rasterizer);
|
||||
rasterizer.cull_face = PIPE_FACE_NONE;
|
||||
rasterizer.gl_rasterization_rules = 1;
|
||||
rasterizer.flatshade = FlatShade;
|
||||
rasterizer.depth_clip = 1;
|
||||
handle = ctx->create_rasterizer_state(ctx, &rasterizer);
|
||||
ctx->bind_rasterizer_state(ctx, handle);
|
||||
handle = info.ctx->create_rasterizer_state(info.ctx, &rasterizer);
|
||||
info.ctx->bind_rasterizer_state(info.ctx, handle);
|
||||
}
|
||||
|
||||
set_viewport(0, 0, WIDTH, HEIGHT, 30, 1000);
|
||||
|
||||
graw_util_viewport(&info, 0, 0, WIDTH, HEIGHT, 30, 1000);
|
||||
|
||||
set_vertices();
|
||||
set_vertex_shader();
|
||||
set_fragment_shader();
|
||||
|
|
@ -254,11 +142,18 @@ static void args(int argc, char *argv[])
|
|||
{
|
||||
int i;
|
||||
|
||||
for (i = 1; i < argc;) {
|
||||
for (i = 1; i < argc; ) {
|
||||
if (graw_parse_args(&i, argc, argv)) {
|
||||
continue;
|
||||
/* ok */
|
||||
}
|
||||
else if (strcmp(argv[i], "-f") == 0) {
|
||||
FlatShade = TRUE;
|
||||
i++;
|
||||
}
|
||||
else {
|
||||
printf("Invalid arg %s\n", argv[i]);
|
||||
exit(1);
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue