summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/swr/swr_state.cpp
diff options
context:
space:
mode:
authorBruce Cherniak <[email protected]>2017-04-13 17:40:11 -0500
committerTim Rowley <[email protected]>2017-04-14 15:22:45 -0500
commit1832ef6cd9bdce4f546128c0b77d7acd6fd898a7 (patch)
tree81da3c4beeb3d64a846b4986a37f785e83d6d6b3 /src/gallium/drivers/swr/swr_state.cpp
parent91a7f0b3afaa88e787d7b80df491928e037967a4 (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.cpp74
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;