Go to the source code of this file.
Functions | |
struct gen_mipmap_state * | util_create_gen_mipmap (struct pipe_context *pipe, struct cso_context *cso) |
Create a mipmap generation context. | |
void | util_destroy_gen_mipmap (struct gen_mipmap_state *ctx) |
Destroy a mipmap generation context. | |
void | util_gen_mipmap_flush (struct gen_mipmap_state *ctx) |
void | util_gen_mipmap (struct gen_mipmap_state *ctx, struct pipe_texture *pt, uint face, uint baseLevel, uint lastLevel, uint filter) |
Generate mipmap images. |
struct gen_mipmap_state* util_create_gen_mipmap | ( | struct pipe_context * | pipe, | |
struct cso_context * | cso | |||
) | [read] |
Create a mipmap generation context.
The idea is to create one of these and re-use it each time we need to generate a mipmap.
Definition at line 700 of file u_gen_mipmap.c.
References pipe_blend_state::alpha_dst_factor, pipe_blend_state::alpha_src_factor, gen_mipmap_state::blend, pipe_rasterizer_state::bypass_clipping, CALLOC_STRUCT, pipe_blend_state::colormask, gen_mipmap_state::cso, pipe_rasterizer_state::cull_mode, gen_mipmap_state::depthstencil, gen_mipmap_state::frag_shader, pipe_rasterizer_state::front_winding, gen_mipmap_state::fs, pipe_rasterizer_state::gl_rasterization_rules, pipe_sampler_state::min_mip_filter, pipe_sampler_state::normalized_coords, gen_mipmap_state::pipe, PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_ZERO, PIPE_MASK_RGBA, PIPE_TEX_MIPFILTER_NEAREST, PIPE_TEX_WRAP_CLAMP_TO_EDGE, PIPE_WINDING_CW, PIPE_WINDING_NONE, gen_mipmap_state::rasterizer, pipe_blend_state::rgb_dst_factor, pipe_blend_state::rgb_src_factor, gen_mipmap_state::sampler, pipe_viewport_state::scale, semantic_names, TGSI_SEMANTIC_GENERIC, TGSI_SEMANTIC_POSITION, pipe_viewport_state::translate, util_make_fragment_tex_shader(), util_make_vertex_passthrough_shader(), gen_mipmap_state::vert_shader, gen_mipmap_state::vertices, gen_mipmap_state::viewport, gen_mipmap_state::vs, pipe_sampler_state::wrap_r, pipe_sampler_state::wrap_s, and pipe_sampler_state::wrap_t.
00702 { 00703 struct gen_mipmap_state *ctx; 00704 uint i; 00705 00706 ctx = CALLOC_STRUCT(gen_mipmap_state); 00707 if (!ctx) 00708 return NULL; 00709 00710 ctx->pipe = pipe; 00711 ctx->cso = cso; 00712 00713 /* disabled blending/masking */ 00714 memset(&ctx->blend, 0, sizeof(ctx->blend)); 00715 ctx->blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE; 00716 ctx->blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE; 00717 ctx->blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; 00718 ctx->blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; 00719 ctx->blend.colormask = PIPE_MASK_RGBA; 00720 00721 /* no-op depth/stencil/alpha */ 00722 memset(&ctx->depthstencil, 0, sizeof(ctx->depthstencil)); 00723 00724 /* rasterizer */ 00725 memset(&ctx->rasterizer, 0, sizeof(ctx->rasterizer)); 00726 ctx->rasterizer.front_winding = PIPE_WINDING_CW; 00727 ctx->rasterizer.cull_mode = PIPE_WINDING_NONE; 00728 ctx->rasterizer.bypass_clipping = 1; 00729 /*ctx->rasterizer.bypass_vs = 1;*/ 00730 ctx->rasterizer.gl_rasterization_rules = 1; 00731 00732 /* sampler state */ 00733 memset(&ctx->sampler, 0, sizeof(ctx->sampler)); 00734 ctx->sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 00735 ctx->sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 00736 ctx->sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 00737 ctx->sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST; 00738 ctx->sampler.normalized_coords = 1; 00739 00740 /* viewport state (identity, verts are in wincoords) */ 00741 ctx->viewport.scale[0] = 1.0; 00742 ctx->viewport.scale[1] = 1.0; 00743 ctx->viewport.scale[2] = 1.0; 00744 ctx->viewport.scale[3] = 1.0; 00745 ctx->viewport.translate[0] = 0.0; 00746 ctx->viewport.translate[1] = 0.0; 00747 ctx->viewport.translate[2] = 0.0; 00748 ctx->viewport.translate[3] = 0.0; 00749 00750 /* vertex shader */ 00751 { 00752 const uint semantic_names[] = { TGSI_SEMANTIC_POSITION, 00753 TGSI_SEMANTIC_GENERIC }; 00754 const uint semantic_indexes[] = { 0, 0 }; 00755 ctx->vs = util_make_vertex_passthrough_shader(pipe, 2, semantic_names, 00756 semantic_indexes, 00757 &ctx->vert_shader); 00758 } 00759 00760 /* fragment shader */ 00761 ctx->fs = util_make_fragment_tex_shader(pipe, &ctx->frag_shader); 00762 00763 /* vertex data that doesn't change */ 00764 for (i = 0; i < 4; i++) { 00765 ctx->vertices[i][0][2] = 0.0f; /* z */ 00766 ctx->vertices[i][0][3] = 1.0f; /* w */ 00767 ctx->vertices[i][1][2] = 0.0f; /* r */ 00768 ctx->vertices[i][1][3] = 1.0f; /* q */ 00769 } 00770 00771 /* Note: the actual vertex buffer is allocated as needed below */ 00772 00773 return ctx; 00774 }
void util_destroy_gen_mipmap | ( | struct gen_mipmap_state * | ctx | ) |
Destroy a mipmap generation context.
Definition at line 844 of file u_gen_mipmap.c.
References pipe_context::delete_fs_state, pipe_context::delete_vs_state, gen_mipmap_state::frag_shader, FREE, gen_mipmap_state::fs, gen_mipmap_state::pipe, pipe_buffer_reference(), pipe_context::screen, pipe_shader_state::tokens, gen_mipmap_state::vbuf, gen_mipmap_state::vert_shader, and gen_mipmap_state::vs.
00845 { 00846 struct pipe_context *pipe = ctx->pipe; 00847 00848 pipe->delete_vs_state(pipe, ctx->vs); 00849 pipe->delete_fs_state(pipe, ctx->fs); 00850 00851 FREE((void*) ctx->vert_shader.tokens); 00852 FREE((void*) ctx->frag_shader.tokens); 00853 00854 pipe_buffer_reference(pipe->screen, &ctx->vbuf, NULL); 00855 00856 FREE(ctx); 00857 }
void util_gen_mipmap | ( | struct gen_mipmap_state * | ctx, | |
struct pipe_texture * | pt, | |||
uint | face, | |||
uint | baseLevel, | |||
uint | lastLevel, | |||
uint | filter | |||
) |
Generate mipmap images.
It's assumed all needed texture memory is already allocated.
pt | the texture to generate mipmap levels for | |
face | which cube face to generate mipmaps for (0 for non-cube maps) | |
baseLevel | the first mipmap level to use as a src | |
lastLevel | the last mipmap level to generate | |
filter | the minification filter used to generate mipmap levels with | |
filter | one of PIPE_TEX_FILTER_LINEAR, PIPE_TEX_FILTER_NEAREST |
Definition at line 883 of file u_gen_mipmap.c.
References gen_mipmap_state::blend, pipe_framebuffer_state::cbufs, gen_mipmap_state::cso, cso_restore_blend(), cso_restore_depth_stencil_alpha(), cso_restore_fragment_shader(), cso_restore_framebuffer(), cso_restore_rasterizer(), cso_restore_sampler_textures(), cso_restore_samplers(), cso_restore_vertex_shader(), cso_restore_viewport(), cso_save_blend(), cso_save_depth_stencil_alpha(), cso_save_fragment_shader(), cso_save_framebuffer(), cso_save_rasterizer(), cso_save_sampler_textures(), cso_save_samplers(), cso_save_vertex_shader(), cso_save_viewport(), cso_set_blend(), cso_set_depth_stencil_alpha(), cso_set_fragment_shader_handle(), cso_set_framebuffer(), cso_set_rasterizer(), cso_set_sampler_textures(), cso_set_vertex_shader_handle(), cso_set_viewport(), cso_single_sampler(), cso_single_sampler_done(), gen_mipmap_state::depthstencil, fallback_gen_mipmap(), pipe_context::flush, pipe_texture::format, gen_mipmap_state::fs, pipe_screen::get_tex_surface, pipe_texture::height, pipe_framebuffer_state::height, pipe_screen::is_format_supported, pipe_sampler_state::lod_bias, pipe_sampler_state::mag_img_filter, pipe_sampler_state::max_lod, pipe_sampler_state::min_img_filter, pipe_sampler_state::min_lod, pipe_framebuffer_state::num_cbufs, offset(), gen_mipmap_state::pipe, PIPE_BUFFER_USAGE_GPU_WRITE, PIPE_FLUSH_RENDER_CACHE, PIPE_PRIM_TRIANGLE_FAN, pipe_surface_reference(), PIPE_TEXTURE_2D, PIPE_TEXTURE_USAGE_RENDER_TARGET, gen_mipmap_state::rasterizer, gen_mipmap_state::sampler, pipe_context::screen, set_vertex_data(), util_draw_vertex_buffer(), gen_mipmap_state::vbuf, gen_mipmap_state::viewport, gen_mipmap_state::vs, pipe_texture::width, and pipe_framebuffer_state::width.
00886 { 00887 struct pipe_context *pipe = ctx->pipe; 00888 struct pipe_screen *screen = pipe->screen; 00889 struct pipe_framebuffer_state fb; 00890 uint dstLevel; 00891 uint zslice = 0; 00892 uint offset; 00893 00894 /* check if we can render in the texture's format */ 00895 if (!screen->is_format_supported(screen, pt->format, PIPE_TEXTURE_2D, 00896 PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) { 00897 fallback_gen_mipmap(ctx, pt, face, baseLevel, lastLevel); 00898 return; 00899 } 00900 00901 /* save state (restored below) */ 00902 cso_save_blend(ctx->cso); 00903 cso_save_depth_stencil_alpha(ctx->cso); 00904 cso_save_rasterizer(ctx->cso); 00905 cso_save_samplers(ctx->cso); 00906 cso_save_sampler_textures(ctx->cso); 00907 cso_save_framebuffer(ctx->cso); 00908 cso_save_fragment_shader(ctx->cso); 00909 cso_save_vertex_shader(ctx->cso); 00910 cso_save_viewport(ctx->cso); 00911 00912 /* bind our state */ 00913 cso_set_blend(ctx->cso, &ctx->blend); 00914 cso_set_depth_stencil_alpha(ctx->cso, &ctx->depthstencil); 00915 cso_set_rasterizer(ctx->cso, &ctx->rasterizer); 00916 cso_set_viewport(ctx->cso, &ctx->viewport); 00917 00918 cso_set_fragment_shader_handle(ctx->cso, ctx->fs); 00919 cso_set_vertex_shader_handle(ctx->cso, ctx->vs); 00920 00921 /* init framebuffer state */ 00922 memset(&fb, 0, sizeof(fb)); 00923 fb.num_cbufs = 1; 00924 00925 /* set min/mag to same filter for faster sw speed */ 00926 ctx->sampler.mag_img_filter = filter; 00927 ctx->sampler.min_img_filter = filter; 00928 00929 /* 00930 * XXX for small mipmap levels, it may be faster to use the software 00931 * fallback path... 00932 */ 00933 for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) { 00934 const uint srcLevel = dstLevel - 1; 00935 00936 struct pipe_surface *surf = 00937 screen->get_tex_surface(screen, pt, face, dstLevel, zslice, 00938 PIPE_BUFFER_USAGE_GPU_WRITE); 00939 00940 /* 00941 * Setup framebuffer / dest surface 00942 */ 00943 fb.cbufs[0] = surf; 00944 fb.width = pt->width[dstLevel]; 00945 fb.height = pt->height[dstLevel]; 00946 cso_set_framebuffer(ctx->cso, &fb); 00947 00948 /* 00949 * Setup sampler state 00950 * Note: we should only have to set the min/max LOD clamps to ensure 00951 * we grab texels from the right mipmap level. But some hardware 00952 * has trouble with min clamping so we also set the lod_bias to 00953 * try to work around that. 00954 */ 00955 ctx->sampler.min_lod = ctx->sampler.max_lod = (float) srcLevel; 00956 ctx->sampler.lod_bias = (float) srcLevel; 00957 cso_single_sampler(ctx->cso, 0, &ctx->sampler); 00958 cso_single_sampler_done(ctx->cso); 00959 00960 cso_set_sampler_textures(ctx->cso, 1, &pt); 00961 00962 /* quad coords in window coords (bypassing clipping, viewport mapping) */ 00963 offset = set_vertex_data(ctx, 00964 (float) pt->width[dstLevel], 00965 (float) pt->height[dstLevel]); 00966 00967 util_draw_vertex_buffer(ctx->pipe, 00968 ctx->vbuf, 00969 offset, 00970 PIPE_PRIM_TRIANGLE_FAN, 00971 4, /* verts */ 00972 2); /* attribs/vert */ 00973 00974 pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); 00975 00976 /* need to signal that the texture has changed _after_ rendering to it */ 00977 pipe_surface_reference( &surf, NULL ); 00978 } 00979 00980 /* restore state we changed */ 00981 cso_restore_blend(ctx->cso); 00982 cso_restore_depth_stencil_alpha(ctx->cso); 00983 cso_restore_rasterizer(ctx->cso); 00984 cso_restore_samplers(ctx->cso); 00985 cso_restore_sampler_textures(ctx->cso); 00986 cso_restore_framebuffer(ctx->cso); 00987 cso_restore_fragment_shader(ctx->cso); 00988 cso_restore_vertex_shader(ctx->cso); 00989 cso_restore_viewport(ctx->cso); 00990 }
void util_gen_mipmap_flush | ( | struct gen_mipmap_state * | ctx | ) |
Definition at line 864 of file u_gen_mipmap.c.
References gen_mipmap_state::pipe, pipe_buffer_reference(), pipe_context::screen, gen_mipmap_state::vbuf, and gen_mipmap_state::vbuf_slot.
00865 { 00866 pipe_buffer_reference(ctx->pipe->screen, &ctx->vbuf, NULL); 00867 ctx->vbuf_slot = 0; 00868 }