Import Mesa 11.0.8

This seems to fix some of the problems with clutter/gnome reported to
occur on r600 with 11.0.6
This commit is contained in:
jsg 2015-12-23 13:18:51 +00:00
parent 1472c2a8d8
commit 9efbf61fd8
76 changed files with 2309 additions and 475 deletions

View File

@ -1 +1 @@
11.0.6 11.0.8

View File

@ -31,7 +31,8 @@ because compatibility contexts are not supported.
<h2>SHA256 checksums</h2> <h2>SHA256 checksums</h2>
<pre> <pre>
TBD 4bdf054af66ebabf3eca0616f9f5e44c2f234695661b570261c391bc2f4f7482 mesa-11.0.6.tar.gz
8340e64cdc91999840404c211496f3de38e7b4cb38db34e2f72f1642c5134760 mesa-11.0.6.tar.xz
</pre> </pre>

View File

@ -0,0 +1,154 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Mesa Release Notes</title>
<link rel="stylesheet" type="text/css" href="../mesa.css">
</head>
<body>
<div class="header">
<h1>The Mesa 3D Graphics Library</h1>
</div>
<iframe src="../contents.html"></iframe>
<div class="content">
<h1>Mesa 11.0.7 Release Notes / December 9, 2015</h1>
<p>
Mesa 11.0.7 is a bug fix release which fixes bugs found since the 11.0.6 release.
</p>
<p>
Mesa 11.0.7 implements the OpenGL 4.1 API, but the version reported by
glGetString(GL_VERSION) or glGetIntegerv(GL_MAJOR_VERSION) /
glGetIntegerv(GL_MINOR_VERSION) depends on the particular driver being used.
Some drivers don't support all the features required in OpenGL 4.1. OpenGL
4.1 is <strong>only</strong> available if requested at context creation
because compatibility contexts are not supported.
</p>
<h2>SHA256 checksums</h2>
<pre>
07c27004ff68b288097d17b2faa7bdf15ec73c96b7e6c9835266e544adf0a62f mesa-11.0.7.tar.gz
e7e90a332ede6c8fd08eff90786a3fd1605a4e62ebf3a9b514047838194538cb mesa-11.0.7.tar.xz
</pre>
<h2>New features</h2>
<p>None</p>
<h2>Bug fixes</h2>
<p>This list is likely incomplete.</p>
<ul>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90348">Bug 90348</a> - Spilling failure of b96 merged value</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=92363">Bug 92363</a> - [BSW/BDW] ogles1conform Gets test fails</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=92438">Bug 92438</a> - Segfault in pushbuf_kref when running the android emulator (qemu) on nv50</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=93110">Bug 93110</a> - [NVE4] textureSize() and textureQueryLevels() uses a texture bound during the previous draw call</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=93126">Bug 93126</a> - wrongly claim supporting GL_EXT_texture_rg</li>
</ul>
<h2>Changes</h2>
<p>Chris Wilson (1):</p>
<ul>
<li>meta: Compute correct buffer size with SkipRows/SkipPixels</li>
</ul>
<p>Daniel Stone (1):</p>
<ul>
<li>egl/wayland: Ignore rects from SwapBuffersWithDamage</li>
</ul>
<p>Dave Airlie (4):</p>
<ul>
<li>texgetimage: consolidate 1D array handling code.</li>
<li>r600: geometry shader gsvs itemsize workaround</li>
<li>r600: rv670 use at least 16es/gs threads</li>
<li>r600: workaround empty geom shader.</li>
</ul>
<p>Emil Velikov (4):</p>
<ul>
<li>docs: add sha256 checksums for 11.0.6</li>
<li>get-pick-list.sh: Require explicit "11.0" for nominating stable patches</li>
<li>mesa; add get-extra-pick-list.sh script into bin/</li>
<li>Update version to 11.0.7</li>
</ul>
<p>François Tigeot (1):</p>
<ul>
<li>xmlconfig: Add support for DragonFly</li>
</ul>
<p>Ian Romanick (22):</p>
<ul>
<li>mesa: Make bind_vertex_buffer avilable outside varray.c</li>
<li>mesa: Refactor update_array_format to make _mesa_update_array_format_public</li>
<li>mesa: Refactor enable_vertex_array_attrib to make _mesa_enable_vertex_array_attrib</li>
<li>i965: Pass brw_context instead of gl_context to brw_draw_rectlist</li>
<li>i965: Use DSA functions for VBOs in brw_meta_fast_clear</li>
<li>i965: Use internal functions for buffer object access</li>
<li>i965: Don't pollute the buffer object namespace in brw_meta_fast_clear</li>
<li>meta: Use DSA functions for PBO in create_texture_for_pbo</li>
<li>meta: Use _mesa_NamedBufferData and _mesa_NamedBufferSubData for users of _mesa_meta_setup_vertex_objects</li>
<li>i965: Use _mesa_NamedBufferSubData for users of _mesa_meta_setup_vertex_objects</li>
<li>meta: Don't leave the VBO bound after _mesa_meta_setup_vertex_objects</li>
<li>meta: Track VBO using gl_buffer_object instead of GL API object handle</li>
<li>meta: Use DSA functions for VBOs in _mesa_meta_setup_vertex_objects</li>
<li>meta: Use internal functions for buffer object and VAO access</li>
<li>meta: Don't pollute the buffer object namespace in _mesa_meta_setup_vertex_objects</li>
<li>meta: Partially convert _mesa_meta_DrawTex to DSA</li>
<li>meta: Track VBO using gl_buffer_object instead of GL API object handle in _mesa_meta_DrawTex</li>
<li>meta: Use internal functions for buffer object and VAO access in _mesa_meta_DrawTex</li>
<li>meta: Don't pollute the buffer object namespace in _mesa_meta_DrawTex</li>
<li>meta/TexSubImage: Don't pollute the buffer object namespace</li>
<li>meta/generate_mipmap: Don't leak the framebuffer object</li>
<li>glsl: Fix off-by-one error in array size check assertion</li>
</ul>
<p>Ilia Mirkin (7):</p>
<ul>
<li>nvc0/ir: actually emit AFETCH on kepler</li>
<li>nir: fix typo in idiv lowering, causing large-udiv-udiv failures</li>
<li>nouveau: use the buffer usage to determine placement when no binding</li>
<li>nv50,nvc0: properly handle buffer storage invalidation on dsa buffer</li>
<li>nv50/ir: fix (un)spilling of 3-wide results</li>
<li>mesa: support GL_RED/GL_RG in ES2 contexts when driver support exists</li>
<li>nvc0/ir: start offset at texBindBase for txq, like regular texturing</li>
</ul>
<p>Jonathan Gray (1):</p>
<ul>
<li>automake: fix some occurrences of hardcoded -ldl and -lpthread</li>
</ul>
<p>Leo Liu (1):</p>
<ul>
<li>radeon/vce: disable Stoney VCE for 11.0</li>
</ul>
<p>Marta Lofstedt (1):</p>
<ul>
<li>gles2: Update gl2ext.h to revision: 32120</li>
</ul>
<p>Oded Gabbay (1):</p>
<ul>
<li>llvmpipe: disable VSX in ppc due to LLVM PPC bug</li>
</ul>
</div>
</body>
</html>

View File

@ -0,0 +1,199 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Mesa Release Notes</title>
<link rel="stylesheet" type="text/css" href="../mesa.css">
</head>
<body>
<div class="header">
<h1>The Mesa 3D Graphics Library</h1>
</div>
<iframe src="../contents.html"></iframe>
<div class="content">
<h1>Mesa 11.0.8 Release Notes / December 9, 2015</h1>
<p>
Mesa 11.0.8 is a bug fix release which fixes bugs found since the 11.0.7 release.
</p>
<p>
Mesa 11.0.8 implements the OpenGL 4.1 API, but the version reported by
glGetString(GL_VERSION) or glGetIntegerv(GL_MAJOR_VERSION) /
glGetIntegerv(GL_MINOR_VERSION) depends on the particular driver being used.
Some drivers don't support all the features required in OpenGL 4.1. OpenGL
4.1 is <strong>only</strong> available if requested at context creation
because compatibility contexts are not supported.
</p>
<h2>SHA256 checksums</h2>
<pre>
TBD
</pre>
<h2>New features</h2>
<p>None</p>
<h2>Bug fixes</h2>
<p>This list is likely incomplete.</p>
<ul>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91806">Bug 91806</a> - configure does not test whether assembler supports sse4.1</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=92849">Bug 92849</a> - [IVB HSW BDW] piglit image load/store load-from-cleared-image.shader_test fails</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=92909">Bug 92909</a> - Offset/alignment issue with layout std140 and vec3</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=93004">Bug 93004</a> - Guild Wars 2 crash on nouveau DX11 cards</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=93215">Bug 93215</a> - [Regression bisected] Ogles1conform Automatic mipmap generation test is fail</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=93266">Bug 93266</a> - gl_arb_shading_language_420pack does not allow binding of image variables</li>
</ul>
<h2>Changes</h2>
<p>Boyuan Zhang (1):</p>
<ul>
<li>radeon/uvd: uv pitch separation for stoney</li>
</ul>
<p>Dave Airlie (9):</p>
<ul>
<li>r600: do SQ flush ES ring rolling workaround</li>
<li>r600: SMX returns CONTEXT_DONE early workaround</li>
<li>r600/shader: split address get out to a function.</li>
<li>r600/shader: add utility functions to do single slot arithmatic</li>
<li>r600g: fix geom shader input indirect indexing.</li>
<li>r600: handle geometry dynamic input array index</li>
<li>radeonsi: handle doubles in lds load path.</li>
<li>mesa/varray: set double arrays to non-normalised.</li>
<li>mesa/shader: return correct attribute location for double matrix arrays</li>
</ul>
<p>Emil Velikov (8):</p>
<ul>
<li>docs: add sha256 checksums for 11.0.7</li>
<li>cherry-ignore: don't pick a specific i965 formats patch</li>
<li>Revert "i965/nir: Remove unused indirect handling"</li>
<li>Revert "i965/state: Get rid of dword_pitch arguments to buffer functions"</li>
<li>Revert "i965/vec4: Use a stride of 1 and byte offsets for UBOs"</li>
<li>Revert "i965/fs: Use a stride of 1 and byte offsets for UBOs"</li>
<li>Revert "i965/vec4: Use byte offsets for UBO pulls on Sandy Bridge"</li>
<li>Update version to 11.0.8</li>
</ul>
<p>Francisco Jerez (1):</p>
<ul>
<li>i965: Resolve color and flush for all active shader images in intel_update_state().</li>
</ul>
<p>Ian Romanick (1):</p>
<ul>
<li>meta/generate_mipmap: Work-around GLES 1.x problem with GL_DRAW_FRAMEBUFFER</li>
</ul>
<p>Ilia Mirkin (17):</p>
<ul>
<li>freedreno/a4xx: support lod_bias</li>
<li>freedreno/a4xx: fix 5_5_5_1 texture sampler format</li>
<li>freedreno/a4xx: point regid to "red" even for alpha-only rb formats</li>
<li>nvc0/ir: fold postfactor into immediate</li>
<li>nv50/ir: deal with loops with no breaks</li>
<li>nv50/ir: the mad source might not have a defining instruction</li>
<li>nv50/ir: fix instruction permutation logic</li>
<li>nv50/ir: don't forget to mark flagsDef on cvt in txb lowering</li>
<li>nv50/ir: fix DCE to not generate 96-bit loads</li>
<li>nv50/ir: avoid looking at uninitialized srcMods entries</li>
<li>gk110/ir: fix imul hi emission with limm arg</li>
<li>gk104/ir: sampler doesn't matter for txf</li>
<li>gk110/ir: fix imad sat/hi flag emission for immediate args</li>
<li>nv50/ir: fix cutoff for using r63 vs r127 when replacing zero</li>
<li>nv50/ir: can't have predication and immediates</li>
<li>glsl: assign varying locations to tess shaders when doing SSO</li>
<li>ttn: add TEX2 support</li>
</ul>
<p>Jason Ekstrand (5):</p>
<ul>
<li>i965/vec4: Use byte offsets for UBO pulls on Sandy Bridge</li>
<li>i965/fs: Use a stride of 1 and byte offsets for UBOs</li>
<li>i965/vec4: Use a stride of 1 and byte offsets for UBOs</li>
<li>i965/state: Get rid of dword_pitch arguments to buffer functions</li>
<li>i965/nir: Remove unused indirect handling</li>
</ul>
<p>Jonathan Gray (2):</p>
<ul>
<li>configure.ac: use pkg-config for libelf</li>
<li>configure: check for python2.7 for PYTHON2</li>
</ul>
<p>Kenneth Graunke (2):</p>
<ul>
<li>i965: Fix fragment shader struct inputs.</li>
<li>i965: Fix scalar vertex shader struct outputs.</li>
</ul>
<p>Marek Olšák (8):</p>
<ul>
<li>radeonsi: fix occlusion queries on Fiji</li>
<li>radeonsi: fix a hang due to uninitialized border color registers</li>
<li>radeonsi: fix Fiji for LLVM &lt;= 3.7</li>
<li>radeonsi: don't call of u_prims_for_vertices for patches and rectangles</li>
<li>radeonsi: apply the streamout workaround to Fiji as well</li>
<li>gallium/radeon: fix Hyper-Z hangs by programming PA_SC_MODE_CNTL_1 correctly</li>
<li>tgsi/scan: add flag colors_written</li>
<li>r600g: write all MRTs only if there is exactly one output (fixes a hang)</li>
</ul>
<p>Matt Turner (1):</p>
<ul>
<li>glsl: Allow binding of image variables with 420pack.</li>
</ul>
<p>Neil Roberts (2):</p>
<ul>
<li>i965: Add MESA_FORMAT_B8G8R8X8_SRGB to brw_format_for_mesa_format</li>
<li>i965: Add B8G8R8X8_SRGB to the alpha format override</li>
</ul>
<p>Oded Gabbay (1):</p>
<ul>
<li>configura.ac: fix test for SSE4.1 assembler support</li>
</ul>
<p>Patrick Rudolph (2):</p>
<ul>
<li>nv50,nvc0: fix use-after-free when vertex buffers are unbound</li>
<li>gallium/util: return correct number of bound vertex buffers</li>
</ul>
<p>Samuel Pitoiset (1):</p>
<ul>
<li>nvc0: free memory allocated by the prog which reads MP perf counters</li>
</ul>
<p>Tapani Pälli (1):</p>
<ul>
<li>i965: use _Shader to get fragment program when updating surface state</li>
</ul>
<p>Tom Stellard (2):</p>
<ul>
<li>radeonsi: Rename si_shader::ls_rsrc{1,2} to si_shader::rsrc{1,2}</li>
<li>radeonsi/compute: Use the compiler's COMPUTE_PGM_RSRC* register values</li>
</ul>
</div>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@ -703,18 +703,10 @@ dri2_wl_swap_buffers_with_damage(_EGLDriver *drv,
dri2_surf->dx = 0; dri2_surf->dx = 0;
dri2_surf->dy = 0; dri2_surf->dy = 0;
if (n_rects == 0) { /* We deliberately ignore the damage region and post maximum damage, due to
wl_surface_damage(dri2_surf->wl_win->surface, * https://bugs.freedesktop.org/78190 */
0, 0, INT32_MAX, INT32_MAX); wl_surface_damage(dri2_surf->wl_win->surface,
} else { 0, 0, INT32_MAX, INT32_MAX);
for (i = 0; i < n_rects; i++) {
const int *rect = &rects[i * 4];
wl_surface_damage(dri2_surf->wl_win->surface,
rect[0],
dri2_surf->base.Height - rect[1] - rect[3],
rect[2], rect[3]);
}
}
if (dri2_dpy->is_different_gpu) { if (dri2_dpy->is_different_gpu) {
_EGLContext *ctx = _eglGetCurrentContext(); _EGLContext *ctx = _eglGetCurrentContext();

View File

@ -536,6 +536,15 @@ lp_build_create_jit_compiler_for_module(LLVMExecutionEngineRef *OutJIT,
#if defined(PIPE_ARCH_PPC) #if defined(PIPE_ARCH_PPC)
MAttrs.push_back(util_cpu_caps.has_altivec ? "+altivec" : "-altivec"); MAttrs.push_back(util_cpu_caps.has_altivec ? "+altivec" : "-altivec");
#if HAVE_LLVM >= 0x0304
/*
* Make sure VSX instructions are disabled
* See LLVM bug https://llvm.org/bugs/show_bug.cgi?id=25503#c7
*/
if (util_cpu_caps.has_altivec) {
MAttrs.push_back("-vsx");
}
#endif
#endif #endif
builder.setMAttrs(MAttrs); builder.setMAttrs(MAttrs);

View File

@ -1087,6 +1087,11 @@ ttn_tex(struct ttn_compile *c, nir_alu_dest dest, nir_ssa_def **src)
op = nir_texop_tex; op = nir_texop_tex;
num_srcs = 1; num_srcs = 1;
break; break;
case TGSI_OPCODE_TEX2:
op = nir_texop_tex;
num_srcs = 1;
samp = 2;
break;
case TGSI_OPCODE_TXP: case TGSI_OPCODE_TXP:
op = nir_texop_tex; op = nir_texop_tex;
num_srcs = 2; num_srcs = 2;
@ -1242,10 +1247,12 @@ ttn_tex(struct ttn_compile *c, nir_alu_dest dest, nir_ssa_def **src)
} }
if (instr->is_shadow) { if (instr->is_shadow) {
if (instr->coord_components < 3) if (instr->coord_components == 4)
instr->src[src_number].src = nir_src_for_ssa(ttn_channel(b, src[0], Z)); instr->src[src_number].src = nir_src_for_ssa(ttn_channel(b, src[1], X));
else else if (instr->coord_components == 3)
instr->src[src_number].src = nir_src_for_ssa(ttn_channel(b, src[0], W)); instr->src[src_number].src = nir_src_for_ssa(ttn_channel(b, src[0], W));
else
instr->src[src_number].src = nir_src_for_ssa(ttn_channel(b, src[0], Z));
instr->src[src_number].src_type = nir_tex_src_comparitor; instr->src[src_number].src_type = nir_tex_src_comparitor;
src_number++; src_number++;
@ -1651,6 +1658,7 @@ ttn_emit_instruction(struct ttn_compile *c)
case TGSI_OPCODE_TXL: case TGSI_OPCODE_TXL:
case TGSI_OPCODE_TXB: case TGSI_OPCODE_TXB:
case TGSI_OPCODE_TXD: case TGSI_OPCODE_TXD:
case TGSI_OPCODE_TEX2:
case TGSI_OPCODE_TXL2: case TGSI_OPCODE_TXL2:
case TGSI_OPCODE_TXB2: case TGSI_OPCODE_TXB2:
case TGSI_OPCODE_TXQ_LZ: case TGSI_OPCODE_TXQ_LZ:

View File

@ -258,6 +258,9 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
info->output_semantic_index[reg] = (ubyte) semIndex; info->output_semantic_index[reg] = (ubyte) semIndex;
info->num_outputs++; info->num_outputs++;
if (semName == TGSI_SEMANTIC_COLOR)
info->colors_written |= 1 << semIndex;
if (procType == TGSI_PROCESSOR_VERTEX || if (procType == TGSI_PROCESSOR_VERTEX ||
procType == TGSI_PROCESSOR_GEOMETRY || procType == TGSI_PROCESSOR_GEOMETRY ||
procType == TGSI_PROCESSOR_TESS_CTRL || procType == TGSI_PROCESSOR_TESS_CTRL ||

View File

@ -76,6 +76,7 @@ struct tgsi_shader_info
uint opcode_count[TGSI_OPCODE_LAST]; /**< opcode histogram */ uint opcode_count[TGSI_OPCODE_LAST]; /**< opcode histogram */
ubyte colors_written;
boolean reads_position; /**< does fragment shader read position? */ boolean reads_position; /**< does fragment shader read position? */
boolean reads_z; /**< does fragment shader read depth? */ boolean reads_z; /**< does fragment shader read depth? */
boolean writes_z; /**< does fragment shader write Z value? */ boolean writes_z; /**< does fragment shader write Z value? */

View File

@ -81,7 +81,13 @@ void util_set_vertex_buffers_count(struct pipe_vertex_buffer *dst,
const struct pipe_vertex_buffer *src, const struct pipe_vertex_buffer *src,
unsigned start_slot, unsigned count) unsigned start_slot, unsigned count)
{ {
uint32_t enabled_buffers = (1ull << *dst_count) - 1; unsigned i;
uint32_t enabled_buffers = 0;
for (i = 0; i < *dst_count; i++) {
if (dst[i].buffer || dst[i].user_buffer)
enabled_buffers |= (1ull << i);
}
util_set_vertex_buffers_mask(dst, &enabled_buffers, src, start_slot, util_set_vertex_buffers_mask(dst, &enabled_buffers, src, start_slot,
count); count);

View File

@ -153,7 +153,7 @@ enum a4xx_vtx_fmt {
enum a4xx_tex_fmt { enum a4xx_tex_fmt {
TFMT4_5_6_5_UNORM = 11, TFMT4_5_6_5_UNORM = 11,
TFMT4_5_5_5_1_UNORM = 10, TFMT4_5_5_5_1_UNORM = 9,
TFMT4_4_4_4_4_UNORM = 8, TFMT4_4_4_4_4_UNORM = 8,
TFMT4_X8Z24_UNORM = 71, TFMT4_X8Z24_UNORM = 71,
TFMT4_10_10_10_2_UNORM = 33, TFMT4_10_10_10_2_UNORM = 33,
@ -2718,6 +2718,12 @@ static inline uint32_t A4XX_TEX_SAMP_0_ANISO(enum a4xx_tex_aniso val)
{ {
return ((val) << A4XX_TEX_SAMP_0_ANISO__SHIFT) & A4XX_TEX_SAMP_0_ANISO__MASK; return ((val) << A4XX_TEX_SAMP_0_ANISO__SHIFT) & A4XX_TEX_SAMP_0_ANISO__MASK;
} }
#define A4XX_TEX_SAMP_0_LOD_BIAS__MASK 0xfff80000
#define A4XX_TEX_SAMP_0_LOD_BIAS__SHIFT 19
static inline uint32_t A4XX_TEX_SAMP_0_LOD_BIAS(float val)
{
return ((((int32_t)(val * 256.0))) << A4XX_TEX_SAMP_0_LOD_BIAS__SHIFT) & A4XX_TEX_SAMP_0_LOD_BIAS__MASK;
}
#define REG_A4XX_TEX_SAMP_1 0x00000001 #define REG_A4XX_TEX_SAMP_1 0x00000001
#define A4XX_TEX_SAMP_1_COMPARE_FUNC__MASK 0x0000000e #define A4XX_TEX_SAMP_1_COMPARE_FUNC__MASK 0x0000000e

View File

@ -250,14 +250,6 @@ fd4_program_emit(struct fd_ringbuffer *ring, struct fd4_emit *emit,
} }
} }
/* adjust regids for alpha output formats. there is no alpha render
* format, so it's just treated like red
*/
for (i = 0; i < nr; i++)
if (util_format_is_alpha(pipe_surface_format(bufs[i])))
color_regid[i] += 3;
/* TODO get these dynamically: */ /* TODO get these dynamically: */
face_regid = s[FS].v->frag_face ? regid(0,0) : regid(63,0); face_regid = s[FS].v->frag_face ? regid(0,0) : regid(63,0);
coord_regid = s[FS].v->frag_coord ? regid(0,0) : regid(63,0); coord_regid = s[FS].v->frag_coord ? regid(0,0) : regid(63,0);

View File

@ -111,6 +111,7 @@ fd4_sampler_state_create(struct pipe_context *pctx,
COND(!cso->normalized_coords, A4XX_TEX_SAMP_1_UNNORM_COORDS); COND(!cso->normalized_coords, A4XX_TEX_SAMP_1_UNNORM_COORDS);
if (cso->min_mip_filter != PIPE_TEX_MIPFILTER_NONE) { if (cso->min_mip_filter != PIPE_TEX_MIPFILTER_NONE) {
so->texsamp0 |= A4XX_TEX_SAMP_0_LOD_BIAS(cso->lod_bias);
so->texsamp1 |= so->texsamp1 |=
A4XX_TEX_SAMP_1_MIN_LOD(cso->min_lod) | A4XX_TEX_SAMP_1_MIN_LOD(cso->min_lod) |
A4XX_TEX_SAMP_1_MAX_LOD(cso->max_lod); A4XX_TEX_SAMP_1_MAX_LOD(cso->max_lod);

View File

@ -291,7 +291,7 @@ void BasicBlock::permuteAdjacent(Instruction *a, Instruction *b)
if (b->prev) if (b->prev)
b->prev->next = b; b->prev->next = b;
if (a->prev) if (a->next)
a->next->prev = a; a->next->prev = a;
} }

View File

@ -575,8 +575,8 @@ CodeEmitterGK110::emitIMUL(const Instruction *i)
if (isLIMM(i->src(1), TYPE_S32)) { if (isLIMM(i->src(1), TYPE_S32)) {
emitForm_L(i, 0x280, 2, Modifier(0)); emitForm_L(i, 0x280, 2, Modifier(0));
assert(i->subOp != NV50_IR_SUBOP_MUL_HIGH); if (i->subOp == NV50_IR_SUBOP_MUL_HIGH)
code[1] |= 1 << 24;
if (i->sType == TYPE_S32) if (i->sType == TYPE_S32)
code[1] |= 3 << 25; code[1] |= 3 << 25;
} else { } else {
@ -695,14 +695,9 @@ CodeEmitterGK110::emitIMAD(const Instruction *i)
if (i->sType == TYPE_S32) if (i->sType == TYPE_S32)
code[1] |= (1 << 19) | (1 << 24); code[1] |= (1 << 19) | (1 << 24);
if (code[0] & 0x1) { if (i->subOp == NV50_IR_SUBOP_MUL_HIGH)
assert(!i->subOp); code[1] |= 1 << 25;
SAT_(39); SAT_(35);
} else {
if (i->subOp == NV50_IR_SUBOP_MUL_HIGH)
code[1] |= 1 << 25;
SAT_(35);
}
} }
void void

View File

@ -2322,6 +2322,9 @@ CodeEmitterNVC0::emitInstruction(Instruction *insn)
case OP_PFETCH: case OP_PFETCH:
emitPFETCH(insn); emitPFETCH(insn);
break; break;
case OP_AFETCH:
emitAFETCH(insn);
break;
case OP_EMIT: case OP_EMIT:
case OP_RESTART: case OP_RESTART:
emitOUT(insn); emitOUT(insn);

View File

@ -2870,6 +2870,12 @@ Converter::handleInstruction(const struct tgsi_full_instruction *insn)
bb->cfg.attach(&loopBB->cfg, Graph::Edge::BACK); bb->cfg.attach(&loopBB->cfg, Graph::Edge::BACK);
} }
setPosition(reinterpret_cast<BasicBlock *>(breakBBs.pop().u.p), true); setPosition(reinterpret_cast<BasicBlock *>(breakBBs.pop().u.p), true);
// If the loop never breaks (e.g. only has RET's inside), then there
// will be no way to get to the break bb. However BGNLOOP will have
// already made a PREBREAK to it, so it must be in the CFG.
if (getBB()->cfg.incidentCount() == 0)
loopBB->cfg.attach(&getBB()->cfg, Graph::Edge::TREE);
} }
break; break;
case TGSI_OPCODE_BRK: case TGSI_OPCODE_BRK:

View File

@ -202,7 +202,8 @@ NV50LegalizePostRA::visit(Function *fn)
Program *prog = fn->getProgram(); Program *prog = fn->getProgram();
r63 = new_LValue(fn, FILE_GPR); r63 = new_LValue(fn, FILE_GPR);
if (prog->maxGPR < 63) // GPR units on nv50 are in half-regs
if (prog->maxGPR < 126)
r63->reg.data.id = 63; r63->reg.data.id = 63;
else else
r63->reg.data.id = 127; r63->reg.data.id = 127;
@ -831,7 +832,7 @@ NV50LoweringPreSSA::handleTXB(TexInstruction *i)
} }
Value *flags = bld.getScratch(1, FILE_FLAGS); Value *flags = bld.getScratch(1, FILE_FLAGS);
bld.setPosition(cond, true); bld.setPosition(cond, true);
bld.mkCvt(OP_CVT, TYPE_U8, flags, TYPE_U32, cond->getDef(0)); bld.mkCvt(OP_CVT, TYPE_U8, flags, TYPE_U32, cond->getDef(0))->flagsDef = 0;
Instruction *tex[4]; Instruction *tex[4];
for (l = 0; l < 4; ++l) { for (l = 0; l < 4; ++l) {

View File

@ -686,7 +686,7 @@ NVC0LoweringPass::handleTEX(TexInstruction *i)
i->tex.s = 0x1f; i->tex.s = 0x1f;
i->setIndirectR(hnd); i->setIndirectR(hnd);
i->setIndirectS(NULL); i->setIndirectS(NULL);
} else if (i->tex.r == i->tex.s) { } else if (i->tex.r == i->tex.s || i->op == OP_TXF) {
i->tex.r += prog->driver->io.texBindBase / 4; i->tex.r += prog->driver->io.texBindBase / 4;
i->tex.s = 0; // only a single cX[] value possible here i->tex.s = 0; // only a single cX[] value possible here
} else { } else {
@ -962,11 +962,14 @@ NVC0LoweringPass::handleTXD(TexInstruction *txd)
bool bool
NVC0LoweringPass::handleTXQ(TexInstruction *txq) NVC0LoweringPass::handleTXQ(TexInstruction *txq)
{ {
const int chipset = prog->getTarget()->getChipset();
if (chipset >= NVISA_GK104_CHIPSET && txq->tex.rIndirectSrc < 0)
txq->tex.r += prog->driver->io.texBindBase / 4;
if (txq->tex.rIndirectSrc < 0) if (txq->tex.rIndirectSrc < 0)
return true; return true;
Value *ticRel = txq->getIndirectR(); Value *ticRel = txq->getIndirectR();
const int chipset = prog->getTarget()->getChipset();
txq->setIndirectS(NULL); txq->setIndirectS(NULL);
txq->tex.sIndirectSrc = -1; txq->tex.sIndirectSrc = -1;

View File

@ -842,6 +842,12 @@ ConstantFolding::opnd(Instruction *i, ImmediateValue &imm0, int s)
i->src(0).mod = i->src(t).mod; i->src(0).mod = i->src(t).mod;
i->setSrc(1, new_ImmediateValue(prog, imm0.reg.data.u32)); i->setSrc(1, new_ImmediateValue(prog, imm0.reg.data.u32));
i->src(1).mod = 0; i->src(1).mod = 0;
} else
if (i->postFactor && i->sType == TYPE_F32) {
/* Can't emit a postfactor with an immediate, have to fold it in */
i->setSrc(s, new_ImmediateValue(
prog, imm0.reg.data.f32 * exp2f(i->postFactor)));
i->postFactor = 0;
} }
break; break;
case OP_MAD: case OP_MAD:
@ -2606,8 +2612,11 @@ NV50PostRaConstantFolding::visit(BasicBlock *bb)
i->getSrc(0)->reg.data.id >= 64) i->getSrc(0)->reg.data.id >= 64)
break; break;
if (i->getPredicate())
break;
def = i->getSrc(1)->getInsn(); def = i->getSrc(1)->getInsn();
if (def->op == OP_MOV && def->src(0).getFile() == FILE_IMMEDIATE) { if (def && def->op == OP_MOV && def->src(0).getFile() == FILE_IMMEDIATE) {
vtmp = i->getSrc(1); vtmp = i->getSrc(1);
i->setSrc(1, def->getSrc(0)); i->setSrc(1, def->getSrc(0));
@ -2909,6 +2918,16 @@ DeadCodeElim::visit(BasicBlock *bb)
return true; return true;
} }
// Each load can go into up to 4 destinations, any of which might potentially
// be dead (i.e. a hole). These can always be split into 2 loads, independent
// of where the holes are. We find the first contiguous region, put it into
// the first load, and then put the second contiguous region into the second
// load. There can be at most 2 contiguous regions.
//
// Note that there are some restrictions, for example it's not possible to do
// a 64-bit load that's not 64-bit aligned, so such a load has to be split
// up. Also hardware doesn't support 96-bit loads, so those also have to be
// split into a 64-bit and 32-bit load.
void void
DeadCodeElim::checkSplitLoad(Instruction *ld1) DeadCodeElim::checkSplitLoad(Instruction *ld1)
{ {
@ -2929,6 +2948,8 @@ DeadCodeElim::checkSplitLoad(Instruction *ld1)
addr1 = ld1->getSrc(0)->reg.data.offset; addr1 = ld1->getSrc(0)->reg.data.offset;
n1 = n2 = 0; n1 = n2 = 0;
size1 = size2 = 0; size1 = size2 = 0;
// Compute address/width for first load
for (d = 0; ld1->defExists(d); ++d) { for (d = 0; ld1->defExists(d); ++d) {
if (mask & (1 << d)) { if (mask & (1 << d)) {
if (size1 && (addr1 & 0x7)) if (size1 && (addr1 & 0x7))
@ -2942,16 +2963,34 @@ DeadCodeElim::checkSplitLoad(Instruction *ld1)
break; break;
} }
} }
// Scale back the size of the first load until it can be loaded. This
// typically happens for TYPE_B96 loads.
while (n1 &&
!prog->getTarget()->isAccessSupported(ld1->getSrc(0)->reg.file,
typeOfSize(size1))) {
size1 -= def1[--n1]->reg.size;
d--;
}
// Compute address/width for second load
for (addr2 = addr1 + size1; ld1->defExists(d); ++d) { for (addr2 = addr1 + size1; ld1->defExists(d); ++d) {
if (mask & (1 << d)) { if (mask & (1 << d)) {
assert(!size2 || !(addr2 & 0x7));
def2[n2] = ld1->getDef(d); def2[n2] = ld1->getDef(d);
size2 += def2[n2++]->reg.size; size2 += def2[n2++]->reg.size;
} else { } else if (!n2) {
assert(!n2); assert(!n2);
addr2 += ld1->getDef(d)->reg.size; addr2 += ld1->getDef(d)->reg.size;
} else {
break;
} }
} }
// Make sure that we've processed all the values
for (; ld1->defExists(d); ++d)
assert(!(mask & (1 << d)));
updateLdStOffset(ld1, addr1, func); updateLdStOffset(ld1, addr1, func);
ld1->setType(typeOfSize(size1)); ld1->setType(typeOfSize(size1));
for (d = 0; d < 4; ++d) for (d = 0; d < 4; ++d)

View File

@ -1573,10 +1573,28 @@ SpillCodeInserter::spill(Instruction *defi, Value *slot, LValue *lval)
Instruction *st; Instruction *st;
if (slot->reg.file == FILE_MEMORY_LOCAL) { if (slot->reg.file == FILE_MEMORY_LOCAL) {
st = new_Instruction(func, OP_STORE, ty);
st->setSrc(0, slot);
st->setSrc(1, lval);
lval->noSpill = 1; lval->noSpill = 1;
if (ty != TYPE_B96) {
st = new_Instruction(func, OP_STORE, ty);
st->setSrc(0, slot);
st->setSrc(1, lval);
} else {
st = new_Instruction(func, OP_SPLIT, ty);
st->setSrc(0, lval);
for (int d = 0; d < lval->reg.size / 4; ++d)
st->setDef(d, new_LValue(func, FILE_GPR));
for (int d = lval->reg.size / 4 - 1; d >= 0; --d) {
Value *tmp = cloneShallow(func, slot);
tmp->reg.size = 4;
tmp->reg.data.offset += 4 * d;
Instruction *s = new_Instruction(func, OP_STORE, TYPE_U32);
s->setSrc(0, tmp);
s->setSrc(1, st->getDef(d));
defi->bb->insertAfter(defi, s);
}
}
} else { } else {
st = new_Instruction(func, OP_CVT, ty); st = new_Instruction(func, OP_CVT, ty);
st->setDef(0, slot); st->setDef(0, slot);
@ -1596,7 +1614,27 @@ SpillCodeInserter::unspill(Instruction *usei, LValue *lval, Value *slot)
Instruction *ld; Instruction *ld;
if (slot->reg.file == FILE_MEMORY_LOCAL) { if (slot->reg.file == FILE_MEMORY_LOCAL) {
lval->noSpill = 1; lval->noSpill = 1;
ld = new_Instruction(func, OP_LOAD, ty); if (ty != TYPE_B96) {
ld = new_Instruction(func, OP_LOAD, ty);
} else {
ld = new_Instruction(func, OP_MERGE, ty);
for (int d = 0; d < lval->reg.size / 4; ++d) {
Value *tmp = cloneShallow(func, slot);
LValue *val;
tmp->reg.size = 4;
tmp->reg.data.offset += 4 * d;
Instruction *l = new_Instruction(func, OP_LOAD, TYPE_U32);
l->setDef(0, (val = new_LValue(func, FILE_GPR)));
l->setSrc(0, tmp);
usei->bb->insertBefore(usei, l);
ld->setSrc(d, val);
val->noSpill = 1;
}
ld->setDef(0, lval);
usei->bb->insertBefore(usei, ld);
return lval;
}
} else { } else {
ld = new_Instruction(func, OP_CVT, ty); ld = new_Instruction(func, OP_CVT, ty);
} }

View File

@ -454,7 +454,7 @@ TargetNV50::isModSupported(const Instruction *insn, int s, Modifier mod) const
return false; return false;
} }
} }
if (s >= 3) if (s >= opInfo[insn->op].srcNr || s >= 3)
return false; return false;
return (mod & Modifier(opInfo[insn->op].srcMods[s])) == mod; return (mod & Modifier(opInfo[insn->op].srcMods[s])) == mod;
} }

View File

@ -426,7 +426,7 @@ TargetNVC0::isModSupported(const Instruction *insn, int s, Modifier mod) const
return false; return false;
} }
} }
if (s >= 3) if (s >= opInfo[insn->op].srcNr || s >= 3)
return false; return false;
return (mod & Modifier(opInfo[insn->op].srcMods[s])) == mod; return (mod & Modifier(opInfo[insn->op].srcMods[s])) == mod;
} }

View File

@ -656,8 +656,8 @@ nouveau_buffer_create(struct pipe_screen *pscreen,
if (buffer->base.flags & (PIPE_RESOURCE_FLAG_MAP_PERSISTENT | if (buffer->base.flags & (PIPE_RESOURCE_FLAG_MAP_PERSISTENT |
PIPE_RESOURCE_FLAG_MAP_COHERENT)) { PIPE_RESOURCE_FLAG_MAP_COHERENT)) {
buffer->domain = NOUVEAU_BO_GART; buffer->domain = NOUVEAU_BO_GART;
} else if (buffer->base.bind & } else if (buffer->base.bind == 0 || (buffer->base.bind &
(screen->vidmem_bindings & screen->sysmem_bindings)) { (screen->vidmem_bindings & screen->sysmem_bindings))) {
switch (buffer->base.usage) { switch (buffer->base.usage) {
case PIPE_USAGE_DEFAULT: case PIPE_USAGE_DEFAULT:
case PIPE_USAGE_IMMUTABLE: case PIPE_USAGE_IMMUTABLE:
@ -684,6 +684,10 @@ nouveau_buffer_create(struct pipe_screen *pscreen,
if (buffer->base.bind & screen->sysmem_bindings) if (buffer->base.bind & screen->sysmem_bindings)
buffer->domain = NOUVEAU_BO_GART; buffer->domain = NOUVEAU_BO_GART;
} }
/* There can be very special situations where we want non-gpu-mapped
* buffers, but never through this interface.
*/
assert(buffer->domain);
ret = nouveau_buffer_allocate(screen, buffer, buffer->domain); ret = nouveau_buffer_allocate(screen, buffer, buffer->domain);
if (ret == false) if (ret == false)

View File

@ -159,9 +159,10 @@ nv50_invalidate_resource_storage(struct nouveau_context *ctx,
int ref) int ref)
{ {
struct nv50_context *nv50 = nv50_context(&ctx->pipe); struct nv50_context *nv50 = nv50_context(&ctx->pipe);
unsigned bind = res->bind ? res->bind : PIPE_BIND_VERTEX_BUFFER;
unsigned s, i; unsigned s, i;
if (res->bind & PIPE_BIND_RENDER_TARGET) { if (bind & PIPE_BIND_RENDER_TARGET) {
assert(nv50->framebuffer.nr_cbufs <= PIPE_MAX_COLOR_BUFS); assert(nv50->framebuffer.nr_cbufs <= PIPE_MAX_COLOR_BUFS);
for (i = 0; i < nv50->framebuffer.nr_cbufs; ++i) { for (i = 0; i < nv50->framebuffer.nr_cbufs; ++i) {
if (nv50->framebuffer.cbufs[i] && if (nv50->framebuffer.cbufs[i] &&
@ -173,7 +174,7 @@ nv50_invalidate_resource_storage(struct nouveau_context *ctx,
} }
} }
} }
if (res->bind & PIPE_BIND_DEPTH_STENCIL) { if (bind & PIPE_BIND_DEPTH_STENCIL) {
if (nv50->framebuffer.zsbuf && if (nv50->framebuffer.zsbuf &&
nv50->framebuffer.zsbuf->texture == res) { nv50->framebuffer.zsbuf->texture == res) {
nv50->dirty |= NV50_NEW_FRAMEBUFFER; nv50->dirty |= NV50_NEW_FRAMEBUFFER;
@ -183,11 +184,11 @@ nv50_invalidate_resource_storage(struct nouveau_context *ctx,
} }
} }
if (res->bind & (PIPE_BIND_VERTEX_BUFFER | if (bind & (PIPE_BIND_VERTEX_BUFFER |
PIPE_BIND_INDEX_BUFFER | PIPE_BIND_INDEX_BUFFER |
PIPE_BIND_CONSTANT_BUFFER | PIPE_BIND_CONSTANT_BUFFER |
PIPE_BIND_STREAM_OUTPUT | PIPE_BIND_STREAM_OUTPUT |
PIPE_BIND_SAMPLER_VIEW)) { PIPE_BIND_SAMPLER_VIEW)) {
assert(nv50->num_vtxbufs <= PIPE_MAX_ATTRIBS); assert(nv50->num_vtxbufs <= PIPE_MAX_ATTRIBS);
for (i = 0; i < nv50->num_vtxbufs; ++i) { for (i = 0; i < nv50->num_vtxbufs; ++i) {

View File

@ -960,6 +960,9 @@ nv50_set_vertex_buffers(struct pipe_context *pipe,
struct nv50_context *nv50 = nv50_context(pipe); struct nv50_context *nv50 = nv50_context(pipe);
unsigned i; unsigned i;
nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_VERTEX);
nv50->dirty |= NV50_NEW_ARRAYS;
util_set_vertex_buffers_count(nv50->vtxbuf, &nv50->num_vtxbufs, vb, util_set_vertex_buffers_count(nv50->vtxbuf, &nv50->num_vtxbufs, vb,
start_slot, count); start_slot, count);
@ -983,10 +986,6 @@ nv50_set_vertex_buffers(struct pipe_context *pipe,
nv50->vbo_constant &= ~(1 << dst_index); nv50->vbo_constant &= ~(1 << dst_index);
} }
} }
nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_VERTEX);
nv50->dirty |= NV50_NEW_ARRAYS;
} }
static void static void

View File

@ -180,9 +180,10 @@ nvc0_invalidate_resource_storage(struct nouveau_context *ctx,
int ref) int ref)
{ {
struct nvc0_context *nvc0 = nvc0_context(&ctx->pipe); struct nvc0_context *nvc0 = nvc0_context(&ctx->pipe);
unsigned bind = res->bind ? res->bind : PIPE_BIND_VERTEX_BUFFER;
unsigned s, i; unsigned s, i;
if (res->bind & PIPE_BIND_RENDER_TARGET) { if (bind & PIPE_BIND_RENDER_TARGET) {
for (i = 0; i < nvc0->framebuffer.nr_cbufs; ++i) { for (i = 0; i < nvc0->framebuffer.nr_cbufs; ++i) {
if (nvc0->framebuffer.cbufs[i] && if (nvc0->framebuffer.cbufs[i] &&
nvc0->framebuffer.cbufs[i]->texture == res) { nvc0->framebuffer.cbufs[i]->texture == res) {
@ -193,7 +194,7 @@ nvc0_invalidate_resource_storage(struct nouveau_context *ctx,
} }
} }
} }
if (res->bind & PIPE_BIND_DEPTH_STENCIL) { if (bind & PIPE_BIND_DEPTH_STENCIL) {
if (nvc0->framebuffer.zsbuf && if (nvc0->framebuffer.zsbuf &&
nvc0->framebuffer.zsbuf->texture == res) { nvc0->framebuffer.zsbuf->texture == res) {
nvc0->dirty |= NVC0_NEW_FRAMEBUFFER; nvc0->dirty |= NVC0_NEW_FRAMEBUFFER;
@ -203,12 +204,12 @@ nvc0_invalidate_resource_storage(struct nouveau_context *ctx,
} }
} }
if (res->bind & (PIPE_BIND_VERTEX_BUFFER | if (bind & (PIPE_BIND_VERTEX_BUFFER |
PIPE_BIND_INDEX_BUFFER | PIPE_BIND_INDEX_BUFFER |
PIPE_BIND_CONSTANT_BUFFER | PIPE_BIND_CONSTANT_BUFFER |
PIPE_BIND_STREAM_OUTPUT | PIPE_BIND_STREAM_OUTPUT |
PIPE_BIND_COMMAND_ARGS_BUFFER | PIPE_BIND_COMMAND_ARGS_BUFFER |
PIPE_BIND_SAMPLER_VIEW)) { PIPE_BIND_SAMPLER_VIEW)) {
for (i = 0; i < nvc0->num_vtxbufs; ++i) { for (i = 0; i < nvc0->num_vtxbufs; ++i) {
if (nvc0->vtxbuf[i].buffer == res) { if (nvc0->vtxbuf[i].buffer == res) {
nvc0->dirty |= NVC0_NEW_ARRAYS; nvc0->dirty |= NVC0_NEW_ARRAYS;

View File

@ -417,6 +417,7 @@ nvc0_screen_destroy(struct pipe_screen *pscreen)
if (screen->pm.prog) { if (screen->pm.prog) {
screen->pm.prog->code = NULL; /* hardcoded, don't FREE */ screen->pm.prog->code = NULL; /* hardcoded, don't FREE */
nvc0_program_destroy(NULL, screen->pm.prog); nvc0_program_destroy(NULL, screen->pm.prog);
FREE(screen->pm.prog);
} }
nouveau_bo_ref(NULL, &screen->text); nouveau_bo_ref(NULL, &screen->text);

View File

@ -998,6 +998,9 @@ nvc0_set_vertex_buffers(struct pipe_context *pipe,
struct nvc0_context *nvc0 = nvc0_context(pipe); struct nvc0_context *nvc0 = nvc0_context(pipe);
unsigned i; unsigned i;
nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_VTX);
nvc0->dirty |= NVC0_NEW_ARRAYS;
util_set_vertex_buffers_count(nvc0->vtxbuf, &nvc0->num_vtxbufs, vb, util_set_vertex_buffers_count(nvc0->vtxbuf, &nvc0->num_vtxbufs, vb,
start_slot, count); start_slot, count);
@ -1021,9 +1024,6 @@ nvc0_set_vertex_buffers(struct pipe_context *pipe,
nvc0->constant_vbos &= ~(1 << dst_index); nvc0->constant_vbos &= ~(1 << dst_index);
} }
} }
nvc0->dirty |= NVC0_NEW_ARRAYS;
nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_VTX);
} }
static void static void

View File

@ -1527,12 +1527,17 @@ static void evergreen_emit_msaa_state(struct r600_context *rctx, int nr_samples,
S_028C00_EXPAND_LINE_WIDTH(1)); /* R_028C00_PA_SC_LINE_CNTL */ S_028C00_EXPAND_LINE_WIDTH(1)); /* R_028C00_PA_SC_LINE_CNTL */
radeon_emit(cs, S_028C04_MSAA_NUM_SAMPLES(util_logbase2(nr_samples)) | radeon_emit(cs, S_028C04_MSAA_NUM_SAMPLES(util_logbase2(nr_samples)) |
S_028C04_MAX_SAMPLE_DIST(max_dist)); /* R_028C04_PA_SC_AA_CONFIG */ S_028C04_MAX_SAMPLE_DIST(max_dist)); /* R_028C04_PA_SC_AA_CONFIG */
r600_write_context_reg(cs, EG_R_028A4C_PA_SC_MODE_CNTL_1, EG_S_028A4C_PS_ITER_SAMPLE(ps_iter_samples > 1)); r600_write_context_reg(cs, EG_R_028A4C_PA_SC_MODE_CNTL_1,
EG_S_028A4C_PS_ITER_SAMPLE(ps_iter_samples > 1) |
EG_S_028A4C_FORCE_EOV_CNTDWN_ENABLE(1) |
EG_S_028A4C_FORCE_EOV_REZ_ENABLE(1));
} else { } else {
r600_write_context_reg_seq(cs, R_028C00_PA_SC_LINE_CNTL, 2); r600_write_context_reg_seq(cs, R_028C00_PA_SC_LINE_CNTL, 2);
radeon_emit(cs, S_028C00_LAST_PIXEL(1)); /* R_028C00_PA_SC_LINE_CNTL */ radeon_emit(cs, S_028C00_LAST_PIXEL(1)); /* R_028C00_PA_SC_LINE_CNTL */
radeon_emit(cs, 0); /* R_028C04_PA_SC_AA_CONFIG */ radeon_emit(cs, 0); /* R_028C04_PA_SC_AA_CONFIG */
r600_write_context_reg(cs, EG_R_028A4C_PA_SC_MODE_CNTL_1, 0); r600_write_context_reg(cs, EG_R_028A4C_PA_SC_MODE_CNTL_1,
EG_S_028A4C_FORCE_EOV_CNTDWN_ENABLE(1) |
EG_S_028A4C_FORCE_EOV_REZ_ENABLE(1));
} }
} }

View File

@ -57,7 +57,7 @@
/* the number of CS dwords for flushing and drawing */ /* the number of CS dwords for flushing and drawing */
#define R600_MAX_FLUSH_CS_DWORDS 16 #define R600_MAX_FLUSH_CS_DWORDS 16
#define R600_MAX_DRAW_CS_DWORDS 47 #define R600_MAX_DRAW_CS_DWORDS 52
#define R600_TRACE_CS_DWORDS 7 #define R600_TRACE_CS_DWORDS 7
#define R600_MAX_USER_CONST_BUFFERS 13 #define R600_MAX_USER_CONST_BUFFERS 13

View File

@ -598,6 +598,106 @@ static int select_twoside_color(struct r600_shader_ctx *ctx, int front, int back
return 0; return 0;
} }
/* execute a single slot ALU calculation */
static int single_alu_op2(struct r600_shader_ctx *ctx, int op,
int dst_sel, int dst_chan,
int src0_sel, unsigned src0_chan_val,
int src1_sel, unsigned src1_chan_val)
{
struct r600_bytecode_alu alu;
int r, i;
if (ctx->bc->chip_class == CAYMAN && op == ALU_OP2_MULLO_INT) {
for (i = 0; i < 4; i++) {
memset(&alu, 0, sizeof(struct r600_bytecode_alu));
alu.op = op;
alu.src[0].sel = src0_sel;
if (src0_sel == V_SQ_ALU_SRC_LITERAL)
alu.src[0].value = src0_chan_val;
else
alu.src[0].chan = src0_chan_val;
alu.src[1].sel = src1_sel;
if (src1_sel == V_SQ_ALU_SRC_LITERAL)
alu.src[1].value = src1_chan_val;
else
alu.src[1].chan = src1_chan_val;
alu.dst.sel = dst_sel;
alu.dst.chan = i;
alu.dst.write = i == dst_chan;
alu.last = (i == 3);
r = r600_bytecode_add_alu(ctx->bc, &alu);
if (r)
return r;
}
return 0;
}
memset(&alu, 0, sizeof(struct r600_bytecode_alu));
alu.op = op;
alu.src[0].sel = src0_sel;
if (src0_sel == V_SQ_ALU_SRC_LITERAL)
alu.src[0].value = src0_chan_val;
else
alu.src[0].chan = src0_chan_val;
alu.src[1].sel = src1_sel;
if (src1_sel == V_SQ_ALU_SRC_LITERAL)
alu.src[1].value = src1_chan_val;
else
alu.src[1].chan = src1_chan_val;
alu.dst.sel = dst_sel;
alu.dst.chan = dst_chan;
alu.dst.write = 1;
alu.last = 1;
r = r600_bytecode_add_alu(ctx->bc, &alu);
if (r)
return r;
return 0;
}
/* execute a single slot ALU calculation */
static int single_alu_op3(struct r600_shader_ctx *ctx, int op,
int dst_sel, int dst_chan,
int src0_sel, unsigned src0_chan_val,
int src1_sel, unsigned src1_chan_val,
int src2_sel, unsigned src2_chan_val)
{
struct r600_bytecode_alu alu;
int r;
/* validate this for other ops */
assert(op == ALU_OP3_MULADD_UINT24);
memset(&alu, 0, sizeof(struct r600_bytecode_alu));
alu.op = op;
alu.src[0].sel = src0_sel;
if (src0_sel == V_SQ_ALU_SRC_LITERAL)
alu.src[0].value = src0_chan_val;
else
alu.src[0].chan = src0_chan_val;
alu.src[1].sel = src1_sel;
if (src1_sel == V_SQ_ALU_SRC_LITERAL)
alu.src[1].value = src1_chan_val;
else
alu.src[1].chan = src1_chan_val;
alu.src[2].sel = src2_sel;
if (src2_sel == V_SQ_ALU_SRC_LITERAL)
alu.src[2].value = src2_chan_val;
else
alu.src[2].chan = src2_chan_val;
alu.dst.sel = dst_sel;
alu.dst.chan = dst_chan;
alu.is_op3 = 1;
alu.last = 1;
r = r600_bytecode_add_alu(ctx->bc, &alu);
if (r)
return r;
return 0;
}
static inline int get_address_file_reg(struct r600_shader_ctx *ctx, int index)
{
return index > 0 ? ctx->bc->index_reg[index - 1] : ctx->bc->ar_reg;
}
static int vs_add_primid_output(struct r600_shader_ctx *ctx, int prim_id_sid) static int vs_add_primid_output(struct r600_shader_ctx *ctx, int prim_id_sid)
{ {
int i; int i;
@ -1129,6 +1229,7 @@ static int fetch_gs_input(struct r600_shader_ctx *ctx, struct tgsi_full_src_regi
unsigned vtx_id = src->Dimension.Index; unsigned vtx_id = src->Dimension.Index;
int offset_reg = vtx_id / 3; int offset_reg = vtx_id / 3;
int offset_chan = vtx_id % 3; int offset_chan = vtx_id % 3;
int t2 = 0;
/* offsets of per-vertex data in ESGS ring are passed to GS in R0.x, R0.y, /* offsets of per-vertex data in ESGS ring are passed to GS in R0.x, R0.y,
* R0.w, R1.x, R1.y, R1.z (it seems R0.z is used for PrimitiveID) */ * R0.w, R1.x, R1.y, R1.z (it seems R0.z is used for PrimitiveID) */
@ -1136,13 +1237,24 @@ static int fetch_gs_input(struct r600_shader_ctx *ctx, struct tgsi_full_src_regi
if (offset_reg == 0 && offset_chan == 2) if (offset_reg == 0 && offset_chan == 2)
offset_chan = 3; offset_chan = 3;
if (src->Dimension.Indirect || src->Register.Indirect)
t2 = r600_get_temp(ctx);
if (src->Dimension.Indirect) { if (src->Dimension.Indirect) {
int treg[3]; int treg[3];
int t2;
struct r600_bytecode_alu alu; struct r600_bytecode_alu alu;
int r, i; int r, i;
unsigned addr_reg;
/* you have got to be shitting me - addr_reg = get_address_file_reg(ctx, src->DimIndirect.Index);
if (src->DimIndirect.Index > 0) {
r = single_alu_op2(ctx, ALU_OP1_MOV,
ctx->bc->ar_reg, 0,
addr_reg, 0,
0, 0);
if (r)
return r;
}
/*
we have to put the R0.x/y/w into Rt.x Rt+1.x Rt+2.x then index reg from Rt. we have to put the R0.x/y/w into Rt.x Rt+1.x Rt+2.x then index reg from Rt.
at least this is what fglrx seems to do. */ at least this is what fglrx seems to do. */
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
@ -1150,7 +1262,6 @@ static int fetch_gs_input(struct r600_shader_ctx *ctx, struct tgsi_full_src_regi
} }
r600_add_gpr_array(ctx->shader, treg[0], 3, 0x0F); r600_add_gpr_array(ctx->shader, treg[0], 3, 0x0F);
t2 = r600_get_temp(ctx);
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
memset(&alu, 0, sizeof(struct r600_bytecode_alu)); memset(&alu, 0, sizeof(struct r600_bytecode_alu));
alu.op = ALU_OP1_MOV; alu.op = ALU_OP1_MOV;
@ -1175,8 +1286,33 @@ static int fetch_gs_input(struct r600_shader_ctx *ctx, struct tgsi_full_src_regi
if (r) if (r)
return r; return r;
offset_reg = t2; offset_reg = t2;
offset_chan = 0;
} }
if (src->Register.Indirect) {
int addr_reg;
unsigned first = ctx->info.input_array_first[src->Indirect.ArrayID];
addr_reg = get_address_file_reg(ctx, src->Indirect.Index);
/* pull the value from index_reg */
r = single_alu_op2(ctx, ALU_OP2_ADD_INT,
t2, 1,
addr_reg, 0,
V_SQ_ALU_SRC_LITERAL, first);
if (r)
return r;
r = single_alu_op3(ctx, ALU_OP3_MULADD_UINT24,
t2, 0,
t2, 1,
V_SQ_ALU_SRC_LITERAL, 4,
offset_reg, offset_chan);
if (r)
return r;
offset_reg = t2;
offset_chan = 0;
index = src->Register.Index - first;
}
memset(&vtx, 0, sizeof(vtx)); memset(&vtx, 0, sizeof(vtx));
vtx.buffer_id = R600_GS_RING_CONST_BUFFER; vtx.buffer_id = R600_GS_RING_CONST_BUFFER;
@ -1222,6 +1358,7 @@ static int tgsi_split_gs_inputs(struct r600_shader_ctx *ctx)
fetch_gs_input(ctx, src, treg); fetch_gs_input(ctx, src, treg);
ctx->src[i].sel = treg; ctx->src[i].sel = treg;
ctx->src[i].rel = 0;
} }
} }
return 0; return 0;
@ -1972,7 +2109,9 @@ static int r600_shader_from_tgsi(struct r600_context *rctx,
ctx.nliterals = 0; ctx.nliterals = 0;
ctx.literals = NULL; ctx.literals = NULL;
shader->fs_write_all = FALSE;
shader->fs_write_all = ctx.info.properties[TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS] &&
ctx.info.colors_written == 1;
if (shader->vs_as_gs_a) if (shader->vs_as_gs_a)
vs_add_primid_output(&ctx, key.vs.prim_id_out); vs_add_primid_output(&ctx, key.vs.prim_id_out);
@ -2003,10 +2142,6 @@ static int r600_shader_from_tgsi(struct r600_context *rctx,
case TGSI_TOKEN_TYPE_PROPERTY: case TGSI_TOKEN_TYPE_PROPERTY:
property = &ctx.parse.FullToken.FullProperty; property = &ctx.parse.FullToken.FullProperty;
switch (property->Property.PropertyName) { switch (property->Property.PropertyName) {
case TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS:
if (property->u[0].Data == 1)
shader->fs_write_all = TRUE;
break;
case TGSI_PROPERTY_VS_WINDOW_SPACE_POSITION: case TGSI_PROPERTY_VS_WINDOW_SPACE_POSITION:
if (property->u[0].Data == 1) if (property->u[0].Data == 1)
shader->vs_position_window_space = TRUE; shader->vs_position_window_space = TRUE;
@ -2159,6 +2294,10 @@ static int r600_shader_from_tgsi(struct r600_context *rctx,
struct r600_bytecode_alu alu; struct r600_bytecode_alu alu;
int r; int r;
/* GS thread with no output workaround - emit a cut at start of GS */
if (ctx.bc->chip_class == R600)
r600_bytecode_add_cfinst(ctx.bc, CF_OP_CUT_VERTEX);
memset(&alu, 0, sizeof(struct r600_bytecode_alu)); memset(&alu, 0, sizeof(struct r600_bytecode_alu));
alu.op = ALU_OP1_MOV; alu.op = ALU_OP1_MOV;
alu.src[0].sel = V_SQ_ALU_SRC_LITERAL; alu.src[0].sel = V_SQ_ALU_SRC_LITERAL;
@ -6671,7 +6810,7 @@ static int tgsi_eg_arl(struct r600_shader_ctx *ctx)
struct r600_bytecode_alu alu; struct r600_bytecode_alu alu;
int r; int r;
int i, lasti = tgsi_last_instruction(inst->Dst[0].Register.WriteMask); int i, lasti = tgsi_last_instruction(inst->Dst[0].Register.WriteMask);
unsigned reg = inst->Dst[0].Register.Index > 0 ? ctx->bc->index_reg[inst->Dst[0].Register.Index - 1] : ctx->bc->ar_reg; unsigned reg = get_address_file_reg(ctx, inst->Dst[0].Register.Index);
assert(inst->Dst[0].Register.Index < 3); assert(inst->Dst[0].Register.Index < 3);
memset(&alu, 0, sizeof(struct r600_bytecode_alu)); memset(&alu, 0, sizeof(struct r600_bytecode_alu));

View File

@ -2181,10 +2181,11 @@ void r600_init_atom_start_cs(struct r600_context *rctx)
num_temp_gprs = 4; num_temp_gprs = 4;
num_gs_gprs = 0; num_gs_gprs = 0;
num_es_gprs = 0; num_es_gprs = 0;
num_ps_threads = 136; /* use limits 40 VS and at least 16 ES/GS */
num_vs_threads = 48; num_ps_threads = 120;
num_gs_threads = 4; num_vs_threads = 40;
num_es_threads = 4; num_gs_threads = 16;
num_es_threads = 16;
num_ps_stack_entries = 40; num_ps_stack_entries = 40;
num_vs_stack_entries = 40; num_vs_stack_entries = 40;
num_gs_stack_entries = 32; num_gs_stack_entries = 32;
@ -2643,6 +2644,9 @@ void r600_update_vs_state(struct pipe_context *ctx, struct r600_pipe_shader *sha
S_02881C_USE_VTX_VIEWPORT_INDX(rshader->vs_out_viewport); S_02881C_USE_VTX_VIEWPORT_INDX(rshader->vs_out_viewport);
} }
#define RV610_GSVS_ALIGN 32
#define R600_GSVS_ALIGN 16
void r600_update_gs_state(struct pipe_context *ctx, struct r600_pipe_shader *shader) void r600_update_gs_state(struct pipe_context *ctx, struct r600_pipe_shader *shader)
{ {
struct r600_context *rctx = (struct r600_context *)ctx; struct r600_context *rctx = (struct r600_context *)ctx;
@ -2652,6 +2656,23 @@ void r600_update_gs_state(struct pipe_context *ctx, struct r600_pipe_shader *sha
unsigned gsvs_itemsize = unsigned gsvs_itemsize =
(cp_shader->ring_item_size * rshader->gs_max_out_vertices) >> 2; (cp_shader->ring_item_size * rshader->gs_max_out_vertices) >> 2;
/* some r600s needs gsvs itemsize aligned to cacheline size
this was fixed in rs780 and above. */
switch (rctx->b.family) {
case CHIP_RV610:
gsvs_itemsize = align(gsvs_itemsize, RV610_GSVS_ALIGN);
break;
case CHIP_R600:
case CHIP_RV630:
case CHIP_RV670:
case CHIP_RV620:
case CHIP_RV635:
gsvs_itemsize = align(gsvs_itemsize, R600_GSVS_ALIGN);
break;
default:
break;
}
r600_init_command_buffer(cb, 64); r600_init_command_buffer(cb, 64);
/* VGT_GS_MODE is written by r600_emit_shader_stages */ /* VGT_GS_MODE is written by r600_emit_shader_stages */

View File

@ -1691,6 +1691,24 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info
(info.count_from_stream_output ? S_0287F0_USE_OPAQUE(1) : 0); (info.count_from_stream_output ? S_0287F0_USE_OPAQUE(1) : 0);
} }
/* SMX returns CONTEXT_DONE too early workaround */
if (rctx->b.family == CHIP_R600 ||
rctx->b.family == CHIP_RV610 ||
rctx->b.family == CHIP_RV630 ||
rctx->b.family == CHIP_RV635) {
/* if we have gs shader or streamout
we need to do a wait idle after every draw */
if (rctx->gs_shader || rctx->b.streamout.streamout_enabled) {
r600_write_config_reg(cs, R_008040_WAIT_UNTIL, S_008040_WAIT_3D_IDLE(1));
}
}
/* ES ring rolling over at EOP - workaround */
if (rctx->b.chip_class == R600) {
cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE, 0, 0);
cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_SQ_NON_EVENT);
}
if (rctx->screen->b.trace_bo) { if (rctx->screen->b.trace_bo) {
r600_trace_emit(rctx); r600_trace_emit(rctx);
} }

View File

@ -130,6 +130,7 @@
#define EVENT_TYPE_SAMPLE_STREAMOUTSTATS 0x20 #define EVENT_TYPE_SAMPLE_STREAMOUTSTATS 0x20
#define EVENT_TYPE_FLUSH_AND_INV_DB_META 0x2c /* supported on r700+ */ #define EVENT_TYPE_FLUSH_AND_INV_DB_META 0x2c /* supported on r700+ */
#define EVENT_TYPE_VGT_FLUSH 0x24 #define EVENT_TYPE_VGT_FLUSH 0x24
#define EVENT_TYPE_SQ_NON_EVENT 0x26
#define EVENT_TYPE_FLUSH_AND_INV_CB_META 46 /* supported on r700+ */ #define EVENT_TYPE_FLUSH_AND_INV_CB_META 46 /* supported on r700+ */
#define EVENT_TYPE(x) ((x) << 0) #define EVENT_TYPE(x) ((x) << 0)
#define EVENT_INDEX(x) ((x) << 8) #define EVENT_INDEX(x) ((x) << 8)

View File

@ -16,7 +16,8 @@ libradeon_la_SOURCES = \
if NEED_RADEON_LLVM if NEED_RADEON_LLVM
AM_CFLAGS += \ AM_CFLAGS += \
$(LLVM_CFLAGS) $(LLVM_CFLAGS) \
$(LIBELF_CFLAGS)
libradeon_la_SOURCES += \ libradeon_la_SOURCES += \
$(LLVM_C_FILES) $(LLVM_C_FILES)
@ -24,7 +25,7 @@ libradeon_la_SOURCES += \
libradeon_la_LIBADD = \ libradeon_la_LIBADD = \
$(CLOCK_LIB) \ $(CLOCK_LIB) \
$(LLVM_LIBS) \ $(LLVM_LIBS) \
$(ELF_LIB) $(LIBELF_LIBS)
libradeon_la_LDFLAGS = \ libradeon_la_LDFLAGS = \
$(LLVM_LDFLAGS) $(LLVM_LDFLAGS)

View File

@ -229,13 +229,17 @@ void cayman_emit_msaa_config(struct radeon_winsys_cs *cs, int nr_samples,
S_028804_HIGH_QUALITY_INTERSECTIONS(1) | S_028804_HIGH_QUALITY_INTERSECTIONS(1) |
S_028804_STATIC_ANCHOR_ASSOCIATIONS(1)); S_028804_STATIC_ANCHOR_ASSOCIATIONS(1));
r600_write_context_reg(cs, EG_R_028A4C_PA_SC_MODE_CNTL_1, r600_write_context_reg(cs, EG_R_028A4C_PA_SC_MODE_CNTL_1,
EG_S_028A4C_PS_ITER_SAMPLE(ps_iter_samples > 1)); EG_S_028A4C_PS_ITER_SAMPLE(ps_iter_samples > 1) |
EG_S_028A4C_FORCE_EOV_CNTDWN_ENABLE(1) |
EG_S_028A4C_FORCE_EOV_REZ_ENABLE(1));
} else if (overrast_samples > 1) { } else if (overrast_samples > 1) {
r600_write_context_reg(cs, CM_R_028804_DB_EQAA, r600_write_context_reg(cs, CM_R_028804_DB_EQAA,
S_028804_HIGH_QUALITY_INTERSECTIONS(1) | S_028804_HIGH_QUALITY_INTERSECTIONS(1) |
S_028804_STATIC_ANCHOR_ASSOCIATIONS(1) | S_028804_STATIC_ANCHOR_ASSOCIATIONS(1) |
S_028804_OVERRASTERIZATION_AMOUNT(log_samples)); S_028804_OVERRASTERIZATION_AMOUNT(log_samples));
r600_write_context_reg(cs, EG_R_028A4C_PA_SC_MODE_CNTL_1, 0); r600_write_context_reg(cs, EG_R_028A4C_PA_SC_MODE_CNTL_1,
EG_S_028A4C_FORCE_EOV_CNTDWN_ENABLE(1) |
EG_S_028A4C_FORCE_EOV_REZ_ENABLE(1));
} }
} else { } else {
r600_write_context_reg_seq(cs, CM_R_028BDC_PA_SC_LINE_CNTL, 2); r600_write_context_reg_seq(cs, CM_R_028BDC_PA_SC_LINE_CNTL, 2);
@ -245,6 +249,8 @@ void cayman_emit_msaa_config(struct radeon_winsys_cs *cs, int nr_samples,
r600_write_context_reg(cs, CM_R_028804_DB_EQAA, r600_write_context_reg(cs, CM_R_028804_DB_EQAA,
S_028804_HIGH_QUALITY_INTERSECTIONS(1) | S_028804_HIGH_QUALITY_INTERSECTIONS(1) |
S_028804_STATIC_ANCHOR_ASSOCIATIONS(1)); S_028804_STATIC_ANCHOR_ASSOCIATIONS(1));
r600_write_context_reg(cs, EG_R_028A4C_PA_SC_MODE_CNTL_1, 0); r600_write_context_reg(cs, EG_R_028A4C_PA_SC_MODE_CNTL_1,
EG_S_028A4C_FORCE_EOV_CNTDWN_ENABLE(1) |
EG_S_028A4C_FORCE_EOV_REZ_ENABLE(1));
} }
} }

View File

@ -226,8 +226,8 @@ bool r600_common_context_init(struct r600_common_context *rctx,
rctx->family = rscreen->family; rctx->family = rscreen->family;
rctx->chip_class = rscreen->chip_class; rctx->chip_class = rscreen->chip_class;
if (rscreen->family == CHIP_HAWAII) if (rscreen->chip_class >= CIK)
rctx->max_db = 16; rctx->max_db = MAX2(8, rscreen->info.r600_num_backends);
else if (rscreen->chip_class >= EVERGREEN) else if (rscreen->chip_class >= EVERGREEN)
rctx->max_db = 8; rctx->max_db = 8;
else else
@ -543,10 +543,11 @@ const char *r600_get_llvm_processor_name(enum radeon_family family)
case CHIP_TONGA: return "tonga"; case CHIP_TONGA: return "tonga";
case CHIP_ICELAND: return "iceland"; case CHIP_ICELAND: return "iceland";
case CHIP_CARRIZO: return "carrizo"; case CHIP_CARRIZO: return "carrizo";
case CHIP_FIJI: return "fiji";
#if HAVE_LLVM <= 0x0307 #if HAVE_LLVM <= 0x0307
case CHIP_FIJI: return "tonga";
case CHIP_STONEY: return "carrizo"; case CHIP_STONEY: return "carrizo";
#else #else
case CHIP_FIJI: return "fiji";
case CHIP_STONEY: return "stoney"; case CHIP_STONEY: return "stoney";
#endif #endif
default: return ""; default: return "";

View File

@ -168,6 +168,8 @@
#define EG_R_028A4C_PA_SC_MODE_CNTL_1 0x028A4C #define EG_R_028A4C_PA_SC_MODE_CNTL_1 0x028A4C
#define EG_S_028A4C_PS_ITER_SAMPLE(x) (((x) & 0x1) << 16) #define EG_S_028A4C_PS_ITER_SAMPLE(x) (((x) & 0x1) << 16)
#define EG_S_028A4C_FORCE_EOV_CNTDWN_ENABLE(x) (((x) & 0x1) << 25)
#define EG_S_028A4C_FORCE_EOV_REZ_ENABLE(x) (((x) & 0x1) << 26)
#define CM_R_028804_DB_EQAA 0x00028804 #define CM_R_028804_DB_EQAA 0x00028804
#define S_028804_MAX_ANCHOR_SAMPLES(x) (((x) & 0x7) << 0) #define S_028804_MAX_ANCHOR_SAMPLES(x) (((x) & 0x7) << 0)

View File

@ -951,6 +951,8 @@ static void ruvd_end_frame(struct pipe_video_codec *decoder,
dec->msg->body.decode.db_pitch = dec->base.width; dec->msg->body.decode.db_pitch = dec->base.width;
dt = dec->set_dtb(dec->msg, (struct vl_video_buffer *)target); dt = dec->set_dtb(dec->msg, (struct vl_video_buffer *)target);
if (((struct r600_common_screen*)dec->screen)->family >= CHIP_STONEY)
dec->msg->body.decode.dt_wa_chroma_top_offset = dec->msg->body.decode.dt_pitch / 2;
switch (u_reduce_video_profile(picture->profile)) { switch (u_reduce_video_profile(picture->profile)) {
case PIPE_VIDEO_FORMAT_MPEG4_AVC: case PIPE_VIDEO_FORMAT_MPEG4_AVC:

View File

@ -385,7 +385,10 @@ struct ruvd_msg {
uint32_t dt_chroma_top_offset; uint32_t dt_chroma_top_offset;
uint32_t dt_chroma_bottom_offset; uint32_t dt_chroma_bottom_offset;
uint32_t dt_surf_tile_config; uint32_t dt_surf_tile_config;
uint32_t dt_reserved[3]; uint32_t dt_uv_surf_tile_config;
// re-use dt_wa_chroma_top_offset as dt_ext_info for UV pitch in stoney
uint32_t dt_wa_chroma_top_offset;
uint32_t dt_wa_chroma_bottom_offset;
uint32_t reserved[16]; uint32_t reserved[16];

View File

@ -388,6 +388,11 @@ struct pipe_video_codec *rvce_create_encoder(struct pipe_context *context,
struct radeon_surf *tmp_surf; struct radeon_surf *tmp_surf;
unsigned cpb_size; unsigned cpb_size;
if (rscreen->info.family == CHIP_STONEY) {
RVID_ERR("Stoney VCE is not supported!\n");
return NULL;
}
if (!rscreen->info.vce_fw_version) { if (!rscreen->info.vce_fw_version) {
RVID_ERR("Kernel doesn't supports VCE!\n"); RVID_ERR("Kernel doesn't supports VCE!\n");
return NULL; return NULL;

View File

@ -33,14 +33,6 @@
#include "sid.h" #include "sid.h"
#define MAX_GLOBAL_BUFFERS 20 #define MAX_GLOBAL_BUFFERS 20
#if HAVE_LLVM < 0x0305
#define NUM_USER_SGPRS 2
#else
/* XXX: Even though we don't pass the scratch buffer via user sgprs any more
* LLVM still expects that we specify 4 USER_SGPRS so it can remain compatible
* with older mesa. */
#define NUM_USER_SGPRS 4
#endif
struct si_compute { struct si_compute {
struct si_context *ctx; struct si_context *ctx;
@ -241,7 +233,6 @@ static void si_launch_grid(
uint64_t kernel_args_va; uint64_t kernel_args_va;
uint64_t scratch_buffer_va = 0; uint64_t scratch_buffer_va = 0;
uint64_t shader_va; uint64_t shader_va;
unsigned arg_user_sgpr_count = NUM_USER_SGPRS;
unsigned i; unsigned i;
struct si_shader *shader = &program->shader; struct si_shader *shader = &program->shader;
unsigned lds_blocks; unsigned lds_blocks;
@ -365,20 +356,7 @@ static void si_launch_grid(
si_pm4_set_reg(pm4, R_00B830_COMPUTE_PGM_LO, (shader_va >> 8) & 0xffffffff); si_pm4_set_reg(pm4, R_00B830_COMPUTE_PGM_LO, (shader_va >> 8) & 0xffffffff);
si_pm4_set_reg(pm4, R_00B834_COMPUTE_PGM_HI, shader_va >> 40); si_pm4_set_reg(pm4, R_00B834_COMPUTE_PGM_HI, shader_va >> 40);
si_pm4_set_reg(pm4, R_00B848_COMPUTE_PGM_RSRC1, si_pm4_set_reg(pm4, R_00B848_COMPUTE_PGM_RSRC1, shader->rsrc1);
/* We always use at least 3 VGPRS, these come from
* TIDIG_COMP_CNT.
* XXX: The compiler should account for this.
*/
S_00B848_VGPRS((MAX2(3, shader->num_vgprs) - 1) / 4)
/* We always use at least 4 + arg_user_sgpr_count. The 4 extra
* sgprs are from TGID_X_EN, TGID_Y_EN, TGID_Z_EN, TG_SIZE_EN
* XXX: The compiler should account for this.
*/
| S_00B848_SGPRS(((MAX2(4 + arg_user_sgpr_count,
shader->num_sgprs)) - 1) / 8)
| S_00B028_FLOAT_MODE(shader->float_mode))
;
lds_blocks = shader->lds_size; lds_blocks = shader->lds_size;
/* XXX: We are over allocating LDS. For SI, the shader reports LDS in /* XXX: We are over allocating LDS. For SI, the shader reports LDS in
@ -394,17 +372,10 @@ static void si_launch_grid(
assert(lds_blocks <= 0xFF); assert(lds_blocks <= 0xFF);
si_pm4_set_reg(pm4, R_00B84C_COMPUTE_PGM_RSRC2, shader->rsrc2 &= C_00B84C_LDS_SIZE;
S_00B84C_SCRATCH_EN(shader->scratch_bytes_per_wave > 0) shader->rsrc2 |= S_00B84C_LDS_SIZE(lds_blocks);
| S_00B84C_USER_SGPR(arg_user_sgpr_count)
| S_00B84C_TGID_X_EN(1) si_pm4_set_reg(pm4, R_00B84C_COMPUTE_PGM_RSRC2, shader->rsrc2);
| S_00B84C_TGID_Y_EN(1)
| S_00B84C_TGID_Z_EN(1)
| S_00B84C_TG_SIZE_EN(1)
| S_00B84C_TIDIG_COMP_CNT(2)
| S_00B84C_LDS_SIZE(lds_blocks)
| S_00B84C_EXCP_EN(0))
;
si_pm4_set_reg(pm4, R_00B854_COMPUTE_RESOURCE_LIMITS, 0); si_pm4_set_reg(pm4, R_00B854_COMPUTE_RESOURCE_LIMITS, 0);
si_pm4_set_reg(pm4, R_00B858_COMPUTE_STATIC_THREAD_MGMT_SE0, si_pm4_set_reg(pm4, R_00B858_COMPUTE_STATIC_THREAD_MGMT_SE0,

View File

@ -637,6 +637,14 @@ static LLVMValueRef lds_load(struct lp_build_tgsi_context *bld_base,
lp_build_const_int32(gallivm, swizzle)); lp_build_const_int32(gallivm, swizzle));
value = build_indexed_load(si_shader_ctx, si_shader_ctx->lds, dw_addr); value = build_indexed_load(si_shader_ctx, si_shader_ctx->lds, dw_addr);
if (type == TGSI_TYPE_DOUBLE) {
LLVMValueRef value2;
dw_addr = lp_build_add(&bld_base->uint_bld, dw_addr,
lp_build_const_int32(gallivm, swizzle + 1));
value2 = build_indexed_load(si_shader_ctx, si_shader_ctx->lds, dw_addr);
return radeon_llvm_emit_fetch_double(bld_base, value, value2);
}
return LLVMBuildBitCast(gallivm->builder, value, return LLVMBuildBitCast(gallivm->builder, value,
tgsi2llvmtype(bld_base, type), ""); tgsi2llvmtype(bld_base, type), "");
} }
@ -3752,12 +3760,14 @@ void si_shader_binary_read_config(const struct si_screen *sscreen,
shader->num_sgprs = MAX2(shader->num_sgprs, (G_00B028_SGPRS(value) + 1) * 8); shader->num_sgprs = MAX2(shader->num_sgprs, (G_00B028_SGPRS(value) + 1) * 8);
shader->num_vgprs = MAX2(shader->num_vgprs, (G_00B028_VGPRS(value) + 1) * 4); shader->num_vgprs = MAX2(shader->num_vgprs, (G_00B028_VGPRS(value) + 1) * 4);
shader->float_mode = G_00B028_FLOAT_MODE(value); shader->float_mode = G_00B028_FLOAT_MODE(value);
shader->rsrc1 = value;
break; break;
case R_00B02C_SPI_SHADER_PGM_RSRC2_PS: case R_00B02C_SPI_SHADER_PGM_RSRC2_PS:
shader->lds_size = MAX2(shader->lds_size, G_00B02C_EXTRA_LDS_SIZE(value)); shader->lds_size = MAX2(shader->lds_size, G_00B02C_EXTRA_LDS_SIZE(value));
break; break;
case R_00B84C_COMPUTE_PGM_RSRC2: case R_00B84C_COMPUTE_PGM_RSRC2:
shader->lds_size = MAX2(shader->lds_size, G_00B84C_LDS_SIZE(value)); shader->lds_size = MAX2(shader->lds_size, G_00B84C_LDS_SIZE(value));
shader->rsrc2 = value;
break; break;
case R_0286CC_SPI_PS_INPUT_ENA: case R_0286CC_SPI_PS_INPUT_ENA:
shader->spi_ps_input_ena = value; shader->spi_ps_input_ena = value;

View File

@ -268,8 +268,8 @@ struct si_shader {
bool is_gs_copy_shader; bool is_gs_copy_shader;
bool dx10_clamp_mode; /* convert NaNs to 0 */ bool dx10_clamp_mode; /* convert NaNs to 0 */
unsigned ls_rsrc1; unsigned rsrc1;
unsigned ls_rsrc2; unsigned rsrc2;
}; };
static inline struct tgsi_shader_info *si_get_vs_info(struct si_context *sctx) static inline struct tgsi_shader_info *si_get_vs_info(struct si_context *sctx)

View File

@ -2979,6 +2979,28 @@ static void si_need_gfx_cs_space(struct pipe_context *ctx, unsigned num_dw,
si_need_cs_space((struct si_context*)ctx, num_dw, include_draw_vbo); si_need_cs_space((struct si_context*)ctx, num_dw, include_draw_vbo);
} }
static void si_init_border_color_buffer(struct si_context *sctx)
{
struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state);
if (!pm4)
return;
assert(sctx->scratch_buffer == NULL);
r600_resource_reference(&sctx->scratch_buffer, NULL);
sctx->scratch_buffer = si_resource_create_custom(&sctx->screen->b.b,
PIPE_USAGE_DEFAULT,
4096 * 16);
uint64_t va = sctx->scratch_buffer->gpu_address;
si_pm4_set_reg(pm4, R_028080_TA_BC_BASE_ADDR, va >> 8);
if (sctx->b.chip_class >= CIK)
si_pm4_set_reg(pm4, R_028084_TA_BC_BASE_ADDR_HI, va >> 40);
si_pm4_add_bo(pm4, sctx->scratch_buffer, RADEON_USAGE_READ,
RADEON_PRIO_SHADER_DATA);
si_pm4_set_state(sctx, ta_bordercolor_base, pm4);
}
static void si_init_config(struct si_context *sctx); static void si_init_config(struct si_context *sctx);
void si_init_state_functions(struct si_context *sctx) void si_init_state_functions(struct si_context *sctx)
@ -3045,6 +3067,7 @@ void si_init_state_functions(struct si_context *sctx)
} }
si_init_config(sctx); si_init_config(sctx);
si_init_border_color_buffer(sctx);
} }
static void static void

View File

@ -163,7 +163,7 @@ static void si_emit_derived_tess_state(struct si_context *sctx,
perpatch_output_offset = output_patch0_offset + pervertex_output_patch_size; perpatch_output_offset = output_patch0_offset + pervertex_output_patch_size;
lds_size = output_patch0_offset + output_patch_size * *num_patches; lds_size = output_patch0_offset + output_patch_size * *num_patches;
ls_rsrc2 = ls->current->ls_rsrc2; ls_rsrc2 = ls->current->rsrc2;
if (sctx->b.chip_class >= CIK) { if (sctx->b.chip_class >= CIK) {
assert(lds_size <= 65536); assert(lds_size <= 65536);
@ -178,7 +178,7 @@ static void si_emit_derived_tess_state(struct si_context *sctx,
if (sctx->b.chip_class == CIK && sctx->b.family != CHIP_HAWAII) if (sctx->b.chip_class == CIK && sctx->b.family != CHIP_HAWAII)
si_write_sh_reg(cs, R_00B52C_SPI_SHADER_PGM_RSRC2_LS, ls_rsrc2); si_write_sh_reg(cs, R_00B52C_SPI_SHADER_PGM_RSRC2_LS, ls_rsrc2);
si_write_sh_reg_seq(cs, R_00B528_SPI_SHADER_PGM_RSRC1_LS, 2); si_write_sh_reg_seq(cs, R_00B528_SPI_SHADER_PGM_RSRC1_LS, 2);
radeon_emit(cs, ls->current->ls_rsrc1); radeon_emit(cs, ls->current->rsrc1);
radeon_emit(cs, ls_rsrc2); radeon_emit(cs, ls_rsrc2);
/* Compute userdata SGPRs. */ /* Compute userdata SGPRs. */
@ -216,6 +216,18 @@ static void si_emit_derived_tess_state(struct si_context *sctx,
radeon_emit(cs, tcs_out_layout | (num_tcs_output_cp << 26)); radeon_emit(cs, tcs_out_layout | (num_tcs_output_cp << 26));
} }
static unsigned si_num_prims_for_vertices(const struct pipe_draw_info *info)
{
switch (info->mode) {
case PIPE_PRIM_PATCHES:
return info->count / info->vertices_per_patch;
case R600_PRIM_RECTANGLE_LIST:
return info->count / 3;
default:
return u_prims_for_vertices(info->mode, info->count);
}
}
static unsigned si_get_ia_multi_vgt_param(struct si_context *sctx, static unsigned si_get_ia_multi_vgt_param(struct si_context *sctx,
const struct pipe_draw_info *info, const struct pipe_draw_info *info,
unsigned num_patches) unsigned num_patches)
@ -305,7 +317,7 @@ static unsigned si_get_ia_multi_vgt_param(struct si_context *sctx,
if (sctx->b.screen->info.max_se >= 2 && ia_switch_on_eoi && if (sctx->b.screen->info.max_se >= 2 && ia_switch_on_eoi &&
(info->indirect || (info->indirect ||
(info->instance_count > 1 && (info->instance_count > 1 &&
u_prims_for_vertices(info->mode, info->count) <= 1))) si_num_prims_for_vertices(info) <= 1)))
sctx->b.flags |= SI_CONTEXT_VGT_FLUSH; sctx->b.flags |= SI_CONTEXT_VGT_FLUSH;
/* Instancing bug on 2 SE chips. */ /* Instancing bug on 2 SE chips. */
@ -849,7 +861,9 @@ void si_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
/* Workaround for a VGT hang when streamout is enabled. /* Workaround for a VGT hang when streamout is enabled.
* It must be done after drawing. */ * It must be done after drawing. */
if ((sctx->b.family == CHIP_HAWAII || sctx->b.family == CHIP_TONGA) && if ((sctx->b.family == CHIP_HAWAII ||
sctx->b.family == CHIP_TONGA ||
sctx->b.family == CHIP_FIJI) &&
(sctx->b.streamout.streamout_enabled || (sctx->b.streamout.streamout_enabled ||
sctx->b.streamout.prims_gen_query_enabled)) { sctx->b.streamout.prims_gen_query_enabled)) {
sctx->b.flags |= SI_CONTEXT_VGT_STREAMOUT_SYNC; sctx->b.flags |= SI_CONTEXT_VGT_STREAMOUT_SYNC;

View File

@ -119,10 +119,10 @@ static void si_shader_ls(struct si_shader *shader)
si_pm4_set_reg(pm4, R_00B520_SPI_SHADER_PGM_LO_LS, va >> 8); si_pm4_set_reg(pm4, R_00B520_SPI_SHADER_PGM_LO_LS, va >> 8);
si_pm4_set_reg(pm4, R_00B524_SPI_SHADER_PGM_HI_LS, va >> 40); si_pm4_set_reg(pm4, R_00B524_SPI_SHADER_PGM_HI_LS, va >> 40);
shader->ls_rsrc1 = S_00B528_VGPRS((shader->num_vgprs - 1) / 4) | shader->rsrc1 = S_00B528_VGPRS((shader->num_vgprs - 1) / 4) |
S_00B528_SGPRS((num_sgprs - 1) / 8) | S_00B528_SGPRS((num_sgprs - 1) / 8) |
S_00B528_VGPR_COMP_CNT(vgpr_comp_cnt); S_00B528_VGPR_COMP_CNT(vgpr_comp_cnt);
shader->ls_rsrc2 = S_00B52C_USER_SGPR(num_user_sgprs) | shader->rsrc2 = S_00B52C_USER_SGPR(num_user_sgprs) |
S_00B52C_SCRATCH_EN(shader->scratch_bytes_per_wave > 0); S_00B52C_SCRATCH_EN(shader->scratch_bytes_per_wave > 0);
} }

View File

@ -2,6 +2,9 @@ include $(top_srcdir)/src/gallium/Automake.inc
lib_LTLIBRARIES = lib@OPENCL_LIBNAME@.la lib_LTLIBRARIES = lib@OPENCL_LIBNAME@.la
AM_CPPFLAGS = \
$(LIBELF_CFLAGS)
lib@OPENCL_LIBNAME@_la_LDFLAGS = \ lib@OPENCL_LIBNAME@_la_LDFLAGS = \
$(LLVM_LDFLAGS) \ $(LLVM_LDFLAGS) \
-no-undefined \ -no-undefined \
@ -20,8 +23,8 @@ lib@OPENCL_LIBNAME@_la_LIBADD = \
$(top_builddir)/src/gallium/auxiliary/libgallium.la \ $(top_builddir)/src/gallium/auxiliary/libgallium.la \
$(top_builddir)/src/util/libmesautil.la \ $(top_builddir)/src/util/libmesautil.la \
$(GALLIUM_PIPE_LOADER_WINSYS_LIBS) \ $(GALLIUM_PIPE_LOADER_WINSYS_LIBS) \
$(ELF_LIB) \ $(LIBELF_LIBS) \
-ldl \ $(DLOPEN_LIBS) \
-lclangCodeGen \ -lclangCodeGen \
-lclangFrontendTool \ -lclangFrontendTool \
-lclangFrontend \ -lclangFrontend \

View File

@ -2281,7 +2281,9 @@ validate_binding_qualifier(struct _mesa_glsl_parse_state *state,
return false; return false;
} }
} else if (state->is_version(420, 310) && base_type->is_image()) { } else if ((state->is_version(420, 310) ||
state->ARB_shading_language_420pack_enable) &&
base_type->is_image()) {
assert(ctx->Const.MaxImageUnits <= MAX_IMAGE_UNITS); assert(ctx->Const.MaxImageUnits <= MAX_IMAGE_UNITS);
if (max_index >= ctx->Const.MaxImageUnits) { if (max_index >= ctx->Const.MaxImageUnits) {
_mesa_glsl_error(loc, state, "Image binding %d exceeds the " _mesa_glsl_error(loc, state, "Image binding %d exceeds the "

View File

@ -1402,8 +1402,7 @@ static const char * const tex_opcode_strs[] = { "tex", "txb", "txl", "txd", "txf
const char *ir_texture::opcode_string() const char *ir_texture::opcode_string()
{ {
assert((unsigned int) op <= assert((unsigned int) op < ARRAY_SIZE(tex_opcode_strs));
sizeof(tex_opcode_strs) / sizeof(tex_opcode_strs[0]));
return tex_opcode_strs[op]; return tex_opcode_strs[op];
} }

View File

@ -3754,13 +3754,13 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
if (first < MESA_SHADER_FRAGMENT) { if (first < MESA_SHADER_FRAGMENT) {
gl_shader *const sh = prog->_LinkedShaders[last]; gl_shader *const sh = prog->_LinkedShaders[last];
if (first == MESA_SHADER_GEOMETRY) { if (first != MESA_SHADER_VERTEX) {
/* There was no vertex shader, but we still have to assign varying /* There was no vertex shader, but we still have to assign varying
* locations for use by geometry shader inputs in SSO. * locations for use by tessellation/geometry shader inputs in SSO.
* *
* If the shader is not separable (i.e., prog->SeparateShader is * If the shader is not separable (i.e., prog->SeparateShader is
* false), linking will have already failed when first is * false), linking will have already failed when first is not
* MESA_SHADER_GEOMETRY. * MESA_SHADER_VERTEX.
*/ */
if (!assign_varying_locations(ctx, mem_ctx, prog, if (!assign_varying_locations(ctx, mem_ctx, prog,
NULL, prog->_LinkedShaders[first], NULL, prog->_LinkedShaders[first],

View File

@ -96,7 +96,7 @@ convert_instr(nir_builder *bld, nir_alu_instr *alu)
r = nir_imul(bld, q, b); r = nir_imul(bld, q, b);
r = nir_isub(bld, a, r); r = nir_isub(bld, a, r);
r = nir_ige(bld, r, b); r = nir_uge(bld, r, b);
r = nir_b2i(bld, r); r = nir_b2i(bld, r);
q = nir_iadd(bld, q, r); q = nir_iadd(bld, q, r);

View File

@ -95,9 +95,12 @@ static struct blit_shader *
choose_blit_shader(GLenum target, struct blit_shader_table *table); choose_blit_shader(GLenum target, struct blit_shader_table *table);
static void cleanup_temp_texture(struct temp_texture *tex); static void cleanup_temp_texture(struct temp_texture *tex);
static void meta_glsl_clear_cleanup(struct clear_state *clear); static void meta_glsl_clear_cleanup(struct gl_context *ctx,
static void meta_decompress_cleanup(struct decompress_state *decompress); struct clear_state *clear);
static void meta_drawpix_cleanup(struct drawpix_state *drawpix); static void meta_decompress_cleanup(struct gl_context *ctx,
struct decompress_state *decompress);
static void meta_drawpix_cleanup(struct gl_context *ctx,
struct drawpix_state *drawpix);
void void
_mesa_meta_bind_fbo_image(GLenum fboTarget, GLenum attachment, _mesa_meta_bind_fbo_image(GLenum fboTarget, GLenum attachment,
@ -310,13 +313,13 @@ _mesa_meta_setup_blit_shader(struct gl_context *ctx,
/** /**
* Configure vertex buffer and vertex array objects for tests * Configure vertex buffer and vertex array objects for tests
* *
* Regardless of whether a new VAO and new VBO are created, the objects * Regardless of whether a new VAO is created, the object referenced by \c VAO
* referenced by \c VAO and \c VBO will be bound into the GL state vector * will be bound into the GL state vector when this function terminates. The
* when this function terminates. * object referenced by \c VBO will \b not be bound.
* *
* \param VAO Storage for vertex array object handle. If 0, a new VAO * \param VAO Storage for vertex array object handle. If 0, a new VAO
* will be created. * will be created.
* \param VBO Storage for vertex buffer object handle. If 0, a new VBO * \param buf_obj Storage for vertex buffer object pointer. If \c NULL, a new VBO
* will be created. The new VBO will have storage for 4 * will be created. The new VBO will have storage for 4
* \c vertex structures. * \c vertex structures.
* \param use_generic_attributes Should generic attributes 0 and 1 be used, * \param use_generic_attributes Should generic attributes 0 and 1 be used,
@ -333,57 +336,84 @@ _mesa_meta_setup_blit_shader(struct gl_context *ctx,
* Use \c texcoord_size instead. * Use \c texcoord_size instead.
*/ */
void void
_mesa_meta_setup_vertex_objects(GLuint *VAO, GLuint *VBO, _mesa_meta_setup_vertex_objects(struct gl_context *ctx,
GLuint *VAO, struct gl_buffer_object **buf_obj,
bool use_generic_attributes, bool use_generic_attributes,
unsigned vertex_size, unsigned texcoord_size, unsigned vertex_size, unsigned texcoord_size,
unsigned color_size) unsigned color_size)
{ {
if (*VAO == 0) { if (*VAO == 0) {
assert(*VBO == 0); struct gl_vertex_array_object *array_obj;
assert(*buf_obj == NULL);
/* create vertex array object */ /* create vertex array object */
_mesa_GenVertexArrays(1, VAO); _mesa_GenVertexArrays(1, VAO);
_mesa_BindVertexArray(*VAO); _mesa_BindVertexArray(*VAO);
array_obj = _mesa_lookup_vao(ctx, *VAO);
assert(array_obj != NULL);
/* create vertex array buffer */ /* create vertex array buffer */
_mesa_GenBuffers(1, VBO); *buf_obj = ctx->Driver.NewBufferObject(ctx, 0xDEADBEEF);
_mesa_BindBuffer(GL_ARRAY_BUFFER, *VBO); if (*buf_obj == NULL)
_mesa_BufferData(GL_ARRAY_BUFFER, 4 * sizeof(struct vertex), NULL, return;
GL_DYNAMIC_DRAW);
_mesa_buffer_data(ctx, *buf_obj, GL_NONE, 4 * sizeof(struct vertex), NULL,
GL_DYNAMIC_DRAW, __func__);
/* setup vertex arrays */ /* setup vertex arrays */
if (use_generic_attributes) { if (use_generic_attributes) {
assert(color_size == 0); assert(color_size == 0);
_mesa_VertexAttribPointer(0, vertex_size, GL_FLOAT, GL_FALSE, _mesa_update_array_format(ctx, array_obj, VERT_ATTRIB_GENERIC(0),
sizeof(struct vertex), OFFSET(x)); vertex_size, GL_FLOAT, GL_RGBA, GL_FALSE,
_mesa_EnableVertexAttribArray(0); GL_FALSE, GL_FALSE,
offsetof(struct vertex, x), true);
_mesa_bind_vertex_buffer(ctx, array_obj, VERT_ATTRIB_GENERIC(0),
*buf_obj, 0, sizeof(struct vertex));
_mesa_enable_vertex_array_attrib(ctx, array_obj,
VERT_ATTRIB_GENERIC(0));
if (texcoord_size > 0) { if (texcoord_size > 0) {
_mesa_VertexAttribPointer(1, texcoord_size, GL_FLOAT, GL_FALSE, _mesa_update_array_format(ctx, array_obj, VERT_ATTRIB_GENERIC(1),
sizeof(struct vertex), OFFSET(tex)); texcoord_size, GL_FLOAT, GL_RGBA,
_mesa_EnableVertexAttribArray(1); GL_FALSE, GL_FALSE, GL_FALSE,
offsetof(struct vertex, tex), false);
_mesa_bind_vertex_buffer(ctx, array_obj, VERT_ATTRIB_GENERIC(1),
*buf_obj, 0, sizeof(struct vertex));
_mesa_enable_vertex_array_attrib(ctx, array_obj,
VERT_ATTRIB_GENERIC(1));
} }
} else { } else {
_mesa_VertexPointer(vertex_size, GL_FLOAT, sizeof(struct vertex), _mesa_update_array_format(ctx, array_obj, VERT_ATTRIB_POS,
OFFSET(x)); vertex_size, GL_FLOAT, GL_RGBA, GL_FALSE,
_mesa_EnableClientState(GL_VERTEX_ARRAY); GL_FALSE, GL_FALSE,
offsetof(struct vertex, x), true);
_mesa_bind_vertex_buffer(ctx, array_obj, VERT_ATTRIB_POS,
*buf_obj, 0, sizeof(struct vertex));
_mesa_enable_vertex_array_attrib(ctx, array_obj, VERT_ATTRIB_POS);
if (texcoord_size > 0) { if (texcoord_size > 0) {
_mesa_TexCoordPointer(texcoord_size, GL_FLOAT, _mesa_update_array_format(ctx, array_obj, VERT_ATTRIB_TEX(0),
sizeof(struct vertex), OFFSET(tex)); vertex_size, GL_FLOAT, GL_RGBA, GL_FALSE,
_mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY); GL_FALSE, GL_FALSE,
offsetof(struct vertex, tex), false);
_mesa_bind_vertex_buffer(ctx, array_obj, VERT_ATTRIB_TEX(0),
*buf_obj, 0, sizeof(struct vertex));
_mesa_enable_vertex_array_attrib(ctx, array_obj, VERT_ATTRIB_TEX(0));
} }
if (color_size > 0) { if (color_size > 0) {
_mesa_ColorPointer(color_size, GL_FLOAT, _mesa_update_array_format(ctx, array_obj, VERT_ATTRIB_COLOR0,
sizeof(struct vertex), OFFSET(r)); vertex_size, GL_FLOAT, GL_RGBA, GL_FALSE,
_mesa_EnableClientState(GL_COLOR_ARRAY); GL_FALSE, GL_FALSE,
offsetof(struct vertex, r), false);
_mesa_bind_vertex_buffer(ctx, array_obj, VERT_ATTRIB_COLOR0,
*buf_obj, 0, sizeof(struct vertex));
_mesa_enable_vertex_array_attrib(ctx, array_obj, VERT_ATTRIB_COLOR0);
} }
} }
} else { } else {
_mesa_BindVertexArray(*VAO); _mesa_BindVertexArray(*VAO);
_mesa_BindBuffer(GL_ARRAY_BUFFER, *VBO);
} }
} }
@ -408,12 +438,12 @@ _mesa_meta_free(struct gl_context *ctx)
{ {
GET_CURRENT_CONTEXT(old_context); GET_CURRENT_CONTEXT(old_context);
_mesa_make_current(ctx, NULL, NULL); _mesa_make_current(ctx, NULL, NULL);
_mesa_meta_glsl_blit_cleanup(&ctx->Meta->Blit); _mesa_meta_glsl_blit_cleanup(ctx, &ctx->Meta->Blit);
meta_glsl_clear_cleanup(&ctx->Meta->Clear); meta_glsl_clear_cleanup(ctx, &ctx->Meta->Clear);
_mesa_meta_glsl_generate_mipmap_cleanup(&ctx->Meta->Mipmap); _mesa_meta_glsl_generate_mipmap_cleanup(ctx, &ctx->Meta->Mipmap);
cleanup_temp_texture(&ctx->Meta->TempTex); cleanup_temp_texture(&ctx->Meta->TempTex);
meta_decompress_cleanup(&ctx->Meta->Decompress); meta_decompress_cleanup(ctx, &ctx->Meta->Decompress);
meta_drawpix_cleanup(&ctx->Meta->DrawPix); meta_drawpix_cleanup(ctx, &ctx->Meta->DrawPix);
if (old_context) if (old_context)
_mesa_make_current(old_context, old_context->WinSysDrawBuffer, old_context->WinSysReadBuffer); _mesa_make_current(old_context, old_context->WinSysDrawBuffer, old_context->WinSysReadBuffer);
else else
@ -1477,10 +1507,12 @@ _mesa_meta_setup_drawpix_texture(struct gl_context *ctx,
} }
void void
_mesa_meta_setup_ff_tnl_for_blit(GLuint *VAO, GLuint *VBO, _mesa_meta_setup_ff_tnl_for_blit(struct gl_context *ctx,
GLuint *VAO, struct gl_buffer_object **buf_obj,
unsigned texcoord_size) unsigned texcoord_size)
{ {
_mesa_meta_setup_vertex_objects(VAO, VBO, false, 2, texcoord_size, 0); _mesa_meta_setup_vertex_objects(ctx, VAO, buf_obj, false, 2, texcoord_size,
0);
/* setup projection matrix */ /* setup projection matrix */
_mesa_MatrixMode(GL_PROJECTION); _mesa_MatrixMode(GL_PROJECTION);
@ -1525,7 +1557,8 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)
GLuint vs, fs; GLuint vs, fs;
bool has_integer_textures; bool has_integer_textures;
_mesa_meta_setup_vertex_objects(&clear->VAO, &clear->VBO, true, 3, 0, 0); _mesa_meta_setup_vertex_objects(ctx, &clear->VAO, &clear->buf_obj, true,
3, 0, 0);
if (clear->ShaderProg != 0) if (clear->ShaderProg != 0)
return; return;
@ -1606,14 +1639,13 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)
} }
static void static void
meta_glsl_clear_cleanup(struct clear_state *clear) meta_glsl_clear_cleanup(struct gl_context *ctx, struct clear_state *clear)
{ {
if (clear->VAO == 0) if (clear->VAO == 0)
return; return;
_mesa_DeleteVertexArrays(1, &clear->VAO); _mesa_DeleteVertexArrays(1, &clear->VAO);
clear->VAO = 0; clear->VAO = 0;
_mesa_DeleteBuffers(1, &clear->VBO); _mesa_reference_buffer_object(ctx, &clear->buf_obj, NULL);
clear->VBO = 0;
_mesa_DeleteProgram(clear->ShaderProg); _mesa_DeleteProgram(clear->ShaderProg);
clear->ShaderProg = 0; clear->ShaderProg = 0;
@ -1721,7 +1753,8 @@ meta_clear(struct gl_context *ctx, GLbitfield buffers, bool glsl)
y1 = ((float) fb->_Ymax / fb->Height) * 2.0f - 1.0f; y1 = ((float) fb->_Ymax / fb->Height) * 2.0f - 1.0f;
z = -invert_z(ctx->Depth.Clear); z = -invert_z(ctx->Depth.Clear);
} else { } else {
_mesa_meta_setup_vertex_objects(&clear->VAO, &clear->VBO, false, 3, 0, 4); _mesa_meta_setup_vertex_objects(ctx, &clear->VAO, &clear->buf_obj, false,
3, 0, 4);
x0 = (float) fb->_Xmin; x0 = (float) fb->_Xmin;
y0 = (float) fb->_Ymin; y0 = (float) fb->_Ymin;
@ -1804,8 +1837,8 @@ meta_clear(struct gl_context *ctx, GLbitfield buffers, bool glsl)
} }
/* upload new vertex data */ /* upload new vertex data */
_mesa_BufferData(GL_ARRAY_BUFFER_ARB, sizeof(verts), verts, _mesa_buffer_data(ctx, clear->buf_obj, GL_NONE, sizeof(verts), verts,
GL_DYNAMIC_DRAW_ARB); GL_DYNAMIC_DRAW, __func__);
/* draw quad(s) */ /* draw quad(s) */
if (fb->MaxNumLayers > 0) { if (fb->MaxNumLayers > 0) {
@ -1851,7 +1884,7 @@ _mesa_meta_CopyPixels(struct gl_context *ctx, GLint srcX, GLint srcY,
MESA_META_VERTEX | MESA_META_VERTEX |
MESA_META_VIEWPORT)); MESA_META_VIEWPORT));
_mesa_meta_setup_vertex_objects(&copypix->VAO, &copypix->VBO, false, _mesa_meta_setup_vertex_objects(ctx, &copypix->VAO, &copypix->buf_obj, false,
3, 2, 0); 3, 2, 0);
/* Silence valgrind warnings about reading uninitialized stack. */ /* Silence valgrind warnings about reading uninitialized stack. */
@ -1891,7 +1924,8 @@ _mesa_meta_CopyPixels(struct gl_context *ctx, GLint srcX, GLint srcY,
verts[3].tex[1] = tex->Ttop; verts[3].tex[1] = tex->Ttop;
/* upload new vertex data */ /* upload new vertex data */
_mesa_BufferSubData(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts); _mesa_buffer_sub_data(ctx, copypix->buf_obj, 0, sizeof(verts), verts,
__func__);
} }
_mesa_set_enable(ctx, tex->Target, GL_TRUE); _mesa_set_enable(ctx, tex->Target, GL_TRUE);
@ -1905,14 +1939,13 @@ _mesa_meta_CopyPixels(struct gl_context *ctx, GLint srcX, GLint srcY,
} }
static void static void
meta_drawpix_cleanup(struct drawpix_state *drawpix) meta_drawpix_cleanup(struct gl_context *ctx, struct drawpix_state *drawpix)
{ {
if (drawpix->VAO != 0) { if (drawpix->VAO != 0) {
_mesa_DeleteVertexArrays(1, &drawpix->VAO); _mesa_DeleteVertexArrays(1, &drawpix->VAO);
drawpix->VAO = 0; drawpix->VAO = 0;
_mesa_DeleteBuffers(1, &drawpix->VBO); _mesa_reference_buffer_object(ctx, &drawpix->buf_obj, NULL);
drawpix->VBO = 0;
} }
if (drawpix->StencilFP != 0) { if (drawpix->StencilFP != 0) {
@ -2172,7 +2205,7 @@ _mesa_meta_DrawPixels(struct gl_context *ctx,
newTex = _mesa_meta_alloc_texture(tex, width, height, texIntFormat); newTex = _mesa_meta_alloc_texture(tex, width, height, texIntFormat);
_mesa_meta_setup_vertex_objects(&drawpix->VAO, &drawpix->VBO, false, _mesa_meta_setup_vertex_objects(ctx, &drawpix->VAO, &drawpix->buf_obj, false,
3, 2, 0); 3, 2, 0);
/* Silence valgrind warnings about reading uninitialized stack. */ /* Silence valgrind warnings about reading uninitialized stack. */
@ -2209,8 +2242,8 @@ _mesa_meta_DrawPixels(struct gl_context *ctx,
} }
/* upload new vertex data */ /* upload new vertex data */
_mesa_BufferData(GL_ARRAY_BUFFER_ARB, sizeof(verts), _mesa_buffer_data(ctx, drawpix->buf_obj, GL_NONE, sizeof(verts), verts,
verts, GL_DYNAMIC_DRAW_ARB); GL_DYNAMIC_DRAW, __func__);
/* set given unpack params */ /* set given unpack params */
ctx->Unpack = *unpack; ctx->Unpack = *unpack;
@ -2365,7 +2398,8 @@ _mesa_meta_Bitmap(struct gl_context *ctx,
MESA_META_VERTEX | MESA_META_VERTEX |
MESA_META_VIEWPORT)); MESA_META_VIEWPORT));
_mesa_meta_setup_vertex_objects(&bitmap->VAO, &bitmap->VBO, false, 3, 2, 4); _mesa_meta_setup_vertex_objects(ctx, &bitmap->VAO, &bitmap->buf_obj, false,
3, 2, 4);
newTex = _mesa_meta_alloc_texture(tex, width, height, texIntFormat); newTex = _mesa_meta_alloc_texture(tex, width, height, texIntFormat);
@ -2410,7 +2444,8 @@ _mesa_meta_Bitmap(struct gl_context *ctx,
} }
/* upload new vertex data */ /* upload new vertex data */
_mesa_BufferSubData(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts); _mesa_buffer_sub_data(ctx, bitmap->buf_obj, 0, sizeof(verts), verts,
__func__);
} }
/* choose different foreground/background alpha values */ /* choose different foreground/background alpha values */
@ -2939,14 +2974,15 @@ meta_decompress_fbo_cleanup(struct decompress_fbo_state *decompress_fbo)
} }
static void static void
meta_decompress_cleanup(struct decompress_state *decompress) meta_decompress_cleanup(struct gl_context *ctx,
struct decompress_state *decompress)
{ {
meta_decompress_fbo_cleanup(&decompress->byteFBO); meta_decompress_fbo_cleanup(&decompress->byteFBO);
meta_decompress_fbo_cleanup(&decompress->floatFBO); meta_decompress_fbo_cleanup(&decompress->floatFBO);
if (decompress->VAO != 0) { if (decompress->VAO != 0) {
_mesa_DeleteVertexArrays(1, &decompress->VAO); _mesa_DeleteVertexArrays(1, &decompress->VAO);
_mesa_DeleteBuffers(1, &decompress->VBO); _mesa_reference_buffer_object(ctx, &decompress->buf_obj, NULL);
} }
if (decompress->Sampler != 0) if (decompress->Sampler != 0)
@ -3066,12 +3102,14 @@ decompress_texture_image(struct gl_context *ctx,
} }
if (use_glsl_version) { if (use_glsl_version) {
_mesa_meta_setup_vertex_objects(&decompress->VAO, &decompress->VBO, true, _mesa_meta_setup_vertex_objects(ctx, &decompress->VAO,
&decompress->buf_obj, true,
2, 4, 0); 2, 4, 0);
_mesa_meta_setup_blit_shader(ctx, target, false, &decompress->shaders); _mesa_meta_setup_blit_shader(ctx, target, false, &decompress->shaders);
} else { } else {
_mesa_meta_setup_ff_tnl_for_blit(&decompress->VAO, &decompress->VBO, 3); _mesa_meta_setup_ff_tnl_for_blit(ctx, &decompress->VAO,
&decompress->buf_obj, 3);
} }
if (!decompress->Sampler) { if (!decompress->Sampler) {
@ -3115,7 +3153,8 @@ decompress_texture_image(struct gl_context *ctx,
_mesa_set_viewport(ctx, 0, 0, 0, width, height); _mesa_set_viewport(ctx, 0, 0, 0, width, height);
/* upload new vertex data */ /* upload new vertex data */
_mesa_BufferSubData(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts); _mesa_buffer_sub_data(ctx, decompress->buf_obj, 0, sizeof(verts), verts,
__func__);
/* setup texture state */ /* setup texture state */
_mesa_BindTexture(target, texObj->Name); _mesa_BindTexture(target, texObj->Name);
@ -3259,36 +3298,45 @@ _mesa_meta_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z,
if (drawtex->VAO == 0) { if (drawtex->VAO == 0) {
/* one-time setup */ /* one-time setup */
GLint active_texture; struct gl_vertex_array_object *array_obj;
/* create vertex array object */ /* create vertex array object */
_mesa_GenVertexArrays(1, &drawtex->VAO); _mesa_GenVertexArrays(1, &drawtex->VAO);
_mesa_BindVertexArray(drawtex->VAO); _mesa_BindVertexArray(drawtex->VAO);
/* create vertex array buffer */ array_obj = _mesa_lookup_vao(ctx, drawtex->VAO);
_mesa_GenBuffers(1, &drawtex->VBO); assert(array_obj != NULL);
_mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, drawtex->VBO);
_mesa_BufferData(GL_ARRAY_BUFFER_ARB, sizeof(verts),
NULL, GL_DYNAMIC_DRAW_ARB);
/* client active texture is not part of the array object */ /* create vertex array buffer */
active_texture = ctx->Array.ActiveTexture; drawtex->buf_obj = ctx->Driver.NewBufferObject(ctx, 0xDEADBEEF);
if (drawtex->buf_obj == NULL)
return;
_mesa_buffer_data(ctx, drawtex->buf_obj, GL_NONE, sizeof(verts), verts,
GL_DYNAMIC_DRAW, __func__);
/* setup vertex arrays */ /* setup vertex arrays */
_mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x)); _mesa_update_array_format(ctx, array_obj, VERT_ATTRIB_POS,
_mesa_EnableClientState(GL_VERTEX_ARRAY); 3, GL_FLOAT, GL_RGBA, GL_FALSE,
for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { GL_FALSE, GL_FALSE,
_mesa_ClientActiveTexture(GL_TEXTURE0 + i); offsetof(struct vertex, x), true);
_mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(st[i])); _mesa_bind_vertex_buffer(ctx, array_obj, VERT_ATTRIB_POS,
_mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY); drawtex->buf_obj, 0, sizeof(struct vertex));
} _mesa_enable_vertex_array_attrib(ctx, array_obj, VERT_ATTRIB_POS);
/* restore client active texture */
_mesa_ClientActiveTexture(GL_TEXTURE0 + active_texture); for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
_mesa_update_array_format(ctx, array_obj, VERT_ATTRIB_TEX(i),
2, GL_FLOAT, GL_RGBA, GL_FALSE,
GL_FALSE, GL_FALSE,
offsetof(struct vertex, st[i]), true);
_mesa_bind_vertex_buffer(ctx, array_obj, VERT_ATTRIB_TEX(i),
drawtex->buf_obj, 0, sizeof(struct vertex));
_mesa_enable_vertex_array_attrib(ctx, array_obj, VERT_ATTRIB_TEX(i));
}
} }
else { else {
_mesa_BindVertexArray(drawtex->VAO); _mesa_BindVertexArray(drawtex->VAO);
_mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, drawtex->VBO);
} }
/* vertex positions, texcoords */ /* vertex positions, texcoords */
@ -3353,7 +3401,8 @@ _mesa_meta_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z,
verts[3].st[i][1] = t1; verts[3].st[i][1] = t1;
} }
_mesa_BufferSubData(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts); _mesa_buffer_sub_data(ctx, drawtex->buf_obj, 0, sizeof(verts), verts,
__func__);
} }
_mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);

View File

@ -297,7 +297,7 @@ enum blit_msaa_shader {
struct blit_state struct blit_state
{ {
GLuint VAO; GLuint VAO;
GLuint VBO; struct gl_buffer_object *buf_obj;
struct blit_shader_table shaders_with_depth; struct blit_shader_table shaders_with_depth;
struct blit_shader_table shaders_without_depth; struct blit_shader_table shaders_without_depth;
GLuint msaa_shaders[BLIT_MSAA_SHADER_COUNT]; GLuint msaa_shaders[BLIT_MSAA_SHADER_COUNT];
@ -319,7 +319,7 @@ struct fb_tex_blit_state
struct clear_state struct clear_state
{ {
GLuint VAO; GLuint VAO;
GLuint VBO; struct gl_buffer_object *buf_obj;
GLuint ShaderProg; GLuint ShaderProg;
GLint ColorLocation; GLint ColorLocation;
GLint LayerLocation; GLint LayerLocation;
@ -336,7 +336,7 @@ struct clear_state
struct copypix_state struct copypix_state
{ {
GLuint VAO; GLuint VAO;
GLuint VBO; struct gl_buffer_object *buf_obj;
}; };
@ -346,7 +346,7 @@ struct copypix_state
struct drawpix_state struct drawpix_state
{ {
GLuint VAO; GLuint VAO;
GLuint VBO; struct gl_buffer_object *buf_obj;
GLuint StencilFP; /**< Fragment program for drawing stencil images */ GLuint StencilFP; /**< Fragment program for drawing stencil images */
GLuint DepthFP; /**< Fragment program for drawing depth images */ GLuint DepthFP; /**< Fragment program for drawing depth images */
@ -359,7 +359,7 @@ struct drawpix_state
struct bitmap_state struct bitmap_state
{ {
GLuint VAO; GLuint VAO;
GLuint VBO; struct gl_buffer_object *buf_obj;
struct temp_texture Tex; /**< separate texture from other meta ops */ struct temp_texture Tex; /**< separate texture from other meta ops */
}; };
@ -369,7 +369,7 @@ struct bitmap_state
struct gen_mipmap_state struct gen_mipmap_state
{ {
GLuint VAO; GLuint VAO;
GLuint VBO; struct gl_buffer_object *buf_obj;
GLuint FBO; GLuint FBO;
GLuint Sampler; GLuint Sampler;
@ -393,7 +393,8 @@ struct decompress_state
{ {
GLuint VAO; GLuint VAO;
struct decompress_fbo_state byteFBO, floatFBO; struct decompress_fbo_state byteFBO, floatFBO;
GLuint VBO, Sampler; struct gl_buffer_object *buf_obj;
GLuint Sampler;
struct blit_shader_table shaders; struct blit_shader_table shaders;
}; };
@ -404,7 +405,7 @@ struct decompress_state
struct drawtex_state struct drawtex_state
{ {
GLuint VAO; GLuint VAO;
GLuint VBO; struct gl_buffer_object *buf_obj;
}; };
#define MAX_META_OPS_DEPTH 8 #define MAX_META_OPS_DEPTH 8
@ -615,13 +616,15 @@ struct temp_texture *
_mesa_meta_get_temp_depth_texture(struct gl_context *ctx); _mesa_meta_get_temp_depth_texture(struct gl_context *ctx);
void void
_mesa_meta_setup_vertex_objects(GLuint *VAO, GLuint *VBO, _mesa_meta_setup_vertex_objects(struct gl_context *ctx,
GLuint *VAO, struct gl_buffer_object **buf_obj,
bool use_generic_attributes, bool use_generic_attributes,
unsigned vertex_size, unsigned texcoord_size, unsigned vertex_size, unsigned texcoord_size,
unsigned color_size); unsigned color_size);
void void
_mesa_meta_setup_ff_tnl_for_blit(GLuint *VAO, GLuint *VBO, _mesa_meta_setup_ff_tnl_for_blit(struct gl_context *ctx,
GLuint *VAO, struct gl_buffer_object **buf_obj,
unsigned texcoord_size); unsigned texcoord_size);
void void
@ -647,13 +650,14 @@ _mesa_meta_setup_blit_shader(struct gl_context *ctx,
struct blit_shader_table *table); struct blit_shader_table *table);
void void
_mesa_meta_glsl_blit_cleanup(struct blit_state *blit); _mesa_meta_glsl_blit_cleanup(struct gl_context *ctx, struct blit_state *blit);
void void
_mesa_meta_blit_shader_table_cleanup(struct blit_shader_table *table); _mesa_meta_blit_shader_table_cleanup(struct blit_shader_table *table);
void void
_mesa_meta_glsl_generate_mipmap_cleanup(struct gen_mipmap_state *mipmap); _mesa_meta_glsl_generate_mipmap_cleanup(struct gl_context *ctx,
struct gen_mipmap_state *mipmap);
void void
_mesa_meta_bind_fbo_image(GLenum target, GLenum attachment, _mesa_meta_bind_fbo_image(GLenum target, GLenum attachment,

View File

@ -533,7 +533,7 @@ setup_glsl_blit_framebuffer(struct gl_context *ctx,
texcoord_size = 2 + (src_rb->Depth > 1 ? 1 : 0); texcoord_size = 2 + (src_rb->Depth > 1 ? 1 : 0);
_mesa_meta_setup_vertex_objects(&blit->VAO, &blit->VBO, true, _mesa_meta_setup_vertex_objects(ctx, &blit->VAO, &blit->buf_obj, true,
2, texcoord_size, 0); 2, texcoord_size, 0);
if (is_target_multisample && is_filter_scaled_resolve && is_scaled_blit) { if (is_target_multisample && is_filter_scaled_resolve && is_scaled_blit) {
@ -659,8 +659,9 @@ blitframebuffer_texture(struct gl_context *ctx,
do_depth); do_depth);
} }
else { else {
_mesa_meta_setup_ff_tnl_for_blit(&ctx->Meta->Blit.VAO, _mesa_meta_setup_ff_tnl_for_blit(ctx,
&ctx->Meta->Blit.VBO, &ctx->Meta->Blit.VAO,
&ctx->Meta->Blit.buf_obj,
2); 2);
} }
@ -757,7 +758,8 @@ blitframebuffer_texture(struct gl_context *ctx,
verts[3].tex[1] = t1; verts[3].tex[1] = t1;
verts[3].tex[2] = readAtt->Zoffset; verts[3].tex[2] = readAtt->Zoffset;
_mesa_BufferSubData(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts); _mesa_buffer_sub_data(ctx, blit->buf_obj, 0, sizeof(verts), verts,
__func__);
} }
/* setup viewport */ /* setup viewport */
@ -972,13 +974,12 @@ _mesa_meta_BlitFramebuffer(struct gl_context *ctx,
} }
void void
_mesa_meta_glsl_blit_cleanup(struct blit_state *blit) _mesa_meta_glsl_blit_cleanup(struct gl_context *ctx, struct blit_state *blit)
{ {
if (blit->VAO) { if (blit->VAO) {
_mesa_DeleteVertexArrays(1, &blit->VAO); _mesa_DeleteVertexArrays(1, &blit->VAO);
blit->VAO = 0; blit->VAO = 0;
_mesa_DeleteBuffers(1, &blit->VBO); _mesa_reference_buffer_object(ctx, &blit->buf_obj, NULL);
blit->VBO = 0;
} }
_mesa_meta_blit_shader_table_cleanup(&blit->shaders_with_depth); _mesa_meta_blit_shader_table_cleanup(&blit->shaders_with_depth);

View File

@ -62,6 +62,15 @@ fallback_required(struct gl_context *ctx, GLenum target,
GLuint srcLevel; GLuint srcLevel;
GLenum status; GLenum status;
/* GL_DRAW_FRAMEBUFFER does not exist in OpenGL ES 1.x, and since
* _mesa_meta_begin hasn't been called yet, we have to work-around API
* difficulties. The whole reason that GL_DRAW_FRAMEBUFFER is used instead
* of GL_FRAMEBUFFER is that the read framebuffer may be different. This
* is moot in OpenGL ES 1.x.
*/
const GLenum fbo_target = ctx->API == API_OPENGLES
? GL_FRAMEBUFFER : GL_DRAW_FRAMEBUFFER;
/* check for fallbacks */ /* check for fallbacks */
if (target == GL_TEXTURE_3D) { if (target == GL_TEXTURE_3D) {
_mesa_perf_debug(ctx, MESA_DEBUG_SEVERITY_HIGH, _mesa_perf_debug(ctx, MESA_DEBUG_SEVERITY_HIGH,
@ -102,13 +111,13 @@ fallback_required(struct gl_context *ctx, GLenum target,
*/ */
if (!mipmap->FBO) if (!mipmap->FBO)
_mesa_GenFramebuffers(1, &mipmap->FBO); _mesa_GenFramebuffers(1, &mipmap->FBO);
_mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, mipmap->FBO); _mesa_BindFramebuffer(fbo_target, mipmap->FBO);
_mesa_meta_bind_fbo_image(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, baseImage, 0); _mesa_meta_bind_fbo_image(fbo_target, GL_COLOR_ATTACHMENT0, baseImage, 0);
status = _mesa_CheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); status = _mesa_CheckFramebufferStatus(fbo_target);
_mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, fboSave); _mesa_BindFramebuffer(fbo_target, fboSave);
if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
_mesa_perf_debug(ctx, MESA_DEBUG_SEVERITY_HIGH, _mesa_perf_debug(ctx, MESA_DEBUG_SEVERITY_HIGH,
@ -120,17 +129,22 @@ fallback_required(struct gl_context *ctx, GLenum target,
} }
void void
_mesa_meta_glsl_generate_mipmap_cleanup(struct gen_mipmap_state *mipmap) _mesa_meta_glsl_generate_mipmap_cleanup(struct gl_context *ctx,
struct gen_mipmap_state *mipmap)
{ {
if (mipmap->VAO == 0) if (mipmap->VAO == 0)
return; return;
_mesa_DeleteVertexArrays(1, &mipmap->VAO); _mesa_DeleteVertexArrays(1, &mipmap->VAO);
mipmap->VAO = 0; mipmap->VAO = 0;
_mesa_DeleteBuffers(1, &mipmap->VBO); _mesa_reference_buffer_object(ctx, &mipmap->buf_obj, NULL);
mipmap->VBO = 0;
_mesa_DeleteSamplers(1, &mipmap->Sampler); _mesa_DeleteSamplers(1, &mipmap->Sampler);
mipmap->Sampler = 0; mipmap->Sampler = 0;
if (mipmap->FBO != 0) {
_mesa_DeleteFramebuffers(1, &mipmap->FBO);
mipmap->FBO = 0;
}
_mesa_meta_blit_shader_table_cleanup(&mipmap->shaders); _mesa_meta_blit_shader_table_cleanup(&mipmap->shaders);
} }
@ -192,11 +206,11 @@ _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target,
* GenerateMipmap function. * GenerateMipmap function.
*/ */
if (use_glsl_version) { if (use_glsl_version) {
_mesa_meta_setup_vertex_objects(&mipmap->VAO, &mipmap->VBO, true, _mesa_meta_setup_vertex_objects(ctx, &mipmap->VAO, &mipmap->buf_obj, true,
2, 4, 0); 2, 4, 0);
_mesa_meta_setup_blit_shader(ctx, target, false, &mipmap->shaders); _mesa_meta_setup_blit_shader(ctx, target, false, &mipmap->shaders);
} else { } else {
_mesa_meta_setup_ff_tnl_for_blit(&mipmap->VAO, &mipmap->VBO, 3); _mesa_meta_setup_ff_tnl_for_blit(ctx, &mipmap->VAO, &mipmap->buf_obj, 3);
_mesa_set_enable(ctx, target, GL_TRUE); _mesa_set_enable(ctx, target, GL_TRUE);
} }
@ -331,8 +345,8 @@ _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target,
verts[3].tex); verts[3].tex);
/* upload vertex data */ /* upload vertex data */
_mesa_BufferData(GL_ARRAY_BUFFER_ARB, sizeof(verts), _mesa_buffer_data(ctx, mipmap->buf_obj, GL_NONE, sizeof(verts), verts,
verts, GL_DYNAMIC_DRAW_ARB); GL_DYNAMIC_DRAW, __func__);
_mesa_meta_bind_fbo_image(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, dstImage, layer); _mesa_meta_bind_fbo_image(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, dstImage, layer);

View File

@ -64,11 +64,12 @@ need_signed_unsigned_int_conversion(mesa_format mesaFormat,
} }
static struct gl_texture_image * static struct gl_texture_image *
create_texture_for_pbo(struct gl_context *ctx, bool create_pbo, create_texture_for_pbo(struct gl_context *ctx,
GLenum pbo_target, int width, int height, bool create_pbo, GLenum pbo_target,
int dims, int width, int height, int depth,
GLenum format, GLenum type, const void *pixels, GLenum format, GLenum type, const void *pixels,
const struct gl_pixelstore_attrib *packing, const struct gl_pixelstore_attrib *packing,
GLuint *tmp_pbo, GLuint *tmp_tex) struct gl_buffer_object **tmp_pbo, GLuint *tmp_tex)
{ {
uint32_t pbo_format; uint32_t pbo_format;
GLenum internal_format; GLenum internal_format;
@ -91,40 +92,45 @@ create_texture_for_pbo(struct gl_context *ctx, bool create_pbo,
return NULL; return NULL;
/* Account for SKIP_PIXELS, SKIP_ROWS, ALIGNMENT, and SKIP_IMAGES */ /* Account for SKIP_PIXELS, SKIP_ROWS, ALIGNMENT, and SKIP_IMAGES */
pixels = _mesa_image_address3d(packing, pixels, uint32_t first_pixel = _mesa_image_offset(dims, packing, width, height,
width, height, format, type, 0, 0, 0); format, type,
0, 0, 0);
uint32_t last_pixel = _mesa_image_offset(dims, packing, width, height,
format, type,
depth-1, height-1, width);
row_stride = _mesa_image_row_stride(packing, width, format, type); row_stride = _mesa_image_row_stride(packing, width, format, type);
if (_mesa_is_bufferobj(packing->BufferObj)) { if (_mesa_is_bufferobj(packing->BufferObj)) {
*tmp_pbo = 0; *tmp_pbo = NULL;
buffer_obj = packing->BufferObj; buffer_obj = packing->BufferObj;
first_pixel += (intptr_t)pixels;
} else { } else {
bool is_pixel_pack = pbo_target == GL_PIXEL_PACK_BUFFER; bool is_pixel_pack = pbo_target == GL_PIXEL_PACK_BUFFER;
assert(create_pbo); assert(create_pbo);
_mesa_GenBuffers(1, tmp_pbo); *tmp_pbo = ctx->Driver.NewBufferObject(ctx, 0xDEADBEEF);
if (*tmp_pbo == NULL)
/* We are not doing this inside meta_begin/end. However, we know the return NULL;
* client doesn't have the given target bound, so we can go ahead and
* squash it. We'll set it back when we're done.
*/
_mesa_BindBuffer(pbo_target, *tmp_pbo);
/* In case of GL_PIXEL_PACK_BUFFER, pass null pointer for the pixel /* In case of GL_PIXEL_PACK_BUFFER, pass null pointer for the pixel
* data to avoid unnecessary data copying in _mesa_BufferData(). * data to avoid unnecessary data copying in _mesa_buffer_data.
*/ */
if (is_pixel_pack) if (is_pixel_pack)
_mesa_BufferData(pbo_target, row_stride * height, NULL, _mesa_buffer_data(ctx, *tmp_pbo, GL_NONE,
GL_STREAM_READ); last_pixel - first_pixel,
NULL,
GL_STREAM_READ,
__func__);
else else
_mesa_BufferData(pbo_target, row_stride * height, pixels, _mesa_buffer_data(ctx, *tmp_pbo, GL_NONE,
GL_STREAM_DRAW); last_pixel - first_pixel,
(char *)pixels + first_pixel,
GL_STREAM_DRAW,
__func__);
buffer_obj = packing->BufferObj; buffer_obj = *tmp_pbo;
pixels = NULL; first_pixel = 0;
_mesa_BindBuffer(pbo_target, 0);
} }
_mesa_GenTextures(1, tmp_tex); _mesa_GenTextures(1, tmp_tex);
@ -137,18 +143,25 @@ create_texture_for_pbo(struct gl_context *ctx, bool create_pbo,
internal_format = _mesa_get_format_base_format(pbo_format); internal_format = _mesa_get_format_base_format(pbo_format);
/* The texture is addressed as a single very-tall image, so we
* need to pack the multiple image depths together taking the
* inter-image padding into account.
*/
int image_height = packing->ImageHeight == 0 ? height : packing->ImageHeight;
int full_height = image_height * (depth - 1) + height;
tex_image = _mesa_get_tex_image(ctx, tex_obj, tex_obj->Target, 0); tex_image = _mesa_get_tex_image(ctx, tex_obj, tex_obj->Target, 0);
_mesa_init_teximage_fields(ctx, tex_image, width, height, 1, _mesa_init_teximage_fields(ctx, tex_image, width, full_height, 1,
0, internal_format, pbo_format); 0, internal_format, pbo_format);
read_only = pbo_target == GL_PIXEL_UNPACK_BUFFER; read_only = pbo_target == GL_PIXEL_UNPACK_BUFFER;
if (!ctx->Driver.SetTextureStorageForBufferObject(ctx, tex_obj, if (!ctx->Driver.SetTextureStorageForBufferObject(ctx, tex_obj,
buffer_obj, buffer_obj,
(intptr_t)pixels, first_pixel,
row_stride, row_stride,
read_only)) { read_only)) {
_mesa_DeleteTextures(1, tmp_tex); _mesa_DeleteTextures(1, tmp_tex);
_mesa_DeleteBuffers(1, tmp_pbo); _mesa_reference_buffer_object(ctx, tmp_pbo, NULL);
return NULL; return NULL;
} }
@ -164,8 +177,9 @@ _mesa_meta_pbo_TexSubImage(struct gl_context *ctx, GLuint dims,
bool allocate_storage, bool create_pbo, bool allocate_storage, bool create_pbo,
const struct gl_pixelstore_attrib *packing) const struct gl_pixelstore_attrib *packing)
{ {
GLuint pbo = 0, pbo_tex = 0, fbos[2] = { 0, 0 }; struct gl_buffer_object *pbo = NULL;
int full_height, image_height; GLuint pbo_tex = 0, fbos[2] = { 0, 0 };
int image_height;
struct gl_texture_image *pbo_tex_image; struct gl_texture_image *pbo_tex_image;
GLenum status; GLenum status;
bool success = false; bool success = false;
@ -196,11 +210,10 @@ _mesa_meta_pbo_TexSubImage(struct gl_context *ctx, GLuint dims,
* property. * property.
*/ */
image_height = packing->ImageHeight == 0 ? height : packing->ImageHeight; image_height = packing->ImageHeight == 0 ? height : packing->ImageHeight;
full_height = image_height * (depth - 1) + height;
pbo_tex_image = create_texture_for_pbo(ctx, create_pbo, pbo_tex_image = create_texture_for_pbo(ctx, create_pbo,
GL_PIXEL_UNPACK_BUFFER, GL_PIXEL_UNPACK_BUFFER,
width, full_height, dims, width, height, depth,
format, type, pixels, packing, format, type, pixels, packing,
&pbo, &pbo_tex); &pbo, &pbo_tex);
if (!pbo_tex_image) if (!pbo_tex_image)
@ -268,7 +281,7 @@ _mesa_meta_pbo_TexSubImage(struct gl_context *ctx, GLuint dims,
fail: fail:
_mesa_DeleteFramebuffers(2, fbos); _mesa_DeleteFramebuffers(2, fbos);
_mesa_DeleteTextures(1, &pbo_tex); _mesa_DeleteTextures(1, &pbo_tex);
_mesa_DeleteBuffers(1, &pbo); _mesa_reference_buffer_object(ctx, &pbo, NULL);
_mesa_meta_end(ctx); _mesa_meta_end(ctx);
@ -283,8 +296,9 @@ _mesa_meta_pbo_GetTexSubImage(struct gl_context *ctx, GLuint dims,
GLenum format, GLenum type, const void *pixels, GLenum format, GLenum type, const void *pixels,
const struct gl_pixelstore_attrib *packing) const struct gl_pixelstore_attrib *packing)
{ {
GLuint pbo = 0, pbo_tex = 0, fbos[2] = { 0, 0 }; struct gl_buffer_object *pbo = NULL;
int full_height, image_height; GLuint pbo_tex = 0, fbos[2] = { 0, 0 };
int image_height;
struct gl_texture_image *pbo_tex_image; struct gl_texture_image *pbo_tex_image;
struct gl_renderbuffer *rb = NULL; struct gl_renderbuffer *rb = NULL;
GLenum dstBaseFormat = _mesa_unpack_format_to_base_format(format); GLenum dstBaseFormat = _mesa_unpack_format_to_base_format(format);
@ -331,10 +345,9 @@ _mesa_meta_pbo_GetTexSubImage(struct gl_context *ctx, GLuint dims,
* property. * property.
*/ */
image_height = packing->ImageHeight == 0 ? height : packing->ImageHeight; image_height = packing->ImageHeight == 0 ? height : packing->ImageHeight;
full_height = image_height * (depth - 1) + height;
pbo_tex_image = create_texture_for_pbo(ctx, false, GL_PIXEL_PACK_BUFFER, pbo_tex_image = create_texture_for_pbo(ctx, false, GL_PIXEL_PACK_BUFFER,
width, full_height * depth, dims, width, height, depth,
format, type, pixels, packing, format, type, pixels, packing,
&pbo, &pbo_tex); &pbo, &pbo_tex);
if (!pbo_tex_image) if (!pbo_tex_image)
@ -441,7 +454,7 @@ _mesa_meta_pbo_GetTexSubImage(struct gl_context *ctx, GLuint dims,
fail: fail:
_mesa_DeleteFramebuffers(2, fbos); _mesa_DeleteFramebuffers(2, fbos);
_mesa_DeleteTextures(1, &pbo_tex); _mesa_DeleteTextures(1, &pbo_tex);
_mesa_DeleteBuffers(1, &pbo); _mesa_reference_buffer_object(ctx, &pbo, NULL);
_mesa_meta_end(ctx); _mesa_meta_end(ctx);

View File

@ -59,6 +59,9 @@ extern char *program_invocation_name, *program_invocation_short_name;
#elif defined(__NetBSD__) && defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 106000100) #elif defined(__NetBSD__) && defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 106000100)
# include <stdlib.h> # include <stdlib.h>
# define GET_PROGRAM_NAME() getprogname() # define GET_PROGRAM_NAME() getprogname()
#elif defined(__DragonFly__)
# include <stdlib.h>
# define GET_PROGRAM_NAME() getprogname()
#elif defined(__APPLE__) #elif defined(__APPLE__)
# include <stdlib.h> # include <stdlib.h>
# define GET_PROGRAM_NAME() getprogname() # define GET_PROGRAM_NAME() getprogname()

View File

@ -189,6 +189,24 @@ intel_update_state(struct gl_context * ctx, GLuint new_state)
brw_render_cache_set_check_flush(brw, tex_obj->mt->bo); brw_render_cache_set_check_flush(brw, tex_obj->mt->bo);
} }
/* Resolve color for each active shader image. */
for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
const struct gl_shader *shader = ctx->_Shader->CurrentProgram[i] ?
ctx->_Shader->CurrentProgram[i]->_LinkedShaders[i] : NULL;
if (unlikely(shader && shader->NumImages)) {
for (unsigned j = 0; j < shader->NumImages; j++) {
struct gl_image_unit *u = &ctx->ImageUnits[shader->ImageUnits[j]];
tex_obj = intel_texture_object(u->TexObj);
if (tex_obj && tex_obj->mt) {
intel_miptree_resolve_color(brw, tex_obj->mt);
brw_render_cache_set_check_flush(brw, tex_obj->mt->bo);
}
}
}
}
_mesa_lock_context_textures(ctx); _mesa_lock_context_textures(ctx);
} }

View File

@ -1039,33 +1039,19 @@ fs_visitor::emit_linterp(const fs_reg &attr, const fs_reg &interp,
} }
void void
fs_visitor::emit_general_interpolation(fs_reg attr, const char *name, fs_visitor::emit_general_interpolation(fs_reg *attr, const char *name,
const glsl_type *type, const glsl_type *type,
glsl_interp_qualifier interpolation_mode, glsl_interp_qualifier interpolation_mode,
int location, bool mod_centroid, int *location, bool mod_centroid,
bool mod_sample) bool mod_sample)
{ {
attr.type = brw_type_for_base_type(type->get_scalar_type());
assert(stage == MESA_SHADER_FRAGMENT); assert(stage == MESA_SHADER_FRAGMENT);
brw_wm_prog_data *prog_data = (brw_wm_prog_data*) this->prog_data; brw_wm_prog_data *prog_data = (brw_wm_prog_data*) this->prog_data;
brw_wm_prog_key *key = (brw_wm_prog_key*) this->key; brw_wm_prog_key *key = (brw_wm_prog_key*) this->key;
unsigned int array_elements;
if (type->is_array()) {
array_elements = type->length;
if (array_elements == 0) {
fail("dereferenced array '%s' has length 0\n", name);
}
type = type->fields.array;
} else {
array_elements = 1;
}
if (interpolation_mode == INTERP_QUALIFIER_NONE) { if (interpolation_mode == INTERP_QUALIFIER_NONE) {
bool is_gl_Color = bool is_gl_Color =
location == VARYING_SLOT_COL0 || location == VARYING_SLOT_COL1; *location == VARYING_SLOT_COL0 || *location == VARYING_SLOT_COL1;
if (key->flat_shade && is_gl_Color) { if (key->flat_shade && is_gl_Color) {
interpolation_mode = INTERP_QUALIFIER_FLAT; interpolation_mode = INTERP_QUALIFIER_FLAT;
} else { } else {
@ -1073,71 +1059,86 @@ fs_visitor::emit_general_interpolation(fs_reg attr, const char *name,
} }
} }
for (unsigned int i = 0; i < array_elements; i++) { if (type->is_array() || type->is_matrix()) {
for (unsigned int j = 0; j < type->matrix_columns; j++) { const glsl_type *elem_type = glsl_get_array_element(type);
if (prog_data->urb_setup[location] == -1) { const unsigned length = glsl_get_length(type);
/* If there's no incoming setup data for this slot, don't
* emit interpolation for it.
*/
attr = offset(attr, bld, type->vector_elements);
location++;
continue;
}
if (interpolation_mode == INTERP_QUALIFIER_FLAT) { for (unsigned i = 0; i < length; i++) {
/* Constant interpolation (flat shading) case. The SF has emit_general_interpolation(attr, name, elem_type, interpolation_mode,
* handed us defined values in only the constant offset location, mod_centroid, mod_sample);
* field of the setup reg.
*/
for (unsigned int k = 0; k < type->vector_elements; k++) {
struct brw_reg interp = interp_reg(location, k);
interp = suboffset(interp, 3);
interp.type = attr.type;
bld.emit(FS_OPCODE_CINTERP, attr, fs_reg(interp));
attr = offset(attr, bld, 1);
}
} else {
/* Smooth/noperspective interpolation case. */
for (unsigned int k = 0; k < type->vector_elements; k++) {
struct brw_reg interp = interp_reg(location, k);
if (devinfo->needs_unlit_centroid_workaround && mod_centroid) {
/* Get the pixel/sample mask into f0 so that we know
* which pixels are lit. Then, for each channel that is
* unlit, replace the centroid data with non-centroid
* data.
*/
bld.emit(FS_OPCODE_MOV_DISPATCH_TO_FLAGS);
fs_inst *inst;
inst = emit_linterp(attr, fs_reg(interp), interpolation_mode,
false, false);
inst->predicate = BRW_PREDICATE_NORMAL;
inst->predicate_inverse = true;
if (devinfo->has_pln)
inst->no_dd_clear = true;
inst = emit_linterp(attr, fs_reg(interp), interpolation_mode,
mod_centroid && !key->persample_shading,
mod_sample || key->persample_shading);
inst->predicate = BRW_PREDICATE_NORMAL;
inst->predicate_inverse = false;
if (devinfo->has_pln)
inst->no_dd_check = true;
} else {
emit_linterp(attr, fs_reg(interp), interpolation_mode,
mod_centroid && !key->persample_shading,
mod_sample || key->persample_shading);
}
if (devinfo->gen < 6 && interpolation_mode == INTERP_QUALIFIER_SMOOTH) {
bld.MUL(attr, attr, this->pixel_w);
}
attr = offset(attr, bld, 1);
}
}
location++;
} }
} else if (type->is_record()) {
for (unsigned i = 0; i < type->length; i++) {
const glsl_type *field_type = type->fields.structure[i].type;
emit_general_interpolation(attr, name, field_type, interpolation_mode,
location, mod_centroid, mod_sample);
}
} else {
assert(type->is_scalar() || type->is_vector());
if (prog_data->urb_setup[*location] == -1) {
/* If there's no incoming setup data for this slot, don't
* emit interpolation for it.
*/
*attr = offset(*attr, bld, type->vector_elements);
(*location)++;
return;
}
attr->type = brw_type_for_base_type(type->get_scalar_type());
if (interpolation_mode == INTERP_QUALIFIER_FLAT) {
/* Constant interpolation (flat shading) case. The SF has
* handed us defined values in only the constant offset
* field of the setup reg.
*/
for (unsigned int i = 0; i < type->vector_elements; i++) {
struct brw_reg interp = interp_reg(*location, i);
interp = suboffset(interp, 3);
interp.type = attr->type;
bld.emit(FS_OPCODE_CINTERP, *attr, fs_reg(interp));
*attr = offset(*attr, bld, 1);
}
} else {
/* Smooth/noperspective interpolation case. */
for (unsigned int i = 0; i < type->vector_elements; i++) {
struct brw_reg interp = interp_reg(*location, i);
if (devinfo->needs_unlit_centroid_workaround && mod_centroid) {
/* Get the pixel/sample mask into f0 so that we know
* which pixels are lit. Then, for each channel that is
* unlit, replace the centroid data with non-centroid
* data.
*/
bld.emit(FS_OPCODE_MOV_DISPATCH_TO_FLAGS);
fs_inst *inst;
inst = emit_linterp(*attr, fs_reg(interp), interpolation_mode,
false, false);
inst->predicate = BRW_PREDICATE_NORMAL;
inst->predicate_inverse = true;
if (devinfo->has_pln)
inst->no_dd_clear = true;
inst = emit_linterp(*attr, fs_reg(interp), interpolation_mode,
mod_centroid && !key->persample_shading,
mod_sample || key->persample_shading);
inst->predicate = BRW_PREDICATE_NORMAL;
inst->predicate_inverse = false;
if (devinfo->has_pln)
inst->no_dd_check = true;
} else {
emit_linterp(*attr, fs_reg(interp), interpolation_mode,
mod_centroid && !key->persample_shading,
mod_sample || key->persample_shading);
}
if (devinfo->gen < 6 && interpolation_mode == INTERP_QUALIFIER_SMOOTH) {
bld.MUL(*attr, *attr, this->pixel_w);
}
*attr = offset(*attr, bld, 1);
}
}
(*location)++;
} }
} }

View File

@ -197,10 +197,10 @@ public:
fs_reg *emit_frontfacing_interpolation(); fs_reg *emit_frontfacing_interpolation();
fs_reg *emit_samplepos_setup(); fs_reg *emit_samplepos_setup();
fs_reg *emit_sampleid_setup(); fs_reg *emit_sampleid_setup();
void emit_general_interpolation(fs_reg attr, const char *name, void emit_general_interpolation(fs_reg *attr, const char *name,
const glsl_type *type, const glsl_type *type,
glsl_interp_qualifier interpolation_mode, glsl_interp_qualifier interpolation_mode,
int location, bool mod_centroid, int *location, bool mod_centroid,
bool mod_sample); bool mod_sample);
fs_reg *emit_vs_system_value(int location); fs_reg *emit_vs_system_value(int location);
void emit_interpolation_setup_gen4(); void emit_interpolation_setup_gen4();
@ -240,6 +240,8 @@ public:
void emit_nir_code(); void emit_nir_code();
void nir_setup_inputs(nir_shader *shader); void nir_setup_inputs(nir_shader *shader);
void nir_setup_single_output_varying(fs_reg &reg, const glsl_type *type,
unsigned &location);
void nir_setup_outputs(nir_shader *shader); void nir_setup_outputs(nir_shader *shader);
void nir_setup_uniforms(nir_shader *shader); void nir_setup_uniforms(nir_shader *shader);
void nir_setup_uniform(nir_variable *var); void nir_setup_uniform(nir_variable *var);

View File

@ -105,9 +105,10 @@ fs_visitor::nir_setup_inputs(nir_shader *shader)
emit_percomp(bld, fs_inst(BRW_OPCODE_MOV, bld.dispatch_width(), emit_percomp(bld, fs_inst(BRW_OPCODE_MOV, bld.dispatch_width(),
input, reg), 0xF); input, reg), 0xF);
} else { } else {
emit_general_interpolation(input, var->name, var->type, int location = var->data.location;
emit_general_interpolation(&input, var->name, var->type,
(glsl_interp_qualifier) var->data.interpolation, (glsl_interp_qualifier) var->data.interpolation,
var->data.location, var->data.centroid, &location, var->data.centroid,
var->data.sample); var->data.sample);
} }
break; break;
@ -115,6 +116,32 @@ fs_visitor::nir_setup_inputs(nir_shader *shader)
} }
} }
void
fs_visitor::nir_setup_single_output_varying(fs_reg &reg,
const glsl_type *type,
unsigned &location)
{
if (type->is_array() || type->is_matrix()) {
const struct glsl_type *elem_type = glsl_get_array_element(type);
const unsigned length = glsl_get_length(type);
for (unsigned i = 0; i < length; i++) {
nir_setup_single_output_varying(reg, elem_type, location);
}
} else if (type->is_record()) {
for (unsigned i = 0; i < type->length; i++) {
const struct glsl_type *field_type = type->fields.structure[i].type;
nir_setup_single_output_varying(reg, field_type, location);
}
} else {
assert(type->is_scalar() || type->is_vector());
this->outputs[location] = reg;
this->output_components[location] = type->vector_elements;
reg = offset(reg, bld, 4);
location++;
}
}
void void
fs_visitor::nir_setup_outputs(nir_shader *shader) fs_visitor::nir_setup_outputs(nir_shader *shader)
{ {
@ -130,13 +157,11 @@ fs_visitor::nir_setup_outputs(nir_shader *shader)
: var->type->vector_elements; : var->type->vector_elements;
switch (stage) { switch (stage) {
case MESA_SHADER_VERTEX: case MESA_SHADER_VERTEX: {
for (int i = 0; i < ALIGN(type_size(var->type), 4) / 4; i++) { unsigned location = var->data.location;
int output = var->data.location + i; nir_setup_single_output_varying(reg, var->type, location);
this->outputs[output] = offset(reg, bld, 4 * i);
this->output_components[output] = vector_elements;
}
break; break;
}
case MESA_SHADER_FRAGMENT: case MESA_SHADER_FRAGMENT:
if (var->data.index > 0) { if (var->data.index > 0) {
assert(var->data.location == FRAG_RESULT_DATA0); assert(var->data.location == FRAG_RESULT_DATA0);

View File

@ -54,8 +54,9 @@
#include "brw_blorp.h" #include "brw_blorp.h"
struct brw_fast_clear_state { struct brw_fast_clear_state {
struct gl_buffer_object *buf_obj;
struct gl_vertex_array_object *array_obj;
GLuint vao; GLuint vao;
GLuint vbo;
GLuint shader_prog; GLuint shader_prog;
GLint color_location; GLint color_location;
}; };
@ -64,11 +65,11 @@ static bool
brw_fast_clear_init(struct brw_context *brw) brw_fast_clear_init(struct brw_context *brw)
{ {
struct brw_fast_clear_state *clear; struct brw_fast_clear_state *clear;
struct gl_context *ctx = &brw->ctx;
if (brw->fast_clear_state) { if (brw->fast_clear_state) {
clear = brw->fast_clear_state; clear = brw->fast_clear_state;
_mesa_BindVertexArray(clear->vao); _mesa_BindVertexArray(clear->vao);
_mesa_BindBuffer(GL_ARRAY_BUFFER, clear->vbo);
return true; return true;
} }
@ -79,10 +80,21 @@ brw_fast_clear_init(struct brw_context *brw)
memset(clear, 0, sizeof *clear); memset(clear, 0, sizeof *clear);
_mesa_GenVertexArrays(1, &clear->vao); _mesa_GenVertexArrays(1, &clear->vao);
_mesa_BindVertexArray(clear->vao); _mesa_BindVertexArray(clear->vao);
_mesa_GenBuffers(1, &clear->vbo);
_mesa_BindBuffer(GL_ARRAY_BUFFER, clear->vbo); clear->buf_obj = ctx->Driver.NewBufferObject(ctx, 0xDEADBEEF);
_mesa_VertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0); if (clear->buf_obj == NULL)
_mesa_EnableVertexAttribArray(0); return false;
clear->array_obj = _mesa_lookup_vao(ctx, clear->vao);
assert(clear->array_obj != NULL);
_mesa_update_array_format(ctx, clear->array_obj, VERT_ATTRIB_GENERIC(0),
2, GL_FLOAT, GL_RGBA, GL_FALSE, GL_FALSE, GL_FALSE,
0, true);
_mesa_bind_vertex_buffer(ctx, clear->array_obj, VERT_ATTRIB_GENERIC(0),
clear->buf_obj, 0, sizeof(float) * 2);
_mesa_enable_vertex_array_attrib(ctx, clear->array_obj,
VERT_ATTRIB_GENERIC(0));
return true; return true;
} }
@ -150,7 +162,7 @@ brw_meta_fast_clear_free(struct brw_context *brw)
_mesa_make_current(&brw->ctx, NULL, NULL); _mesa_make_current(&brw->ctx, NULL, NULL);
_mesa_DeleteVertexArrays(1, &clear->vao); _mesa_DeleteVertexArrays(1, &clear->vao);
_mesa_DeleteBuffers(1, &clear->vbo); _mesa_reference_buffer_object(&brw->ctx, &clear->buf_obj, NULL);
_mesa_DeleteProgram(clear->shader_prog); _mesa_DeleteProgram(clear->shader_prog);
free(clear); free(clear);
@ -165,8 +177,10 @@ struct rect {
}; };
static void static void
brw_draw_rectlist(struct gl_context *ctx, struct rect *rect, int num_instances) brw_draw_rectlist(struct brw_context *brw, struct rect *rect, int num_instances)
{ {
struct gl_context *ctx = &brw->ctx;
struct brw_fast_clear_state *clear = brw->fast_clear_state;
int start = 0, count = 3; int start = 0, count = 3;
struct _mesa_prim prim; struct _mesa_prim prim;
float verts[6]; float verts[6];
@ -179,8 +193,8 @@ brw_draw_rectlist(struct gl_context *ctx, struct rect *rect, int num_instances)
verts[5] = rect->y0; verts[5] = rect->y0;
/* upload new vertex data */ /* upload new vertex data */
_mesa_BufferData(GL_ARRAY_BUFFER_ARB, sizeof(verts), verts, _mesa_buffer_data(ctx, clear->buf_obj, GL_NONE, sizeof(verts), verts,
GL_DYNAMIC_DRAW_ARB); GL_DYNAMIC_DRAW, __func__);
if (ctx->NewState) if (ctx->NewState)
_mesa_update_state(ctx); _mesa_update_state(ctx);
@ -582,14 +596,14 @@ brw_meta_fast_clear(struct brw_context *brw, struct gl_framebuffer *fb,
_mesa_meta_drawbuffers_from_bitfield(fast_clear_buffers); _mesa_meta_drawbuffers_from_bitfield(fast_clear_buffers);
brw_bind_rep_write_shader(brw, (float *) fast_clear_color); brw_bind_rep_write_shader(brw, (float *) fast_clear_color);
set_fast_clear_op(brw, GEN7_PS_RENDER_TARGET_FAST_CLEAR_ENABLE); set_fast_clear_op(brw, GEN7_PS_RENDER_TARGET_FAST_CLEAR_ENABLE);
brw_draw_rectlist(ctx, &fast_clear_rect, layers); brw_draw_rectlist(brw, &fast_clear_rect, layers);
set_fast_clear_op(brw, 0); set_fast_clear_op(brw, 0);
} }
if (rep_clear_buffers) { if (rep_clear_buffers) {
_mesa_meta_drawbuffers_from_bitfield(rep_clear_buffers); _mesa_meta_drawbuffers_from_bitfield(rep_clear_buffers);
brw_bind_rep_write_shader(brw, ctx->Color.ClearColor.f); brw_bind_rep_write_shader(brw, ctx->Color.ClearColor.f);
brw_draw_rectlist(ctx, &clear_rect, layers); brw_draw_rectlist(brw, &clear_rect, layers);
} }
/* Now set the mts we cleared to INTEL_FAST_CLEAR_STATE_CLEAR so we'll /* Now set the mts we cleared to INTEL_FAST_CLEAR_STATE_CLEAR so we'll
@ -701,7 +715,7 @@ brw_meta_resolve_color(struct brw_context *brw,
mt->fast_clear_state = INTEL_FAST_CLEAR_STATE_RESOLVED; mt->fast_clear_state = INTEL_FAST_CLEAR_STATE_RESOLVED;
get_resolve_rect(brw, mt, &rect); get_resolve_rect(brw, mt, &rect);
brw_draw_rectlist(ctx, &rect, 1); brw_draw_rectlist(brw, &rect, 1);
set_fast_clear_op(brw, 0); set_fast_clear_op(brw, 0);
use_rectlist(brw, false); use_rectlist(brw, false);

View File

@ -279,7 +279,8 @@ setup_program(struct brw_context *brw, bool msaa_tex)
char *fs_source; char *fs_source;
const struct sampler_and_fetch *sampler = &samplers[msaa_tex]; const struct sampler_and_fetch *sampler = &samplers[msaa_tex];
_mesa_meta_setup_vertex_objects(&blit->VAO, &blit->VBO, true, 2, 2, 0); _mesa_meta_setup_vertex_objects(&brw->ctx, &blit->VAO, &blit->buf_obj, true,
2, 2, 0);
GLuint *prog_id = &brw->meta_stencil_blit_programs[msaa_tex]; GLuint *prog_id = &brw->meta_stencil_blit_programs[msaa_tex];
@ -360,7 +361,7 @@ adjust_mip_level(const struct intel_mipmap_tree *mt,
} }
static void static void
prepare_vertex_data(void) prepare_vertex_data(struct gl_context *ctx, struct gl_buffer_object *buf_obj)
{ {
static const struct vertex verts[] = { static const struct vertex verts[] = {
{ .x = -1.0f, .y = -1.0f }, { .x = -1.0f, .y = -1.0f },
@ -368,7 +369,7 @@ prepare_vertex_data(void)
{ .x = 1.0f, .y = 1.0f }, { .x = 1.0f, .y = 1.0f },
{ .x = -1.0f, .y = 1.0f } }; { .x = -1.0f, .y = 1.0f } };
_mesa_BufferSubData(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts); _mesa_buffer_sub_data(ctx, buf_obj, 0, sizeof(verts), verts, __func__);
} }
static bool static bool
@ -448,7 +449,7 @@ brw_meta_stencil_blit(struct brw_context *brw,
_mesa_Uniform1i(_mesa_GetUniformLocation(prog, "dst_num_samples"), _mesa_Uniform1i(_mesa_GetUniformLocation(prog, "dst_num_samples"),
dst_mt->num_samples); dst_mt->num_samples);
prepare_vertex_data(); prepare_vertex_data(ctx, ctx->Meta->Blit.buf_obj);
_mesa_set_viewport(ctx, 0, dims.dst_x0, dims.dst_y0, _mesa_set_viewport(ctx, 0, dims.dst_x0, dims.dst_y0,
dims.dst_x1 - dims.dst_x0, dims.dst_y1 - dims.dst_y0); dims.dst_x1 - dims.dst_x0, dims.dst_y1 - dims.dst_y0);
_mesa_ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); _mesa_ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);

View File

@ -379,6 +379,7 @@ brw_format_for_mesa_format(mesa_format mesa_format)
[MESA_FORMAT_A8R8G8B8_SRGB] = 0, [MESA_FORMAT_A8R8G8B8_SRGB] = 0,
[MESA_FORMAT_R8G8B8A8_SRGB] = BRW_SURFACEFORMAT_R8G8B8A8_UNORM_SRGB, [MESA_FORMAT_R8G8B8A8_SRGB] = BRW_SURFACEFORMAT_R8G8B8A8_UNORM_SRGB,
[MESA_FORMAT_X8R8G8B8_SRGB] = 0, [MESA_FORMAT_X8R8G8B8_SRGB] = 0,
[MESA_FORMAT_B8G8R8X8_SRGB] = BRW_SURFACEFORMAT_B8G8R8X8_UNORM_SRGB,
[MESA_FORMAT_L_SRGB8] = BRW_SURFACEFORMAT_L8_UNORM_SRGB, [MESA_FORMAT_L_SRGB8] = BRW_SURFACEFORMAT_L8_UNORM_SRGB,
[MESA_FORMAT_L8A8_SRGB] = BRW_SURFACEFORMAT_L8A8_UNORM_SRGB, [MESA_FORMAT_L8A8_SRGB] = BRW_SURFACEFORMAT_L8A8_UNORM_SRGB,
[MESA_FORMAT_A8L8_SRGB] = 0, [MESA_FORMAT_A8L8_SRGB] = 0,
@ -614,6 +615,10 @@ brw_init_surface_formats(struct brw_context *brw)
*/ */
render = BRW_SURFACEFORMAT_B8G8R8A8_UNORM; render = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
break; break;
case BRW_SURFACEFORMAT_B8G8R8X8_UNORM_SRGB:
if (gen < tinfo->render_target)
render = BRW_SURFACEFORMAT_B8G8R8A8_UNORM_SRGB;
break;
case BRW_SURFACEFORMAT_R8G8B8X8_UNORM: case BRW_SURFACEFORMAT_R8G8B8X8_UNORM:
render = BRW_SURFACEFORMAT_R8G8B8A8_UNORM; render = BRW_SURFACEFORMAT_R8G8B8A8_UNORM;
break; break;

View File

@ -981,7 +981,7 @@ brw_upload_wm_abo_surfaces(struct brw_context *brw)
{ {
struct gl_context *ctx = &brw->ctx; struct gl_context *ctx = &brw->ctx;
/* _NEW_PROGRAM */ /* _NEW_PROGRAM */
struct gl_shader_program *prog = ctx->Shader._CurrentFragmentProgram; struct gl_shader_program *prog = ctx->_Shader->_CurrentFragmentProgram;
if (prog) { if (prog) {
/* BRW_NEW_FS_PROG_DATA */ /* BRW_NEW_FS_PROG_DATA */
@ -1257,7 +1257,7 @@ brw_upload_wm_image_surfaces(struct brw_context *brw)
{ {
struct gl_context *ctx = &brw->ctx; struct gl_context *ctx = &brw->ctx;
/* BRW_NEW_FRAGMENT_PROGRAM */ /* BRW_NEW_FRAGMENT_PROGRAM */
struct gl_shader_program *prog = ctx->Shader._CurrentFragmentProgram; struct gl_shader_program *prog = ctx->_Shader->_CurrentFragmentProgram;
if (prog) { if (prog) {
/* BRW_NEW_FS_PROG_DATA, BRW_NEW_IMAGE_UNITS, _NEW_TEXTURE */ /* BRW_NEW_FS_PROG_DATA, BRW_NEW_IMAGE_UNITS, _NEW_TEXTURE */

View File

@ -2018,12 +2018,18 @@ _mesa_error_check_format_and_type(const struct gl_context *ctx,
* \return error code, or GL_NO_ERROR. * \return error code, or GL_NO_ERROR.
*/ */
GLenum GLenum
_mesa_es_error_check_format_and_type(GLenum format, GLenum type, _mesa_es_error_check_format_and_type(const struct gl_context *ctx,
GLenum format, GLenum type,
unsigned dimensions) unsigned dimensions)
{ {
GLboolean type_valid = GL_TRUE; GLboolean type_valid = GL_TRUE;
switch (format) { switch (format) {
case GL_RED:
case GL_RG:
if (ctx->API == API_OPENGLES || !ctx->Extensions.ARB_texture_rg)
return GL_INVALID_VALUE;
/* fallthrough */
case GL_ALPHA: case GL_ALPHA:
case GL_LUMINANCE: case GL_LUMINANCE:
case GL_LUMINANCE_ALPHA: case GL_LUMINANCE_ALPHA:

View File

@ -124,7 +124,8 @@ _mesa_error_check_format_and_type(const struct gl_context *ctx,
GLenum format, GLenum type); GLenum format, GLenum type);
extern GLenum extern GLenum
_mesa_es_error_check_format_and_type(GLenum format, GLenum type, _mesa_es_error_check_format_and_type(const struct gl_context *ctx,
GLenum format, GLenum type,
unsigned dimensions); unsigned dimensions);
extern GLenum extern GLenum

View File

@ -1043,7 +1043,7 @@ _mesa_ReadnPixelsARB( GLint x, GLint y, GLsizei width, GLsizei height,
_mesa_get_color_read_type(ctx) == type) { _mesa_get_color_read_type(ctx) == type) {
err = GL_NO_ERROR; err = GL_NO_ERROR;
} else if (ctx->Version < 30) { } else if (ctx->Version < 30) {
err = _mesa_es_error_check_format_and_type(format, type, 2); err = _mesa_es_error_check_format_and_type(ctx, format, type, 2);
if (err == GL_NO_ERROR) { if (err == GL_NO_ERROR) {
if (type == GL_FLOAT || type == GL_HALF_FLOAT_OES) { if (type == GL_FLOAT || type == GL_HALF_FLOAT_OES) {
err = GL_INVALID_OPERATION; err = GL_INVALID_OPERATION;

View File

@ -776,13 +776,18 @@ program_resource_location(struct gl_shader_program *shProg,
* and user-defined attributes. * and user-defined attributes.
*/ */
switch (res->Type) { switch (res->Type) {
case GL_PROGRAM_INPUT: case GL_PROGRAM_INPUT: {
const ir_variable *var = RESOURCE_VAR(res);
/* If the input is an array, fail if the index is out of bounds. */ /* If the input is an array, fail if the index is out of bounds. */
if (array_index > 0 if (array_index > 0
&& array_index >= RESOURCE_VAR(res)->type->length) { && array_index >= var->type->length) {
return -1; return -1;
} }
return RESOURCE_VAR(res)->data.location + array_index - VERT_ATTRIB_GENERIC0; return (var->data.location +
(array_index * var->type->without_array()->matrix_columns) -
VERT_ATTRIB_GENERIC0);
}
case GL_PROGRAM_OUTPUT: case GL_PROGRAM_OUTPUT:
/* If the output is an array, fail if the index is out of bounds. */ /* If the output is an array, fail if the index is out of bounds. */
if (array_index > 0 if (array_index > 0

View File

@ -88,12 +88,6 @@ get_tex_depth(struct gl_context *ctx, GLuint dimensions,
return; return;
} }
if (texImage->TexObject->Target == GL_TEXTURE_1D_ARRAY) {
depth = height;
height = 1;
}
assert(zoffset + depth <= texImage->Depth);
for (img = 0; img < depth; img++) { for (img = 0; img < depth; img++) {
GLubyte *srcMap; GLubyte *srcMap;
GLint srcRowStride; GLint srcRowStride;
@ -141,7 +135,6 @@ get_tex_depth_stencil(struct gl_context *ctx, GLuint dimensions,
assert(type == GL_UNSIGNED_INT_24_8 || assert(type == GL_UNSIGNED_INT_24_8 ||
type == GL_FLOAT_32_UNSIGNED_INT_24_8_REV); type == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
assert(zoffset + depth <= texImage->Depth);
for (img = 0; img < depth; img++) { for (img = 0; img < depth; img++) {
GLubyte *srcMap; GLubyte *srcMap;
GLint rowstride; GLint rowstride;
@ -233,7 +226,6 @@ get_tex_ycbcr(struct gl_context *ctx, GLuint dimensions,
{ {
GLint img, row; GLint img, row;
assert(zoffset + depth <= texImage->Depth);
for (img = 0; img < depth; img++) { for (img = 0; img < depth; img++) {
GLubyte *srcMap; GLubyte *srcMap;
GLint rowstride; GLint rowstride;
@ -432,13 +424,6 @@ get_tex_rgba_uncompressed(struct gl_context *ctx, GLuint dimensions,
bool needsRebase; bool needsRebase;
void *rgba = NULL; void *rgba = NULL;
if (texImage->TexObject->Target == GL_TEXTURE_1D_ARRAY) {
depth = height;
height = 1;
zoffset = yoffset;
yoffset = 0;
}
/* Depending on the base format involved we may need to apply a rebase /* Depending on the base format involved we may need to apply a rebase
* transform (for example: if we download to a Luminance format we want * transform (for example: if we download to a Luminance format we want
* G=0 and B=0). * G=0 and B=0).
@ -738,6 +723,17 @@ _mesa_GetTexSubImage_sw(struct gl_context *ctx,
pixels = ADD_POINTERS(buf, pixels); pixels = ADD_POINTERS(buf, pixels);
} }
/* for all array textures, the Z axis selects the layer */
if (texImage->TexObject->Target == GL_TEXTURE_1D_ARRAY) {
depth = height;
height = 1;
zoffset = yoffset;
yoffset = 0;
assert(zoffset + depth <= texImage->Height);
} else {
assert(zoffset + depth <= texImage->Depth);
}
if (get_tex_memcpy(ctx, xoffset, yoffset, zoffset, width, height, depth, if (get_tex_memcpy(ctx, xoffset, yoffset, zoffset, width, height, depth,
format, type, pixels, texImage)) { format, type, pixels, texImage)) {
/* all done */ /* all done */

View File

@ -1616,7 +1616,7 @@ texture_format_error_check_gles(struct gl_context *ctx, GLenum format,
} }
} }
else { else {
err = _mesa_es_error_check_format_and_type(format, type, dimensions); err = _mesa_es_error_check_format_and_type(ctx, format, type, dimensions);
if (err != GL_NO_ERROR) { if (err != GL_NO_ERROR) {
_mesa_error(ctx, err, "%s(format = %s, type = %s)", _mesa_error(ctx, err, "%s(format = %s, type = %s)",
callerName, _mesa_enum_to_string(format), callerName, _mesa_enum_to_string(format),

View File

@ -154,12 +154,12 @@ vertex_attrib_binding(struct gl_context *ctx,
* Binds a buffer object to the vertex buffer binding point given by index, * Binds a buffer object to the vertex buffer binding point given by index,
* and sets the Offset and Stride fields. * and sets the Offset and Stride fields.
*/ */
static void void
bind_vertex_buffer(struct gl_context *ctx, _mesa_bind_vertex_buffer(struct gl_context *ctx,
struct gl_vertex_array_object *vao, struct gl_vertex_array_object *vao,
GLuint index, GLuint index,
struct gl_buffer_object *vbo, struct gl_buffer_object *vbo,
GLintptr offset, GLsizei stride) GLintptr offset, GLsizei stride)
{ {
struct gl_vertex_buffer_binding *binding = &vao->VertexBinding[index]; struct gl_vertex_buffer_binding *binding = &vao->VertexBinding[index];
@ -247,6 +247,52 @@ get_legal_types_mask(const struct gl_context *ctx)
} }
/**
* \param attrib The index of the attribute array
* \param size Components per element (1, 2, 3 or 4)
* \param type Datatype of each component (GL_FLOAT, GL_INT, etc)
* \param format Either GL_RGBA or GL_BGRA.
* \param normalized Whether integer types are converted to floats in [-1, 1]
* \param integer Integer-valued values (will not be normalized to [-1, 1])
* \param doubles Double values not reduced to floats
* \param relativeOffset Offset of the first element relative to the binding
* offset.
* \param flush_verties Should \c FLUSH_VERTICES be invoked before updating
* state?
*/
void
_mesa_update_array_format(struct gl_context *ctx,
struct gl_vertex_array_object *vao,
GLuint attrib, GLint size, GLenum type,
GLenum format, GLboolean normalized,
GLboolean integer, GLboolean doubles,
GLuint relativeOffset, bool flush_vertices)
{
struct gl_vertex_attrib_array *const array = &vao->VertexAttrib[attrib];
GLint elementSize;
assert(size <= 4);
if (flush_vertices) {
FLUSH_VERTICES(ctx, 0);
}
elementSize = _mesa_bytes_per_vertex_attrib(size, type);
assert(elementSize != -1);
array->Size = size;
array->Type = type;
array->Format = format;
array->Normalized = normalized;
array->Integer = integer;
array->Doubles = doubles;
array->RelativeOffset = relativeOffset;
array->_ElementSize = elementSize;
vao->NewArrays |= VERT_BIT(attrib);
ctx->NewState |= _NEW_ARRAY;
}
/** /**
* Does error checking and updates the format in an attrib array. * Does error checking and updates the format in an attrib array.
* *
@ -274,9 +320,7 @@ update_array_format(struct gl_context *ctx,
GLboolean normalized, GLboolean integer, GLboolean doubles, GLboolean normalized, GLboolean integer, GLboolean doubles,
GLuint relativeOffset) GLuint relativeOffset)
{ {
struct gl_vertex_attrib_array *array;
GLbitfield typeBit; GLbitfield typeBit;
GLint elementSize;
GLenum format = GL_RGBA; GLenum format = GL_RGBA;
if (ctx->Array.LegalTypesMask == 0 || ctx->Array.LegalTypesMaskAPI != ctx->API) { if (ctx->Array.LegalTypesMask == 0 || ctx->Array.LegalTypesMaskAPI != ctx->API) {
@ -377,23 +421,9 @@ update_array_format(struct gl_context *ctx,
return false; return false;
} }
assert(size <= 4); _mesa_update_array_format(ctx, vao, attrib, size, type, format,
normalized, integer, doubles, relativeOffset,
elementSize = _mesa_bytes_per_vertex_attrib(size, type); false);
assert(elementSize != -1);
array = &vao->VertexAttrib[attrib];
array->Size = size;
array->Type = type;
array->Format = format;
array->Normalized = normalized;
array->Integer = integer;
array->Doubles = doubles;
array->RelativeOffset = relativeOffset;
array->_ElementSize = elementSize;
vao->NewArrays |= VERT_BIT(attrib);
ctx->NewState |= _NEW_ARRAY;
return true; return true;
} }
@ -491,8 +521,9 @@ update_array(struct gl_context *ctx,
/* Update the vertex buffer binding */ /* Update the vertex buffer binding */
effectiveStride = stride != 0 ? stride : array->_ElementSize; effectiveStride = stride != 0 ? stride : array->_ElementSize;
bind_vertex_buffer(ctx, ctx->Array.VAO, attrib, ctx->Array.ArrayBufferObj, _mesa_bind_vertex_buffer(ctx, ctx->Array.VAO, attrib,
(GLintptr) ptr, effectiveStride); ctx->Array.ArrayBufferObj, (GLintptr) ptr,
effectiveStride);
} }
@ -735,10 +766,26 @@ _mesa_VertexAttribLPointer(GLuint index, GLint size, GLenum type,
update_array(ctx, "glVertexAttribLPointer", VERT_ATTRIB_GENERIC(index), update_array(ctx, "glVertexAttribLPointer", VERT_ATTRIB_GENERIC(index),
legalTypes, 1, 4, legalTypes, 1, 4,
size, type, stride, GL_TRUE, GL_FALSE, GL_TRUE, ptr); size, type, stride, GL_FALSE, GL_FALSE, GL_TRUE, ptr);
} }
void
_mesa_enable_vertex_array_attrib(struct gl_context *ctx,
struct gl_vertex_array_object *vao,
unsigned attrib)
{
assert(attrib < ARRAY_SIZE(vao->VertexAttrib));
if (!vao->VertexAttrib[attrib].Enabled) {
/* was disabled, now being enabled */
FLUSH_VERTICES(ctx, _NEW_ARRAY);
vao->VertexAttrib[attrib].Enabled = GL_TRUE;
vao->_Enabled |= VERT_BIT(attrib);
vao->NewArrays |= VERT_BIT(attrib);
}
}
static void static void
enable_vertex_array_attrib(struct gl_context *ctx, enable_vertex_array_attrib(struct gl_context *ctx,
struct gl_vertex_array_object *vao, struct gl_vertex_array_object *vao,
@ -750,15 +797,7 @@ enable_vertex_array_attrib(struct gl_context *ctx,
return; return;
} }
assert(VERT_ATTRIB_GENERIC(index) < ARRAY_SIZE(vao->VertexAttrib)); _mesa_enable_vertex_array_attrib(ctx, vao, VERT_ATTRIB_GENERIC(index));
if (!vao->VertexAttrib[VERT_ATTRIB_GENERIC(index)].Enabled) {
/* was disabled, now being enabled */
FLUSH_VERTICES(ctx, _NEW_ARRAY);
vao->VertexAttrib[VERT_ATTRIB_GENERIC(index)].Enabled = GL_TRUE;
vao->_Enabled |= VERT_BIT_GENERIC(index);
vao->NewArrays |= VERT_BIT_GENERIC(index);
}
} }
@ -1710,8 +1749,8 @@ vertex_array_vertex_buffer(struct gl_context *ctx, struct gl_vertex_array_object
vbo = ctx->Shared->NullBufferObj; vbo = ctx->Shared->NullBufferObj;
} }
bind_vertex_buffer(ctx, vao, VERT_ATTRIB_GENERIC(bindingIndex), _mesa_bind_vertex_buffer(ctx, vao, VERT_ATTRIB_GENERIC(bindingIndex),
vbo, offset, stride); vbo, offset, stride);
} }
@ -1798,8 +1837,8 @@ vertex_array_vertex_buffers(struct gl_context *ctx,
struct gl_buffer_object *vbo = ctx->Shared->NullBufferObj; struct gl_buffer_object *vbo = ctx->Shared->NullBufferObj;
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
bind_vertex_buffer(ctx, vao, VERT_ATTRIB_GENERIC(first + i), _mesa_bind_vertex_buffer(ctx, vao, VERT_ATTRIB_GENERIC(first + i),
vbo, 0, 16); vbo, 0, 16);
return; return;
} }
@ -1870,8 +1909,8 @@ vertex_array_vertex_buffers(struct gl_context *ctx,
vbo = ctx->Shared->NullBufferObj; vbo = ctx->Shared->NullBufferObj;
} }
bind_vertex_buffer(ctx, vao, VERT_ATTRIB_GENERIC(first + i), _mesa_bind_vertex_buffer(ctx, vao, VERT_ATTRIB_GENERIC(first + i),
vbo, offsets[i], strides[i]); vbo, offsets[i], strides[i]);
} }
_mesa_end_bufferobj_lookups(ctx); _mesa_end_bufferobj_lookups(ctx);

View File

@ -90,6 +90,26 @@ _mesa_attr_zero_aliases_vertex(struct gl_context *ctx)
&& !is_forward_compatible_context)); && !is_forward_compatible_context));
} }
extern void
_mesa_update_array_format(struct gl_context *ctx,
struct gl_vertex_array_object *vao,
GLuint attrib, GLint size, GLenum type,
GLenum format, GLboolean normalized,
GLboolean integer, GLboolean doubles,
GLuint relativeOffset, bool flush_vertices);
extern void
_mesa_enable_vertex_array_attrib(struct gl_context *ctx,
struct gl_vertex_array_object *vao,
unsigned attrib);
extern void
_mesa_bind_vertex_buffer(struct gl_context *ctx,
struct gl_vertex_array_object *vao,
GLuint index,
struct gl_buffer_object *vbo,
GLintptr offset, GLsizei stride);
extern void GLAPIENTRY extern void GLAPIENTRY
_mesa_VertexPointer(GLint size, GLenum type, GLsizei stride, _mesa_VertexPointer(GLint size, GLenum type, GLsizei stride,
const GLvoid *ptr); const GLvoid *ptr);