X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fswr%2Fswr_context.cpp;h=aa5cca8e653e2c36df95f4ccde28d513661df9ab;hb=d4c14867373862e47ed7286ac08d0301e95d707f;hp=6f46d666ac59909f1bb790e9c8599b545b8363bb;hpb=97bbb7b6a3afadc22ef956f507f70998629fe99a;p=mesa.git diff --git a/src/gallium/drivers/swr/swr_context.cpp b/src/gallium/drivers/swr/swr_context.cpp index 6f46d666ac5..aa5cca8e653 100644 --- a/src/gallium/drivers/swr/swr_context.cpp +++ b/src/gallium/drivers/swr/swr_context.cpp @@ -267,20 +267,104 @@ swr_resource_copy(struct pipe_context *pipe, } +/* XXX: This resolve is incomplete and suboptimal. It will be removed once the + * pipelined resolve blit works. */ +void +swr_do_msaa_resolve(struct pipe_resource *src_resource, + struct pipe_resource *dst_resource) +{ + /* This is a pretty dumb inline resolve. It only supports 8-bit formats + * (ex RGBA8/BGRA8) - which are most common display formats anyway. + */ + + /* quick check for 8-bit and number of components */ + uint8_t bits_per_component = + util_format_get_component_bits(src_resource->format, + UTIL_FORMAT_COLORSPACE_RGB, 0); + + /* Unsupported resolve format */ + assert(src_resource->format == dst_resource->format); + assert(bits_per_component == 8); + if ((src_resource->format != dst_resource->format) || + (bits_per_component != 8)) { + return; + } + + uint8_t src_num_comps = util_format_get_nr_components(src_resource->format); + + SWR_SURFACE_STATE *src_surface = &swr_resource(src_resource)->swr; + SWR_SURFACE_STATE *dst_surface = &swr_resource(dst_resource)->swr; + + uint32_t *src, *dst, offset; + uint32_t num_samples = src_surface->numSamples; + float recip_num_samples = 1.0f / num_samples; + for (uint32_t y = 0; y < src_surface->height; y++) { + for (uint32_t x = 0; x < src_surface->width; x++) { + float r = 0.0f; + float g = 0.0f; + float b = 0.0f; + float a = 0.0f; + for (uint32_t sampleNum = 0; sampleNum < num_samples; sampleNum++) { + offset = ComputeSurfaceOffset(x, y, 0, 0, sampleNum, 0, src_surface); + src = (uint32_t *) src_surface->pBaseAddress + offset/src_num_comps; + const uint32_t sample = *src; + r += (float)((sample >> 24) & 0xff) / 255.0f * recip_num_samples; + g += (float)((sample >> 16) & 0xff) / 255.0f * recip_num_samples; + b += (float)((sample >> 8) & 0xff) / 255.0f * recip_num_samples; + a += (float)((sample ) & 0xff) / 255.0f * recip_num_samples; + } + uint32_t result = 0; + result = ((uint8_t)(r * 255.0f) & 0xff) << 24; + result |= ((uint8_t)(g * 255.0f) & 0xff) << 16; + result |= ((uint8_t)(b * 255.0f) & 0xff) << 8; + result |= ((uint8_t)(a * 255.0f) & 0xff); + offset = ComputeSurfaceOffset(x, y, 0, 0, 0, 0, src_surface); + dst = (uint32_t *) dst_surface->pBaseAddress + offset/src_num_comps; + *dst = result; + } + } +} + + static void swr_blit(struct pipe_context *pipe, const struct pipe_blit_info *blit_info) { struct swr_context *ctx = swr_context(pipe); + /* Make a copy of the const blit_info, so we can modify it */ struct pipe_blit_info info = *blit_info; - if (blit_info->render_condition_enable && !swr_check_render_cond(pipe)) + if (info.render_condition_enable && !swr_check_render_cond(pipe)) return; if (info.src.resource->nr_samples > 1 && info.dst.resource->nr_samples <= 1 && !util_format_is_depth_or_stencil(info.src.resource->format) && !util_format_is_pure_integer(info.src.resource->format)) { - debug_printf("swr: color resolve unimplemented\n"); - return; + debug_printf("swr_blit: color resolve : %d -> %d\n", + info.src.resource->nr_samples, info.dst.resource->nr_samples); + + /* Because the resolve is being done inline (not pipelined), + * resources need to be stored out of hottiles and the pipeline empty. + * + * Resources are marked unused following fence finish because all + * pipeline operations are complete. Validation of the blit will mark + * them are read/write again. + */ + swr_store_dirty_resource(pipe, info.src.resource, SWR_TILE_RESOLVED); + swr_store_dirty_resource(pipe, info.dst.resource, SWR_TILE_RESOLVED); + swr_fence_finish(pipe->screen, NULL, swr_screen(pipe->screen)->flush_fence, 0); + swr_resource_unused(info.src.resource); + swr_resource_unused(info.dst.resource); + + struct pipe_resource *src_resource = info.src.resource; + struct pipe_resource *resolve_target = + swr_resource(src_resource)->resolve_target; + + /* Inline resolve samples into resolve target resource, then continue + * the blit. */ + swr_do_msaa_resolve(src_resource, resolve_target); + + /* The resolve target becomes the new source for the blit. */ + info.src.resource = resolve_target; } if (util_try_blit_via_copy_region(pipe, &info)) {