diff options
author | Bruce Cherniak <[email protected]> | 2017-04-13 17:40:11 -0500 |
---|---|---|
committer | Tim Rowley <[email protected]> | 2017-04-14 15:22:45 -0500 |
commit | 1832ef6cd9bdce4f546128c0b77d7acd6fd898a7 (patch) | |
tree | 81da3c4beeb3d64a846b4986a37f785e83d6d6b3 /src/gallium/drivers/swr/swr_state.cpp | |
parent | 91a7f0b3afaa88e787d7b80df491928e037967a4 (diff) |
swr: Enable MSAA in OpenSWR software renderer
This patch enables multisample antialiasing in the OpenSWR software renderer.
MSAA is a proof-of-concept/work-in-progress with bug fixes and performance
on the way. We wanted to get the changes out now to allow several customers
to begin experimenting with MSAA in a software renderer. So as not to
impact current customers, MSAA is turned off by default - previous
functionality and performance remain intact. It is easily enabled via
environment variables, as described below.
It has only been tested with the glx-lib winsys. The intention is to
enable other state-trackers, both Windows and Linux and more fully support
FBOs.
There are 2 environment variables that affect behavior:
* SWR_MSAA_FORCE_ENABLE - force MSAA on, for apps that are not designed
for MSAA... Beware, results will vary. This is mainly for testing.
* SWR_MSAA_MAX_SAMPLE_COUNT - sets maximum supported number of
samples (1,2,4,8,16), or 0 to disable MSAA altogether.
(The default is currently 0.)
Reviewed-by: George Kyriazis <[email protected]>
Diffstat (limited to 'src/gallium/drivers/swr/swr_state.cpp')
-rw-r--r-- | src/gallium/drivers/swr/swr_state.cpp | 74 |
1 files changed, 65 insertions, 9 deletions
diff --git a/src/gallium/drivers/swr/swr_state.cpp b/src/gallium/drivers/swr/swr_state.cpp index 5cc01ddcab0..aa9fe099f0a 100644 --- a/src/gallium/drivers/swr/swr_state.cpp +++ b/src/gallium/drivers/swr/swr_state.cpp @@ -30,6 +30,7 @@ #include "common/os.h" #include "jit_api.h" #include "gen_state_llvm.h" +#include "core/multisample.h" #include "gallivm/lp_bld_tgsi.h" #include "util/u_format.h" @@ -668,6 +669,9 @@ swr_set_framebuffer_state(struct pipe_context *pipe, if (changed) { util_copy_framebuffer_state(&ctx->framebuffer, fb); + /* 0 and 1 both indicate no msaa. Core doesn't understand 0 samples */ + ctx->framebuffer.samples = std::max((ubyte)1, ctx->framebuffer.samples); + ctx->dirty |= SWR_NEW_FRAMEBUFFER; } } @@ -685,6 +689,36 @@ swr_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask) } /* + * MSAA fixed sample position table + * used by update_derived and get_sample_position + * (integer locations on a 16x16 grid) + */ +static const uint8_t swr_sample_positions[][2] = +{ /* 1x*/ { 8, 8}, + /* 2x*/ {12,12},{ 4, 4}, + /* 4x*/ { 6, 2},{14, 6},{ 2,10},{10,14}, + /* 8x*/ { 9, 5},{ 7,11},{13, 9},{ 5, 3}, + { 3,13},{ 1, 7},{11,15},{15, 1}, + /*16x*/ { 9, 9},{ 7, 5},{ 5,10},{12, 7}, + { 3, 6},{10,13},{13,11},{11, 3}, + { 6,14},{ 8, 1},{ 4, 2},{ 2,12}, + { 0, 8},{15, 4},{14,15},{ 1, 0} }; + +static void +swr_get_sample_position(struct pipe_context *pipe, + unsigned sample_count, unsigned sample_index, + float *out_value) +{ + /* validate sample_count */ + sample_count = GetNumSamples(GetSampleCount(sample_count)); + + const uint8_t *sample = swr_sample_positions[sample_count-1 + sample_index]; + out_value[0] = sample[0] / 16.0f; + out_value[1] = sample[1] / 16.0f; +} + + +/* * Update resource in-use status * All resources bound to color or depth targets marked as WRITE resources. * VBO Vertex/index buffers and texture views marked as READ resources. @@ -1060,9 +1094,30 @@ swr_update_derived(struct pipe_context *pipe, rastState->pointSpriteTopOrigin = rasterizer->sprite_coord_mode == PIPE_SPRITE_COORD_UPPER_LEFT; - /* XXX TODO: Add multisample */ - rastState->sampleCount = SWR_MULTISAMPLE_1X; + /* If SWR_MSAA_FORCE_ENABLE is set, turn msaa on */ + if (screen->msaa_force_enable && !rasterizer->multisample) { + /* Force enable and use the value the surface was created with */ + rasterizer->multisample = true; + fb->samples = swr_resource(fb->cbufs[0]->texture)->swr.numSamples; + fprintf(stderr,"msaa force enable: %d samples\n", fb->samples); + } + + rastState->sampleCount = GetSampleCount(fb->samples); rastState->forcedSampleCount = false; + rastState->bIsCenterPattern = !rasterizer->multisample; + rastState->pixelLocation = SWR_PIXEL_LOCATION_CENTER; + + /* Only initialize sample positions if msaa is enabled */ + if (rasterizer->multisample) { + for (uint32_t i = 0; i < fb->samples; i++) { + const uint8_t *sample = swr_sample_positions[fb->samples-1 + i]; + rastState->samplePositions.SetXi(i, sample[0] << 4); + rastState->samplePositions.SetYi(i, sample[1] << 4); + rastState->samplePositions.SetX (i, sample[0] / 16.0f); + rastState->samplePositions.SetY (i, sample[1] / 16.0f); + } + rastState->samplePositions.PrecalcSampleData(fb->samples); + } bool do_offset = false; switch (rasterizer->fill_front) { @@ -1375,9 +1430,9 @@ swr_update_derived(struct pipe_context *pipe, psState.inputCoverage = SWR_INPUT_COVERAGE_NORMAL; psState.writesODepth = ctx->fs->info.base.writes_z; psState.usesSourceDepth = ctx->fs->info.base.reads_z; - psState.shadingRate = SWR_SHADING_RATE_PIXEL; // XXX + psState.shadingRate = SWR_SHADING_RATE_PIXEL; psState.numRenderTargets = ctx->framebuffer.nr_cbufs; - psState.posOffset = SWR_PS_POSITION_SAMPLE_NONE; // XXX msaa + psState.posOffset = SWR_PS_POSITION_SAMPLE_NONE; uint32_t barycentricsMask = 0; #if 0 // when we switch to mesa-master @@ -1507,6 +1562,7 @@ swr_update_derived(struct pipe_context *pipe, /* Blend State */ if (ctx->dirty & (SWR_NEW_BLEND | + SWR_NEW_RASTERIZER | SWR_NEW_FRAMEBUFFER | SWR_NEW_DEPTH_STENCIL_ALPHA)) { struct pipe_framebuffer_state *fb = &ctx->framebuffer; @@ -1520,9 +1576,8 @@ swr_update_derived(struct pipe_context *pipe, blendState.alphaTestReference = *((uint32_t*)&ctx->depth_stencil->alpha.ref_value); - // XXX MSAA - blendState.sampleMask = 0; - blendState.sampleCount = SWR_MULTISAMPLE_1X; + blendState.sampleMask = ctx->sample_mask; + blendState.sampleCount = GetSampleCount(fb->samples); /* If there are no color buffers bound, disable writes on RT0 * and skip loop */ @@ -1578,8 +1633,8 @@ swr_update_derived(struct pipe_context *pipe, compileState.blendState.alphaBlendFunc); compileState.desc.alphaToCoverageEnable = ctx->blend->pipe.alpha_to_coverage; - compileState.desc.sampleMaskEnable = 0; // XXX - compileState.desc.numSamples = 1; // XXX + compileState.desc.sampleMaskEnable = (blendState.sampleMask != 0); + compileState.desc.numSamples = fb->samples; compileState.alphaTestFunction = swr_convert_depth_func(ctx->depth_stencil->alpha.func); @@ -1781,6 +1836,7 @@ swr_state_init(struct pipe_context *pipe) pipe->set_stencil_ref = swr_set_stencil_ref; pipe->set_sample_mask = swr_set_sample_mask; + pipe->get_sample_position = swr_get_sample_position; pipe->create_stream_output_target = swr_create_so_target; pipe->stream_output_target_destroy = swr_destroy_so_target; |