/**************************************************************************
*
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2008 VMware, Inc.
* All Rights Reserved.
* Copyright 2008 VMware, Inc. All rights reserved.
*
* 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 NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS 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.
struct pipe_context *pipe;
struct cso_context *cso;
- struct pipe_blend_state blend;
- struct pipe_depth_stencil_alpha_state depthstencil;
+ struct pipe_blend_state blend_keep_color, blend_write_color;
+ struct pipe_depth_stencil_alpha_state dsa_keep_depth, dsa_write_depth;
struct pipe_rasterizer_state rasterizer;
struct pipe_sampler_state sampler;
- struct pipe_clip_state clip;
struct pipe_vertex_element velem[2];
void *vs;
- void *fs1d, *fs2d, *fs3d, *fsCube, *fs1da, *fs2da;
+
+ /** Not all are used, but simplifies code */
+ void *fs_color[TGSI_TEXTURE_COUNT];
+ void *fs_depth[TGSI_TEXTURE_COUNT];
struct pipe_resource *vbuf; /**< quad vertices */
unsigned vbuf_slot;
struct pipe_transfer *srcTrans, *dstTrans;
void *srcMap, *dstMap;
- srcTrans = pipe_get_transfer(pipe, pt, srcLevel, layer,
- PIPE_TRANSFER_READ, 0, 0,
- u_minify(pt->width0, srcLevel),
- u_minify(pt->height0, srcLevel));
- dstTrans = pipe_get_transfer(pipe, pt, dstLevel, layer,
- PIPE_TRANSFER_WRITE, 0, 0,
- u_minify(pt->width0, dstLevel),
- u_minify(pt->height0, dstLevel));
-
- srcMap = (ubyte *) pipe->transfer_map(pipe, srcTrans);
- dstMap = (ubyte *) pipe->transfer_map(pipe, dstTrans);
+ srcMap = pipe_transfer_map(pipe, pt, srcLevel, layer,
+ PIPE_TRANSFER_READ, 0, 0,
+ u_minify(pt->width0, srcLevel),
+ u_minify(pt->height0, srcLevel), &srcTrans);
+ dstMap = pipe_transfer_map(pipe, pt, dstLevel, layer,
+ PIPE_TRANSFER_WRITE, 0, 0,
+ u_minify(pt->width0, dstLevel),
+ u_minify(pt->height0, dstLevel), &dstTrans);
reduce_1d(pt->format,
srcTrans->box.width, srcMap,
pipe->transfer_unmap(pipe, srcTrans);
pipe->transfer_unmap(pipe, dstTrans);
-
- pipe->transfer_destroy(pipe, srcTrans);
- pipe->transfer_destroy(pipe, dstTrans);
}
}
struct pipe_transfer *srcTrans, *dstTrans;
ubyte *srcMap, *dstMap;
- srcTrans = pipe_get_transfer(pipe, pt, srcLevel, layer,
- PIPE_TRANSFER_READ, 0, 0,
- u_minify(pt->width0, srcLevel),
- u_minify(pt->height0, srcLevel));
- dstTrans = pipe_get_transfer(pipe, pt, dstLevel, layer,
- PIPE_TRANSFER_WRITE, 0, 0,
- u_minify(pt->width0, dstLevel),
- u_minify(pt->height0, dstLevel));
-
- srcMap = (ubyte *) pipe->transfer_map(pipe, srcTrans);
- dstMap = (ubyte *) pipe->transfer_map(pipe, dstTrans);
+ srcMap = pipe_transfer_map(pipe, pt, srcLevel, layer,
+ PIPE_TRANSFER_READ, 0, 0,
+ u_minify(pt->width0, srcLevel),
+ u_minify(pt->height0, srcLevel), &srcTrans);
+ dstMap = pipe_transfer_map(pipe, pt, dstLevel, layer,
+ PIPE_TRANSFER_WRITE, 0, 0,
+ u_minify(pt->width0, dstLevel),
+ u_minify(pt->height0, dstLevel), &dstTrans);
reduce_2d(pt->format,
srcTrans->box.width, srcTrans->box.height,
pipe->transfer_unmap(pipe, srcTrans);
pipe->transfer_unmap(pipe, dstTrans);
-
- pipe->transfer_destroy(pipe, srcTrans);
- pipe->transfer_destroy(pipe, dstTrans);
}
}
dst_box.height = u_minify(pt->height0, dstLevel);
dst_box.depth = u_minify(pt->depth0, dstLevel);
- srcTrans = pipe->get_transfer(pipe, pt, srcLevel,
- PIPE_TRANSFER_READ,
- &src_box);
- dstTrans = pipe->get_transfer(pipe, pt, dstLevel,
- PIPE_TRANSFER_WRITE,
- &dst_box);
-
- srcMap = (ubyte *) pipe->transfer_map(pipe, srcTrans);
- dstMap = (ubyte *) pipe->transfer_map(pipe, dstTrans);
+ srcMap = pipe->transfer_map(pipe, pt, srcLevel,
+ PIPE_TRANSFER_READ,
+ &src_box, &srcTrans);
+ dstMap = pipe->transfer_map(pipe, pt, dstLevel,
+ PIPE_TRANSFER_WRITE,
+ &dst_box, &dstTrans);
reduce_3d(pt->format,
srcTrans->box.width, srcTrans->box.height, srcTrans->box.depth,
pipe->transfer_unmap(pipe, srcTrans);
pipe->transfer_unmap(pipe, dstTrans);
-
- pipe->transfer_destroy(pipe, srcTrans);
- pipe->transfer_destroy(pipe, dstTrans);
}
}
ctx->cso = cso;
/* disabled blending/masking */
- memset(&ctx->blend, 0, sizeof(ctx->blend));
- ctx->blend.rt[0].colormask = PIPE_MASK_RGBA;
+ memset(&ctx->blend_keep_color, 0, sizeof(ctx->blend_keep_color));
+ memset(&ctx->blend_write_color, 0, sizeof(ctx->blend_write_color));
+ ctx->blend_write_color.rt[0].colormask = PIPE_MASK_RGBA;
/* no-op depth/stencil/alpha */
- memset(&ctx->depthstencil, 0, sizeof(ctx->depthstencil));
+ memset(&ctx->dsa_keep_depth, 0, sizeof(ctx->dsa_keep_depth));
+ memset(&ctx->dsa_write_depth, 0, sizeof(ctx->dsa_write_depth));
+ ctx->dsa_write_depth.depth.enabled = 1;
+ ctx->dsa_write_depth.depth.func = PIPE_FUNC_ALWAYS;
+ ctx->dsa_write_depth.depth.writemask = 1;
/* rasterizer */
memset(&ctx->rasterizer, 0, sizeof(ctx->rasterizer));
ctx->rasterizer.cull_face = PIPE_FACE_NONE;
- ctx->rasterizer.gl_rasterization_rules = 1;
+ ctx->rasterizer.half_pixel_center = 1;
+ ctx->rasterizer.bottom_edge_rule = 1;
+ ctx->rasterizer.depth_clip = 1;
/* sampler state */
memset(&ctx->sampler, 0, sizeof(ctx->sampler));
for (i = 0; i < 2; i++) {
ctx->velem[i].src_offset = i * 4 * sizeof(float);
ctx->velem[i].instance_divisor = 0;
- ctx->velem[i].vertex_buffer_index = 0;
+ ctx->velem[i].vertex_buffer_index = cso_get_aux_vertex_buffer_slot(cso);
ctx->velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
}
- /* vertex shader - still needed to specify mapping from fragment
- * shader input semantics to vertex elements
- */
- {
- const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
- TGSI_SEMANTIC_GENERIC };
- const uint semantic_indexes[] = { 0, 0 };
- ctx->vs = util_make_vertex_passthrough_shader(pipe, 2, semantic_names,
- semantic_indexes);
- }
-
- /* fragment shader */
- ctx->fs1d = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_1D,
- TGSI_INTERPOLATE_LINEAR);
- ctx->fs2d = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_2D,
- TGSI_INTERPOLATE_LINEAR);
- ctx->fs3d = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_3D,
- TGSI_INTERPOLATE_LINEAR);
- ctx->fsCube = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_CUBE,
- TGSI_INTERPOLATE_LINEAR);
- if (pipe->screen->get_param(pipe->screen, PIPE_CAP_ARRAY_TEXTURES)) {
- ctx->fs1da = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_1D_ARRAY,
- TGSI_INTERPOLATE_LINEAR);
- ctx->fs2da = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_2D_ARRAY,
- TGSI_INTERPOLATE_LINEAR);
- }
-
-
/* vertex data that doesn't change */
for (i = 0; i < 4; i++) {
ctx->vertices[i][0][2] = 0.0f; /* z */
}
+/**
+ * Helper function to set the fragment shaders.
+ */
+static INLINE void
+set_fragment_shader(struct gen_mipmap_state *ctx, uint type,
+ boolean output_depth)
+{
+ if (output_depth) {
+ if (!ctx->fs_depth[type])
+ ctx->fs_depth[type] =
+ util_make_fragment_tex_shader_writedepth(ctx->pipe, type,
+ TGSI_INTERPOLATE_LINEAR);
+
+ cso_set_fragment_shader_handle(ctx->cso, ctx->fs_depth[type]);
+ }
+ else {
+ if (!ctx->fs_color[type])
+ ctx->fs_color[type] =
+ util_make_fragment_tex_shader(ctx->pipe, type,
+ TGSI_INTERPOLATE_LINEAR);
+
+ cso_set_fragment_shader_handle(ctx->cso, ctx->fs_color[type]);
+ }
+}
+
+
+/**
+ * Helper function to set the vertex shader.
+ */
+static INLINE void
+set_vertex_shader(struct gen_mipmap_state *ctx)
+{
+ /* vertex shader - still required to provide the linkage between
+ * fragment shader input semantics and vertex_element/buffers.
+ */
+ if (!ctx->vs)
+ {
+ const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
+ TGSI_SEMANTIC_GENERIC };
+ const uint semantic_indexes[] = { 0, 0 };
+ ctx->vs = util_make_vertex_passthrough_shader(ctx->pipe, 2,
+ semantic_names,
+ semantic_indexes);
+ }
+
+ cso_set_vertex_shader_handle(ctx->cso, ctx->vs);
+}
+
+
/**
* Get next "slot" of vertex space in the vertex buffer.
* We're allocating one large vertex buffer and using it piece by piece.
{
const unsigned max_slots = 4096 / sizeof ctx->vertices;
- if (ctx->vbuf_slot >= max_slots)
- util_gen_mipmap_flush( ctx );
+ if (ctx->vbuf_slot >= max_slots) {
+ pipe_resource_reference(&ctx->vbuf, NULL);
+ ctx->vbuf_slot = 0;
+ }
if (!ctx->vbuf) {
ctx->vbuf = pipe_buffer_create(ctx->pipe->screen,
};
util_map_texcoords2d_onto_cubemap(layer, &st[0][0], 2,
- &ctx->vertices[0][1][0], 8);
+ &ctx->vertices[0][1][0], 8,
+ FALSE);
}
else if (tex_target == PIPE_TEXTURE_1D_ARRAY) {
/* 1D texture array */
util_destroy_gen_mipmap(struct gen_mipmap_state *ctx)
{
struct pipe_context *pipe = ctx->pipe;
+ unsigned i;
+
+ for (i = 0; i < Elements(ctx->fs_color); i++)
+ if (ctx->fs_color[i])
+ pipe->delete_fs_state(pipe, ctx->fs_color[i]);
- if (ctx->fs2da)
- pipe->delete_fs_state(pipe, ctx->fs2da);
- if (ctx->fs1da)
- pipe->delete_fs_state(pipe, ctx->fs1da);
- pipe->delete_fs_state(pipe, ctx->fsCube);
- pipe->delete_fs_state(pipe, ctx->fs3d);
- pipe->delete_fs_state(pipe, ctx->fs2d);
- pipe->delete_fs_state(pipe, ctx->fs1d);
- pipe->delete_vs_state(pipe, ctx->vs);
+ for (i = 0; i < Elements(ctx->fs_depth); i++)
+ if (ctx->fs_depth[i])
+ pipe->delete_fs_state(pipe, ctx->fs_depth[i]);
+
+ if (ctx->vs)
+ pipe->delete_vs_state(pipe, ctx->vs);
pipe_resource_reference(&ctx->vbuf, NULL);
}
-
-/* Release vertex buffer at end of frame to avoid synchronous
- * rendering.
- */
-void util_gen_mipmap_flush( struct gen_mipmap_state *ctx )
-{
- pipe_resource_reference(&ctx->vbuf, NULL);
- ctx->vbuf_slot = 0;
-}
-
-
/**
* Generate mipmap images. It's assumed all needed texture memory is
* already allocated.
struct pipe_screen *screen = pipe->screen;
struct pipe_framebuffer_state fb;
struct pipe_resource *pt = psv->texture;
- void *fs;
uint dstLevel;
uint offset;
+ uint type;
+ boolean is_depth = util_format_is_depth_or_stencil(psv->format);
/* The texture object should have room for the levels which we're
* about to generate.
switch (pt->target) {
case PIPE_TEXTURE_1D:
- fs = ctx->fs1d;
+ type = TGSI_TEXTURE_1D;
break;
case PIPE_TEXTURE_2D:
- fs = ctx->fs2d;
+ type = TGSI_TEXTURE_2D;
break;
case PIPE_TEXTURE_3D:
- fs = ctx->fs3d;
+ type = TGSI_TEXTURE_3D;
break;
case PIPE_TEXTURE_CUBE:
- fs = ctx->fsCube;
+ type = TGSI_TEXTURE_CUBE;
break;
case PIPE_TEXTURE_1D_ARRAY:
- fs = ctx->fs1da;
+ type = TGSI_TEXTURE_1D_ARRAY;
break;
case PIPE_TEXTURE_2D_ARRAY:
- fs = ctx->fs2da;
+ type = TGSI_TEXTURE_2D_ARRAY;
break;
default:
assert(0);
- fs = ctx->fs2d;
+ type = TGSI_TEXTURE_2D;
}
/* check if we can render in the texture's format */
if (!screen->is_format_supported(screen, psv->format, pt->target,
- pt->nr_samples, PIPE_BIND_RENDER_TARGET)) {
+ pt->nr_samples,
+ is_depth ? PIPE_BIND_DEPTH_STENCIL :
+ PIPE_BIND_RENDER_TARGET)) {
fallback_gen_mipmap(ctx, pt, face, baseLevel, lastLevel);
return;
}
cso_save_blend(ctx->cso);
cso_save_depth_stencil_alpha(ctx->cso);
cso_save_rasterizer(ctx->cso);
- cso_save_samplers(ctx->cso);
- cso_save_fragment_sampler_views(ctx->cso);
+ cso_save_sample_mask(ctx->cso);
+ cso_save_samplers(ctx->cso, PIPE_SHADER_FRAGMENT);
+ cso_save_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT);
+ cso_save_stream_outputs(ctx->cso);
cso_save_framebuffer(ctx->cso);
cso_save_fragment_shader(ctx->cso);
cso_save_vertex_shader(ctx->cso);
+ cso_save_geometry_shader(ctx->cso);
cso_save_viewport(ctx->cso);
- cso_save_clip(ctx->cso);
cso_save_vertex_elements(ctx->cso);
+ cso_save_aux_vertex_buffer_slot(ctx->cso);
+ cso_save_render_condition(ctx->cso);
/* bind our state */
- cso_set_blend(ctx->cso, &ctx->blend);
- cso_set_depth_stencil_alpha(ctx->cso, &ctx->depthstencil);
+ cso_set_blend(ctx->cso, is_depth ? &ctx->blend_keep_color :
+ &ctx->blend_write_color);
+ cso_set_depth_stencil_alpha(ctx->cso, is_depth ? &ctx->dsa_write_depth :
+ &ctx->dsa_keep_depth);
cso_set_rasterizer(ctx->cso, &ctx->rasterizer);
- cso_set_clip(ctx->cso, &ctx->clip);
+ cso_set_sample_mask(ctx->cso, ~0);
cso_set_vertex_elements(ctx->cso, 2, ctx->velem);
+ cso_set_stream_outputs(ctx->cso, 0, NULL, NULL);
+ cso_set_render_condition(ctx->cso, NULL, FALSE, 0);
- cso_set_fragment_shader_handle(ctx->cso, fs);
- cso_set_vertex_shader_handle(ctx->cso, ctx->vs);
+ set_fragment_shader(ctx, type, is_depth);
+ set_vertex_shader(ctx);
+ cso_set_geometry_shader_handle(ctx->cso, NULL);
/* init framebuffer state */
memset(&fb, 0, sizeof(fb));
- fb.nr_cbufs = 1;
/* set min/mag to same filter for faster sw speed */
ctx->sampler.mag_img_filter = filter;
ctx->sampler.min_img_filter = filter;
- /*
- * XXX for small mipmap levels, it may be faster to use the software
- * fallback path...
- */
for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) {
const uint srcLevel = dstLevel - 1;
struct pipe_viewport_state vp;
} else
layer = face;
- memset(&surf_templ, 0, sizeof(surf_templ));
- u_surface_default_template(&surf_templ, pt, PIPE_BIND_RENDER_TARGET);
+ u_surface_default_template(&surf_templ, pt);
surf_templ.u.tex.level = dstLevel;
surf_templ.u.tex.first_layer = layer;
surf_templ.u.tex.last_layer = layer;
/*
* Setup framebuffer / dest surface
*/
- fb.cbufs[0] = surf;
+ if (is_depth) {
+ fb.nr_cbufs = 0;
+ fb.zsbuf = surf;
+ }
+ else {
+ fb.nr_cbufs = 1;
+ fb.cbufs[0] = surf;
+ }
fb.width = u_minify(pt->width0, dstLevel);
fb.height = u_minify(pt->height0, dstLevel);
cso_set_framebuffer(ctx->cso, &fb);
*/
ctx->sampler.min_lod = ctx->sampler.max_lod = (float) srcLevel;
ctx->sampler.lod_bias = (float) srcLevel;
- cso_single_sampler(ctx->cso, 0, &ctx->sampler);
- cso_single_sampler_done(ctx->cso);
+ cso_single_sampler(ctx->cso, PIPE_SHADER_FRAGMENT, 0, &ctx->sampler);
+ cso_single_sampler_done(ctx->cso, PIPE_SHADER_FRAGMENT);
- cso_set_fragment_sampler_views(ctx->cso, 1, &psv);
+ cso_set_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT, 1, &psv);
/* quad coords in clip coords */
offset = set_vertex_data(ctx,
util_draw_vertex_buffer(ctx->pipe,
ctx->cso,
ctx->vbuf,
+ cso_get_aux_vertex_buffer_slot(ctx->cso),
offset,
PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */
cso_restore_blend(ctx->cso);
cso_restore_depth_stencil_alpha(ctx->cso);
cso_restore_rasterizer(ctx->cso);
- cso_restore_samplers(ctx->cso);
- cso_restore_fragment_sampler_views(ctx->cso);
+ cso_restore_sample_mask(ctx->cso);
+ cso_restore_samplers(ctx->cso, PIPE_SHADER_FRAGMENT);
+ cso_restore_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT);
cso_restore_framebuffer(ctx->cso);
cso_restore_fragment_shader(ctx->cso);
cso_restore_vertex_shader(ctx->cso);
+ cso_restore_geometry_shader(ctx->cso);
cso_restore_viewport(ctx->cso);
- cso_restore_clip(ctx->cso);
cso_restore_vertex_elements(ctx->cso);
+ cso_restore_stream_outputs(ctx->cso);
+ cso_restore_aux_vertex_buffer_slot(ctx->cso);
+ cso_restore_render_condition(ctx->cso);
}