diff options
author | Laura Ekstrand <laura@jlekstrand.net> | 2018-03-16 15:53:06 -0700 |
---|---|---|
committer | Laura Ekstrand <laura@jlekstrand.net> | 2018-04-18 16:29:07 -0700 |
commit | 18e16f8550cfcd37b77fdab6d1c4250f857b238d (patch) | |
tree | b381994b334d7ccfd3135735464eb43c47d5971d | |
parent | 120667db428eec39db8152a3c156a23c0268a450 (diff) |
i965: Replace blitter with blorp in glBitmap.blitter-rebase
This is a major rewrite. There's really no way to avoid this
because we don't have to chop the bitmap up into pieces anymore.
-rw-r--r-- | src/intel/blorp/blorp.h | 12 | ||||
-rw-r--r-- | src/intel/blorp/blorp_clear.c | 112 | ||||
-rw-r--r-- | src/intel/blorp/blorp_nir_builder.h | 25 | ||||
-rw-r--r-- | src/intel/blorp/blorp_priv.h | 1 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_blorp.c | 65 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_blorp.h | 10 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/intel_pixel_bitmap.c | 217 |
7 files changed, 292 insertions, 150 deletions
diff --git a/src/intel/blorp/blorp.h b/src/intel/blorp/blorp.h index 4626f2f83c..e78ae7a873 100644 --- a/src/intel/blorp/blorp.h +++ b/src/intel/blorp/blorp.h @@ -219,6 +219,18 @@ blorp_mcs_partial_resolve(struct blorp_batch *batch, uint32_t start_layer, uint32_t num_layers); void +blorp_bitmap(struct blorp_batch *batch, + const struct blorp_surf *src_surf, + unsigned src_level, unsigned src_layer, + enum isl_format src_format, + const struct blorp_surf *dst_surf, + unsigned dst_level, unsigned dst_layer, + enum isl_format dst_format, + unsigned dstx, unsigned dsty, + unsigned width, unsigned height, + union isl_color_value rasterColor); + +void blorp_hiz_op(struct blorp_batch *batch, struct blorp_surf *surf, uint32_t level, uint32_t start_layer, uint32_t num_layers, enum isl_aux_op op); diff --git a/src/intel/blorp/blorp_clear.c b/src/intel/blorp/blorp_clear.c index 832e8ee26f..6197960594 100644 --- a/src/intel/blorp/blorp_clear.c +++ b/src/intel/blorp/blorp_clear.c @@ -924,6 +924,75 @@ blorp_params_get_mcs_partial_resolve_kernel(struct blorp_context *blorp, return result; } +struct blorp_bitmap_key +{ + enum blorp_shader_type shader_type; +}; + +static bool +blorp_params_get_bitmap_kernel(struct blorp_context *blorp, + struct blorp_params *params) +{ + const struct blorp_bitmap_key blorp_key = { + .shader_type = BLORP_SHADER_TYPE_BITMAP, + }; + + if (blorp->lookup_shader(blorp, &blorp_key, sizeof(blorp_key), + ¶ms->wm_prog_kernel, ¶ms->wm_prog_data)) + return true; + + void *mem_ctx = ralloc_context(NULL); + + nir_builder b; + nir_builder_init_simple_shader(&b, mem_ctx, MESA_SHADER_FRAGMENT, NULL); + b.shader->info.name = ralloc_strdup(b.shader, "BLORP-bitmap"); + + nir_variable *r_color = + BLORP_CREATE_NIR_INPUT(b.shader, clear_color, glsl_vec4_type()); + nir_variable *v_dst_offset = + BLORP_CREATE_NIR_INPUT(b.shader, dst_offset, + glsl_vector_type(GLSL_TYPE_UINT, 2)); + + nir_variable *frag_color = + nir_variable_create(b.shader, nir_var_shader_out, + glsl_vec4_type(), "gl_FragColor"); + frag_color->data.location = FRAG_RESULT_COLOR; + + nir_ssa_def *src_pos = + nir_isub(&b, nir_f2i32(&b, blorp_nir_frag_coord(&b)), + nir_load_var(&b, v_dst_offset)); + + /* Do a fetch and check if it should be masked */ + nir_ssa_def *bitmap = blorp_nir_txf_2d(&b, src_pos); + nir_ssa_def *is_masked = + nir_ieq(&b, nir_channel(&b, bitmap, 0), nir_imm_int(&b, 0)); + + /* If we are masked, discard. */ + nir_intrinsic_instr *discard = + nir_intrinsic_instr_create(b.shader, nir_intrinsic_discard_if); + discard->src[0] = nir_src_for_ssa(is_masked); + nir_builder_instr_insert(&b, &discard->instr); + + nir_store_var(&b, frag_color, nir_load_var(&b, r_color), 0xf); + + struct brw_wm_prog_key wm_key; + brw_blorp_init_wm_prog_key(&wm_key); + + struct brw_wm_prog_data prog_data; + const unsigned *program = + blorp_compile_fs(blorp, mem_ctx, b.shader, &wm_key, false, + &prog_data); + + bool result = + blorp->upload_shader(blorp, &blorp_key, sizeof(blorp_key), + program, prog_data.base.program_size, + &prog_data.base, sizeof(prog_data), + ¶ms->wm_prog_kernel, ¶ms->wm_prog_data); + + ralloc_free(mem_ctx); + return result; +} + void blorp_mcs_partial_resolve(struct blorp_batch *batch, struct blorp_surf *surf, @@ -958,6 +1027,49 @@ blorp_mcs_partial_resolve(struct blorp_batch *batch, batch->blorp->exec(batch, ¶ms); } +/* + * Kind of like a clear, only src is a mask. + * Implements glBitmap. + */ +void +blorp_bitmap(struct blorp_batch *batch, + const struct blorp_surf *src_surf, + unsigned src_level, unsigned src_layer, + enum isl_format src_format, + const struct blorp_surf *dst_surf, + unsigned dst_level, unsigned dst_layer, + enum isl_format dst_format, + unsigned dstx, unsigned dsty, + unsigned width, unsigned height, + union isl_color_value rasterColor) { + + struct blorp_params params; + blorp_params_init(¶ms); + + params.x0 = dstx; + params.y0 = dsty; + params.x1 = dstx + width; + params.y1 = dsty + height; + + params.wm_inputs.dst_offset.x = dstx; + params.wm_inputs.dst_offset.y = dsty; + + brw_blorp_surface_info_init(batch->blorp, ¶ms.src, src_surf, src_level, + src_layer, src_format, false); + brw_blorp_surface_info_init(batch->blorp, ¶ms.dst, dst_surf, dst_level, + dst_layer, dst_format, true); + + params.num_samples = params.dst.surf.samples; + params.num_layers = 1; + memcpy(¶ms.wm_inputs.clear_color, + rasterColor.f32, sizeof(float) * 4); + + if (!blorp_params_get_bitmap_kernel(batch->blorp, ¶ms)) + return; + + batch->blorp->exec(batch, ¶ms); +} + /** Clear a CCS to the "uncompressed" state * * This pass is the CCS equivalent of a "HiZ resolve". It sets the CCS values diff --git a/src/intel/blorp/blorp_nir_builder.h b/src/intel/blorp/blorp_nir_builder.h index 7f23abdef4..61e5d594e5 100644 --- a/src/intel/blorp/blorp_nir_builder.h +++ b/src/intel/blorp/blorp_nir_builder.h @@ -100,3 +100,28 @@ blorp_nir_mcs_is_clear_color(nir_builder *b, unreachable("Invalid sample count"); } } + +static inline nir_ssa_def * +blorp_nir_txf_2d(nir_builder *b, nir_ssa_def *xy_pos) +{ + nir_tex_instr *tex = nir_tex_instr_create(b->shader, 1); + tex->op = nir_texop_txf; + tex->sampler_dim = GLSL_SAMPLER_DIM_2D; + tex->dest_type = nir_type_int; + + nir_ssa_def *coord; + tex->is_array = false; + tex->coord_components = 2; + coord = nir_channels(b, xy_pos, 0x3); + tex->src[0].src_type = nir_tex_src_coord; + tex->src[0].src = nir_src_for_ssa(coord); + + /* Blorp only has one texture and it's bound at unit 0 */ + tex->texture_index = 0; + tex->sampler_index = 0; + + nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, NULL); + nir_builder_instr_insert(b, &tex->instr); + + return &tex->dest.ssa; +} diff --git a/src/intel/blorp/blorp_priv.h b/src/intel/blorp/blorp_priv.h index 3811ec6fbc..093f8623bc 100644 --- a/src/intel/blorp/blorp_priv.h +++ b/src/intel/blorp/blorp_priv.h @@ -217,6 +217,7 @@ enum blorp_shader_type { BLORP_SHADER_TYPE_BLIT, BLORP_SHADER_TYPE_CLEAR, BLORP_SHADER_TYPE_MCS_PARTIAL_RESOLVE, + BLORP_SHADER_TYPE_BITMAP, BLORP_SHADER_TYPE_LAYER_OFFSET_VS, BLORP_SHADER_TYPE_GEN4_SF, }; diff --git a/src/mesa/drivers/dri/i965/brw_blorp.c b/src/mesa/drivers/dri/i965/brw_blorp.c index 1d586e5ef3..a6f1bfb1ca 100644 --- a/src/mesa/drivers/dri/i965/brw_blorp.c +++ b/src/mesa/drivers/dri/i965/brw_blorp.c @@ -1328,6 +1328,71 @@ brw_blorp_clear_color(struct brw_context *brw, struct gl_framebuffer *fb, } void +brw_blorp_bitmap(struct brw_context *brw, struct intel_mipmap_tree *dst_mt, + unsigned dst_level, unsigned dst_layer, + mesa_format dst_format, + unsigned dstx, unsigned dsty, unsigned width, unsigned height, + union isl_color_value rasterColor, + struct intel_mipmap_tree *src_mt, mesa_format src_format) { + + DBG("to mt %p %d %d %s (%f,%f) (%f,%f) " + "in rastercolor %f %f %f %f, bitmap mt %s %p\n", + __func__, + dst_mt, dst_level, dst_layer, _mesa_get_format_name(dst_mt->format), + dstx, dsty, width, height, + rasterColor.f32[0], rasterColor.f32[1], + rasterColor.f32[2], rasterColor.f32[3], + _mesa_get_format_name(src_mt->format), src_mt); + + enum isl_format src_isl_format = + brw_blorp_to_isl_format(brw, src_format, false); + enum isl_aux_usage src_aux_usage = + intel_miptree_texture_aux_usage(brw, src_mt, src_isl_format); + /* We do format workarounds for some depth formats so we can't reliably + * sample with HiZ. One of these days, we should fix that. + */ + if (src_aux_usage == ISL_AUX_USAGE_HIZ) + src_aux_usage = ISL_AUX_USAGE_NONE; + const bool src_clear_supported = + src_aux_usage != ISL_AUX_USAGE_NONE && src_mt->format == src_format; + intel_miptree_prepare_access(brw, src_mt, 0, 1, 0, 1, + src_aux_usage, src_clear_supported); + + enum isl_format dst_isl_format = + brw_blorp_to_isl_format(brw, dst_format, true); + enum isl_aux_usage dst_aux_usage = + intel_miptree_render_aux_usage(brw, dst_mt, dst_isl_format, + false, false); + const bool dst_clear_supported = dst_aux_usage != ISL_AUX_USAGE_NONE; + intel_miptree_prepare_access(brw, dst_mt, dst_level, 1, dst_layer, 1, + dst_aux_usage, dst_clear_supported); + + struct isl_surf tmp_surfs[2]; + struct blorp_surf src_surf, dst_surf; + unsigned src_level = 0; + unsigned src_layer = 0; + + blorp_surf_for_miptree(brw, &src_surf, src_mt, src_aux_usage, false, + &src_level, src_layer, 1, &tmp_surfs[0]); + blorp_surf_for_miptree(brw, &dst_surf, dst_mt, dst_aux_usage, true, + &dst_level, dst_layer, 1, &tmp_surfs[1]); + + struct blorp_batch batch; + blorp_batch_init(&brw->blorp, &batch, brw, 0); + blorp_bitmap(&batch, &src_surf, src_level, src_layer, + src_isl_format, + &dst_surf, dst_level, dst_layer, + dst_isl_format, + dstx, dsty, width, height, rasterColor); + blorp_batch_finish(&batch); + + intel_miptree_finish_write(brw, dst_mt, dst_level, dst_layer, 1, + dst_aux_usage); + + return; +} + +void brw_blorp_clear_depth_stencil(struct brw_context *brw, struct gl_framebuffer *fb, GLbitfield mask, bool partial_clear) diff --git a/src/mesa/drivers/dri/i965/brw_blorp.h b/src/mesa/drivers/dri/i965/brw_blorp.h index 551e1fcdcb..cea04ebfda 100644 --- a/src/mesa/drivers/dri/i965/brw_blorp.h +++ b/src/mesa/drivers/dri/i965/brw_blorp.h @@ -26,6 +26,7 @@ #include "blorp/blorp.h" #include "intel_mipmap_tree.h" +#include "isl/isl.h" #include "program/prog_instruction.h" #ifdef __cplusplus @@ -90,6 +91,15 @@ brw_blorp_download_miptree(struct brw_context *brw, void brw_blorp_clear_color(struct brw_context *brw, struct gl_framebuffer *fb, GLbitfield mask, bool partial_clear, bool encode_srgb); + +void +brw_blorp_bitmap(struct brw_context *brw, struct intel_mipmap_tree *dst_mt, + unsigned dst_level, unsigned dst_logical_layer, + mesa_format dst_format, + unsigned dstx, unsigned dsty, unsigned width, unsigned height, + union isl_color_value rasterColor, + struct intel_mipmap_tree *bitmap_mt, mesa_format src_format); + void brw_blorp_clear_depth_stencil(struct brw_context *brw, struct gl_framebuffer *fb, diff --git a/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c b/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c index eb4fcdf149..f032d14395 100644 --- a/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c +++ b/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c @@ -23,11 +23,13 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#include "isl/isl.h" #include "main/blend.h" #include "main/enums.h" #include "main/image.h" #include "main/colormac.h" #include "main/condrender.h" +#include "main/glformats.h" #include "main/mtypes.h" #include "main/macros.h" #include "main/pbo.h" @@ -39,14 +41,15 @@ #include "swrast/swrast.h" #include "drivers/common/meta.h" +#include "brw_blorp.h" #include "brw_context.h" #include "intel_screen.h" #include "intel_batchbuffer.h" -#include "intel_blit.h" #include "intel_fbo.h" #include "intel_image.h" #include "intel_buffers.h" #include "intel_pixel.h" +#include "intel_buffer_objects.h" #define FILE_DEBUG_FLAG DEBUG_PIXEL @@ -85,72 +88,6 @@ static const GLubyte *map_pbo( struct gl_context *ctx, return ADD_POINTERS(buf, bitmap); } -static bool test_bit( const GLubyte *src, GLuint bit ) -{ - return (src[bit/8] & (1<<(bit % 8))) ? 1 : 0; -} - -static void set_bit( GLubyte *dest, GLuint bit ) -{ - dest[bit/8] |= 1 << (bit % 8); -} - -/* Extract a rectangle's worth of data from the bitmap. Called - * per chunk of HW-sized bitmap. - */ -static GLuint get_bitmap_rect(GLsizei width, GLsizei height, - const struct gl_pixelstore_attrib *unpack, - const GLubyte *bitmap, - GLuint x, GLuint y, - GLuint w, GLuint h, - GLubyte *dest, - GLuint row_align, - bool invert) -{ - GLuint src_offset = (x + unpack->SkipPixels) & 0x7; - GLuint mask = unpack->LsbFirst ? 0 : 7; - GLuint bit = 0; - GLint row, col; - GLint first, last; - GLint incr; - GLuint count = 0; - - DBG("%s %d,%d %dx%d bitmap %dx%d skip %d src_offset %d mask %d\n", - __func__, x,y,w,h,width,height,unpack->SkipPixels, src_offset, mask); - - if (invert) { - first = h-1; - last = 0; - incr = -1; - } - else { - first = 0; - last = h-1; - incr = 1; - } - - /* Require that dest be pre-zero'd. - */ - for (row = first; row != (last+incr); row += incr) { - const GLubyte *rowsrc = _mesa_image_address2d(unpack, bitmap, - width, height, - GL_COLOR_INDEX, GL_BITMAP, - y + row, x); - - for (col = 0; col < w; col++, bit++) { - if (test_bit(rowsrc, (col + src_offset) ^ mask)) { - set_bit(dest, bit ^ 7); - count++; - } - } - - if (row_align) - bit = ALIGN(bit, row_align); - } - - return count; -} - /** * Returns the low Y value of the vertical range given, flipped according to * whether the framebuffer is or not. @@ -177,15 +114,7 @@ do_blit_bitmap( struct gl_context *ctx, struct brw_context *brw = brw_context(ctx); struct gl_framebuffer *fb = ctx->DrawBuffer; struct intel_renderbuffer *irb; - GLfloat rasterColor[4]; - GLubyte ubcolor[4]; - GLuint color; - GLsizei bitmap_width = width; - GLsizei bitmap_height = height; - GLint px, py; - GLuint stipple[32]; - GLint orig_dstx = dstx; - GLint orig_dsty = dsty; + union isl_color_value rasterColor; /* Update draw buffer bounds */ _mesa_update_state(ctx); @@ -214,32 +143,13 @@ do_blit_bitmap( struct gl_context *ctx, return true; /* even though this is an error, we're done */ } - COPY_4V(rasterColor, ctx->Current.RasterColor); + COPY_4V(rasterColor.f32, ctx->Current.RasterColor); if (_mesa_need_secondary_color(ctx)) { - ADD_3V(rasterColor, rasterColor, ctx->Current.RasterSecondaryColor); + ADD_3V(rasterColor.f32, rasterColor.f32, ctx->Current.RasterSecondaryColor); } - UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[0], rasterColor[0]); - UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[1], rasterColor[1]); - UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[2], rasterColor[2]); - UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[3], rasterColor[3]); - - switch (_mesa_get_render_format(ctx, intel_rb_format(irb))) { - case MESA_FORMAT_B8G8R8A8_UNORM: - case MESA_FORMAT_B8G8R8X8_UNORM: - color = PACK_COLOR_8888(ubcolor[3], ubcolor[0], ubcolor[1], ubcolor[2]); - break; - case MESA_FORMAT_B5G6R5_UNORM: - color = PACK_COLOR_565(ubcolor[0], ubcolor[1], ubcolor[2]); - break; - default: - perf_debug("Unsupported format %s in accelerated glBitmap()\n", - _mesa_get_format_name(irb->mt->format)); - return false; - } - - if (!intel_check_blit_fragment_ops(ctx, rasterColor[3] == 1.0F)) + if (!intel_check_blit_fragment_ops(ctx, rasterColor.f32[3] == 1.0F)) return false; /* Clip to buffer bounds and scissor. */ @@ -250,61 +160,68 @@ do_blit_bitmap( struct gl_context *ctx, dsty = y_flip(fb, dsty, height); -#define DY 32 -#define DX 32 + mesa_format src_format = MESA_FORMAT_R_UINT8; + mesa_format dst_format = irb->mt->format; + + /* We can safely discard sRGB encode/decode for the DrawPixels interface */ + src_format = _mesa_get_srgb_format_linear(src_format); + dst_format = _mesa_get_srgb_format_linear(dst_format); - /* The blitter has no idea about fast color clears, so we need to resolve - * the miptree before we do anything. + int src_stride = _mesa_image_row_stride(unpack, width, GL_RED, + GL_UNSIGNED_BYTE); + /* Mesa flips the src_stride for unpack->Invert, but we want our mt to have + * a normal src_stride. */ - intel_miptree_access_raw(brw, irb->mt, irb->mt_level, irb->mt_layer, true); - - /* Chop it all into chunks that can be digested by hardware: */ - for (py = 0; py < height; py += DY) { - for (px = 0; px < width; px += DX) { - int h = MIN2(DY, height - py); - int w = MIN2(DX, width - px); - GLuint sz = ALIGN(ALIGN(w,8) * h, 64)/8; - - assert(sz <= sizeof(stipple)); - memset(stipple, 0, sz); - - /* May need to adjust this when padding has been introduced in - * sz above: - * - * Have to translate destination coordinates back into source - * coordinates. - */ - int count = get_bitmap_rect(bitmap_width, bitmap_height, unpack, - bitmap, - -orig_dstx + (dstx + px), - -orig_dsty + y_flip(fb, dsty + py, h), - w, h, - (GLubyte *)stipple, - 8, - _mesa_is_winsys_fbo(fb)); - if (count == 0) - continue; - - if (!intelEmitImmediateColorExpandBlit(brw, - irb->mt->cpp, - (GLubyte *)stipple, - sz, - color, - irb->mt->surf.row_pitch, - irb->mt->bo, - irb->mt->offset, - irb->mt->surf.tiling, - dstx + px, - dsty + py, - w, h, - COLOR_LOGICOP_COPY)) { - return false; - } - - if (ctx->Query.CurrentOcclusionObject) - ctx->Query.CurrentOcclusionObject->Result += count; - } + if (unpack->Invert) { + src_stride = -src_stride; } + + + GLuint src_offset = (GLintptr) bitmap; + src_offset += _mesa_image_offset(2, unpack, width, height, + GL_RED, GL_UNSIGNED_BYTE, 0, 0, 0); + + struct intel_mipmap_tree *pbo_mt = + intel_miptree_create(brw, + GL_TEXTURE_2D, + MESA_FORMAT_R_UINT8, + 0, 0, + width, height, 1, + 1, + MIPTREE_CREATE_LINEAR); + + if (!pbo_mt) + return false; + + void *pbo_ptr; + ptrdiff_t pbo_stride; + intel_miptree_map(brw, pbo_mt, 0, 0, 0, 0, width, height, + GL_MAP_WRITE_BIT, &pbo_ptr, &pbo_stride); + + memset(pbo_ptr, 0, height * pbo_stride); + + /* + * As mentioned state_tracker/st_cb_bitmap.c, this will + * produce an upside-down bitmap (thanks to GL, as usual). + * So we have to invert it. + */ + pbo_ptr += (height - 1) * pbo_stride; + _mesa_expand_bitmap(width, height, unpack, + bitmap, pbo_ptr, -pbo_stride, 0x1); + intel_miptree_unmap(brw, pbo_mt, 0, 0); + + /* + * float color is fine, use rasterColor for raster color + * Don't worry, xmove and ymove are handled in entry point. + */ + brw_blorp_bitmap(brw, irb->mt, irb->mt_level, irb->mt_layer, + dst_format, + dstx, dsty, width, height, rasterColor, + pbo_mt, src_format); + + if (ctx->Query.CurrentOcclusionObject) + ctx->Query.CurrentOcclusionObject->Result += width * height; + out: if (unlikely(INTEL_DEBUG & DEBUG_SYNC)) |