diff options
Diffstat (limited to 'progs/gallium')
-rw-r--r-- | progs/gallium/python/samples/tri.py | 20 | ||||
-rw-r--r-- | progs/gallium/raw/SConscript | 17 | ||||
-rw-r--r-- | progs/gallium/raw/clear.c | 95 | ||||
-rw-r--r-- | progs/gallium/trivial/.gitignore | 3 | ||||
-rw-r--r-- | progs/gallium/trivial/Makefile | 44 | ||||
-rw-r--r-- | progs/gallium/trivial/quad-tex.c | 346 | ||||
-rw-r--r-- | progs/gallium/trivial/tri.c | 278 |
7 files changed, 793 insertions, 10 deletions
diff --git a/progs/gallium/python/samples/tri.py b/progs/gallium/python/samples/tri.py index d7fbdb10ac3..9f6d787dcb2 100644 --- a/progs/gallium/python/samples/tri.py +++ b/progs/gallium/python/samples/tri.py @@ -30,19 +30,19 @@ from gallium import * -def make_image(surface): - data = surface.get_tile_rgba8(0, 0, surface.width, surface.height) +def make_image(ctx, surface): + data = ctx.surface_read_rgba8(surface, 0, 0, surface.width, surface.height) import Image outimage = Image.fromstring('RGBA', (surface.width, surface.height), data, "raw", 'RGBA', 0, 1) return outimage -def save_image(filename, surface): - outimage = make_image(surface) +def save_image(ctx, surface, filename): + outimage = make_image(ctx, surface) outimage.save(filename, "PNG") -def show_image(surface): - outimage = make_image(surface) +def show_image(ctx, surface): + outimage = make_image(ctx, surface) import Tkinter as tk from PIL import Image, ImageTk @@ -216,10 +216,10 @@ def test(dev): ctx.flush() - show_image(cbuf) - #show_image(zbuf) - #save_image('cbuf.png', cbuf) - #save_image('zbuf.png', zbuf) + show_image(ctx, cbuf) + show_image(ctx, zbuf) + save_image(ctx, cbuf, 'cbuf.png') + save_image(ctx, zbuf, 'zbuf.png') diff --git a/progs/gallium/raw/SConscript b/progs/gallium/raw/SConscript new file mode 100644 index 00000000000..073b97951e7 --- /dev/null +++ b/progs/gallium/raw/SConscript @@ -0,0 +1,17 @@ +Import('*') + +env = env.Clone() + +env.Prepend(LIBPATH = [graw.dir]) +env.Prepend(LIBS = [graw.name]) + +progs = [ + 'clear' +] + +for prog in progs: + env.Program( + target = prog, + source = prog + '.c', + ) + diff --git a/progs/gallium/raw/clear.c b/progs/gallium/raw/clear.c new file mode 100644 index 00000000000..5ef5254edc9 --- /dev/null +++ b/progs/gallium/raw/clear.c @@ -0,0 +1,95 @@ +/* Display a cleared blue window. This demo has no dependencies on + * any utility code, just the graw interface and gallium. + */ + +#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 <unistd.h> /* for sleep() */ + +#include "util/u_debug.h" /* debug_dump_surface_bmp() */ + +enum pipe_format formats[] = { + PIPE_FORMAT_R8G8B8A8_UNORM, + PIPE_FORMAT_B8G8R8A8_UNORM, + PIPE_FORMAT_NONE +}; + +static const int WIDTH = 300; +static const int HEIGHT = 300; + +int main( int argc, char *argv[] ) +{ + struct pipe_screen *screen; + struct pipe_context *pipe; + struct pipe_surface *surf; + struct pipe_framebuffer_state fb; + struct pipe_texture *tex, templat; + void *window = NULL; + float clear_color[4] = {1,0,1,1}; + int i; + + screen = graw_init(); + if (screen == NULL) + exit(1); + + for (i = 0; + window == NULL && formats[i] != PIPE_FORMAT_NONE; + i++) { + + window = graw_create_window(0,0,300,300, formats[i]); + } + + if (window == NULL) + exit(2); + + pipe = screen->context_create(screen, NULL); + if (pipe == NULL) + exit(3); + + templat.target = PIPE_TEXTURE_2D; + templat.format = formats[i]; + templat.width0 = WIDTH; + templat.height0 = HEIGHT; + templat.depth0 = 1; + templat.last_level = 0; + templat.nr_samples = 1; + templat.tex_usage = (PIPE_TEXTURE_USAGE_RENDER_TARGET | + PIPE_TEXTURE_USAGE_DISPLAY_TARGET); + + tex = screen->texture_create(screen, + &templat); + if (tex == NULL) + exit(4); + + surf = screen->get_tex_surface(screen, tex, 0, 0, 0, + PIPE_TEXTURE_USAGE_RENDER_TARGET | + PIPE_TEXTURE_USAGE_DISPLAY_TARGET); + if (surf == NULL) + exit(5); + + memset(&fb, 0, sizeof fb); + fb.nr_cbufs = 1; + fb.width = WIDTH; + fb.height = HEIGHT; + fb.cbufs[0] = surf; + + pipe->set_framebuffer_state(pipe, &fb); + pipe->clear(pipe, PIPE_CLEAR_COLOR, clear_color, 0, 0); + pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); + + /* At the moment, libgraw includes/makes available all 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. + */ + if (0) + debug_dump_surface_bmp(pipe, "result.bmp", surf); + + screen->flush_frontbuffer(screen, surf, window); + + sleep(100); + return 0; +} diff --git a/progs/gallium/trivial/.gitignore b/progs/gallium/trivial/.gitignore new file mode 100644 index 00000000000..af6cdedbeba --- /dev/null +++ b/progs/gallium/trivial/.gitignore @@ -0,0 +1,3 @@ +tri +quad-tex +result.bmp diff --git a/progs/gallium/trivial/Makefile b/progs/gallium/trivial/Makefile new file mode 100644 index 00000000000..2b8af1ac06c --- /dev/null +++ b/progs/gallium/trivial/Makefile @@ -0,0 +1,44 @@ +# progs/gallium/simple/Makefile + +TOP = ../../.. +include $(TOP)/configs/current + +INCLUDES = \ + -I. \ + -I$(TOP)/src/gallium/include \ + -I$(TOP)/src/gallium/auxiliary \ + -I$(TOP)/src/gallium/drivers \ + -I$(TOP)/src/gallium/winsys \ + $(PROG_INCLUDES) + +LINKS = \ + $(TOP)/src/gallium/drivers/trace/libtrace.a \ + $(TOP)/src/gallium/winsys/sw/null/libws_null.a \ + $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ + $(GALLIUM_AUXILIARIES) \ + $(PROG_LINKS) + +SOURCES = \ + tri.c \ + quad-tex.c + +OBJECTS = $(SOURCES:.c=.o) + +PROGS = $(OBJECTS:.o=) + +##### TARGETS ##### + +default: $(PROGS) + +clean: + -rm -f $(PROGS) + -rm -f *.o + -rm -f result.bmp + +##### RULES ##### + +$(OBJECTS): %.o: %.c + $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $(PROG_DEFINES) $< -o $@ + +$(PROGS): %: %.o + $(CC) $(LDFLAGS) $< $(LINKS) -lm -lpthread -o $@ diff --git a/progs/gallium/trivial/quad-tex.c b/progs/gallium/trivial/quad-tex.c new file mode 100644 index 00000000000..553f5582e7e --- /dev/null +++ b/progs/gallium/trivial/quad-tex.c @@ -0,0 +1,346 @@ +/************************************************************************** + * + * Copyright © 2010 Jakob Bornecrantz + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#define USE_TRACE 0 +#define WIDTH 300 +#define HEIGHT 300 +#define NEAR 30 +#define FAR 1000 +#define FLIP 0 + +/* pipe_*_state structs */ +#include "pipe/p_state.h" +/* pipe_context */ +#include "pipe/p_context.h" +/* pipe_screen */ +#include "pipe/p_screen.h" +/* PIPE_* */ +#include "pipe/p_defines.h" +/* TGSI_SEMANTIC_{POSITION|GENERIC} */ +#include "pipe/p_shader_tokens.h" +/* pipe_buffer_* helpers */ +#include "util/u_inlines.h" + +/* constant state object helper */ +#include "cso_cache/cso_context.h" + +/* u_sampler_view_default_template */ +#include "util/u_sampler.h" +/* debug_dump_surface_bmp */ +#include "util/u_debug.h" +/* util_draw_vertex_buffer helper */ +#include "util/u_draw_quad.h" +/* FREE & CALLOC_STRUCT */ +#include "util/u_memory.h" +/* util_make_[fragment|vertex]_passthrough_shader */ +#include "util/u_simple_shaders.h" + +/* softpipe software driver */ +#include "softpipe/sp_public.h" + +/* null software winsys */ +#include "sw/null/null_sw_winsys.h" + +/* traceing support see src/gallium/drivers/trace/README for more info. */ +#if USE_TRACE +#include "trace/tr_screen.h" +#include "trace/tr_context.h" +#endif + +struct program +{ + struct pipe_screen *screen; + struct pipe_context *pipe; + struct cso_context *cso; + + struct pipe_blend_state blend; + struct pipe_depth_stencil_alpha_state depthstencil; + struct pipe_rasterizer_state rasterizer; + struct pipe_sampler_state sampler; + struct pipe_viewport_state viewport; + struct pipe_framebuffer_state framebuffer; + struct pipe_vertex_element velem[2]; + + void *vs; + void *fs; + + float clear_color[4]; + + struct pipe_buffer *vbuf; + struct pipe_texture *target; + struct pipe_texture *tex; + struct pipe_sampler_view *view; +}; + +static void init_prog(struct program *p) +{ + /* create the software rasterizer */ + p->screen = softpipe_create_screen(null_sw_create()); +#if USE_TRACE + p->screen = trace_screen_create(p->screen); +#endif + p->pipe = p->screen->context_create(p->screen, NULL); + p->cso = cso_create_context(p->pipe); + + /* set clear color */ + p->clear_color[0] = 0.3; + p->clear_color[1] = 0.1; + p->clear_color[2] = 0.3; + p->clear_color[3] = 1.0; + + /* vertex buffer */ + { + float vertices[4][2][4] = { + { + { 0.9f, 0.9f, 0.0f, 1.0f }, + { 1.0f, 1.0f, 0.0f, 1.0f } + }, + { + { -0.9f, 0.9f, 0.0f, 1.0f }, + { 0.0f, 1.0f, 0.0f, 1.0f } + }, + { + { -0.9f, -0.9f, 0.0f, 1.0f }, + { 0.0f, 0.0f, 1.0f, 1.0f } + }, + { + { 0.9f, -0.9f, 0.0f, 1.0f }, + { 1.0f, 0.0f, 1.0f, 1.0f } + } + }; + + p->vbuf = pipe_buffer_create(p->screen, 16, PIPE_BUFFER_USAGE_VERTEX, sizeof(vertices)); + pipe_buffer_write(p->screen, p->vbuf, 0, sizeof(vertices), vertices); + } + + /* render target texture */ + { + struct pipe_texture tmplt; + memset(&tmplt, 0, sizeof(tmplt)); + tmplt.target = PIPE_TEXTURE_2D; + tmplt.format = PIPE_FORMAT_B8G8R8A8_UNORM; /* All drivers support this */ + tmplt.width0 = WIDTH; + tmplt.height0 = HEIGHT; + tmplt.depth0 = 1; + tmplt.last_level = 0; + tmplt.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET; + + p->target = p->screen->texture_create(p->screen, &tmplt); + } + + /* sampler texture */ + { + uint32_t *ptr; + struct pipe_transfer *t; + struct pipe_texture t_tmplt; + struct pipe_sampler_view v_tmplt; + + memset(&t_tmplt, 0, sizeof(t_tmplt)); + t_tmplt.target = PIPE_TEXTURE_2D; + t_tmplt.format = PIPE_FORMAT_B8G8R8A8_UNORM; /* All drivers support this */ + t_tmplt.width0 = 2; + t_tmplt.height0 = 2; + t_tmplt.depth0 = 1; + t_tmplt.last_level = 0; + t_tmplt.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET; + + p->tex = p->screen->texture_create(p->screen, &t_tmplt); + + t = p->pipe->get_tex_transfer(p->pipe, p->tex, + 0, 0, 0, /* face, level, zslice */ + PIPE_TRANSFER_WRITE, + 0, 0, 2, 2); /* x, y, width, height */ + + ptr = p->pipe->transfer_map(p->pipe, t); + ptr[0] = 0xffff0000; + ptr[1] = 0xff0000ff; + ptr[2] = 0xff00ff00; + ptr[3] = 0xffffff00; + p->pipe->transfer_unmap(p->pipe, t); + + p->pipe->tex_transfer_destroy(p->pipe, t); + + u_sampler_view_default_template(&v_tmplt, p->tex, p->tex->format); + + p->view = p->pipe->create_sampler_view(p->pipe, p->tex, &v_tmplt); + } + + /* disabled blending/masking */ + memset(&p->blend, 0, sizeof(p->blend)); + p->blend.rt[0].colormask = PIPE_MASK_RGBA; + + /* no-op depth/stencil/alpha */ + memset(&p->depthstencil, 0, sizeof(p->depthstencil)); + + /* rasterizer */ + memset(&p->rasterizer, 0, sizeof(p->rasterizer)); + p->rasterizer.front_winding = PIPE_WINDING_CW; + p->rasterizer.cull_mode = PIPE_WINDING_NONE; + p->rasterizer.gl_rasterization_rules = 1; + + /* sampler */ + memset(&p->sampler, 0, sizeof(p->sampler)); + p->sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + p->sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + p->sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + p->sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; + p->sampler.min_img_filter = PIPE_TEX_MIPFILTER_LINEAR; + p->sampler.mag_img_filter = PIPE_TEX_MIPFILTER_LINEAR; + p->sampler.normalized_coords = 1; + + /* drawing destination */ + memset(&p->framebuffer, 0, sizeof(p->framebuffer)); + p->framebuffer.width = WIDTH; + p->framebuffer.height = HEIGHT; + p->framebuffer.nr_cbufs = 1; + p->framebuffer.cbufs[0] = p->screen->get_tex_surface(p->screen, p->target, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE); + + /* viewport, depth isn't really needed */ + { + float x = 0; + float y = 0; + 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; + float scale, bias; + + if (FLIP) { + scale = -1.0f; + bias = (float)HEIGHT; + } else { + scale = 1.0f; + bias = 0.0f; + } + + p->viewport.scale[0] = half_width; + p->viewport.scale[1] = half_height * scale; + p->viewport.scale[2] = half_depth; + p->viewport.scale[3] = 1.0f; + + p->viewport.translate[0] = half_width + x; + p->viewport.translate[1] = (half_height + y) * scale + bias; + p->viewport.translate[2] = half_depth + z; + p->viewport.translate[3] = 0.0f; + } + + /* vertex elements state */ + memset(p->velem, 0, sizeof(p->velem)); + p->velem[0].src_offset = 0 * 4 * sizeof(float); /* offset 0, first element */ + p->velem[0].instance_divisor = 0; + p->velem[0].vertex_buffer_index = 0; + p->velem[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + + p->velem[1].src_offset = 1 * 4 * sizeof(float); /* offset 16, second element */ + p->velem[1].instance_divisor = 0; + p->velem[1].vertex_buffer_index = 0; + p->velem[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + + /* vertex shader */ + { + const uint semantic_names[] = { TGSI_SEMANTIC_POSITION, + TGSI_SEMANTIC_GENERIC }; + const uint semantic_indexes[] = { 0, 0 }; + p->vs = util_make_vertex_passthrough_shader(p->pipe, 2, semantic_names, semantic_indexes); + } + + /* fragment shader */ + p->fs = util_make_fragment_tex_shader(p->pipe, TGSI_TEXTURE_2D); +} + +static void close_prog(struct program *p) +{ + /* unset bound textures as well */ + cso_set_fragment_sampler_views(p->cso, 0, NULL); + + /* unset all state */ + cso_release_all(p->cso); + + p->pipe->delete_vs_state(p->pipe, p->vs); + p->pipe->delete_fs_state(p->pipe, p->fs); + + pipe_surface_reference(&p->framebuffer.cbufs[0], NULL); + pipe_sampler_view_reference(&p->view, NULL); + pipe_texture_reference(&p->target, NULL); + pipe_texture_reference(&p->tex, NULL); + pipe_buffer_reference(&p->vbuf, NULL); + + cso_destroy_context(p->cso); + p->pipe->destroy(p->pipe); + p->screen->destroy(p->screen); + + FREE(p); +} + +static void draw(struct program *p) +{ + /* set the render target */ + cso_set_framebuffer(p->cso, &p->framebuffer); + + /* clear the render target */ + p->pipe->clear(p->pipe, PIPE_CLEAR_COLOR, p->clear_color, 0, 0); + + /* set misc state we care about */ + cso_set_blend(p->cso, &p->blend); + cso_set_depth_stencil_alpha(p->cso, &p->depthstencil); + cso_set_rasterizer(p->cso, &p->rasterizer); + cso_set_viewport(p->cso, &p->viewport); + + /* sampler */ + cso_single_sampler(p->cso, 0, &p->sampler); + cso_single_sampler_done(p->cso); + + /* texture sampler view */ + cso_set_fragment_sampler_views(p->cso, 1, &p->view); + + /* shaders */ + cso_set_fragment_shader_handle(p->cso, p->fs); + cso_set_vertex_shader_handle(p->cso, p->vs); + + /* vertex element data */ + cso_set_vertex_elements(p->cso, 2, p->velem); + + util_draw_vertex_buffer(p->pipe, + p->vbuf, 0, + PIPE_PRIM_QUADS, + 4, /* verts */ + 2); /* attribs/vert */ + + p->pipe->flush(p->pipe, PIPE_FLUSH_RENDER_CACHE, NULL); + + debug_dump_surface_bmp(p->pipe, "result.bmp", p->framebuffer.cbufs[0]); +} + +int main(int argc, char** argv) +{ + struct program *p = CALLOC_STRUCT(program); + + init_prog(p); + draw(p); + close_prog(p); + + return 0; +} diff --git a/progs/gallium/trivial/tri.c b/progs/gallium/trivial/tri.c new file mode 100644 index 00000000000..cae1bdb1b1c --- /dev/null +++ b/progs/gallium/trivial/tri.c @@ -0,0 +1,278 @@ +/************************************************************************** + * + * Copyright © 2010 Jakob Bornecrantz + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#define USE_TRACE 0 +#define WIDTH 300 +#define HEIGHT 300 +#define NEAR 30 +#define FAR 1000 +#define FLIP 0 + +/* pipe_*_state structs */ +#include "pipe/p_state.h" +/* pipe_context */ +#include "pipe/p_context.h" +/* pipe_screen */ +#include "pipe/p_screen.h" +/* PIPE_* */ +#include "pipe/p_defines.h" +/* TGSI_SEMANTIC_{POSITION|GENERIC} */ +#include "pipe/p_shader_tokens.h" +/* pipe_buffer_* helpers */ +#include "util/u_inlines.h" + +/* constant state object helper */ +#include "cso_cache/cso_context.h" + +/* debug_dump_surface_bmp */ +#include "util/u_debug.h" +/* util_draw_vertex_buffer helper */ +#include "util/u_draw_quad.h" +/* FREE & CALLOC_STRUCT */ +#include "util/u_memory.h" +/* util_make_[fragment|vertex]_passthrough_shader */ +#include "util/u_simple_shaders.h" + +/* softpipe software driver */ +#include "softpipe/sp_public.h" + +/* null software winsys */ +#include "sw/null/null_sw_winsys.h" + +/* traceing support see src/gallium/drivers/trace/README for more info. */ +#if USE_TRACE +#include "trace/tr_screen.h" +#include "trace/tr_context.h" +#endif + +struct program +{ + struct pipe_screen *screen; + struct pipe_context *pipe; + struct cso_context *cso; + + struct pipe_blend_state blend; + struct pipe_depth_stencil_alpha_state depthstencil; + struct pipe_rasterizer_state rasterizer; + struct pipe_viewport_state viewport; + struct pipe_framebuffer_state framebuffer; + struct pipe_vertex_element velem[2]; + + void *vs; + void *fs; + + float clear_color[4]; + + struct pipe_buffer *vbuf; + struct pipe_texture *target; +}; + +static void init_prog(struct program *p) +{ + /* create the software rasterizer */ + p->screen = softpipe_create_screen(null_sw_create()); +#if USE_TRACE + p->screen = trace_screen_create(p->screen); +#endif + p->pipe = p->screen->context_create(p->screen, NULL); + p->cso = cso_create_context(p->pipe); + + /* set clear color */ + p->clear_color[0] = 0.3; + p->clear_color[1] = 0.1; + p->clear_color[2] = 0.3; + p->clear_color[3] = 1.0; + + /* vertex buffer */ + { + float vertices[4][2][4] = { + { + { 0.0f, -0.9f, 0.0f, 1.0f }, + { 1.0f, 0.0f, 0.0f, 1.0f } + }, + { + { -0.9f, 0.9f, 0.0f, 1.0f }, + { 0.0f, 1.0f, 0.0f, 1.0f } + }, + { + { 0.9f, 0.9f, 0.0f, 1.0f }, + { 0.0f, 0.0f, 1.0f, 1.0f } + } + }; + + p->vbuf = pipe_buffer_create(p->screen, 16, PIPE_BUFFER_USAGE_VERTEX, sizeof(vertices)); + pipe_buffer_write(p->screen, p->vbuf, 0, sizeof(vertices), vertices); + } + + /* render target texture */ + { + struct pipe_texture tmplt; + memset(&tmplt, 0, sizeof(tmplt)); + tmplt.target = PIPE_TEXTURE_2D; + tmplt.format = PIPE_FORMAT_B8G8R8A8_UNORM; /* All drivers support this */ + tmplt.width0 = WIDTH; + tmplt.height0 = HEIGHT; + tmplt.depth0 = 1; + tmplt.last_level = 0; + tmplt.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET; + + p->target = p->screen->texture_create(p->screen, &tmplt); + } + + /* disabled blending/masking */ + memset(&p->blend, 0, sizeof(p->blend)); + p->blend.rt[0].colormask = PIPE_MASK_RGBA; + + /* no-op depth/stencil/alpha */ + memset(&p->depthstencil, 0, sizeof(p->depthstencil)); + + /* rasterizer */ + memset(&p->rasterizer, 0, sizeof(p->rasterizer)); + p->rasterizer.front_winding = PIPE_WINDING_CW; + p->rasterizer.cull_mode = PIPE_WINDING_NONE; + p->rasterizer.gl_rasterization_rules = 1; + + /* drawing destination */ + memset(&p->framebuffer, 0, sizeof(p->framebuffer)); + p->framebuffer.width = WIDTH; + p->framebuffer.height = HEIGHT; + p->framebuffer.nr_cbufs = 1; + p->framebuffer.cbufs[0] = p->screen->get_tex_surface(p->screen, p->target, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE); + + /* viewport, depth isn't really needed */ + { + float x = 0; + float y = 0; + 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; + float scale, bias; + + if (FLIP) { + scale = -1.0f; + bias = (float)HEIGHT; + } else { + scale = 1.0f; + bias = 0.0f; + } + + p->viewport.scale[0] = half_width; + p->viewport.scale[1] = half_height * scale; + p->viewport.scale[2] = half_depth; + p->viewport.scale[3] = 1.0f; + + p->viewport.translate[0] = half_width + x; + p->viewport.translate[1] = (half_height + y) * scale + bias; + p->viewport.translate[2] = half_depth + z; + p->viewport.translate[3] = 0.0f; + } + + /* vertex elements state */ + memset(p->velem, 0, sizeof(p->velem)); + p->velem[0].src_offset = 0 * 4 * sizeof(float); /* offset 0, first element */ + p->velem[0].instance_divisor = 0; + p->velem[0].vertex_buffer_index = 0; + p->velem[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + + p->velem[1].src_offset = 1 * 4 * sizeof(float); /* offset 16, second element */ + p->velem[1].instance_divisor = 0; + p->velem[1].vertex_buffer_index = 0; + p->velem[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + + /* vertex shader */ + { + const uint semantic_names[] = { TGSI_SEMANTIC_POSITION, + TGSI_SEMANTIC_COLOR }; + const uint semantic_indexes[] = { 0, 0 }; + p->vs = util_make_vertex_passthrough_shader(p->pipe, 2, semantic_names, semantic_indexes); + } + + /* fragment shader */ + p->fs = util_make_fragment_passthrough_shader(p->pipe); +} + +static void close_prog(struct program *p) +{ + /* unset all state */ + cso_release_all(p->cso); + + p->pipe->delete_vs_state(p->pipe, p->vs); + p->pipe->delete_fs_state(p->pipe, p->fs); + + pipe_surface_reference(&p->framebuffer.cbufs[0], NULL); + pipe_texture_reference(&p->target, NULL); + pipe_buffer_reference(&p->vbuf, NULL); + + cso_destroy_context(p->cso); + p->pipe->destroy(p->pipe); + p->screen->destroy(p->screen); + + FREE(p); +} + +static void draw(struct program *p) +{ + /* set the render target */ + cso_set_framebuffer(p->cso, &p->framebuffer); + + /* clear the render target */ + p->pipe->clear(p->pipe, PIPE_CLEAR_COLOR, p->clear_color, 0, 0); + + /* set misc state we care about */ + cso_set_blend(p->cso, &p->blend); + cso_set_depth_stencil_alpha(p->cso, &p->depthstencil); + cso_set_rasterizer(p->cso, &p->rasterizer); + cso_set_viewport(p->cso, &p->viewport); + + /* shaders */ + cso_set_fragment_shader_handle(p->cso, p->fs); + cso_set_vertex_shader_handle(p->cso, p->vs); + + /* vertex element data */ + cso_set_vertex_elements(p->cso, 2, p->velem); + + util_draw_vertex_buffer(p->pipe, + p->vbuf, 0, + PIPE_PRIM_TRIANGLES, + 3, /* verts */ + 2); /* attribs/vert */ + + p->pipe->flush(p->pipe, PIPE_FLUSH_RENDER_CACHE, NULL); + + debug_dump_surface_bmp(p->pipe, "result.bmp", p->framebuffer.cbufs[0]); +} + +int main(int argc, char** argv) +{ + struct program *p = CALLOC_STRUCT(program); + + init_prog(p); + draw(p); + close_prog(p); + + return 0; +} |