aboutsummaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers
Commit message (Collapse)AuthorAgeFilesLines
* mesa/meta: Use interpolateAtOffset for 16x MSAA copy blitNeil Roberts2015-11-051-2/+37
| | | | | | | | | | | | | | | | | | | | | | | | | Previously there was a problem in i965 where if 16x MSAA is used then some of the sample positions are exactly on the 0 x or y axis. When the MSAA copy blit shader interpolates the texture coordinates at these sample positions it was possible that it would jump to a neighboring texel due to rounding errors. It is likely that these positions would be used on 16x MSAA because that is where they are defined to be in D3D. To fix that this patch makes it use interpolateAtOffset in the blit shader whenever 16x MSAA is used and the GL_ARB_gpu_shader5 extension is available. This forces it to interpolate the texture coordinates at the pixel center to avoid these problematic positions. This fixes ext_framebuffer_multisample-unaligned-blit and ext_framebuffer_multisample-clip-and-scissor-blit with 16x MSAA on SKL+. v2: Use interpolateAtOffset instead of interpolateAtSample v3: Always try to enable GL_ARB_gpu_shader5 in the shader [Ian Romanick] Reviewed-by: Anuj Phogat <[email protected]>
* meta/blit: Always try to enable GL_ARB_sample_shadingNeil Roberts2015-11-051-14/+2
| | | | | | | | | | | Previously this extension was only enabled when blitting between two multisampled buffers. However I don't think it does any harm to just enable it all the time. The ‘enable’ option is used instead of ‘require’ so that the shader will still compile if the extension isn't available in the cases where it isn't used. This will make the next patch simpler because it wants to add another optional extension. Reviewed-by: Anuj Phogat <[email protected]>
* meta: Support 16x MSAA in the multisample scaled blit shaderNeil Roberts2015-11-053-10/+35
| | | | | | v2: Fix the x_scale in the shader. Remove the doubts in the commit message. Reviewed-by: Anuj Phogat <[email protected]>
* i965/meta: Support 16x MSAA in the meta stencil blitNeil Roberts2015-11-051-5/+17
| | | | | | | The destination rectangle is now drawn at 4x4 the size and the shader code to calculate the sample number is adjusted accordingly. Acked-by: Ben Widawsky <[email protected]>
* i965/fs/skl+: Fix calculating gl_SampleID for 16x MSAANeil Roberts2015-11-051-1/+7
| | | | | | | | In order to accomodate 16x MSAA, the starting sample pair index is now 3 bits rather than 2 on SKL+. Reviewed-by: Ben Widawsky <[email protected]> Reviewed-by: Anuj Phogat <[email protected]>
* i965: Support allocating the MCS buffer for 16x MSAANeil Roberts2015-11-051-0/+6
| | | | | | When 16 samples are used the MCS buffer needs 64 bits per pixel. Reviewed-by: Ben Widawsky <[email protected]>
* i965: Support calculating the bits needed to set up 16x MSAANeil Roberts2015-11-051-1/+1
| | | | | | | The gen7_surface_msaa_bits function already returns the right values for 16 samples but it just needs its assert to be relaxed. Reviewed-by: Ben Widawsky <[email protected]>
* i965/fs: Add a sampler program key for whether the texture is 16x MSAANeil Roberts2015-11-053-1/+16
| | | | | | | | | | | | | | | | When 16x MSAA is used for sampling with texelFetch the compiler needs to use a different instruction which passes more arguments for the MCS data. Previously on skl+ it was unconditionally using this new instruction. However since 16x MSAA is probably going to be pretty rare, it is probably worthwhile to avoid using this instruction for the other sample counts. In order to do that this patch adds a new member to brw_sampler_prog_key_data to track when a sampler refers to a buffer with 16 samples. Note that this isn't done for the vec4 backend because it wouldn't change how many registers it uses. Acked-by: Ben Widawsky <[email protected]>
* i965/vec4/skl+: Use ld2dms_w instead of ld2dmsNeil Roberts2015-11-053-2/+18
| | | | | | | | | In order to support 16x MSAA, skl+ has a wider version of ld2dms that takes two parameters for the MCS data. The MCS data in the response still fits in a single register so we just need to ensure we copy both values rather than just the lower one. Acked-by: Ben Widawsky <[email protected]>
* i965/fs/skl+: Use ld2dms_w instead of ld2dmsNeil Roberts2015-11-056-5/+60
| | | | | | | | | | | | In order to support 16x MSAA, skl+ has a wider version of ld2dms that takes two parameters for the MCS data. The MCS data retrieved from the ld_mcs instruction already returns 4 or 8 registers and is documented to return zeroes for the mcsh value when the sample count is less than 16. v2: Use get_lowered_simd_width to fall back to SIMD8 instructions when the message length would be too long in SIMD16. Reviewed-by: Ben Widawsky <[email protected]>
* i965: Program 16x MSAA sample positions.Neil Roberts2015-11-053-7/+34
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This is the standard pattern used by the other 3D graphics API. BDW has slots for these values, but they aren't actually used until SKL. Even though the documentation for BDW says they must be zero, it doesn't seem to cause any harm to program them anyway. The comment above for the 8x sample positions says that the hardware implements centroid interpolation by picking the centre-most sample that is inside the primitive. That implies that it might be worthwhile to pick a pattern that includes 0.5,0.5. However by experimentation this doesn't seem to actually be the case. With the sample positions in this patch, if I modify the piglit test below so that it instead reports the centroid position, it reports 0.492188,0.421875 which doesn't match any of the positions. If I modify the sample positions so that they include one at exactly 0.5,0.5 it doesn't help and it reports another position which is even further from the center for some reason. arb_gpu_shader5-interpolateAtSample-different Kenneth Graunke experimented with some other patterns that have a higher standard deviation but I think after some discussion it was decided that it would be better to pick the same pattern as the other graphics API in case there are games that rely on this pattern. (Based on a patch by Kenneth Graunke) Cc: Kenneth Graunke <[email protected]> Reviewed-by: Ben Widawsky <ben at bwidawsk.net>
* i965: Handle 16x MSAA in IMS dimension munging code.Kenneth Graunke2015-11-051-2/+6
| | | | | | Signed-off-by: Kenneth Graunke <[email protected]> Reviewed-by: Neil Roberts <[email protected]> Reviewed-by: Ben Widawsky <[email protected]>
* i965/vec4: select predicate based on writemask for sel emissionsAlejandro Piñeiro2015-11-051-1/+17
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Equivalent to commit 8ac3b525c but with sel operations. In this case we select the PredCtrl based on the writemask. This patch helps on cases like this: 1: cmp.l.f0.0 vgrf40.0.x:F, vgrf0.zzzz:F, vgrf7.xxxx:F 2: cmp.nz.f0.0 null:D, vgrf40.xxxx:D, 0D 3: (+f0.0) sel vgrf41.0.x:UD, vgrf6.xxxx:UD, vgrf5.xxxx:UD In this case, cmod propagation can't optimize instruction #2, because instructions #1 and #2 have different writemasks, and we can't update directly instruction #2 writemask because our code thinks that sel at instruction #3 reads all four channels of the flag, when it actually only reads .x. So, with this patch, the previous case becames this: 1: cmp.l.f0.0 vgrf40.0.x:F, vgrf0.zzzz:F, vgrf7.xxxx:F 2: cmp.nz.f0.0 null:D, vgrf40.xxxx:D, 0D 3: (+f0.0.x) sel vgrf41.0.x:UD, vgrf6.xxxx:UD, vgrf5.xxxx:UD Now only the x channel of the flag is used, allowing dead code eliminate to update the writemask at the second instruction: 1: cmp.l.f0.0 vgrf40.0.x:F, vgrf0.zzzz:F, vgrf7.xxxx:F 2: cmp.nz.f0.0 null.x:D, vgrf40.xxxx:D, 0D 3: (+f0.0.x) sel vgrf41.0.x:UD, vgrf6.xxxx:UD, vgrf5.xxxx:UD So now cmod propagation can simplify out #2: 1: cmp.l.f0.0 vgrf40.0.x:F, attr18.wwww:F, vgrf7.xxxx:F 2: (+f0.0.x) sel vgrf41.0.x:UD, vgrf6.xxxx:UD, vgrf5.xxxx:UD Shader-db numbers: total instructions in shared programs: 6235835 -> 6228008 (-0.13%) instructions in affected programs: 219850 -> 212023 (-3.56%) total loops in shared programs: 1979 -> 1979 (0.00%) helped: 1192 HURT: 0
* i965: check inst->predicate when clearing flag_live at dead code eliminateAlejandro Piñeiro2015-11-042-2/+2
| | | | | | | Detected by Matt Turner while reviewing commit a59359ecd22154cc2b3f88bb8c599f21af8a3934 Reviewed-by: Matt Turner <[email protected]>
* i965/meta: Assert fast clears and rep clears never overlapBen Widawsky2015-11-031-0/+2
| | | | | | | | | | | There is nothing wrong with the code today, but as one modifies the code it turns out to be not too difficult to mess up the code, and this easy assertion should catch such driver implementation failures quickly. Cc: Kristian Høgsberg <[email protected]> Signed-off-by: Ben Widawsky <[email protected]> Reviewed-by: Chad Versace <[email protected]> Reviewed-by: Neil Roberts <[email protected]>
* i965: enable ARB_arrays_of_arraysTimothy Arceri2015-11-041-0/+1
| | | | Reviewed-by: Samuel Iglesias Gonsálvez <[email protected]>
* i965: add support for image AoATimothy Arceri2015-11-042-14/+18
| | | | | | | | | | | | | V3: clamp array index to the correct size (the size of the current array rather than the inner array) Francisco Jerez. V2: avoid useless zero-initialization and addition for the first AoA level, avoid redundant temporary, make use of type_size_scalar(), rename aoa_size to element_size, assign the indirect indexing temporary directly to image.reladdr, and replace while loop with a for loop. All suggested by Francisco Jerez. Reviewed-by: Francisco Jerez <[email protected]>
* i965/vec4: Send from GRF in atomic operations.Matt Turner2015-11-031-12/+18
| | | | Reviewed-by: Kenneth Graunke <[email protected]>
* i965: Add scalar geometry shader support.Kenneth Graunke2015-11-035-24/+666
| | | | | | | | | | | | | | | | | | | | This is hidden behind INTEL_SCALAR_GS=1 for now, as we don't yet support instanced geometry shaders, and Orbital Explorer's shader spills like crazy. But the infrastructure is in place, and it's largely working. v2: Lots of rebasing. v3: (feedback from Kristian Høgsberg) - Handle stride and subreg_offset correctly for ATTRs; use a helper. - Fix missing emit_shader_time_end() call. - Delete dead code after early EOT in static vertex case to avoid tripping asserts in emit_shader_time_end(). - Use proper D/UD type in intexp2(). - Fix "EndPrimitve" and "to that" typos. - Assert that invocations == 1 so we know this is missing. Signed-off-by: Kenneth Graunke <[email protected]> Reviewed-by: Kristian Høgsberg <[email protected]>
* i965: Add scalar GS input lowering code.Kenneth Graunke2015-11-031-5/+39
| | | | | | | | | We really ought to compute the VUE map at link time and stash it, rather than recomputing it here, but with the mess of program structures I wasn't sure where to put it. We can improve that later. Signed-off-by: Kenneth Graunke <[email protected]> Reviewed-by: Kristian Høgsberg <[email protected]>
* i965: Fix the fs_visitor GS constructor to take shader_time_index.Kenneth Graunke2015-11-032-3/+5
| | | | | | | | Jason reworked this so it isn't simply ST_GS anymore...it's either -1 (not enabled) or an actual offset. Signed-off-by: Kenneth Graunke <[email protected]> Reviewed-by: Kristian Høgsberg <[email protected]>
* i965/gen8+: Extract color clear surface stateBen Widawsky2015-11-031-6/+15
| | | | | | | | | | | | | | On future generation platforms the color clear value is stored elsewhere in the surface state. By extracting this logic, we can cleanly implement the difference in an upcoming patch. Should have no functional impact. v2: Move hunk from the next patch into this patch (Matt) Whitespace fix (Ben) Signed-off-by: Ben Widawsky <[email protected]> Reviewed-by: Neil Roberts <[email protected]>
* i965/gen8+: Remove redundant zeroing of surface stateBen Widawsky2015-11-031-12/+0
| | | | | | | | | | | | | | The allocate_surface_state already zeroes out the surface state, and doing it later in the function is destructive for what we want to accomplish when we split out support for gen9 fast clears (next patch). NOTE: Only dword 12 actually needed to be fixed, but it seemed more consistent to remove the other instances as well. I can make an argument both ways (open coding it, vs. not). I can rework the next patch if requires. Signed-off-by: Ben Widawsky <[email protected]> Reviewed-by: Chad Versace <[email protected]> Reviewed-by: Neil Roberts <[email protected]>
* i965/skl: Add GT4 PCI IDsBen Widawsky2015-11-031-1/+5
| | | | | | | | | | | | | | | | | | | | Like other gen8+ hardware, the hardware automatically scales up thread counts. We must be careful about the URB sizes since GT4 adds another slice. One of the existing PCI IDs is actually mislabeled as GT3. Arguably this is a real bug since the URB size will be wrong. Because this patch is simply meant to add the missing IDs, that will be fixed in a later patch. v2: No longer relevant. v3: Update the wm thread count to support GT4. The WM thread count is used to determine the maximum scratch space required. Currently the code always allocates the maximum amount even though lower GT SKUs require less. The formula is threads_per_psd * subslices_per_slice * slices Cc: [email protected] Reviewed-by: Jordan Justen <[email protected]> Signed-off-by: Ben Widawsky <[email protected]>
* i965/fs: Clean up FBH code.Matt Turner2015-11-021-4/+3
| | | | Reviewed-by: Ian Romanick <[email protected]>
* i965/vec4: Clean up FBH code.Matt Turner2015-11-021-13/+5
| | | | | | It did a bunch of unnecessary stuff, emitting an extra MOV included. Reviewed-by: Ian Romanick <[email protected]>
* i965: Replace default case with list of enum values.Matt Turner2015-11-025-26/+29
| | | | | | | If we add a new file type, we'd like to get warnings if it's not handled. Reviewed-by: Ian Romanick <[email protected]>
* i965/vec4: Don't disable channels in any/all comparisons.Matt Turner2015-11-021-42/+10
| | | | | | | | | | | | | | | | | | | | | | We've made a mistake in calling the Channel Enable bits "writemask", because they do more than control which channels of the destination are written -- they actually control which channels are enabled (surprise! surprise!) So, if we emit cmp.z.f0(8) null.xy<1>D g10<4,4,1>.xyzzD g2<0,4,1>.xyzzD mov(8) g12<1>.xUD 0x00000000UD (+f0.all4h) mov(8) g12<1>.xUD 0xffffffffUD where the CMP instruction has only .xy channel enables, it won't write the .zw channels of the flag register, which are of course read by the +f0.all4 predicate. We need to always emit CMP instructions whose flag result might be read by such a predicate with all channels enabled. Reviewed-by: Jason Ekstrand <[email protected]>
* nouveau: set MaxDrawBuffers to the same value as MaxColorAttachmentsIlia Mirkin2015-11-011-1/+1
| | | | | Signed-off-by: Ilia Mirkin <[email protected]> Cc: [email protected]
* i965: Setup pull constant state for compute programsJordan Justen2015-11-014-1/+35
| | | | | Signed-off-by: Jordan Justen <[email protected]> Reviewed-by: Iago Toral Quiroga <[email protected]>
* i965/sched: don't calculate live intervals for post-RA schedulingConnor Abbott2015-10-311-1/+2
| | | | | | | | | | | For some reason, this causes assertions on gm965 only. In any case, it's unnecessary since we don't need liveness information in the post-RA scheduler. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=92744 Cc: Mark Janes <[email protected]> Signed-off-by: Connor Abbott <[email protected]> Reviewed-by: Jason Ekstrand <[email protected]>
* i965: Do legacy userclipping in OpenGL ES 1.x contexts.Ian Romanick2015-10-301-1/+2
| | | | | | | | | | | | | | | Commit fba4823a disabled user clipping for everything except compatibility profile. Core profile and OpenGL ES 2.0+ have all removed the classic, OpenGL 1.0 user clip planes. ES 1.x, however, still has them. Fixes OpenGL ES 1.1 conformance mustpass.c and userclip.c Signed-off-by: Ian Romanick <[email protected]> Reviewed-by: Kenneth Graunke <[email protected]> Tested-by: Olivier Berthier <[email protected]> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=92639 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=92641
* i965: enable ARB_shader_clock on gen7+Emil Velikov2015-10-301-0/+1
| | | | | Signed-off-by: Emil Velikov <[email protected]> Reviewed-by: Matt Turner <[email protected]>
* i965: Implement nir_intrinsic_shader_clockEmil Velikov2015-10-302-0/+19
| | | | | | | | | | | | | | | v2: - Add a few const qualifiers for good measure. - Drop unneeded retype()s (Matt) - Convert timestamp to SIMD8/16, as fs_visitor::get_timestamp() returns SIMD4 (Connor) v3: - Remove unneeded temporary + MOV (Connor) Signed-off-by: Emil Velikov <[email protected]> Reviewed-by: Connor Abbott <[email protected]> Reviewed-by: Matt Turner <[email protected]>
* i965/fs: move the fs_reg::smear() from get_timestamp() to the callersEmil Velikov2015-10-301-12/+17
| | | | | | | | | | | | | We're about to reuse get_timestamp() for the nir_intrinsic_shader_clock. In the latter the generalisation does not apply, so move the smear() where needed. This also makes the function analogous to the vec4 one. v2: Tweak the comment - The caller -> We (Matt, Connor). v3: More comment tweaks (Connor) Signed-off-by: Emil Velikov <[email protected]> Reviewed-by: Connor Abbott <[email protected]> Reviewed-by: Matt Turner <[email protected]>
* i965: Fix invalid memory accesses after resizing brw_codegen's store tableKristian Høgsberg2015-10-301-4/+13
| | | | Reviewed-by: Iago Toral Quiroga <[email protected]>
* i965/sched: use liveness analysis for computing register pressureConnor Abbott2015-10-301-56/+229
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Previously, we were using some heuristics to try and detect when a write was about to begin a live range, or when a read was about to end a live range. We never used the liveness analysis information used by the register allocator, though, which meant that the scheduler's and the allocator's ideas of when a live range began and ended were different. Not only did this make our estimate of the register pressure benefit of scheduling an instruction wrong in some cases, but it was preventing us from knowing the actual register pressure when scheduling each instruction, which we want to have in order to switch to register pressure scheduling only when the register pressure is too high. This commit rewrites the register pressure tracking code to use the same model as our register allocator currently uses. We use the results of liveness analysis, as well as the compute_payload_ranges() function that we split out in the last commit. This means that we compute live ranges twice on each round through the register allocator, although we could speed it up by only recomputing the ranges and not the live in/live out sets after scheduling, since we only shuffle around instructions within a single basic block when we schedule. Shader-db results on bdw: total instructions in shared programs: 7130187 -> 7129880 (-0.00%) instructions in affected programs: 1744 -> 1437 (-17.60%) helped: 1 HURT: 1 total cycles in shared programs: 172535126 -> 172473226 (-0.04%) cycles in affected programs: 11338636 -> 11276736 (-0.55%) helped: 876 HURT: 873 LOST: 8 GAINED: 0 v2: use regs_read() in more places. Reviewed-by: Jason Ekstrand <[email protected]>
* i965/fs: split out calculation of payload live rangesConnor Abbott2015-10-302-22/+31
| | | | | | | | We'll need this for the scheduler too, since it wants to know when the live ranges of payload registers end in order to model them in our register pressure calculations. Reviewed-by: Jason Ekstrand <[email protected]>
* i965: dump scheduling cycle estimatesConnor Abbott2015-10-304-10/+36
| | | | | | | | | | | | | The heuristic we're using is rather lame, since it assumes everything is non-uniform and loops execute 10 times, but it should be enough for measuring improvements in the scheduler that don't result in a change in the number of instructions. v2: - Switch loops and cycle counts to be compatible with older shader-db. - Make loop heuristic 10x to match with spilling code. Reviewed-by: Jason Ekstrand <[email protected]>
* i965: always run the post-RA schedulerConnor Abbott2015-10-301-2/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | Before, we would only do scheduling after register allocation if we spilled, despite the fact that the pre-RA scheduler was only supposed to be for register pressure and set the latencies of every instruction to 1. This meant that unless we spilled, which we rarely do, then we never considered instruction latencies at all, and we usually never bothered to try and hide texture fetch latency. Although a later commit removes the setting the latency to 1 part, we still want to always run the post-RA scheduler since it's able to take the false dependencies that the register allocator creates into account, and it can be more aggressive than the pre-RA scheduler since it doesn't have to worry about register pressure at all. Test master post-ra-sched diff %diff bench_OglPSBump2 396.730 402.386 5.656 +1.400% bench_OglPSBump8 244.370 247.591 3.221 +1.300% bench_OglPSPhong 241.117 242.002 0.885 +0.300% bench_OglPSPom 59.555 59.725 0.170 +0.200% bench_OglShMapPcf 86.149 102.346 16.197 +18.800% bench_OglVSTangent 388.849 395.489 6.640 +1.700% bench_trex 65.471 65.862 0.390 +0.500% bench_trexoff 69.562 70.150 0.588 +0.800% bench_heaven 25.179 25.254 0.074 +0.200% Reviewed-by: Jason Ekstrand <[email protected]>
* i965/sched: write-after-read dependencies are freeConnor Abbott2015-10-301-5/+5
| | | | | | | | | | | | Although write-after-write dependencies have the same latency as read-after-write dependencies due to how the register scoreboard works, write-after-read dependencies aren't checked by the EU at all, so they're purely a constraint on how the scheduler can order the instructions. v2: fix accumulator dependencies too. Reviewed-by: Jason Ekstrand <[email protected]>
* i965: fix cycle estimates when there's a pipeline stallConnor Abbott2015-10-301-7/+8
| | | | | | | | | | | | The issue time for an instruction is how many cycles it takes to actually put it into the pipeline. If there's a pipeline stall that causes the instruction to be delayed, we should first take that into account to figure out when the instruction would start executing and *then* add the issue time. The old code had it backwards, and so we would underestimate the total time whenever we thought there would be a pipeline stall by up to the issue time of the instruction. Reviewed-by: Jason Ekstrand <[email protected]>
* i965: Add INTEL_DEBUG=nocompact to disable instruction compaction.Matt Turner2015-10-293-0/+5
| | | | Reviewed-by: Kenneth Graunke <[email protected]>
* i965: Add INTEL_DEBUG=hex to print the hex with the disassembly.Matt Turner2015-10-293-1/+3
| | | | Reviewed-by: Kenneth Graunke <[email protected]>
* i965: Print the type and writemask on null destinations.Matt Turner2015-10-291-1/+1
| | | | | | | | These are often useful in debugging, and the writemask (actually "Channel Enables") determines more than just what goes into the destination. Reviewed-by: Kenneth Graunke <[email protected]>
* i965: Test fixed_hw_reg.file against BRW_IMMEDIATE_VALUE, not IMM.Matt Turner2015-10-291-4/+4
| | | | | | | | No functional change, since they were both 3, but BRW_IMMEDIATE_VALUE is the hardware value and IMM was the IR value -- and you can see that BRW_IMMEDIATE_VALUE was correctly used in the context of this patch. Reviewed-by: Kenneth Graunke <[email protected]>
* i965/vec4: Test against BRW_IMMEDIATE_VALUE, not IMM.Matt Turner2015-10-291-1/+1
| | | | | | | | No functional change, since they were both 3, but BRW_IMMEDIATE_VALUE is the hardware value and IMM was the IR value -- and you can see that BRW_IMMEDIATE_VALUE was correctly used in the context of this patch. Reviewed-by: Kenneth Graunke <[email protected]>
* i965/fs: Use group(4, 0) to emit an exec-size 4 MOV.Matt Turner2015-10-291-2/+3
| | | | Reviewed-by: Kenneth Graunke <[email protected]>
* i965/cfg: Handle no-idom case in cfg_t::dump_domtree().Matt Turner2015-10-291-1/+3
| | | | Reviewed-by: Kenneth Graunke <[email protected]>
* i965/disasm: Remove unused _addr_mode argument from src_ia1().Matt Turner2015-10-291-3/+0
| | | | Reviewed-by: Kenneth Graunke <[email protected]>