brw_blorp_blit.cpp revision 19e9b24626c2b9d7abef054d57bb2a52106c545b
1506d70be21cd3469118de89297cba0c0f709c1aePaul Berry/* 2506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * Copyright © 2012 Intel Corporation 3506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * 4506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * Permission is hereby granted, free of charge, to any person obtaining a 5506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * copy of this software and associated documentation files (the "Software"), 6506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * to deal in the Software without restriction, including without limitation 7506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * and/or sell copies of the Software, and to permit persons to whom the 9506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * Software is furnished to do so, subject to the following conditions: 10506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * 11506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * The above copyright notice and this permission notice (including the next 12506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * paragraph) shall be included in all copies or substantial portions of the 13506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * Software. 14506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * 15506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * IN THE SOFTWARE. 22506d70be21cd3469118de89297cba0c0f709c1aePaul Berry */ 23506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 24506d70be21cd3469118de89297cba0c0f709c1aePaul Berry#include "main/teximage.h" 25506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 26506d70be21cd3469118de89297cba0c0f709c1aePaul Berry#include "glsl/ralloc.h" 27506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 28506d70be21cd3469118de89297cba0c0f709c1aePaul Berry#include "intel_fbo.h" 29506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 30506d70be21cd3469118de89297cba0c0f709c1aePaul Berry#include "brw_blorp.h" 31506d70be21cd3469118de89297cba0c0f709c1aePaul Berry#include "brw_context.h" 32506d70be21cd3469118de89297cba0c0f709c1aePaul Berry#include "brw_eu.h" 33506d70be21cd3469118de89297cba0c0f709c1aePaul Berry#include "brw_state.h" 34506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 35506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 36506d70be21cd3469118de89297cba0c0f709c1aePaul Berry/** 37506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * Helper function for handling mirror image blits. 38506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * 39506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * If coord0 > coord1, swap them and invert the "mirror" boolean. 40506d70be21cd3469118de89297cba0c0f709c1aePaul Berry */ 41506d70be21cd3469118de89297cba0c0f709c1aePaul Berrystatic inline void 42506d70be21cd3469118de89297cba0c0f709c1aePaul Berryfixup_mirroring(bool &mirror, GLint &coord0, GLint &coord1) 43506d70be21cd3469118de89297cba0c0f709c1aePaul Berry{ 44506d70be21cd3469118de89297cba0c0f709c1aePaul Berry if (coord0 > coord1) { 45506d70be21cd3469118de89297cba0c0f709c1aePaul Berry mirror = !mirror; 46506d70be21cd3469118de89297cba0c0f709c1aePaul Berry GLint tmp = coord0; 47506d70be21cd3469118de89297cba0c0f709c1aePaul Berry coord0 = coord1; 48506d70be21cd3469118de89297cba0c0f709c1aePaul Berry coord1 = tmp; 49506d70be21cd3469118de89297cba0c0f709c1aePaul Berry } 50506d70be21cd3469118de89297cba0c0f709c1aePaul Berry} 51506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 52506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 53506d70be21cd3469118de89297cba0c0f709c1aePaul Berrystatic bool 54506d70be21cd3469118de89297cba0c0f709c1aePaul Berrytry_blorp_blit(struct intel_context *intel, 55506d70be21cd3469118de89297cba0c0f709c1aePaul Berry GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 56506d70be21cd3469118de89297cba0c0f709c1aePaul Berry GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 57506d70be21cd3469118de89297cba0c0f709c1aePaul Berry GLenum filter, GLbitfield buffer_bit) 58506d70be21cd3469118de89297cba0c0f709c1aePaul Berry{ 59506d70be21cd3469118de89297cba0c0f709c1aePaul Berry struct gl_context *ctx = &intel->ctx; 60506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 61506d70be21cd3469118de89297cba0c0f709c1aePaul Berry /* Sync up the state of window system buffers. We need to do this before 62506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * we go looking for the buffers. 63506d70be21cd3469118de89297cba0c0f709c1aePaul Berry */ 64506d70be21cd3469118de89297cba0c0f709c1aePaul Berry intel_prepare_render(intel); 65506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 66506d70be21cd3469118de89297cba0c0f709c1aePaul Berry /* Find buffers */ 67506d70be21cd3469118de89297cba0c0f709c1aePaul Berry const struct gl_framebuffer *read_fb = ctx->ReadBuffer; 68506d70be21cd3469118de89297cba0c0f709c1aePaul Berry const struct gl_framebuffer *draw_fb = ctx->DrawBuffer; 69506d70be21cd3469118de89297cba0c0f709c1aePaul Berry struct gl_renderbuffer *src_rb; 70506d70be21cd3469118de89297cba0c0f709c1aePaul Berry struct gl_renderbuffer *dst_rb; 71506d70be21cd3469118de89297cba0c0f709c1aePaul Berry switch (buffer_bit) { 72506d70be21cd3469118de89297cba0c0f709c1aePaul Berry case GL_COLOR_BUFFER_BIT: 73506d70be21cd3469118de89297cba0c0f709c1aePaul Berry src_rb = read_fb->_ColorReadBuffer; 74506d70be21cd3469118de89297cba0c0f709c1aePaul Berry dst_rb = 75506d70be21cd3469118de89297cba0c0f709c1aePaul Berry draw_fb->Attachment[ 76506d70be21cd3469118de89297cba0c0f709c1aePaul Berry draw_fb->_ColorDrawBufferIndexes[0]].Renderbuffer; 77506d70be21cd3469118de89297cba0c0f709c1aePaul Berry break; 78506d70be21cd3469118de89297cba0c0f709c1aePaul Berry case GL_DEPTH_BUFFER_BIT: 79506d70be21cd3469118de89297cba0c0f709c1aePaul Berry src_rb = read_fb->Attachment[BUFFER_DEPTH].Renderbuffer; 80506d70be21cd3469118de89297cba0c0f709c1aePaul Berry dst_rb = draw_fb->Attachment[BUFFER_DEPTH].Renderbuffer; 81506d70be21cd3469118de89297cba0c0f709c1aePaul Berry break; 82506d70be21cd3469118de89297cba0c0f709c1aePaul Berry case GL_STENCIL_BUFFER_BIT: 83506d70be21cd3469118de89297cba0c0f709c1aePaul Berry src_rb = read_fb->Attachment[BUFFER_STENCIL].Renderbuffer; 84506d70be21cd3469118de89297cba0c0f709c1aePaul Berry dst_rb = draw_fb->Attachment[BUFFER_STENCIL].Renderbuffer; 85506d70be21cd3469118de89297cba0c0f709c1aePaul Berry break; 86506d70be21cd3469118de89297cba0c0f709c1aePaul Berry default: 87506d70be21cd3469118de89297cba0c0f709c1aePaul Berry assert(false); 88506d70be21cd3469118de89297cba0c0f709c1aePaul Berry } 89506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 90506d70be21cd3469118de89297cba0c0f709c1aePaul Berry /* Validate source */ 91506d70be21cd3469118de89297cba0c0f709c1aePaul Berry if (!src_rb) return false; 92506d70be21cd3469118de89297cba0c0f709c1aePaul Berry struct intel_renderbuffer *src_irb = intel_renderbuffer(src_rb); 93506d70be21cd3469118de89297cba0c0f709c1aePaul Berry struct intel_mipmap_tree *src_mt = src_irb->mt; 94506d70be21cd3469118de89297cba0c0f709c1aePaul Berry if (!src_mt) return false; 95506d70be21cd3469118de89297cba0c0f709c1aePaul Berry if (buffer_bit == GL_STENCIL_BUFFER_BIT && src_mt->stencil_mt) 96506d70be21cd3469118de89297cba0c0f709c1aePaul Berry src_mt = src_mt->stencil_mt; 97506d70be21cd3469118de89297cba0c0f709c1aePaul Berry switch (src_mt->format) { 98506d70be21cd3469118de89297cba0c0f709c1aePaul Berry case MESA_FORMAT_ARGB8888: 99506d70be21cd3469118de89297cba0c0f709c1aePaul Berry case MESA_FORMAT_X8_Z24: 100506d70be21cd3469118de89297cba0c0f709c1aePaul Berry case MESA_FORMAT_S8: 101506d70be21cd3469118de89297cba0c0f709c1aePaul Berry break; /* Supported */ 102506d70be21cd3469118de89297cba0c0f709c1aePaul Berry default: 103506d70be21cd3469118de89297cba0c0f709c1aePaul Berry /* Unsupported format. 104506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * 105506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * TODO: need to support all formats that are allowed as multisample 106506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * render targets. 107506d70be21cd3469118de89297cba0c0f709c1aePaul Berry */ 108506d70be21cd3469118de89297cba0c0f709c1aePaul Berry return false; 109506d70be21cd3469118de89297cba0c0f709c1aePaul Berry } 110506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 111506d70be21cd3469118de89297cba0c0f709c1aePaul Berry /* Validate destination */ 112506d70be21cd3469118de89297cba0c0f709c1aePaul Berry if (!dst_rb) return false; 113506d70be21cd3469118de89297cba0c0f709c1aePaul Berry struct intel_renderbuffer *dst_irb = intel_renderbuffer(dst_rb); 114506d70be21cd3469118de89297cba0c0f709c1aePaul Berry struct intel_mipmap_tree *dst_mt = dst_irb->mt; 115506d70be21cd3469118de89297cba0c0f709c1aePaul Berry if (!dst_mt) return false; 116506d70be21cd3469118de89297cba0c0f709c1aePaul Berry if (buffer_bit == GL_STENCIL_BUFFER_BIT && dst_mt->stencil_mt) 117506d70be21cd3469118de89297cba0c0f709c1aePaul Berry dst_mt = dst_mt->stencil_mt; 118506d70be21cd3469118de89297cba0c0f709c1aePaul Berry switch (dst_mt->format) { 119506d70be21cd3469118de89297cba0c0f709c1aePaul Berry case MESA_FORMAT_ARGB8888: 120506d70be21cd3469118de89297cba0c0f709c1aePaul Berry case MESA_FORMAT_X8_Z24: 121506d70be21cd3469118de89297cba0c0f709c1aePaul Berry case MESA_FORMAT_S8: 122506d70be21cd3469118de89297cba0c0f709c1aePaul Berry break; /* Supported */ 123506d70be21cd3469118de89297cba0c0f709c1aePaul Berry default: 124506d70be21cd3469118de89297cba0c0f709c1aePaul Berry /* Unsupported format. 125506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * 126506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * TODO: need to support all formats that are allowed as multisample 127506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * render targets. 128506d70be21cd3469118de89297cba0c0f709c1aePaul Berry */ 129506d70be21cd3469118de89297cba0c0f709c1aePaul Berry return false; 130506d70be21cd3469118de89297cba0c0f709c1aePaul Berry } 131506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 132506d70be21cd3469118de89297cba0c0f709c1aePaul Berry /* Account for the fact that in the system framebuffer, the origin is at 133506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * the lower left. 134506d70be21cd3469118de89297cba0c0f709c1aePaul Berry */ 135506d70be21cd3469118de89297cba0c0f709c1aePaul Berry if (read_fb->Name == 0) { 136506d70be21cd3469118de89297cba0c0f709c1aePaul Berry srcY0 = read_fb->Height - srcY0; 137506d70be21cd3469118de89297cba0c0f709c1aePaul Berry srcY1 = read_fb->Height - srcY1; 138506d70be21cd3469118de89297cba0c0f709c1aePaul Berry } 139506d70be21cd3469118de89297cba0c0f709c1aePaul Berry if (draw_fb->Name == 0) { 140506d70be21cd3469118de89297cba0c0f709c1aePaul Berry dstY0 = draw_fb->Height - dstY0; 141506d70be21cd3469118de89297cba0c0f709c1aePaul Berry dstY1 = draw_fb->Height - dstY1; 142506d70be21cd3469118de89297cba0c0f709c1aePaul Berry } 143506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 144506d70be21cd3469118de89297cba0c0f709c1aePaul Berry /* Detect if the blit needs to be mirrored */ 145506d70be21cd3469118de89297cba0c0f709c1aePaul Berry bool mirror_x = false, mirror_y = false; 146506d70be21cd3469118de89297cba0c0f709c1aePaul Berry fixup_mirroring(mirror_x, srcX0, srcX1); 147506d70be21cd3469118de89297cba0c0f709c1aePaul Berry fixup_mirroring(mirror_x, dstX0, dstX1); 148506d70be21cd3469118de89297cba0c0f709c1aePaul Berry fixup_mirroring(mirror_y, srcY0, srcY1); 149506d70be21cd3469118de89297cba0c0f709c1aePaul Berry fixup_mirroring(mirror_y, dstY0, dstY1); 150506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 151506d70be21cd3469118de89297cba0c0f709c1aePaul Berry /* Make sure width and height match */ 152506d70be21cd3469118de89297cba0c0f709c1aePaul Berry GLsizei width = srcX1 - srcX0; 153506d70be21cd3469118de89297cba0c0f709c1aePaul Berry GLsizei height = srcY1 - srcY0; 154506d70be21cd3469118de89297cba0c0f709c1aePaul Berry if (width != dstX1 - dstX0) return false; 155506d70be21cd3469118de89297cba0c0f709c1aePaul Berry if (height != dstY1 - dstY0) return false; 156506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 157506d70be21cd3469118de89297cba0c0f709c1aePaul Berry /* Make sure width and height don't need to be clipped or scissored. 158506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * TODO: support clipping and scissoring. 159506d70be21cd3469118de89297cba0c0f709c1aePaul Berry */ 160506d70be21cd3469118de89297cba0c0f709c1aePaul Berry if (srcX0 < 0 || (GLuint) srcX1 > read_fb->Width) return false; 161506d70be21cd3469118de89297cba0c0f709c1aePaul Berry if (srcY0 < 0 || (GLuint) srcY1 > read_fb->Height) return false; 162506d70be21cd3469118de89297cba0c0f709c1aePaul Berry if (dstX0 < 0 || (GLuint) dstX1 > draw_fb->Width) return false; 163506d70be21cd3469118de89297cba0c0f709c1aePaul Berry if (dstY0 < 0 || (GLuint) dstY1 > draw_fb->Height) return false; 164506d70be21cd3469118de89297cba0c0f709c1aePaul Berry if (ctx->Scissor.Enabled) return false; 165506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 166506d70be21cd3469118de89297cba0c0f709c1aePaul Berry /* Get ready to blit. This includes depth resolving the src and dst 167506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * buffers if necessary. 168506d70be21cd3469118de89297cba0c0f709c1aePaul Berry */ 169506d70be21cd3469118de89297cba0c0f709c1aePaul Berry intel_renderbuffer_resolve_depth(intel, src_irb); 170506d70be21cd3469118de89297cba0c0f709c1aePaul Berry intel_renderbuffer_resolve_depth(intel, dst_irb); 171506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 172506d70be21cd3469118de89297cba0c0f709c1aePaul Berry /* Do the blit */ 173506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_blorp_blit_params params(src_mt, dst_mt, 174506d70be21cd3469118de89297cba0c0f709c1aePaul Berry srcX0, srcY0, dstX0, dstY0, dstX1, dstY1, 175506d70be21cd3469118de89297cba0c0f709c1aePaul Berry mirror_x, mirror_y); 176506d70be21cd3469118de89297cba0c0f709c1aePaul Berry params.exec(intel); 177506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 178506d70be21cd3469118de89297cba0c0f709c1aePaul Berry /* Mark the dst buffer as needing a HiZ resolve if necessary. */ 179506d70be21cd3469118de89297cba0c0f709c1aePaul Berry intel_renderbuffer_set_needs_hiz_resolve(dst_irb); 180506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 181506d70be21cd3469118de89297cba0c0f709c1aePaul Berry return true; 182506d70be21cd3469118de89297cba0c0f709c1aePaul Berry} 183506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 184506d70be21cd3469118de89297cba0c0f709c1aePaul BerryGLbitfield 185506d70be21cd3469118de89297cba0c0f709c1aePaul Berrybrw_blorp_framebuffer(struct intel_context *intel, 186506d70be21cd3469118de89297cba0c0f709c1aePaul Berry GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 187506d70be21cd3469118de89297cba0c0f709c1aePaul Berry GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 188506d70be21cd3469118de89297cba0c0f709c1aePaul Berry GLbitfield mask, GLenum filter) 189506d70be21cd3469118de89297cba0c0f709c1aePaul Berry{ 190506d70be21cd3469118de89297cba0c0f709c1aePaul Berry /* BLORP is only supported on Gen6. TODO: implement on Gen7. */ 191506d70be21cd3469118de89297cba0c0f709c1aePaul Berry if (intel->gen != 6) 192506d70be21cd3469118de89297cba0c0f709c1aePaul Berry return mask; 193506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 194506d70be21cd3469118de89297cba0c0f709c1aePaul Berry static GLbitfield buffer_bits[] = { 195506d70be21cd3469118de89297cba0c0f709c1aePaul Berry GL_COLOR_BUFFER_BIT, 196506d70be21cd3469118de89297cba0c0f709c1aePaul Berry GL_DEPTH_BUFFER_BIT, 197506d70be21cd3469118de89297cba0c0f709c1aePaul Berry GL_STENCIL_BUFFER_BIT, 198506d70be21cd3469118de89297cba0c0f709c1aePaul Berry }; 199506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 200506d70be21cd3469118de89297cba0c0f709c1aePaul Berry for (unsigned int i = 0; i < ARRAY_SIZE(buffer_bits); ++i) { 201506d70be21cd3469118de89297cba0c0f709c1aePaul Berry if ((mask & buffer_bits[i]) && 202506d70be21cd3469118de89297cba0c0f709c1aePaul Berry try_blorp_blit(intel, 203506d70be21cd3469118de89297cba0c0f709c1aePaul Berry srcX0, srcY0, srcX1, srcY1, 204506d70be21cd3469118de89297cba0c0f709c1aePaul Berry dstX0, dstY0, dstX1, dstY1, 205506d70be21cd3469118de89297cba0c0f709c1aePaul Berry filter, buffer_bits[i])) { 206506d70be21cd3469118de89297cba0c0f709c1aePaul Berry mask &= ~buffer_bits[i]; 207506d70be21cd3469118de89297cba0c0f709c1aePaul Berry } 208506d70be21cd3469118de89297cba0c0f709c1aePaul Berry } 209506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 210506d70be21cd3469118de89297cba0c0f709c1aePaul Berry return mask; 211506d70be21cd3469118de89297cba0c0f709c1aePaul Berry} 212506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 213506d70be21cd3469118de89297cba0c0f709c1aePaul Berry/** 214506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * Generator for WM programs used in BLORP blits. 215506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * 216506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * The bulk of the work done by the WM program is to wrap and unwrap the 217506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * coordinate transformations used by the hardware to store surfaces in 21819e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * memory. The hardware transforms a pixel location (X, Y, S) (where S is the 21919e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * sample index for a multisampled surface) to a memory offset by the 22019e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * following formulas: 221506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * 22219e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * offset = tile(tiling_format, encode_msaa(num_samples, X, Y, S)) 22319e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * (X, Y, S) = decode_msaa(num_samples, detile(tiling_format, offset)) 22419e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * 22519e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * For a single-sampled surface, encode_msaa() and decode_msaa are the 22619e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * identity function: 22719e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * 22819e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * encode_msaa(1, X, Y, 0) = (X, Y) 22919e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * decode_msaa(1, X, Y) = (X, Y, 0) 23019e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * 23119e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * For a 4x multisampled surface, encode_msaa() embeds the sample number into 23219e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * bit 1 of the X and Y coordinates: 23319e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * 23419e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * encode_msaa(4, X, Y, S) = (X', Y') 23519e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * where X' = (X & ~0b1) << 1 | (S & 0b1) << 1 | (X & 0b1) 23619e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * Y' = (Y & ~0b1 ) << 1 | (S & 0b10) | (Y & 0b1) 23719e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * decode_msaa(4, X, Y) = (X', Y', S) 23819e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * where X' = (X & ~0b11) >> 1 | (X & 0b1) 23919e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * Y' = (Y & ~0b11) >> 1 | (Y & 0b1) 24019e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * S = (Y & 0b10) | (X & 0b10) >> 1 241506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * 242506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * For X tiling, tile() combines together the low-order bits of the X and Y 243506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * coordinates in the pattern 0byyyxxxxxxxxx, creating 4k tiles that are 512 244506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * bytes wide and 8 rows high: 245506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * 246506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * tile(x_tiled, X, Y) = A 247506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * where A = tile_num << 12 | offset 248506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * tile_num = (Y >> 3) * tile_pitch + (X' >> 9) 249506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * offset = (Y & 0b111) << 9 250506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * | (X & 0b111111111) 251506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * X' = X * cpp 252506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * detile(x_tiled, A) = (X, Y) 253506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * where X = X' / cpp 254506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * Y = (tile_num / tile_pitch) << 3 255506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * | (A & 0b111000000000) >> 9 256506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * X' = (tile_num % tile_pitch) << 9 257506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * | (A & 0b111111111) 258506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * 259506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * (In all tiling formulas, cpp is the number of bytes occupied by a single 26019e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * sample ("chars per pixel"), and tile_pitch is the number of 4k tiles 261506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * required to fill the width of the surface). 262506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * 263506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * For Y tiling, tile() combines together the low-order bits of the X and Y 264506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * coordinates in the pattern 0bxxxyyyyyxxxx, creating 4k tiles that are 128 265506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * bytes wide and 32 rows high: 266506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * 267506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * tile(y_tiled, X, Y) = A 268506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * where A = tile_num << 12 | offset 269506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * tile_num = (Y >> 5) * tile_pitch + (X' >> 7) 270506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * offset = (X' & 0b1110000) << 5 271506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * | (Y' & 0b11111) << 4 272506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * | (X' & 0b1111) 273506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * X' = X * cpp 274506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * detile(y_tiled, A) = (X, Y) 275506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * where X = X' / cpp 276506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * Y = (tile_num / tile_pitch) << 5 277506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * | (A & 0b111110000) >> 4 278506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * X' = (tile_num % tile_pitch) << 7 279506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * | (A & 0b111000000000) >> 5 280506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * | (A & 0b1111) 281506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * 282506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * For W tiling, tile() combines together the low-order bits of the X and Y 283506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * coordinates in the pattern 0bxxxyyyyxyxyx, creating 4k tiles that are 64 284506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * bytes wide and 64 rows high (note that W tiling is only used for stencil 285506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * buffers, which always have cpp = 1): 286506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * 287506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * tile(w_tiled, X, Y) = A 288506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * where A = tile_num << 12 | offset 289506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * tile_num = (Y >> 6) * tile_pitch + (X' >> 6) 290506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * offset = (X' & 0b111000) << 6 291506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * | (Y & 0b111100) << 3 292506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * | (X' & 0b100) << 2 293506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * | (Y & 0b10) << 2 294506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * | (X' & 0b10) << 1 295506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * | (Y & 0b1) << 1 296506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * | (X' & 0b1) 297506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * X' = X * cpp = X 298506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * detile(w_tiled, A) = (X, Y) 299506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * where X = X' / cpp = X' 300506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * Y = (tile_num / tile_pitch) << 6 301506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * | (A & 0b111100000) >> 3 302506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * | (A & 0b1000) >> 2 303506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * | (A & 0b10) >> 1 304506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * X' = (tile_num % tile_pitch) << 6 305506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * | (A & 0b111000000000) >> 6 306506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * | (A & 0b10000) >> 2 307506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * | (A & 0b100) >> 1 308506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * | (A & 0b1) 309506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * 310506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * Finally, for a non-tiled surface, tile() simply combines together the X and 311506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * Y coordinates in the natural way: 312506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * 313506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * tile(untiled, X, Y) = A 314506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * where A = Y * pitch + X' 315506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * X' = X * cpp 316506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * detile(untiled, A) = (X, Y) 317506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * where X = X' / cpp 318506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * Y = A / pitch 319506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * X' = A % pitch 320506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * 321506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * (In these formulas, pitch is the number of bytes occupied by a single row 32219e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * of samples). 323506d70be21cd3469118de89297cba0c0f709c1aePaul Berry */ 324506d70be21cd3469118de89297cba0c0f709c1aePaul Berryclass brw_blorp_blit_program 325506d70be21cd3469118de89297cba0c0f709c1aePaul Berry{ 326506d70be21cd3469118de89297cba0c0f709c1aePaul Berrypublic: 327506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_blorp_blit_program(struct brw_context *brw, 328506d70be21cd3469118de89297cba0c0f709c1aePaul Berry const brw_blorp_blit_prog_key *key); 329506d70be21cd3469118de89297cba0c0f709c1aePaul Berry ~brw_blorp_blit_program(); 330506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 331506d70be21cd3469118de89297cba0c0f709c1aePaul Berry const GLuint *compile(struct brw_context *brw, GLuint *program_size); 332506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 333506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_blorp_prog_data prog_data; 334506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 335506d70be21cd3469118de89297cba0c0f709c1aePaul Berryprivate: 336506d70be21cd3469118de89297cba0c0f709c1aePaul Berry void alloc_regs(); 337506d70be21cd3469118de89297cba0c0f709c1aePaul Berry void alloc_push_const_regs(int base_reg); 338506d70be21cd3469118de89297cba0c0f709c1aePaul Berry void compute_frag_coords(); 339506d70be21cd3469118de89297cba0c0f709c1aePaul Berry void translate_tiling(bool old_tiled_w, bool new_tiled_w); 34019e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry void encode_msaa(unsigned num_samples); 34119e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry void decode_msaa(unsigned num_samples); 342506d70be21cd3469118de89297cba0c0f709c1aePaul Berry void kill_if_outside_dst_rect(); 343506d70be21cd3469118de89297cba0c0f709c1aePaul Berry void translate_dst_to_src(); 34419e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry void single_to_blend(); 34519e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry void sample(); 346506d70be21cd3469118de89297cba0c0f709c1aePaul Berry void texel_fetch(); 347506d70be21cd3469118de89297cba0c0f709c1aePaul Berry void texture_lookup(GLuint msg_type, 348506d70be21cd3469118de89297cba0c0f709c1aePaul Berry struct brw_reg mrf_u, struct brw_reg mrf_v); 349506d70be21cd3469118de89297cba0c0f709c1aePaul Berry void render_target_write(); 350506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 351506d70be21cd3469118de89297cba0c0f709c1aePaul Berry void *mem_ctx; 352506d70be21cd3469118de89297cba0c0f709c1aePaul Berry struct brw_context *brw; 353506d70be21cd3469118de89297cba0c0f709c1aePaul Berry const brw_blorp_blit_prog_key *key; 354506d70be21cd3469118de89297cba0c0f709c1aePaul Berry struct brw_compile func; 355506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 356506d70be21cd3469118de89297cba0c0f709c1aePaul Berry /* Thread dispatch header */ 357506d70be21cd3469118de89297cba0c0f709c1aePaul Berry struct brw_reg R0; 358506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 359506d70be21cd3469118de89297cba0c0f709c1aePaul Berry /* Pixel X/Y coordinates (always in R1). */ 360506d70be21cd3469118de89297cba0c0f709c1aePaul Berry struct brw_reg R1; 361506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 362506d70be21cd3469118de89297cba0c0f709c1aePaul Berry /* Push constants */ 363506d70be21cd3469118de89297cba0c0f709c1aePaul Berry struct brw_reg dst_x0; 364506d70be21cd3469118de89297cba0c0f709c1aePaul Berry struct brw_reg dst_x1; 365506d70be21cd3469118de89297cba0c0f709c1aePaul Berry struct brw_reg dst_y0; 366506d70be21cd3469118de89297cba0c0f709c1aePaul Berry struct brw_reg dst_y1; 367506d70be21cd3469118de89297cba0c0f709c1aePaul Berry struct { 368506d70be21cd3469118de89297cba0c0f709c1aePaul Berry struct brw_reg multiplier; 369506d70be21cd3469118de89297cba0c0f709c1aePaul Berry struct brw_reg offset; 370506d70be21cd3469118de89297cba0c0f709c1aePaul Berry } x_transform, y_transform; 371506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 372506d70be21cd3469118de89297cba0c0f709c1aePaul Berry /* Data returned from texture lookup (4 vec16's) */ 373506d70be21cd3469118de89297cba0c0f709c1aePaul Berry struct brw_reg Rdata; 374506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 375506d70be21cd3469118de89297cba0c0f709c1aePaul Berry /* X coordinates. We have two of them so that we can perform coordinate 376506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * transformations easily. 377506d70be21cd3469118de89297cba0c0f709c1aePaul Berry */ 378506d70be21cd3469118de89297cba0c0f709c1aePaul Berry struct brw_reg x_coords[2]; 379506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 380506d70be21cd3469118de89297cba0c0f709c1aePaul Berry /* Y coordinates. We have two of them so that we can perform coordinate 381506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * transformations easily. 382506d70be21cd3469118de89297cba0c0f709c1aePaul Berry */ 383506d70be21cd3469118de89297cba0c0f709c1aePaul Berry struct brw_reg y_coords[2]; 384506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 385506d70be21cd3469118de89297cba0c0f709c1aePaul Berry /* Which element of x_coords and y_coords is currently in use. 386506d70be21cd3469118de89297cba0c0f709c1aePaul Berry */ 387506d70be21cd3469118de89297cba0c0f709c1aePaul Berry int xy_coord_index; 388506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 38919e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry /* True if, at the point in the program currently being compiled, the 39019e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * sample index is known to be zero. 39119e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry */ 39219e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry bool s_is_zero; 39319e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry 39419e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry /* Register storing the sample index when s_is_zero is false. */ 39519e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry struct brw_reg sample_index; 39619e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry 397506d70be21cd3469118de89297cba0c0f709c1aePaul Berry /* Temporaries */ 398506d70be21cd3469118de89297cba0c0f709c1aePaul Berry struct brw_reg t1; 399506d70be21cd3469118de89297cba0c0f709c1aePaul Berry struct brw_reg t2; 400506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 401506d70be21cd3469118de89297cba0c0f709c1aePaul Berry /* M2-3: u coordinate */ 402506d70be21cd3469118de89297cba0c0f709c1aePaul Berry GLuint base_mrf; 403506d70be21cd3469118de89297cba0c0f709c1aePaul Berry struct brw_reg mrf_u_float; 404506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 405506d70be21cd3469118de89297cba0c0f709c1aePaul Berry /* M4-5: v coordinate */ 406506d70be21cd3469118de89297cba0c0f709c1aePaul Berry struct brw_reg mrf_v_float; 407506d70be21cd3469118de89297cba0c0f709c1aePaul Berry}; 408506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 409506d70be21cd3469118de89297cba0c0f709c1aePaul Berrybrw_blorp_blit_program::brw_blorp_blit_program( 410506d70be21cd3469118de89297cba0c0f709c1aePaul Berry struct brw_context *brw, 411506d70be21cd3469118de89297cba0c0f709c1aePaul Berry const brw_blorp_blit_prog_key *key) 412506d70be21cd3469118de89297cba0c0f709c1aePaul Berry : mem_ctx(ralloc_context(NULL)), 413506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw(brw), 414506d70be21cd3469118de89297cba0c0f709c1aePaul Berry key(key) 415506d70be21cd3469118de89297cba0c0f709c1aePaul Berry{ 416506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_init_compile(brw, &func, mem_ctx); 417506d70be21cd3469118de89297cba0c0f709c1aePaul Berry} 418506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 419506d70be21cd3469118de89297cba0c0f709c1aePaul Berrybrw_blorp_blit_program::~brw_blorp_blit_program() 420506d70be21cd3469118de89297cba0c0f709c1aePaul Berry{ 421506d70be21cd3469118de89297cba0c0f709c1aePaul Berry ralloc_free(mem_ctx); 422506d70be21cd3469118de89297cba0c0f709c1aePaul Berry} 423506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 424506d70be21cd3469118de89297cba0c0f709c1aePaul Berryconst GLuint * 425506d70be21cd3469118de89297cba0c0f709c1aePaul Berrybrw_blorp_blit_program::compile(struct brw_context *brw, 426506d70be21cd3469118de89297cba0c0f709c1aePaul Berry GLuint *program_size) 427506d70be21cd3469118de89297cba0c0f709c1aePaul Berry{ 42819e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry /* Sanity checks */ 42919e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry if (key->src_tiled_w) { 43019e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry /* If the source image is W tiled, then tex_samples must be 0. 43119e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * Otherwise, after conversion between W and Y tiling, there's no 43219e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * guarantee that the sample index will be 0. 43319e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry */ 43419e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry assert(key->tex_samples == 0); 43519e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry } 43619e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry 43719e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry if (key->dst_tiled_w) { 43819e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry /* If the destination image is W tiled, then dst_samples must be 0. 43919e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * Otherwise, after conversion between W and Y tiling, there's no 44019e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * guarantee that all samples corresponding to a single pixel will still 44119e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * be together. 44219e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry */ 44319e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry assert(key->rt_samples == 0); 44419e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry } 44519e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry 44619e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry if (key->blend) { 44719e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry /* We are blending, which means we'll be using a SAMPLE message, which 44819e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * causes the hardware to pick up the all of the samples corresponding 44919e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * to this pixel and average them together. Since we'll be relying on 45019e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * the hardware to find all of the samples and combine them together, 45119e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * the surface state for the texture must be configured with the correct 45219e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * tiling and sample count. 45319e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry */ 45419e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry assert(!key->src_tiled_w); 45519e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry assert(key->tex_samples == key->src_samples); 45619e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry assert(key->tex_samples > 0); 45719e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry } 45819e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry 459506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_set_compression_control(&func, BRW_COMPRESSION_NONE); 460506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 461506d70be21cd3469118de89297cba0c0f709c1aePaul Berry alloc_regs(); 462506d70be21cd3469118de89297cba0c0f709c1aePaul Berry compute_frag_coords(); 463506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 464506d70be21cd3469118de89297cba0c0f709c1aePaul Berry /* Render target and texture hardware don't support W tiling. */ 465506d70be21cd3469118de89297cba0c0f709c1aePaul Berry const bool rt_tiled_w = false; 466506d70be21cd3469118de89297cba0c0f709c1aePaul Berry const bool tex_tiled_w = false; 467506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 468506d70be21cd3469118de89297cba0c0f709c1aePaul Berry /* The address that data will be written to is determined by the 46919e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * coordinates supplied to the WM thread and the tiling and sample count of 47019e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * the render target, according to the formula: 471506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * 47219e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * (X, Y, S) = decode_msaa(rt_samples, detile(rt_tiling, offset)) 473506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * 47419e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * If the actual tiling and sample count of the destination surface are not 47519e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * the same as the configuration of the render target, then these 47619e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * coordinates are wrong and we have to adjust them to compensate for the 47719e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * difference. 478506d70be21cd3469118de89297cba0c0f709c1aePaul Berry */ 47919e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry if (rt_tiled_w != key->dst_tiled_w || 48019e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry key->rt_samples != key->dst_samples) { 48119e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry encode_msaa(key->rt_samples); 48219e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry /* Now (X, Y) = detile(rt_tiling, offset) */ 483506d70be21cd3469118de89297cba0c0f709c1aePaul Berry translate_tiling(rt_tiled_w, key->dst_tiled_w); 48419e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry /* Now (X, Y) = detile(dst_tiling, offset) */ 48519e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry decode_msaa(key->dst_samples); 48619e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry } 487506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 48819e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry /* Now (X, Y, S) = decode_msaa(dst_samples, detile(dst_tiling, offset)). 489506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * 49019e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * That is: X, Y and S now contain the true coordinates and sample index of 49119e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * the data that the WM thread should output. 492506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * 493506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * If we need to kill pixels that are outside the destination rectangle, 494506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * now is the time to do it. 495506d70be21cd3469118de89297cba0c0f709c1aePaul Berry */ 496506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 497506d70be21cd3469118de89297cba0c0f709c1aePaul Berry if (key->use_kill) 498506d70be21cd3469118de89297cba0c0f709c1aePaul Berry kill_if_outside_dst_rect(); 499506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 500506d70be21cd3469118de89297cba0c0f709c1aePaul Berry /* Next, apply a translation to obtain coordinates in the source image. */ 501506d70be21cd3469118de89297cba0c0f709c1aePaul Berry translate_dst_to_src(); 502506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 50319e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry /* If the source image is not multisampled, then we want to fetch sample 50419e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * number 0, because that's the only sample there is. 505506d70be21cd3469118de89297cba0c0f709c1aePaul Berry */ 50619e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry if (key->src_samples == 0) 50719e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry s_is_zero = true; 508506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 50919e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry /* X, Y, and S are now the coordinates of the pixel in the source image 51019e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * that we want to texture from. Exception: if we are blending, then S is 51119e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * irrelevant, because we are going to fetch all samples. 512506d70be21cd3469118de89297cba0c0f709c1aePaul Berry */ 51319e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry if (key->blend) { 51419e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry single_to_blend(); 51519e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry sample(); 51619e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry } else { 51719e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry /* We aren't blending, which means we just want to fetch a single sample 51819e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * from the source surface. The address that we want to fetch from is 51919e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * related to the X, Y and S values according to the formula: 52019e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * 52119e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * (X, Y, S) = decode_msaa(src_samples, detile(src_tiling, offset)). 52219e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * 52319e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * If the actual tiling and sample count of the source surface are not 52419e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * the same as the configuration of the texture, then we need to adjust 52519e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * the coordinates to compensate for the difference. 52619e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry */ 52719e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry if (tex_tiled_w != key->src_tiled_w || 52819e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry key->tex_samples != key->src_samples) { 52919e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry encode_msaa(key->src_samples); 53019e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry /* Now (X, Y) = detile(src_tiling, offset) */ 53119e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry translate_tiling(key->src_tiled_w, tex_tiled_w); 53219e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry /* Now (X, Y) = detile(tex_tiling, offset) */ 53319e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry decode_msaa(key->tex_samples); 53419e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry } 535506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 53619e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry /* Now (X, Y, S) = decode_msaa(tex_samples, detile(tex_tiling, offset)). 53719e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * 53819e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * In other words: X, Y, and S now contain values which, when passed to 53919e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * the texturing unit, will cause data to be read from the correct 54019e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * memory location. So we can fetch the texel now. 54119e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry */ 54219e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry texel_fetch(); 54319e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry } 54419e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry 54519e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry /* Finally, write the fetched (or blended) value to the render target and 54619e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * terminate the thread. 547506d70be21cd3469118de89297cba0c0f709c1aePaul Berry */ 548506d70be21cd3469118de89297cba0c0f709c1aePaul Berry render_target_write(); 549506d70be21cd3469118de89297cba0c0f709c1aePaul Berry return brw_get_program(&func, program_size); 550506d70be21cd3469118de89297cba0c0f709c1aePaul Berry} 551506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 552506d70be21cd3469118de89297cba0c0f709c1aePaul Berryvoid 553506d70be21cd3469118de89297cba0c0f709c1aePaul Berrybrw_blorp_blit_program::alloc_push_const_regs(int base_reg) 554506d70be21cd3469118de89297cba0c0f709c1aePaul Berry{ 555506d70be21cd3469118de89297cba0c0f709c1aePaul Berry#define CONST_LOC(name) offsetof(brw_blorp_wm_push_constants, name) 556506d70be21cd3469118de89297cba0c0f709c1aePaul Berry#define ALLOC_REG(name) \ 557506d70be21cd3469118de89297cba0c0f709c1aePaul Berry this->name = \ 558506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_uw1_reg(BRW_GENERAL_REGISTER_FILE, base_reg, CONST_LOC(name) / 2) 559506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 560506d70be21cd3469118de89297cba0c0f709c1aePaul Berry ALLOC_REG(dst_x0); 561506d70be21cd3469118de89297cba0c0f709c1aePaul Berry ALLOC_REG(dst_x1); 562506d70be21cd3469118de89297cba0c0f709c1aePaul Berry ALLOC_REG(dst_y0); 563506d70be21cd3469118de89297cba0c0f709c1aePaul Berry ALLOC_REG(dst_y1); 564506d70be21cd3469118de89297cba0c0f709c1aePaul Berry ALLOC_REG(x_transform.multiplier); 565506d70be21cd3469118de89297cba0c0f709c1aePaul Berry ALLOC_REG(x_transform.offset); 566506d70be21cd3469118de89297cba0c0f709c1aePaul Berry ALLOC_REG(y_transform.multiplier); 567506d70be21cd3469118de89297cba0c0f709c1aePaul Berry ALLOC_REG(y_transform.offset); 568506d70be21cd3469118de89297cba0c0f709c1aePaul Berry#undef CONST_LOC 569506d70be21cd3469118de89297cba0c0f709c1aePaul Berry#undef ALLOC_REG 570506d70be21cd3469118de89297cba0c0f709c1aePaul Berry} 571506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 572506d70be21cd3469118de89297cba0c0f709c1aePaul Berryvoid 573506d70be21cd3469118de89297cba0c0f709c1aePaul Berrybrw_blorp_blit_program::alloc_regs() 574506d70be21cd3469118de89297cba0c0f709c1aePaul Berry{ 575506d70be21cd3469118de89297cba0c0f709c1aePaul Berry int reg = 0; 576506d70be21cd3469118de89297cba0c0f709c1aePaul Berry this->R0 = retype(brw_vec8_grf(reg++, 0), BRW_REGISTER_TYPE_UW); 577506d70be21cd3469118de89297cba0c0f709c1aePaul Berry this->R1 = retype(brw_vec8_grf(reg++, 0), BRW_REGISTER_TYPE_UW); 578506d70be21cd3469118de89297cba0c0f709c1aePaul Berry prog_data.first_curbe_grf = reg; 579506d70be21cd3469118de89297cba0c0f709c1aePaul Berry alloc_push_const_regs(reg); 580506d70be21cd3469118de89297cba0c0f709c1aePaul Berry reg += BRW_BLORP_NUM_PUSH_CONST_REGS; 581506d70be21cd3469118de89297cba0c0f709c1aePaul Berry this->Rdata = vec16(brw_vec8_grf(reg, 0)); reg += 8; 582506d70be21cd3469118de89297cba0c0f709c1aePaul Berry for (int i = 0; i < 2; ++i) { 583506d70be21cd3469118de89297cba0c0f709c1aePaul Berry this->x_coords[i] 584506d70be21cd3469118de89297cba0c0f709c1aePaul Berry = vec16(retype(brw_vec8_grf(reg++, 0), BRW_REGISTER_TYPE_UW)); 585506d70be21cd3469118de89297cba0c0f709c1aePaul Berry this->y_coords[i] 586506d70be21cd3469118de89297cba0c0f709c1aePaul Berry = vec16(retype(brw_vec8_grf(reg++, 0), BRW_REGISTER_TYPE_UW)); 587506d70be21cd3469118de89297cba0c0f709c1aePaul Berry } 588506d70be21cd3469118de89297cba0c0f709c1aePaul Berry this->xy_coord_index = 0; 58919e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry this->sample_index 59019e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry = vec16(retype(brw_vec8_grf(reg++, 0), BRW_REGISTER_TYPE_UW)); 591506d70be21cd3469118de89297cba0c0f709c1aePaul Berry this->t1 = vec16(retype(brw_vec8_grf(reg++, 0), BRW_REGISTER_TYPE_UW)); 592506d70be21cd3469118de89297cba0c0f709c1aePaul Berry this->t2 = vec16(retype(brw_vec8_grf(reg++, 0), BRW_REGISTER_TYPE_UW)); 593506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 594506d70be21cd3469118de89297cba0c0f709c1aePaul Berry int mrf = 2; 595506d70be21cd3469118de89297cba0c0f709c1aePaul Berry this->base_mrf = mrf; 596506d70be21cd3469118de89297cba0c0f709c1aePaul Berry this->mrf_u_float = vec16(brw_message_reg(mrf)); mrf += 2; 597506d70be21cd3469118de89297cba0c0f709c1aePaul Berry this->mrf_v_float = vec16(brw_message_reg(mrf)); mrf += 2; 598506d70be21cd3469118de89297cba0c0f709c1aePaul Berry} 599506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 600506d70be21cd3469118de89297cba0c0f709c1aePaul Berry/* In the code that follows, X and Y can be used to quickly refer to the 601506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * active elements of x_coords and y_coords, and Xp and Yp ("X prime" and "Y 602506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * prime") to the inactive elements. 60319e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * 60419e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * S can be used to quickly refer to sample_index. 605506d70be21cd3469118de89297cba0c0f709c1aePaul Berry */ 606506d70be21cd3469118de89297cba0c0f709c1aePaul Berry#define X x_coords[xy_coord_index] 607506d70be21cd3469118de89297cba0c0f709c1aePaul Berry#define Y y_coords[xy_coord_index] 608506d70be21cd3469118de89297cba0c0f709c1aePaul Berry#define Xp x_coords[!xy_coord_index] 609506d70be21cd3469118de89297cba0c0f709c1aePaul Berry#define Yp y_coords[!xy_coord_index] 61019e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry#define S sample_index 611506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 612506d70be21cd3469118de89297cba0c0f709c1aePaul Berry/* Quickly swap the roles of (X, Y) and (Xp, Yp). Saves us from having to do 613506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * MOVs to transfor (Xp, Yp) to (X, Y) after a coordinate transformation. 614506d70be21cd3469118de89297cba0c0f709c1aePaul Berry */ 615506d70be21cd3469118de89297cba0c0f709c1aePaul Berry#define SWAP_XY_AND_XPYP() xy_coord_index = !xy_coord_index; 616506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 617506d70be21cd3469118de89297cba0c0f709c1aePaul Berry/** 618506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * Emit code to compute the X and Y coordinates of the pixels being rendered 619506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * by this WM invocation. 620506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * 621506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * Assuming the render target is set up for Y tiling, these (X, Y) values are 622506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * related to the address offset where outputs will be written by the formula: 623506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * 624506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * (X, Y, S) = decode_msaa(detile(offset)). 625506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * 626506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * (See brw_blorp_blit_program). 627506d70be21cd3469118de89297cba0c0f709c1aePaul Berry */ 628506d70be21cd3469118de89297cba0c0f709c1aePaul Berryvoid 629506d70be21cd3469118de89297cba0c0f709c1aePaul Berrybrw_blorp_blit_program::compute_frag_coords() 630506d70be21cd3469118de89297cba0c0f709c1aePaul Berry{ 631506d70be21cd3469118de89297cba0c0f709c1aePaul Berry /* R1.2[15:0] = X coordinate of upper left pixel of subspan 0 (pixel 0) 632506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * R1.3[15:0] = X coordinate of upper left pixel of subspan 1 (pixel 4) 633506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * R1.4[15:0] = X coordinate of upper left pixel of subspan 2 (pixel 8) 634506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * R1.5[15:0] = X coordinate of upper left pixel of subspan 3 (pixel 12) 635506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * 636506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * Pixels within a subspan are laid out in this arrangement: 637506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * 0 1 638506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * 2 3 639506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * 640506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * So, to compute the coordinates of each pixel, we need to read every 2nd 641506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * 16-bit value (vstride=2) from R1, starting at the 4th 16-bit value 642506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * (suboffset=4), and duplicate each value 4 times (hstride=0, width=4). 643506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * In other words, the data we want to access is R1.4<2;4,0>UW. 644506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * 645506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * Then, we need to add the repeating sequence (0, 1, 0, 1, ...) to the 646506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * result, since pixels n+1 and n+3 are in the right half of the subspan. 647506d70be21cd3469118de89297cba0c0f709c1aePaul Berry */ 648506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_ADD(&func, X, stride(suboffset(R1, 4), 2, 4, 0), brw_imm_v(0x10101010)); 649506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 650506d70be21cd3469118de89297cba0c0f709c1aePaul Berry /* Similarly, Y coordinates for subspans come from R1.2[31:16] through 651506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * R1.5[31:16], so to get pixel Y coordinates we need to start at the 5th 652506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * 16-bit value instead of the 4th (R1.5<2;4,0>UW instead of 653506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * R1.4<2;4,0>UW). 654506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * 655506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * And we need to add the repeating sequence (0, 0, 1, 1, ...), since 656506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * pixels n+2 and n+3 are in the bottom half of the subspan. 657506d70be21cd3469118de89297cba0c0f709c1aePaul Berry */ 658506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_ADD(&func, Y, stride(suboffset(R1, 5), 2, 4, 0), brw_imm_v(0x11001100)); 65919e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry 66019e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry /* Since we always run the WM in a mode that causes a single fragment 66119e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * dispatch per pixel, it's not meaningful to compute a sample value. Just 66219e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * set it to 0. 66319e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry */ 66419e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry s_is_zero = true; 665506d70be21cd3469118de89297cba0c0f709c1aePaul Berry} 666506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 667506d70be21cd3469118de89297cba0c0f709c1aePaul Berry/** 668506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * Emit code to compensate for the difference between Y and W tiling. 669506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * 670506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * This code modifies the X and Y coordinates according to the formula: 671506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * 672506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * (X', Y') = detile(new_tiling, tile(old_tiling, X, Y)) 673506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * 674506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * (See brw_blorp_blit_program). 675506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * 676506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * It can only translate between W and Y tiling, so new_tiling and old_tiling 677506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * are booleans where true represents W tiling and false represents Y tiling. 678506d70be21cd3469118de89297cba0c0f709c1aePaul Berry */ 679506d70be21cd3469118de89297cba0c0f709c1aePaul Berryvoid 680506d70be21cd3469118de89297cba0c0f709c1aePaul Berrybrw_blorp_blit_program::translate_tiling(bool old_tiled_w, bool new_tiled_w) 681506d70be21cd3469118de89297cba0c0f709c1aePaul Berry{ 682506d70be21cd3469118de89297cba0c0f709c1aePaul Berry if (old_tiled_w == new_tiled_w) 683506d70be21cd3469118de89297cba0c0f709c1aePaul Berry return; 684506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 685506d70be21cd3469118de89297cba0c0f709c1aePaul Berry if (new_tiled_w) { 686506d70be21cd3469118de89297cba0c0f709c1aePaul Berry /* Given X and Y coordinates that describe an address using Y tiling, 687506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * translate to the X and Y coordinates that describe the same address 688506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * using W tiling. 689506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * 690506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * If we break down the low order bits of X and Y, using a 691506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * single letter to represent each low-order bit: 692506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * 693506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * X = A << 7 | 0bBCDEFGH 694506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * Y = J << 5 | 0bKLMNP (1) 695506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * 696506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * Then we can apply the Y tiling formula to see the memory offset being 697506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * addressed: 698506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * 699506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * offset = (J * tile_pitch + A) << 12 | 0bBCDKLMNPEFGH (2) 700506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * 701506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * If we apply the W detiling formula to this memory location, that the 702506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * corresponding X' and Y' coordinates are: 703506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * 704506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * X' = A << 6 | 0bBCDPFH (3) 705506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * Y' = J << 6 | 0bKLMNEG 706506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * 707506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * Combining (1) and (3), we see that to transform (X, Y) to (X', Y'), 708506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * we need to make the following computation: 709506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * 710506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * X' = (X & ~0b1011) >> 1 | (Y & 0b1) << 2 | X & 0b1 (4) 711506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * Y' = (Y & ~0b1) << 1 | (X & 0b1000) >> 2 | (X & 0b10) >> 1 712506d70be21cd3469118de89297cba0c0f709c1aePaul Berry */ 713506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_AND(&func, t1, X, brw_imm_uw(0xfff4)); /* X & ~0b1011 */ 714506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_SHR(&func, t1, t1, brw_imm_uw(1)); /* (X & ~0b1011) >> 1 */ 715506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_AND(&func, t2, Y, brw_imm_uw(1)); /* Y & 0b1 */ 716506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_SHL(&func, t2, t2, brw_imm_uw(2)); /* (Y & 0b1) << 2 */ 717506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_OR(&func, t1, t1, t2); /* (X & ~0b1011) >> 1 | (Y & 0b1) << 2 */ 718506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_AND(&func, t2, X, brw_imm_uw(1)); /* X & 0b1 */ 719506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_OR(&func, Xp, t1, t2); 720506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_AND(&func, t1, Y, brw_imm_uw(0xfffe)); /* Y & ~0b1 */ 721506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_SHL(&func, t1, t1, brw_imm_uw(1)); /* (Y & ~0b1) << 1 */ 722506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_AND(&func, t2, X, brw_imm_uw(8)); /* X & 0b1000 */ 723506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_SHR(&func, t2, t2, brw_imm_uw(2)); /* (X & 0b1000) >> 2 */ 724506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_OR(&func, t1, t1, t2); /* (Y & ~0b1) << 1 | (X & 0b1000) >> 2 */ 725506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_AND(&func, t2, X, brw_imm_uw(2)); /* X & 0b10 */ 726506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_SHR(&func, t2, t2, brw_imm_uw(1)); /* (X & 0b10) >> 1 */ 727506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_OR(&func, Yp, t1, t2); 728506d70be21cd3469118de89297cba0c0f709c1aePaul Berry SWAP_XY_AND_XPYP(); 729506d70be21cd3469118de89297cba0c0f709c1aePaul Berry } else { 730506d70be21cd3469118de89297cba0c0f709c1aePaul Berry /* Applying the same logic as above, but in reverse, we obtain the 731506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * formulas: 732506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * 733506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * X' = (X & ~0b101) << 1 | (Y & 0b10) << 2 | (Y & 0b1) << 1 | X & 0b1 734506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * Y' = (Y & ~0b11) >> 1 | (X & 0b100) >> 2 735506d70be21cd3469118de89297cba0c0f709c1aePaul Berry */ 736506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_AND(&func, t1, X, brw_imm_uw(0xfffa)); /* X & ~0b101 */ 737506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_SHL(&func, t1, t1, brw_imm_uw(1)); /* (X & ~0b101) << 1 */ 738506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_AND(&func, t2, Y, brw_imm_uw(2)); /* Y & 0b10 */ 739506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_SHL(&func, t2, t2, brw_imm_uw(2)); /* (Y & 0b10) << 2 */ 740506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_OR(&func, t1, t1, t2); /* (X & ~0b101) << 1 | (Y & 0b10) << 2 */ 741506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_AND(&func, t2, Y, brw_imm_uw(1)); /* Y & 0b1 */ 742506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_SHL(&func, t2, t2, brw_imm_uw(1)); /* (Y & 0b1) << 1 */ 743506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_OR(&func, t1, t1, t2); /* (X & ~0b101) << 1 | (Y & 0b10) << 2 744506d70be21cd3469118de89297cba0c0f709c1aePaul Berry | (Y & 0b1) << 1 */ 745506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_AND(&func, t2, X, brw_imm_uw(1)); /* X & 0b1 */ 746506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_OR(&func, Xp, t1, t2); 747506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_AND(&func, t1, Y, brw_imm_uw(0xfffc)); /* Y & ~0b11 */ 748506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_SHR(&func, t1, t1, brw_imm_uw(1)); /* (Y & ~0b11) >> 1 */ 749506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_AND(&func, t2, X, brw_imm_uw(4)); /* X & 0b100 */ 750506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_SHR(&func, t2, t2, brw_imm_uw(2)); /* (X & 0b100) >> 2 */ 751506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_OR(&func, Yp, t1, t2); 752506d70be21cd3469118de89297cba0c0f709c1aePaul Berry SWAP_XY_AND_XPYP(); 753506d70be21cd3469118de89297cba0c0f709c1aePaul Berry } 754506d70be21cd3469118de89297cba0c0f709c1aePaul Berry} 755506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 756506d70be21cd3469118de89297cba0c0f709c1aePaul Berry/** 75719e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * Emit code to compensate for the difference between MSAA and non-MSAA 75819e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * surfaces. 75919e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * 76019e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * This code modifies the X and Y coordinates according to the formula: 76119e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * 76219e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * (X', Y') = encode_msaa_4x(X, Y, S) 76319e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * 76419e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * (See brw_blorp_blit_program). 76519e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry */ 76619e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berryvoid 76719e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berrybrw_blorp_blit_program::encode_msaa(unsigned num_samples) 76819e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry{ 76919e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry if (num_samples == 0) { 77019e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry /* No translation necessary. */ 77119e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry } else { 77219e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry /* encode_msaa_4x(X, Y, S) = (X', Y') 77319e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * where X' = (X & ~0b1) << 1 | (S & 0b1) << 1 | (X & 0b1) 77419e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * Y' = (Y & ~0b1 ) << 1 | (S & 0b10) | (Y & 0b1) 77519e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry */ 77619e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry brw_AND(&func, t1, X, brw_imm_uw(0xfffe)); /* X & ~0b1 */ 77719e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry if (!s_is_zero) { 77819e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry brw_AND(&func, t2, S, brw_imm_uw(1)); /* S & 0b1 */ 77919e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry brw_OR(&func, t1, t1, t2); /* (X & ~0b1) | (S & 0b1) */ 78019e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry } 78119e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry brw_SHL(&func, t1, t1, brw_imm_uw(1)); /* (X & ~0b1) << 1 78219e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry | (S & 0b1) << 1 */ 78319e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry brw_AND(&func, t2, X, brw_imm_uw(1)); /* X & 0b1 */ 78419e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry brw_OR(&func, Xp, t1, t2); 78519e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry brw_AND(&func, t1, Y, brw_imm_uw(0xfffe)); /* Y & ~0b1 */ 78619e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry brw_SHL(&func, t1, t1, brw_imm_uw(1)); /* (Y & ~0b1) << 1 */ 78719e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry if (!s_is_zero) { 78819e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry brw_AND(&func, t2, S, brw_imm_uw(2)); /* S & 0b10 */ 78919e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry brw_OR(&func, t1, t1, t2); /* (Y & ~0b1) << 1 | (S & 0b10) */ 79019e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry } 79119e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry brw_AND(&func, t2, Y, brw_imm_uw(1)); 79219e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry brw_OR(&func, Yp, t1, t2); 79319e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry SWAP_XY_AND_XPYP(); 79419e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry } 79519e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry} 79619e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry 79719e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry/** 79819e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * Emit code to compensate for the difference between MSAA and non-MSAA 79919e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * surfaces. 80019e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * 80119e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * This code modifies the X and Y coordinates according to the formula: 80219e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * 80319e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * (X', Y', S) = decode_msaa(num_samples, X, Y) 80419e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * 80519e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * (See brw_blorp_blit_program). 80619e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry */ 80719e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berryvoid 80819e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berrybrw_blorp_blit_program::decode_msaa(unsigned num_samples) 80919e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry{ 81019e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry if (num_samples == 0) { 81119e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry /* No translation necessary. */ 81219e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry s_is_zero = true; 81319e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry } else { 81419e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry /* decode_msaa_4x(X, Y) = (X', Y', S) 81519e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * where X' = (X & ~0b11) >> 1 | (X & 0b1) 81619e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * Y' = (Y & ~0b11) >> 1 | (Y & 0b1) 81719e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * S = (Y & 0b10) | (X & 0b10) >> 1 81819e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry */ 81919e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry brw_AND(&func, t1, X, brw_imm_uw(0xfffc)); /* X & ~0b11 */ 82019e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry brw_SHR(&func, t1, t1, brw_imm_uw(1)); /* (X & ~0b11) >> 1 */ 82119e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry brw_AND(&func, t2, X, brw_imm_uw(1)); /* X & 0b1 */ 82219e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry brw_OR(&func, Xp, t1, t2); 82319e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry brw_AND(&func, t1, Y, brw_imm_uw(0xfffc)); /* Y & ~0b11 */ 82419e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry brw_SHR(&func, t1, t1, brw_imm_uw(1)); /* (Y & ~0b11) >> 1 */ 82519e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry brw_AND(&func, t2, Y, brw_imm_uw(1)); /* Y & 0b1 */ 82619e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry brw_OR(&func, Yp, t1, t2); 82719e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry brw_AND(&func, t1, Y, brw_imm_uw(2)); /* Y & 0b10 */ 82819e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry brw_AND(&func, t2, X, brw_imm_uw(2)); /* X & 0b10 */ 82919e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry brw_SHR(&func, t2, t2, brw_imm_uw(1)); /* (X & 0b10) >> 1 */ 83019e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry brw_OR(&func, S, t1, t2); 83119e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry s_is_zero = false; 83219e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry SWAP_XY_AND_XPYP(); 83319e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry } 83419e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry} 83519e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry 83619e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry/** 837506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * Emit code that kills pixels whose X and Y coordinates are outside the 838506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * boundary of the rectangle defined by the push constants (dst_x0, dst_y0, 839506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * dst_x1, dst_y1). 840506d70be21cd3469118de89297cba0c0f709c1aePaul Berry */ 841506d70be21cd3469118de89297cba0c0f709c1aePaul Berryvoid 842506d70be21cd3469118de89297cba0c0f709c1aePaul Berrybrw_blorp_blit_program::kill_if_outside_dst_rect() 843506d70be21cd3469118de89297cba0c0f709c1aePaul Berry{ 844506d70be21cd3469118de89297cba0c0f709c1aePaul Berry struct brw_reg f0 = brw_flag_reg(); 845506d70be21cd3469118de89297cba0c0f709c1aePaul Berry struct brw_reg g1 = retype(brw_vec1_grf(1, 7), BRW_REGISTER_TYPE_UW); 846506d70be21cd3469118de89297cba0c0f709c1aePaul Berry struct brw_reg null16 = vec16(retype(brw_null_reg(), BRW_REGISTER_TYPE_UW)); 847506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 848506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_CMP(&func, null16, BRW_CONDITIONAL_GE, X, dst_x0); 849506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_CMP(&func, null16, BRW_CONDITIONAL_GE, Y, dst_y0); 850506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_CMP(&func, null16, BRW_CONDITIONAL_L, X, dst_x1); 851506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_CMP(&func, null16, BRW_CONDITIONAL_L, Y, dst_y1); 852506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 853506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_set_predicate_control(&func, BRW_PREDICATE_NONE); 854506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_push_insn_state(&func); 855506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_set_mask_control(&func, BRW_MASK_DISABLE); 856506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_AND(&func, g1, f0, g1); 857506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_pop_insn_state(&func); 858506d70be21cd3469118de89297cba0c0f709c1aePaul Berry} 859506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 860506d70be21cd3469118de89297cba0c0f709c1aePaul Berry/** 861506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * Emit code to translate from destination (X, Y) coordinates to source (X, Y) 862506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * coordinates. 863506d70be21cd3469118de89297cba0c0f709c1aePaul Berry */ 864506d70be21cd3469118de89297cba0c0f709c1aePaul Berryvoid 865506d70be21cd3469118de89297cba0c0f709c1aePaul Berrybrw_blorp_blit_program::translate_dst_to_src() 866506d70be21cd3469118de89297cba0c0f709c1aePaul Berry{ 867506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_MUL(&func, Xp, X, x_transform.multiplier); 868506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_MUL(&func, Yp, Y, y_transform.multiplier); 869506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_ADD(&func, Xp, Xp, x_transform.offset); 870506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_ADD(&func, Yp, Yp, y_transform.offset); 871506d70be21cd3469118de89297cba0c0f709c1aePaul Berry SWAP_XY_AND_XPYP(); 872506d70be21cd3469118de89297cba0c0f709c1aePaul Berry} 873506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 874506d70be21cd3469118de89297cba0c0f709c1aePaul Berry/** 87519e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * Emit code to transform the X and Y coordinates as needed for blending 87619e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * together the different samples in an MSAA texture. 87719e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry */ 87819e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berryvoid 87919e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berrybrw_blorp_blit_program::single_to_blend() 88019e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry{ 88119e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry /* When looking up samples in an MSAA texture using the SAMPLE message, 88219e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * Gen6 requires the texture coordinates to be odd integers (so that they 88319e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * correspond to the center of a 2x2 block representing the four samples 88419e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * that maxe up a pixel). So we need to multiply our X and Y coordinates 88519e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * each by 2 and then add 1. 88619e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry */ 88719e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry brw_SHL(&func, t1, X, brw_imm_w(1)); 88819e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry brw_SHL(&func, t2, Y, brw_imm_w(1)); 88919e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry brw_ADD(&func, Xp, t1, brw_imm_w(1)); 89019e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry brw_ADD(&func, Yp, t2, brw_imm_w(1)); 89119e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry SWAP_XY_AND_XPYP(); 89219e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry} 89319e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry 89419e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry/** 89519e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * Emit code to look up a value in the texture using the SAMPLE message (which 89619e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * does blending of MSAA surfaces). 89719e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry */ 89819e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berryvoid 89919e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berrybrw_blorp_blit_program::sample() 90019e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry{ 90119e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry texture_lookup(GEN5_SAMPLER_MESSAGE_SAMPLE, mrf_u_float, mrf_v_float); 90219e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry} 90319e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry 90419e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry/** 905506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * Emit code to look up a value in the texture using the SAMPLE_LD message 906506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * (which does a simple texel fetch). 907506d70be21cd3469118de89297cba0c0f709c1aePaul Berry */ 908506d70be21cd3469118de89297cba0c0f709c1aePaul Berryvoid 909506d70be21cd3469118de89297cba0c0f709c1aePaul Berrybrw_blorp_blit_program::texel_fetch() 910506d70be21cd3469118de89297cba0c0f709c1aePaul Berry{ 91119e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry assert(s_is_zero); 912506d70be21cd3469118de89297cba0c0f709c1aePaul Berry texture_lookup(GEN5_SAMPLER_MESSAGE_SAMPLE_LD, 913506d70be21cd3469118de89297cba0c0f709c1aePaul Berry retype(mrf_u_float, BRW_REGISTER_TYPE_UD), 914506d70be21cd3469118de89297cba0c0f709c1aePaul Berry retype(mrf_v_float, BRW_REGISTER_TYPE_UD)); 915506d70be21cd3469118de89297cba0c0f709c1aePaul Berry} 916506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 917506d70be21cd3469118de89297cba0c0f709c1aePaul Berryvoid 918506d70be21cd3469118de89297cba0c0f709c1aePaul Berrybrw_blorp_blit_program::texture_lookup(GLuint msg_type, 919506d70be21cd3469118de89297cba0c0f709c1aePaul Berry struct brw_reg mrf_u, 920506d70be21cd3469118de89297cba0c0f709c1aePaul Berry struct brw_reg mrf_v) 921506d70be21cd3469118de89297cba0c0f709c1aePaul Berry{ 922506d70be21cd3469118de89297cba0c0f709c1aePaul Berry /* Expand X and Y coordinates from 16 bits to 32 bits. */ 923506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_MOV(&func, vec8(mrf_u), vec8(X)); 924506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_set_compression_control(&func, BRW_COMPRESSION_2NDHALF); 925506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_MOV(&func, offset(vec8(mrf_u), 1), suboffset(vec8(X), 8)); 926506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_set_compression_control(&func, BRW_COMPRESSION_NONE); 927506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_MOV(&func, vec8(mrf_v), vec8(Y)); 928506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_set_compression_control(&func, BRW_COMPRESSION_2NDHALF); 929506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_MOV(&func, offset(vec8(mrf_v), 1), suboffset(vec8(Y), 8)); 930506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_set_compression_control(&func, BRW_COMPRESSION_NONE); 931506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 932506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_SAMPLE(&func, 933506d70be21cd3469118de89297cba0c0f709c1aePaul Berry retype(Rdata, BRW_REGISTER_TYPE_UW) /* dest */, 934506d70be21cd3469118de89297cba0c0f709c1aePaul Berry base_mrf /* msg_reg_nr */, 935506d70be21cd3469118de89297cba0c0f709c1aePaul Berry vec8(mrf_u) /* src0 */, 936506d70be21cd3469118de89297cba0c0f709c1aePaul Berry BRW_BLORP_TEXTURE_BINDING_TABLE_INDEX, 937506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 0 /* sampler -- ignored for SAMPLE_LD message */, 938506d70be21cd3469118de89297cba0c0f709c1aePaul Berry WRITEMASK_XYZW, 939506d70be21cd3469118de89297cba0c0f709c1aePaul Berry msg_type, 940506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 8 /* response_length. TODO: should be smaller for non-RGBA formats? */, 941506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 4 /* msg_length */, 942506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 0 /* header_present */, 943506d70be21cd3469118de89297cba0c0f709c1aePaul Berry BRW_SAMPLER_SIMD_MODE_SIMD16, 944506d70be21cd3469118de89297cba0c0f709c1aePaul Berry BRW_SAMPLER_RETURN_FORMAT_FLOAT32); 945506d70be21cd3469118de89297cba0c0f709c1aePaul Berry} 946506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 947506d70be21cd3469118de89297cba0c0f709c1aePaul Berry#undef X 948506d70be21cd3469118de89297cba0c0f709c1aePaul Berry#undef Y 949506d70be21cd3469118de89297cba0c0f709c1aePaul Berry#undef U 950506d70be21cd3469118de89297cba0c0f709c1aePaul Berry#undef V 951506d70be21cd3469118de89297cba0c0f709c1aePaul Berry#undef S 952506d70be21cd3469118de89297cba0c0f709c1aePaul Berry#undef SWAP_XY_AND_XPYP 953506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 954506d70be21cd3469118de89297cba0c0f709c1aePaul Berryvoid 955506d70be21cd3469118de89297cba0c0f709c1aePaul Berrybrw_blorp_blit_program::render_target_write() 956506d70be21cd3469118de89297cba0c0f709c1aePaul Berry{ 957506d70be21cd3469118de89297cba0c0f709c1aePaul Berry struct brw_reg mrf_rt_write = vec16(brw_message_reg(base_mrf)); 958506d70be21cd3469118de89297cba0c0f709c1aePaul Berry int mrf_offset = 0; 959506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 960506d70be21cd3469118de89297cba0c0f709c1aePaul Berry /* If we may have killed pixels, then we need to send R0 and R1 in a header 961506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * so that the render target knows which pixels we killed. 962506d70be21cd3469118de89297cba0c0f709c1aePaul Berry */ 963506d70be21cd3469118de89297cba0c0f709c1aePaul Berry bool use_header = key->use_kill; 964506d70be21cd3469118de89297cba0c0f709c1aePaul Berry if (use_header) { 965506d70be21cd3469118de89297cba0c0f709c1aePaul Berry /* Copy R0/1 to MRF */ 966506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_MOV(&func, retype(mrf_rt_write, BRW_REGISTER_TYPE_UD), 967506d70be21cd3469118de89297cba0c0f709c1aePaul Berry retype(R0, BRW_REGISTER_TYPE_UD)); 968506d70be21cd3469118de89297cba0c0f709c1aePaul Berry mrf_offset += 2; 969506d70be21cd3469118de89297cba0c0f709c1aePaul Berry } 970506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 971506d70be21cd3469118de89297cba0c0f709c1aePaul Berry /* Copy texture data to MRFs */ 972506d70be21cd3469118de89297cba0c0f709c1aePaul Berry for (int i = 0; i < 4; ++i) { 973506d70be21cd3469118de89297cba0c0f709c1aePaul Berry /* E.g. mov(16) m2.0<1>:f r2.0<8;8,1>:f { Align1, H1 } */ 974506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_MOV(&func, offset(mrf_rt_write, mrf_offset), offset(vec8(Rdata), 2*i)); 975506d70be21cd3469118de89297cba0c0f709c1aePaul Berry mrf_offset += 2; 976506d70be21cd3469118de89297cba0c0f709c1aePaul Berry } 977506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 978506d70be21cd3469118de89297cba0c0f709c1aePaul Berry /* Now write to the render target and terminate the thread */ 979506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_fb_WRITE(&func, 980506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 16 /* dispatch_width */, 981506d70be21cd3469118de89297cba0c0f709c1aePaul Berry base_mrf /* msg_reg_nr */, 982506d70be21cd3469118de89297cba0c0f709c1aePaul Berry mrf_rt_write /* src0 */, 983506d70be21cd3469118de89297cba0c0f709c1aePaul Berry BRW_BLORP_RENDERBUFFER_BINDING_TABLE_INDEX, 984506d70be21cd3469118de89297cba0c0f709c1aePaul Berry mrf_offset /* msg_length. TODO: Should be smaller for non-RGBA formats. */, 985506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 0 /* response_length */, 986506d70be21cd3469118de89297cba0c0f709c1aePaul Berry true /* eot */, 987506d70be21cd3469118de89297cba0c0f709c1aePaul Berry use_header); 988506d70be21cd3469118de89297cba0c0f709c1aePaul Berry} 989506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 990506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 991506d70be21cd3469118de89297cba0c0f709c1aePaul Berryvoid 992506d70be21cd3469118de89297cba0c0f709c1aePaul Berrybrw_blorp_coord_transform_params::setup(GLuint src0, GLuint dst0, GLuint dst1, 993506d70be21cd3469118de89297cba0c0f709c1aePaul Berry bool mirror) 994506d70be21cd3469118de89297cba0c0f709c1aePaul Berry{ 995506d70be21cd3469118de89297cba0c0f709c1aePaul Berry if (!mirror) { 996506d70be21cd3469118de89297cba0c0f709c1aePaul Berry /* When not mirroring a coordinate (say, X), we need: 997506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * x' - src_x0 = x - dst_x0 998506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * Therefore: 999506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * x' = 1*x + (src_x0 - dst_x0) 1000506d70be21cd3469118de89297cba0c0f709c1aePaul Berry */ 1001506d70be21cd3469118de89297cba0c0f709c1aePaul Berry multiplier = 1; 1002506d70be21cd3469118de89297cba0c0f709c1aePaul Berry offset = src0 - dst0; 1003506d70be21cd3469118de89297cba0c0f709c1aePaul Berry } else { 1004506d70be21cd3469118de89297cba0c0f709c1aePaul Berry /* When mirroring X we need: 1005506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * x' - src_x0 = dst_x1 - x - 1 1006506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * Therefore: 1007506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * x' = -1*x + (src_x0 + dst_x1 - 1) 1008506d70be21cd3469118de89297cba0c0f709c1aePaul Berry */ 1009506d70be21cd3469118de89297cba0c0f709c1aePaul Berry multiplier = -1; 1010506d70be21cd3469118de89297cba0c0f709c1aePaul Berry offset = src0 + dst1 - 1; 1011506d70be21cd3469118de89297cba0c0f709c1aePaul Berry } 1012506d70be21cd3469118de89297cba0c0f709c1aePaul Berry} 1013506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 1014506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 1015506d70be21cd3469118de89297cba0c0f709c1aePaul Berrybrw_blorp_blit_params::brw_blorp_blit_params(struct intel_mipmap_tree *src_mt, 1016506d70be21cd3469118de89297cba0c0f709c1aePaul Berry struct intel_mipmap_tree *dst_mt, 1017506d70be21cd3469118de89297cba0c0f709c1aePaul Berry GLuint src_x0, GLuint src_y0, 1018506d70be21cd3469118de89297cba0c0f709c1aePaul Berry GLuint dst_x0, GLuint dst_y0, 1019506d70be21cd3469118de89297cba0c0f709c1aePaul Berry GLuint dst_x1, GLuint dst_y1, 1020506d70be21cd3469118de89297cba0c0f709c1aePaul Berry bool mirror_x, bool mirror_y) 1021506d70be21cd3469118de89297cba0c0f709c1aePaul Berry{ 1022506d70be21cd3469118de89297cba0c0f709c1aePaul Berry src.set(src_mt, 0, 0); 1023506d70be21cd3469118de89297cba0c0f709c1aePaul Berry dst.set(dst_mt, 0, 0); 1024506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 1025506d70be21cd3469118de89297cba0c0f709c1aePaul Berry use_wm_prog = true; 1026506d70be21cd3469118de89297cba0c0f709c1aePaul Berry memset(&wm_prog_key, 0, sizeof(wm_prog_key)); 1027506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 102819e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry if (src_mt->num_samples > 0 && dst_mt->num_samples > 0) { 102919e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry /* We are blitting from a multisample buffer to a multisample buffer, so 103019e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * we must preserve samples within a pixel. This means we have to 103119e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * configure the render target and texture surface states as 103219e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * single-sampled, so that the WM program can access each sample 103319e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * individually. 103419e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry */ 103519e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry src.num_samples = dst.num_samples = 0; 103619e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry } 103719e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry 103819e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry /* The render path must be configured to use the same number of samples as 103919e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * the destination buffer. 104019e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry */ 104119e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry num_samples = dst.num_samples; 104219e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry 104319e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry GLenum base_format = _mesa_get_format_base_format(src_mt->format); 104419e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry if (base_format != GL_DEPTH_COMPONENT && /* TODO: what about depth/stencil? */ 104519e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry base_format != GL_STENCIL_INDEX && 104619e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry src_mt->num_samples > 0 && dst_mt->num_samples == 0) { 104719e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry /* We are downsampling a color buffer, so blend. */ 104819e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry wm_prog_key.blend = true; 104919e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry } 105019e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry 105119e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry /* src_samples and dst_samples are the true sample counts */ 105219e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry wm_prog_key.src_samples = src_mt->num_samples; 105319e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry wm_prog_key.dst_samples = dst_mt->num_samples; 105419e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry 105519e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry /* tex_samples and rt_samples are the sample counts that are set up in 105619e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * SURFACE_STATE. 105719e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry */ 105819e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry wm_prog_key.tex_samples = src.num_samples; 105919e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry wm_prog_key.rt_samples = dst.num_samples; 106019e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry 1061506d70be21cd3469118de89297cba0c0f709c1aePaul Berry wm_prog_key.src_tiled_w = src.map_stencil_as_y_tiled; 1062506d70be21cd3469118de89297cba0c0f709c1aePaul Berry wm_prog_key.dst_tiled_w = dst.map_stencil_as_y_tiled; 1063506d70be21cd3469118de89297cba0c0f709c1aePaul Berry x0 = wm_push_consts.dst_x0 = dst_x0; 1064506d70be21cd3469118de89297cba0c0f709c1aePaul Berry y0 = wm_push_consts.dst_y0 = dst_y0; 1065506d70be21cd3469118de89297cba0c0f709c1aePaul Berry x1 = wm_push_consts.dst_x1 = dst_x1; 1066506d70be21cd3469118de89297cba0c0f709c1aePaul Berry y1 = wm_push_consts.dst_y1 = dst_y1; 1067506d70be21cd3469118de89297cba0c0f709c1aePaul Berry wm_push_consts.x_transform.setup(src_x0, dst_x0, dst_x1, mirror_x); 1068506d70be21cd3469118de89297cba0c0f709c1aePaul Berry wm_push_consts.y_transform.setup(src_y0, dst_y0, dst_y1, mirror_y); 1069506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 107019e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry if (dst.num_samples == 0 && dst_mt->num_samples > 0) { 107119e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry /* We must expand the rectangle we send through the rendering pipeline, 107219e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * to account for the fact that we are mapping the destination region as 107319e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * single-sampled when it is in fact multisampled. We must also align 107419e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * it to a multiple of the multisampling pattern, because the 107519e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * differences between multisampled and single-sampled surface formats 107619e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * will mean that pixels are scrambled within the multisampling pattern. 107719e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * TODO: what if this makes the coordinates too large? 107819e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry */ 107919e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry x0 = (x0 * 2) & ~3; 108019e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry y0 = (y0 * 2) & ~3; 108119e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry x1 = ALIGN(x1 * 2, 4); 108219e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry y1 = ALIGN(y1 * 2, 4); 108319e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry wm_prog_key.use_kill = true; 108419e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry } 108519e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry 1086506d70be21cd3469118de89297cba0c0f709c1aePaul Berry if (dst.map_stencil_as_y_tiled) { 1087506d70be21cd3469118de89297cba0c0f709c1aePaul Berry /* We must modify the rectangle we send through the rendering pipeline, 1088506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * to account for the fact that we are mapping it as Y-tiled when it is 1089506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * in fact W-tiled. Y tiles have dimensions 128x32 whereas W tiles have 1090506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * dimensions 64x64. We must also align it to a multiple of the tile 1091506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * size, because the differences between W and Y tiling formats will 1092506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * mean that pixels are scrambled within the tile. 1093506d70be21cd3469118de89297cba0c0f709c1aePaul Berry * TODO: what if this makes the coordinates too large? 1094506d70be21cd3469118de89297cba0c0f709c1aePaul Berry */ 1095506d70be21cd3469118de89297cba0c0f709c1aePaul Berry x0 = (x0 * 2) & ~127; 1096506d70be21cd3469118de89297cba0c0f709c1aePaul Berry y0 = (y0 / 2) & ~31; 1097506d70be21cd3469118de89297cba0c0f709c1aePaul Berry x1 = ALIGN(x1 * 2, 128); 1098506d70be21cd3469118de89297cba0c0f709c1aePaul Berry y1 = ALIGN(y1 / 2, 32); 1099506d70be21cd3469118de89297cba0c0f709c1aePaul Berry wm_prog_key.use_kill = true; 1100506d70be21cd3469118de89297cba0c0f709c1aePaul Berry } 1101506d70be21cd3469118de89297cba0c0f709c1aePaul Berry} 1102506d70be21cd3469118de89297cba0c0f709c1aePaul Berry 1103506d70be21cd3469118de89297cba0c0f709c1aePaul Berryuint32_t 1104506d70be21cd3469118de89297cba0c0f709c1aePaul Berrybrw_blorp_blit_params::get_wm_prog(struct brw_context *brw, 1105506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_blorp_prog_data **prog_data) const 1106506d70be21cd3469118de89297cba0c0f709c1aePaul Berry{ 1107506d70be21cd3469118de89297cba0c0f709c1aePaul Berry uint32_t prog_offset; 1108506d70be21cd3469118de89297cba0c0f709c1aePaul Berry if (!brw_search_cache(&brw->cache, BRW_BLORP_BLIT_PROG, 1109506d70be21cd3469118de89297cba0c0f709c1aePaul Berry &this->wm_prog_key, sizeof(this->wm_prog_key), 1110506d70be21cd3469118de89297cba0c0f709c1aePaul Berry &prog_offset, prog_data)) { 1111506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_blorp_blit_program prog(brw, &this->wm_prog_key); 1112506d70be21cd3469118de89297cba0c0f709c1aePaul Berry GLuint program_size; 1113506d70be21cd3469118de89297cba0c0f709c1aePaul Berry const GLuint *program = prog.compile(brw, &program_size); 1114506d70be21cd3469118de89297cba0c0f709c1aePaul Berry brw_upload_cache(&brw->cache, BRW_BLORP_BLIT_PROG, 1115506d70be21cd3469118de89297cba0c0f709c1aePaul Berry &this->wm_prog_key, sizeof(this->wm_prog_key), 1116506d70be21cd3469118de89297cba0c0f709c1aePaul Berry program, program_size, 1117506d70be21cd3469118de89297cba0c0f709c1aePaul Berry &prog.prog_data, sizeof(prog.prog_data), 1118506d70be21cd3469118de89297cba0c0f709c1aePaul Berry &prog_offset, prog_data); 1119506d70be21cd3469118de89297cba0c0f709c1aePaul Berry } 1120506d70be21cd3469118de89297cba0c0f709c1aePaul Berry return prog_offset; 1121506d70be21cd3469118de89297cba0c0f709c1aePaul Berry} 1122