Merge branch 'master' into r300-compiler
Conflicts: src/gallium/drivers/r300/r300_tgsi_to_rc.c
This commit is contained in:
commit
f02f63997c
|
@ -126,6 +126,7 @@ AC_ARG_ENABLE([32-bit],
|
|||
if test "x$enable_32bit" = xyes; then
|
||||
if test "x$GCC" = xyes; then
|
||||
CFLAGS="$CFLAGS -m32"
|
||||
ARCH_FLAGS="$ARCH_FLAGS -m32"
|
||||
fi
|
||||
if test "x$GXX" = xyes; then
|
||||
CXXFLAGS="$CXXFLAGS -m32"
|
||||
|
|
|
@ -39,7 +39,6 @@ a:visited {
|
|||
<ul>
|
||||
<li><a href="download.html" target="MainFrame">Downloading / Unpacking</a>
|
||||
<li><a href="install.html" target="MainFrame">Compiling / Installing</a>
|
||||
<li><a href="glu.html" target="MainFrame">SGI's GLU</a>
|
||||
<li><a href="precompiled.html" target="MainFrame">Precompiled Libraries</a>
|
||||
</ul>
|
||||
|
||||
|
@ -68,6 +67,7 @@ a:visited {
|
|||
<li><a href="repository.html" target="MainFrame">Source Code Repository</a>
|
||||
<li><a href="memory.html" target="MainFrame">DRI Memory Management</a>
|
||||
<li><a href="shading.html" target="MainFrame">Shading Language</a>
|
||||
<li><a href="glu.html" target="MainFrame">SGI's GLU</a>
|
||||
<li><a href="utilities.html" target="MainFrame">Utilities</a>
|
||||
<li><a href="helpwanted.html" target="MainFrame">Help Wanted</a>
|
||||
<li><a href="devinfo.html" target="MainFrame">Development Notes</a>
|
||||
|
|
|
@ -9,14 +9,14 @@
|
|||
<H1>Downloading</H1>
|
||||
|
||||
<p>
|
||||
Primary download site:
|
||||
<a href="http://sourceforge.net/project/showfiles.php?group_id=3"
|
||||
target="_parent">SourceForge</a>
|
||||
Primary Mesa download site:
|
||||
<a href="ftp://ftp.freedesktop.org/pub/mesa/"
|
||||
target="_parent">freedesktop.org</a> (FTP)
|
||||
</p>
|
||||
|
||||
<p>
|
||||
When a new release is coming, release candidates (betas) can be found
|
||||
<a href="http://www.mesa3d.org/beta/">here</a>.
|
||||
When a new release is coming, release candidates (betas) may be found
|
||||
<a href="ftp://ftp.freedesktop.org/pub/mesa/beta/" target="_parent">here</a>.
|
||||
</p>
|
||||
|
||||
|
||||
|
|
|
@ -11,6 +11,13 @@
|
|||
<H1>News</H1>
|
||||
|
||||
|
||||
<h2>September 3, 2009</h2>
|
||||
<p>
|
||||
<a href="relnotes-7.5.1.html">Mesa 7.5.1</a> is released.
|
||||
This is a bug-fix release which fixes bugs found in version 7.5.
|
||||
</p>
|
||||
|
||||
|
||||
<h2>July 17, 2009</h2>
|
||||
<p>
|
||||
<a href="relnotes-7.5.html">Mesa 7.5</a> is released.
|
||||
|
|
|
@ -9,17 +9,11 @@
|
|||
<H1>Precompiled Libraries</H1>
|
||||
|
||||
<p>
|
||||
In general, precompiled libraries are not available.
|
||||
However, people occasionally prepare packages of precompiled libraries
|
||||
for some systems.
|
||||
In general, precompiled Mesa libraries are not available.
|
||||
</p>
|
||||
|
||||
<H2>Mesa-6.0 for Solaris</H2>
|
||||
|
||||
<p>
|
||||
Steve Christensen has submitted precompiled Mesa-6.0 libraries for
|
||||
Solaris at <a href="http://sunfreeware.com/" target="_parent">
|
||||
sunfreeware.com</a>.
|
||||
However, some Linux distros (such as Ubuntu) seem to closely track
|
||||
Mesa and often have the latest Mesa release available as an update.
|
||||
</p>
|
||||
|
||||
</BODY>
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
<body bgcolor="#eeeeee">
|
||||
|
||||
<H1>Mesa 7.5.1 Release Notes / (date TBD)</H1>
|
||||
<H1>Mesa 7.5.1 Release Notes, 3 September 2009</H1>
|
||||
|
||||
<p>
|
||||
Mesa 7.5.1 is a bug-fix release fixing issues found since the 7.5 release.
|
||||
|
@ -31,7 +31,15 @@ for DRI hardware acceleration.
|
|||
|
||||
<h2>MD5 checksums</h2>
|
||||
<pre>
|
||||
tbd
|
||||
d7269e93bc7484430637d54ced250876 MesaLib-7.5.1.tar.gz
|
||||
877d6a4b24efc2b1d02aa553f262cba8 MesaLib-7.5.1.tar.bz2
|
||||
23f4fb757a05c8396425681234ae20e5 MesaLib-7.5.1.zip
|
||||
5af4bd113652108f5cec5113dad813f2 MesaDemos-7.5.1.tar.gz
|
||||
785402e3b9f0e335538fcc6bf19f6987 MesaDemos-7.5.1.tar.bz2
|
||||
950058cc6d6106e9c7d5876a03789fe9 MesaDemos-7.5.1.zip
|
||||
cb52ce2c93389c2711cbe8d857ec5303 MesaGLUT-7.5.1.tar.gz
|
||||
e3a9892e056d625c5353617a7c5b7e9c MesaGLUT-7.5.1.tar.bz2
|
||||
da1de364df148c94b4994006191a1e69 MesaGLUT-7.5.1.zip
|
||||
</pre>
|
||||
|
||||
|
||||
|
@ -54,12 +62,11 @@ tbd
|
|||
<li>Fixed Gallium glBitmap() Z position bug
|
||||
<li>Setting arrays of sampler uniforms did not work
|
||||
<li>Selection/Feedback mode didn't handle polygon culling correctly (bug 16866)
|
||||
<li>Fixed 32/64-bit cross compilation issue in gen_matypes.c
|
||||
<li>Fixed glXCreateGLXPixmap() for direct rendering.
|
||||
<li>Fixed Gallium glCopyPixels(GL_STENCIL_INDEX) mispositioned image bug.
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>Changes</h2>
|
||||
<ul>
|
||||
</ul>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -36,18 +36,25 @@ tbd
|
|||
<ul>
|
||||
<li><a href="openvg.html">OpenVG</a> front-end (state tracker for Gallium).
|
||||
This was written by Zack Rusin at Tungsten Graphics.
|
||||
<li>GL_APPLE_vertex_array_object for Gallium drivers and Intel DRI drivers.
|
||||
<li>GL_ARB_vertex_array_object for Gallium drivers, software drivers and
|
||||
Intel DRI drivers.
|
||||
<li>GL_ARB_copy_buffer extension (supported in Gallium and swrast drivers)
|
||||
<LI>GL_ARB_map_buffer_range extension (supported in Gallium and software drivers)
|
||||
<li>GL_EXT_provoking_vertex extension (supported in Gallium and software drivers)
|
||||
<li>GL_ARB_vertex_array_object and GL_APPLE_vertex_array_object extensions
|
||||
(supported in Gallium drivers, Intel DRI drivers, and software drivers)</li>
|
||||
<li>GL_ARB_copy_buffer extension
|
||||
(supported in Gallium drivers, Intel DRI drivers, and software drivers)</li>
|
||||
<li>GL_ARB_map_buffer_range extension
|
||||
(supported in Gallium drivers, Intel DRI drivers, and software drivers)</li>
|
||||
<li>GL_ARB_seamless_cube_map extension
|
||||
(supported in software drivers and i965 drivers)</li>
|
||||
<li>GL_ARB_vertex_array_bgra (ARB synonym for GL_EXT_vertex_array_bgra)</li>
|
||||
<li>GL_ARB_sync (supported in software drivers and Intel DRI drivers)</li>
|
||||
<li>GL_EXT_provoking_vertex extension (supported in Gallium, i915, i965, and software drivers)
|
||||
<li>Rewritten radeon/r200/r300 driver using a buffer manager
|
||||
<li>radeon/r200/r300 GL_EXT_framebuffer_object support when used with
|
||||
kernel memory manager
|
||||
<li>r300 driver support for GL_EXT_vertex_array_bgra, GL_EXT_texture_sRGB
|
||||
<li>i915/945 driver support for GL_ARB_point_sprite, GL_EXT_stencil_two_side
|
||||
and GL_ATI_separate_stencil extensions
|
||||
<li>Rewritten assembler for GL_ARB_vertex_program /
|
||||
GL_ARB_fragment_program.</li>
|
||||
<li>Added configure --with-max-width=W, --with-max-height=H options to specify
|
||||
max framebuffer, viewport size.
|
||||
</ul>
|
||||
|
|
|
@ -92,6 +92,12 @@ static void Init(void)
|
|||
numObjects = 10;
|
||||
InitObjects(numObjects);
|
||||
glGetIntegerv(GL_VIEWPORT, vp);
|
||||
|
||||
#if 0 /* debug - test culling */
|
||||
glCullFace(GL_BACK);
|
||||
glFrontFace(GL_CW);
|
||||
glEnable(GL_CULL_FACE);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void Reshape(int width, int height)
|
||||
|
|
|
@ -127,7 +127,7 @@ Init( void )
|
|||
|
||||
if (!glutExtensionSupported("GL_EXT_framebuffer_object")) {
|
||||
printf("GL_EXT_framebuffer_object not found!\n");
|
||||
/*exit(0);*/
|
||||
exit(0);
|
||||
}
|
||||
printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
|
||||
|
||||
|
|
|
@ -371,11 +371,11 @@ int main( int argc, char *argv[] )
|
|||
glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
|
||||
|
||||
if (glutCreateWindow(argv[0]) <= 0) {
|
||||
glewInit();
|
||||
printf("Couldn't create window\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
glewInit();
|
||||
gl_version = atof( (const char *) glGetString( GL_VERSION ) );
|
||||
if ( (gl_version < 1.3)
|
||||
&& !glutExtensionSupported("GL_ARB_texture_compression") ) {
|
||||
|
|
|
@ -24,6 +24,8 @@ static void Display(void)
|
|||
glClearColor(0.5, 0.5, 0.5, 1.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
/* draw a sphere */
|
||||
glViewport(0, 0, 100, 100);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
|
@ -46,9 +48,12 @@ static void Display(void)
|
|||
|
||||
/* draw depth image with scaling (into z buffer) */
|
||||
glPixelZoom(4.0, 4.0);
|
||||
glColor4f(1, 0, 0, 0);
|
||||
glWindowPos2i(100, 0);
|
||||
glDrawPixels(100, 100, GL_DEPTH_COMPONENT, GL_FLOAT, depth);
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
/* read back scaled depth image */
|
||||
glReadPixels(100, 0, 400, 400, GL_DEPTH_COMPONENT, GL_FLOAT, depth2);
|
||||
/* draw as luminance */
|
||||
|
@ -96,7 +101,6 @@ static void Init(void)
|
|||
glLightfv(GL_LIGHT0, GL_POSITION, pos);
|
||||
glEnable(GL_LIGHTING);
|
||||
glEnable(GL_LIGHT0);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
"""llvm
|
||||
|
||||
Tool-specific initialization for LLVM
|
||||
|
||||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2009 VMware, Inc.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
import os
|
||||
import os.path
|
||||
|
||||
import SCons.Errors
|
||||
import SCons.Util
|
||||
|
||||
|
||||
def generate(env):
|
||||
try:
|
||||
llvm_dir = os.environ['LLVM']
|
||||
except KeyError:
|
||||
# Do nothing -- use the system headers/libs
|
||||
pass
|
||||
else:
|
||||
if not os.path.isdir(llvm_dir):
|
||||
raise SCons.Errors.InternalError, "Specified LLVM directory not found"
|
||||
|
||||
if env['debug']:
|
||||
llvm_subdir = 'Debug'
|
||||
else:
|
||||
llvm_subdir = 'Release'
|
||||
|
||||
llvm_bin_dir = os.path.join(llvm_dir, llvm_subdir, 'bin')
|
||||
if not os.path.isdir(llvm_bin_dir):
|
||||
raise SCons.Errors.InternalError, "LLVM build directory not found"
|
||||
|
||||
env.PrependENVPath('PATH', llvm_bin_dir)
|
||||
|
||||
if env.Detect('llvm-config'):
|
||||
try:
|
||||
env['LLVM_VERSION'] = env.backtick('llvm-config --version')
|
||||
except AttributeError:
|
||||
env['LLVM_VERSION'] = 'X.X'
|
||||
|
||||
env.ParseConfig('llvm-config --cppflags')
|
||||
env.ParseConfig('llvm-config --libs jit interpreter nativecodegen bitwriter')
|
||||
env.ParseConfig('llvm-config --ldflags')
|
||||
env['LINK'] = env['CXX']
|
||||
|
||||
def exists(env):
|
||||
return True
|
||||
|
||||
# vim:set ts=4 sw=4 et:
|
|
@ -187,11 +187,7 @@ TGSI Instruction Specification
|
|||
|
||||
1.2.6 CND0 - Condition Zero
|
||||
|
||||
dst.x = (src2.x >= 0.0) ? src0.x : src1.x
|
||||
dst.y = (src2.y >= 0.0) ? src0.y : src1.y
|
||||
dst.z = (src2.z >= 0.0) ? src0.z : src1.z
|
||||
dst.w = (src2.w >= 0.0) ? src0.w : src1.w
|
||||
|
||||
Removed. Use (CMP src2, src1, src0) instead.
|
||||
|
||||
1.2.7 DOT2ADD - 2-component Dot Product And Add
|
||||
|
||||
|
@ -1031,12 +1027,12 @@ TGSI Instruction Specification
|
|||
|
||||
1.18.1 EXPP - Approximate Exponential Base 2
|
||||
|
||||
Alias for EXP.
|
||||
Use EXP. See also 1.19.3.
|
||||
|
||||
|
||||
1.18.2 LOGP - Logarithm Base 2
|
||||
|
||||
Alias for LG2.
|
||||
Use LOG. See also 1.19.4.
|
||||
|
||||
|
||||
1.19 vs_2_0
|
||||
|
@ -1053,6 +1049,16 @@ TGSI Instruction Specification
|
|||
Alias for ARR.
|
||||
|
||||
|
||||
1.19.3 EXPP - Approximate Exponential Base 2
|
||||
|
||||
Use EX2.
|
||||
|
||||
|
||||
1.19.4 LOGP - Logarithm Base 2
|
||||
|
||||
Use LG2.
|
||||
|
||||
|
||||
2 Explanation of symbols used
|
||||
==============================
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@ struct dump_ctx
|
|||
struct tgsi_iterate_context iter;
|
||||
|
||||
uint instno;
|
||||
int indent;
|
||||
|
||||
uint indentation;
|
||||
|
||||
|
@ -335,14 +336,6 @@ tgsi_dump_immediate(
|
|||
iter_immediate( &ctx.iter, (struct tgsi_full_immediate *)imm );
|
||||
}
|
||||
|
||||
static void
|
||||
indent(struct dump_ctx *ctx)
|
||||
{
|
||||
uint i;
|
||||
for (i = 0; i < ctx->indentation; i++)
|
||||
TXT(" ");
|
||||
}
|
||||
|
||||
static boolean
|
||||
iter_instruction(
|
||||
struct tgsi_iterate_context *iter,
|
||||
|
@ -350,22 +343,19 @@ iter_instruction(
|
|||
{
|
||||
struct dump_ctx *ctx = (struct dump_ctx *) iter;
|
||||
uint instno = ctx->instno++;
|
||||
|
||||
const struct tgsi_opcode_info *info = tgsi_get_opcode_info( inst->Instruction.Opcode );
|
||||
uint i;
|
||||
boolean first_reg = TRUE;
|
||||
|
||||
INSTID( instno );
|
||||
TXT( ": " );
|
||||
|
||||
/* update indentation */
|
||||
if (inst->Instruction.Opcode == TGSI_OPCODE_ENDIF ||
|
||||
inst->Instruction.Opcode == TGSI_OPCODE_ENDFOR ||
|
||||
inst->Instruction.Opcode == TGSI_OPCODE_ENDLOOP) {
|
||||
ctx->indentation -= indent_spaces;
|
||||
}
|
||||
indent(ctx);
|
||||
|
||||
TXT( tgsi_get_opcode_info( inst->Instruction.Opcode )->mnemonic );
|
||||
|
||||
ctx->indent -= info->pre_dedent;
|
||||
for(i = 0; (int)i < ctx->indent; ++i)
|
||||
TXT( " " );
|
||||
ctx->indent += info->post_indent;
|
||||
|
||||
TXT( info->mnemonic );
|
||||
|
||||
switch (inst->Instruction.Saturate) {
|
||||
case TGSI_SAT_NONE:
|
||||
|
@ -526,6 +516,7 @@ tgsi_dump_instruction(
|
|||
struct dump_ctx ctx;
|
||||
|
||||
ctx.instno = instno;
|
||||
ctx.indent = 0;
|
||||
ctx.printf = dump_ctx_printf;
|
||||
ctx.indentation = 0;
|
||||
|
||||
|
@ -559,6 +550,7 @@ tgsi_dump(
|
|||
ctx.iter.epilog = NULL;
|
||||
|
||||
ctx.instno = 0;
|
||||
ctx.indent = 0;
|
||||
ctx.printf = dump_ctx_printf;
|
||||
ctx.indentation = 0;
|
||||
|
||||
|
@ -612,6 +604,7 @@ tgsi_dump_str(
|
|||
ctx.base.iter.epilog = NULL;
|
||||
|
||||
ctx.base.instno = 0;
|
||||
ctx.base.indent = 0;
|
||||
ctx.base.printf = &str_dump_ctx_printf;
|
||||
ctx.base.indentation = 0;
|
||||
|
||||
|
|
|
@ -2329,16 +2329,6 @@ exec_instruction(
|
|||
}
|
||||
break;
|
||||
|
||||
case TGSI_OPCODE_CND0:
|
||||
FOR_EACH_ENABLED_CHANNEL(*inst, chan_index) {
|
||||
FETCH(&r[0], 0, chan_index);
|
||||
FETCH(&r[1], 1, chan_index);
|
||||
FETCH(&r[2], 2, chan_index);
|
||||
micro_le(&r[0], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &r[2], &r[0], &r[1]);
|
||||
STORE(&r[0], 0, chan_index);
|
||||
}
|
||||
break;
|
||||
|
||||
case TGSI_OPCODE_DP2A:
|
||||
FETCH( &r[0], 0, CHAN_X );
|
||||
FETCH( &r[1], 1, CHAN_X );
|
||||
|
@ -3104,6 +3094,12 @@ exec_instruction(
|
|||
break;
|
||||
|
||||
case TGSI_OPCODE_BGNFOR:
|
||||
assert(mach->LoopCounterStackTop < TGSI_EXEC_MAX_LOOP_NESTING);
|
||||
for (chan_index = 0; chan_index < 3; chan_index++) {
|
||||
FETCH( &mach->LoopCounterStack[mach->LoopCounterStackTop].xyzw[chan_index], 0, chan_index );
|
||||
}
|
||||
STORE( &mach->LoopCounterStack[mach->LoopCounterStackTop].xyzw[CHAN_Y], 0, CHAN_X );
|
||||
++mach->LoopCounterStackTop;
|
||||
/* fall-through (for now) */
|
||||
case TGSI_OPCODE_BGNLOOP:
|
||||
/* push LoopMask and ContMasks */
|
||||
|
@ -3111,18 +3107,42 @@ exec_instruction(
|
|||
mach->LoopStack[mach->LoopStackTop++] = mach->LoopMask;
|
||||
assert(mach->ContStackTop < TGSI_EXEC_MAX_LOOP_NESTING);
|
||||
mach->ContStack[mach->ContStackTop++] = mach->ContMask;
|
||||
assert(mach->LoopLabelStackTop < TGSI_EXEC_MAX_LOOP_NESTING);
|
||||
mach->LoopLabelStack[mach->LoopLabelStackTop++] = *pc - 1;
|
||||
break;
|
||||
|
||||
case TGSI_OPCODE_ENDFOR:
|
||||
/* fall-through (for now at least) */
|
||||
case TGSI_OPCODE_ENDLOOP:
|
||||
assert(mach->LoopCounterStackTop > 0);
|
||||
micro_sub( &mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_X],
|
||||
&mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_X],
|
||||
&mach->Temps[TEMP_1_I].xyzw[TEMP_1_C] );
|
||||
/* update LoopMask */
|
||||
if( mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_X].f[0] <= 0) {
|
||||
mach->LoopMask &= ~0x1;
|
||||
}
|
||||
if( mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_X].f[1] <= 0 ) {
|
||||
mach->LoopMask &= ~0x2;
|
||||
}
|
||||
if( mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_X].f[2] <= 0 ) {
|
||||
mach->LoopMask &= ~0x4;
|
||||
}
|
||||
if( mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_X].f[3] <= 0 ) {
|
||||
mach->LoopMask &= ~0x8;
|
||||
}
|
||||
micro_add( &mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_Y],
|
||||
&mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_Y],
|
||||
&mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_Z]);
|
||||
assert(mach->LoopLabelStackTop > 0);
|
||||
inst = mach->Instructions + mach->LoopLabelStack[mach->LoopLabelStackTop - 1];
|
||||
STORE( &mach->LoopCounterStack[mach->LoopCounterStackTop].xyzw[CHAN_Y], 0, CHAN_X );
|
||||
/* Restore ContMask, but don't pop */
|
||||
assert(mach->ContStackTop > 0);
|
||||
mach->ContMask = mach->ContStack[mach->ContStackTop - 1];
|
||||
UPDATE_EXEC_MASK(mach);
|
||||
if (mach->ExecMask) {
|
||||
/* repeat loop: jump to instruction just past BGNLOOP */
|
||||
*pc = inst->InstructionExtLabel.Label + 1;
|
||||
assert(mach->LoopLabelStackTop > 0);
|
||||
*pc = mach->LoopLabelStack[mach->LoopLabelStackTop - 1] + 1;
|
||||
}
|
||||
else {
|
||||
/* exit loop: pop LoopMask */
|
||||
|
@ -3131,6 +3151,33 @@ exec_instruction(
|
|||
/* pop ContMask */
|
||||
assert(mach->ContStackTop > 0);
|
||||
mach->ContMask = mach->ContStack[--mach->ContStackTop];
|
||||
assert(mach->LoopLabelStackTop > 0);
|
||||
--mach->LoopLabelStackTop;
|
||||
assert(mach->LoopCounterStackTop > 0);
|
||||
--mach->LoopCounterStackTop;
|
||||
}
|
||||
UPDATE_EXEC_MASK(mach);
|
||||
break;
|
||||
|
||||
case TGSI_OPCODE_ENDLOOP:
|
||||
/* Restore ContMask, but don't pop */
|
||||
assert(mach->ContStackTop > 0);
|
||||
mach->ContMask = mach->ContStack[mach->ContStackTop - 1];
|
||||
UPDATE_EXEC_MASK(mach);
|
||||
if (mach->ExecMask) {
|
||||
/* repeat loop: jump to instruction just past BGNLOOP */
|
||||
assert(mach->LoopLabelStackTop > 0);
|
||||
*pc = mach->LoopLabelStack[mach->LoopLabelStackTop - 1] + 1;
|
||||
}
|
||||
else {
|
||||
/* exit loop: pop LoopMask */
|
||||
assert(mach->LoopStackTop > 0);
|
||||
mach->LoopMask = mach->LoopStack[--mach->LoopStackTop];
|
||||
/* pop ContMask */
|
||||
assert(mach->ContStackTop > 0);
|
||||
mach->ContMask = mach->ContStack[--mach->ContStackTop];
|
||||
assert(mach->LoopLabelStackTop > 0);
|
||||
--mach->LoopLabelStackTop;
|
||||
}
|
||||
UPDATE_EXEC_MASK(mach);
|
||||
break;
|
||||
|
|
|
@ -232,6 +232,14 @@ struct tgsi_exec_machine
|
|||
uint LoopStack[TGSI_EXEC_MAX_LOOP_NESTING];
|
||||
int LoopStackTop;
|
||||
|
||||
/** Loop label stack */
|
||||
uint LoopLabelStack[TGSI_EXEC_MAX_LOOP_NESTING];
|
||||
int LoopLabelStackTop;
|
||||
|
||||
/** Loop counter stack (x = count, y = current, z = step) */
|
||||
struct tgsi_exec_vector LoopCounterStack[TGSI_EXEC_MAX_LOOP_NESTING];
|
||||
int LoopCounterStackTop;
|
||||
|
||||
/** Loop continue mask stack (see comments in tgsi_exec.c) */
|
||||
uint ContStack[TGSI_EXEC_MAX_LOOP_NESTING];
|
||||
int ContStackTop;
|
||||
|
|
|
@ -31,125 +31,125 @@
|
|||
|
||||
static const struct tgsi_opcode_info opcode_info[TGSI_OPCODE_LAST] =
|
||||
{
|
||||
{ 1, 1, 0, 0, "ARL", TGSI_OPCODE_ARL },
|
||||
{ 1, 1, 0, 0, "MOV", TGSI_OPCODE_MOV },
|
||||
{ 1, 1, 0, 0, "LIT", TGSI_OPCODE_LIT },
|
||||
{ 1, 1, 0, 0, "RCP", TGSI_OPCODE_RCP },
|
||||
{ 1, 1, 0, 0, "RSQ", TGSI_OPCODE_RSQ },
|
||||
{ 1, 1, 0, 0, "EXP", TGSI_OPCODE_EXP },
|
||||
{ 1, 1, 0, 0, "LOG", TGSI_OPCODE_LOG },
|
||||
{ 1, 2, 0, 0, "MUL", TGSI_OPCODE_MUL },
|
||||
{ 1, 2, 0, 0, "ADD", TGSI_OPCODE_ADD },
|
||||
{ 1, 2, 0, 0, "DP3", TGSI_OPCODE_DP3 },
|
||||
{ 1, 2, 0, 0, "DP4", TGSI_OPCODE_DP4 },
|
||||
{ 1, 2, 0, 0, "DST", TGSI_OPCODE_DST },
|
||||
{ 1, 2, 0, 0, "MIN", TGSI_OPCODE_MIN },
|
||||
{ 1, 2, 0, 0, "MAX", TGSI_OPCODE_MAX },
|
||||
{ 1, 2, 0, 0, "SLT", TGSI_OPCODE_SLT },
|
||||
{ 1, 2, 0, 0, "SGE", TGSI_OPCODE_SGE },
|
||||
{ 1, 3, 0, 0, "MAD", TGSI_OPCODE_MAD },
|
||||
{ 1, 2, 0, 0, "SUB", TGSI_OPCODE_SUB },
|
||||
{ 1, 3, 0, 0, "LRP", TGSI_OPCODE_LRP },
|
||||
{ 1, 3, 0, 0, "CND", TGSI_OPCODE_CND },
|
||||
{ 1, 3, 0, 0, "CND0", TGSI_OPCODE_CND0 },
|
||||
{ 1, 3, 0, 0, "DP2A", TGSI_OPCODE_DP2A },
|
||||
{ 0, 0, 0, 0, "", 22 }, /* removed */
|
||||
{ 0, 0, 0, 0, "", 23 }, /* removed */
|
||||
{ 1, 1, 0, 0, "FRC", TGSI_OPCODE_FRC },
|
||||
{ 1, 3, 0, 0, "CLAMP", TGSI_OPCODE_CLAMP },
|
||||
{ 1, 1, 0, 0, "FLR", TGSI_OPCODE_FLR },
|
||||
{ 1, 1, 0, 0, "ROUND", TGSI_OPCODE_ROUND },
|
||||
{ 1, 1, 0, 0, "EX2", TGSI_OPCODE_EX2 },
|
||||
{ 1, 1, 0, 0, "LG2", TGSI_OPCODE_LG2 },
|
||||
{ 1, 2, 0, 0, "POW", TGSI_OPCODE_POW },
|
||||
{ 1, 2, 0, 0, "XPD", TGSI_OPCODE_XPD },
|
||||
{ 0, 0, 0, 0, "", 32 }, /* removed */
|
||||
{ 1, 1, 0, 0, "ABS", TGSI_OPCODE_ABS },
|
||||
{ 1, 1, 0, 0, "RCC", TGSI_OPCODE_RCC },
|
||||
{ 1, 2, 0, 0, "DPH", TGSI_OPCODE_DPH },
|
||||
{ 1, 1, 0, 0, "COS", TGSI_OPCODE_COS },
|
||||
{ 1, 1, 0, 0, "DDX", TGSI_OPCODE_DDX },
|
||||
{ 1, 1, 0, 0, "DDY", TGSI_OPCODE_DDY },
|
||||
{ 0, 0, 0, 0, "KILP", TGSI_OPCODE_KILP },
|
||||
{ 1, 1, 0, 0, "PK2H", TGSI_OPCODE_PK2H },
|
||||
{ 1, 1, 0, 0, "PK2US", TGSI_OPCODE_PK2US },
|
||||
{ 1, 1, 0, 0, "PK4B", TGSI_OPCODE_PK4B },
|
||||
{ 1, 1, 0, 0, "PK4UB", TGSI_OPCODE_PK4UB },
|
||||
{ 1, 2, 0, 0, "RFL", TGSI_OPCODE_RFL },
|
||||
{ 1, 2, 0, 0, "SEQ", TGSI_OPCODE_SEQ },
|
||||
{ 1, 2, 0, 0, "SFL", TGSI_OPCODE_SFL },
|
||||
{ 1, 2, 0, 0, "SGT", TGSI_OPCODE_SGT },
|
||||
{ 1, 1, 0, 0, "SIN", TGSI_OPCODE_SIN },
|
||||
{ 1, 2, 0, 0, "SLE", TGSI_OPCODE_SLE },
|
||||
{ 1, 2, 0, 0, "SNE", TGSI_OPCODE_SNE },
|
||||
{ 1, 2, 0, 0, "STR", TGSI_OPCODE_STR },
|
||||
{ 1, 2, 1, 0, "TEX", TGSI_OPCODE_TEX },
|
||||
{ 1, 4, 1, 0, "TXD", TGSI_OPCODE_TXD },
|
||||
{ 1, 2, 1, 0, "TXP", TGSI_OPCODE_TXP },
|
||||
{ 1, 1, 0, 0, "UP2H", TGSI_OPCODE_UP2H },
|
||||
{ 1, 1, 0, 0, "UP2US", TGSI_OPCODE_UP2US },
|
||||
{ 1, 1, 0, 0, "UP4B", TGSI_OPCODE_UP4B },
|
||||
{ 1, 1, 0, 0, "UP4UB", TGSI_OPCODE_UP4UB },
|
||||
{ 1, 3, 0, 0, "X2D", TGSI_OPCODE_X2D },
|
||||
{ 1, 1, 0, 0, "ARA", TGSI_OPCODE_ARA },
|
||||
{ 1, 1, 0, 0, "ARR", TGSI_OPCODE_ARR },
|
||||
{ 0, 1, 0, 0, "BRA", TGSI_OPCODE_BRA },
|
||||
{ 0, 0, 0, 1, "CAL", TGSI_OPCODE_CAL },
|
||||
{ 0, 0, 0, 0, "RET", TGSI_OPCODE_RET },
|
||||
{ 1, 1, 0, 0, "SSG", TGSI_OPCODE_SSG },
|
||||
{ 1, 3, 0, 0, "CMP", TGSI_OPCODE_CMP },
|
||||
{ 1, 1, 0, 0, "SCS", TGSI_OPCODE_SCS },
|
||||
{ 1, 2, 1, 0, "TXB", TGSI_OPCODE_TXB },
|
||||
{ 1, 1, 0, 0, "NRM", TGSI_OPCODE_NRM },
|
||||
{ 1, 2, 0, 0, "DIV", TGSI_OPCODE_DIV },
|
||||
{ 1, 2, 0, 0, "DP2", TGSI_OPCODE_DP2 },
|
||||
{ 1, 2, 1, 0, "TXL", TGSI_OPCODE_TXL },
|
||||
{ 0, 0, 0, 0, "BRK", TGSI_OPCODE_BRK },
|
||||
{ 0, 1, 0, 1, "IF", TGSI_OPCODE_IF },
|
||||
{ 1, 1, 0, 0, "BGNFOR", TGSI_OPCODE_BGNFOR },
|
||||
{ 0, 1, 0, 0, "REP", TGSI_OPCODE_REP },
|
||||
{ 0, 0, 0, 1, "ELSE", TGSI_OPCODE_ELSE },
|
||||
{ 0, 0, 0, 0, "ENDIF", TGSI_OPCODE_ENDIF },
|
||||
{ 1, 0, 0, 0, "ENDFOR", TGSI_OPCODE_ENDFOR },
|
||||
{ 0, 0, 0, 0, "ENDREP", TGSI_OPCODE_ENDREP },
|
||||
{ 0, 1, 0, 0, "PUSHA", TGSI_OPCODE_PUSHA },
|
||||
{ 1, 0, 0, 0, "POPA", TGSI_OPCODE_POPA },
|
||||
{ 1, 1, 0, 0, "CEIL", TGSI_OPCODE_CEIL },
|
||||
{ 1, 1, 0, 0, "I2F", TGSI_OPCODE_I2F },
|
||||
{ 1, 1, 0, 0, "NOT", TGSI_OPCODE_NOT },
|
||||
{ 1, 1, 0, 0, "TRUNC", TGSI_OPCODE_TRUNC },
|
||||
{ 1, 2, 0, 0, "SHL", TGSI_OPCODE_SHL },
|
||||
{ 1, 2, 0, 0, "SHR", TGSI_OPCODE_SHR },
|
||||
{ 1, 2, 0, 0, "AND", TGSI_OPCODE_AND },
|
||||
{ 1, 2, 0, 0, "OR", TGSI_OPCODE_OR },
|
||||
{ 1, 2, 0, 0, "MOD", TGSI_OPCODE_MOD },
|
||||
{ 1, 2, 0, 0, "XOR", TGSI_OPCODE_XOR },
|
||||
{ 1, 3, 0, 0, "SAD", TGSI_OPCODE_SAD },
|
||||
{ 1, 2, 1, 0, "TXF", TGSI_OPCODE_TXF },
|
||||
{ 1, 2, 1, 0, "TXQ", TGSI_OPCODE_TXQ },
|
||||
{ 0, 0, 0, 0, "CONT", TGSI_OPCODE_CONT },
|
||||
{ 0, 0, 0, 0, "EMIT", TGSI_OPCODE_EMIT },
|
||||
{ 0, 0, 0, 0, "ENDPRIM", TGSI_OPCODE_ENDPRIM },
|
||||
{ 0, 0, 0, 1, "BGNLOOP", TGSI_OPCODE_BGNLOOP },
|
||||
{ 0, 0, 0, 0, "BGNSUB", TGSI_OPCODE_BGNSUB },
|
||||
{ 0, 0, 0, 1, "ENDLOOP", TGSI_OPCODE_ENDLOOP },
|
||||
{ 0, 0, 0, 0, "ENDSUB", TGSI_OPCODE_ENDSUB },
|
||||
{ 1, 1, 0, 0, "NOISE1", TGSI_OPCODE_NOISE1 },
|
||||
{ 1, 1, 0, 0, "NOISE2", TGSI_OPCODE_NOISE2 },
|
||||
{ 1, 1, 0, 0, "NOISE3", TGSI_OPCODE_NOISE3 },
|
||||
{ 1, 1, 0, 0, "NOISE4", TGSI_OPCODE_NOISE4 },
|
||||
{ 0, 0, 0, 0, "NOP", TGSI_OPCODE_NOP },
|
||||
{ 0, 0, 0, 0, "", 108 }, /* removed */
|
||||
{ 0, 0, 0, 0, "", 109 }, /* removed */
|
||||
{ 0, 0, 0, 0, "", 110 }, /* removed */
|
||||
{ 0, 0, 0, 0, "", 111 }, /* removed */
|
||||
{ 1, 1, 0, 0, "NRM4", TGSI_OPCODE_NRM4 },
|
||||
{ 0, 1, 0, 0, "CALLNZ", TGSI_OPCODE_CALLNZ },
|
||||
{ 0, 1, 0, 0, "IFC", TGSI_OPCODE_IFC },
|
||||
{ 0, 1, 0, 0, "BREAKC", TGSI_OPCODE_BREAKC },
|
||||
{ 0, 1, 0, 0, "KIL", TGSI_OPCODE_KIL },
|
||||
{ 0, 0, 0, 0, "END", TGSI_OPCODE_END },
|
||||
{ 1, 1, 0, 0, "SWZ", TGSI_OPCODE_SWZ }
|
||||
{ 1, 1, 0, 0, 0, 0, "ARL", TGSI_OPCODE_ARL },
|
||||
{ 1, 1, 0, 0, 0, 0, "MOV", TGSI_OPCODE_MOV },
|
||||
{ 1, 1, 0, 0, 0, 0, "LIT", TGSI_OPCODE_LIT },
|
||||
{ 1, 1, 0, 0, 0, 0, "RCP", TGSI_OPCODE_RCP },
|
||||
{ 1, 1, 0, 0, 0, 0, "RSQ", TGSI_OPCODE_RSQ },
|
||||
{ 1, 1, 0, 0, 0, 0, "EXP", TGSI_OPCODE_EXP },
|
||||
{ 1, 1, 0, 0, 0, 0, "LOG", TGSI_OPCODE_LOG },
|
||||
{ 1, 2, 0, 0, 0, 0, "MUL", TGSI_OPCODE_MUL },
|
||||
{ 1, 2, 0, 0, 0, 0, "ADD", TGSI_OPCODE_ADD },
|
||||
{ 1, 2, 0, 0, 0, 0, "DP3", TGSI_OPCODE_DP3 },
|
||||
{ 1, 2, 0, 0, 0, 0, "DP4", TGSI_OPCODE_DP4 },
|
||||
{ 1, 2, 0, 0, 0, 0, "DST", TGSI_OPCODE_DST },
|
||||
{ 1, 2, 0, 0, 0, 0, "MIN", TGSI_OPCODE_MIN },
|
||||
{ 1, 2, 0, 0, 0, 0, "MAX", TGSI_OPCODE_MAX },
|
||||
{ 1, 2, 0, 0, 0, 0, "SLT", TGSI_OPCODE_SLT },
|
||||
{ 1, 2, 0, 0, 0, 0, "SGE", TGSI_OPCODE_SGE },
|
||||
{ 1, 3, 0, 0, 0, 0, "MAD", TGSI_OPCODE_MAD },
|
||||
{ 1, 2, 0, 0, 0, 0, "SUB", TGSI_OPCODE_SUB },
|
||||
{ 1, 3, 0, 0, 0, 0, "LRP", TGSI_OPCODE_LRP },
|
||||
{ 1, 3, 0, 0, 0, 0, "CND", TGSI_OPCODE_CND },
|
||||
{ 0, 0, 0, 0, 0, 0, "", 20 }, /* removed */
|
||||
{ 1, 3, 0, 0, 0, 0, "DP2A", TGSI_OPCODE_DP2A },
|
||||
{ 0, 0, 0, 0, 0, 0, "", 22 }, /* removed */
|
||||
{ 0, 0, 0, 0, 0, 0, "", 23 }, /* removed */
|
||||
{ 1, 1, 0, 0, 0, 0, "FRC", TGSI_OPCODE_FRC },
|
||||
{ 1, 3, 0, 0, 0, 0, "CLAMP", TGSI_OPCODE_CLAMP },
|
||||
{ 1, 1, 0, 0, 0, 0, "FLR", TGSI_OPCODE_FLR },
|
||||
{ 1, 1, 0, 0, 0, 0, "ROUND", TGSI_OPCODE_ROUND },
|
||||
{ 1, 1, 0, 0, 0, 0, "EX2", TGSI_OPCODE_EX2 },
|
||||
{ 1, 1, 0, 0, 0, 0, "LG2", TGSI_OPCODE_LG2 },
|
||||
{ 1, 2, 0, 0, 0, 0, "POW", TGSI_OPCODE_POW },
|
||||
{ 1, 2, 0, 0, 0, 0, "XPD", TGSI_OPCODE_XPD },
|
||||
{ 0, 0, 0, 0, 0, 0, "", 32 }, /* removed */
|
||||
{ 1, 1, 0, 0, 0, 0, "ABS", TGSI_OPCODE_ABS },
|
||||
{ 1, 1, 0, 0, 0, 0, "RCC", TGSI_OPCODE_RCC },
|
||||
{ 1, 2, 0, 0, 0, 0, "DPH", TGSI_OPCODE_DPH },
|
||||
{ 1, 1, 0, 0, 0, 0, "COS", TGSI_OPCODE_COS },
|
||||
{ 1, 1, 0, 0, 0, 0, "DDX", TGSI_OPCODE_DDX },
|
||||
{ 1, 1, 0, 0, 0, 0, "DDY", TGSI_OPCODE_DDY },
|
||||
{ 0, 0, 0, 0, 0, 0, "KILP", TGSI_OPCODE_KILP },
|
||||
{ 1, 1, 0, 0, 0, 0, "PK2H", TGSI_OPCODE_PK2H },
|
||||
{ 1, 1, 0, 0, 0, 0, "PK2US", TGSI_OPCODE_PK2US },
|
||||
{ 1, 1, 0, 0, 0, 0, "PK4B", TGSI_OPCODE_PK4B },
|
||||
{ 1, 1, 0, 0, 0, 0, "PK4UB", TGSI_OPCODE_PK4UB },
|
||||
{ 1, 2, 0, 0, 0, 0, "RFL", TGSI_OPCODE_RFL },
|
||||
{ 1, 2, 0, 0, 0, 0, "SEQ", TGSI_OPCODE_SEQ },
|
||||
{ 1, 2, 0, 0, 0, 0, "SFL", TGSI_OPCODE_SFL },
|
||||
{ 1, 2, 0, 0, 0, 0, "SGT", TGSI_OPCODE_SGT },
|
||||
{ 1, 1, 0, 0, 0, 0, "SIN", TGSI_OPCODE_SIN },
|
||||
{ 1, 2, 0, 0, 0, 0, "SLE", TGSI_OPCODE_SLE },
|
||||
{ 1, 2, 0, 0, 0, 0, "SNE", TGSI_OPCODE_SNE },
|
||||
{ 1, 2, 0, 0, 0, 0, "STR", TGSI_OPCODE_STR },
|
||||
{ 1, 2, 1, 0, 0, 0, "TEX", TGSI_OPCODE_TEX },
|
||||
{ 1, 4, 1, 0, 0, 0, "TXD", TGSI_OPCODE_TXD },
|
||||
{ 1, 2, 1, 0, 0, 0, "TXP", TGSI_OPCODE_TXP },
|
||||
{ 1, 1, 0, 0, 0, 0, "UP2H", TGSI_OPCODE_UP2H },
|
||||
{ 1, 1, 0, 0, 0, 0, "UP2US", TGSI_OPCODE_UP2US },
|
||||
{ 1, 1, 0, 0, 0, 0, "UP4B", TGSI_OPCODE_UP4B },
|
||||
{ 1, 1, 0, 0, 0, 0, "UP4UB", TGSI_OPCODE_UP4UB },
|
||||
{ 1, 3, 0, 0, 0, 0, "X2D", TGSI_OPCODE_X2D },
|
||||
{ 1, 1, 0, 0, 0, 0, "ARA", TGSI_OPCODE_ARA },
|
||||
{ 1, 1, 0, 0, 0, 0, "ARR", TGSI_OPCODE_ARR },
|
||||
{ 0, 1, 0, 0, 0, 0, "BRA", TGSI_OPCODE_BRA },
|
||||
{ 0, 0, 0, 1, 0, 0, "CAL", TGSI_OPCODE_CAL },
|
||||
{ 0, 0, 0, 0, 0, 0, "RET", TGSI_OPCODE_RET },
|
||||
{ 1, 1, 0, 0, 0, 0, "SSG", TGSI_OPCODE_SSG },
|
||||
{ 1, 3, 0, 0, 0, 0, "CMP", TGSI_OPCODE_CMP },
|
||||
{ 1, 1, 0, 0, 0, 0, "SCS", TGSI_OPCODE_SCS },
|
||||
{ 1, 2, 1, 0, 0, 0, "TXB", TGSI_OPCODE_TXB },
|
||||
{ 1, 1, 0, 0, 0, 0, "NRM", TGSI_OPCODE_NRM },
|
||||
{ 1, 2, 0, 0, 0, 0, "DIV", TGSI_OPCODE_DIV },
|
||||
{ 1, 2, 0, 0, 0, 0, "DP2", TGSI_OPCODE_DP2 },
|
||||
{ 1, 2, 1, 0, 0, 0, "TXL", TGSI_OPCODE_TXL },
|
||||
{ 0, 0, 0, 0, 0, 0, "BRK", TGSI_OPCODE_BRK },
|
||||
{ 0, 1, 0, 1, 0, 1, "IF", TGSI_OPCODE_IF },
|
||||
{ 1, 1, 0, 0, 0, 1, "BGNFOR", TGSI_OPCODE_BGNFOR },
|
||||
{ 0, 1, 0, 0, 0, 1, "REP", TGSI_OPCODE_REP },
|
||||
{ 0, 0, 0, 1, 1, 1, "ELSE", TGSI_OPCODE_ELSE },
|
||||
{ 0, 0, 0, 0, 1, 0, "ENDIF", TGSI_OPCODE_ENDIF },
|
||||
{ 1, 0, 0, 0, 1, 0, "ENDFOR", TGSI_OPCODE_ENDFOR },
|
||||
{ 0, 0, 0, 0, 1, 0, "ENDREP", TGSI_OPCODE_ENDREP },
|
||||
{ 0, 1, 0, 0, 0, 0, "PUSHA", TGSI_OPCODE_PUSHA },
|
||||
{ 1, 0, 0, 0, 0, 0, "POPA", TGSI_OPCODE_POPA },
|
||||
{ 1, 1, 0, 0, 0, 0, "CEIL", TGSI_OPCODE_CEIL },
|
||||
{ 1, 1, 0, 0, 0, 0, "I2F", TGSI_OPCODE_I2F },
|
||||
{ 1, 1, 0, 0, 0, 0, "NOT", TGSI_OPCODE_NOT },
|
||||
{ 1, 1, 0, 0, 0, 0, "TRUNC", TGSI_OPCODE_TRUNC },
|
||||
{ 1, 2, 0, 0, 0, 0, "SHL", TGSI_OPCODE_SHL },
|
||||
{ 1, 2, 0, 0, 0, 0, "SHR", TGSI_OPCODE_SHR },
|
||||
{ 1, 2, 0, 0, 0, 0, "AND", TGSI_OPCODE_AND },
|
||||
{ 1, 2, 0, 0, 0, 0, "OR", TGSI_OPCODE_OR },
|
||||
{ 1, 2, 0, 0, 0, 0, "MOD", TGSI_OPCODE_MOD },
|
||||
{ 1, 2, 0, 0, 0, 0, "XOR", TGSI_OPCODE_XOR },
|
||||
{ 1, 3, 0, 0, 0, 0, "SAD", TGSI_OPCODE_SAD },
|
||||
{ 1, 2, 1, 0, 0, 0, "TXF", TGSI_OPCODE_TXF },
|
||||
{ 1, 2, 1, 0, 0, 0, "TXQ", TGSI_OPCODE_TXQ },
|
||||
{ 0, 0, 0, 0, 0, 0, "CONT", TGSI_OPCODE_CONT },
|
||||
{ 0, 0, 0, 0, 0, 0, "EMIT", TGSI_OPCODE_EMIT },
|
||||
{ 0, 0, 0, 0, 0, 0, "ENDPRIM", TGSI_OPCODE_ENDPRIM },
|
||||
{ 0, 0, 0, 1, 0, 1, "BGNLOOP", TGSI_OPCODE_BGNLOOP },
|
||||
{ 0, 0, 0, 0, 0, 1, "BGNSUB", TGSI_OPCODE_BGNSUB },
|
||||
{ 0, 0, 0, 1, 1, 0, "ENDLOOP", TGSI_OPCODE_ENDLOOP },
|
||||
{ 0, 0, 0, 0, 1, 0, "ENDSUB", TGSI_OPCODE_ENDSUB },
|
||||
{ 1, 1, 0, 0, 0, 0, "NOISE1", TGSI_OPCODE_NOISE1 },
|
||||
{ 1, 1, 0, 0, 0, 0, "NOISE2", TGSI_OPCODE_NOISE2 },
|
||||
{ 1, 1, 0, 0, 0, 0, "NOISE3", TGSI_OPCODE_NOISE3 },
|
||||
{ 1, 1, 0, 0, 0, 0, "NOISE4", TGSI_OPCODE_NOISE4 },
|
||||
{ 0, 0, 0, 0, 0, 0, "NOP", TGSI_OPCODE_NOP },
|
||||
{ 0, 0, 0, 0, 0, 0, "", 108 }, /* removed */
|
||||
{ 0, 0, 0, 0, 0, 0, "", 109 }, /* removed */
|
||||
{ 0, 0, 0, 0, 0, 0, "", 110 }, /* removed */
|
||||
{ 0, 0, 0, 0, 0, 0, "", 111 }, /* removed */
|
||||
{ 1, 1, 0, 0, 0, 0, "NRM4", TGSI_OPCODE_NRM4 },
|
||||
{ 0, 1, 0, 0, 0, 0, "CALLNZ", TGSI_OPCODE_CALLNZ },
|
||||
{ 0, 1, 0, 0, 0, 0, "IFC", TGSI_OPCODE_IFC },
|
||||
{ 0, 1, 0, 0, 0, 0, "BREAKC", TGSI_OPCODE_BREAKC },
|
||||
{ 0, 1, 0, 0, 0, 0, "KIL", TGSI_OPCODE_KIL },
|
||||
{ 0, 0, 0, 0, 0, 0, "END", TGSI_OPCODE_END },
|
||||
{ 1, 1, 0, 0, 0, 0, "SWZ", TGSI_OPCODE_SWZ }
|
||||
};
|
||||
|
||||
const struct tgsi_opcode_info *
|
||||
|
|
|
@ -36,10 +36,12 @@ extern "C" {
|
|||
|
||||
struct tgsi_opcode_info
|
||||
{
|
||||
uint num_dst;
|
||||
uint num_src;
|
||||
boolean is_tex;
|
||||
boolean is_branch;
|
||||
unsigned num_dst:3;
|
||||
unsigned num_src:3;
|
||||
unsigned is_tex:1;
|
||||
unsigned is_branch:1;
|
||||
int pre_dedent:2;
|
||||
int post_indent:2;
|
||||
const char *mnemonic;
|
||||
uint opcode;
|
||||
};
|
||||
|
|
|
@ -60,7 +60,6 @@ OP13(MAD)
|
|||
OP12(SUB)
|
||||
OP13(LRP)
|
||||
OP13(CND)
|
||||
OP13(CND0)
|
||||
OP13(DP2A)
|
||||
OP11(FRC)
|
||||
OP13(CLAMP)
|
||||
|
|
|
@ -199,10 +199,10 @@ iter_instruction(
|
|||
}
|
||||
|
||||
if (info->num_dst != inst->Instruction.NumDstRegs) {
|
||||
report_error( ctx, "Invalid number of destination operands, should be %u", info->num_dst );
|
||||
report_error( ctx, "%s: Invalid number of destination operands, should be %u", info->mnemonic, info->num_dst );
|
||||
}
|
||||
if (info->num_src != inst->Instruction.NumSrcRegs) {
|
||||
report_error( ctx, "Invalid number of source operands, should be %u", info->num_src );
|
||||
report_error( ctx, "%s: Invalid number of source operands, should be %u", info->mnemonic, info->num_src );
|
||||
}
|
||||
|
||||
/* Check destination and source registers' validity.
|
||||
|
|
|
@ -2089,10 +2089,6 @@ emit_instruction(
|
|||
return 0;
|
||||
break;
|
||||
|
||||
case TGSI_OPCODE_CND0:
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case TGSI_OPCODE_DP2A:
|
||||
FETCH( func, *inst, 0, 0, CHAN_X ); /* xmm0 = src[0].x */
|
||||
FETCH( func, *inst, 1, 1, CHAN_X ); /* xmm1 = src[1].x */
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "pipe/p_context.h"
|
||||
#include "pipe/p_state.h"
|
||||
#include "tgsi/tgsi_ureg.h"
|
||||
#include "tgsi/tgsi_info.h"
|
||||
#include "tgsi/tgsi_dump.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_math.h"
|
||||
|
@ -71,6 +72,7 @@ struct ureg_tokens {
|
|||
#define UREG_MAX_OUTPUT PIPE_MAX_ATTRIBS
|
||||
#define UREG_MAX_IMMEDIATE 32
|
||||
#define UREG_MAX_TEMP 256
|
||||
#define UREG_MAX_ADDR 2
|
||||
|
||||
#define DOMAIN_DECL 0
|
||||
#define DOMAIN_INSN 1
|
||||
|
@ -99,11 +101,15 @@ struct ureg_program
|
|||
} immediate[UREG_MAX_IMMEDIATE];
|
||||
unsigned nr_immediates;
|
||||
|
||||
struct ureg_src sampler[PIPE_MAX_SAMPLERS];
|
||||
unsigned nr_samplers;
|
||||
|
||||
unsigned temps_active[UREG_MAX_TEMP / 32];
|
||||
unsigned nr_temps;
|
||||
|
||||
unsigned nr_addrs;
|
||||
|
||||
unsigned nr_constants;
|
||||
unsigned nr_samplers;
|
||||
unsigned nr_instructions;
|
||||
|
||||
struct ureg_tokens domain[2];
|
||||
|
@ -187,6 +193,8 @@ ureg_dst_register( unsigned file,
|
|||
dst.File = file;
|
||||
dst.WriteMask = TGSI_WRITEMASK_XYZW;
|
||||
dst.Indirect = 0;
|
||||
dst.IndirectIndex = 0;
|
||||
dst.IndirectSwizzle = 0;
|
||||
dst.Saturate = 0;
|
||||
dst.Index = index;
|
||||
dst.Pad1 = 0;
|
||||
|
@ -208,6 +216,8 @@ ureg_src_register( unsigned file,
|
|||
src.SwizzleW = TGSI_SWIZZLE_W;
|
||||
src.Pad = 0;
|
||||
src.Indirect = 0;
|
||||
src.IndirectIndex = 0;
|
||||
src.IndirectSwizzle = 0;
|
||||
src.Absolute = 0;
|
||||
src.Index = index;
|
||||
src.Negate = 0;
|
||||
|
@ -254,6 +264,7 @@ ureg_DECL_fs_input( struct ureg_program *ureg,
|
|||
unsigned index,
|
||||
unsigned interp )
|
||||
{
|
||||
assert(ureg->processor == TGSI_PROCESSOR_FRAGMENT);
|
||||
return ureg_DECL_input( ureg, name, index, interp );
|
||||
}
|
||||
|
||||
|
@ -263,6 +274,7 @@ ureg_DECL_vs_input( struct ureg_program *ureg,
|
|||
unsigned name,
|
||||
unsigned index )
|
||||
{
|
||||
assert(ureg->processor == TGSI_PROCESSOR_VERTEX);
|
||||
return ureg_DECL_input( ureg, name, index, TGSI_INTERPOLATE_CONSTANT );
|
||||
}
|
||||
|
||||
|
@ -346,11 +358,36 @@ void ureg_release_temporary( struct ureg_program *ureg,
|
|||
}
|
||||
|
||||
|
||||
/* Allocate a new address register.
|
||||
*/
|
||||
struct ureg_dst ureg_DECL_address( struct ureg_program *ureg )
|
||||
{
|
||||
if (ureg->nr_addrs < UREG_MAX_ADDR)
|
||||
return ureg_dst_register( TGSI_FILE_ADDRESS, ureg->nr_addrs++ );
|
||||
|
||||
assert( 0 );
|
||||
return ureg_dst_register( TGSI_FILE_ADDRESS, 0 );
|
||||
}
|
||||
|
||||
/* Allocate a new sampler.
|
||||
*/
|
||||
struct ureg_src ureg_DECL_sampler( struct ureg_program *ureg )
|
||||
struct ureg_src ureg_DECL_sampler( struct ureg_program *ureg,
|
||||
unsigned nr )
|
||||
{
|
||||
return ureg_src_register( TGSI_FILE_SAMPLER, ureg->nr_samplers++ );
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < ureg->nr_samplers; i++)
|
||||
if (ureg->sampler[i].Index == nr)
|
||||
return ureg->sampler[i];
|
||||
|
||||
if (i < PIPE_MAX_SAMPLERS) {
|
||||
ureg->sampler[i] = ureg_src_register( TGSI_FILE_SAMPLER, nr );
|
||||
ureg->nr_samplers++;
|
||||
return ureg->sampler[i];
|
||||
}
|
||||
|
||||
assert( 0 );
|
||||
return ureg->sampler[0];
|
||||
}
|
||||
|
||||
|
||||
|
@ -363,6 +400,8 @@ static int match_or_expand_immediate( const float *v,
|
|||
unsigned *swizzle )
|
||||
{
|
||||
unsigned i, j;
|
||||
|
||||
*swizzle = 0;
|
||||
|
||||
for (i = 0; i < nr; i++) {
|
||||
boolean found = FALSE;
|
||||
|
@ -394,8 +433,8 @@ struct ureg_src ureg_DECL_immediate( struct ureg_program *ureg,
|
|||
const float *v,
|
||||
unsigned nr )
|
||||
{
|
||||
unsigned i;
|
||||
unsigned swizzle = 0;
|
||||
unsigned i, j;
|
||||
unsigned swizzle;
|
||||
|
||||
/* Could do a first pass where we examine all existing immediates
|
||||
* without expanding.
|
||||
|
@ -423,6 +462,12 @@ struct ureg_src ureg_DECL_immediate( struct ureg_program *ureg,
|
|||
set_bad( ureg );
|
||||
|
||||
out:
|
||||
/* Make sure that all referenced elements are from this immediate.
|
||||
* Has the effect of making size-one immediates into scalars.
|
||||
*/
|
||||
for (j = nr; j < 4; j++)
|
||||
swizzle |= (swizzle & 0x3) << (j * 2);
|
||||
|
||||
return ureg_swizzle( ureg_src_register( TGSI_FILE_IMMEDIATE, i ),
|
||||
(swizzle >> 0) & 0x3,
|
||||
(swizzle >> 2) & 0x3,
|
||||
|
@ -442,31 +487,39 @@ ureg_emit_src( struct ureg_program *ureg,
|
|||
union tgsi_any_token *out = get_tokens( ureg, DOMAIN_INSN, size );
|
||||
unsigned n = 0;
|
||||
|
||||
assert(src.File != TGSI_FILE_NULL);
|
||||
assert(src.File != TGSI_FILE_OUTPUT);
|
||||
assert(src.File < TGSI_FILE_COUNT);
|
||||
|
||||
out[n].value = 0;
|
||||
out[n].src.File = src.File;
|
||||
out[n].src.SwizzleX = src.SwizzleX;
|
||||
out[n].src.SwizzleY = src.SwizzleY;
|
||||
out[n].src.SwizzleZ = src.SwizzleZ;
|
||||
out[n].src.SwizzleW = src.SwizzleW;
|
||||
out[n].src.Indirect = src.Indirect;
|
||||
out[n].src.Index = src.Index;
|
||||
out[n].src.Negate = src.Negate;
|
||||
n++;
|
||||
|
||||
if (src.Absolute) {
|
||||
out[0].src.Extended = 1;
|
||||
out[0].src.Negate = 0;
|
||||
out[n].value = 0;
|
||||
out[n].src_ext_mod.Type = TGSI_SRC_REGISTER_EXT_TYPE_MOD;
|
||||
out[n].src_ext_mod.Absolute = 1;
|
||||
out[n].src_ext_mod.Negate = src.Negate;
|
||||
n++;
|
||||
}
|
||||
|
||||
if (src.Indirect) {
|
||||
out[0].src.Indirect = 1;
|
||||
out[n].value = 0;
|
||||
out[n].src.File = TGSI_FILE_ADDRESS;
|
||||
out[n].src.SwizzleX = TGSI_SWIZZLE_X;
|
||||
out[n].src.SwizzleY = TGSI_SWIZZLE_X;
|
||||
out[n].src.SwizzleZ = TGSI_SWIZZLE_X;
|
||||
out[n].src.SwizzleW = TGSI_SWIZZLE_X;
|
||||
out[n].src.Indirect = 0;
|
||||
out[n].src.Index = 0;
|
||||
out[n].src.SwizzleX = src.IndirectSwizzle;
|
||||
out[n].src.SwizzleY = src.IndirectSwizzle;
|
||||
out[n].src.SwizzleZ = src.IndirectSwizzle;
|
||||
out[n].src.SwizzleW = src.IndirectSwizzle;
|
||||
out[n].src.Index = src.IndirectIndex;
|
||||
n++;
|
||||
}
|
||||
|
||||
|
@ -484,6 +537,13 @@ ureg_emit_dst( struct ureg_program *ureg,
|
|||
union tgsi_any_token *out = get_tokens( ureg, DOMAIN_INSN, size );
|
||||
unsigned n = 0;
|
||||
|
||||
assert(dst.File != TGSI_FILE_NULL);
|
||||
assert(dst.File != TGSI_FILE_CONSTANT);
|
||||
assert(dst.File != TGSI_FILE_INPUT);
|
||||
assert(dst.File != TGSI_FILE_SAMPLER);
|
||||
assert(dst.File != TGSI_FILE_IMMEDIATE);
|
||||
assert(dst.File < TGSI_FILE_COUNT);
|
||||
|
||||
out[n].value = 0;
|
||||
out[n].dst.File = dst.File;
|
||||
out[n].dst.WriteMask = dst.WriteMask;
|
||||
|
@ -494,12 +554,11 @@ ureg_emit_dst( struct ureg_program *ureg,
|
|||
if (dst.Indirect) {
|
||||
out[n].value = 0;
|
||||
out[n].src.File = TGSI_FILE_ADDRESS;
|
||||
out[n].src.SwizzleX = TGSI_SWIZZLE_X;
|
||||
out[n].src.SwizzleY = TGSI_SWIZZLE_X;
|
||||
out[n].src.SwizzleZ = TGSI_SWIZZLE_X;
|
||||
out[n].src.SwizzleW = TGSI_SWIZZLE_X;
|
||||
out[n].src.Indirect = 0;
|
||||
out[n].src.Index = 0;
|
||||
out[n].src.SwizzleX = dst.IndirectSwizzle;
|
||||
out[n].src.SwizzleY = dst.IndirectSwizzle;
|
||||
out[n].src.SwizzleZ = dst.IndirectSwizzle;
|
||||
out[n].src.SwizzleW = dst.IndirectSwizzle;
|
||||
out[n].src.Index = dst.IndirectIndex;
|
||||
n++;
|
||||
}
|
||||
|
||||
|
@ -523,7 +582,6 @@ ureg_emit_insn(struct ureg_program *ureg,
|
|||
out[0].insn.NrTokens = 0;
|
||||
out[0].insn.Opcode = opcode;
|
||||
out[0].insn.Saturate = saturate;
|
||||
out[0].insn.NrTokens = 0;
|
||||
out[0].insn.NumDstRegs = num_dst;
|
||||
out[0].insn.NumSrcRegs = num_src;
|
||||
out[0].insn.Padding = 0;
|
||||
|
@ -542,6 +600,9 @@ ureg_emit_label(struct ureg_program *ureg,
|
|||
{
|
||||
union tgsi_any_token *out, *insn;
|
||||
|
||||
if(!label_token)
|
||||
return;
|
||||
|
||||
out = get_tokens( ureg, DOMAIN_INSN, 1 );
|
||||
insn = retrieve_token( ureg, DOMAIN_INSN, insn_token );
|
||||
|
||||
|
@ -617,6 +678,17 @@ ureg_insn(struct ureg_program *ureg,
|
|||
unsigned insn, i;
|
||||
boolean saturate;
|
||||
|
||||
#ifdef DEBUG
|
||||
{
|
||||
const struct tgsi_opcode_info *info = tgsi_get_opcode_info( opcode );
|
||||
assert(info);
|
||||
if(info) {
|
||||
assert(nr_dst == info->num_dst);
|
||||
assert(nr_src == info->num_src);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
saturate = nr_dst ? dst[0].Saturate : FALSE;
|
||||
|
||||
insn = ureg_emit_insn( ureg, opcode, saturate, nr_dst, nr_src );
|
||||
|
@ -723,10 +795,10 @@ static void emit_decls( struct ureg_program *ureg )
|
|||
TGSI_INTERPOLATE_CONSTANT );
|
||||
}
|
||||
|
||||
if (ureg->nr_samplers) {
|
||||
for (i = 0; i < ureg->nr_samplers; i++) {
|
||||
emit_decl_range( ureg,
|
||||
TGSI_FILE_SAMPLER,
|
||||
0, ureg->nr_samplers );
|
||||
ureg->sampler[i].Index, 1 );
|
||||
}
|
||||
|
||||
if (ureg->nr_constants) {
|
||||
|
@ -741,6 +813,12 @@ static void emit_decls( struct ureg_program *ureg )
|
|||
0, ureg->nr_temps );
|
||||
}
|
||||
|
||||
if (ureg->nr_addrs) {
|
||||
emit_decl_range( ureg,
|
||||
TGSI_FILE_ADDRESS,
|
||||
0, ureg->nr_addrs );
|
||||
}
|
||||
|
||||
for (i = 0; i < ureg->nr_immediates; i++) {
|
||||
emit_immediate( ureg,
|
||||
ureg->immediate[i].v );
|
||||
|
@ -764,7 +842,7 @@ static void copy_instructions( struct ureg_program *ureg )
|
|||
|
||||
|
||||
static void
|
||||
fixup_header_size(struct ureg_program *ureg )
|
||||
fixup_header_size(struct ureg_program *ureg)
|
||||
{
|
||||
union tgsi_any_token *out = retrieve_token( ureg, DOMAIN_DECL, 1 );
|
||||
|
||||
|
|
|
@ -31,6 +31,10 @@
|
|||
#include "pipe/p_compiler.h"
|
||||
#include "pipe/p_shader_tokens.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct ureg_program;
|
||||
|
||||
/* Almost a tgsi_src_register, but we need to pull in the Absolute
|
||||
|
@ -48,6 +52,8 @@ struct ureg_src
|
|||
unsigned Absolute : 1; /* BOOL */
|
||||
int Index : 16; /* SINT */
|
||||
unsigned Negate : 1; /* BOOL */
|
||||
int IndirectIndex : 16; /* SINT */
|
||||
int IndirectSwizzle : 2; /* TGSI_SWIZZLE_ */
|
||||
};
|
||||
|
||||
/* Very similar to a tgsi_dst_register, removing unsupported fields
|
||||
|
@ -64,6 +70,8 @@ struct ureg_dst
|
|||
int Index : 16; /* SINT */
|
||||
unsigned Pad1 : 5;
|
||||
unsigned Pad2 : 1; /* BOOL */
|
||||
int IndirectIndex : 16; /* SINT */
|
||||
int IndirectSwizzle : 2; /* TGSI_SWIZZLE_ */
|
||||
};
|
||||
|
||||
struct pipe_context;
|
||||
|
@ -131,12 +139,21 @@ void
|
|||
ureg_release_temporary( struct ureg_program *ureg,
|
||||
struct ureg_dst tmp );
|
||||
|
||||
struct ureg_dst
|
||||
ureg_DECL_address( struct ureg_program * );
|
||||
|
||||
/* Supply an index to the sampler declaration as this is the hook to
|
||||
* the external pipe_sampler state. Users of this function probably
|
||||
* don't want just any sampler, but a specific one which they've set
|
||||
* up state for in the context.
|
||||
*/
|
||||
struct ureg_src
|
||||
ureg_DECL_sampler( struct ureg_program * );
|
||||
ureg_DECL_sampler( struct ureg_program *,
|
||||
unsigned index );
|
||||
|
||||
|
||||
static INLINE struct ureg_src
|
||||
ureg_DECL_immediate4f( struct ureg_program *ureg,
|
||||
ureg_imm4f( struct ureg_program *ureg,
|
||||
float a, float b,
|
||||
float c, float d)
|
||||
{
|
||||
|
@ -149,7 +166,7 @@ ureg_DECL_immediate4f( struct ureg_program *ureg,
|
|||
}
|
||||
|
||||
static INLINE struct ureg_src
|
||||
ureg_DECL_immediate3f( struct ureg_program *ureg,
|
||||
ureg_imm3f( struct ureg_program *ureg,
|
||||
float a, float b,
|
||||
float c)
|
||||
{
|
||||
|
@ -161,7 +178,7 @@ ureg_DECL_immediate3f( struct ureg_program *ureg,
|
|||
}
|
||||
|
||||
static INLINE struct ureg_src
|
||||
ureg_DECL_immediate2f( struct ureg_program *ureg,
|
||||
ureg_imm2f( struct ureg_program *ureg,
|
||||
float a, float b)
|
||||
{
|
||||
float v[2];
|
||||
|
@ -171,7 +188,7 @@ ureg_DECL_immediate2f( struct ureg_program *ureg,
|
|||
}
|
||||
|
||||
static INLINE struct ureg_src
|
||||
ureg_DECL_immediate1f( struct ureg_program *ureg,
|
||||
ureg_imm1f( struct ureg_program *ureg,
|
||||
float a)
|
||||
{
|
||||
float v[1];
|
||||
|
@ -392,6 +409,7 @@ static INLINE void ureg_##op( struct ureg_program *ureg, \
|
|||
static INLINE struct ureg_src
|
||||
ureg_negate( struct ureg_src reg )
|
||||
{
|
||||
assert(reg.File != TGSI_FILE_NULL);
|
||||
reg.Negate ^= 1;
|
||||
return reg;
|
||||
}
|
||||
|
@ -399,6 +417,7 @@ ureg_negate( struct ureg_src reg )
|
|||
static INLINE struct ureg_src
|
||||
ureg_abs( struct ureg_src reg )
|
||||
{
|
||||
assert(reg.File != TGSI_FILE_NULL);
|
||||
reg.Absolute = 1;
|
||||
reg.Negate = 0;
|
||||
return reg;
|
||||
|
@ -413,6 +432,12 @@ ureg_swizzle( struct ureg_src reg,
|
|||
(reg.SwizzleZ << 4) |
|
||||
(reg.SwizzleW << 6));
|
||||
|
||||
assert(reg.File != TGSI_FILE_NULL);
|
||||
assert(x < 4);
|
||||
assert(y < 4);
|
||||
assert(z < 4);
|
||||
assert(w < 4);
|
||||
|
||||
reg.SwizzleX = (swz >> (x*2)) & 0x3;
|
||||
reg.SwizzleY = (swz >> (y*2)) & 0x3;
|
||||
reg.SwizzleZ = (swz >> (z*2)) & 0x3;
|
||||
|
@ -430,6 +455,7 @@ static INLINE struct ureg_dst
|
|||
ureg_writemask( struct ureg_dst reg,
|
||||
unsigned writemask )
|
||||
{
|
||||
assert(reg.File != TGSI_FILE_NULL);
|
||||
reg.WriteMask &= writemask;
|
||||
return reg;
|
||||
}
|
||||
|
@ -437,10 +463,33 @@ ureg_writemask( struct ureg_dst reg,
|
|||
static INLINE struct ureg_dst
|
||||
ureg_saturate( struct ureg_dst reg )
|
||||
{
|
||||
assert(reg.File != TGSI_FILE_NULL);
|
||||
reg.Saturate = 1;
|
||||
return reg;
|
||||
}
|
||||
|
||||
static INLINE struct ureg_dst
|
||||
ureg_dst_indirect( struct ureg_dst reg, struct ureg_src addr )
|
||||
{
|
||||
assert(reg.File != TGSI_FILE_NULL);
|
||||
assert(addr.File == TGSI_FILE_ADDRESS);
|
||||
reg.Indirect = 1;
|
||||
reg.IndirectIndex = addr.Index;
|
||||
reg.IndirectSwizzle = addr.SwizzleX;
|
||||
return reg;
|
||||
}
|
||||
|
||||
static INLINE struct ureg_src
|
||||
ureg_src_indirect( struct ureg_src reg, struct ureg_src addr )
|
||||
{
|
||||
assert(reg.File != TGSI_FILE_NULL);
|
||||
assert(addr.File == TGSI_FILE_ADDRESS);
|
||||
reg.Indirect = 1;
|
||||
reg.IndirectIndex = addr.Index;
|
||||
reg.IndirectSwizzle = addr.SwizzleX;
|
||||
return reg;
|
||||
}
|
||||
|
||||
static INLINE struct ureg_dst
|
||||
ureg_dst( struct ureg_src src )
|
||||
{
|
||||
|
@ -449,6 +498,8 @@ ureg_dst( struct ureg_src src )
|
|||
dst.File = src.File;
|
||||
dst.WriteMask = TGSI_WRITEMASK_XYZW;
|
||||
dst.Indirect = src.Indirect;
|
||||
dst.IndirectIndex = src.IndirectIndex;
|
||||
dst.IndirectSwizzle = src.IndirectSwizzle;
|
||||
dst.Saturate = 0;
|
||||
dst.Index = src.Index;
|
||||
dst.Pad1 = 0;
|
||||
|
@ -469,6 +520,8 @@ ureg_src( struct ureg_dst dst )
|
|||
src.SwizzleW = TGSI_SWIZZLE_W;
|
||||
src.Pad = 0;
|
||||
src.Indirect = dst.Indirect;
|
||||
src.IndirectIndex = dst.IndirectIndex;
|
||||
src.IndirectSwizzle = dst.IndirectSwizzle;
|
||||
src.Absolute = 0;
|
||||
src.Index = dst.Index;
|
||||
src.Negate = 0;
|
||||
|
@ -478,4 +531,60 @@ ureg_src( struct ureg_dst dst )
|
|||
|
||||
|
||||
|
||||
static INLINE struct ureg_dst
|
||||
ureg_dst_undef( void )
|
||||
{
|
||||
struct ureg_dst dst;
|
||||
|
||||
dst.File = TGSI_FILE_NULL;
|
||||
dst.WriteMask = 0;
|
||||
dst.Indirect = 0;
|
||||
dst.IndirectIndex = 0;
|
||||
dst.IndirectSwizzle = 0;
|
||||
dst.Saturate = 0;
|
||||
dst.Index = 0;
|
||||
dst.Pad1 = 0;
|
||||
dst.Pad2 = 0;
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
static INLINE struct ureg_src
|
||||
ureg_src_undef( void )
|
||||
{
|
||||
struct ureg_src src;
|
||||
|
||||
src.File = TGSI_FILE_NULL;
|
||||
src.SwizzleX = 0;
|
||||
src.SwizzleY = 0;
|
||||
src.SwizzleZ = 0;
|
||||
src.SwizzleW = 0;
|
||||
src.Pad = 0;
|
||||
src.Indirect = 0;
|
||||
src.IndirectIndex = 0;
|
||||
src.IndirectSwizzle = 0;
|
||||
src.Absolute = 0;
|
||||
src.Index = 0;
|
||||
src.Negate = 0;
|
||||
|
||||
return src;
|
||||
}
|
||||
|
||||
static INLINE boolean
|
||||
ureg_src_is_undef( struct ureg_src src )
|
||||
{
|
||||
return src.File == TGSI_FILE_NULL;
|
||||
}
|
||||
|
||||
static INLINE boolean
|
||||
ureg_dst_is_undef( struct ureg_dst dst )
|
||||
{
|
||||
return dst.File == TGSI_FILE_NULL;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -32,6 +32,10 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct tgsi_src_register;
|
||||
struct tgsi_src_register_ext_swz;
|
||||
struct tgsi_full_src_register;
|
||||
|
||||
void *
|
||||
tgsi_align_128bit(
|
||||
void *unaligned );
|
||||
|
|
|
@ -62,7 +62,7 @@ struct blit_state
|
|||
struct pipe_viewport_state viewport;
|
||||
|
||||
void *vs;
|
||||
void *fs;
|
||||
void *fs[TGSI_WRITEMASK_XYZW + 1];
|
||||
|
||||
struct pipe_buffer *vbuf; /**< quad vertices */
|
||||
unsigned vbuf_slot;
|
||||
|
@ -125,7 +125,7 @@ util_create_blit(struct pipe_context *pipe, struct cso_context *cso)
|
|||
}
|
||||
|
||||
/* fragment shader */
|
||||
ctx->fs = util_make_fragment_tex_shader(pipe);
|
||||
ctx->fs[TGSI_WRITEMASK_XYZW] = util_make_fragment_tex_shader(pipe);
|
||||
ctx->vbuf = NULL;
|
||||
|
||||
/* init vertex data that doesn't change */
|
||||
|
@ -146,9 +146,13 @@ void
|
|||
util_destroy_blit(struct blit_state *ctx)
|
||||
{
|
||||
struct pipe_context *pipe = ctx->pipe;
|
||||
unsigned i;
|
||||
|
||||
pipe->delete_vs_state(pipe, ctx->vs);
|
||||
pipe->delete_fs_state(pipe, ctx->fs);
|
||||
|
||||
for (i = 0; i < Elements(ctx->fs); i++)
|
||||
if (ctx->fs[i])
|
||||
pipe->delete_fs_state(pipe, ctx->fs[i]);
|
||||
|
||||
pipe_buffer_reference(&ctx->vbuf, NULL);
|
||||
|
||||
|
@ -299,14 +303,15 @@ regions_overlap(int srcX0, int srcY0,
|
|||
* XXX need some control over blitting Z and/or stencil.
|
||||
*/
|
||||
void
|
||||
util_blit_pixels(struct blit_state *ctx,
|
||||
struct pipe_surface *src,
|
||||
int srcX0, int srcY0,
|
||||
int srcX1, int srcY1,
|
||||
struct pipe_surface *dst,
|
||||
int dstX0, int dstY0,
|
||||
int dstX1, int dstY1,
|
||||
float z, uint filter)
|
||||
util_blit_pixels_writemask(struct blit_state *ctx,
|
||||
struct pipe_surface *src,
|
||||
int srcX0, int srcY0,
|
||||
int srcX1, int srcY1,
|
||||
struct pipe_surface *dst,
|
||||
int dstX0, int dstY0,
|
||||
int dstX1, int dstY1,
|
||||
float z, uint filter,
|
||||
uint writemask)
|
||||
{
|
||||
struct pipe_context *pipe = ctx->pipe;
|
||||
struct pipe_screen *screen = pipe->screen;
|
||||
|
@ -426,8 +431,11 @@ util_blit_pixels(struct blit_state *ctx,
|
|||
/* texture */
|
||||
cso_set_sampler_textures(ctx->cso, 1, &tex);
|
||||
|
||||
if (ctx->fs[writemask] == NULL)
|
||||
ctx->fs[writemask] = util_make_fragment_tex_shader_writemask(pipe, writemask);
|
||||
|
||||
/* shaders */
|
||||
cso_set_fragment_shader_handle(ctx->cso, ctx->fs);
|
||||
cso_set_fragment_shader_handle(ctx->cso, ctx->fs[writemask]);
|
||||
cso_set_vertex_shader_handle(ctx->cso, ctx->vs);
|
||||
|
||||
/* drawing dest */
|
||||
|
@ -462,6 +470,27 @@ util_blit_pixels(struct blit_state *ctx,
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
util_blit_pixels(struct blit_state *ctx,
|
||||
struct pipe_surface *src,
|
||||
int srcX0, int srcY0,
|
||||
int srcX1, int srcY1,
|
||||
struct pipe_surface *dst,
|
||||
int dstX0, int dstY0,
|
||||
int dstX1, int dstY1,
|
||||
float z, uint filter )
|
||||
{
|
||||
util_blit_pixels_writemask( ctx, src,
|
||||
srcX0, srcY0,
|
||||
srcX1, srcY1,
|
||||
dst,
|
||||
dstX0, dstY0,
|
||||
dstX1, dstY1,
|
||||
z, filter,
|
||||
TGSI_WRITEMASK_XYZW );
|
||||
}
|
||||
|
||||
|
||||
/* Release vertex buffer at end of frame to avoid synchronous
|
||||
* rendering.
|
||||
*/
|
||||
|
@ -535,7 +564,7 @@ util_blit_pixels_tex(struct blit_state *ctx,
|
|||
cso_set_sampler_textures(ctx->cso, 1, &tex);
|
||||
|
||||
/* shaders */
|
||||
cso_set_fragment_shader_handle(ctx->cso, ctx->fs);
|
||||
cso_set_fragment_shader_handle(ctx->cso, ctx->fs[TGSI_WRITEMASK_XYZW]);
|
||||
cso_set_vertex_shader_handle(ctx->cso, ctx->vs);
|
||||
|
||||
/* drawing dest */
|
||||
|
|
|
@ -60,6 +60,17 @@ util_blit_pixels(struct blit_state *ctx,
|
|||
int dstX1, int dstY1,
|
||||
float z, uint filter);
|
||||
|
||||
void
|
||||
util_blit_pixels_writemask(struct blit_state *ctx,
|
||||
struct pipe_surface *src,
|
||||
int srcX0, int srcY0,
|
||||
int srcX1, int srcY1,
|
||||
struct pipe_surface *dst,
|
||||
int dstX0, int dstY0,
|
||||
int dstX1, int dstY1,
|
||||
float z, uint filter,
|
||||
uint writemask);
|
||||
|
||||
extern void
|
||||
util_blit_pixels_tex(struct blit_state *ctx,
|
||||
struct pipe_texture *tex,
|
||||
|
|
|
@ -374,6 +374,10 @@ unsigned ffs( unsigned u )
|
|||
#define ffs __builtin_ffs
|
||||
#endif
|
||||
|
||||
#ifdef __MINGW32__
|
||||
#define ffs __builtin_ffs
|
||||
#endif
|
||||
|
||||
|
||||
/* Could also binary search for the highest bit.
|
||||
*/
|
||||
|
|
|
@ -88,11 +88,14 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe,
|
|||
|
||||
/**
|
||||
* Make simple fragment texture shader:
|
||||
* TEX OUT[0], IN[0], SAMP[0], 2D;
|
||||
* IMM {0,0,0,1} // (if writemask != 0xf)
|
||||
* MOV OUT[0], IMM[0] // (if writemask != 0xf)
|
||||
* TEX OUT[0].writemask, IN[0], SAMP[0], 2D;
|
||||
* END;
|
||||
*/
|
||||
void *
|
||||
util_make_fragment_tex_shader(struct pipe_context *pipe)
|
||||
util_make_fragment_tex_shader_writemask(struct pipe_context *pipe,
|
||||
unsigned writemask )
|
||||
{
|
||||
struct ureg_program *ureg;
|
||||
struct ureg_src sampler;
|
||||
|
@ -103,7 +106,7 @@ util_make_fragment_tex_shader(struct pipe_context *pipe)
|
|||
if (ureg == NULL)
|
||||
return NULL;
|
||||
|
||||
sampler = ureg_DECL_sampler( ureg );
|
||||
sampler = ureg_DECL_sampler( ureg, 0 );
|
||||
|
||||
tex = ureg_DECL_fs_input( ureg,
|
||||
TGSI_SEMANTIC_GENERIC, 0,
|
||||
|
@ -119,6 +122,13 @@ util_make_fragment_tex_shader(struct pipe_context *pipe)
|
|||
return ureg_create_shader_and_destroy( ureg, pipe );
|
||||
}
|
||||
|
||||
void *
|
||||
util_make_fragment_tex_shader(struct pipe_context *pipe )
|
||||
{
|
||||
return util_make_fragment_tex_shader_writemask( pipe,
|
||||
TGSI_WRITEMASK_XYZW );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -49,6 +49,10 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe,
|
|||
const uint *semantic_indexes);
|
||||
|
||||
|
||||
extern void *
|
||||
util_make_fragment_tex_shader_writemask(struct pipe_context *pipe,
|
||||
unsigned writemask );
|
||||
|
||||
extern void *
|
||||
util_make_fragment_tex_shader(struct pipe_context *pipe);
|
||||
|
||||
|
|
|
@ -1150,10 +1150,6 @@ exec_instruction(
|
|||
ASSERT (0);
|
||||
break;
|
||||
|
||||
case TGSI_OPCODE_CND0:
|
||||
ASSERT (0);
|
||||
break;
|
||||
|
||||
case TGSI_OPCODE_DP2A:
|
||||
ASSERT (0);
|
||||
break;
|
||||
|
|
|
@ -5,6 +5,7 @@ LIBNAME = i915simple
|
|||
|
||||
C_SOURCES = \
|
||||
i915_blit.c \
|
||||
i915_buffer.c \
|
||||
i915_clear.c \
|
||||
i915_flush.c \
|
||||
i915_context.c \
|
||||
|
|
|
@ -6,6 +6,7 @@ i915simple = env.ConvenienceLibrary(
|
|||
target = 'i915simple',
|
||||
source = [
|
||||
'i915_blit.c',
|
||||
'i915_buffer.c',
|
||||
'i915_clear.c',
|
||||
'i915_context.c',
|
||||
'i915_debug.c',
|
||||
|
|
|
@ -28,89 +28,20 @@
|
|||
#ifndef I915_BATCH_H
|
||||
#define I915_BATCH_H
|
||||
|
||||
#include "i915_winsys.h"
|
||||
#include "intel_batchbuffer.h"
|
||||
|
||||
struct i915_batchbuffer
|
||||
{
|
||||
struct pipe_buffer *buffer;
|
||||
struct i915_winsys *winsys;
|
||||
#define BEGIN_BATCH(dwords, relocs) \
|
||||
(intel_batchbuffer_check(i915->batch, dwords, relocs))
|
||||
|
||||
unsigned char *map;
|
||||
unsigned char *ptr;
|
||||
#define OUT_BATCH(dword) \
|
||||
intel_batchbuffer_dword(i915->batch, dword)
|
||||
|
||||
size_t size;
|
||||
size_t actual_size;
|
||||
#define OUT_RELOC(buf, usage, offset) \
|
||||
intel_batchbuffer_reloc(i915->batch, buf, usage, offset)
|
||||
|
||||
size_t relocs;
|
||||
size_t max_relocs;
|
||||
};
|
||||
|
||||
static INLINE boolean
|
||||
i915_batchbuffer_check( struct i915_batchbuffer *batch,
|
||||
size_t dwords,
|
||||
size_t relocs )
|
||||
{
|
||||
return dwords * 4 <= batch->size - (batch->ptr - batch->map) &&
|
||||
relocs <= (batch->max_relocs - batch->relocs);
|
||||
}
|
||||
|
||||
static INLINE size_t
|
||||
i915_batchbuffer_space( struct i915_batchbuffer *batch )
|
||||
{
|
||||
return batch->size - (batch->ptr - batch->map);
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
i915_batchbuffer_dword( struct i915_batchbuffer *batch,
|
||||
unsigned dword )
|
||||
{
|
||||
if (i915_batchbuffer_space(batch) < 4)
|
||||
return;
|
||||
|
||||
*(unsigned *)batch->ptr = dword;
|
||||
batch->ptr += 4;
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
i915_batchbuffer_write( struct i915_batchbuffer *batch,
|
||||
void *data,
|
||||
size_t size )
|
||||
{
|
||||
if (i915_batchbuffer_space(batch) < size)
|
||||
return;
|
||||
|
||||
memcpy(data, batch->ptr, size);
|
||||
batch->ptr += size;
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
i915_batchbuffer_reloc( struct i915_batchbuffer *batch,
|
||||
struct pipe_buffer *buffer,
|
||||
size_t flags,
|
||||
size_t offset )
|
||||
{
|
||||
batch->winsys->batch_reloc( batch->winsys, buffer, flags, offset );
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
i915_batchbuffer_flush( struct i915_batchbuffer *batch,
|
||||
struct pipe_fence_handle **fence )
|
||||
{
|
||||
batch->winsys->batch_flush( batch->winsys, fence );
|
||||
}
|
||||
|
||||
#define BEGIN_BATCH( dwords, relocs ) \
|
||||
(i915_batchbuffer_check( i915->batch, dwords, relocs ))
|
||||
|
||||
#define OUT_BATCH( dword ) \
|
||||
i915_batchbuffer_dword( i915->batch, dword )
|
||||
|
||||
#define OUT_RELOC( buf, flags, delta ) \
|
||||
i915_batchbuffer_reloc( i915->batch, buf, flags, delta )
|
||||
|
||||
#define FLUSH_BATCH(fence) do { \
|
||||
i915->winsys->batch_flush( i915->winsys, fence ); \
|
||||
i915->hardware_dirty = ~0; \
|
||||
#define FLUSH_BATCH(fence) do { \
|
||||
intel_batchbuffer_flush(i915->batch, fence); \
|
||||
i915->hardware_dirty = ~0; \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -26,8 +26,6 @@
|
|||
**************************************************************************/
|
||||
|
||||
|
||||
#include "i915_context.h"
|
||||
#include "i915_winsys.h"
|
||||
#include "i915_blit.h"
|
||||
#include "i915_reg.h"
|
||||
#include "i915_batch.h"
|
||||
|
@ -37,33 +35,33 @@
|
|||
|
||||
void
|
||||
i915_fill_blit(struct i915_context *i915,
|
||||
unsigned cpp,
|
||||
unsigned short dst_pitch,
|
||||
struct pipe_buffer *dst_buffer,
|
||||
unsigned dst_offset,
|
||||
short x, short y,
|
||||
short w, short h,
|
||||
unsigned color)
|
||||
unsigned cpp,
|
||||
unsigned short dst_pitch,
|
||||
struct intel_buffer *dst_buffer,
|
||||
unsigned dst_offset,
|
||||
short x, short y,
|
||||
short w, short h,
|
||||
unsigned color)
|
||||
{
|
||||
unsigned BR13, CMD;
|
||||
|
||||
|
||||
I915_DBG(i915,
|
||||
"%s dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n",
|
||||
__FUNCTION__,
|
||||
dst_buffer, dst_pitch, dst_offset, x, y, w, h);
|
||||
"%s dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n",
|
||||
__FUNCTION__,
|
||||
dst_buffer, dst_pitch, dst_offset, x, y, w, h);
|
||||
|
||||
switch (cpp) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
BR13 = (((int) dst_pitch) & 0xffff) |
|
||||
(0xF0 << 16) | (1 << 24);
|
||||
(0xF0 << 16) | (1 << 24);
|
||||
CMD = XY_COLOR_BLT_CMD;
|
||||
break;
|
||||
case 4:
|
||||
BR13 = (((int) dst_pitch) & 0xffff) |
|
||||
(0xF0 << 16) | (1 << 24) | (1 << 25);
|
||||
(0xF0 << 16) | (1 << 24) | (1 << 25);
|
||||
CMD = (XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA |
|
||||
XY_COLOR_BLT_WRITE_RGB);
|
||||
break;
|
||||
|
@ -79,25 +77,24 @@ i915_fill_blit(struct i915_context *i915,
|
|||
OUT_BATCH(BR13);
|
||||
OUT_BATCH((y << 16) | x);
|
||||
OUT_BATCH(((y + h) << 16) | (x + w));
|
||||
OUT_RELOC( dst_buffer, I915_BUFFER_ACCESS_WRITE, dst_offset);
|
||||
OUT_RELOC(dst_buffer, INTEL_USAGE_2D_TARGET, dst_offset);
|
||||
OUT_BATCH(color);
|
||||
FLUSH_BATCH(NULL);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
i915_copy_blit( struct i915_context *i915,
|
||||
unsigned do_flip,
|
||||
unsigned cpp,
|
||||
unsigned short src_pitch,
|
||||
struct pipe_buffer *src_buffer,
|
||||
unsigned src_offset,
|
||||
unsigned short dst_pitch,
|
||||
struct pipe_buffer *dst_buffer,
|
||||
unsigned dst_offset,
|
||||
short src_x, short src_y,
|
||||
short dst_x, short dst_y,
|
||||
short w, short h )
|
||||
i915_copy_blit(struct i915_context *i915,
|
||||
unsigned do_flip,
|
||||
unsigned cpp,
|
||||
unsigned short src_pitch,
|
||||
struct intel_buffer *src_buffer,
|
||||
unsigned src_offset,
|
||||
unsigned short dst_pitch,
|
||||
struct intel_buffer *dst_buffer,
|
||||
unsigned dst_offset,
|
||||
short src_x, short src_y,
|
||||
short dst_x, short dst_y,
|
||||
short w, short h)
|
||||
{
|
||||
unsigned CMD, BR13;
|
||||
int dst_y2 = dst_y + h;
|
||||
|
@ -105,32 +102,30 @@ i915_copy_blit( struct i915_context *i915,
|
|||
|
||||
|
||||
I915_DBG(i915,
|
||||
"%s src:buf(%p)/%d+%d %d,%d dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n",
|
||||
__FUNCTION__,
|
||||
src_buffer, src_pitch, src_offset, src_x, src_y,
|
||||
dst_buffer, dst_pitch, dst_offset, dst_x, dst_y, w, h);
|
||||
"%s src:buf(%p)/%d+%d %d,%d dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n",
|
||||
__FUNCTION__,
|
||||
src_buffer, src_pitch, src_offset, src_x, src_y,
|
||||
dst_buffer, dst_pitch, dst_offset, dst_x, dst_y, w, h);
|
||||
|
||||
switch (cpp) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
BR13 = (((int) dst_pitch) & 0xffff) |
|
||||
(0xCC << 16) | (1 << 24);
|
||||
(0xCC << 16) | (1 << 24);
|
||||
CMD = XY_SRC_COPY_BLT_CMD;
|
||||
break;
|
||||
case 4:
|
||||
BR13 = (((int) dst_pitch) & 0xffff) |
|
||||
(0xCC << 16) | (1 << 24) | (1 << 25);
|
||||
CMD =
|
||||
(XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
|
||||
XY_SRC_COPY_BLT_WRITE_RGB);
|
||||
(0xCC << 16) | (1 << 24) | (1 << 25);
|
||||
CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
|
||||
XY_SRC_COPY_BLT_WRITE_RGB);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if (dst_y2 < dst_y ||
|
||||
dst_x2 < dst_x) {
|
||||
if (dst_y2 < dst_y || dst_x2 < dst_x) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -140,7 +135,6 @@ i915_copy_blit( struct i915_context *i915,
|
|||
*/
|
||||
assert (dst_pitch > 0 && src_pitch > 0);
|
||||
|
||||
|
||||
if (!BEGIN_BATCH(8, 2)) {
|
||||
FLUSH_BATCH(NULL);
|
||||
assert(BEGIN_BATCH(8, 2));
|
||||
|
@ -149,11 +143,9 @@ i915_copy_blit( struct i915_context *i915,
|
|||
OUT_BATCH(BR13);
|
||||
OUT_BATCH((dst_y << 16) | dst_x);
|
||||
OUT_BATCH((dst_y2 << 16) | dst_x2);
|
||||
OUT_RELOC(dst_buffer, I915_BUFFER_ACCESS_WRITE, dst_offset);
|
||||
OUT_RELOC(dst_buffer, INTEL_USAGE_2D_TARGET, dst_offset);
|
||||
OUT_BATCH((src_y << 16) | src_x);
|
||||
OUT_BATCH(((int) src_pitch & 0xffff));
|
||||
OUT_RELOC(src_buffer, I915_BUFFER_ACCESS_READ, src_offset);
|
||||
OUT_RELOC(src_buffer, INTEL_USAGE_2D_SOURCE, src_offset);
|
||||
FLUSH_BATCH(NULL);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -32,24 +32,24 @@
|
|||
|
||||
extern void i915_copy_blit(struct i915_context *i915,
|
||||
unsigned do_flip,
|
||||
unsigned cpp,
|
||||
unsigned short src_pitch,
|
||||
struct pipe_buffer *src_buffer,
|
||||
unsigned src_offset,
|
||||
unsigned short dst_pitch,
|
||||
struct pipe_buffer *dst_buffer,
|
||||
unsigned dst_offset,
|
||||
short srcx, short srcy,
|
||||
short dstx, short dsty,
|
||||
short w, short h );
|
||||
unsigned cpp,
|
||||
unsigned short src_pitch,
|
||||
struct intel_buffer *src_buffer,
|
||||
unsigned src_offset,
|
||||
unsigned short dst_pitch,
|
||||
struct intel_buffer *dst_buffer,
|
||||
unsigned dst_offset,
|
||||
short srcx, short srcy,
|
||||
short dstx, short dsty,
|
||||
short w, short h);
|
||||
|
||||
extern void i915_fill_blit(struct i915_context *i915,
|
||||
unsigned cpp,
|
||||
unsigned short dst_pitch,
|
||||
struct pipe_buffer *dst_buffer,
|
||||
unsigned dst_offset,
|
||||
short x, short y,
|
||||
short w, short h, unsigned color);
|
||||
unsigned cpp,
|
||||
unsigned short dst_pitch,
|
||||
struct intel_buffer *dst_buffer,
|
||||
unsigned dst_offset,
|
||||
short x, short y,
|
||||
short w, short h, unsigned color);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,136 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright © 2009 Jakob Bornecrantz
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include "util/u_memory.h"
|
||||
#include "i915_screen.h"
|
||||
#include "i915_buffer.h"
|
||||
|
||||
struct intel_buffer;
|
||||
|
||||
struct i915_buffer
|
||||
{
|
||||
struct pipe_buffer base;
|
||||
|
||||
struct intel_buffer *ibuf; /** hw buffer */
|
||||
|
||||
void *data; /**< user and malloc data */
|
||||
boolean own; /**< we own the data incase of malloc */
|
||||
};
|
||||
|
||||
static INLINE struct i915_buffer *
|
||||
i915_buffer(struct pipe_buffer *buffer)
|
||||
{
|
||||
return (struct i915_buffer *)buffer;
|
||||
}
|
||||
|
||||
static struct pipe_buffer *
|
||||
i915_buffer_create(struct pipe_screen *screen,
|
||||
unsigned alignment,
|
||||
unsigned usage,
|
||||
unsigned size)
|
||||
{
|
||||
struct i915_buffer *buf = CALLOC_STRUCT(i915_buffer);
|
||||
|
||||
if (!buf)
|
||||
return NULL;
|
||||
|
||||
pipe_reference_init(&buf->base.reference, 1);
|
||||
buf->base.alignment = alignment;
|
||||
buf->base.screen = screen;
|
||||
buf->base.usage = usage;
|
||||
buf->base.size = size;
|
||||
buf->data = MALLOC(size);
|
||||
buf->own = TRUE;
|
||||
|
||||
if (!buf->data)
|
||||
goto err;
|
||||
|
||||
return &buf->base;
|
||||
|
||||
err:
|
||||
FREE(buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct pipe_buffer *
|
||||
i915_user_buffer_create(struct pipe_screen *screen,
|
||||
void *ptr,
|
||||
unsigned bytes)
|
||||
{
|
||||
struct i915_buffer *buf = CALLOC_STRUCT(i915_buffer);
|
||||
|
||||
if (!buf)
|
||||
return NULL;
|
||||
|
||||
pipe_reference_init(&buf->base.reference, 1);
|
||||
buf->base.alignment = 0;
|
||||
buf->base.screen = screen;
|
||||
buf->base.usage = 0;
|
||||
buf->base.size = bytes;
|
||||
buf->data = ptr;
|
||||
buf->own = FALSE;
|
||||
|
||||
return &buf->base;
|
||||
}
|
||||
|
||||
static void *
|
||||
i915_buffer_map(struct pipe_screen *screen,
|
||||
struct pipe_buffer *buffer,
|
||||
unsigned usage)
|
||||
{
|
||||
struct i915_buffer *buf = i915_buffer(buffer);
|
||||
assert(!buf->ibuf);
|
||||
return buf->data;
|
||||
}
|
||||
|
||||
static void
|
||||
i915_buffer_unmap(struct pipe_screen *screen,
|
||||
struct pipe_buffer *buffer)
|
||||
{
|
||||
struct i915_buffer *buf = i915_buffer(buffer);
|
||||
assert(!buf->ibuf);
|
||||
}
|
||||
|
||||
static void
|
||||
i915_buffer_destroy(struct pipe_buffer *buffer)
|
||||
{
|
||||
struct i915_buffer *buf = i915_buffer(buffer);
|
||||
assert(!buf->ibuf);
|
||||
|
||||
if (buf->own)
|
||||
FREE(buf->data);
|
||||
FREE(buf);
|
||||
}
|
||||
|
||||
void i915_init_screen_buffer_functions(struct i915_screen *screen)
|
||||
{
|
||||
screen->base.buffer_create = i915_buffer_create;
|
||||
screen->base.user_buffer_create = i915_user_buffer_create;
|
||||
screen->base.buffer_map = i915_buffer_map;
|
||||
screen->base.buffer_map_range = NULL;
|
||||
screen->base.buffer_flush_mapped_range = NULL;
|
||||
screen->base.buffer_unmap = i915_buffer_unmap;
|
||||
screen->base.buffer_destroy = i915_buffer_destroy;
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright © 2009 Jakob Bornecrantz
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef I915_BUFFER_H
|
||||
#define I915_BUFFER_H
|
||||
|
||||
void i915_init_screen_buffer_functions(struct i915_screen *screen);
|
||||
|
||||
#endif
|
|
@ -26,8 +26,8 @@
|
|||
**************************************************************************/
|
||||
|
||||
#include "i915_context.h"
|
||||
#include "i915_winsys.h"
|
||||
#include "i915_state.h"
|
||||
#include "i915_screen.h"
|
||||
#include "i915_batch.h"
|
||||
#include "i915_texture.h"
|
||||
#include "i915_reg.h"
|
||||
|
@ -40,66 +40,58 @@
|
|||
#include "pipe/p_screen.h"
|
||||
|
||||
|
||||
static void i915_destroy( struct pipe_context *pipe )
|
||||
{
|
||||
struct i915_context *i915 = i915_context( pipe );
|
||||
|
||||
draw_destroy( i915->draw );
|
||||
|
||||
if(i915->winsys->destroy)
|
||||
i915->winsys->destroy(i915->winsys);
|
||||
|
||||
FREE( i915 );
|
||||
}
|
||||
/*
|
||||
* Draw functions
|
||||
*/
|
||||
|
||||
|
||||
static boolean
|
||||
i915_draw_range_elements(struct pipe_context *pipe,
|
||||
struct pipe_buffer *indexBuffer,
|
||||
unsigned indexSize,
|
||||
unsigned min_index,
|
||||
unsigned max_index,
|
||||
unsigned prim, unsigned start, unsigned count)
|
||||
struct pipe_buffer *indexBuffer,
|
||||
unsigned indexSize,
|
||||
unsigned min_index,
|
||||
unsigned max_index,
|
||||
unsigned prim, unsigned start, unsigned count)
|
||||
{
|
||||
struct i915_context *i915 = i915_context( pipe );
|
||||
struct i915_context *i915 = i915_context(pipe);
|
||||
struct draw_context *draw = i915->draw;
|
||||
unsigned i;
|
||||
|
||||
if (i915->dirty)
|
||||
i915_update_derived( i915 );
|
||||
i915_update_derived(i915);
|
||||
|
||||
/*
|
||||
* Map vertex buffers
|
||||
*/
|
||||
for (i = 0; i < i915->num_vertex_buffers; i++) {
|
||||
void *buf
|
||||
= pipe_buffer_map(pipe->screen,
|
||||
i915->vertex_buffer[i].buffer,
|
||||
PIPE_BUFFER_USAGE_CPU_READ);
|
||||
void *buf = pipe_buffer_map(pipe->screen, i915->vertex_buffer[i].buffer,
|
||||
PIPE_BUFFER_USAGE_CPU_READ);
|
||||
draw_set_mapped_vertex_buffer(draw, i, buf);
|
||||
}
|
||||
/* Map index buffer, if present */
|
||||
|
||||
/*
|
||||
* Map index buffer, if present
|
||||
*/
|
||||
if (indexBuffer) {
|
||||
void *mapped_indexes
|
||||
= pipe_buffer_map(pipe->screen, indexBuffer,
|
||||
PIPE_BUFFER_USAGE_CPU_READ);
|
||||
void *mapped_indexes = pipe_buffer_map(pipe->screen, indexBuffer,
|
||||
PIPE_BUFFER_USAGE_CPU_READ);
|
||||
draw_set_mapped_element_buffer_range(draw, indexSize,
|
||||
min_index,
|
||||
max_index,
|
||||
mapped_indexes);
|
||||
}
|
||||
else {
|
||||
/* no index/element buffer */
|
||||
min_index,
|
||||
max_index,
|
||||
mapped_indexes);
|
||||
} else {
|
||||
draw_set_mapped_element_buffer(draw, 0, NULL);
|
||||
}
|
||||
|
||||
|
||||
draw_set_mapped_constant_buffer(draw,
|
||||
i915->current.constants[PIPE_SHADER_VERTEX],
|
||||
( i915->current.num_user_constants[PIPE_SHADER_VERTEX] *
|
||||
4 * sizeof(float) ));
|
||||
(i915->current.num_user_constants[PIPE_SHADER_VERTEX] *
|
||||
4 * sizeof(float)));
|
||||
|
||||
/* draw! */
|
||||
/*
|
||||
* Do the drawing
|
||||
*/
|
||||
draw_arrays(i915->draw, prim, start, count);
|
||||
|
||||
/*
|
||||
|
@ -109,6 +101,7 @@ i915_draw_range_elements(struct pipe_context *pipe,
|
|||
pipe_buffer_unmap(pipe->screen, i915->vertex_buffer[i].buffer);
|
||||
draw_set_mapped_vertex_buffer(draw, i, NULL);
|
||||
}
|
||||
|
||||
if (indexBuffer) {
|
||||
pipe_buffer_unmap(pipe->screen, indexBuffer);
|
||||
draw_set_mapped_element_buffer_range(draw, 0, start, start + count - 1, NULL);
|
||||
|
@ -118,28 +111,34 @@ i915_draw_range_elements(struct pipe_context *pipe,
|
|||
}
|
||||
|
||||
static boolean
|
||||
i915_draw_elements( struct pipe_context *pipe,
|
||||
struct pipe_buffer *indexBuffer,
|
||||
unsigned indexSize,
|
||||
unsigned prim, unsigned start, unsigned count)
|
||||
i915_draw_elements(struct pipe_context *pipe,
|
||||
struct pipe_buffer *indexBuffer,
|
||||
unsigned indexSize,
|
||||
unsigned prim, unsigned start, unsigned count)
|
||||
{
|
||||
return i915_draw_range_elements( pipe, indexBuffer,
|
||||
indexSize,
|
||||
0, 0xffffffff,
|
||||
prim, start, count );
|
||||
return i915_draw_range_elements(pipe, indexBuffer,
|
||||
indexSize,
|
||||
0, 0xffffffff,
|
||||
prim, start, count);
|
||||
}
|
||||
|
||||
static boolean i915_draw_arrays( struct pipe_context *pipe,
|
||||
unsigned prim, unsigned start, unsigned count)
|
||||
static boolean
|
||||
i915_draw_arrays(struct pipe_context *pipe,
|
||||
unsigned prim, unsigned start, unsigned count)
|
||||
{
|
||||
return i915_draw_elements(pipe, NULL, 0, prim, start, count);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Is referenced functions
|
||||
*/
|
||||
|
||||
|
||||
static unsigned int
|
||||
i915_is_texture_referenced( struct pipe_context *pipe,
|
||||
struct pipe_texture *texture,
|
||||
unsigned face, unsigned level)
|
||||
i915_is_texture_referenced(struct pipe_context *pipe,
|
||||
struct pipe_texture *texture,
|
||||
unsigned face, unsigned level)
|
||||
{
|
||||
/**
|
||||
* FIXME: Return the corrent result. We can't alays return referenced
|
||||
|
@ -153,8 +152,8 @@ i915_is_texture_referenced( struct pipe_context *pipe,
|
|||
}
|
||||
|
||||
static unsigned int
|
||||
i915_is_buffer_referenced( struct pipe_context *pipe,
|
||||
struct pipe_buffer *buf)
|
||||
i915_is_buffer_referenced(struct pipe_context *pipe,
|
||||
struct pipe_buffer *buf)
|
||||
{
|
||||
/**
|
||||
* FIXME: Return the corrent result. We can't alays return referenced
|
||||
|
@ -168,9 +167,25 @@ i915_is_buffer_referenced( struct pipe_context *pipe,
|
|||
}
|
||||
|
||||
|
||||
struct pipe_context *i915_create_context( struct pipe_screen *screen,
|
||||
struct pipe_winsys *pipe_winsys,
|
||||
struct i915_winsys *i915_winsys )
|
||||
/*
|
||||
* Generic context functions
|
||||
*/
|
||||
|
||||
|
||||
static void i915_destroy(struct pipe_context *pipe)
|
||||
{
|
||||
struct i915_context *i915 = i915_context(pipe);
|
||||
|
||||
draw_destroy(i915->draw);
|
||||
|
||||
if(i915->batch)
|
||||
i915->iws->batchbuffer_destroy(i915->batch);
|
||||
|
||||
FREE(i915);
|
||||
}
|
||||
|
||||
struct pipe_context *
|
||||
i915_create_context(struct pipe_screen *screen)
|
||||
{
|
||||
struct i915_context *i915;
|
||||
|
||||
|
@ -178,21 +193,20 @@ struct pipe_context *i915_create_context( struct pipe_screen *screen,
|
|||
if (i915 == NULL)
|
||||
return NULL;
|
||||
|
||||
i915->winsys = i915_winsys;
|
||||
i915->pipe.winsys = pipe_winsys;
|
||||
i915->pipe.screen = screen;
|
||||
i915->iws = i915_screen(screen)->iws;
|
||||
i915->base.winsys = NULL;
|
||||
i915->base.screen = screen;
|
||||
|
||||
i915->pipe.destroy = i915_destroy;
|
||||
i915->base.destroy = i915_destroy;
|
||||
|
||||
i915->pipe.clear = i915_clear;
|
||||
i915->base.clear = i915_clear;
|
||||
|
||||
i915->base.draw_arrays = i915_draw_arrays;
|
||||
i915->base.draw_elements = i915_draw_elements;
|
||||
i915->base.draw_range_elements = i915_draw_range_elements;
|
||||
|
||||
i915->pipe.draw_arrays = i915_draw_arrays;
|
||||
i915->pipe.draw_elements = i915_draw_elements;
|
||||
i915->pipe.draw_range_elements = i915_draw_range_elements;
|
||||
|
||||
i915->pipe.is_texture_referenced = i915_is_texture_referenced;
|
||||
i915->pipe.is_buffer_referenced = i915_is_buffer_referenced;
|
||||
i915->base.is_texture_referenced = i915_is_texture_referenced;
|
||||
i915->base.is_buffer_referenced = i915_is_buffer_referenced;
|
||||
|
||||
/*
|
||||
* Create drawing context and plug our rendering stage into it.
|
||||
|
@ -201,27 +215,23 @@ struct pipe_context *i915_create_context( struct pipe_screen *screen,
|
|||
assert(i915->draw);
|
||||
if (!debug_get_bool_option("I915_NO_VBUF", FALSE)) {
|
||||
draw_set_rasterize_stage(i915->draw, i915_draw_vbuf_stage(i915));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
draw_set_rasterize_stage(i915->draw, i915_draw_render_stage(i915));
|
||||
}
|
||||
|
||||
i915_init_surface_functions(i915);
|
||||
i915_init_state_functions(i915);
|
||||
i915_init_flush_functions(i915);
|
||||
i915_init_texture_functions(i915);
|
||||
|
||||
draw_install_aaline_stage(i915->draw, &i915->pipe);
|
||||
draw_install_aapoint_stage(i915->draw, &i915->pipe);
|
||||
draw_install_aaline_stage(i915->draw, &i915->base);
|
||||
draw_install_aapoint_stage(i915->draw, &i915->base);
|
||||
|
||||
i915->dirty = ~0;
|
||||
i915->hardware_dirty = ~0;
|
||||
|
||||
/* Batch stream debugging is a bit hacked up at the moment:
|
||||
*/
|
||||
i915->batch = i915_winsys->batch_get(i915_winsys);
|
||||
i915->batch->winsys = i915_winsys;
|
||||
i915->batch = i915->iws->batchbuffer_create(i915->iws);
|
||||
|
||||
return &i915->pipe;
|
||||
return &i915->base;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,11 @@
|
|||
#include "tgsi/tgsi_scan.h"
|
||||
|
||||
|
||||
struct intel_winsys;
|
||||
struct intel_buffer;
|
||||
struct intel_batchbuffer;
|
||||
|
||||
|
||||
#define I915_TEX_UNITS 8
|
||||
|
||||
#define I915_DYNAMIC_MODES4 0
|
||||
|
@ -182,7 +187,6 @@ struct i915_sampler_state {
|
|||
unsigned maxlod;
|
||||
};
|
||||
|
||||
|
||||
struct i915_texture {
|
||||
struct pipe_texture base;
|
||||
|
||||
|
@ -192,7 +196,8 @@ struct i915_texture {
|
|||
unsigned depth_stride; /* per-image on i945? */
|
||||
unsigned total_nblocksy;
|
||||
|
||||
unsigned tiled;
|
||||
unsigned sw_tiled; /**< tiled with software flags */
|
||||
unsigned hw_tiled; /**< tiled with hardware fences */
|
||||
|
||||
unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS];
|
||||
|
||||
|
@ -206,15 +211,15 @@ struct i915_texture {
|
|||
|
||||
/* The data is held here:
|
||||
*/
|
||||
struct pipe_buffer *buffer;
|
||||
struct intel_buffer *buffer;
|
||||
};
|
||||
|
||||
struct i915_batchbuffer;
|
||||
|
||||
struct i915_context
|
||||
{
|
||||
struct pipe_context pipe;
|
||||
struct i915_winsys *winsys;
|
||||
struct pipe_context base;
|
||||
|
||||
struct intel_winsys *iws;
|
||||
|
||||
struct draw_context *draw;
|
||||
|
||||
/* The most recent drawing state as set by the driver:
|
||||
|
@ -243,10 +248,10 @@ struct i915_context
|
|||
unsigned num_vertex_elements;
|
||||
unsigned num_vertex_buffers;
|
||||
|
||||
struct i915_batchbuffer *batch;
|
||||
struct intel_batchbuffer *batch;
|
||||
|
||||
/** Vertex buffer */
|
||||
struct pipe_buffer *vbo;
|
||||
struct intel_buffer *vbo;
|
||||
size_t vbo_offset;
|
||||
unsigned vbo_flushed;
|
||||
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
|
||||
#include "i915_reg.h"
|
||||
#include "i915_context.h"
|
||||
#include "i915_winsys.h"
|
||||
#include "i915_debug.h"
|
||||
#include "i915_batch.h"
|
||||
#include "pipe/internal/p_winsys_screen.h"
|
||||
|
@ -864,7 +863,7 @@ static boolean i915_debug_packet( struct debug_stream *stream )
|
|||
|
||||
|
||||
void
|
||||
i915_dump_batchbuffer( struct i915_batchbuffer *batch )
|
||||
i915_dump_batchbuffer( struct intel_batchbuffer *batch )
|
||||
{
|
||||
struct debug_stream stream;
|
||||
unsigned *start = (unsigned*)batch->map;
|
||||
|
|
|
@ -104,9 +104,9 @@ I915_DBG(
|
|||
#endif
|
||||
|
||||
|
||||
struct i915_batchbuffer;
|
||||
struct intel_batchbuffer;
|
||||
|
||||
void i915_dump_batchbuffer( struct i915_batchbuffer *i915 );
|
||||
void i915_dump_batchbuffer( struct intel_batchbuffer *i915 );
|
||||
|
||||
void i915_debug_init( struct i915_context *i915 );
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@ static void i915_flush( struct pipe_context *pipe,
|
|||
|
||||
draw_flush(i915->draw);
|
||||
|
||||
#if 0
|
||||
/* Do we need to emit an MI_FLUSH command to flush the hardware
|
||||
* caches?
|
||||
*/
|
||||
|
@ -63,6 +64,13 @@ static void i915_flush( struct pipe_context *pipe,
|
|||
}
|
||||
OUT_BATCH( flush );
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
if (i915->batch->map == i915->batch->ptr) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If there are no flags, just flush pending commands to hardware:
|
||||
*/
|
||||
|
@ -74,5 +82,5 @@ static void i915_flush( struct pipe_context *pipe,
|
|||
|
||||
void i915_init_flush_functions( struct i915_context *i915 )
|
||||
{
|
||||
i915->pipe.flush = i915_flush;
|
||||
i915->base.flush = i915_flush;
|
||||
}
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
#include "util/u_pack_color.h"
|
||||
|
||||
#include "i915_context.h"
|
||||
#include "i915_winsys.h"
|
||||
#include "i915_reg.h"
|
||||
#include "i915_state.h"
|
||||
#include "i915_batch.h"
|
||||
|
|
|
@ -42,13 +42,11 @@
|
|||
#include "draw/draw_vbuf.h"
|
||||
#include "util/u_debug.h"
|
||||
#include "pipe/p_inlines.h"
|
||||
#include "pipe/internal/p_winsys_screen.h"
|
||||
#include "util/u_math.h"
|
||||
#include "util/u_memory.h"
|
||||
|
||||
#include "i915_context.h"
|
||||
#include "i915_reg.h"
|
||||
#include "i915_winsys.h"
|
||||
#include "i915_batch.h"
|
||||
#include "i915_state.h"
|
||||
|
||||
|
@ -59,7 +57,7 @@
|
|||
struct i915_vbuf_render {
|
||||
struct vbuf_render base;
|
||||
|
||||
struct i915_context *i915;
|
||||
struct i915_context *i915;
|
||||
|
||||
/** Vertex size in bytes */
|
||||
size_t vertex_size;
|
||||
|
@ -74,7 +72,7 @@ struct i915_vbuf_render {
|
|||
unsigned fallback;
|
||||
|
||||
/* Stuff for the vbo */
|
||||
struct pipe_buffer *vbo;
|
||||
struct intel_buffer *vbo;
|
||||
size_t vbo_size;
|
||||
size_t vbo_offset;
|
||||
void *vbo_ptr;
|
||||
|
@ -87,36 +85,34 @@ struct i915_vbuf_render {
|
|||
* Basically a cast wrapper.
|
||||
*/
|
||||
static INLINE struct i915_vbuf_render *
|
||||
i915_vbuf_render( struct vbuf_render *render )
|
||||
i915_vbuf_render(struct vbuf_render *render)
|
||||
{
|
||||
assert(render);
|
||||
return (struct i915_vbuf_render *)render;
|
||||
}
|
||||
|
||||
|
||||
static const struct vertex_info *
|
||||
i915_vbuf_render_get_vertex_info( struct vbuf_render *render )
|
||||
i915_vbuf_render_get_vertex_info(struct vbuf_render *render)
|
||||
{
|
||||
struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
|
||||
struct i915_context *i915 = i915_render->i915;
|
||||
|
||||
if (i915->dirty) {
|
||||
/* make sure we have up to date vertex layout */
|
||||
i915_update_derived( i915 );
|
||||
i915_update_derived(i915);
|
||||
}
|
||||
|
||||
return &i915->current.vertex_info;
|
||||
}
|
||||
|
||||
|
||||
static boolean
|
||||
i915_vbuf_render_allocate_vertices( struct vbuf_render *render,
|
||||
ushort vertex_size,
|
||||
ushort nr_vertices )
|
||||
i915_vbuf_render_allocate_vertices(struct vbuf_render *render,
|
||||
ushort vertex_size,
|
||||
ushort nr_vertices)
|
||||
{
|
||||
struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
|
||||
struct i915_context *i915 = i915_render->i915;
|
||||
struct pipe_screen *screen = i915->pipe.screen;
|
||||
struct intel_winsys *iws = i915->iws;
|
||||
size_t size = (size_t)vertex_size * (size_t)nr_vertices;
|
||||
|
||||
/* FIXME: handle failure */
|
||||
|
@ -125,17 +121,17 @@ i915_vbuf_render_allocate_vertices( struct vbuf_render *render,
|
|||
if (i915_render->vbo_size > size + i915_render->vbo_offset && !i915->vbo_flushed) {
|
||||
} else {
|
||||
i915->vbo_flushed = 0;
|
||||
if (i915_render->vbo)
|
||||
pipe_buffer_reference(&i915_render->vbo, NULL);
|
||||
if (i915_render->vbo) {
|
||||
iws->buffer_destroy(iws, i915_render->vbo);
|
||||
i915_render->vbo = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!i915_render->vbo) {
|
||||
i915_render->vbo_size = MAX2(size, i915_render->vbo_alloc_size);
|
||||
i915_render->vbo_offset = 0;
|
||||
i915_render->vbo = pipe_buffer_create(screen,
|
||||
64,
|
||||
I915_BUFFER_USAGE_LIT_VERTEX,
|
||||
i915_render->vbo_size);
|
||||
i915_render->vbo = iws->buffer_create(iws, i915_render->vbo_size, 64,
|
||||
INTEL_NEW_VERTEX);
|
||||
|
||||
}
|
||||
|
||||
|
@ -149,40 +145,37 @@ i915_vbuf_render_allocate_vertices( struct vbuf_render *render,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
i915_vbuf_render_map_vertices( struct vbuf_render *render )
|
||||
i915_vbuf_render_map_vertices(struct vbuf_render *render)
|
||||
{
|
||||
struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
|
||||
struct i915_context *i915 = i915_render->i915;
|
||||
struct pipe_screen *screen = i915->pipe.screen;
|
||||
struct intel_winsys *iws = i915->iws;
|
||||
|
||||
if (i915->vbo_flushed)
|
||||
debug_printf("%s bad vbo flush occured stalling on hw\n");
|
||||
|
||||
i915_render->vbo_ptr = pipe_buffer_map(screen,
|
||||
i915_render->vbo,
|
||||
PIPE_BUFFER_USAGE_CPU_WRITE);
|
||||
i915_render->vbo_ptr = iws->buffer_map(iws, i915_render->vbo, TRUE);
|
||||
|
||||
return (unsigned char *)i915_render->vbo_ptr + i915->vbo_offset;
|
||||
}
|
||||
|
||||
static void
|
||||
i915_vbuf_render_unmap_vertices( struct vbuf_render *render,
|
||||
ushort min_index,
|
||||
ushort max_index )
|
||||
i915_vbuf_render_unmap_vertices(struct vbuf_render *render,
|
||||
ushort min_index,
|
||||
ushort max_index)
|
||||
{
|
||||
struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
|
||||
struct i915_context *i915 = i915_render->i915;
|
||||
struct pipe_screen *screen = i915->pipe.screen;
|
||||
struct intel_winsys *iws = i915->iws;
|
||||
|
||||
i915_render->vbo_max_used = MAX2(i915_render->vbo_max_used, i915_render->vertex_size * (max_index + 1));
|
||||
pipe_buffer_unmap(screen, i915_render->vbo);
|
||||
iws->buffer_unmap(iws, i915_render->vbo);
|
||||
}
|
||||
|
||||
static boolean
|
||||
i915_vbuf_render_set_primitive( struct vbuf_render *render,
|
||||
unsigned prim )
|
||||
i915_vbuf_render_set_primitive(struct vbuf_render *render,
|
||||
unsigned prim)
|
||||
{
|
||||
struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
|
||||
i915_render->prim = prim;
|
||||
|
@ -234,15 +227,13 @@ i915_vbuf_render_set_primitive( struct vbuf_render *render,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Used for fallbacks in draw_arrays
|
||||
*/
|
||||
static void
|
||||
draw_arrays_generate_indices( struct vbuf_render *render,
|
||||
unsigned start, uint nr,
|
||||
unsigned type )
|
||||
draw_arrays_generate_indices(struct vbuf_render *render,
|
||||
unsigned start, uint nr,
|
||||
unsigned type)
|
||||
{
|
||||
struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
|
||||
struct i915_context *i915 = i915_render->i915;
|
||||
|
@ -251,29 +242,29 @@ draw_arrays_generate_indices( struct vbuf_render *render,
|
|||
switch(type) {
|
||||
case 0:
|
||||
for (i = start; i+1 < end; i += 2)
|
||||
OUT_BATCH( (i+0) | (i+1) << 16 );
|
||||
OUT_BATCH((i+0) | (i+1) << 16);
|
||||
if (i < end)
|
||||
OUT_BATCH( i );
|
||||
OUT_BATCH(i);
|
||||
break;
|
||||
case PIPE_PRIM_LINE_LOOP:
|
||||
if (nr >= 2) {
|
||||
for (i = start + 1; i < end; i++)
|
||||
OUT_BATCH( (i-0) | (i+0) << 16 );
|
||||
OUT_BATCH( (i-0) | ( start) << 16 );
|
||||
for (i = start + 1; i < end; i++)
|
||||
OUT_BATCH((i-0) | (i+0) << 16);
|
||||
OUT_BATCH((i-0) | ( start) << 16);
|
||||
}
|
||||
break;
|
||||
case PIPE_PRIM_QUADS:
|
||||
for (i = start; i + 3 < end; i += 4) {
|
||||
OUT_BATCH( (i+0) | (i+1) << 16 );
|
||||
OUT_BATCH( (i+3) | (i+1) << 16 );
|
||||
OUT_BATCH( (i+2) | (i+3) << 16 );
|
||||
OUT_BATCH((i+0) | (i+1) << 16);
|
||||
OUT_BATCH((i+3) | (i+1) << 16);
|
||||
OUT_BATCH((i+2) | (i+3) << 16);
|
||||
}
|
||||
break;
|
||||
case PIPE_PRIM_QUAD_STRIP:
|
||||
for (i = start; i + 3 < end; i += 2) {
|
||||
OUT_BATCH( (i+0) | (i+1) << 16 );
|
||||
OUT_BATCH( (i+3) | (i+2) << 16 );
|
||||
OUT_BATCH( (i+0) | (i+3) << 16 );
|
||||
OUT_BATCH((i+0) | (i+1) << 16);
|
||||
OUT_BATCH((i+3) | (i+2) << 16);
|
||||
OUT_BATCH((i+0) | (i+3) << 16);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -282,16 +273,16 @@ draw_arrays_generate_indices( struct vbuf_render *render,
|
|||
}
|
||||
|
||||
static unsigned
|
||||
draw_arrays_calc_nr_indices( uint nr, unsigned type )
|
||||
draw_arrays_calc_nr_indices(uint nr, unsigned type)
|
||||
{
|
||||
switch (type) {
|
||||
case 0:
|
||||
return nr;
|
||||
case PIPE_PRIM_LINE_LOOP:
|
||||
if (nr >= 2)
|
||||
return nr * 2;
|
||||
return nr * 2;
|
||||
else
|
||||
return 0;
|
||||
return 0;
|
||||
case PIPE_PRIM_QUADS:
|
||||
return (nr / 4) * 6;
|
||||
case PIPE_PRIM_QUAD_STRIP:
|
||||
|
@ -303,64 +294,64 @@ draw_arrays_calc_nr_indices( uint nr, unsigned type )
|
|||
}
|
||||
|
||||
static void
|
||||
draw_arrays_fallback( struct vbuf_render *render,
|
||||
unsigned start,
|
||||
uint nr )
|
||||
draw_arrays_fallback(struct vbuf_render *render,
|
||||
unsigned start,
|
||||
uint nr)
|
||||
{
|
||||
struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
|
||||
struct i915_context *i915 = i915_render->i915;
|
||||
unsigned nr_indices;
|
||||
|
||||
if (i915->dirty)
|
||||
i915_update_derived( i915 );
|
||||
i915_update_derived(i915);
|
||||
|
||||
if (i915->hardware_dirty)
|
||||
i915_emit_hardware_state( i915 );
|
||||
i915_emit_hardware_state(i915);
|
||||
|
||||
nr_indices = draw_arrays_calc_nr_indices( nr, i915_render->fallback );
|
||||
nr_indices = draw_arrays_calc_nr_indices(nr, i915_render->fallback);
|
||||
if (!nr_indices)
|
||||
return;
|
||||
|
||||
if (!BEGIN_BATCH( 1 + (nr_indices + 1)/2, 1 )) {
|
||||
if (!BEGIN_BATCH(1 + (nr_indices + 1)/2, 1)) {
|
||||
FLUSH_BATCH(NULL);
|
||||
|
||||
/* Make sure state is re-emitted after a flush:
|
||||
*/
|
||||
i915_update_derived( i915 );
|
||||
i915_emit_hardware_state( i915 );
|
||||
i915_update_derived(i915);
|
||||
i915_emit_hardware_state(i915);
|
||||
i915->vbo_flushed = 1;
|
||||
|
||||
if (!BEGIN_BATCH( 1 + (nr_indices + 1)/2, 1 )) {
|
||||
assert(0);
|
||||
goto out;
|
||||
if (!BEGIN_BATCH(1 + (nr_indices + 1)/2, 1)) {
|
||||
assert(0);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
OUT_BATCH( _3DPRIMITIVE |
|
||||
PRIM_INDIRECT |
|
||||
i915_render->hwprim |
|
||||
PRIM_INDIRECT_ELTS |
|
||||
nr_indices );
|
||||
OUT_BATCH(_3DPRIMITIVE |
|
||||
PRIM_INDIRECT |
|
||||
i915_render->hwprim |
|
||||
PRIM_INDIRECT_ELTS |
|
||||
nr_indices);
|
||||
|
||||
draw_arrays_generate_indices( render, start, nr, i915_render->fallback );
|
||||
draw_arrays_generate_indices(render, start, nr, i915_render->fallback);
|
||||
|
||||
out:
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
i915_vbuf_render_draw_arrays( struct vbuf_render *render,
|
||||
unsigned start,
|
||||
uint nr )
|
||||
i915_vbuf_render_draw_arrays(struct vbuf_render *render,
|
||||
unsigned start,
|
||||
uint nr)
|
||||
{
|
||||
struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
|
||||
|
||||
if (i915_render->fallback) {
|
||||
draw_arrays_fallback( render, start, nr );
|
||||
draw_arrays_fallback(render, start, nr);
|
||||
return;
|
||||
}
|
||||
|
||||
/* JB: TODO submit direct cmds */
|
||||
draw_arrays_fallback( render, start, nr );
|
||||
draw_arrays_fallback(render, start, nr);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -368,10 +359,10 @@ i915_vbuf_render_draw_arrays( struct vbuf_render *render,
|
|||
* If type is zero normal operation assumed.
|
||||
*/
|
||||
static void
|
||||
draw_generate_indices( struct vbuf_render *render,
|
||||
const ushort *indices,
|
||||
uint nr_indices,
|
||||
unsigned type )
|
||||
draw_generate_indices(struct vbuf_render *render,
|
||||
const ushort *indices,
|
||||
uint nr_indices,
|
||||
unsigned type)
|
||||
{
|
||||
struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
|
||||
struct i915_context *i915 = i915_render->i915;
|
||||
|
@ -380,31 +371,31 @@ draw_generate_indices( struct vbuf_render *render,
|
|||
switch(type) {
|
||||
case 0:
|
||||
for (i = 0; i + 1 < nr_indices; i += 2) {
|
||||
OUT_BATCH( indices[i] | indices[i+1] << 16 );
|
||||
OUT_BATCH(indices[i] | indices[i+1] << 16);
|
||||
}
|
||||
if (i < nr_indices) {
|
||||
OUT_BATCH( indices[i] );
|
||||
OUT_BATCH(indices[i]);
|
||||
}
|
||||
break;
|
||||
case PIPE_PRIM_LINE_LOOP:
|
||||
if (nr_indices >= 2) {
|
||||
for (i = 1; i < nr_indices; i++)
|
||||
OUT_BATCH( indices[i-1] | indices[i] << 16 );
|
||||
OUT_BATCH( indices[i-1] | indices[0] << 16 );
|
||||
for (i = 1; i < nr_indices; i++)
|
||||
OUT_BATCH(indices[i-1] | indices[i] << 16);
|
||||
OUT_BATCH(indices[i-1] | indices[0] << 16);
|
||||
}
|
||||
break;
|
||||
case PIPE_PRIM_QUADS:
|
||||
for (i = 0; i + 3 < nr_indices; i += 4) {
|
||||
OUT_BATCH( indices[i+0] | indices[i+1] << 16 );
|
||||
OUT_BATCH( indices[i+3] | indices[i+1] << 16 );
|
||||
OUT_BATCH( indices[i+2] | indices[i+3] << 16 );
|
||||
OUT_BATCH(indices[i+0] | indices[i+1] << 16);
|
||||
OUT_BATCH(indices[i+3] | indices[i+1] << 16);
|
||||
OUT_BATCH(indices[i+2] | indices[i+3] << 16);
|
||||
}
|
||||
break;
|
||||
case PIPE_PRIM_QUAD_STRIP:
|
||||
for (i = 0; i + 3 < nr_indices; i += 2) {
|
||||
OUT_BATCH( indices[i+0] | indices[i+1] << 16 );
|
||||
OUT_BATCH( indices[i+3] | indices[i+2] << 16 );
|
||||
OUT_BATCH( indices[i+0] | indices[i+3] << 16 );
|
||||
OUT_BATCH(indices[i+0] | indices[i+1] << 16);
|
||||
OUT_BATCH(indices[i+3] | indices[i+2] << 16);
|
||||
OUT_BATCH(indices[i+0] | indices[i+3] << 16);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -414,16 +405,16 @@ draw_generate_indices( struct vbuf_render *render,
|
|||
}
|
||||
|
||||
static unsigned
|
||||
draw_calc_nr_indices( uint nr_indices, unsigned type )
|
||||
draw_calc_nr_indices(uint nr_indices, unsigned type)
|
||||
{
|
||||
switch (type) {
|
||||
case 0:
|
||||
return nr_indices;
|
||||
case PIPE_PRIM_LINE_LOOP:
|
||||
if (nr_indices >= 2)
|
||||
return nr_indices * 2;
|
||||
return nr_indices * 2;
|
||||
else
|
||||
return 0;
|
||||
return 0;
|
||||
case PIPE_PRIM_QUADS:
|
||||
return (nr_indices / 4) * 6;
|
||||
case PIPE_PRIM_QUAD_STRIP:
|
||||
|
@ -435,9 +426,9 @@ draw_calc_nr_indices( uint nr_indices, unsigned type )
|
|||
}
|
||||
|
||||
static void
|
||||
i915_vbuf_render_draw( struct vbuf_render *render,
|
||||
const ushort *indices,
|
||||
uint nr_indices)
|
||||
i915_vbuf_render_draw(struct vbuf_render *render,
|
||||
const ushort *indices,
|
||||
uint nr_indices)
|
||||
{
|
||||
struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
|
||||
struct i915_context *i915 = i915_render->i915;
|
||||
|
@ -445,48 +436,47 @@ i915_vbuf_render_draw( struct vbuf_render *render,
|
|||
|
||||
save_nr_indices = nr_indices;
|
||||
|
||||
nr_indices = draw_calc_nr_indices( nr_indices, i915_render->fallback );
|
||||
nr_indices = draw_calc_nr_indices(nr_indices, i915_render->fallback);
|
||||
if (!nr_indices)
|
||||
return;
|
||||
|
||||
if (i915->dirty)
|
||||
i915_update_derived( i915 );
|
||||
i915_update_derived(i915);
|
||||
|
||||
if (i915->hardware_dirty)
|
||||
i915_emit_hardware_state( i915 );
|
||||
i915_emit_hardware_state(i915);
|
||||
|
||||
if (!BEGIN_BATCH( 1 + (nr_indices + 1)/2, 1 )) {
|
||||
if (!BEGIN_BATCH(1 + (nr_indices + 1)/2, 1)) {
|
||||
FLUSH_BATCH(NULL);
|
||||
|
||||
/* Make sure state is re-emitted after a flush:
|
||||
*/
|
||||
i915_update_derived( i915 );
|
||||
i915_emit_hardware_state( i915 );
|
||||
i915_update_derived(i915);
|
||||
i915_emit_hardware_state(i915);
|
||||
i915->vbo_flushed = 1;
|
||||
|
||||
if (!BEGIN_BATCH( 1 + (nr_indices + 1)/2, 1 )) {
|
||||
assert(0);
|
||||
goto out;
|
||||
if (!BEGIN_BATCH(1 + (nr_indices + 1)/2, 1)) {
|
||||
assert(0);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
OUT_BATCH( _3DPRIMITIVE |
|
||||
PRIM_INDIRECT |
|
||||
i915_render->hwprim |
|
||||
PRIM_INDIRECT_ELTS |
|
||||
nr_indices );
|
||||
draw_generate_indices( render,
|
||||
indices,
|
||||
save_nr_indices,
|
||||
i915_render->fallback );
|
||||
OUT_BATCH(_3DPRIMITIVE |
|
||||
PRIM_INDIRECT |
|
||||
i915_render->hwprim |
|
||||
PRIM_INDIRECT_ELTS |
|
||||
nr_indices);
|
||||
draw_generate_indices(render,
|
||||
indices,
|
||||
save_nr_indices,
|
||||
i915_render->fallback);
|
||||
|
||||
out:
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
i915_vbuf_render_release_vertices( struct vbuf_render *render )
|
||||
i915_vbuf_render_release_vertices(struct vbuf_render *render)
|
||||
{
|
||||
struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
|
||||
struct i915_context *i915 = i915_render->i915;
|
||||
|
@ -499,23 +489,21 @@ i915_vbuf_render_release_vertices( struct vbuf_render *render )
|
|||
i915->dirty |= I915_NEW_VBO;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
i915_vbuf_render_destroy( struct vbuf_render *render )
|
||||
i915_vbuf_render_destroy(struct vbuf_render *render)
|
||||
{
|
||||
struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
|
||||
FREE(i915_render);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a new primitive render.
|
||||
*/
|
||||
static struct vbuf_render *
|
||||
i915_vbuf_render_create( struct i915_context *i915 )
|
||||
i915_vbuf_render_create(struct i915_context *i915)
|
||||
{
|
||||
struct i915_vbuf_render *i915_render = CALLOC_STRUCT(i915_vbuf_render);
|
||||
struct pipe_screen *screen = i915->pipe.screen;
|
||||
struct intel_winsys *iws = i915->iws;
|
||||
|
||||
i915_render->i915 = i915;
|
||||
|
||||
|
@ -539,23 +527,19 @@ i915_vbuf_render_create( struct i915_context *i915 )
|
|||
i915_render->vbo_alloc_size = 128 * 4096;
|
||||
i915_render->vbo_size = i915_render->vbo_alloc_size;
|
||||
i915_render->vbo_offset = 0;
|
||||
i915_render->vbo = pipe_buffer_create(screen,
|
||||
64,
|
||||
I915_BUFFER_USAGE_LIT_VERTEX,
|
||||
i915_render->vbo_size);
|
||||
i915_render->vbo_ptr = pipe_buffer_map(screen,
|
||||
i915_render->vbo,
|
||||
PIPE_BUFFER_USAGE_CPU_WRITE);
|
||||
pipe_buffer_unmap(screen, i915_render->vbo);
|
||||
i915_render->vbo = iws->buffer_create(iws, i915_render->vbo_size, 64,
|
||||
INTEL_NEW_VERTEX);
|
||||
/* TODO JB: is this realy needed? */
|
||||
i915_render->vbo_ptr = iws->buffer_map(iws, i915_render->vbo, TRUE);
|
||||
iws->buffer_unmap(iws, i915_render->vbo);
|
||||
|
||||
return &i915_render->base;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a new primitive vbuf/render stage.
|
||||
*/
|
||||
struct draw_stage *i915_draw_vbuf_stage( struct i915_context *i915 )
|
||||
struct draw_stage *i915_draw_vbuf_stage(struct i915_context *i915)
|
||||
{
|
||||
struct vbuf_render *render;
|
||||
struct draw_stage *stage;
|
||||
|
@ -564,7 +548,7 @@ struct draw_stage *i915_draw_vbuf_stage( struct i915_context *i915 )
|
|||
if(!render)
|
||||
return NULL;
|
||||
|
||||
stage = draw_vbuf_stage( i915->draw, render );
|
||||
stage = draw_vbuf_stage(i915->draw, render);
|
||||
if(!stage) {
|
||||
render->destroy(render);
|
||||
return NULL;
|
||||
|
|
|
@ -26,33 +26,36 @@
|
|||
**************************************************************************/
|
||||
|
||||
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_simple_screen.h"
|
||||
#include "pipe/internal/p_winsys_screen.h"
|
||||
#include "pipe/p_inlines.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_string.h"
|
||||
|
||||
#include "i915_reg.h"
|
||||
#include "i915_context.h"
|
||||
#include "i915_screen.h"
|
||||
#include "i915_buffer.h"
|
||||
#include "i915_texture.h"
|
||||
#include "i915_winsys.h"
|
||||
#include "intel_winsys.h"
|
||||
|
||||
|
||||
/*
|
||||
* Probe functions
|
||||
*/
|
||||
|
||||
|
||||
static const char *
|
||||
i915_get_vendor( struct pipe_screen *pscreen )
|
||||
i915_get_vendor(struct pipe_screen *screen)
|
||||
{
|
||||
return "Tungsten Graphics, Inc.";
|
||||
}
|
||||
|
||||
|
||||
static const char *
|
||||
i915_get_name( struct pipe_screen *pscreen )
|
||||
i915_get_name(struct pipe_screen *screen)
|
||||
{
|
||||
static char buffer[128];
|
||||
const char *chipset;
|
||||
|
||||
switch (i915_screen(pscreen)->pci_id) {
|
||||
switch (i915_screen(screen)->pci_id) {
|
||||
case PCI_CHIP_I915_G:
|
||||
chipset = "915G";
|
||||
break;
|
||||
|
@ -86,7 +89,6 @@ i915_get_name( struct pipe_screen *pscreen )
|
|||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
i915_get_param(struct pipe_screen *screen, int param)
|
||||
{
|
||||
|
@ -122,7 +124,6 @@ i915_get_param(struct pipe_screen *screen, int param)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static float
|
||||
i915_get_paramf(struct pipe_screen *screen, int param)
|
||||
{
|
||||
|
@ -148,13 +149,12 @@ i915_get_paramf(struct pipe_screen *screen, int param)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static boolean
|
||||
i915_is_format_supported( struct pipe_screen *screen,
|
||||
enum pipe_format format,
|
||||
enum pipe_texture_target target,
|
||||
unsigned tex_usage,
|
||||
unsigned geom_flags )
|
||||
i915_is_format_supported(struct pipe_screen *screen,
|
||||
enum pipe_format format,
|
||||
enum pipe_texture_target target,
|
||||
unsigned tex_usage,
|
||||
unsigned geom_flags)
|
||||
{
|
||||
static const enum pipe_format tex_supported[] = {
|
||||
PIPE_FORMAT_R8G8B8A8_UNORM,
|
||||
|
@ -173,7 +173,6 @@ i915_is_format_supported( struct pipe_screen *screen,
|
|||
PIPE_FORMAT_A8R8G8B8_UNORM,
|
||||
PIPE_FORMAT_R5G6B5_UNORM,
|
||||
PIPE_FORMAT_S8Z24_UNORM,
|
||||
/*PIPE_FORMAT_R16G16B16A16_SNORM,*/
|
||||
PIPE_FORMAT_NONE /* list terminator */
|
||||
};
|
||||
const enum pipe_format *list;
|
||||
|
@ -193,122 +192,73 @@ i915_is_format_supported( struct pipe_screen *screen,
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
i915_destroy_screen( struct pipe_screen *screen )
|
||||
{
|
||||
struct pipe_winsys *winsys = screen->winsys;
|
||||
/*
|
||||
* Fence functions
|
||||
*/
|
||||
|
||||
if(winsys->destroy)
|
||||
winsys->destroy(winsys);
|
||||
|
||||
FREE(screen);
|
||||
}
|
||||
|
||||
|
||||
static struct pipe_transfer*
|
||||
i915_get_tex_transfer(struct pipe_screen *screen,
|
||||
struct pipe_texture *texture,
|
||||
unsigned face, unsigned level, unsigned zslice,
|
||||
enum pipe_transfer_usage usage, unsigned x, unsigned y,
|
||||
unsigned w, unsigned h)
|
||||
{
|
||||
struct i915_texture *tex = (struct i915_texture *)texture;
|
||||
struct i915_transfer *trans;
|
||||
unsigned offset; /* in bytes */
|
||||
|
||||
if (texture->target == PIPE_TEXTURE_CUBE) {
|
||||
offset = tex->image_offset[level][face];
|
||||
}
|
||||
else if (texture->target == PIPE_TEXTURE_3D) {
|
||||
offset = tex->image_offset[level][zslice];
|
||||
}
|
||||
else {
|
||||
offset = tex->image_offset[level][0];
|
||||
assert(face == 0);
|
||||
assert(zslice == 0);
|
||||
}
|
||||
|
||||
trans = CALLOC_STRUCT(i915_transfer);
|
||||
if (trans) {
|
||||
pipe_texture_reference(&trans->base.texture, texture);
|
||||
trans->base.format = trans->base.format;
|
||||
trans->base.x = x;
|
||||
trans->base.y = y;
|
||||
trans->base.width = w;
|
||||
trans->base.height = h;
|
||||
trans->base.block = texture->block;
|
||||
trans->base.nblocksx = texture->nblocksx[level];
|
||||
trans->base.nblocksy = texture->nblocksy[level];
|
||||
trans->base.stride = tex->stride;
|
||||
trans->offset = offset;
|
||||
trans->base.usage = usage;
|
||||
}
|
||||
return &trans->base;
|
||||
}
|
||||
|
||||
static void
|
||||
i915_tex_transfer_destroy(struct pipe_transfer *trans)
|
||||
i915_fence_reference(struct pipe_screen *screen,
|
||||
struct pipe_fence_handle **ptr,
|
||||
struct pipe_fence_handle *fence)
|
||||
{
|
||||
pipe_texture_reference(&trans->texture, NULL);
|
||||
FREE(trans);
|
||||
struct i915_screen *is = i915_screen(screen);
|
||||
|
||||
is->iws->fence_reference(is->iws, ptr, fence);
|
||||
}
|
||||
|
||||
static void *
|
||||
i915_transfer_map( struct pipe_screen *screen,
|
||||
struct pipe_transfer *transfer )
|
||||
static int
|
||||
i915_fence_signalled(struct pipe_screen *screen,
|
||||
struct pipe_fence_handle *fence,
|
||||
unsigned flags)
|
||||
{
|
||||
struct i915_texture *tex = (struct i915_texture *)transfer->texture;
|
||||
char *map;
|
||||
unsigned flags = 0;
|
||||
struct i915_screen *is = i915_screen(screen);
|
||||
|
||||
if (transfer->usage != PIPE_TRANSFER_WRITE)
|
||||
flags |= PIPE_BUFFER_USAGE_CPU_READ;
|
||||
|
||||
if (transfer->usage != PIPE_TRANSFER_READ)
|
||||
flags |= PIPE_BUFFER_USAGE_CPU_WRITE;
|
||||
|
||||
map = pipe_buffer_map( screen, tex->buffer, flags );
|
||||
if (map == NULL)
|
||||
return NULL;
|
||||
|
||||
if (transfer->texture &&
|
||||
(flags & PIPE_BUFFER_USAGE_CPU_WRITE))
|
||||
{
|
||||
/* Do something to notify contexts of a texture change.
|
||||
*/
|
||||
/* i915_screen(screen)->timestamp++; */
|
||||
}
|
||||
|
||||
return map + i915_transfer(transfer)->offset +
|
||||
transfer->y / transfer->block.height * transfer->stride +
|
||||
transfer->x / transfer->block.width * transfer->block.size;
|
||||
return is->iws->fence_signalled(is->iws, fence);
|
||||
}
|
||||
|
||||
static int
|
||||
i915_fence_finish(struct pipe_screen *screen,
|
||||
struct pipe_fence_handle *fence,
|
||||
unsigned flags)
|
||||
{
|
||||
struct i915_screen *is = i915_screen(screen);
|
||||
|
||||
return is->iws->fence_finish(is->iws, fence);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Generic functions
|
||||
*/
|
||||
|
||||
|
||||
static void
|
||||
i915_transfer_unmap(struct pipe_screen *screen,
|
||||
struct pipe_transfer *transfer)
|
||||
i915_destroy_screen(struct pipe_screen *screen)
|
||||
{
|
||||
struct i915_texture *tex = (struct i915_texture *)transfer->texture;
|
||||
pipe_buffer_unmap( screen, tex->buffer );
|
||||
struct i915_screen *is = i915_screen(screen);
|
||||
|
||||
if (is->iws)
|
||||
is->iws->destroy(is->iws);
|
||||
|
||||
FREE(is);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create a new i915_screen object
|
||||
*/
|
||||
struct pipe_screen *
|
||||
i915_create_screen(struct pipe_winsys *winsys, uint pci_id)
|
||||
i915_create_screen(struct intel_winsys *iws, uint pci_id)
|
||||
{
|
||||
struct i915_screen *i915screen = CALLOC_STRUCT(i915_screen);
|
||||
struct i915_screen *is = CALLOC_STRUCT(i915_screen);
|
||||
|
||||
if (!i915screen)
|
||||
if (!is)
|
||||
return NULL;
|
||||
|
||||
switch (pci_id) {
|
||||
case PCI_CHIP_I915_G:
|
||||
case PCI_CHIP_I915_GM:
|
||||
i915screen->is_i945 = FALSE;
|
||||
is->is_i945 = FALSE;
|
||||
break;
|
||||
|
||||
case PCI_CHIP_I945_G:
|
||||
|
@ -317,7 +267,7 @@ i915_create_screen(struct pipe_winsys *winsys, uint pci_id)
|
|||
case PCI_CHIP_G33_G:
|
||||
case PCI_CHIP_Q33_G:
|
||||
case PCI_CHIP_Q35_G:
|
||||
i915screen->is_i945 = TRUE;
|
||||
is->is_i945 = TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -326,24 +276,25 @@ i915_create_screen(struct pipe_winsys *winsys, uint pci_id)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
i915screen->pci_id = pci_id;
|
||||
is->pci_id = pci_id;
|
||||
is->iws = iws;
|
||||
|
||||
i915screen->screen.winsys = winsys;
|
||||
is->base.winsys = NULL;
|
||||
|
||||
i915screen->screen.destroy = i915_destroy_screen;
|
||||
is->base.destroy = i915_destroy_screen;
|
||||
|
||||
i915screen->screen.get_name = i915_get_name;
|
||||
i915screen->screen.get_vendor = i915_get_vendor;
|
||||
i915screen->screen.get_param = i915_get_param;
|
||||
i915screen->screen.get_paramf = i915_get_paramf;
|
||||
i915screen->screen.is_format_supported = i915_is_format_supported;
|
||||
i915screen->screen.get_tex_transfer = i915_get_tex_transfer;
|
||||
i915screen->screen.tex_transfer_destroy = i915_tex_transfer_destroy;
|
||||
i915screen->screen.transfer_map = i915_transfer_map;
|
||||
i915screen->screen.transfer_unmap = i915_transfer_unmap;
|
||||
is->base.get_name = i915_get_name;
|
||||
is->base.get_vendor = i915_get_vendor;
|
||||
is->base.get_param = i915_get_param;
|
||||
is->base.get_paramf = i915_get_paramf;
|
||||
is->base.is_format_supported = i915_is_format_supported;
|
||||
|
||||
i915_init_screen_texture_functions(&i915screen->screen);
|
||||
u_simple_screen_init(&i915screen->screen);
|
||||
is->base.fence_reference = i915_fence_reference;
|
||||
is->base.fence_signalled = i915_fence_signalled;
|
||||
is->base.fence_finish = i915_fence_finish;
|
||||
|
||||
return &i915screen->screen;
|
||||
i915_init_screen_texture_functions(is);
|
||||
i915_init_screen_buffer_functions(is);
|
||||
|
||||
return &is->base;
|
||||
}
|
||||
|
|
|
@ -25,17 +25,14 @@
|
|||
*
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
#ifndef I915_SCREEN_H
|
||||
#define I915_SCREEN_H
|
||||
|
||||
|
||||
#include "pipe/p_state.h"
|
||||
#include "pipe/p_screen.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
struct intel_winsys;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -43,13 +40,14 @@ extern "C" {
|
|||
*/
|
||||
struct i915_screen
|
||||
{
|
||||
struct pipe_screen screen;
|
||||
struct pipe_screen base;
|
||||
|
||||
struct intel_winsys *iws;
|
||||
|
||||
boolean is_i945;
|
||||
uint pci_id;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Subclass of pipe_transfer
|
||||
*/
|
||||
|
@ -61,7 +59,11 @@ struct i915_transfer
|
|||
};
|
||||
|
||||
|
||||
/** cast wrappers */
|
||||
/*
|
||||
* Cast wrappers
|
||||
*/
|
||||
|
||||
|
||||
static INLINE struct i915_screen *
|
||||
i915_screen(struct pipe_screen *pscreen)
|
||||
{
|
||||
|
@ -69,14 +71,10 @@ i915_screen(struct pipe_screen *pscreen)
|
|||
}
|
||||
|
||||
static INLINE struct i915_transfer *
|
||||
i915_transfer( struct pipe_transfer *transfer )
|
||||
i915_transfer(struct pipe_transfer *transfer)
|
||||
{
|
||||
return (struct i915_transfer *)transfer;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* I915_SCREEN_H */
|
||||
|
|
|
@ -518,7 +518,7 @@ static void i915_set_constant_buffer(struct pipe_context *pipe,
|
|||
const struct pipe_constant_buffer *buf)
|
||||
{
|
||||
struct i915_context *i915 = i915_context(pipe);
|
||||
struct pipe_winsys *ws = pipe->winsys;
|
||||
struct pipe_screen *screen = pipe->screen;
|
||||
draw_flush(i915->draw);
|
||||
|
||||
assert(shader < PIPE_SHADER_TYPES);
|
||||
|
@ -536,10 +536,10 @@ static void i915_set_constant_buffer(struct pipe_context *pipe,
|
|||
if (buf) {
|
||||
void *mapped;
|
||||
if (buf->buffer && buf->buffer->size &&
|
||||
(mapped = ws->buffer_map(ws, buf->buffer,
|
||||
(mapped = pipe_buffer_map(screen, buf->buffer,
|
||||
PIPE_BUFFER_USAGE_CPU_READ))) {
|
||||
memcpy(i915->current.constants[shader], mapped, buf->buffer->size);
|
||||
ws->buffer_unmap(ws, buf->buffer);
|
||||
pipe_buffer_unmap(screen, buf->buffer);
|
||||
i915->current.num_user_constants[shader]
|
||||
= buf->buffer->size / (4 * sizeof(float));
|
||||
}
|
||||
|
@ -751,38 +751,38 @@ static void i915_set_edgeflags(struct pipe_context *pipe,
|
|||
void
|
||||
i915_init_state_functions( struct i915_context *i915 )
|
||||
{
|
||||
i915->pipe.set_edgeflags = i915_set_edgeflags;
|
||||
i915->pipe.create_blend_state = i915_create_blend_state;
|
||||
i915->pipe.bind_blend_state = i915_bind_blend_state;
|
||||
i915->pipe.delete_blend_state = i915_delete_blend_state;
|
||||
i915->base.set_edgeflags = i915_set_edgeflags;
|
||||
i915->base.create_blend_state = i915_create_blend_state;
|
||||
i915->base.bind_blend_state = i915_bind_blend_state;
|
||||
i915->base.delete_blend_state = i915_delete_blend_state;
|
||||
|
||||
i915->pipe.create_sampler_state = i915_create_sampler_state;
|
||||
i915->pipe.bind_sampler_states = i915_bind_sampler_states;
|
||||
i915->pipe.delete_sampler_state = i915_delete_sampler_state;
|
||||
i915->base.create_sampler_state = i915_create_sampler_state;
|
||||
i915->base.bind_sampler_states = i915_bind_sampler_states;
|
||||
i915->base.delete_sampler_state = i915_delete_sampler_state;
|
||||
|
||||
i915->pipe.create_depth_stencil_alpha_state = i915_create_depth_stencil_state;
|
||||
i915->pipe.bind_depth_stencil_alpha_state = i915_bind_depth_stencil_state;
|
||||
i915->pipe.delete_depth_stencil_alpha_state = i915_delete_depth_stencil_state;
|
||||
i915->base.create_depth_stencil_alpha_state = i915_create_depth_stencil_state;
|
||||
i915->base.bind_depth_stencil_alpha_state = i915_bind_depth_stencil_state;
|
||||
i915->base.delete_depth_stencil_alpha_state = i915_delete_depth_stencil_state;
|
||||
|
||||
i915->pipe.create_rasterizer_state = i915_create_rasterizer_state;
|
||||
i915->pipe.bind_rasterizer_state = i915_bind_rasterizer_state;
|
||||
i915->pipe.delete_rasterizer_state = i915_delete_rasterizer_state;
|
||||
i915->pipe.create_fs_state = i915_create_fs_state;
|
||||
i915->pipe.bind_fs_state = i915_bind_fs_state;
|
||||
i915->pipe.delete_fs_state = i915_delete_fs_state;
|
||||
i915->pipe.create_vs_state = i915_create_vs_state;
|
||||
i915->pipe.bind_vs_state = i915_bind_vs_state;
|
||||
i915->pipe.delete_vs_state = i915_delete_vs_state;
|
||||
i915->base.create_rasterizer_state = i915_create_rasterizer_state;
|
||||
i915->base.bind_rasterizer_state = i915_bind_rasterizer_state;
|
||||
i915->base.delete_rasterizer_state = i915_delete_rasterizer_state;
|
||||
i915->base.create_fs_state = i915_create_fs_state;
|
||||
i915->base.bind_fs_state = i915_bind_fs_state;
|
||||
i915->base.delete_fs_state = i915_delete_fs_state;
|
||||
i915->base.create_vs_state = i915_create_vs_state;
|
||||
i915->base.bind_vs_state = i915_bind_vs_state;
|
||||
i915->base.delete_vs_state = i915_delete_vs_state;
|
||||
|
||||
i915->pipe.set_blend_color = i915_set_blend_color;
|
||||
i915->pipe.set_clip_state = i915_set_clip_state;
|
||||
i915->pipe.set_constant_buffer = i915_set_constant_buffer;
|
||||
i915->pipe.set_framebuffer_state = i915_set_framebuffer_state;
|
||||
i915->base.set_blend_color = i915_set_blend_color;
|
||||
i915->base.set_clip_state = i915_set_clip_state;
|
||||
i915->base.set_constant_buffer = i915_set_constant_buffer;
|
||||
i915->base.set_framebuffer_state = i915_set_framebuffer_state;
|
||||
|
||||
i915->pipe.set_polygon_stipple = i915_set_polygon_stipple;
|
||||
i915->pipe.set_scissor_state = i915_set_scissor_state;
|
||||
i915->pipe.set_sampler_textures = i915_set_sampler_textures;
|
||||
i915->pipe.set_viewport_state = i915_set_viewport_state;
|
||||
i915->pipe.set_vertex_buffers = i915_set_vertex_buffers;
|
||||
i915->pipe.set_vertex_elements = i915_set_vertex_elements;
|
||||
i915->base.set_polygon_stipple = i915_set_polygon_stipple;
|
||||
i915->base.set_scissor_state = i915_set_scissor_state;
|
||||
i915->base.set_sampler_textures = i915_set_sampler_textures;
|
||||
i915->base.set_viewport_state = i915_set_viewport_state;
|
||||
i915->base.set_vertex_buffers = i915_set_vertex_buffers;
|
||||
i915->base.set_vertex_elements = i915_set_vertex_elements;
|
||||
}
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
|
||||
#include "i915_reg.h"
|
||||
#include "i915_context.h"
|
||||
#include "i915_winsys.h"
|
||||
#include "i915_batch.h"
|
||||
#include "i915_reg.h"
|
||||
|
||||
|
@ -107,7 +106,7 @@ i915_emit_hardware_state(struct i915_context *i915 )
|
|||
6
|
||||
) * 3/2; /* plus 50% margin */
|
||||
const unsigned relocs = ( I915_TEX_UNITS +
|
||||
3
|
||||
3
|
||||
) * 3/2; /* plus 50% margin */
|
||||
|
||||
#if 0
|
||||
|
@ -123,9 +122,9 @@ i915_emit_hardware_state(struct i915_context *i915 )
|
|||
if (i915->hardware_dirty & I915_HW_INVARIENT)
|
||||
{
|
||||
OUT_BATCH(_3DSTATE_AA_CMD |
|
||||
AA_LINE_ECAAR_WIDTH_ENABLE |
|
||||
AA_LINE_ECAAR_WIDTH_1_0 |
|
||||
AA_LINE_REGION_WIDTH_ENABLE | AA_LINE_REGION_WIDTH_1_0);
|
||||
AA_LINE_ECAAR_WIDTH_ENABLE |
|
||||
AA_LINE_ECAAR_WIDTH_1_0 |
|
||||
AA_LINE_REGION_WIDTH_ENABLE | AA_LINE_REGION_WIDTH_1_0);
|
||||
|
||||
OUT_BATCH(_3DSTATE_DFLT_DIFFUSE_CMD);
|
||||
OUT_BATCH(0);
|
||||
|
@ -137,24 +136,24 @@ i915_emit_hardware_state(struct i915_context *i915 )
|
|||
OUT_BATCH(0);
|
||||
|
||||
OUT_BATCH(_3DSTATE_COORD_SET_BINDINGS |
|
||||
CSB_TCB(0, 0) |
|
||||
CSB_TCB(1, 1) |
|
||||
CSB_TCB(2, 2) |
|
||||
CSB_TCB(3, 3) |
|
||||
CSB_TCB(4, 4) |
|
||||
CSB_TCB(5, 5) |
|
||||
CSB_TCB(6, 6) |
|
||||
CSB_TCB(7, 7));
|
||||
CSB_TCB(0, 0) |
|
||||
CSB_TCB(1, 1) |
|
||||
CSB_TCB(2, 2) |
|
||||
CSB_TCB(3, 3) |
|
||||
CSB_TCB(4, 4) |
|
||||
CSB_TCB(5, 5) |
|
||||
CSB_TCB(6, 6) |
|
||||
CSB_TCB(7, 7));
|
||||
|
||||
OUT_BATCH(_3DSTATE_RASTER_RULES_CMD |
|
||||
ENABLE_POINT_RASTER_RULE |
|
||||
OGL_POINT_RASTER_RULE |
|
||||
ENABLE_LINE_STRIP_PROVOKE_VRTX |
|
||||
ENABLE_TRI_FAN_PROVOKE_VRTX |
|
||||
LINE_STRIP_PROVOKE_VRTX(1) |
|
||||
TRI_FAN_PROVOKE_VRTX(2) |
|
||||
ENABLE_TEXKILL_3D_4D |
|
||||
TEXKILL_4D);
|
||||
ENABLE_POINT_RASTER_RULE |
|
||||
OGL_POINT_RASTER_RULE |
|
||||
ENABLE_LINE_STRIP_PROVOKE_VRTX |
|
||||
ENABLE_TRI_FAN_PROVOKE_VRTX |
|
||||
LINE_STRIP_PROVOKE_VRTX(1) |
|
||||
TRI_FAN_PROVOKE_VRTX(2) |
|
||||
ENABLE_TEXKILL_3D_4D |
|
||||
TEXKILL_4D);
|
||||
|
||||
/* Need to initialize this to zero.
|
||||
*/
|
||||
|
@ -173,21 +172,21 @@ i915_emit_hardware_state(struct i915_context *i915 )
|
|||
if (i915->hardware_dirty & I915_HW_IMMEDIATE)
|
||||
{
|
||||
OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 |
|
||||
I1_LOAD_S(0) |
|
||||
I1_LOAD_S(1) |
|
||||
I1_LOAD_S(2) |
|
||||
I1_LOAD_S(4) |
|
||||
I1_LOAD_S(5) |
|
||||
I1_LOAD_S(6) |
|
||||
(5));
|
||||
I1_LOAD_S(0) |
|
||||
I1_LOAD_S(1) |
|
||||
I1_LOAD_S(2) |
|
||||
I1_LOAD_S(4) |
|
||||
I1_LOAD_S(5) |
|
||||
I1_LOAD_S(6) |
|
||||
(5));
|
||||
|
||||
if(i915->vbo)
|
||||
OUT_RELOC(i915->vbo,
|
||||
I915_BUFFER_ACCESS_READ,
|
||||
INTEL_USAGE_VERTEX,
|
||||
i915->current.immediate[I915_IMMEDIATE_S0]);
|
||||
else
|
||||
/* FIXME: we should not do this */
|
||||
OUT_BATCH(0);
|
||||
/* FIXME: we should not do this */
|
||||
OUT_BATCH(0);
|
||||
OUT_BATCH(i915->current.immediate[I915_IMMEDIATE_S1]);
|
||||
OUT_BATCH(i915->current.immediate[I915_IMMEDIATE_S2]);
|
||||
OUT_BATCH(i915->current.immediate[I915_IMMEDIATE_S4]);
|
||||
|
@ -200,7 +199,7 @@ i915_emit_hardware_state(struct i915_context *i915 )
|
|||
{
|
||||
int i;
|
||||
for (i = 0; i < I915_MAX_DYNAMIC; i++) {
|
||||
OUT_BATCH(i915->current.dynamic[i]);
|
||||
OUT_BATCH(i915->current.dynamic[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -211,68 +210,68 @@ i915_emit_hardware_state(struct i915_context *i915 )
|
|||
struct pipe_surface *depth_surface = i915->framebuffer.zsbuf;
|
||||
|
||||
if (cbuf_surface) {
|
||||
unsigned ctile = BUF_3D_USE_FENCE;
|
||||
unsigned ctile = BUF_3D_USE_FENCE;
|
||||
struct i915_texture *tex = (struct i915_texture *)
|
||||
cbuf_surface->texture;
|
||||
assert(tex);
|
||||
|
||||
if (tex && tex->tiled) {
|
||||
ctile = BUF_3D_TILED_SURFACE;
|
||||
}
|
||||
if (tex && tex->sw_tiled) {
|
||||
ctile = BUF_3D_TILED_SURFACE;
|
||||
}
|
||||
|
||||
OUT_BATCH(_3DSTATE_BUF_INFO_CMD);
|
||||
OUT_BATCH(_3DSTATE_BUF_INFO_CMD);
|
||||
|
||||
OUT_BATCH(BUF_3D_ID_COLOR_BACK |
|
||||
BUF_3D_PITCH(tex->stride) | /* pitch in bytes */
|
||||
ctile);
|
||||
OUT_BATCH(BUF_3D_ID_COLOR_BACK |
|
||||
BUF_3D_PITCH(tex->stride) | /* pitch in bytes */
|
||||
ctile);
|
||||
|
||||
OUT_RELOC(tex->buffer,
|
||||
I915_BUFFER_ACCESS_WRITE,
|
||||
cbuf_surface->offset);
|
||||
OUT_RELOC(tex->buffer,
|
||||
INTEL_USAGE_RENDER,
|
||||
cbuf_surface->offset);
|
||||
}
|
||||
|
||||
/* What happens if no zbuf??
|
||||
*/
|
||||
if (depth_surface) {
|
||||
unsigned ztile = BUF_3D_USE_FENCE;
|
||||
unsigned ztile = BUF_3D_USE_FENCE;
|
||||
struct i915_texture *tex = (struct i915_texture *)
|
||||
depth_surface->texture;
|
||||
assert(tex);
|
||||
|
||||
if (tex && tex->tiled) {
|
||||
ztile = BUF_3D_TILED_SURFACE;
|
||||
}
|
||||
if (tex && tex->sw_tiled) {
|
||||
ztile = BUF_3D_TILED_SURFACE;
|
||||
}
|
||||
|
||||
OUT_BATCH(_3DSTATE_BUF_INFO_CMD);
|
||||
OUT_BATCH(_3DSTATE_BUF_INFO_CMD);
|
||||
|
||||
OUT_BATCH(BUF_3D_ID_DEPTH |
|
||||
BUF_3D_PITCH(tex->stride) | /* pitch in bytes */
|
||||
ztile);
|
||||
OUT_BATCH(BUF_3D_ID_DEPTH |
|
||||
BUF_3D_PITCH(tex->stride) | /* pitch in bytes */
|
||||
ztile);
|
||||
|
||||
OUT_RELOC(tex->buffer,
|
||||
I915_BUFFER_ACCESS_WRITE,
|
||||
depth_surface->offset);
|
||||
OUT_RELOC(tex->buffer,
|
||||
INTEL_USAGE_RENDER,
|
||||
depth_surface->offset);
|
||||
}
|
||||
|
||||
{
|
||||
unsigned cformat, zformat = 0;
|
||||
unsigned cformat, zformat = 0;
|
||||
|
||||
if (cbuf_surface)
|
||||
if (cbuf_surface)
|
||||
cformat = cbuf_surface->format;
|
||||
else
|
||||
cformat = PIPE_FORMAT_A8R8G8B8_UNORM; /* arbitrary */
|
||||
cformat = translate_format(cformat);
|
||||
|
||||
if (depth_surface)
|
||||
zformat = translate_depth_format( i915->framebuffer.zsbuf->format );
|
||||
if (depth_surface)
|
||||
zformat = translate_depth_format( i915->framebuffer.zsbuf->format );
|
||||
|
||||
OUT_BATCH(_3DSTATE_DST_BUF_VARS_CMD);
|
||||
OUT_BATCH(DSTORG_HORT_BIAS(0x8) | /* .5 */
|
||||
DSTORG_VERT_BIAS(0x8) | /* .5 */
|
||||
LOD_PRECLAMP_OGL |
|
||||
TEX_DEFAULT_COLOR_OGL |
|
||||
cformat |
|
||||
zformat );
|
||||
OUT_BATCH(_3DSTATE_DST_BUF_VARS_CMD);
|
||||
OUT_BATCH(DSTORG_HORT_BIAS(0x8) | /* .5 */
|
||||
DSTORG_VERT_BIAS(0x8) | /* .5 */
|
||||
LOD_PRECLAMP_OGL |
|
||||
TEX_DEFAULT_COLOR_OGL |
|
||||
cformat |
|
||||
zformat );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -290,16 +289,13 @@ i915_emit_hardware_state(struct i915_context *i915 )
|
|||
OUT_BATCH(enabled);
|
||||
for (unit = 0; unit < I915_TEX_UNITS; unit++) {
|
||||
if (enabled & (1 << unit)) {
|
||||
struct pipe_buffer *buf =
|
||||
i915->texture[unit]->buffer;
|
||||
struct intel_buffer *buf = i915->texture[unit]->buffer;
|
||||
uint offset = 0;
|
||||
assert(buf);
|
||||
|
||||
count++;
|
||||
|
||||
OUT_RELOC(buf,
|
||||
I915_BUFFER_ACCESS_READ,
|
||||
offset);
|
||||
OUT_RELOC(buf, INTEL_USAGE_SAMPLER, offset);
|
||||
OUT_BATCH(i915->current.texbuffer[unit][0]); /* MS3 */
|
||||
OUT_BATCH(i915->current.texbuffer[unit][1]); /* MS4 */
|
||||
}
|
||||
|
@ -315,20 +311,20 @@ i915_emit_hardware_state(struct i915_context *i915 )
|
|||
if (i915->hardware_dirty & I915_HW_SAMPLER)
|
||||
{
|
||||
if (i915->current.sampler_enable_nr) {
|
||||
int i;
|
||||
|
||||
OUT_BATCH( _3DSTATE_SAMPLER_STATE |
|
||||
(3 * i915->current.sampler_enable_nr) );
|
||||
int i;
|
||||
|
||||
OUT_BATCH( _3DSTATE_SAMPLER_STATE |
|
||||
(3 * i915->current.sampler_enable_nr) );
|
||||
|
||||
OUT_BATCH( i915->current.sampler_enable_flags );
|
||||
OUT_BATCH( i915->current.sampler_enable_flags );
|
||||
|
||||
for (i = 0; i < I915_TEX_UNITS; i++) {
|
||||
if (i915->current.sampler_enable_flags & (1<<i)) {
|
||||
OUT_BATCH( i915->current.sampler[i][0] );
|
||||
OUT_BATCH( i915->current.sampler[i][1] );
|
||||
OUT_BATCH( i915->current.sampler[i][2] );
|
||||
}
|
||||
}
|
||||
for (i = 0; i < I915_TEX_UNITS; i++) {
|
||||
if (i915->current.sampler_enable_flags & (1<<i)) {
|
||||
OUT_BATCH( i915->current.sampler[i][0] );
|
||||
OUT_BATCH( i915->current.sampler[i][1] );
|
||||
OUT_BATCH( i915->current.sampler[i][2] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -247,7 +247,7 @@ i915_update_texture(struct i915_context *i915,
|
|||
assert(format);
|
||||
assert(pitch);
|
||||
|
||||
if (tex->tiled) {
|
||||
if (tex->sw_tiled) {
|
||||
assert(!((pitch - 1) & pitch));
|
||||
tiled = MS3_TILED_SURFACE;
|
||||
}
|
||||
|
|
|
@ -89,6 +89,6 @@ i915_surface_fill(struct pipe_context *pipe,
|
|||
void
|
||||
i915_init_surface_functions(struct i915_context *i915)
|
||||
{
|
||||
i915->pipe.surface_copy = i915_surface_copy;
|
||||
i915->pipe.surface_fill = i915_surface_fill;
|
||||
i915->base.surface_copy = i915_surface_copy;
|
||||
i915->base.surface_fill = i915_surface_fill;
|
||||
}
|
||||
|
|
|
@ -42,12 +42,14 @@
|
|||
#include "i915_texture.h"
|
||||
#include "i915_debug.h"
|
||||
#include "i915_screen.h"
|
||||
#include "i915_winsys.h"
|
||||
#include "intel_winsys.h"
|
||||
|
||||
|
||||
/*
|
||||
* Helper function and arrays
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Initial offset for Cube map.
|
||||
*/
|
||||
|
@ -133,7 +135,7 @@ i915_miptree_set_level_info(struct i915_texture *tex,
|
|||
|
||||
static void
|
||||
i915_miptree_set_image_offset(struct i915_texture *tex,
|
||||
unsigned level, unsigned img, unsigned x, unsigned y)
|
||||
unsigned level, unsigned img, unsigned x, unsigned y)
|
||||
{
|
||||
if (img == 0 && level == 0)
|
||||
assert(x == 0 && y == 0);
|
||||
|
@ -150,7 +152,7 @@ i915_miptree_set_image_offset(struct i915_texture *tex,
|
|||
|
||||
|
||||
/*
|
||||
* Layout functions
|
||||
* i915 layout functions, some used by i945
|
||||
*/
|
||||
|
||||
|
||||
|
@ -165,37 +167,174 @@ i915_scanout_layout(struct i915_texture *tex)
|
|||
if (pt->last_level > 0 || pt->block.size != 4)
|
||||
return 0;
|
||||
|
||||
i915_miptree_set_level_info( tex, 0, 1,
|
||||
tex->base.width[0],
|
||||
tex->base.height[0],
|
||||
1 );
|
||||
i915_miptree_set_image_offset( tex, 0, 0, 0, 0 );
|
||||
i915_miptree_set_level_info(tex, 0, 1,
|
||||
tex->base.width[0],
|
||||
tex->base.height[0],
|
||||
1);
|
||||
i915_miptree_set_image_offset(tex, 0, 0, 0, 0);
|
||||
|
||||
#if 0 /* TODO use this code when backend is smarter */
|
||||
if (tex->base.width[0] >= 240) {
|
||||
tex->stride = power_of_two(tex->base.nblocksx[0] * pt->block.size);
|
||||
tex->total_nblocksy = round_up(tex->base.nblocksy[0], 8);
|
||||
#else
|
||||
if (tex->base.width[0] >= 240) {
|
||||
tex->stride = 2048 * 4;
|
||||
tex->total_nblocksy = round_up(tex->base.nblocksy[0], 8);
|
||||
#endif
|
||||
tex->hw_tiled = INTEL_TILE_X;
|
||||
} else if (tex->base.width[0] == 64 && tex->base.height[0] == 64) {
|
||||
tex->stride = power_of_two(tex->base.nblocksx[0] * pt->block.size);
|
||||
tex->total_nblocksy = round_up(tex->base.nblocksy[0], 8);
|
||||
} else {
|
||||
return 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
debug_printf("%s size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__,
|
||||
tex->base.width[0], tex->base.height[0], pt->block.size,
|
||||
tex->stride, tex->total_nblocksy, tex->stride * tex->total_nblocksy);
|
||||
|
||||
return 1;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
i945_miptree_layout_2d( struct i915_texture *tex )
|
||||
i915_miptree_layout_2d(struct i915_texture *tex)
|
||||
{
|
||||
struct pipe_texture *pt = &tex->base;
|
||||
unsigned level;
|
||||
unsigned width = pt->width[0];
|
||||
unsigned height = pt->height[0];
|
||||
unsigned nblocksx = pt->nblocksx[0];
|
||||
unsigned nblocksy = pt->nblocksy[0];
|
||||
|
||||
tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4);
|
||||
tex->total_nblocksy = 0;
|
||||
|
||||
for (level = 0; level <= pt->last_level; level++) {
|
||||
i915_miptree_set_level_info(tex, level, 1, width, height, 1);
|
||||
i915_miptree_set_image_offset(tex, level, 0, 0, tex->total_nblocksy);
|
||||
|
||||
nblocksy = round_up(MAX2(2, nblocksy), 2);
|
||||
|
||||
tex->total_nblocksy += nblocksy;
|
||||
|
||||
width = minify(width);
|
||||
height = minify(height);
|
||||
nblocksx = pf_get_nblocksx(&pt->block, width);
|
||||
nblocksy = pf_get_nblocksy(&pt->block, height);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
i915_miptree_layout_3d(struct i915_texture *tex)
|
||||
{
|
||||
struct pipe_texture *pt = &tex->base;
|
||||
unsigned level;
|
||||
|
||||
unsigned width = pt->width[0];
|
||||
unsigned height = pt->height[0];
|
||||
unsigned depth = pt->depth[0];
|
||||
unsigned nblocksx = pt->nblocksx[0];
|
||||
unsigned nblocksy = pt->nblocksy[0];
|
||||
unsigned stack_nblocksy = 0;
|
||||
|
||||
/* Calculate the size of a single slice.
|
||||
*/
|
||||
tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4);
|
||||
|
||||
/* XXX: hardware expects/requires 9 levels at minimum.
|
||||
*/
|
||||
for (level = 0; level <= MAX2(8, pt->last_level); level++) {
|
||||
i915_miptree_set_level_info(tex, level, depth, width, height, depth);
|
||||
|
||||
stack_nblocksy += MAX2(2, nblocksy);
|
||||
|
||||
width = minify(width);
|
||||
height = minify(height);
|
||||
depth = minify(depth);
|
||||
nblocksx = pf_get_nblocksx(&pt->block, width);
|
||||
nblocksy = pf_get_nblocksy(&pt->block, height);
|
||||
}
|
||||
|
||||
/* Fixup depth image_offsets:
|
||||
*/
|
||||
depth = pt->depth[0];
|
||||
for (level = 0; level <= pt->last_level; level++) {
|
||||
unsigned i;
|
||||
for (i = 0; i < depth; i++)
|
||||
i915_miptree_set_image_offset(tex, level, i, 0, i * stack_nblocksy);
|
||||
|
||||
depth = minify(depth);
|
||||
}
|
||||
|
||||
/* Multiply slice size by texture depth for total size. It's
|
||||
* remarkable how wasteful of memory the i915 texture layouts
|
||||
* are. They are largely fixed in the i945.
|
||||
*/
|
||||
tex->total_nblocksy = stack_nblocksy * pt->depth[0];
|
||||
}
|
||||
|
||||
static void
|
||||
i915_miptree_layout_cube(struct i915_texture *tex)
|
||||
{
|
||||
struct pipe_texture *pt = &tex->base;
|
||||
unsigned width = pt->width[0], height = pt->height[0];
|
||||
const unsigned nblocks = pt->nblocksx[0];
|
||||
unsigned level;
|
||||
unsigned face;
|
||||
|
||||
assert(width == height); /* cubemap images are square */
|
||||
|
||||
/* double pitch for cube layouts */
|
||||
tex->stride = round_up(nblocks * pt->block.size * 2, 4);
|
||||
tex->total_nblocksy = nblocks * 4;
|
||||
|
||||
for (level = 0; level <= pt->last_level; level++) {
|
||||
i915_miptree_set_level_info(tex, level, 6, width, height, 1);
|
||||
width /= 2;
|
||||
height /= 2;
|
||||
}
|
||||
|
||||
for (face = 0; face < 6; face++) {
|
||||
unsigned x = initial_offsets[face][0] * nblocks;
|
||||
unsigned y = initial_offsets[face][1] * nblocks;
|
||||
unsigned d = nblocks;
|
||||
|
||||
for (level = 0; level <= pt->last_level; level++) {
|
||||
i915_miptree_set_image_offset(tex, level, face, x, y);
|
||||
d >>= 1;
|
||||
x += step_offsets[face][0] * d;
|
||||
y += step_offsets[face][1] * d;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static boolean
|
||||
i915_miptree_layout(struct i915_texture * tex)
|
||||
{
|
||||
struct pipe_texture *pt = &tex->base;
|
||||
|
||||
switch (pt->target) {
|
||||
case PIPE_TEXTURE_1D:
|
||||
case PIPE_TEXTURE_2D:
|
||||
i915_miptree_layout_2d(tex);
|
||||
break;
|
||||
case PIPE_TEXTURE_3D:
|
||||
i915_miptree_layout_3d(tex);
|
||||
break;
|
||||
case PIPE_TEXTURE_CUBE:
|
||||
i915_miptree_layout_cube(tex);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* i945 layout functions
|
||||
*/
|
||||
|
||||
|
||||
static void
|
||||
i945_miptree_layout_2d(struct i915_texture *tex)
|
||||
{
|
||||
struct pipe_texture *pt = &tex->base;
|
||||
const int align_x = 2, align_y = 4;
|
||||
|
@ -210,7 +349,7 @@ i945_miptree_layout_2d( struct i915_texture *tex )
|
|||
/* used for scanouts that need special layouts */
|
||||
if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_PRIMARY)
|
||||
if (i915_scanout_layout(tex))
|
||||
return;
|
||||
return;
|
||||
|
||||
tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4);
|
||||
|
||||
|
@ -221,11 +360,11 @@ i945_miptree_layout_2d( struct i915_texture *tex )
|
|||
*/
|
||||
if (pt->last_level > 0) {
|
||||
unsigned mip1_nblocksx
|
||||
= align(pf_get_nblocksx(&pt->block, minify(width)), align_x)
|
||||
= align(pf_get_nblocksx(&pt->block, minify(width)), align_x)
|
||||
+ pf_get_nblocksx(&pt->block, minify(minify(width)));
|
||||
|
||||
if (mip1_nblocksx > nblocksx)
|
||||
tex->stride = mip1_nblocksx * pt->block.size;
|
||||
tex->stride = mip1_nblocksx * pt->block.size;
|
||||
}
|
||||
|
||||
/* Pitch must be a whole number of dwords
|
||||
|
@ -247,10 +386,10 @@ i945_miptree_layout_2d( struct i915_texture *tex )
|
|||
/* Layout_below: step right after second mipmap level.
|
||||
*/
|
||||
if (level == 1) {
|
||||
x += align(nblocksx, align_x);
|
||||
x += align(nblocksx, align_x);
|
||||
}
|
||||
else {
|
||||
y += nblocksy;
|
||||
y += nblocksy;
|
||||
}
|
||||
|
||||
width = minify(width);
|
||||
|
@ -260,6 +399,63 @@ i945_miptree_layout_2d( struct i915_texture *tex )
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
i945_miptree_layout_3d(struct i915_texture *tex)
|
||||
{
|
||||
struct pipe_texture *pt = &tex->base;
|
||||
unsigned width = pt->width[0];
|
||||
unsigned height = pt->height[0];
|
||||
unsigned depth = pt->depth[0];
|
||||
unsigned nblocksx = pt->nblocksx[0];
|
||||
unsigned nblocksy = pt->nblocksy[0];
|
||||
unsigned pack_x_pitch, pack_x_nr;
|
||||
unsigned pack_y_pitch;
|
||||
unsigned level;
|
||||
|
||||
tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4);
|
||||
tex->total_nblocksy = 0;
|
||||
|
||||
pack_y_pitch = MAX2(pt->nblocksy[0], 2);
|
||||
pack_x_pitch = tex->stride / pt->block.size;
|
||||
pack_x_nr = 1;
|
||||
|
||||
for (level = 0; level <= pt->last_level; level++) {
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
unsigned q, j;
|
||||
|
||||
i915_miptree_set_level_info(tex, level, depth, width, height, depth);
|
||||
|
||||
for (q = 0; q < depth;) {
|
||||
for (j = 0; j < pack_x_nr && q < depth; j++, q++) {
|
||||
i915_miptree_set_image_offset(tex, level, q, x, y + tex->total_nblocksy);
|
||||
x += pack_x_pitch;
|
||||
}
|
||||
|
||||
x = 0;
|
||||
y += pack_y_pitch;
|
||||
}
|
||||
|
||||
tex->total_nblocksy += y;
|
||||
|
||||
if (pack_x_pitch > 4) {
|
||||
pack_x_pitch >>= 1;
|
||||
pack_x_nr <<= 1;
|
||||
assert(pack_x_pitch * pack_x_nr * pt->block.size <= tex->stride);
|
||||
}
|
||||
|
||||
if (pack_y_pitch > 2) {
|
||||
pack_y_pitch >>= 1;
|
||||
}
|
||||
|
||||
width = minify(width);
|
||||
height = minify(height);
|
||||
depth = minify(depth);
|
||||
nblocksx = pf_get_nblocksx(&pt->block, width);
|
||||
nblocksy = pf_get_nblocksy(&pt->block, height);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
i945_miptree_layout_cube(struct i915_texture *tex)
|
||||
{
|
||||
|
@ -361,225 +557,42 @@ i945_miptree_layout_cube(struct i915_texture *tex)
|
|||
}
|
||||
}
|
||||
|
||||
static boolean
|
||||
i915_miptree_layout(struct i915_texture * tex)
|
||||
{
|
||||
struct pipe_texture *pt = &tex->base;
|
||||
unsigned level;
|
||||
|
||||
switch (pt->target) {
|
||||
case PIPE_TEXTURE_CUBE: {
|
||||
const unsigned nblocks = pt->nblocksx[0];
|
||||
unsigned face;
|
||||
unsigned width = pt->width[0], height = pt->height[0];
|
||||
|
||||
assert(width == height); /* cubemap images are square */
|
||||
|
||||
/* double pitch for cube layouts */
|
||||
tex->stride = round_up(nblocks * pt->block.size * 2, 4);
|
||||
tex->total_nblocksy = nblocks * 4;
|
||||
|
||||
for (level = 0; level <= pt->last_level; level++) {
|
||||
i915_miptree_set_level_info(tex, level, 6,
|
||||
width, height,
|
||||
1);
|
||||
width /= 2;
|
||||
height /= 2;
|
||||
}
|
||||
|
||||
for (face = 0; face < 6; face++) {
|
||||
unsigned x = initial_offsets[face][0] * nblocks;
|
||||
unsigned y = initial_offsets[face][1] * nblocks;
|
||||
unsigned d = nblocks;
|
||||
|
||||
for (level = 0; level <= pt->last_level; level++) {
|
||||
i915_miptree_set_image_offset(tex, level, face, x, y);
|
||||
d >>= 1;
|
||||
x += step_offsets[face][0] * d;
|
||||
y += step_offsets[face][1] * d;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PIPE_TEXTURE_3D:{
|
||||
unsigned width = pt->width[0];
|
||||
unsigned height = pt->height[0];
|
||||
unsigned depth = pt->depth[0];
|
||||
unsigned nblocksx = pt->nblocksx[0];
|
||||
unsigned nblocksy = pt->nblocksy[0];
|
||||
unsigned stack_nblocksy = 0;
|
||||
|
||||
/* Calculate the size of a single slice.
|
||||
*/
|
||||
tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4);
|
||||
|
||||
/* XXX: hardware expects/requires 9 levels at minimum.
|
||||
*/
|
||||
for (level = 0; level <= MAX2(8, pt->last_level);
|
||||
level++) {
|
||||
i915_miptree_set_level_info(tex, level, depth,
|
||||
width, height, depth);
|
||||
|
||||
|
||||
stack_nblocksy += MAX2(2, nblocksy);
|
||||
|
||||
width = minify(width);
|
||||
height = minify(height);
|
||||
depth = minify(depth);
|
||||
nblocksx = pf_get_nblocksx(&pt->block, width);
|
||||
nblocksy = pf_get_nblocksy(&pt->block, height);
|
||||
}
|
||||
|
||||
/* Fixup depth image_offsets:
|
||||
*/
|
||||
depth = pt->depth[0];
|
||||
for (level = 0; level <= pt->last_level; level++) {
|
||||
unsigned i;
|
||||
for (i = 0; i < depth; i++)
|
||||
i915_miptree_set_image_offset(tex, level, i,
|
||||
0, i * stack_nblocksy);
|
||||
|
||||
depth = minify(depth);
|
||||
}
|
||||
|
||||
|
||||
/* Multiply slice size by texture depth for total size. It's
|
||||
* remarkable how wasteful of memory the i915 texture layouts
|
||||
* are. They are largely fixed in the i945.
|
||||
*/
|
||||
tex->total_nblocksy = stack_nblocksy * pt->depth[0];
|
||||
break;
|
||||
}
|
||||
|
||||
default:{
|
||||
unsigned width = pt->width[0];
|
||||
unsigned height = pt->height[0];
|
||||
unsigned nblocksx = pt->nblocksx[0];
|
||||
unsigned nblocksy = pt->nblocksy[0];
|
||||
|
||||
tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4);
|
||||
tex->total_nblocksy = 0;
|
||||
|
||||
for (level = 0; level <= pt->last_level; level++) {
|
||||
i915_miptree_set_level_info(tex, level, 1,
|
||||
width, height, 1);
|
||||
i915_miptree_set_image_offset(tex, level, 0,
|
||||
0, tex->total_nblocksy);
|
||||
|
||||
nblocksy = round_up(MAX2(2, nblocksy), 2);
|
||||
|
||||
tex->total_nblocksy += nblocksy;
|
||||
|
||||
width = minify(width);
|
||||
height = minify(height);
|
||||
nblocksx = pf_get_nblocksx(&pt->block, width);
|
||||
nblocksy = pf_get_nblocksy(&pt->block, height);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__,
|
||||
tex->pitch,
|
||||
tex->total_nblocksy, pt->block.size, tex->stride * tex->total_nblocksy);
|
||||
*/
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static boolean
|
||||
i945_miptree_layout(struct i915_texture * tex)
|
||||
{
|
||||
struct pipe_texture *pt = &tex->base;
|
||||
unsigned level;
|
||||
|
||||
switch (pt->target) {
|
||||
case PIPE_TEXTURE_1D:
|
||||
case PIPE_TEXTURE_2D:
|
||||
i945_miptree_layout_2d(tex);
|
||||
break;
|
||||
case PIPE_TEXTURE_3D:
|
||||
i945_miptree_layout_3d(tex);
|
||||
break;
|
||||
case PIPE_TEXTURE_CUBE:
|
||||
i945_miptree_layout_cube(tex);
|
||||
break;
|
||||
case PIPE_TEXTURE_3D:{
|
||||
unsigned width = pt->width[0];
|
||||
unsigned height = pt->height[0];
|
||||
unsigned depth = pt->depth[0];
|
||||
unsigned nblocksx = pt->nblocksx[0];
|
||||
unsigned nblocksy = pt->nblocksy[0];
|
||||
unsigned pack_x_pitch, pack_x_nr;
|
||||
unsigned pack_y_pitch;
|
||||
|
||||
tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4);
|
||||
tex->total_nblocksy = 0;
|
||||
|
||||
pack_y_pitch = MAX2(pt->nblocksy[0], 2);
|
||||
pack_x_pitch = tex->stride / pt->block.size;
|
||||
pack_x_nr = 1;
|
||||
|
||||
for (level = 0; level <= pt->last_level; level++) {
|
||||
unsigned nr_images = pt->target == PIPE_TEXTURE_3D ? depth : 6;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
unsigned q, j;
|
||||
|
||||
i915_miptree_set_level_info(tex, level, nr_images,
|
||||
width, height, depth);
|
||||
|
||||
for (q = 0; q < nr_images;) {
|
||||
for (j = 0; j < pack_x_nr && q < nr_images; j++, q++) {
|
||||
i915_miptree_set_image_offset(tex, level, q, x, y + tex->total_nblocksy);
|
||||
x += pack_x_pitch;
|
||||
}
|
||||
|
||||
x = 0;
|
||||
y += pack_y_pitch;
|
||||
}
|
||||
|
||||
|
||||
tex->total_nblocksy += y;
|
||||
|
||||
if (pack_x_pitch > 4) {
|
||||
pack_x_pitch >>= 1;
|
||||
pack_x_nr <<= 1;
|
||||
assert(pack_x_pitch * pack_x_nr * pt->block.size <= tex->stride);
|
||||
}
|
||||
|
||||
if (pack_y_pitch > 2) {
|
||||
pack_y_pitch >>= 1;
|
||||
}
|
||||
|
||||
width = minify(width);
|
||||
height = minify(height);
|
||||
depth = minify(depth);
|
||||
nblocksx = pf_get_nblocksx(&pt->block, width);
|
||||
nblocksy = pf_get_nblocksy(&pt->block, height);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case PIPE_TEXTURE_1D:
|
||||
case PIPE_TEXTURE_2D:
|
||||
// case PIPE_TEXTURE_RECTANGLE:
|
||||
i945_miptree_layout_2d(tex);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__,
|
||||
tex->pitch,
|
||||
tex->total_nblocksy, pt->block.size, tex->stride * tex->total_nblocksy);
|
||||
*/
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Screen texture functions
|
||||
*/
|
||||
|
||||
|
||||
static struct pipe_texture *
|
||||
i915_texture_create(struct pipe_screen *screen,
|
||||
const struct pipe_texture *templat)
|
||||
{
|
||||
struct i915_screen *i915screen = i915_screen(screen);
|
||||
struct i915_screen *is = i915_screen(screen);
|
||||
struct intel_winsys *iws = is->iws;
|
||||
struct i915_texture *tex = CALLOC_STRUCT(i915_texture);
|
||||
size_t tex_size;
|
||||
unsigned buf_usage = 0;
|
||||
|
@ -594,27 +607,35 @@ i915_texture_create(struct pipe_screen *screen,
|
|||
tex->base.nblocksx[0] = pf_get_nblocksx(&tex->base.block, tex->base.width[0]);
|
||||
tex->base.nblocksy[0] = pf_get_nblocksy(&tex->base.block, tex->base.height[0]);
|
||||
|
||||
if (i915screen->is_i945) {
|
||||
if (is->is_i945) {
|
||||
if (!i945_miptree_layout(tex))
|
||||
goto fail;
|
||||
goto fail;
|
||||
} else {
|
||||
if (!i915_miptree_layout(tex))
|
||||
goto fail;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
tex_size = tex->stride * tex->total_nblocksy;
|
||||
|
||||
buf_usage = PIPE_BUFFER_USAGE_PIXEL;
|
||||
|
||||
/* for scanouts and cursors, cursors don't have the scanout tag */
|
||||
|
||||
/* for scanouts and cursors, cursors arn't scanouts */
|
||||
if (templat->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY && templat->width[0] != 64)
|
||||
buf_usage |= I915_BUFFER_USAGE_SCANOUT;
|
||||
|
||||
tex->buffer = screen->buffer_create(screen, 64, buf_usage, tex_size);
|
||||
buf_usage = INTEL_NEW_SCANOUT;
|
||||
else
|
||||
buf_usage = INTEL_NEW_TEXTURE;
|
||||
|
||||
tex->buffer = iws->buffer_create(iws, tex_size, 64, buf_usage);
|
||||
if (!tex->buffer)
|
||||
goto fail;
|
||||
|
||||
/* setup any hw fences */
|
||||
if (tex->hw_tiled) {
|
||||
assert(tex->sw_tiled == INTEL_TILE_NONE);
|
||||
iws->buffer_set_fence_reg(iws, tex->buffer, tex->stride, tex->hw_tiled);
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
void *ptr = ws->buffer_map(ws, tex->buffer,
|
||||
PIPE_BUFFER_USAGE_CPU_WRITE);
|
||||
|
@ -629,18 +650,56 @@ fail:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static struct pipe_texture *
|
||||
i915_texture_blanket(struct pipe_screen * screen,
|
||||
const struct pipe_texture *base,
|
||||
const unsigned *stride,
|
||||
struct pipe_buffer *buffer)
|
||||
{
|
||||
#if 0
|
||||
struct i915_texture *tex;
|
||||
assert(screen);
|
||||
|
||||
/* Only supports one type */
|
||||
if (base->target != PIPE_TEXTURE_2D ||
|
||||
base->last_level != 0 ||
|
||||
base->depth[0] != 1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tex = CALLOC_STRUCT(i915_texture);
|
||||
if (!tex)
|
||||
return NULL;
|
||||
|
||||
tex->base = *base;
|
||||
pipe_reference_init(&tex->base.reference, 1);
|
||||
tex->base.screen = screen;
|
||||
|
||||
tex->stride = stride[0];
|
||||
|
||||
i915_miptree_set_level_info(tex, 0, 1, base->width[0], base->height[0], 1);
|
||||
i915_miptree_set_image_offset(tex, 0, 0, 0, 0);
|
||||
|
||||
pipe_buffer_reference(&tex->buffer, buffer);
|
||||
|
||||
return &tex->base;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
i915_texture_destroy(struct pipe_texture *pt)
|
||||
{
|
||||
struct i915_texture *tex = (struct i915_texture *)pt;
|
||||
struct intel_winsys *iws = i915_screen(pt->screen)->iws;
|
||||
uint i;
|
||||
|
||||
/*
|
||||
DBG("%s deleting %p\n", __FUNCTION__, (void *) tex);
|
||||
*/
|
||||
|
||||
pipe_buffer_reference(&tex->buffer, NULL);
|
||||
iws->buffer_destroy(iws, tex->buffer);
|
||||
|
||||
for (i = 0; i < PIPE_MAX_TEXTURE_LEVELS; i++)
|
||||
if (tex->image_offset[i])
|
||||
|
@ -649,6 +708,12 @@ i915_texture_destroy(struct pipe_texture *pt)
|
|||
FREE(tex);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Screen surface functions
|
||||
*/
|
||||
|
||||
|
||||
static struct pipe_surface *
|
||||
i915_get_tex_surface(struct pipe_screen *screen,
|
||||
struct pipe_texture *pt,
|
||||
|
@ -684,11 +749,122 @@ i915_get_tex_surface(struct pipe_screen *screen,
|
|||
return ps;
|
||||
}
|
||||
|
||||
static struct pipe_texture *
|
||||
i915_texture_blanket(struct pipe_screen * screen,
|
||||
const struct pipe_texture *base,
|
||||
const unsigned *stride,
|
||||
struct pipe_buffer *buffer)
|
||||
static void
|
||||
i915_tex_surface_destroy(struct pipe_surface *surf)
|
||||
{
|
||||
pipe_texture_reference(&surf->texture, NULL);
|
||||
FREE(surf);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Screen transfer functions
|
||||
*/
|
||||
|
||||
|
||||
static struct pipe_transfer*
|
||||
i915_get_tex_transfer(struct pipe_screen *screen,
|
||||
struct pipe_texture *texture,
|
||||
unsigned face, unsigned level, unsigned zslice,
|
||||
enum pipe_transfer_usage usage, unsigned x, unsigned y,
|
||||
unsigned w, unsigned h)
|
||||
{
|
||||
struct i915_texture *tex = (struct i915_texture *)texture;
|
||||
struct i915_transfer *trans;
|
||||
unsigned offset; /* in bytes */
|
||||
|
||||
if (texture->target == PIPE_TEXTURE_CUBE) {
|
||||
offset = tex->image_offset[level][face];
|
||||
}
|
||||
else if (texture->target == PIPE_TEXTURE_3D) {
|
||||
offset = tex->image_offset[level][zslice];
|
||||
}
|
||||
else {
|
||||
offset = tex->image_offset[level][0];
|
||||
assert(face == 0);
|
||||
assert(zslice == 0);
|
||||
}
|
||||
|
||||
trans = CALLOC_STRUCT(i915_transfer);
|
||||
if (trans) {
|
||||
pipe_texture_reference(&trans->base.texture, texture);
|
||||
trans->base.format = trans->base.format;
|
||||
trans->base.x = x;
|
||||
trans->base.y = y;
|
||||
trans->base.width = w;
|
||||
trans->base.height = h;
|
||||
trans->base.block = texture->block;
|
||||
trans->base.nblocksx = texture->nblocksx[level];
|
||||
trans->base.nblocksy = texture->nblocksy[level];
|
||||
trans->base.stride = tex->stride;
|
||||
trans->offset = offset;
|
||||
trans->base.usage = usage;
|
||||
}
|
||||
return &trans->base;
|
||||
}
|
||||
|
||||
static void *
|
||||
i915_transfer_map(struct pipe_screen *screen,
|
||||
struct pipe_transfer *transfer)
|
||||
{
|
||||
struct i915_texture *tex = (struct i915_texture *)transfer->texture;
|
||||
struct intel_winsys *iws = i915_screen(tex->base.screen)->iws;
|
||||
char *map;
|
||||
boolean write = FALSE;
|
||||
|
||||
if (transfer->usage != PIPE_TRANSFER_READ)
|
||||
write = TRUE;
|
||||
|
||||
map = iws->buffer_map(iws, tex->buffer, write);
|
||||
if (map == NULL)
|
||||
return NULL;
|
||||
|
||||
return map + i915_transfer(transfer)->offset +
|
||||
transfer->y / transfer->block.height * transfer->stride +
|
||||
transfer->x / transfer->block.width * transfer->block.size;
|
||||
}
|
||||
|
||||
static void
|
||||
i915_transfer_unmap(struct pipe_screen *screen,
|
||||
struct pipe_transfer *transfer)
|
||||
{
|
||||
struct i915_texture *tex = (struct i915_texture *)transfer->texture;
|
||||
struct intel_winsys *iws = i915_screen(tex->base.screen)->iws;
|
||||
iws->buffer_unmap(iws, tex->buffer);
|
||||
}
|
||||
|
||||
static void
|
||||
i915_tex_transfer_destroy(struct pipe_transfer *trans)
|
||||
{
|
||||
pipe_texture_reference(&trans->texture, NULL);
|
||||
FREE(trans);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Other texture functions
|
||||
*/
|
||||
|
||||
|
||||
void
|
||||
i915_init_screen_texture_functions(struct i915_screen *is)
|
||||
{
|
||||
is->base.texture_create = i915_texture_create;
|
||||
is->base.texture_blanket = i915_texture_blanket;
|
||||
is->base.texture_destroy = i915_texture_destroy;
|
||||
is->base.get_tex_surface = i915_get_tex_surface;
|
||||
is->base.tex_surface_destroy = i915_tex_surface_destroy;
|
||||
is->base.get_tex_transfer = i915_get_tex_transfer;
|
||||
is->base.transfer_map = i915_transfer_map;
|
||||
is->base.transfer_unmap = i915_transfer_unmap;
|
||||
is->base.tex_transfer_destroy = i915_tex_transfer_destroy;
|
||||
}
|
||||
|
||||
struct pipe_texture *
|
||||
i915_texture_blanket_intel(struct pipe_screen *screen,
|
||||
struct pipe_texture *base,
|
||||
unsigned stride,
|
||||
struct intel_buffer *buffer)
|
||||
{
|
||||
struct i915_texture *tex;
|
||||
assert(screen);
|
||||
|
@ -708,52 +884,28 @@ i915_texture_blanket(struct pipe_screen * screen,
|
|||
pipe_reference_init(&tex->base.reference, 1);
|
||||
tex->base.screen = screen;
|
||||
|
||||
tex->stride = stride[0];
|
||||
tex->stride = stride;
|
||||
|
||||
i915_miptree_set_level_info(tex, 0, 1, base->width[0], base->height[0], 1);
|
||||
i915_miptree_set_image_offset(tex, 0, 0, 0, 0);
|
||||
|
||||
pipe_buffer_reference(&tex->buffer, buffer);
|
||||
tex->buffer = buffer;
|
||||
|
||||
return &tex->base;
|
||||
}
|
||||
|
||||
void
|
||||
i915_init_texture_functions(struct i915_context *i915)
|
||||
{
|
||||
// i915->pipe.texture_update = i915_texture_update;
|
||||
}
|
||||
|
||||
static void
|
||||
i915_tex_surface_destroy(struct pipe_surface *surf)
|
||||
{
|
||||
pipe_texture_reference(&surf->texture, NULL);
|
||||
FREE(surf);
|
||||
}
|
||||
|
||||
void
|
||||
i915_init_screen_texture_functions(struct pipe_screen *screen)
|
||||
{
|
||||
screen->texture_create = i915_texture_create;
|
||||
screen->texture_destroy = i915_texture_destroy;
|
||||
screen->get_tex_surface = i915_get_tex_surface;
|
||||
screen->texture_blanket = i915_texture_blanket;
|
||||
screen->tex_surface_destroy = i915_tex_surface_destroy;
|
||||
}
|
||||
|
||||
boolean i915_get_texture_buffer( struct pipe_texture *texture,
|
||||
struct pipe_buffer **buf,
|
||||
unsigned *stride )
|
||||
boolean
|
||||
i915_get_texture_buffer_intel(struct pipe_texture *texture,
|
||||
struct intel_buffer **buffer,
|
||||
unsigned *stride)
|
||||
{
|
||||
struct i915_texture *tex = (struct i915_texture *)texture;
|
||||
|
||||
if (!tex)
|
||||
if (!texture)
|
||||
return FALSE;
|
||||
|
||||
pipe_buffer_reference(buf, tex->buffer);
|
||||
|
||||
if (stride)
|
||||
*stride = tex->stride;
|
||||
*stride = tex->stride;
|
||||
*buffer = tex->buffer;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -28,16 +28,9 @@
|
|||
#ifndef I915_TEXTURE_H
|
||||
#define I915_TEXTURE_H
|
||||
|
||||
struct i915_context;
|
||||
struct pipe_screen;
|
||||
|
||||
struct i915_screen;
|
||||
|
||||
extern void
|
||||
i915_init_texture_functions(struct i915_context *i915);
|
||||
|
||||
|
||||
extern void
|
||||
i915_init_screen_texture_functions(struct pipe_screen *screen);
|
||||
|
||||
i915_init_screen_texture_functions(struct i915_screen *is);
|
||||
|
||||
#endif /* I915_TEXTURE_H */
|
||||
|
|
|
@ -1,144 +0,0 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* This is the interface that i915simple requires any window system
|
||||
* hosting it to implement. This is the only include file in i915simple
|
||||
* which is public.
|
||||
*
|
||||
* This isn't currently true as the winsys needs i915_batchbuffer.h
|
||||
*/
|
||||
|
||||
#ifndef I915_WINSYS_H
|
||||
#define I915_WINSYS_H
|
||||
|
||||
|
||||
#include "pipe/p_defines.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* Pipe drivers are independent of both GL and the window system.
|
||||
* The window system provides a buffer manager and a set of additional
|
||||
* hooks for things like command buffer submission, etc.
|
||||
*
|
||||
* There clearly has to be some agreement between the window system
|
||||
* driver and the hardware driver about the format of command buffers,
|
||||
* etc.
|
||||
*/
|
||||
|
||||
struct i915_batchbuffer;
|
||||
struct pipe_texture;
|
||||
struct pipe_buffer;
|
||||
struct pipe_fence_handle;
|
||||
struct pipe_winsys;
|
||||
struct pipe_screen;
|
||||
|
||||
|
||||
/**
|
||||
* Additional winsys interface for i915simple.
|
||||
*
|
||||
* It is an over-simple batchbuffer mechanism. Will want to improve the
|
||||
* performance of this, perhaps based on the cmdstream stuff. It
|
||||
* would be pretty impossible to implement swz on top of this
|
||||
* interface.
|
||||
*
|
||||
* Will also need additions/changes to implement static/dynamic
|
||||
* indirect state.
|
||||
*/
|
||||
struct i915_winsys {
|
||||
|
||||
void (*destroy)( struct i915_winsys *sws );
|
||||
|
||||
/**
|
||||
* Get the current batch buffer from the winsys.
|
||||
*/
|
||||
struct i915_batchbuffer *(*batch_get)( struct i915_winsys *sws );
|
||||
|
||||
/**
|
||||
* Emit a relocation to a buffer.
|
||||
*
|
||||
* Used not only when the buffer addresses are not pinned, but also to
|
||||
* ensure refered buffers will not be destroyed until the current batch
|
||||
* buffer execution is finished.
|
||||
*
|
||||
* The access flags is a combination of I915_BUFFER_ACCESS_WRITE and
|
||||
* I915_BUFFER_ACCESS_READ macros.
|
||||
*/
|
||||
void (*batch_reloc)( struct i915_winsys *sws,
|
||||
struct pipe_buffer *buf,
|
||||
unsigned access_flags,
|
||||
unsigned delta );
|
||||
|
||||
/**
|
||||
* Flush the batch.
|
||||
*/
|
||||
void (*batch_flush)( struct i915_winsys *sws,
|
||||
struct pipe_fence_handle **fence );
|
||||
};
|
||||
|
||||
#define I915_BUFFER_ACCESS_WRITE 0x1
|
||||
#define I915_BUFFER_ACCESS_READ 0x2
|
||||
|
||||
#define I915_BUFFER_USAGE_LIT_VERTEX (PIPE_BUFFER_USAGE_CUSTOM << 0)
|
||||
#define I915_BUFFER_USAGE_SCANOUT (PIPE_BUFFER_USAGE_CUSTOM << 1)
|
||||
|
||||
|
||||
/**
|
||||
* Create i915 pipe_screen.
|
||||
*/
|
||||
struct pipe_screen *i915_create_screen( struct pipe_winsys *winsys,
|
||||
uint pci_id );
|
||||
|
||||
/**
|
||||
* Create a i915 pipe_context.
|
||||
*/
|
||||
struct pipe_context *i915_create_context( struct pipe_screen *screen,
|
||||
struct pipe_winsys *winsys,
|
||||
struct i915_winsys *i915 );
|
||||
|
||||
/**
|
||||
* Used for the winsys to get the buffer used for a texture
|
||||
* and also the stride used for the texture.
|
||||
*
|
||||
* Buffer is referenced for you so you need to unref after use.
|
||||
*
|
||||
* This is needed for example kms.
|
||||
*/
|
||||
boolean i915_get_texture_buffer( struct pipe_texture *texture,
|
||||
struct pipe_buffer **buf,
|
||||
unsigned *stride );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,87 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef INTEL_BATCH_H
|
||||
#define INTEL_BATCH_H
|
||||
|
||||
#include "intel_winsys.h"
|
||||
|
||||
static INLINE boolean
|
||||
intel_batchbuffer_check(struct intel_batchbuffer *batch,
|
||||
size_t dwords,
|
||||
size_t relocs)
|
||||
{
|
||||
return dwords * 4 <= batch->size - (batch->ptr - batch->map) &&
|
||||
relocs <= (batch->max_relocs - batch->relocs);
|
||||
}
|
||||
|
||||
static INLINE size_t
|
||||
intel_batchbuffer_space(struct intel_batchbuffer *batch)
|
||||
{
|
||||
return batch->size - (batch->ptr - batch->map);
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
intel_batchbuffer_dword(struct intel_batchbuffer *batch,
|
||||
unsigned dword)
|
||||
{
|
||||
if (intel_batchbuffer_space(batch) < 4)
|
||||
return;
|
||||
|
||||
*(unsigned *)batch->ptr = dword;
|
||||
batch->ptr += 4;
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
intel_batchbuffer_write(struct intel_batchbuffer *batch,
|
||||
void *data,
|
||||
size_t size)
|
||||
{
|
||||
if (intel_batchbuffer_space(batch) < size)
|
||||
return;
|
||||
|
||||
memcpy(data, batch->ptr, size);
|
||||
batch->ptr += size;
|
||||
}
|
||||
|
||||
static INLINE int
|
||||
intel_batchbuffer_reloc(struct intel_batchbuffer *batch,
|
||||
struct intel_buffer *buffer,
|
||||
enum intel_buffer_usage usage,
|
||||
size_t offset)
|
||||
{
|
||||
return batch->iws->batchbuffer_reloc(batch, buffer, usage, offset);
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
intel_batchbuffer_flush(struct intel_batchbuffer *batch,
|
||||
struct pipe_fence_handle **fence)
|
||||
{
|
||||
batch->iws->batchbuffer_flush(batch, fence);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,219 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright © 2009 Jakob Bornecrantz
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef INTEL_WINSYS_H
|
||||
#define INTEL_WINSYS_H
|
||||
|
||||
#include "pipe/p_compiler.h"
|
||||
|
||||
struct intel_winsys;
|
||||
struct intel_buffer;
|
||||
struct intel_batchbuffer;
|
||||
struct pipe_texture;
|
||||
struct pipe_fence_handle;
|
||||
|
||||
enum intel_buffer_usage
|
||||
{
|
||||
/* use on textures */
|
||||
INTEL_USAGE_RENDER = 0x01,
|
||||
INTEL_USAGE_SAMPLER = 0x02,
|
||||
INTEL_USAGE_2D_TARGET = 0x04,
|
||||
INTEL_USAGE_2D_SOURCE = 0x08,
|
||||
/* use on vertex */
|
||||
INTEL_USAGE_VERTEX = 0x10,
|
||||
};
|
||||
|
||||
enum intel_buffer_type
|
||||
{
|
||||
INTEL_NEW_TEXTURE,
|
||||
INTEL_NEW_SCANOUT, /**< a texture used for scanning out from */
|
||||
INTEL_NEW_VERTEX,
|
||||
};
|
||||
|
||||
enum intel_buffer_tile
|
||||
{
|
||||
INTEL_TILE_NONE,
|
||||
INTEL_TILE_X,
|
||||
INTEL_TILE_Y,
|
||||
};
|
||||
|
||||
struct intel_batchbuffer {
|
||||
|
||||
struct intel_winsys *iws;
|
||||
|
||||
/**
|
||||
* Values exported to speed up the writing the batchbuffer,
|
||||
* instead of having to go trough a accesor function for
|
||||
* each dword written.
|
||||
*/
|
||||
/*{@*/
|
||||
uint8_t *map;
|
||||
uint8_t *ptr;
|
||||
size_t size;
|
||||
|
||||
size_t relocs;
|
||||
size_t max_relocs;
|
||||
/*@}*/
|
||||
};
|
||||
|
||||
struct intel_winsys {
|
||||
|
||||
/**
|
||||
* Batchbuffer functions.
|
||||
*/
|
||||
/*@{*/
|
||||
/**
|
||||
* Create a new batchbuffer.
|
||||
*/
|
||||
struct intel_batchbuffer *(*batchbuffer_create)(struct intel_winsys *iws);
|
||||
|
||||
/**
|
||||
* Emit a relocation to a buffer.
|
||||
* Target position in batchbuffer is the same as ptr.
|
||||
*
|
||||
* @batch
|
||||
* @reloc buffer address to be inserted into target.
|
||||
* @usage how is the hardware going to use the buffer.
|
||||
* @offset add this to the reloc buffers address
|
||||
* @target buffer where to write the address, null for batchbuffer.
|
||||
*/
|
||||
int (*batchbuffer_reloc)(struct intel_batchbuffer *batch,
|
||||
struct intel_buffer *reloc,
|
||||
enum intel_buffer_usage usage,
|
||||
unsigned offset);
|
||||
|
||||
/**
|
||||
* Flush a bufferbatch.
|
||||
*/
|
||||
void (*batchbuffer_flush)(struct intel_batchbuffer *batch,
|
||||
struct pipe_fence_handle **fence);
|
||||
|
||||
/**
|
||||
* Destroy a batchbuffer.
|
||||
*/
|
||||
void (*batchbuffer_destroy)(struct intel_batchbuffer *batch);
|
||||
/*@}*/
|
||||
|
||||
|
||||
/**
|
||||
* Buffer functions.
|
||||
*/
|
||||
/*@{*/
|
||||
/**
|
||||
* Create a buffer.
|
||||
*/
|
||||
struct intel_buffer *(*buffer_create)(struct intel_winsys *iws,
|
||||
unsigned size, unsigned alignment,
|
||||
enum intel_buffer_type type);
|
||||
|
||||
/**
|
||||
* Fence a buffer with a fence reg.
|
||||
* Not to be confused with pipe_fence_handle.
|
||||
*/
|
||||
int (*buffer_set_fence_reg)(struct intel_winsys *iws,
|
||||
struct intel_buffer *buffer,
|
||||
unsigned stride,
|
||||
enum intel_buffer_tile tile);
|
||||
|
||||
/**
|
||||
* Map a buffer.
|
||||
*/
|
||||
void *(*buffer_map)(struct intel_winsys *iws,
|
||||
struct intel_buffer *buffer,
|
||||
boolean write);
|
||||
|
||||
/**
|
||||
* Unmap a buffer.
|
||||
*/
|
||||
void (*buffer_unmap)(struct intel_winsys *iws,
|
||||
struct intel_buffer *buffer);
|
||||
|
||||
void (*buffer_destroy)(struct intel_winsys *iws,
|
||||
struct intel_buffer *buffer);
|
||||
/*@}*/
|
||||
|
||||
|
||||
/**
|
||||
* Fence functions.
|
||||
*/
|
||||
/*@{*/
|
||||
/**
|
||||
* Reference fence and set ptr to fence.
|
||||
*/
|
||||
void (*fence_reference)(struct intel_winsys *iws,
|
||||
struct pipe_fence_handle **ptr,
|
||||
struct pipe_fence_handle *fence);
|
||||
|
||||
/**
|
||||
* Check if a fence has finished.
|
||||
*/
|
||||
int (*fence_signalled)(struct intel_winsys *iws,
|
||||
struct pipe_fence_handle *fence);
|
||||
|
||||
/**
|
||||
* Wait on a fence to finish.
|
||||
*/
|
||||
int (*fence_finish)(struct intel_winsys *iws,
|
||||
struct pipe_fence_handle *fence);
|
||||
/*@}*/
|
||||
|
||||
|
||||
/**
|
||||
* Destroy the winsys.
|
||||
*/
|
||||
void (*destroy)(struct intel_winsys *iws);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Create i915 pipe_screen.
|
||||
*/
|
||||
struct pipe_screen *i915_create_screen(struct intel_winsys *iws, unsigned pci_id);
|
||||
|
||||
/**
|
||||
* Create a i915 pipe_context.
|
||||
*/
|
||||
struct pipe_context *i915_create_context(struct pipe_screen *screen);
|
||||
|
||||
/**
|
||||
* Get the intel_winsys buffer backing the texture.
|
||||
*
|
||||
* TODO UGLY
|
||||
*/
|
||||
boolean i915_get_texture_buffer_intel(struct pipe_texture *texture,
|
||||
struct intel_buffer **buffer,
|
||||
unsigned *stride);
|
||||
|
||||
/**
|
||||
* Wrap a intel_winsys buffer with a texture blanket.
|
||||
*
|
||||
* TODO UGLY
|
||||
*/
|
||||
struct pipe_texture * i915_texture_blanket_intel(struct pipe_screen *screen,
|
||||
struct pipe_texture *tmplt,
|
||||
unsigned pitch,
|
||||
struct intel_buffer *buffer);
|
||||
|
||||
#endif
|
|
@ -2,8 +2,12 @@ Import('*')
|
|||
|
||||
env = env.Clone()
|
||||
|
||||
env.Tool('llvm')
|
||||
if 'LLVM_VERSION' not in env:
|
||||
print 'warning: LLVM not found: not building llvmpipe'
|
||||
Return()
|
||||
|
||||
env.Tool('udis86')
|
||||
env.ParseConfig('llvm-config --cppflags')
|
||||
|
||||
llvmpipe = env.ConvenienceLibrary(
|
||||
target = 'llvmpipe',
|
||||
|
@ -57,8 +61,6 @@ llvmpipe = env.ConvenienceLibrary(
|
|||
|
||||
env = env.Clone()
|
||||
|
||||
env['LINK'] = env['CXX']
|
||||
env.ParseConfig('llvm-config --libs jit interpreter nativecodegen bitwriter')
|
||||
env.Prepend(LIBS = [llvmpipe] + auxiliaries)
|
||||
|
||||
env.Program(
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include "lp_bld_type.h"
|
||||
#include "lp_bld_const.h"
|
||||
#include "lp_bld_intr.h"
|
||||
#include "lp_bld_logic.h"
|
||||
#include "lp_bld_arit.h"
|
||||
|
||||
|
||||
|
@ -98,11 +99,8 @@ lp_build_min_simple(struct lp_build_context *bld,
|
|||
if(intrinsic)
|
||||
return lp_build_intrinsic_binary(bld->builder, intrinsic, lp_build_vec_type(bld->type), a, b);
|
||||
|
||||
if(type.floating)
|
||||
cond = LLVMBuildFCmp(bld->builder, LLVMRealULT, a, b, "");
|
||||
else
|
||||
cond = LLVMBuildICmp(bld->builder, type.sign ? LLVMIntSLT : LLVMIntULT, a, b, "");
|
||||
return LLVMBuildSelect(bld->builder, cond, a, b, "");
|
||||
cond = lp_build_cmp(bld, PIPE_FUNC_LESS, a, b);
|
||||
return lp_build_select(bld, cond, a, b);
|
||||
}
|
||||
|
||||
|
||||
|
@ -149,11 +147,8 @@ lp_build_max_simple(struct lp_build_context *bld,
|
|||
if(intrinsic)
|
||||
return lp_build_intrinsic_binary(bld->builder, intrinsic, lp_build_vec_type(bld->type), a, b);
|
||||
|
||||
if(type.floating)
|
||||
cond = LLVMBuildFCmp(bld->builder, LLVMRealULT, a, b, "");
|
||||
else
|
||||
cond = LLVMBuildICmp(bld->builder, type.sign ? LLVMIntSLT : LLVMIntULT, a, b, "");
|
||||
return LLVMBuildSelect(bld->builder, cond, b, a, "");
|
||||
cond = lp_build_cmp(bld, PIPE_FUNC_GREATER, a, b);
|
||||
return lp_build_select(bld, cond, a, b);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
*/
|
||||
|
||||
|
||||
#include "pipe/p_defines.h"
|
||||
#include "lp_bld_type.h"
|
||||
#include "lp_bld_const.h"
|
||||
#include "lp_bld_intr.h"
|
||||
|
@ -52,6 +51,8 @@ lp_build_cmp(struct lp_build_context *bld,
|
|||
LLVMValueRef zeros = LLVMConstNull(int_vec_type);
|
||||
LLVMValueRef ones = LLVMConstAllOnes(int_vec_type);
|
||||
LLVMValueRef cond;
|
||||
LLVMValueRef res;
|
||||
unsigned i;
|
||||
|
||||
if(func == PIPE_FUNC_NEVER)
|
||||
return zeros;
|
||||
|
@ -68,7 +69,6 @@ lp_build_cmp(struct lp_build_context *bld,
|
|||
LLVMValueRef args[3];
|
||||
unsigned cc;
|
||||
boolean swap;
|
||||
LLVMValueRef res;
|
||||
|
||||
swap = FALSE;
|
||||
switch(func) {
|
||||
|
@ -219,7 +219,28 @@ lp_build_cmp(struct lp_build_context *bld,
|
|||
assert(0);
|
||||
return bld->undef;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* XXX: Although valid IR, no LLVM target currently support this */
|
||||
cond = LLVMBuildFCmp(bld->builder, op, a, b, "");
|
||||
res = LLVMBuildSelect(bld->builder, cond, ones, zeros, "");
|
||||
#else
|
||||
debug_printf("%s: warning: using slow element-wise vector comparison\n",
|
||||
__FUNCTION__);
|
||||
res = LLVMGetUndef(int_vec_type);
|
||||
for(i = 0; i < type.length; ++i) {
|
||||
LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
|
||||
cond = LLVMBuildFCmp(bld->builder, op,
|
||||
LLVMBuildExtractElement(bld->builder, a, index, ""),
|
||||
LLVMBuildExtractElement(bld->builder, b, index, ""),
|
||||
"");
|
||||
cond = LLVMBuildSelect(bld->builder, cond,
|
||||
LLVMConstExtractElement(ones, index),
|
||||
LLVMConstExtractElement(zeros, index),
|
||||
"");
|
||||
res = LLVMBuildInsertElement(bld->builder, res, cond, index, "");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
LLVMIntPredicate op;
|
||||
|
@ -246,10 +267,31 @@ lp_build_cmp(struct lp_build_context *bld,
|
|||
assert(0);
|
||||
return bld->undef;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* XXX: Although valid IR, no LLVM target currently support this */
|
||||
cond = LLVMBuildICmp(bld->builder, op, a, b, "");
|
||||
res = LLVMBuildSelect(bld->builder, cond, ones, zeros, "");
|
||||
#else
|
||||
debug_printf("%s: warning: using slow element-wise vector comparison\n",
|
||||
__FUNCTION__);
|
||||
res = LLVMGetUndef(int_vec_type);
|
||||
for(i = 0; i < type.length; ++i) {
|
||||
LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
|
||||
cond = LLVMBuildICmp(bld->builder, op,
|
||||
LLVMBuildExtractElement(bld->builder, a, index, ""),
|
||||
LLVMBuildExtractElement(bld->builder, b, index, ""),
|
||||
"");
|
||||
cond = LLVMBuildSelect(bld->builder, cond,
|
||||
LLVMConstExtractElement(ones, index),
|
||||
LLVMConstExtractElement(zeros, index),
|
||||
"");
|
||||
res = LLVMBuildInsertElement(bld->builder, res, cond, index, "");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return LLVMBuildSelect(bld->builder, cond, ones, zeros, "");
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -39,6 +39,8 @@
|
|||
|
||||
#include <llvm-c/Core.h>
|
||||
|
||||
#include "pipe/p_defines.h" /* For PIPE_FUNC_xxx */
|
||||
|
||||
|
||||
union lp_type type;
|
||||
struct lp_build_context;
|
||||
|
|
|
@ -687,10 +687,6 @@ emit_instruction(
|
|||
return 0;
|
||||
break;
|
||||
|
||||
case TGSI_OPCODE_CND0:
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case TGSI_OPCODE_DP2A:
|
||||
tmp0 = emit_fetch( bld, inst, 0, CHAN_X ); /* xmm0 = src[0].x */
|
||||
tmp1 = emit_fetch( bld, inst, 1, CHAN_X ); /* xmm1 = src[1].x */
|
||||
|
|
|
@ -0,0 +1,150 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2009 VMware, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_math.h"
|
||||
|
||||
#include "lp_winsys.h"
|
||||
#include "lp_screen.h"
|
||||
#include "lp_texture.h"
|
||||
#include "lp_buffer.h"
|
||||
|
||||
|
||||
static void *
|
||||
llvmpipe_buffer_map(struct pipe_screen *screen,
|
||||
struct pipe_buffer *buf,
|
||||
unsigned flags)
|
||||
{
|
||||
struct llvmpipe_buffer *llvmpipe_buf = llvmpipe_buffer(buf);
|
||||
return llvmpipe_buf->data;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
llvmpipe_buffer_unmap(struct pipe_screen *screen,
|
||||
struct pipe_buffer *buf)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
llvmpipe_buffer_destroy(struct pipe_buffer *buf)
|
||||
{
|
||||
struct llvmpipe_buffer *sbuf = llvmpipe_buffer(buf);
|
||||
|
||||
if (!sbuf->userBuffer)
|
||||
align_free(sbuf->data);
|
||||
|
||||
FREE(sbuf);
|
||||
}
|
||||
|
||||
|
||||
static struct pipe_buffer *
|
||||
llvmpipe_buffer_create(struct pipe_screen *screen,
|
||||
unsigned alignment,
|
||||
unsigned usage,
|
||||
unsigned size)
|
||||
{
|
||||
struct llvmpipe_buffer *buffer = CALLOC_STRUCT(llvmpipe_buffer);
|
||||
|
||||
pipe_reference_init(&buffer->base.reference, 1);
|
||||
buffer->base.screen = screen;
|
||||
buffer->base.alignment = MAX2(alignment, 16);
|
||||
buffer->base.usage = usage;
|
||||
buffer->base.size = size;
|
||||
|
||||
buffer->data = align_malloc(size, alignment);
|
||||
|
||||
return &buffer->base;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create buffer which wraps user-space data.
|
||||
*/
|
||||
static struct pipe_buffer *
|
||||
llvmpipe_user_buffer_create(struct pipe_screen *screen,
|
||||
void *ptr,
|
||||
unsigned bytes)
|
||||
{
|
||||
struct llvmpipe_buffer *buffer;
|
||||
|
||||
buffer = CALLOC_STRUCT(llvmpipe_buffer);
|
||||
if(!buffer)
|
||||
return NULL;
|
||||
|
||||
pipe_reference_init(&buffer->base.reference, 1);
|
||||
buffer->base.screen = screen;
|
||||
buffer->base.size = bytes;
|
||||
buffer->userBuffer = TRUE;
|
||||
buffer->data = ptr;
|
||||
|
||||
return &buffer->base;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
llvmpipe_fence_reference(struct pipe_screen *screen,
|
||||
struct pipe_fence_handle **ptr,
|
||||
struct pipe_fence_handle *fence)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
llvmpipe_fence_signalled(struct pipe_screen *screen,
|
||||
struct pipe_fence_handle *fence,
|
||||
unsigned flag)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
llvmpipe_fence_finish(struct pipe_screen *screen,
|
||||
struct pipe_fence_handle *fence,
|
||||
unsigned flag)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
llvmpipe_init_screen_buffer_funcs(struct pipe_screen *screen)
|
||||
{
|
||||
screen->buffer_create = llvmpipe_buffer_create;
|
||||
screen->user_buffer_create = llvmpipe_user_buffer_create;
|
||||
screen->buffer_map = llvmpipe_buffer_map;
|
||||
screen->buffer_unmap = llvmpipe_buffer_unmap;
|
||||
screen->buffer_destroy = llvmpipe_buffer_destroy;
|
||||
|
||||
screen->fence_reference = llvmpipe_fence_reference;
|
||||
screen->fence_signalled = llvmpipe_fence_signalled;
|
||||
screen->fence_finish = llvmpipe_fence_finish;
|
||||
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2009 VMware, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef LP_BUFFER_H
|
||||
#define LP_BUFFER_H
|
||||
|
||||
#include "pipe/p_compiler.h"
|
||||
#include "pipe/p_state.h"
|
||||
|
||||
|
||||
struct llvmpipe_buffer
|
||||
{
|
||||
struct pipe_buffer base;
|
||||
boolean userBuffer; /** Is this a user-space buffer? */
|
||||
void *data;
|
||||
};
|
||||
|
||||
|
||||
/** Cast wrapper */
|
||||
static INLINE struct llvmpipe_buffer *
|
||||
llvmpipe_buffer( struct pipe_buffer *buf )
|
||||
{
|
||||
return (struct llvmpipe_buffer *)buf;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
llvmpipe_init_screen_buffer_funcs(struct pipe_screen *screen);
|
||||
|
||||
|
||||
#endif /* LP_BUFFER_H */
|
|
@ -22,4 +22,15 @@ nouveau_bo(struct pipe_buffer *pb)
|
|||
int nouveau_screen_init(struct nouveau_screen *, struct nouveau_device *);
|
||||
void nouveau_screen_fini(struct nouveau_screen *);
|
||||
|
||||
struct nouveau_miptree {
|
||||
struct pipe_texture base;
|
||||
struct nouveau_bo *bo;
|
||||
};
|
||||
|
||||
static inline struct nouveau_miptree *
|
||||
nouveau_miptree(struct pipe_texture *pt)
|
||||
{
|
||||
return (struct nouveau_miptree *)pt;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -75,9 +75,7 @@ struct nv50_miptree_level {
|
|||
};
|
||||
|
||||
struct nv50_miptree {
|
||||
struct pipe_texture base;
|
||||
|
||||
struct nouveau_bo *bo;
|
||||
struct nouveau_miptree base;
|
||||
|
||||
struct nv50_miptree_level level[PIPE_MAX_TEXTURE_LEVELS];
|
||||
int image_nr;
|
||||
|
|
|
@ -31,15 +31,15 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp)
|
|||
{
|
||||
struct nouveau_device *dev = nouveau_screen(pscreen)->device;
|
||||
struct nv50_miptree *mt = CALLOC_STRUCT(nv50_miptree);
|
||||
struct pipe_texture *pt = &mt->base;
|
||||
struct pipe_texture *pt = &mt->base.base;
|
||||
unsigned width = tmp->width[0], height = tmp->height[0];
|
||||
unsigned depth = tmp->depth[0];
|
||||
uint32_t tile_mode, tile_flags, tile_h;
|
||||
int ret, i, l;
|
||||
|
||||
mt->base = *tmp;
|
||||
pipe_reference_init(&mt->base.reference, 1);
|
||||
mt->base.screen = pscreen;
|
||||
*pt = *tmp;
|
||||
pipe_reference_init(&pt->reference, 1);
|
||||
pt->screen = pscreen;
|
||||
|
||||
switch (pt->format) {
|
||||
case PIPE_FORMAT_Z32_FLOAT:
|
||||
|
@ -116,13 +116,14 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp)
|
|||
}
|
||||
|
||||
ret = nouveau_bo_new_tile(dev, NOUVEAU_BO_VRAM, 256, mt->total_size,
|
||||
mt->level[0].tile_mode, tile_flags, &mt->bo);
|
||||
mt->level[0].tile_mode, tile_flags,
|
||||
&mt->base.bo);
|
||||
if (ret) {
|
||||
FREE(mt);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &mt->base;
|
||||
return pt;
|
||||
}
|
||||
|
||||
static struct pipe_texture *
|
||||
|
@ -141,15 +142,15 @@ nv50_miptree_blanket(struct pipe_screen *pscreen, const struct pipe_texture *pt,
|
|||
if (!mt)
|
||||
return NULL;
|
||||
|
||||
mt->base = *pt;
|
||||
pipe_reference_init(&mt->base.reference, 1);
|
||||
mt->base.screen = pscreen;
|
||||
mt->base.base = *pt;
|
||||
pipe_reference_init(&mt->base.base.reference, 1);
|
||||
mt->base.base.screen = pscreen;
|
||||
mt->image_nr = 1;
|
||||
mt->level[0].pitch = *stride;
|
||||
mt->level[0].image_offset = CALLOC(1, sizeof(unsigned));
|
||||
|
||||
nouveau_bo_ref(bo, &mt->bo);
|
||||
return &mt->base;
|
||||
nouveau_bo_ref(bo, &mt->base.bo);
|
||||
return &mt->base.base;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -157,7 +158,7 @@ nv50_miptree_destroy(struct pipe_texture *pt)
|
|||
{
|
||||
struct nv50_miptree *mt = nv50_miptree(pt);
|
||||
|
||||
nouveau_bo_ref(NULL, &mt->bo);
|
||||
nouveau_bo_ref(NULL, &mt->base.bo);
|
||||
FREE(mt);
|
||||
}
|
||||
|
||||
|
|
|
@ -1106,10 +1106,10 @@ convert_to_long(struct nv50_pc *pc, struct nv50_program_exec *e)
|
|||
m = 0xffff7fff;
|
||||
break;
|
||||
case 0x8:
|
||||
/* INTERP */
|
||||
m = ~0x02000000;
|
||||
if (e->inst[0] & 0x02000000)
|
||||
q = 0x00020000;
|
||||
/* INTERP (move centroid, perspective and flat bits) */
|
||||
m = ~0x03000100;
|
||||
q = (e->inst[0] & (3 << 24)) >> (24 - 16);
|
||||
q |= (e->inst[0] & (1 << 8)) << (18 - 8);
|
||||
break;
|
||||
case 0x9:
|
||||
/* RCP */
|
||||
|
@ -1495,6 +1495,7 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok)
|
|||
}
|
||||
break;
|
||||
case TGSI_OPCODE_MOV:
|
||||
case TGSI_OPCODE_SWZ:
|
||||
for (c = 0; c < 4; c++) {
|
||||
if (!(mask & (1 << c)))
|
||||
continue;
|
||||
|
|
|
@ -33,7 +33,7 @@ nv50_state_validate_fb(struct nv50_context *nv50)
|
|||
|
||||
for (i = 0; i < fb->nr_cbufs; i++) {
|
||||
struct pipe_texture *pt = fb->cbufs[i]->texture;
|
||||
struct nouveau_bo *bo = nv50_miptree(pt)->bo;
|
||||
struct nouveau_bo *bo = nv50_miptree(pt)->base.bo;
|
||||
|
||||
if (!gw) {
|
||||
w = fb->cbufs[i]->width;
|
||||
|
@ -75,7 +75,7 @@ nv50_state_validate_fb(struct nv50_context *nv50)
|
|||
|
||||
if (fb->zsbuf) {
|
||||
struct pipe_texture *pt = fb->zsbuf->texture;
|
||||
struct nouveau_bo *bo = nv50_miptree(pt)->bo;
|
||||
struct nouveau_bo *bo = nv50_miptree(pt)->base.bo;
|
||||
|
||||
if (!gw) {
|
||||
w = fb->zsbuf->width;
|
||||
|
|
|
@ -53,7 +53,7 @@ nv50_surface_set(struct nv50_screen *screen, struct pipe_surface *ps, int dst)
|
|||
struct nv50_miptree *mt = nv50_miptree(ps->texture);
|
||||
struct nouveau_channel *chan = screen->eng2d->channel;
|
||||
struct nouveau_grobj *eng2d = screen->eng2d;
|
||||
struct nouveau_bo *bo = nv50_miptree(ps->texture)->bo;
|
||||
struct nouveau_bo *bo = nv50_miptree(ps->texture)->base.bo;
|
||||
int format, mthd = dst ? NV50_2D_DST_FORMAT : NV50_2D_SRC_FORMAT;
|
||||
int flags = NOUVEAU_BO_VRAM | (dst ? NOUVEAU_BO_WR : NOUVEAU_BO_RD);
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ static int
|
|||
nv50_tex_construct(struct nv50_context *nv50, struct nouveau_stateobj *so,
|
||||
struct nv50_miptree *mt, int unit)
|
||||
{
|
||||
switch (mt->base.format) {
|
||||
switch (mt->base.base.format) {
|
||||
case PIPE_FORMAT_A8R8G8B8_UNORM:
|
||||
so_data(so, NV50TIC_0_0_MAPA_C3 | NV50TIC_0_0_TYPEA_UNORM |
|
||||
NV50TIC_0_0_MAPR_C2 | NV50TIC_0_0_TYPER_UNORM |
|
||||
|
@ -118,18 +118,18 @@ nv50_tex_construct(struct nv50_context *nv50, struct nouveau_stateobj *so,
|
|||
return 1;
|
||||
}
|
||||
|
||||
so_reloc(so, mt->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_LOW |
|
||||
so_reloc(so, mt->base.bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_LOW |
|
||||
NOUVEAU_BO_RD, 0, 0);
|
||||
if (nv50->sampler[unit]->normalized)
|
||||
so_data (so, 0xd0005000 | mt->bo->tile_mode << 22);
|
||||
so_data (so, 0xd0005000 | mt->base.bo->tile_mode << 22);
|
||||
else
|
||||
so_data (so, 0x5001d000 | mt->bo->tile_mode << 22);
|
||||
so_data (so, 0x5001d000 | mt->base.bo->tile_mode << 22);
|
||||
so_data (so, 0x00300000);
|
||||
so_data (so, mt->base.width[0]);
|
||||
so_data (so, (mt->base.last_level << 28) |
|
||||
(mt->base.depth[0] << 16) | mt->base.height[0]);
|
||||
so_data (so, mt->base.base.width[0]);
|
||||
so_data (so, (mt->base.base.last_level << 28) |
|
||||
(mt->base.base.depth[0] << 16) | mt->base.base.height[0]);
|
||||
so_data (so, 0x03000000);
|
||||
so_data (so, mt->base.last_level << 4);
|
||||
so_data (so, mt->base.base.last_level << 4);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -148,8 +148,8 @@ nv50_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
|
|||
tx->base.usage = usage;
|
||||
|
||||
tx->level_pitch = lvl->pitch;
|
||||
tx->level_width = mt->base.width[level];
|
||||
tx->level_height = mt->base.height[level];
|
||||
tx->level_width = mt->base.base.width[level];
|
||||
tx->level_height = mt->base.base.height[level];
|
||||
tx->level_offset = lvl->image_offset[image];
|
||||
tx->level_tiling = lvl->tile_mode;
|
||||
tx->level_x = x;
|
||||
|
@ -162,7 +162,7 @@ nv50_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
|
|||
}
|
||||
|
||||
if (usage != PIPE_TRANSFER_WRITE) {
|
||||
nv50_transfer_rect_m2mf(pscreen, mt->bo, tx->level_offset,
|
||||
nv50_transfer_rect_m2mf(pscreen, mt->base.bo, tx->level_offset,
|
||||
tx->level_pitch, tx->level_tiling,
|
||||
x, y,
|
||||
tx->level_width, tx->level_height,
|
||||
|
@ -188,7 +188,7 @@ nv50_transfer_del(struct pipe_transfer *ptx)
|
|||
nv50_transfer_rect_m2mf(pscreen, tx->bo, 0, tx->base.stride,
|
||||
tx->bo->tile_mode, 0, 0,
|
||||
tx->base.width, tx->base.height,
|
||||
mt->bo, tx->level_offset,
|
||||
mt->base.bo, tx->level_offset,
|
||||
tx->level_pitch, tx->level_tiling,
|
||||
tx->level_x, tx->level_y,
|
||||
tx->level_width, tx->level_height,
|
||||
|
|
|
@ -178,7 +178,7 @@ nv50_draw_elements_inline_u08(struct nv50_context *nv50, uint8_t *map,
|
|||
|
||||
BEGIN_RING(chan, tesla, 0x400015f0, nr >> 1);
|
||||
for (i = 0; i < nr; i += 2)
|
||||
OUT_RING (chan, (map[1] << 16) | map[0]);
|
||||
OUT_RING (chan, (map[i + 1] << 16) | map[i]);
|
||||
|
||||
count -= nr;
|
||||
map += nr;
|
||||
|
@ -207,7 +207,7 @@ nv50_draw_elements_inline_u16(struct nv50_context *nv50, uint16_t *map,
|
|||
|
||||
BEGIN_RING(chan, tesla, 0x400015f0, nr >> 1);
|
||||
for (i = 0; i < nr; i += 2)
|
||||
OUT_RING (chan, (map[1] << 16) | map[0]);
|
||||
OUT_RING (chan, (map[i + 1] << 16) | map[i]);
|
||||
|
||||
count -= nr;
|
||||
map += nr;
|
||||
|
@ -313,18 +313,18 @@ nv50_vbo_static_attrib(struct nv50_context *nv50, unsigned attrib,
|
|||
so_data (so, fui(v[3]));
|
||||
break;
|
||||
case 3:
|
||||
so_method(so, tesla, NV50TCL_VTX_ATTR_3F_X(attrib), 4);
|
||||
so_method(so, tesla, NV50TCL_VTX_ATTR_3F_X(attrib), 3);
|
||||
so_data (so, fui(v[0]));
|
||||
so_data (so, fui(v[1]));
|
||||
so_data (so, fui(v[2]));
|
||||
break;
|
||||
case 2:
|
||||
so_method(so, tesla, NV50TCL_VTX_ATTR_2F_X(attrib), 4);
|
||||
so_method(so, tesla, NV50TCL_VTX_ATTR_2F_X(attrib), 2);
|
||||
so_data (so, fui(v[0]));
|
||||
so_data (so, fui(v[1]));
|
||||
break;
|
||||
case 1:
|
||||
so_method(so, tesla, NV50TCL_VTX_ATTR_1F(attrib), 4);
|
||||
so_method(so, tesla, NV50TCL_VTX_ATTR_1F(attrib), 1);
|
||||
so_data (so, fui(v[0]));
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -233,7 +233,8 @@ static void r300_render_draw(struct vbuf_render* render,
|
|||
OUT_CS_INDEX_RELOC(index_buffer, 0, count, RADEON_GEM_DOMAIN_GTT, 0, 0);
|
||||
END_CS; */
|
||||
|
||||
BEGIN_CS(2 + (count+1)/2);
|
||||
BEGIN_CS(4 + (count+1)/2);
|
||||
OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, count);
|
||||
OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, (count+1)/2);
|
||||
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) |
|
||||
r300render->hwprim);
|
||||
|
|
|
@ -429,6 +429,9 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state)
|
|||
|
||||
r300->rs_state = rs;
|
||||
r300->dirty_state |= R300_NEW_RASTERIZER;
|
||||
r300->dirty_state |= R300_NEW_RS_BLOCK;
|
||||
r300->dirty_state |= R300_NEW_SCISSOR;
|
||||
r300->dirty_state |= R300_NEW_VIEWPORT;
|
||||
}
|
||||
|
||||
/* Free rasterizer state. */
|
||||
|
|
|
@ -38,7 +38,9 @@ void r300_emit_invariant_state(struct r300_context* r300)
|
|||
|
||||
/*** Graphics Backend (GB) ***/
|
||||
/* Various GB enables */
|
||||
OUT_CS_REG(R300_GB_ENABLE, 0x0);
|
||||
OUT_CS_REG(R300_GB_ENABLE, R300_GB_POINT_STUFF_ENABLE |
|
||||
R300_GB_LINE_STUFF_ENABLE |
|
||||
R300_GB_TRIANGLE_STUFF_ENABLE);
|
||||
/* Subpixel multisampling for AA
|
||||
* These are commented out because glisse's CS checker doesn't like them.
|
||||
* I presume these will be re-enabled later.
|
||||
|
|
|
@ -73,9 +73,9 @@ static struct r300_rs_state rs_clear_state = {
|
|||
};
|
||||
|
||||
static struct r300_rs_block r3xx_rs_block_clear_state = {
|
||||
.ip[0] = R500_RS_SEL_S(R300_RS_SEL_K0) |
|
||||
R500_RS_SEL_T(R300_RS_SEL_K0) |
|
||||
R500_RS_SEL_R(R300_RS_SEL_K0) |
|
||||
.ip[0] = R500_RS_SEL_S(R300_RS_SEL_C0) |
|
||||
R500_RS_SEL_T(R300_RS_SEL_C0) |
|
||||
R500_RS_SEL_R(R300_RS_SEL_C0) |
|
||||
R500_RS_SEL_Q(R300_RS_SEL_K1),
|
||||
.inst[0] = R300_RS_INST_COL_CN_WRITE,
|
||||
.count = R300_IT_COUNT(0) | R300_IC_COUNT(1) | R300_HIRES_EN,
|
||||
|
|
|
@ -1277,8 +1277,10 @@ trace_context_create(struct pipe_screen *_screen,
|
|||
tr_ctx->base.set_sampler_textures = trace_context_set_sampler_textures;
|
||||
tr_ctx->base.set_vertex_buffers = trace_context_set_vertex_buffers;
|
||||
tr_ctx->base.set_vertex_elements = trace_context_set_vertex_elements;
|
||||
tr_ctx->base.surface_copy = trace_context_surface_copy;
|
||||
tr_ctx->base.surface_fill = trace_context_surface_fill;
|
||||
if (pipe->surface_copy)
|
||||
tr_ctx->base.surface_copy = trace_context_surface_copy;
|
||||
if (pipe->surface_fill)
|
||||
tr_ctx->base.surface_fill = trace_context_surface_fill;
|
||||
tr_ctx->base.clear = trace_context_clear;
|
||||
tr_ctx->base.flush = trace_context_flush;
|
||||
tr_ctx->base.is_texture_referenced = trace_is_texture_referenced;
|
||||
|
|
|
@ -184,7 +184,7 @@ union tgsi_immediate_data
|
|||
#define TGSI_OPCODE_SUB 17
|
||||
#define TGSI_OPCODE_LRP 18
|
||||
#define TGSI_OPCODE_CND 19
|
||||
#define TGSI_OPCODE_CND0 20
|
||||
/* gap */
|
||||
#define TGSI_OPCODE_DP2A 21
|
||||
/* gap */
|
||||
#define TGSI_OPCODE_FRC 24
|
||||
|
|
|
@ -189,12 +189,10 @@ dri_get_buffers(__DRIdrawablePrivate * dPriv)
|
|||
format = drawable->color_format;
|
||||
break;
|
||||
case __DRI_BUFFER_DEPTH:
|
||||
index = ST_SURFACE_DEPTH;
|
||||
format = drawable->depth_format;
|
||||
break;
|
||||
case __DRI_BUFFER_DEPTH_STENCIL:
|
||||
case __DRI_BUFFER_STENCIL:
|
||||
index = ST_SURFACE_DEPTH;
|
||||
format = drawable->stencil_format;
|
||||
format = drawable->depth_stencil_format;
|
||||
break;
|
||||
case __DRI_BUFFER_ACCUM:
|
||||
default:
|
||||
|
@ -215,6 +213,18 @@ dri_get_buffers(__DRIdrawablePrivate * dPriv)
|
|||
dri_drawable->w,
|
||||
dri_drawable->h, buffers[i].pitch);
|
||||
|
||||
switch (buffers[i].attachment) {
|
||||
case __DRI_BUFFER_FAKE_FRONT_LEFT:
|
||||
case __DRI_BUFFER_BACK_LEFT:
|
||||
drawable->color_format = surface->format;
|
||||
break;
|
||||
case __DRI_BUFFER_DEPTH:
|
||||
case __DRI_BUFFER_DEPTH_STENCIL:
|
||||
case __DRI_BUFFER_STENCIL:
|
||||
drawable->depth_stencil_format = surface->format;
|
||||
break;
|
||||
}
|
||||
|
||||
st_set_framebuffer_surface(drawable->stfb, index, surface);
|
||||
pipe_surface_reference(&surface, NULL);
|
||||
}
|
||||
|
@ -241,9 +251,7 @@ void dri2_set_tex_buffer2(__DRIcontext *pDRICtx, GLint target,
|
|||
st_get_framebuffer_surface(drawable->stfb, ST_SURFACE_FRONT_LEFT, &ps);
|
||||
|
||||
st_bind_texture_surface(ps, target == GL_TEXTURE_2D ? ST_TEXTURE_2D :
|
||||
ST_TEXTURE_RECT, 0,
|
||||
format == GLX_TEXTURE_FORMAT_RGBA_EXT ?
|
||||
PIPE_FORMAT_R8G8B8A8_UNORM : PIPE_FORMAT_R8G8B8X8_UNORM);
|
||||
ST_TEXTURE_RECT, 0, drawable->color_format);
|
||||
}
|
||||
|
||||
void dri2_set_tex_buffer(__DRIcontext *pDRICtx, GLint target,
|
||||
|
@ -311,43 +319,31 @@ dri_create_buffer(__DRIscreenPrivate * sPriv,
|
|||
switch(visual->depthBits) {
|
||||
default:
|
||||
case 0:
|
||||
drawable->depth_format = PIPE_FORMAT_NONE;
|
||||
drawable->depth_stencil_format = PIPE_FORMAT_NONE;
|
||||
break;
|
||||
case 16:
|
||||
drawable->depth_format = PIPE_FORMAT_Z16_UNORM;
|
||||
drawable->depth_stencil_format = PIPE_FORMAT_Z16_UNORM;
|
||||
break;
|
||||
case 24:
|
||||
if (visual->stencilBits == 0) {
|
||||
drawable->depth_format = (screen->d_depth_bits_last) ?
|
||||
drawable->depth_stencil_format = (screen->d_depth_bits_last) ?
|
||||
PIPE_FORMAT_X8Z24_UNORM:
|
||||
PIPE_FORMAT_Z24X8_UNORM;
|
||||
} else {
|
||||
drawable->depth_format = (screen->sd_depth_bits_last) ?
|
||||
drawable->depth_stencil_format = (screen->sd_depth_bits_last) ?
|
||||
PIPE_FORMAT_S8Z24_UNORM:
|
||||
PIPE_FORMAT_Z24S8_UNORM;
|
||||
}
|
||||
break;
|
||||
case 32:
|
||||
drawable->depth_format = PIPE_FORMAT_Z32_UNORM;
|
||||
break;
|
||||
}
|
||||
|
||||
switch(visual->stencilBits) {
|
||||
default:
|
||||
case 0:
|
||||
drawable->stencil_format = PIPE_FORMAT_NONE;
|
||||
break;
|
||||
case 8:
|
||||
drawable->stencil_format = (screen->sd_depth_bits_last) ?
|
||||
PIPE_FORMAT_S8Z24_UNORM:
|
||||
PIPE_FORMAT_Z24S8_UNORM;
|
||||
drawable->depth_stencil_format = PIPE_FORMAT_Z32_UNORM;
|
||||
break;
|
||||
}
|
||||
|
||||
drawable->stfb = st_create_framebuffer(visual,
|
||||
drawable->color_format,
|
||||
drawable->depth_format,
|
||||
drawable->stencil_format,
|
||||
drawable->depth_stencil_format,
|
||||
drawable->depth_stencil_format,
|
||||
dPriv->w,
|
||||
dPriv->h, (void *)drawable);
|
||||
if (drawable->stfb == NULL)
|
||||
|
@ -366,9 +362,11 @@ dri_create_buffer(__DRIscreenPrivate * sPriv,
|
|||
drawable->attachments[i++] = __DRI_BUFFER_BACK_LEFT;
|
||||
else
|
||||
drawable->attachments[i++] = __DRI_BUFFER_FAKE_FRONT_LEFT;
|
||||
if (visual->depthBits)
|
||||
if (visual->depthBits && visual->stencilBits)
|
||||
drawable->attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
|
||||
else if (visual->depthBits)
|
||||
drawable->attachments[i++] = __DRI_BUFFER_DEPTH;
|
||||
if (visual->stencilBits)
|
||||
else if (visual->stencilBits)
|
||||
drawable->attachments[i++] = __DRI_BUFFER_STENCIL;
|
||||
drawable->num_attachments = i;
|
||||
|
||||
|
|
|
@ -63,8 +63,7 @@ struct dri_drawable
|
|||
unsigned int cur_fences;
|
||||
|
||||
enum pipe_format color_format;
|
||||
enum pipe_format depth_format;
|
||||
enum pipe_format stencil_format;
|
||||
enum pipe_format depth_stencil_format;
|
||||
};
|
||||
|
||||
static INLINE struct dri_drawable *
|
||||
|
|
|
@ -286,6 +286,18 @@ choose_pixel_format(XMesaVisual v)
|
|||
return PIPE_FORMAT_B8G8R8A8_UNORM;
|
||||
}
|
||||
}
|
||||
else if ( GET_REDMASK(v) == 0x0000ff00
|
||||
&& GET_GREENMASK(v) == 0x00ff0000
|
||||
&& GET_BLUEMASK(v) == 0xff000000
|
||||
&& v->BitsPerPixel == 32) {
|
||||
if (native_byte_order) {
|
||||
/* no byteswapping needed */
|
||||
return PIPE_FORMAT_B8G8R8A8_UNORM;
|
||||
}
|
||||
else {
|
||||
return PIPE_FORMAT_A8R8G8B8_UNORM;
|
||||
}
|
||||
}
|
||||
else if ( GET_REDMASK(v) == 0xf800
|
||||
&& GET_GREENMASK(v) == 0x07e0
|
||||
&& GET_BLUEMASK(v) == 0x001f
|
||||
|
@ -656,7 +668,7 @@ XMesaVisual XMesaCreateVisual( Display *display,
|
|||
* at a later time.
|
||||
*/
|
||||
v->visinfo = (XVisualInfo *) MALLOC(sizeof(*visinfo));
|
||||
if(!v->visinfo) {
|
||||
if (!v->visinfo) {
|
||||
_mesa_free(v);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -743,7 +755,7 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
|
|||
{
|
||||
static GLboolean firstTime = GL_TRUE;
|
||||
static struct pipe_screen *screen = NULL;
|
||||
struct pipe_context *pipe;
|
||||
struct pipe_context *pipe = NULL;
|
||||
XMesaContext c;
|
||||
GLcontext *mesaCtx;
|
||||
uint pf;
|
||||
|
@ -769,8 +781,7 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
|
|||
if (screen == NULL)
|
||||
goto fail;
|
||||
|
||||
pipe = driver.create_pipe_context( screen,
|
||||
(void *)c );
|
||||
pipe = driver.create_pipe_context(screen, (void *) c);
|
||||
if (pipe == NULL)
|
||||
goto fail;
|
||||
|
||||
|
@ -783,23 +794,15 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
|
|||
mesaCtx = c->st->ctx;
|
||||
c->st->ctx->DriverCtx = c;
|
||||
|
||||
#if 00
|
||||
_mesa_enable_sw_extensions(mesaCtx);
|
||||
_mesa_enable_1_3_extensions(mesaCtx);
|
||||
_mesa_enable_1_4_extensions(mesaCtx);
|
||||
_mesa_enable_1_5_extensions(mesaCtx);
|
||||
_mesa_enable_2_0_extensions(mesaCtx);
|
||||
#endif
|
||||
|
||||
return c;
|
||||
|
||||
fail:
|
||||
fail:
|
||||
if (c->st)
|
||||
st_destroy_context(c->st);
|
||||
else if (pipe)
|
||||
pipe->destroy(pipe);
|
||||
|
||||
FREE(c);
|
||||
_mesa_free(c);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1153,7 +1156,7 @@ void XMesaFlush( XMesaContext c )
|
|||
XMesaBuffer XMesaFindBuffer( Display *dpy, Drawable d )
|
||||
{
|
||||
XMesaBuffer b;
|
||||
for (b=XMesaBufferList; b; b=b->Next) {
|
||||
for (b = XMesaBufferList; b; b = b->Next) {
|
||||
if (b->drawable == d && b->xm_visual->display == dpy) {
|
||||
return b;
|
||||
}
|
||||
|
|
|
@ -2,9 +2,10 @@
|
|||
|
||||
#include "xorg_exa_tgsi.h"
|
||||
|
||||
#include <cso_cache/cso_context.h>
|
||||
#include "cso_cache/cso_context.h"
|
||||
#include "util/u_draw_quad.h"
|
||||
|
||||
#include <pipe/p_inlines.h>
|
||||
#include "pipe/p_inlines.h"
|
||||
|
||||
struct xorg_composite_blend {
|
||||
int op:8;
|
||||
|
@ -39,6 +40,24 @@ static const struct xorg_composite_blend xorg_blends[] = {
|
|||
PIPE_BLENDFACTOR_INV_SRC_ALPHA, PIPE_BLENDFACTOR_INV_SRC_ALPHA },
|
||||
};
|
||||
|
||||
static INLINE void
|
||||
pixel_to_float4(PictFormatPtr format,
|
||||
CARD32 pixel, float *color)
|
||||
{
|
||||
CARD32 r, g, b, a;
|
||||
|
||||
debug_assert(format->type == PictTypeDirect);
|
||||
|
||||
r = (pixel >> format->direct.red) & format->direct.redMask;
|
||||
g = (pixel >> format->direct.green) & format->direct.greenMask;
|
||||
b = (pixel >> format->direct.blue) & format->direct.blueMask;
|
||||
a = (pixel >> format->direct.alpha) & format->direct.alphaMask;
|
||||
color[0] = ((float)r) / ((float)format->direct.redMask);
|
||||
color[1] = ((float)g) / ((float)format->direct.greenMask);
|
||||
color[2] = ((float)b) / ((float)format->direct.blueMask);
|
||||
color[3] = ((float)a) / ((float)format->direct.alphaMask);
|
||||
}
|
||||
|
||||
struct acceleration_info {
|
||||
int op : 16;
|
||||
int with_mask : 1;
|
||||
|
@ -75,19 +94,168 @@ blend_for_op(int op)
|
|||
return xorg_blends[BLEND_OP_OVER];
|
||||
}
|
||||
|
||||
static void
|
||||
draw_texture(struct exa_context *exa)
|
||||
static INLINE int
|
||||
render_repeat_to_gallium(int mode)
|
||||
{
|
||||
#if 0
|
||||
if (buf) {
|
||||
util_draw_vertex_buffer(pipe, buf, 0,
|
||||
PIPE_PRIM_TRIANGLE_FAN,
|
||||
4, /* verts */
|
||||
2); /* attribs/vert */
|
||||
|
||||
pipe_buffer_reference(&buf, NULL);
|
||||
switch(mode) {
|
||||
case RepeatNone:
|
||||
return PIPE_TEX_WRAP_CLAMP;
|
||||
case RepeatNormal:
|
||||
return PIPE_TEX_WRAP_REPEAT;
|
||||
case RepeatReflect:
|
||||
return PIPE_TEX_WRAP_MIRROR_REPEAT;
|
||||
case RepeatPad:
|
||||
return PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
||||
default:
|
||||
debug_printf("Unsupported repeat mode\n");
|
||||
}
|
||||
#endif
|
||||
return PIPE_TEX_WRAP_REPEAT;
|
||||
}
|
||||
|
||||
|
||||
static INLINE void
|
||||
setup_vertex0(float vertex[2][4], float x, float y,
|
||||
float color[4])
|
||||
{
|
||||
vertex[0][0] = x;
|
||||
vertex[0][1] = y;
|
||||
vertex[0][2] = 0.f; /*z*/
|
||||
vertex[0][3] = 1.f; /*w*/
|
||||
|
||||
vertex[1][0] = color[0]; /*r*/
|
||||
vertex[1][1] = color[1]; /*g*/
|
||||
vertex[1][2] = color[2]; /*b*/
|
||||
vertex[1][3] = color[3]; /*a*/
|
||||
}
|
||||
|
||||
static struct pipe_buffer *
|
||||
setup_vertex_data0(struct exa_context *ctx,
|
||||
int srcX, int srcY, int maskX, int maskY,
|
||||
int dstX, int dstY, int width, int height)
|
||||
{
|
||||
float vertices[4][2][4];
|
||||
|
||||
/* 1st vertex */
|
||||
setup_vertex0(vertices[0], dstX, dstY,
|
||||
ctx->solid_color);
|
||||
/* 2nd vertex */
|
||||
setup_vertex0(vertices[1], dstX + width, dstY,
|
||||
ctx->solid_color);
|
||||
/* 3rd vertex */
|
||||
setup_vertex0(vertices[2], dstX + width, dstY + height,
|
||||
ctx->solid_color);
|
||||
/* 4th vertex */
|
||||
setup_vertex0(vertices[3], dstX, dstY + height,
|
||||
ctx->solid_color);
|
||||
|
||||
return pipe_user_buffer_create(ctx->ctx->screen,
|
||||
vertices,
|
||||
sizeof(vertices));
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
setup_vertex1(float vertex[2][4], float x, float y, float s, float t)
|
||||
{
|
||||
vertex[0][0] = x;
|
||||
vertex[0][1] = y;
|
||||
vertex[0][2] = 0.f; /*z*/
|
||||
vertex[0][3] = 1.f; /*w*/
|
||||
|
||||
vertex[1][0] = s; /*s*/
|
||||
vertex[1][1] = t; /*t*/
|
||||
vertex[1][2] = 0.f; /*r*/
|
||||
vertex[1][3] = 1.f; /*q*/
|
||||
}
|
||||
|
||||
static struct pipe_buffer *
|
||||
setup_vertex_data1(struct exa_context *ctx,
|
||||
int srcX, int srcY, int maskX, int maskY,
|
||||
int dstX, int dstY, int width, int height)
|
||||
{
|
||||
float vertices[4][2][4];
|
||||
float s0, t0, s1, t1;
|
||||
struct pipe_texture *src = ctx->bound_textures[0];
|
||||
|
||||
s0 = srcX / src->width[0];
|
||||
s1 = srcX + width / src->width[0];
|
||||
t0 = srcY / src->height[0];
|
||||
t1 = srcY + height / src->height[0];
|
||||
|
||||
/* 1st vertex */
|
||||
setup_vertex1(vertices[0], dstX, dstY,
|
||||
s0, t0);
|
||||
/* 2nd vertex */
|
||||
setup_vertex1(vertices[1], dstX + width, dstY,
|
||||
s1, t0);
|
||||
/* 3rd vertex */
|
||||
setup_vertex1(vertices[2], dstX + width, dstY + height,
|
||||
s1, t1);
|
||||
/* 4th vertex */
|
||||
setup_vertex1(vertices[3], dstX, dstY + height,
|
||||
s0, t1);
|
||||
|
||||
return pipe_user_buffer_create(ctx->ctx->screen,
|
||||
vertices,
|
||||
sizeof(vertices));
|
||||
}
|
||||
|
||||
|
||||
static INLINE void
|
||||
setup_vertex2(float vertex[3][4], float x, float y,
|
||||
float s0, float t0, float s1, float t1)
|
||||
{
|
||||
vertex[0][0] = x;
|
||||
vertex[0][1] = y;
|
||||
vertex[0][2] = 0.f; /*z*/
|
||||
vertex[0][3] = 1.f; /*w*/
|
||||
|
||||
vertex[1][0] = s0; /*s*/
|
||||
vertex[1][1] = t0; /*t*/
|
||||
vertex[1][2] = 0.f; /*r*/
|
||||
vertex[1][3] = 1.f; /*q*/
|
||||
|
||||
vertex[2][0] = s1; /*s*/
|
||||
vertex[2][1] = t1; /*t*/
|
||||
vertex[2][2] = 0.f; /*r*/
|
||||
vertex[2][3] = 1.f; /*q*/
|
||||
}
|
||||
|
||||
static struct pipe_buffer *
|
||||
setup_vertex_data2(struct exa_context *ctx,
|
||||
int srcX, int srcY, int maskX, int maskY,
|
||||
int dstX, int dstY, int width, int height)
|
||||
{
|
||||
float vertices[4][3][4];
|
||||
float st0[4], st1[4];
|
||||
struct pipe_texture *src = ctx->bound_textures[0];
|
||||
struct pipe_texture *mask = ctx->bound_textures[0];
|
||||
|
||||
st0[0] = srcX / src->width[0];
|
||||
st0[1] = srcY / src->height[0];
|
||||
st0[2] = srcX + width / src->width[0];
|
||||
st0[3] = srcY + height / src->height[0];
|
||||
|
||||
st1[0] = maskX / mask->width[0];
|
||||
st1[1] = maskY / mask->height[0];
|
||||
st1[2] = maskX + width / mask->width[0];
|
||||
st1[3] = maskY + height / mask->height[0];
|
||||
|
||||
/* 1st vertex */
|
||||
setup_vertex2(vertices[0], dstX, dstY,
|
||||
st0[0], st0[1], st1[0], st1[1]);
|
||||
/* 2nd vertex */
|
||||
setup_vertex2(vertices[1], dstX + width, dstY,
|
||||
st0[2], st0[1], st1[2], st1[1]);
|
||||
/* 3rd vertex */
|
||||
setup_vertex2(vertices[2], dstX + width, dstY + height,
|
||||
st0[2], st0[3], st1[2], st1[3]);
|
||||
/* 4th vertex */
|
||||
setup_vertex2(vertices[3], dstX, dstY + height,
|
||||
st0[0], st0[3], st1[0], st1[3]);
|
||||
|
||||
return pipe_user_buffer_create(ctx->ctx->screen,
|
||||
vertices,
|
||||
sizeof(vertices));
|
||||
}
|
||||
|
||||
boolean xorg_composite_accelerated(int op,
|
||||
|
@ -172,27 +340,10 @@ set_viewport(struct exa_context *exa, int width, int height,
|
|||
static void
|
||||
bind_viewport_state(struct exa_context *exa, PicturePtr pDstPicture)
|
||||
{
|
||||
const int param_bytes = 8 * sizeof(float);
|
||||
int width = pDstPicture->pDrawable->width;
|
||||
int height = pDstPicture->pDrawable->height;
|
||||
float vs_consts[8] = {
|
||||
2.f/width, 2.f/height, 1, 1,
|
||||
-1, -1, 0, 0
|
||||
};
|
||||
struct pipe_constant_buffer *cbuf = &exa->vs_const_buffer;
|
||||
|
||||
set_viewport(exa, width, height, Y0_BOTTOM);
|
||||
|
||||
pipe_buffer_reference(&cbuf->buffer, NULL);
|
||||
cbuf->buffer = pipe_buffer_create(exa->ctx->screen, 16,
|
||||
PIPE_BUFFER_USAGE_CONSTANT,
|
||||
param_bytes);
|
||||
|
||||
if (cbuf->buffer) {
|
||||
pipe_buffer_write(exa->ctx->screen, cbuf->buffer,
|
||||
0, param_bytes, vs_consts);
|
||||
}
|
||||
exa->ctx->set_constant_buffer(exa->ctx, PIPE_SHADER_VERTEX, 0, cbuf);
|
||||
set_viewport(exa, width, height, Y0_TOP);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -240,8 +391,20 @@ bind_shaders(struct exa_context *exa, int op,
|
|||
struct xorg_shader shader;
|
||||
|
||||
if (pSrcPicture) {
|
||||
vs_traits |= VS_COMPOSITE;
|
||||
fs_traits |= FS_COMPOSITE;
|
||||
if (pSrcPicture->pSourcePict) {
|
||||
if (pSrcPicture->pSourcePict->type == SourcePictTypeSolidFill) {
|
||||
fs_traits |= FS_SOLID_FILL;
|
||||
vs_traits |= VS_SOLID_FILL;
|
||||
pixel_to_float4(pSrcPicture->pFormat,
|
||||
pSrcPicture->pSourcePict->solidFill.color,
|
||||
exa->solid_color);
|
||||
} else {
|
||||
debug_assert("!gradients not supported");
|
||||
}
|
||||
} else {
|
||||
fs_traits |= FS_COMPOSITE;
|
||||
vs_traits |= VS_COMPOSITE;
|
||||
}
|
||||
}
|
||||
|
||||
if (pMaskPicture) {
|
||||
|
@ -264,35 +427,98 @@ bind_samplers(struct exa_context *exa, int op,
|
|||
struct exa_pixmap_priv *pDst)
|
||||
{
|
||||
struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
|
||||
struct pipe_texture *textures[PIPE_MAX_SAMPLERS];
|
||||
struct pipe_sampler_state src_sampler, mask_sampler;
|
||||
|
||||
exa->num_bound_samplers = 0;
|
||||
|
||||
memset(&src_sampler, 0, sizeof(struct pipe_sampler_state));
|
||||
memset(&mask_sampler, 0, sizeof(struct pipe_sampler_state));
|
||||
|
||||
if (pSrcPicture && pSrc) {
|
||||
src_sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
||||
src_sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
||||
unsigned src_wrap = render_repeat_to_gallium(
|
||||
pSrcPicture->repeatType);
|
||||
src_sampler.wrap_s = src_wrap;
|
||||
src_sampler.wrap_t = src_wrap;
|
||||
src_sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST;
|
||||
src_sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST;
|
||||
src_sampler.normalized_coords = 1;
|
||||
samplers[0] = &src_sampler;
|
||||
textures[0] = pSrc->tex;
|
||||
exa->bound_textures[0] = pSrc->tex;
|
||||
++exa->num_bound_samplers;
|
||||
}
|
||||
|
||||
if (pMaskPicture && pMask) {
|
||||
mask_sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
||||
mask_sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
||||
unsigned mask_wrap = render_repeat_to_gallium(
|
||||
pMaskPicture->repeatType);
|
||||
mask_sampler.wrap_s = mask_wrap;
|
||||
mask_sampler.wrap_t = mask_wrap;
|
||||
mask_sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST;
|
||||
mask_sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST;
|
||||
mask_sampler.normalized_coords = 1;
|
||||
samplers[1] = &mask_sampler;
|
||||
textures[1] = pMask->tex;
|
||||
exa->bound_textures[1] = pMask->tex;
|
||||
++exa->num_bound_samplers;
|
||||
}
|
||||
|
||||
cso_set_samplers(exa->cso, 3,
|
||||
cso_set_samplers(exa->cso, exa->num_bound_samplers,
|
||||
(const struct pipe_sampler_state **)samplers);
|
||||
cso_set_sampler_textures(exa->cso, 3, textures);
|
||||
cso_set_sampler_textures(exa->cso, exa->num_bound_samplers,
|
||||
exa->bound_textures);
|
||||
}
|
||||
|
||||
static void
|
||||
setup_vs_constant_buffer(struct exa_context *exa,
|
||||
int width, int height)
|
||||
{
|
||||
const int param_bytes = 8 * sizeof(float);
|
||||
float vs_consts[8] = {
|
||||
2.f/width, 2.f/height, 1, 1,
|
||||
-1, -1, 0, 0
|
||||
};
|
||||
struct pipe_constant_buffer *cbuf = &exa->vs_const_buffer;
|
||||
|
||||
pipe_buffer_reference(&cbuf->buffer, NULL);
|
||||
cbuf->buffer = pipe_buffer_create(exa->ctx->screen, 16,
|
||||
PIPE_BUFFER_USAGE_CONSTANT,
|
||||
param_bytes);
|
||||
|
||||
if (cbuf->buffer) {
|
||||
pipe_buffer_write(exa->ctx->screen, cbuf->buffer,
|
||||
0, param_bytes, vs_consts);
|
||||
}
|
||||
exa->ctx->set_constant_buffer(exa->ctx, PIPE_SHADER_VERTEX, 0, cbuf);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
setup_fs_constant_buffer(struct exa_context *exa)
|
||||
{
|
||||
const int param_bytes = 4 * sizeof(float);
|
||||
float fs_consts[8] = {
|
||||
0, 0, 0, 1,
|
||||
};
|
||||
struct pipe_constant_buffer *cbuf = &exa->fs_const_buffer;
|
||||
|
||||
pipe_buffer_reference(&cbuf->buffer, NULL);
|
||||
cbuf->buffer = pipe_buffer_create(exa->ctx->screen, 16,
|
||||
PIPE_BUFFER_USAGE_CONSTANT,
|
||||
param_bytes);
|
||||
|
||||
if (cbuf->buffer) {
|
||||
pipe_buffer_write(exa->ctx->screen, cbuf->buffer,
|
||||
0, param_bytes, fs_consts);
|
||||
}
|
||||
exa->ctx->set_constant_buffer(exa->ctx, PIPE_SHADER_FRAGMENT, 0, cbuf);
|
||||
}
|
||||
|
||||
static void
|
||||
setup_constant_buffers(struct exa_context *exa, PicturePtr pDstPicture)
|
||||
{
|
||||
int width = pDstPicture->pDrawable->width;
|
||||
int height = pDstPicture->pDrawable->height;
|
||||
|
||||
setup_vs_constant_buffer(exa, width, height);
|
||||
setup_fs_constant_buffer(exa);
|
||||
}
|
||||
|
||||
boolean xorg_composite_bind_state(struct exa_context *exa,
|
||||
|
@ -309,8 +535,10 @@ boolean xorg_composite_bind_state(struct exa_context *exa,
|
|||
bind_blend_state(exa, op, pSrcPicture, pMaskPicture);
|
||||
bind_rasterizer_state(exa);
|
||||
bind_shaders(exa, op, pSrcPicture, pMaskPicture);
|
||||
bind_samplers(exa, op, pSrcPicture, pMaskPicture, pDstPicture,
|
||||
pSrc, pMask, pDst);
|
||||
bind_samplers(exa, op, pSrcPicture, pMaskPicture,
|
||||
pDstPicture, pSrc, pMask, pDst);
|
||||
|
||||
setup_constant_buffers(exa, pDstPicture);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -320,5 +548,37 @@ void xorg_composite(struct exa_context *exa,
|
|||
int srcX, int srcY, int maskX, int maskY,
|
||||
int dstX, int dstY, int width, int height)
|
||||
{
|
||||
struct pipe_context *pipe = exa->ctx;
|
||||
struct pipe_buffer *buf = 0;
|
||||
|
||||
if (exa->num_bound_samplers == 0 ) { /* solid fill */
|
||||
buf = setup_vertex_data0(exa,
|
||||
srcX, srcY, maskX, maskY,
|
||||
dstX, dstY, width, height);
|
||||
} else if (exa->num_bound_samplers == 1 ) /* src */
|
||||
buf = setup_vertex_data1(exa,
|
||||
srcX, srcY, maskX, maskY,
|
||||
dstX, dstY, width, height);
|
||||
else if (exa->num_bound_samplers == 2) /* src + mask */
|
||||
buf = setup_vertex_data2(exa,
|
||||
srcX, srcY, maskX, maskY,
|
||||
dstX, dstY, width, height);
|
||||
else if (exa->num_bound_samplers == 3) { /* src + mask + dst */
|
||||
debug_assert(!"src/mask/dst not handled right now");
|
||||
#if 0
|
||||
buf = setup_vertex_data2(exa,
|
||||
srcX, srcY, maskX, maskY,
|
||||
dstX, dstY, width, height);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (buf) {
|
||||
util_draw_vertex_buffer(pipe, buf, 0,
|
||||
PIPE_PRIM_TRIANGLE_FAN,
|
||||
4, /* verts */
|
||||
1 + exa->num_bound_samplers); /* attribs/vert */
|
||||
|
||||
pipe_buffer_reference(&buf, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "xf86_OSproc.h"
|
||||
|
||||
#include "xorg_tracker.h"
|
||||
#include "xorg_exa.h"
|
||||
|
||||
#include "dri2.h"
|
||||
|
||||
|
@ -47,19 +48,156 @@ typedef struct {
|
|||
struct pipe_fence_handle *fence;
|
||||
} *BufferPrivatePtr;
|
||||
|
||||
static DRI2BufferPtr
|
||||
driCreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count)
|
||||
static Bool
|
||||
driDoCreateBuffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int format)
|
||||
{
|
||||
struct pipe_texture *depth, *tex;
|
||||
struct pipe_buffer *buf;
|
||||
struct pipe_texture *tex = NULL;
|
||||
ScreenPtr pScreen = pDraw->pScreen;
|
||||
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
||||
modesettingPtr ms = modesettingPTR(pScrn);
|
||||
BufferPrivatePtr privates;
|
||||
DRI2BufferPtr buffers;
|
||||
struct exa_pixmap_priv *exa_priv;
|
||||
BufferPrivatePtr private = buffer->driverPrivate;
|
||||
PixmapPtr pPixmap;
|
||||
unsigned stride, handle;
|
||||
boolean have_depth = FALSE, have_stencil = FALSE;
|
||||
|
||||
if (pDraw->type == DRAWABLE_PIXMAP)
|
||||
pPixmap = (PixmapPtr) pDraw;
|
||||
else
|
||||
pPixmap = (*pScreen->GetWindowPixmap)((WindowPtr) pDraw);
|
||||
exa_priv = exaGetPixmapDriverPrivate(pPixmap);
|
||||
|
||||
switch (buffer->attachment) {
|
||||
default:
|
||||
if (buffer->attachment != DRI2BufferFakeFrontLeft ||
|
||||
pDraw->type != DRAWABLE_PIXMAP) {
|
||||
private->pPixmap = (*pScreen->CreatePixmap)(pScreen, pDraw->width,
|
||||
pDraw->height,
|
||||
pDraw->depth,
|
||||
0);
|
||||
}
|
||||
break;
|
||||
case DRI2BufferFrontLeft:
|
||||
break;
|
||||
case DRI2BufferStencil:
|
||||
#if defined(DRI2INFOREC_VERSION) && DRI2INFOREC_VERSION > 2
|
||||
case DRI2BufferDepthStencil:
|
||||
if (exa_priv->depth_stencil_tex &&
|
||||
!pf_is_depth_stencil(exa_priv->depth_stencil_tex->format))
|
||||
exa_priv->depth_stencil_tex = NULL;
|
||||
/* Fall through */
|
||||
#endif
|
||||
case DRI2BufferDepth:
|
||||
if (exa_priv->depth_stencil_tex)
|
||||
pipe_texture_reference(&tex, exa_priv->depth_stencil_tex);
|
||||
else {
|
||||
struct pipe_texture template;
|
||||
memset(&template, 0, sizeof(template));
|
||||
template.target = PIPE_TEXTURE_2D;
|
||||
if (buffer->attachment == DRI2BufferDepth)
|
||||
template.format = ms->ds_depth_bits_last ?
|
||||
PIPE_FORMAT_X8Z24_UNORM : PIPE_FORMAT_Z24X8_UNORM;
|
||||
else
|
||||
template.format = ms->ds_depth_bits_last ?
|
||||
PIPE_FORMAT_S8Z24_UNORM : PIPE_FORMAT_Z24S8_UNORM;
|
||||
pf_get_block(template.format, &template.block);
|
||||
template.width[0] = pDraw->width;
|
||||
template.height[0] = pDraw->height;
|
||||
template.depth[0] = 1;
|
||||
template.last_level = 0;
|
||||
template.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL |
|
||||
PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
|
||||
tex = ms->screen->texture_create(ms->screen, &template);
|
||||
pipe_texture_reference(&exa_priv->depth_stencil_tex, tex);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!private->pPixmap) {
|
||||
private->pPixmap = pPixmap;
|
||||
pPixmap->refcnt++;
|
||||
}
|
||||
|
||||
if (!tex) {
|
||||
xorg_exa_set_shared_usage(private->pPixmap);
|
||||
pScreen->ModifyPixmapHeader(private->pPixmap, 0, 0, 0, 0, 0, NULL);
|
||||
tex = xorg_exa_get_texture(private->pPixmap);
|
||||
}
|
||||
|
||||
if (!tex)
|
||||
FatalError("NO TEXTURE IN DRI2\n");
|
||||
|
||||
ms->api->shared_handle_from_texture(ms->api, ms->screen, tex, &stride, &handle);
|
||||
|
||||
buffer->name = handle;
|
||||
buffer->pitch = stride;
|
||||
buffer->cpp = 4;
|
||||
buffer->driverPrivate = private;
|
||||
buffer->flags = 0; /* not tiled */
|
||||
private->tex = tex;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
driDoDestroyBuffer(DrawablePtr pDraw, DRI2BufferPtr buffer)
|
||||
{
|
||||
ScreenPtr pScreen = pDraw->pScreen;
|
||||
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
||||
modesettingPtr ms = modesettingPTR(pScrn);
|
||||
BufferPrivatePtr private = buffer->driverPrivate;
|
||||
struct exa_pixmap_priv *exa_priv = exaGetPixmapDriverPrivate(private->pPixmap);
|
||||
|
||||
pipe_texture_reference(&private->tex, NULL);
|
||||
ms->screen->fence_reference(ms->screen, &private->fence, NULL);
|
||||
pipe_texture_reference(&exa_priv->depth_stencil_tex, NULL);
|
||||
(*pScreen->DestroyPixmap)(private->pPixmap);
|
||||
}
|
||||
|
||||
#if defined(DRI2INFOREC_VERSION) && DRI2INFOREC_VERSION > 2
|
||||
|
||||
static DRI2BufferPtr
|
||||
driCreateBuffer(DrawablePtr pDraw, unsigned int attachment, unsigned int format)
|
||||
{
|
||||
DRI2BufferPtr buffer;
|
||||
BufferPrivatePtr private;
|
||||
|
||||
buffer = xcalloc(1, sizeof *buffer);
|
||||
if (!buffer)
|
||||
return NULL;
|
||||
|
||||
private = xcalloc(1, sizeof *private);
|
||||
if (!private) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
buffer->attachment = attachment;
|
||||
buffer->driverPrivate = private;
|
||||
|
||||
if (driDoCreateBuffer(pDraw, buffer, format))
|
||||
return buffer;
|
||||
|
||||
xfree(private);
|
||||
fail:
|
||||
xfree(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
driDestroyBuffer(DrawablePtr pDraw, DRI2BufferPtr buffer)
|
||||
{
|
||||
driDoDestroyBuffer(pDraw, buffer);
|
||||
|
||||
xfree(buffer->driverPrivate);
|
||||
xfree(buffer);
|
||||
}
|
||||
|
||||
#else /* DRI2INFOREC_VERSION <= 2 */
|
||||
|
||||
static DRI2BufferPtr
|
||||
driCreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count)
|
||||
{
|
||||
BufferPrivatePtr privates;
|
||||
DRI2BufferPtr buffers;
|
||||
int i;
|
||||
|
||||
buffers = xcalloc(count, sizeof *buffers);
|
||||
|
@ -71,81 +209,17 @@ driCreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count)
|
|||
goto fail_privates;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
if (attachments[i] == DRI2BufferDepth)
|
||||
have_depth = TRUE;
|
||||
else if (attachments[i] == DRI2BufferStencil)
|
||||
have_stencil = TRUE;
|
||||
}
|
||||
|
||||
if (have_stencil && !have_depth)
|
||||
FatalError("Doesn't support only stencil yet\n");
|
||||
|
||||
depth = NULL;
|
||||
for (i = 0; i < count; i++) {
|
||||
pPixmap = NULL;
|
||||
tex = NULL;
|
||||
buf = NULL;
|
||||
if (attachments[i] == DRI2BufferFrontLeft) {
|
||||
if (pDraw->type == DRAWABLE_PIXMAP)
|
||||
pPixmap = (PixmapPtr) pDraw;
|
||||
else
|
||||
pPixmap = (*pScreen->GetWindowPixmap)((WindowPtr) pDraw);
|
||||
pPixmap->refcnt++;
|
||||
} else if (attachments[i] == DRI2BufferStencil) {
|
||||
pipe_texture_reference(&tex, depth);
|
||||
} else if (attachments[i] == DRI2BufferDepth) {
|
||||
struct pipe_texture template;
|
||||
memset(&template, 0, sizeof(template));
|
||||
template.target = PIPE_TEXTURE_2D;
|
||||
if (have_stencil)
|
||||
template.format = ms->ds_depth_bits_last ?
|
||||
PIPE_FORMAT_S8Z24_UNORM : PIPE_FORMAT_Z24S8_UNORM;
|
||||
else
|
||||
template.format = ms->d_depth_bits_last ?
|
||||
PIPE_FORMAT_X8Z24_UNORM : PIPE_FORMAT_Z24X8_UNORM;
|
||||
pf_get_block(template.format, &template.block);
|
||||
template.width[0] = pDraw->width;
|
||||
template.height[0] = pDraw->height;
|
||||
template.depth[0] = 1;
|
||||
template.last_level = 0;
|
||||
template.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL |
|
||||
PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
|
||||
tex = ms->screen->texture_create(ms->screen, &template);
|
||||
depth = tex;
|
||||
} else if (attachments[i] == DRI2BufferFakeFrontLeft &&
|
||||
pDraw->type == DRAWABLE_PIXMAP) {
|
||||
pPixmap = (PixmapPtr) pDraw;
|
||||
pPixmap->refcnt++;
|
||||
} else {
|
||||
pPixmap = (*pScreen->CreatePixmap)(pScreen, pDraw->width,
|
||||
pDraw->height,
|
||||
pDraw->depth,
|
||||
0);
|
||||
}
|
||||
|
||||
if (pPixmap) {
|
||||
xorg_exa_set_shared_usage(pPixmap);
|
||||
pScreen->ModifyPixmapHeader(pPixmap, 0, 0, 0, 0, 0, NULL);
|
||||
tex = xorg_exa_get_texture(pPixmap);
|
||||
}
|
||||
|
||||
if (!tex)
|
||||
FatalError("NO TEXTURE IN DRI2\n");
|
||||
|
||||
ms->api->shared_handle_from_texture(ms->api, ms->screen, tex, &stride, &handle);
|
||||
|
||||
buffers[i].name = handle;
|
||||
buffers[i].attachment = attachments[i];
|
||||
buffers[i].pitch = stride;
|
||||
buffers[i].cpp = 4;
|
||||
buffers[i].driverPrivate = &privates[i];
|
||||
buffers[i].flags = 0; /* not tiled */
|
||||
privates[i].pPixmap = pPixmap;
|
||||
privates[i].tex = tex;
|
||||
|
||||
if (!driDoCreateBuffer(pDraw, &buffers[i], 0))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return buffers;
|
||||
|
||||
fail:
|
||||
xfree(privates);
|
||||
fail_privates:
|
||||
xfree(buffers);
|
||||
fail_buffers:
|
||||
|
@ -155,21 +229,10 @@ fail_buffers:
|
|||
static void
|
||||
driDestroyBuffers(DrawablePtr pDraw, DRI2BufferPtr buffers, int count)
|
||||
{
|
||||
ScreenPtr pScreen = pDraw->pScreen;
|
||||
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
||||
modesettingPtr ms = modesettingPTR(pScrn);
|
||||
BufferPrivatePtr private;
|
||||
int i;
|
||||
(void)ms;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
private = buffers[i].driverPrivate;
|
||||
|
||||
pipe_texture_reference(&private->tex, NULL);
|
||||
ms->screen->fence_reference(ms->screen, &private->fence, NULL);
|
||||
|
||||
if (private->pPixmap)
|
||||
(*pScreen->DestroyPixmap)(private->pPixmap);
|
||||
driDoDestroyBuffer(pDraw, &buffers[i]);
|
||||
}
|
||||
|
||||
if (buffers) {
|
||||
|
@ -178,6 +241,8 @@ driDestroyBuffers(DrawablePtr pDraw, DRI2BufferPtr buffers, int count)
|
|||
}
|
||||
}
|
||||
|
||||
#endif /* DRI2INFOREC_VERSION */
|
||||
|
||||
static void
|
||||
driCopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
|
||||
DRI2BufferPtr pDestBuffer, DRI2BufferPtr pSrcBuffer)
|
||||
|
@ -273,15 +338,25 @@ driScreenInit(ScreenPtr pScreen)
|
|||
modesettingPtr ms = modesettingPTR(pScrn);
|
||||
DRI2InfoRec dri2info;
|
||||
|
||||
#if defined(DRI2INFOREC_VERSION)
|
||||
dri2info.version = DRI2INFOREC_VERSION;
|
||||
#else
|
||||
dri2info.version = 1;
|
||||
#endif
|
||||
dri2info.fd = ms->fd;
|
||||
|
||||
dri2info.driverName = pScrn->driverName;
|
||||
dri2info.deviceName = "/dev/dri/card0"; /* FIXME */
|
||||
|
||||
#if defined(DRI2INFOREC_VERSION) && DRI2INFOREC_VERSION > 2
|
||||
dri2info.CreateBuffer = driCreateBuffer;
|
||||
dri2info.DestroyBuffer = driDestroyBuffer;
|
||||
#else
|
||||
dri2info.CreateBuffers = driCreateBuffers;
|
||||
dri2info.DestroyBuffers = driDestroyBuffers;
|
||||
#endif
|
||||
dri2info.CopyRegion = driCopyRegion;
|
||||
dri2info.Wait = NULL;
|
||||
|
||||
ms->d_depth_bits_last =
|
||||
ms->screen->is_format_supported(ms->screen, PIPE_FORMAT_X8Z24_UNORM,
|
||||
|
|
|
@ -33,10 +33,8 @@
|
|||
#include "xf86.h"
|
||||
#include "xf86_OSproc.h"
|
||||
#include "compiler.h"
|
||||
#include "xf86RAC.h"
|
||||
#include "xf86PciInfo.h"
|
||||
#include "xf86Pci.h"
|
||||
#include "xf86Resources.h"
|
||||
#include "mipointer.h"
|
||||
#include "micmap.h"
|
||||
#include <X11/extensions/randr.h>
|
||||
|
@ -84,42 +82,10 @@ static const OptionInfoRec Options[] = {
|
|||
{-1, NULL, OPTV_NONE, {0}, FALSE}
|
||||
};
|
||||
|
||||
/*
|
||||
* Functions that might be needed
|
||||
*/
|
||||
|
||||
static const char *exaSymbols[] = {
|
||||
"exaGetVersion",
|
||||
"exaDriverInit",
|
||||
"exaDriverFini",
|
||||
"exaOffscreenAlloc",
|
||||
"exaOffscreenFree",
|
||||
"exaWaitSync",
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *fbSymbols[] = {
|
||||
"fbPictureInit",
|
||||
"fbScreenInit",
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *ddcSymbols[] = {
|
||||
"xf86PrintEDID",
|
||||
"xf86SetDDCproperties",
|
||||
NULL
|
||||
};
|
||||
|
||||
/*
|
||||
* Exported Xorg driver functions to winsys
|
||||
*/
|
||||
|
||||
void
|
||||
xorg_tracker_loader_ref_sym_lists()
|
||||
{
|
||||
LoaderRefSymLists(exaSymbols, fbSymbols, ddcSymbols, NULL);
|
||||
}
|
||||
|
||||
const OptionInfoRec *
|
||||
xorg_tracker_available_options(int chipid, int busid)
|
||||
{
|
||||
|
@ -288,10 +254,6 @@ PreInit(ScrnInfoPtr pScrn, int flags)
|
|||
} else
|
||||
ms->entityPrivate = NULL;
|
||||
|
||||
if (xf86RegisterResources(ms->pEnt->index, NULL, ResNone)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (xf86IsEntityShared(pScrn->entityList[0])) {
|
||||
if (xf86IsPrimInitDone(pScrn->entityList[0])) {
|
||||
/* do something */
|
||||
|
@ -312,7 +274,6 @@ PreInit(ScrnInfoPtr pScrn, int flags)
|
|||
if (ms->fd < 0)
|
||||
return FALSE;
|
||||
|
||||
pScrn->racMemFlags = RAC_FB | RAC_COLORMAP;
|
||||
pScrn->monitor = pScrn->confScreen->monitor;
|
||||
pScrn->progClock = TRUE;
|
||||
pScrn->rgbBits = 8;
|
||||
|
@ -398,8 +359,6 @@ PreInit(ScrnInfoPtr pScrn, int flags)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
xf86LoaderReqSymLists(fbSymbols, NULL);
|
||||
|
||||
xf86LoadSubModule(pScrn, "exa");
|
||||
|
||||
#ifdef DRI2
|
||||
|
|
|
@ -97,6 +97,68 @@ ExaMarkSync(ScreenPtr pScreen)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static Bool
|
||||
ExaDownloadFromScreen(PixmapPtr pPix, int x, int y, int w, int h, char *dst,
|
||||
int dst_pitch)
|
||||
{
|
||||
ScreenPtr pScreen = pPix->drawable.pScreen;
|
||||
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
||||
modesettingPtr ms = modesettingPTR(pScrn);
|
||||
struct exa_context *exa = ms->exa;
|
||||
struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPix);
|
||||
struct pipe_transfer *transfer;
|
||||
|
||||
if (!priv || !priv->tex)
|
||||
return FALSE;
|
||||
|
||||
if (exa->ctx->is_texture_referenced(exa->ctx, priv->tex, 0, 0) &
|
||||
PIPE_REFERENCED_FOR_WRITE)
|
||||
exa->ctx->flush(exa->ctx, 0, NULL);
|
||||
|
||||
transfer = exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0,
|
||||
PIPE_TRANSFER_READ, x, y, w, h);
|
||||
if (!transfer)
|
||||
return FALSE;
|
||||
|
||||
util_copy_rect((unsigned char*)dst, &priv->tex->block, dst_pitch, 0, 0,
|
||||
w, h, exa->scrn->transfer_map(exa->scrn, transfer),
|
||||
transfer->stride, 0, 0);
|
||||
|
||||
exa->scrn->transfer_unmap(exa->scrn, transfer);
|
||||
exa->scrn->tex_transfer_destroy(transfer);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
ExaUploadToScreen(PixmapPtr pPix, int x, int y, int w, int h, char *src,
|
||||
int src_pitch)
|
||||
{
|
||||
ScreenPtr pScreen = pPix->drawable.pScreen;
|
||||
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
||||
modesettingPtr ms = modesettingPTR(pScrn);
|
||||
struct exa_context *exa = ms->exa;
|
||||
struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPix);
|
||||
struct pipe_transfer *transfer;
|
||||
|
||||
if (!priv || !priv->tex)
|
||||
return FALSE;
|
||||
|
||||
transfer = exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0,
|
||||
PIPE_TRANSFER_WRITE, x, y, w, h);
|
||||
if (!transfer)
|
||||
return FALSE;
|
||||
|
||||
util_copy_rect(exa->scrn->transfer_map(exa->scrn, transfer),
|
||||
&priv->tex->block, transfer->stride, 0, 0, w, h,
|
||||
(unsigned char*)src, src_pitch, 0, 0);
|
||||
|
||||
exa->scrn->transfer_unmap(exa->scrn, transfer);
|
||||
exa->scrn->tex_transfer_destroy(transfer);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
ExaPrepareAccess(PixmapPtr pPix, int index)
|
||||
{
|
||||
|
@ -188,9 +250,6 @@ ExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg)
|
|||
struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
|
||||
struct exa_context *exa = ms->exa;
|
||||
|
||||
if (1)
|
||||
return FALSE;
|
||||
|
||||
if (pPixmap->drawable.depth < 15)
|
||||
return FALSE;
|
||||
|
||||
|
@ -430,7 +489,7 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
|
|||
modesettingPtr ms = modesettingPTR(pScrn);
|
||||
struct exa_context *exa = ms->exa;
|
||||
|
||||
if (!priv)
|
||||
if (!priv || pPixData)
|
||||
return FALSE;
|
||||
|
||||
if (depth <= 0)
|
||||
|
@ -452,65 +511,69 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
|
|||
bitsPerPixel, devKind, NULL);
|
||||
|
||||
/* Deal with screen resize */
|
||||
if (priv->tex && (priv->tex->width[0] != width ||
|
||||
priv->tex->height[0] != height ||
|
||||
priv->tex_flags != priv->flags)) {
|
||||
pipe_texture_reference(&priv->tex, NULL);
|
||||
}
|
||||
|
||||
if (!priv->tex
|
||||
#ifdef DRM_MODE_FEATURE_DIRTYFB
|
||||
&& priv->flags
|
||||
#endif
|
||||
) {
|
||||
struct pipe_texture template;
|
||||
|
||||
memset(&template, 0, sizeof(template));
|
||||
template.target = PIPE_TEXTURE_2D;
|
||||
exa_get_pipe_format(depth, &template.format, &bitsPerPixel);
|
||||
pf_get_block(template.format, &template.block);
|
||||
template.width[0] = width;
|
||||
template.height[0] = height;
|
||||
template.depth[0] = 1;
|
||||
template.last_level = 0;
|
||||
template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET | priv->flags;
|
||||
priv->tex_flags = priv->flags;
|
||||
priv->tex = exa->scrn->texture_create(exa->scrn, &template);
|
||||
}
|
||||
if (!priv->tex ||
|
||||
(priv->tex->width[0] != width ||
|
||||
priv->tex->height[0] != height ||
|
||||
priv->tex_flags != priv->flags)) {
|
||||
struct pipe_texture *texture = NULL;
|
||||
|
||||
#ifdef DRM_MODE_FEATURE_DIRTYFB
|
||||
if (!priv->tex) {
|
||||
if (pPixData)
|
||||
pPixmap->devPrivate.ptr = pPixData;
|
||||
else
|
||||
pPixmap->devPrivate.ptr = xalloc(pPixmap->drawable.height * pPixmap->devKind);
|
||||
} else
|
||||
if (priv->flags)
|
||||
#endif
|
||||
if (pPixData) {
|
||||
struct pipe_transfer *transfer =
|
||||
exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0,
|
||||
PIPE_TRANSFER_WRITE,
|
||||
0, 0, width, height);
|
||||
util_copy_rect(exa->scrn->transfer_map(exa->scrn, transfer),
|
||||
&priv->tex->block, transfer->stride, 0, 0,
|
||||
width, height, pPixData, pPixmap->devKind, 0, 0);
|
||||
exa->scrn->transfer_unmap(exa->scrn, transfer);
|
||||
exa->scrn->tex_transfer_destroy(transfer);
|
||||
} else if (priv->tex && pPixmap->devPrivate.ptr) {
|
||||
struct pipe_transfer *transfer;
|
||||
{
|
||||
struct pipe_texture template;
|
||||
|
||||
if (priv->map_count != 0)
|
||||
FatalError("doing ExaModifyPixmapHeader on mapped buffer\n");
|
||||
memset(&template, 0, sizeof(template));
|
||||
template.target = PIPE_TEXTURE_2D;
|
||||
exa_get_pipe_format(depth, &template.format, &bitsPerPixel);
|
||||
pf_get_block(template.format, &template.block);
|
||||
template.width[0] = width;
|
||||
template.height[0] = height;
|
||||
template.depth[0] = 1;
|
||||
template.last_level = 0;
|
||||
template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET | priv->flags;
|
||||
priv->tex_flags = priv->flags;
|
||||
texture = exa->scrn->texture_create(exa->scrn, &template);
|
||||
|
||||
transfer =
|
||||
exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0,
|
||||
PIPE_TRANSFER_WRITE,
|
||||
0, 0, width, height);
|
||||
util_copy_rect(exa->scrn->transfer_map(exa->scrn, transfer),
|
||||
&priv->tex->block, transfer->stride, 0, 0,
|
||||
width, height, pPixmap->devPrivate.ptr, pPixmap->devKind, 0, 0);
|
||||
exa->scrn->transfer_unmap(exa->scrn, transfer);
|
||||
exa->scrn->tex_transfer_destroy(transfer);
|
||||
if (priv->tex) {
|
||||
struct pipe_surface *dst_surf;
|
||||
|
||||
dst_surf = exa->scrn->get_tex_surface(exa->scrn, texture, 0, 0, 0,
|
||||
PIPE_BUFFER_USAGE_GPU_WRITE);
|
||||
priv->src_surf = exa_gpu_surface(exa, priv);
|
||||
exa->ctx->surface_copy(exa->ctx, dst_surf, 0, 0, priv->src_surf,
|
||||
0, 0, min(width, texture->width[0]),
|
||||
min(height, texture->height[0]));
|
||||
exa->scrn->tex_surface_destroy(dst_surf);
|
||||
exa->scrn->tex_surface_destroy(priv->src_surf);
|
||||
priv->src_surf = NULL;
|
||||
} else if (pPixmap->devPrivate.ptr) {
|
||||
struct pipe_transfer *transfer;
|
||||
|
||||
if (priv->map_count != 0)
|
||||
FatalError("doing ExaModifyPixmapHeader on mapped buffer\n");
|
||||
|
||||
transfer =
|
||||
exa->scrn->get_tex_transfer(exa->scrn, texture, 0, 0, 0,
|
||||
PIPE_TRANSFER_WRITE,
|
||||
0, 0, width, height);
|
||||
util_copy_rect(exa->scrn->transfer_map(exa->scrn, transfer),
|
||||
&texture->block, transfer->stride, 0, 0,
|
||||
width, height, pPixmap->devPrivate.ptr,
|
||||
pPixmap->devKind, 0, 0);
|
||||
exa->scrn->transfer_unmap(exa->scrn, transfer);
|
||||
exa->scrn->tex_transfer_destroy(transfer);
|
||||
}
|
||||
}
|
||||
#ifdef DRM_MODE_FEATURE_DIRTYFB
|
||||
else {
|
||||
xfree(pPixmap->devPrivate.ptr);
|
||||
pPixmap->devPrivate.ptr = xalloc(pPixmap->drawable.height *
|
||||
pPixmap->devKind);
|
||||
}
|
||||
#endif
|
||||
|
||||
pipe_texture_reference(&priv->tex, texture);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
@ -598,6 +661,8 @@ xorg_exa_init(ScrnInfoPtr pScrn)
|
|||
pExa->Composite = ExaComposite;
|
||||
pExa->DoneComposite = ExaDoneComposite;
|
||||
pExa->PixmapIsOffscreen = ExaPixmapIsOffscreen;
|
||||
pExa->DownloadFromScreen = ExaDownloadFromScreen;
|
||||
pExa->UploadToScreen = ExaUploadToScreen;
|
||||
pExa->PrepareAccess = ExaPrepareAccess;
|
||||
pExa->FinishAccess = ExaFinishAccess;
|
||||
pExa->CreatePixmap = ExaCreatePixmap;
|
||||
|
|
|
@ -8,6 +8,9 @@
|
|||
struct cso_context;
|
||||
struct xorg_shaders;
|
||||
|
||||
/* src + mask + dst */
|
||||
#define MAX_EXA_SAMPLERS 3
|
||||
|
||||
struct exa_context
|
||||
{
|
||||
ExaDriverPtr pExa;
|
||||
|
@ -18,6 +21,11 @@ struct exa_context
|
|||
|
||||
struct pipe_constant_buffer vs_const_buffer;
|
||||
struct pipe_constant_buffer fs_const_buffer;
|
||||
|
||||
struct pipe_texture *bound_textures[MAX_EXA_SAMPLERS];
|
||||
int num_bound_samplers;
|
||||
|
||||
float solid_color[4];
|
||||
};
|
||||
|
||||
|
||||
|
@ -27,6 +35,7 @@ struct exa_pixmap_priv
|
|||
int tex_flags;
|
||||
|
||||
struct pipe_texture *tex;
|
||||
struct pipe_texture *depth_stencil_tex;
|
||||
unsigned int color;
|
||||
struct pipe_surface *src_surf; /* for copies */
|
||||
|
||||
|
|
|
@ -18,22 +18,24 @@
|
|||
#include "cso_cache/cso_hash.h"
|
||||
|
||||
/* Vertex shader:
|
||||
* IN[0] = src_pos
|
||||
* IN[1] = mask_pos
|
||||
* IN[2] = dst_pos
|
||||
* IN[0] = vertex pos
|
||||
* IN[1] = src tex coord | solid fill color
|
||||
* IN[2] = mask tex coord
|
||||
* IN[3] = dst tex coord
|
||||
* CONST[0] = (2/dst_width, 2/dst_height, 1, 1)
|
||||
* CONST[1] = (-1, -1, 0, 0)
|
||||
*
|
||||
* OUT[0] = src_pos
|
||||
* OUT[1] = mask_pos
|
||||
* OUT[2] = dst_pos
|
||||
* OUT[0] = vertex pos
|
||||
* OUT[1] = src tex coord | solid fill color
|
||||
* OUT[2] = mask tex coord
|
||||
* OUT[3] = dst tex coord
|
||||
*/
|
||||
|
||||
/* Fragment shader:
|
||||
* SAMP[0] = src
|
||||
* SAMP[1] = mask
|
||||
* SAMP[2] = dst
|
||||
* IN[0] = pos src
|
||||
* IN[0] = pos src | solid fill color
|
||||
* IN[1] = pos mask
|
||||
* IN[2] = pos dst
|
||||
* CONST[0] = (0, 0, 0, 1)
|
||||
|
@ -84,6 +86,150 @@ vs_normalize_coords(struct ureg_program *ureg, struct ureg_src coords,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
linear_gradient(struct ureg_program *ureg,
|
||||
struct ureg_dst out,
|
||||
struct ureg_src pos,
|
||||
struct ureg_src sampler,
|
||||
struct ureg_src coords,
|
||||
struct ureg_src const0124,
|
||||
struct ureg_src matrow0,
|
||||
struct ureg_src matrow1,
|
||||
struct ureg_src matrow2)
|
||||
{
|
||||
struct ureg_dst temp0 = ureg_DECL_temporary(ureg);
|
||||
struct ureg_dst temp1 = ureg_DECL_temporary(ureg);
|
||||
struct ureg_dst temp2 = ureg_DECL_temporary(ureg);
|
||||
struct ureg_dst temp3 = ureg_DECL_temporary(ureg);
|
||||
struct ureg_dst temp4 = ureg_DECL_temporary(ureg);
|
||||
struct ureg_dst temp5 = ureg_DECL_temporary(ureg);
|
||||
|
||||
ureg_MOV(ureg,
|
||||
ureg_writemask(temp0, TGSI_WRITEMASK_XY), pos);
|
||||
ureg_MOV(ureg,
|
||||
ureg_writemask(temp0, TGSI_WRITEMASK_Z),
|
||||
ureg_scalar(const0124, TGSI_SWIZZLE_Y));
|
||||
|
||||
ureg_DP3(ureg, temp1, matrow0, ureg_src(temp0));
|
||||
ureg_DP3(ureg, temp2, matrow1, ureg_src(temp0));
|
||||
ureg_DP3(ureg, temp3, matrow2, ureg_src(temp0));
|
||||
ureg_RCP(ureg, temp3, ureg_src(temp3));
|
||||
ureg_MUL(ureg, temp1, ureg_src(temp1), ureg_src(temp3));
|
||||
ureg_MUL(ureg, temp2, ureg_src(temp2), ureg_src(temp3));
|
||||
|
||||
ureg_MOV(ureg, ureg_writemask(temp4, TGSI_WRITEMASK_X),
|
||||
ureg_src(temp1));
|
||||
ureg_MOV(ureg, ureg_writemask(temp4, TGSI_WRITEMASK_Y),
|
||||
ureg_src(temp2));
|
||||
|
||||
ureg_MUL(ureg, temp0,
|
||||
ureg_scalar(coords, TGSI_SWIZZLE_Y),
|
||||
ureg_scalar(ureg_src(temp4), TGSI_SWIZZLE_Y));
|
||||
ureg_MAD(ureg, temp1,
|
||||
ureg_scalar(coords, TGSI_SWIZZLE_X),
|
||||
ureg_scalar(ureg_src(temp4), TGSI_SWIZZLE_X),
|
||||
ureg_src(temp0));
|
||||
|
||||
ureg_MUL(ureg, temp2,
|
||||
ureg_src(temp1),
|
||||
ureg_scalar(coords, TGSI_SWIZZLE_Z));
|
||||
|
||||
ureg_TEX(ureg, out,
|
||||
TGSI_TEXTURE_1D, ureg_src(temp2), sampler);
|
||||
|
||||
ureg_release_temporary(ureg, temp0);
|
||||
ureg_release_temporary(ureg, temp1);
|
||||
ureg_release_temporary(ureg, temp2);
|
||||
ureg_release_temporary(ureg, temp3);
|
||||
ureg_release_temporary(ureg, temp4);
|
||||
ureg_release_temporary(ureg, temp5);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
radial_gradient(struct ureg_program *ureg,
|
||||
struct ureg_dst out,
|
||||
struct ureg_src pos,
|
||||
struct ureg_src sampler,
|
||||
struct ureg_src coords,
|
||||
struct ureg_src const0124,
|
||||
struct ureg_src matrow0,
|
||||
struct ureg_src matrow1,
|
||||
struct ureg_src matrow2)
|
||||
{
|
||||
struct ureg_dst temp0 = ureg_DECL_temporary(ureg);
|
||||
struct ureg_dst temp1 = ureg_DECL_temporary(ureg);
|
||||
struct ureg_dst temp2 = ureg_DECL_temporary(ureg);
|
||||
struct ureg_dst temp3 = ureg_DECL_temporary(ureg);
|
||||
struct ureg_dst temp4 = ureg_DECL_temporary(ureg);
|
||||
struct ureg_dst temp5 = ureg_DECL_temporary(ureg);
|
||||
|
||||
ureg_MOV(ureg,
|
||||
ureg_writemask(temp0, TGSI_WRITEMASK_XY),
|
||||
pos);
|
||||
ureg_MOV(ureg,
|
||||
ureg_writemask(temp0, TGSI_WRITEMASK_Z),
|
||||
ureg_scalar(const0124, TGSI_SWIZZLE_Y));
|
||||
|
||||
ureg_DP3(ureg, temp1, matrow0, ureg_src(temp0));
|
||||
ureg_DP3(ureg, temp2, matrow1, ureg_src(temp0));
|
||||
ureg_DP3(ureg, temp3, matrow2, ureg_src(temp0));
|
||||
ureg_RCP(ureg, temp3, ureg_src(temp3));
|
||||
ureg_MUL(ureg, temp1, ureg_src(temp1), ureg_src(temp3));
|
||||
ureg_MUL(ureg, temp2, ureg_src(temp2), ureg_src(temp3));
|
||||
|
||||
ureg_MOV(ureg, ureg_writemask(temp5, TGSI_WRITEMASK_X),
|
||||
ureg_src(temp1));
|
||||
ureg_MOV(ureg, ureg_writemask(temp5, TGSI_WRITEMASK_Y),
|
||||
ureg_src(temp2));
|
||||
|
||||
ureg_MUL(ureg, temp0, ureg_scalar(coords, TGSI_SWIZZLE_Y),
|
||||
ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_Y));
|
||||
ureg_MAD(ureg, temp1,
|
||||
ureg_scalar(coords, TGSI_SWIZZLE_X),
|
||||
ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_X),
|
||||
ureg_src(temp0));
|
||||
ureg_ADD(ureg, temp1,
|
||||
ureg_src(temp1), ureg_src(temp1));
|
||||
ureg_MUL(ureg, temp3,
|
||||
ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_Y),
|
||||
ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_Y));
|
||||
ureg_MAD(ureg, temp4,
|
||||
ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_X),
|
||||
ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_X),
|
||||
ureg_src(temp3));
|
||||
ureg_MOV(ureg, temp4, ureg_negate(ureg_src(temp4)));
|
||||
ureg_MUL(ureg, temp2,
|
||||
ureg_scalar(coords, TGSI_SWIZZLE_Z),
|
||||
ureg_src(temp4));
|
||||
ureg_MUL(ureg, temp0,
|
||||
ureg_scalar(const0124, TGSI_SWIZZLE_W),
|
||||
ureg_src(temp2));
|
||||
ureg_MUL(ureg, temp3,
|
||||
ureg_src(temp1), ureg_src(temp1));
|
||||
ureg_SUB(ureg, temp2,
|
||||
ureg_src(temp3), ureg_src(temp0));
|
||||
ureg_RSQ(ureg, temp2, ureg_abs(ureg_src(temp2)));
|
||||
ureg_RCP(ureg, temp2, ureg_src(temp2));
|
||||
ureg_SUB(ureg, temp1,
|
||||
ureg_src(temp2), ureg_src(temp1));
|
||||
ureg_ADD(ureg, temp0,
|
||||
ureg_scalar(coords, TGSI_SWIZZLE_Z),
|
||||
ureg_scalar(coords, TGSI_SWIZZLE_Z));
|
||||
ureg_RCP(ureg, temp0, ureg_src(temp0));
|
||||
ureg_MUL(ureg, temp2,
|
||||
ureg_src(temp1), ureg_src(temp0));
|
||||
ureg_TEX(ureg, out, TGSI_TEXTURE_1D,
|
||||
ureg_src(temp2), sampler);
|
||||
|
||||
ureg_release_temporary(ureg, temp0);
|
||||
ureg_release_temporary(ureg, temp1);
|
||||
ureg_release_temporary(ureg, temp2);
|
||||
ureg_release_temporary(ureg, temp3);
|
||||
ureg_release_temporary(ureg, temp4);
|
||||
ureg_release_temporary(ureg, temp5);
|
||||
}
|
||||
|
||||
static void *
|
||||
create_vs(struct pipe_context *pipe,
|
||||
unsigned vs_traits)
|
||||
|
@ -92,6 +238,9 @@ create_vs(struct pipe_context *pipe,
|
|||
struct ureg_src src;
|
||||
struct ureg_dst dst;
|
||||
struct ureg_src const0, const1;
|
||||
boolean is_fill = vs_traits & VS_FILL;
|
||||
boolean is_composite = vs_traits & VS_COMPOSITE;
|
||||
boolean has_mask = vs_traits & VS_MASK;
|
||||
|
||||
ureg = ureg_create(TGSI_PROCESSOR_VERTEX);
|
||||
if (ureg == NULL)
|
||||
|
@ -100,18 +249,34 @@ create_vs(struct pipe_context *pipe,
|
|||
const0 = ureg_DECL_constant(ureg);
|
||||
const1 = ureg_DECL_constant(ureg);
|
||||
|
||||
if ((vs_traits & VS_COMPOSITE)) {
|
||||
/* it has to be either a fill or a composite op */
|
||||
debug_assert(is_fill ^ is_composite);
|
||||
|
||||
src = ureg_DECL_vs_input(ureg,
|
||||
TGSI_SEMANTIC_POSITION, 0);
|
||||
dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0);
|
||||
src = vs_normalize_coords(ureg, src,
|
||||
const0, const1);
|
||||
ureg_MOV(ureg, dst, src);
|
||||
|
||||
|
||||
if (is_composite) {
|
||||
src = ureg_DECL_vs_input(ureg,
|
||||
TGSI_SEMANTIC_POSITION, 0);
|
||||
dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0);
|
||||
src = vs_normalize_coords(ureg, src,
|
||||
const0, const1);
|
||||
TGSI_SEMANTIC_GENERIC, 1);
|
||||
dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 1);
|
||||
ureg_MOV(ureg, dst, src);
|
||||
}
|
||||
if ((vs_traits & VS_MASK)) {
|
||||
if (is_fill) {
|
||||
src = ureg_DECL_vs_input(ureg,
|
||||
TGSI_SEMANTIC_POSITION, 1);
|
||||
dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 1);
|
||||
TGSI_SEMANTIC_COLOR, 1);
|
||||
dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 1);
|
||||
ureg_MOV(ureg, dst, src);
|
||||
}
|
||||
|
||||
if (has_mask) {
|
||||
src = ureg_DECL_vs_input(ureg,
|
||||
TGSI_SEMANTIC_GENERIC, 2);
|
||||
dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 2);
|
||||
ureg_MOV(ureg, dst, src);
|
||||
}
|
||||
|
||||
|
@ -125,27 +290,50 @@ create_fs(struct pipe_context *pipe,
|
|||
unsigned fs_traits)
|
||||
{
|
||||
struct ureg_program *ureg;
|
||||
struct ureg_src dst_sampler, src_sampler, mask_sampler;
|
||||
struct ureg_src dst_pos, src_pos, mask_pos;
|
||||
struct ureg_src src, mask;
|
||||
struct ureg_src /*dst_sampler,*/ src_sampler, mask_sampler;
|
||||
struct ureg_src /*dst_pos,*/ src_input, mask_pos;
|
||||
struct ureg_dst src, mask;
|
||||
struct ureg_dst out;
|
||||
boolean has_mask = fs_traits & FS_MASK;
|
||||
boolean is_fill = fs_traits & FS_FILL;
|
||||
boolean is_composite = fs_traits & FS_COMPOSITE;
|
||||
boolean is_solid = fs_traits & FS_SOLID_FILL;
|
||||
boolean is_lingrad = fs_traits & FS_LINGRAD_FILL;
|
||||
boolean is_radgrad = fs_traits & FS_RADGRAD_FILL;
|
||||
|
||||
ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT);
|
||||
if (ureg == NULL)
|
||||
return 0;
|
||||
|
||||
/* it has to be either a fill or a composite op */
|
||||
debug_assert(is_fill ^ is_composite);
|
||||
|
||||
out = ureg_DECL_output(ureg,
|
||||
TGSI_SEMANTIC_COLOR,
|
||||
0);
|
||||
|
||||
src_sampler = ureg_DECL_sampler(ureg);
|
||||
src_pos = ureg_DECL_fs_input(ureg,
|
||||
TGSI_SEMANTIC_POSITION,
|
||||
0,
|
||||
TGSI_INTERPOLATE_PERSPECTIVE);
|
||||
if (is_composite) {
|
||||
src_sampler = ureg_DECL_sampler(ureg, 0);
|
||||
src_input = ureg_DECL_fs_input(ureg,
|
||||
TGSI_SEMANTIC_POSITION,
|
||||
0,
|
||||
TGSI_INTERPOLATE_PERSPECTIVE);
|
||||
}
|
||||
if (is_fill) {
|
||||
if (is_solid)
|
||||
src_input = ureg_DECL_fs_input(ureg,
|
||||
TGSI_SEMANTIC_COLOR,
|
||||
0,
|
||||
TGSI_INTERPOLATE_PERSPECTIVE);
|
||||
else
|
||||
src_input = ureg_DECL_fs_input(ureg,
|
||||
TGSI_SEMANTIC_POSITION,
|
||||
0,
|
||||
TGSI_INTERPOLATE_PERSPECTIVE);
|
||||
}
|
||||
|
||||
if ((fs_traits & FS_MASK)) {
|
||||
mask_sampler = ureg_DECL_sampler(ureg);
|
||||
if (has_mask) {
|
||||
mask_sampler = ureg_DECL_sampler(ureg, 1);
|
||||
mask_pos = ureg_DECL_fs_input(ureg,
|
||||
TGSI_SEMANTIC_POSITION,
|
||||
1,
|
||||
|
@ -153,21 +341,63 @@ create_fs(struct pipe_context *pipe,
|
|||
}
|
||||
|
||||
#if 0 /* unused right now */
|
||||
dst_sampler = ureg_DECL_sampler(ureg);
|
||||
dst_sampler = ureg_DECL_sampler(ureg, 2);
|
||||
dst_pos = ureg_DECL_fs_input(ureg,
|
||||
TGSI_SEMANTIC_POSITION,
|
||||
2,
|
||||
TGSI_INTERPOLATE_PERSPECTIVE);
|
||||
#endif
|
||||
|
||||
if ((fs_traits & FS_MASK)) {
|
||||
ureg_TEX(ureg, ureg_dst(mask),
|
||||
if (is_composite) {
|
||||
if (has_mask)
|
||||
src = ureg_DECL_temporary(ureg);
|
||||
else
|
||||
src = out;
|
||||
ureg_TEX(ureg, src,
|
||||
TGSI_TEXTURE_2D, src_input, src_sampler);
|
||||
} else if (is_fill) {
|
||||
if (is_solid) {
|
||||
if (has_mask)
|
||||
src = ureg_dst(src_input);
|
||||
else
|
||||
ureg_MOV(ureg, out, src_input);
|
||||
} else if (is_lingrad || is_radgrad) {
|
||||
struct ureg_src coords, const0124,
|
||||
matrow0, matrow1, matrow2;
|
||||
|
||||
if (has_mask)
|
||||
src = ureg_DECL_temporary(ureg);
|
||||
else
|
||||
src = out;
|
||||
|
||||
coords = ureg_DECL_constant(ureg);
|
||||
const0124 = ureg_DECL_constant(ureg);
|
||||
matrow0 = ureg_DECL_constant(ureg);
|
||||
matrow1 = ureg_DECL_constant(ureg);
|
||||
matrow2 = ureg_DECL_constant(ureg);
|
||||
|
||||
if (is_lingrad) {
|
||||
linear_gradient(ureg, src,
|
||||
src_input, src_sampler,
|
||||
coords, const0124,
|
||||
matrow0, matrow1, matrow2);
|
||||
} else if (is_radgrad) {
|
||||
radial_gradient(ureg, src,
|
||||
src_input, src_sampler,
|
||||
coords, const0124,
|
||||
matrow0, matrow1, matrow2);
|
||||
}
|
||||
} else
|
||||
debug_assert(!"Unknown fill type!");
|
||||
}
|
||||
|
||||
if (has_mask) {
|
||||
mask = ureg_DECL_temporary(ureg);
|
||||
ureg_TEX(ureg, mask,
|
||||
TGSI_TEXTURE_2D, mask_pos, mask_sampler);
|
||||
/* src IN mask */
|
||||
src_in_mask(ureg, out, src, mask);
|
||||
} else {
|
||||
ureg_TEX(ureg, out,
|
||||
TGSI_TEXTURE_2D, src_pos, src_sampler);
|
||||
src_in_mask(ureg, out, ureg_src(src), ureg_src(mask));
|
||||
ureg_release_temporary(ureg, mask);
|
||||
}
|
||||
|
||||
ureg_END(ureg);
|
||||
|
|
|
@ -6,16 +6,24 @@
|
|||
enum xorg_vs_traits {
|
||||
VS_COMPOSITE = 1 << 0,
|
||||
VS_MASK = 1 << 1,
|
||||
VS_FILL = 1 << 2
|
||||
/*VS_TRANSFORM = 1 << 3*/
|
||||
VS_SOLID_FILL = 1 << 2,
|
||||
VS_LINGRAD_FILL = 1 << 3,
|
||||
VS_RADGRAD_FILL = 1 << 4,
|
||||
VS_FILL = (VS_SOLID_FILL |
|
||||
VS_LINGRAD_FILL |
|
||||
VS_RADGRAD_FILL)
|
||||
/*VS_TRANSFORM = 1 << 5*/
|
||||
};
|
||||
|
||||
enum xorg_fs_traits {
|
||||
FS_COMPOSITE = 1 << 0,
|
||||
FS_MASK = 1 << 1,
|
||||
FS_FILL = 1 << 2,
|
||||
FS_LINEAR_GRADIENT = 1 << 3,
|
||||
FS_RADIAL_GRADIENT = 1 << 4
|
||||
FS_SOLID_FILL = 1 << 2,
|
||||
FS_LINGRAD_FILL = 1 << 3,
|
||||
FS_RADGRAD_FILL = 1 << 4,
|
||||
FS_FILL = (FS_SOLID_FILL |
|
||||
FS_LINGRAD_FILL |
|
||||
FS_RADGRAD_FILL)
|
||||
};
|
||||
|
||||
struct xorg_shader {
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
|
||||
#include "xorg-server.h"
|
||||
#include "xf86.h"
|
||||
#include "xf86Resources.h"
|
||||
#include "pciaccess.h"
|
||||
|
||||
#ifndef XSERVER_LIBPCIACCESS
|
||||
|
@ -46,6 +45,5 @@
|
|||
|
||||
void xorg_tracker_set_functions(ScrnInfoPtr scrn);
|
||||
const OptionInfoRec * xorg_tracker_available_options(int chipid, int busid);
|
||||
void xorg_tracker_loader_ref_sym_lists(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4,10 +4,10 @@ include $(TOP)/configs/current
|
|||
LIBNAME = inteldrm
|
||||
|
||||
C_SOURCES = \
|
||||
intel_be_batchbuffer.c \
|
||||
intel_be_context.c \
|
||||
intel_be_device.c \
|
||||
intel_be_api.c
|
||||
intel_drm_batchbuffer.c \
|
||||
intel_drm_buffer.c \
|
||||
intel_drm_fence.c \
|
||||
intel_drm_api.c
|
||||
|
||||
LIBRARY_INCLUDES = $(shell pkg-config libdrm --cflags-only-I)
|
||||
|
||||
|
|
|
@ -3,10 +3,10 @@ Import('*')
|
|||
env = drienv.Clone()
|
||||
|
||||
inteldrm_sources = [
|
||||
'intel_be_api.c',
|
||||
'intel_be_batchbuffer.c',
|
||||
'intel_be_context.c',
|
||||
'intel_be_device.c',
|
||||
'intel_drm_api.c',
|
||||
'intel_drm_batchbuffer.c',
|
||||
'intel_drm_buffer.c',
|
||||
'intel_drm_fence.c',
|
||||
]
|
||||
|
||||
inteldrm = env.ConvenienceLibrary(
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
|
||||
#include "intel_be_api.h"
|
||||
#include "i915simple/i915_winsys.h"
|
||||
#include "identity/id_drm.h"
|
||||
#include "trace/tr_drm.h"
|
||||
|
||||
static void destroy(struct drm_api *api)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
struct drm_api intel_be_drm_api =
|
||||
{
|
||||
/* intel_be_context.c */
|
||||
.create_context = intel_be_create_context,
|
||||
/* intel_be_device.c */
|
||||
.create_screen = intel_be_create_screen,
|
||||
.texture_from_shared_handle = intel_be_texture_from_shared_handle,
|
||||
.shared_handle_from_texture = intel_be_shared_handle_from_texture,
|
||||
.local_handle_from_texture = intel_be_local_handle_from_texture,
|
||||
.destroy = destroy,
|
||||
};
|
||||
|
||||
struct drm_api *
|
||||
drm_api_create()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
#if 0
|
||||
return identity_drm_create(&intel_be_drm_api);
|
||||
#else
|
||||
return trace_drm_create(&intel_be_drm_api);
|
||||
#endif
|
||||
#else
|
||||
return &intel_be_drm_api;
|
||||
#endif
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
|
||||
#ifndef _INTEL_BE_API_H_
|
||||
#define _INTEL_BE_API_H_
|
||||
|
||||
#include "pipe/p_compiler.h"
|
||||
|
||||
#include "state_tracker/drm_api.h"
|
||||
|
||||
#include "intel_be_device.h"
|
||||
|
||||
extern struct drm_api intel_be_drm_api;
|
||||
|
||||
struct pipe_screen *intel_be_create_screen(struct drm_api *api, int drmFD,
|
||||
struct drm_create_screen_arg *arg);
|
||||
struct pipe_context *intel_be_create_context(struct drm_api *api,
|
||||
struct pipe_screen *screen);
|
||||
|
||||
#endif
|
|
@ -1,156 +0,0 @@
|
|||
|
||||
#include "i915simple/i915_debug.h"
|
||||
#include "intel_be_batchbuffer.h"
|
||||
#include "intel_be_context.h"
|
||||
#include "intel_be_device.h"
|
||||
#include "intel_be_fence.h"
|
||||
#include <errno.h>
|
||||
|
||||
#include "util/u_memory.h"
|
||||
|
||||
struct intel_be_batchbuffer *
|
||||
intel_be_batchbuffer_alloc(struct intel_be_context *intel)
|
||||
{
|
||||
struct intel_be_batchbuffer *batch = CALLOC_STRUCT(intel_be_batchbuffer);
|
||||
|
||||
|
||||
batch->base.buffer = NULL;
|
||||
batch->base.winsys = &intel->base;
|
||||
batch->base.map = NULL;
|
||||
batch->base.ptr = NULL;
|
||||
batch->base.size = 0;
|
||||
batch->base.actual_size = intel->device->max_batch_size;
|
||||
batch->base.relocs = 0;
|
||||
batch->base.max_relocs = 100;/*INTEL_DEFAULT_RELOCS;*/
|
||||
|
||||
batch->intel = intel;
|
||||
batch->device = intel->device;
|
||||
|
||||
intel_be_batchbuffer_reset(batch);
|
||||
|
||||
return batch;
|
||||
}
|
||||
|
||||
void
|
||||
intel_be_batchbuffer_reset(struct intel_be_batchbuffer *batch)
|
||||
{
|
||||
struct intel_be_context *intel = intel_be_context(batch->base.winsys);
|
||||
struct intel_be_device *dev = intel->device;
|
||||
|
||||
if (batch->bo)
|
||||
drm_intel_bo_unreference(batch->bo);
|
||||
batch->bo = drm_intel_bo_alloc(dev->pools.gem,
|
||||
"gallium3d_batch_buffer",
|
||||
batch->base.actual_size,
|
||||
4096);
|
||||
drm_intel_bo_map(batch->bo, TRUE);
|
||||
batch->base.map = batch->bo->virtual;
|
||||
|
||||
memset(batch->base.map, 0, batch->base.actual_size);
|
||||
batch->base.ptr = batch->base.map;
|
||||
batch->base.size = batch->base.actual_size - BATCH_RESERVED;
|
||||
batch->base.relocs = 0;
|
||||
}
|
||||
|
||||
int
|
||||
intel_be_offset_relocation(struct intel_be_batchbuffer *batch,
|
||||
unsigned pre_add,
|
||||
drm_intel_bo *bo,
|
||||
uint32_t read_domains,
|
||||
uint32_t write_domain)
|
||||
{
|
||||
unsigned offset;
|
||||
int ret = 0;
|
||||
|
||||
assert(batch->base.relocs < batch->base.max_relocs);
|
||||
|
||||
offset = (unsigned)(batch->base.ptr - batch->base.map);
|
||||
|
||||
ret = drm_intel_bo_emit_reloc(batch->bo, offset,
|
||||
bo, pre_add,
|
||||
read_domains,
|
||||
write_domain);
|
||||
|
||||
((uint32_t*)batch->base.ptr)[0] = bo->offset + pre_add;
|
||||
batch->base.ptr += 4;
|
||||
|
||||
if (!ret)
|
||||
batch->base.relocs++;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
intel_be_batchbuffer_flush(struct intel_be_batchbuffer *batch,
|
||||
struct intel_be_fence **fence)
|
||||
{
|
||||
struct i915_batchbuffer *i915 = &batch->base;
|
||||
unsigned used = 0;
|
||||
int ret = 0;
|
||||
int i;
|
||||
|
||||
assert(i915_batchbuffer_space(i915) >= 0);
|
||||
|
||||
used = batch->base.ptr - batch->base.map;
|
||||
assert((used & 3) == 0);
|
||||
|
||||
if (used & 4) {
|
||||
i915_batchbuffer_dword(i915, (0x0<<29)|(0x4<<23)|(1<<0)); // MI_FLUSH | FLUSH_MAP_CACHE;
|
||||
i915_batchbuffer_dword(i915, (0x0<<29)|(0x0<<23)); // MI_NOOP
|
||||
i915_batchbuffer_dword(i915, (0x0<<29)|(0xA<<23)); // MI_BATCH_BUFFER_END;
|
||||
} else {
|
||||
i915_batchbuffer_dword(i915, (0x0<<29)|(0x4<<23)|(1<<0)); //MI_FLUSH | FLUSH_MAP_CACHE;
|
||||
i915_batchbuffer_dword(i915, (0x0<<29)|(0xA<<23)); // MI_BATCH_BUFFER_END;
|
||||
}
|
||||
|
||||
used = batch->base.ptr - batch->base.map;
|
||||
|
||||
drm_intel_bo_unmap(batch->bo);
|
||||
|
||||
/* Do the sending to HW */
|
||||
ret = drm_intel_bo_exec(batch->bo, used, NULL, 0, 0);
|
||||
assert(ret == 0);
|
||||
|
||||
if (batch->device->dump_cmd) {
|
||||
unsigned *ptr;
|
||||
drm_intel_bo_map(batch->bo, FALSE);
|
||||
ptr = (unsigned*)batch->bo->virtual;
|
||||
|
||||
debug_printf("%s:\n", __func__);
|
||||
for (i = 0; i < used / 4; i++, ptr++) {
|
||||
debug_printf("\t%08x: %08x\n", i*4, *ptr);
|
||||
}
|
||||
|
||||
drm_intel_bo_unmap(batch->bo);
|
||||
} else {
|
||||
/* TODO figgure out why the gpu hangs if we don't run sync */
|
||||
drm_intel_bo_map(batch->bo, FALSE);
|
||||
drm_intel_bo_unmap(batch->bo);
|
||||
}
|
||||
|
||||
intel_be_batchbuffer_reset(batch);
|
||||
|
||||
if (fence) {
|
||||
if (*fence)
|
||||
intel_be_fence_reference(fence, NULL);
|
||||
|
||||
(*fence) = CALLOC_STRUCT(intel_be_fence);
|
||||
pipe_reference_init(&(*fence)->reference, 1);
|
||||
(*fence)->bo = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
intel_be_batchbuffer_finish(struct intel_be_batchbuffer *batch)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
intel_be_batchbuffer_free(struct intel_be_batchbuffer *batch)
|
||||
{
|
||||
if (batch->bo)
|
||||
drm_intel_bo_unreference(batch->bo);
|
||||
|
||||
free(batch);
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
|
||||
#ifndef INTEL_BE_BATCHBUFFER_H
|
||||
#define INTEL_BE_BATCHBUFFER_H
|
||||
|
||||
#include "i915simple/i915_batch.h"
|
||||
|
||||
#include "drm.h"
|
||||
#include "intel_bufmgr.h"
|
||||
|
||||
#define BATCH_RESERVED 16
|
||||
|
||||
#define INTEL_DEFAULT_RELOCS 100
|
||||
#define INTEL_MAX_RELOCS 400
|
||||
|
||||
#define INTEL_BATCH_NO_CLIPRECTS 0x1
|
||||
#define INTEL_BATCH_CLIPRECTS 0x2
|
||||
|
||||
struct intel_be_context;
|
||||
struct intel_be_device;
|
||||
struct intel_be_fence;
|
||||
|
||||
struct intel_be_batchbuffer
|
||||
{
|
||||
struct i915_batchbuffer base;
|
||||
|
||||
struct intel_be_context *intel;
|
||||
struct intel_be_device *device;
|
||||
|
||||
drm_intel_bo *bo;
|
||||
};
|
||||
|
||||
struct intel_be_batchbuffer *
|
||||
intel_be_batchbuffer_alloc(struct intel_be_context *intel);
|
||||
|
||||
void
|
||||
intel_be_batchbuffer_free(struct intel_be_batchbuffer *batch);
|
||||
|
||||
void
|
||||
intel_be_batchbuffer_finish(struct intel_be_batchbuffer *batch);
|
||||
|
||||
void
|
||||
intel_be_batchbuffer_flush(struct intel_be_batchbuffer *batch,
|
||||
struct intel_be_fence **fence);
|
||||
|
||||
void
|
||||
intel_be_batchbuffer_reset(struct intel_be_batchbuffer *batch);
|
||||
|
||||
int
|
||||
intel_be_offset_relocation(struct intel_be_batchbuffer *batch,
|
||||
unsigned pre_add,
|
||||
drm_intel_bo *bo,
|
||||
uint32_t read_domains,
|
||||
uint32_t write_doman);
|
||||
|
||||
#endif
|
|
@ -1,117 +0,0 @@
|
|||
|
||||
#include "pipe/p_screen.h"
|
||||
|
||||
#include "softpipe/sp_winsys.h"
|
||||
|
||||
#include "intel_be_device.h"
|
||||
#include "intel_be_context.h"
|
||||
#include "intel_be_batchbuffer.h"
|
||||
|
||||
#include "i915_drm.h"
|
||||
|
||||
#include "intel_be_api.h"
|
||||
|
||||
static struct i915_batchbuffer *
|
||||
intel_be_batch_get(struct i915_winsys *sws)
|
||||
{
|
||||
struct intel_be_context *intel = intel_be_context(sws);
|
||||
return &intel->batch->base;
|
||||
}
|
||||
|
||||
static void
|
||||
intel_be_batch_reloc(struct i915_winsys *sws,
|
||||
struct pipe_buffer *buf,
|
||||
unsigned access_flags,
|
||||
unsigned delta)
|
||||
{
|
||||
struct intel_be_context *intel = intel_be_context(sws);
|
||||
drm_intel_bo *bo = intel_bo(buf);
|
||||
int ret;
|
||||
uint32_t read = 0;
|
||||
uint32_t write = 0;
|
||||
|
||||
if (access_flags & I915_BUFFER_ACCESS_WRITE) {
|
||||
write = I915_GEM_DOMAIN_RENDER;
|
||||
read = I915_GEM_DOMAIN_RENDER;
|
||||
}
|
||||
|
||||
if (access_flags & I915_BUFFER_ACCESS_READ) {
|
||||
read |= I915_GEM_DOMAIN_SAMPLER;
|
||||
}
|
||||
|
||||
ret = intel_be_offset_relocation(intel->batch,
|
||||
delta,
|
||||
bo,
|
||||
read,
|
||||
write);
|
||||
assert(ret == 0);
|
||||
|
||||
/* TODO change return type */
|
||||
/* return ret; */
|
||||
}
|
||||
|
||||
static void
|
||||
intel_be_batch_flush(struct i915_winsys *sws,
|
||||
struct pipe_fence_handle **fence)
|
||||
{
|
||||
struct intel_be_context *intel = intel_be_context(sws);
|
||||
struct intel_be_fence **f = (struct intel_be_fence **)fence;
|
||||
|
||||
intel_be_batchbuffer_flush(intel->batch, f);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Misc functions.
|
||||
*/
|
||||
|
||||
static void
|
||||
intel_be_destroy_context(struct i915_winsys *winsys)
|
||||
{
|
||||
struct intel_be_context *intel = intel_be_context(winsys);
|
||||
|
||||
intel_be_batchbuffer_free(intel->batch);
|
||||
|
||||
free(intel);
|
||||
}
|
||||
|
||||
boolean
|
||||
intel_be_init_context(struct intel_be_context *intel, struct intel_be_device *device)
|
||||
{
|
||||
assert(intel);
|
||||
assert(device);
|
||||
intel->device = device;
|
||||
|
||||
intel->base.batch_get = intel_be_batch_get;
|
||||
intel->base.batch_reloc = intel_be_batch_reloc;
|
||||
intel->base.batch_flush = intel_be_batch_flush;
|
||||
|
||||
intel->base.destroy = intel_be_destroy_context;
|
||||
|
||||
intel->batch = intel_be_batchbuffer_alloc(intel);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
struct pipe_context *
|
||||
intel_be_create_context(struct drm_api *api, struct pipe_screen *screen)
|
||||
{
|
||||
struct intel_be_context *intel;
|
||||
struct pipe_context *pipe;
|
||||
struct intel_be_device *device = intel_be_device(screen->winsys);
|
||||
|
||||
intel = (struct intel_be_context *)malloc(sizeof(*intel));
|
||||
memset(intel, 0, sizeof(*intel));
|
||||
|
||||
intel_be_init_context(intel, device);
|
||||
|
||||
if (device->softpipe)
|
||||
pipe = softpipe_create(screen);
|
||||
else
|
||||
pipe = i915_create_context(screen, &device->base, &intel->base);
|
||||
|
||||
if (pipe)
|
||||
pipe->priv = intel;
|
||||
|
||||
return pipe;
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
|
||||
#ifndef INTEL_BE_CONTEXT_H
|
||||
#define INTEL_BE_CONTEXT_H
|
||||
|
||||
#include "i915simple/i915_winsys.h"
|
||||
|
||||
struct intel_be_context
|
||||
{
|
||||
/** Interface to i915simple driver */
|
||||
struct i915_winsys base;
|
||||
|
||||
struct intel_be_device *device;
|
||||
struct intel_be_batchbuffer *batch;
|
||||
};
|
||||
|
||||
static INLINE struct intel_be_context *
|
||||
intel_be_context(struct i915_winsys *sws)
|
||||
{
|
||||
return (struct intel_be_context *)sws;
|
||||
}
|
||||
|
||||
/**
|
||||
* Intialize a allocated intel_be_context struct.
|
||||
*
|
||||
* Remember to set the hardware_* functions.
|
||||
*/
|
||||
boolean
|
||||
intel_be_init_context(struct intel_be_context *intel,
|
||||
struct intel_be_device *device);
|
||||
|
||||
#endif
|
|
@ -1,474 +0,0 @@
|
|||
|
||||
#include "intel_be_device.h"
|
||||
|
||||
#include "pipe/internal/p_winsys_screen.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_state.h"
|
||||
#include "pipe/p_inlines.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_debug.h"
|
||||
#include "util/u_math.h"
|
||||
|
||||
#include "intel_be_fence.h"
|
||||
|
||||
#include "i915simple/i915_winsys.h"
|
||||
#include "softpipe/sp_winsys.h"
|
||||
|
||||
#include "intel_be_api.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#define I915_TILING_X 1
|
||||
|
||||
/*
|
||||
* Buffer
|
||||
*/
|
||||
|
||||
static void *
|
||||
intel_be_buffer_map(struct pipe_winsys *winsys,
|
||||
struct pipe_buffer *buf,
|
||||
unsigned flags)
|
||||
{
|
||||
struct intel_be_buffer *buffer = intel_be_buffer(buf);
|
||||
drm_intel_bo *bo = intel_bo(buf);
|
||||
int write = 0;
|
||||
int ret = 0;
|
||||
|
||||
if (flags & PIPE_BUFFER_USAGE_DONTBLOCK) {
|
||||
/* Remove this when drm_intel_bo_map supports DONTBLOCK
|
||||
*/
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (flags & PIPE_BUFFER_USAGE_CPU_WRITE)
|
||||
write = 1;
|
||||
|
||||
if (buffer->map_count)
|
||||
goto out;
|
||||
|
||||
if (buffer->map_gtt)
|
||||
ret = drm_intel_gem_bo_map_gtt(bo);
|
||||
else
|
||||
ret = drm_intel_bo_map(bo, write);
|
||||
|
||||
buffer->ptr = bo->virtual;
|
||||
|
||||
out:
|
||||
if (ret)
|
||||
return NULL;
|
||||
|
||||
buffer->map_count++;
|
||||
return buffer->ptr;
|
||||
}
|
||||
|
||||
static void
|
||||
intel_be_buffer_unmap(struct pipe_winsys *winsys,
|
||||
struct pipe_buffer *buf)
|
||||
{
|
||||
struct intel_be_buffer *buffer = intel_be_buffer(buf);
|
||||
|
||||
if (--buffer->map_count)
|
||||
return;
|
||||
|
||||
if (buffer->map_gtt)
|
||||
drm_intel_gem_bo_unmap_gtt(intel_bo(buf));
|
||||
else
|
||||
drm_intel_bo_unmap(intel_bo(buf));
|
||||
}
|
||||
|
||||
static void
|
||||
intel_be_buffer_destroy(struct pipe_buffer *buf)
|
||||
{
|
||||
drm_intel_bo_unreference(intel_bo(buf));
|
||||
free(buf);
|
||||
}
|
||||
|
||||
static struct pipe_buffer *
|
||||
intel_be_buffer_create(struct pipe_winsys *winsys,
|
||||
unsigned alignment,
|
||||
unsigned usage,
|
||||
unsigned size)
|
||||
{
|
||||
struct intel_be_buffer *buffer = CALLOC_STRUCT(intel_be_buffer);
|
||||
struct intel_be_device *dev = intel_be_device(winsys);
|
||||
drm_intel_bufmgr *pool;
|
||||
char *name;
|
||||
|
||||
if (!buffer)
|
||||
return NULL;
|
||||
|
||||
pipe_reference_init(&buffer->base.reference, 1);
|
||||
buffer->base.alignment = alignment;
|
||||
buffer->base.usage = usage;
|
||||
buffer->base.size = size;
|
||||
buffer->flinked = FALSE;
|
||||
buffer->flink = 0;
|
||||
buffer->map_gtt = FALSE;
|
||||
|
||||
if (usage & I915_BUFFER_USAGE_SCANOUT) {
|
||||
/* Scanout buffer */
|
||||
name = "gallium3d_scanout";
|
||||
pool = dev->pools.gem;
|
||||
} else if (usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_CONSTANT)) {
|
||||
/* Local buffer */
|
||||
name = "gallium3d_local";
|
||||
pool = dev->pools.gem;
|
||||
} else if (usage & PIPE_BUFFER_USAGE_CUSTOM) {
|
||||
/* For vertex buffers */
|
||||
name = "gallium3d_internal_vertex";
|
||||
pool = dev->pools.gem;
|
||||
} else {
|
||||
/* Regular buffers */
|
||||
name = "gallium3d_regular";
|
||||
pool = dev->pools.gem;
|
||||
}
|
||||
|
||||
buffer->bo = drm_intel_bo_alloc(pool, name, size, alignment);
|
||||
if (usage & I915_BUFFER_USAGE_SCANOUT) {
|
||||
unsigned tiling = I915_TILING_X;
|
||||
unsigned stride = 2048 * 4; /* TODO do something smarter here */
|
||||
drm_intel_bo_set_tiling(buffer->bo, &tiling, stride);
|
||||
buffer->map_gtt = TRUE;
|
||||
}
|
||||
|
||||
if (!buffer->bo)
|
||||
goto err;
|
||||
|
||||
return &buffer->base;
|
||||
|
||||
err:
|
||||
free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct pipe_buffer *
|
||||
intel_be_user_buffer_create(struct pipe_winsys *winsys, void *ptr, unsigned bytes)
|
||||
{
|
||||
struct intel_be_buffer *buffer = CALLOC_STRUCT(intel_be_buffer);
|
||||
struct intel_be_device *dev = intel_be_device(winsys);
|
||||
int ret;
|
||||
|
||||
if (!buffer)
|
||||
return NULL;
|
||||
|
||||
pipe_reference_init(&buffer->base.reference, 1);
|
||||
buffer->base.alignment = 0;
|
||||
buffer->base.usage = 0;
|
||||
buffer->base.size = bytes;
|
||||
|
||||
buffer->bo = drm_intel_bo_alloc(dev->pools.gem,
|
||||
"gallium3d_user_buffer",
|
||||
bytes, 0);
|
||||
|
||||
if (!buffer->bo)
|
||||
goto err;
|
||||
|
||||
ret = drm_intel_bo_subdata(buffer->bo,
|
||||
0, bytes, ptr);
|
||||
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
return &buffer->base;
|
||||
|
||||
err:
|
||||
free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct pipe_buffer *
|
||||
intel_be_surface_buffer_create(struct pipe_winsys *winsys,
|
||||
unsigned width, unsigned height,
|
||||
enum pipe_format format,
|
||||
unsigned usage,
|
||||
unsigned tex_usage,
|
||||
unsigned *stride)
|
||||
{
|
||||
struct pipe_format_block block;
|
||||
unsigned buf_usage = 0;
|
||||
unsigned buf_stride = 0;
|
||||
unsigned buf_size = 0;
|
||||
|
||||
pf_get_block(format, &block);
|
||||
buf_stride = pf_get_stride(&block, width);
|
||||
buf_stride = align(buf_stride, 64);
|
||||
|
||||
if (tex_usage & PIPE_TEXTURE_USAGE_PRIMARY) {
|
||||
/* TODO more checks */
|
||||
assert(buf_stride <= 2048*4);
|
||||
assert(height % 8 == 0);
|
||||
buf_stride = 2048 * 4;
|
||||
buf_usage |= I915_BUFFER_USAGE_SCANOUT;
|
||||
}
|
||||
|
||||
buf_size = buf_stride * height;
|
||||
*stride = buf_stride;
|
||||
|
||||
return intel_be_buffer_create(winsys,
|
||||
0,
|
||||
buf_usage,
|
||||
buf_size);
|
||||
}
|
||||
|
||||
static struct pipe_buffer *
|
||||
intel_be_buffer_from_handle(struct drm_api *api,
|
||||
struct pipe_screen *screen,
|
||||
const char* name, unsigned handle)
|
||||
{
|
||||
struct intel_be_device *dev = intel_be_device(screen->winsys);
|
||||
struct intel_be_buffer *buffer = CALLOC_STRUCT(intel_be_buffer);
|
||||
|
||||
if (!buffer)
|
||||
return NULL;
|
||||
|
||||
buffer->bo = drm_intel_bo_gem_create_from_name(dev->pools.gem, name, handle);
|
||||
|
||||
if (!buffer->bo)
|
||||
goto err;
|
||||
|
||||
pipe_reference_init(&buffer->base.reference, 1);
|
||||
buffer->base.screen = screen;
|
||||
buffer->base.alignment = buffer->bo->align;
|
||||
buffer->base.usage = PIPE_BUFFER_USAGE_GPU_READ |
|
||||
PIPE_BUFFER_USAGE_GPU_WRITE |
|
||||
PIPE_BUFFER_USAGE_CPU_READ |
|
||||
PIPE_BUFFER_USAGE_CPU_WRITE;
|
||||
buffer->base.size = buffer->bo->size;
|
||||
|
||||
return &buffer->base;
|
||||
|
||||
err:
|
||||
free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct pipe_texture *
|
||||
intel_be_texture_from_shared_handle(struct drm_api *api,
|
||||
struct pipe_screen *screen,
|
||||
struct pipe_texture *templ,
|
||||
const char* name,
|
||||
unsigned pitch,
|
||||
unsigned handle)
|
||||
{
|
||||
struct pipe_buffer *buffer;
|
||||
|
||||
buffer = intel_be_buffer_from_handle(api,
|
||||
screen,
|
||||
name,
|
||||
handle);
|
||||
if (!buffer)
|
||||
return NULL;
|
||||
|
||||
return screen->texture_blanket(screen, templ, &pitch, buffer);
|
||||
}
|
||||
|
||||
static boolean
|
||||
intel_be_get_texture_buffer(struct drm_api *api,
|
||||
struct pipe_texture *texture,
|
||||
struct pipe_buffer **buffer,
|
||||
unsigned *stride)
|
||||
{
|
||||
struct intel_be_device *dev;
|
||||
|
||||
if (!texture)
|
||||
return FALSE;
|
||||
|
||||
dev = intel_be_device(texture->screen->winsys);
|
||||
if (dev->softpipe)
|
||||
return softpipe_get_texture_buffer(texture, buffer, stride);
|
||||
else
|
||||
return i915_get_texture_buffer(texture, buffer, stride);
|
||||
}
|
||||
|
||||
boolean
|
||||
intel_be_shared_handle_from_texture(struct drm_api *api,
|
||||
struct pipe_screen *screen,
|
||||
struct pipe_texture *texture,
|
||||
unsigned *pitch,
|
||||
unsigned *handle)
|
||||
{
|
||||
struct pipe_buffer *buffer = NULL;
|
||||
struct intel_be_buffer *buf;
|
||||
if (!intel_be_get_texture_buffer(api,
|
||||
texture,
|
||||
&buffer,
|
||||
pitch))
|
||||
return FALSE;
|
||||
|
||||
buf = intel_be_buffer(buffer);
|
||||
if (!buf->flinked) {
|
||||
if (drm_intel_bo_flink(intel_bo(buffer), &buf->flink))
|
||||
return FALSE;
|
||||
buf->flinked = TRUE;
|
||||
}
|
||||
|
||||
*handle = buf->flink;
|
||||
|
||||
pipe_buffer_reference(&buffer, NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
boolean
|
||||
intel_be_local_handle_from_texture(struct drm_api *api,
|
||||
struct pipe_screen *screen,
|
||||
struct pipe_texture *texture,
|
||||
unsigned *pitch,
|
||||
unsigned *handle)
|
||||
{
|
||||
struct pipe_buffer *buffer = NULL;
|
||||
if (!intel_be_get_texture_buffer(api,
|
||||
texture,
|
||||
&buffer,
|
||||
pitch))
|
||||
return FALSE;
|
||||
|
||||
*handle = intel_bo(buffer)->handle;
|
||||
|
||||
pipe_buffer_reference(&buffer, NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fence
|
||||
*/
|
||||
|
||||
static void
|
||||
intel_be_fence_refunref(struct pipe_winsys *sws,
|
||||
struct pipe_fence_handle **ptr,
|
||||
struct pipe_fence_handle *fence)
|
||||
{
|
||||
struct intel_be_fence **p = (struct intel_be_fence **)ptr;
|
||||
struct intel_be_fence *f = (struct intel_be_fence *)fence;
|
||||
|
||||
intel_be_fence_reference(p, f);
|
||||
}
|
||||
|
||||
static int
|
||||
intel_be_fence_signalled(struct pipe_winsys *sws,
|
||||
struct pipe_fence_handle *fence,
|
||||
unsigned flag)
|
||||
{
|
||||
assert(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
intel_be_fence_finish(struct pipe_winsys *sws,
|
||||
struct pipe_fence_handle *fence,
|
||||
unsigned flag)
|
||||
{
|
||||
struct intel_be_fence *f = (struct intel_be_fence *)fence;
|
||||
|
||||
/* fence already expired */
|
||||
if (!f->bo)
|
||||
return 0;
|
||||
|
||||
drm_intel_bo_wait_rendering(f->bo);
|
||||
drm_intel_bo_unreference(f->bo);
|
||||
f->bo = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Misc functions
|
||||
*/
|
||||
|
||||
static void
|
||||
intel_be_destroy_winsys(struct pipe_winsys *winsys)
|
||||
{
|
||||
struct intel_be_device *dev = intel_be_device(winsys);
|
||||
|
||||
drm_intel_bufmgr_destroy(dev->pools.gem);
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
boolean
|
||||
intel_be_init_device(struct intel_be_device *dev, int fd, unsigned id)
|
||||
{
|
||||
dev->fd = fd;
|
||||
dev->id = id;
|
||||
dev->max_batch_size = 16 * 4096;
|
||||
dev->max_vertex_size = 128 * 4096;
|
||||
|
||||
dev->base.buffer_create = intel_be_buffer_create;
|
||||
dev->base.user_buffer_create = intel_be_user_buffer_create;
|
||||
dev->base.buffer_map = intel_be_buffer_map;
|
||||
dev->base.buffer_unmap = intel_be_buffer_unmap;
|
||||
dev->base.buffer_destroy = intel_be_buffer_destroy;
|
||||
|
||||
/* Used by softpipe */
|
||||
dev->base.surface_buffer_create = intel_be_surface_buffer_create;
|
||||
|
||||
dev->base.fence_reference = intel_be_fence_refunref;
|
||||
dev->base.fence_signalled = intel_be_fence_signalled;
|
||||
dev->base.fence_finish = intel_be_fence_finish;
|
||||
|
||||
dev->base.destroy = intel_be_destroy_winsys;
|
||||
|
||||
dev->pools.gem = drm_intel_bufmgr_gem_init(dev->fd, dev->max_batch_size);
|
||||
|
||||
dev->softpipe = debug_get_bool_option("INTEL_SOFTPIPE", FALSE);
|
||||
dev->dump_cmd = debug_get_bool_option("INTEL_DUMP_CMD", FALSE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
intel_be_get_device_id(unsigned int *device_id)
|
||||
{
|
||||
char path[512];
|
||||
FILE *file;
|
||||
void *shutup_gcc;
|
||||
|
||||
/*
|
||||
* FIXME: Fix this up to use a drm ioctl or whatever.
|
||||
*/
|
||||
|
||||
snprintf(path, sizeof(path), "/sys/class/drm/card0/device/device");
|
||||
file = fopen(path, "r");
|
||||
if (!file) {
|
||||
return;
|
||||
}
|
||||
|
||||
shutup_gcc = fgets(path, sizeof(path), file);
|
||||
sscanf(path, "%x", device_id);
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
struct pipe_screen *
|
||||
intel_be_create_screen(struct drm_api *api, int drmFD,
|
||||
struct drm_create_screen_arg *arg)
|
||||
{
|
||||
struct intel_be_device *dev;
|
||||
struct pipe_screen *screen;
|
||||
unsigned int deviceID;
|
||||
|
||||
if (arg != NULL) {
|
||||
switch(arg->mode) {
|
||||
case DRM_CREATE_NORMAL:
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate the private area */
|
||||
dev = malloc(sizeof(*dev));
|
||||
if (!dev)
|
||||
return NULL;
|
||||
memset(dev, 0, sizeof(*dev));
|
||||
|
||||
intel_be_get_device_id(&deviceID);
|
||||
intel_be_init_device(dev, drmFD, deviceID);
|
||||
|
||||
if (dev->softpipe) {
|
||||
screen = softpipe_create_screen(&dev->base);
|
||||
} else
|
||||
screen = i915_create_screen(&dev->base, deviceID);
|
||||
|
||||
return screen;
|
||||
}
|
|
@ -1,107 +0,0 @@
|
|||
|
||||
#ifndef INTEL_DRM_DEVICE_H
|
||||
#define INTEL_DRM_DEVICE_H
|
||||
|
||||
#include "pipe/internal/p_winsys_screen.h"
|
||||
#include "pipe/p_context.h"
|
||||
|
||||
#include "drm.h"
|
||||
#include "intel_bufmgr.h"
|
||||
|
||||
struct drm_api;
|
||||
|
||||
/*
|
||||
* Device
|
||||
*/
|
||||
|
||||
struct intel_be_device
|
||||
{
|
||||
struct pipe_winsys base;
|
||||
|
||||
boolean softpipe;
|
||||
boolean dump_cmd;
|
||||
|
||||
int fd; /**< Drm file discriptor */
|
||||
|
||||
unsigned id;
|
||||
|
||||
size_t max_batch_size;
|
||||
size_t max_vertex_size;
|
||||
|
||||
struct {
|
||||
drm_intel_bufmgr *gem;
|
||||
} pools;
|
||||
};
|
||||
|
||||
static INLINE struct intel_be_device *
|
||||
intel_be_device(struct pipe_winsys *winsys)
|
||||
{
|
||||
return (struct intel_be_device *)winsys;
|
||||
}
|
||||
|
||||
boolean
|
||||
intel_be_init_device(struct intel_be_device *device, int fd, unsigned id);
|
||||
|
||||
/*
|
||||
* Buffer
|
||||
*/
|
||||
|
||||
struct intel_be_buffer {
|
||||
struct pipe_buffer base;
|
||||
void *ptr;
|
||||
unsigned map_count;
|
||||
boolean map_gtt;
|
||||
|
||||
drm_intel_bo *bo;
|
||||
boolean flinked;
|
||||
unsigned flink;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a texture from a shared drm handle.
|
||||
*/
|
||||
struct pipe_texture *
|
||||
intel_be_texture_from_shared_handle(struct drm_api *api,
|
||||
struct pipe_screen *screen,
|
||||
struct pipe_texture *templ,
|
||||
const char* name,
|
||||
unsigned pitch,
|
||||
unsigned handle);
|
||||
|
||||
/**
|
||||
* Gets a shared handle from a texture.
|
||||
*
|
||||
* If texture is destroyed handle may become invalid.
|
||||
*/
|
||||
boolean
|
||||
intel_be_shared_handle_from_texture(struct drm_api *api,
|
||||
struct pipe_screen *screen,
|
||||
struct pipe_texture *texture,
|
||||
unsigned *pitch,
|
||||
unsigned *handle);
|
||||
|
||||
/**
|
||||
* Gets the local handle from a texture. As used by KMS.
|
||||
*
|
||||
* If texture is destroyed handle may become invalid.
|
||||
*/
|
||||
boolean
|
||||
intel_be_local_handle_from_texture(struct drm_api *api,
|
||||
struct pipe_screen *screen,
|
||||
struct pipe_texture *texture,
|
||||
unsigned *pitch,
|
||||
unsigned *handle);
|
||||
|
||||
static INLINE struct intel_be_buffer *
|
||||
intel_be_buffer(struct pipe_buffer *buf)
|
||||
{
|
||||
return (struct intel_be_buffer *)buf;
|
||||
}
|
||||
|
||||
static INLINE drm_intel_bo *
|
||||
intel_bo(struct pipe_buffer *buf)
|
||||
{
|
||||
return intel_be_buffer(buf)->bo;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,34 +0,0 @@
|
|||
|
||||
#ifndef INTEL_BE_FENCE_H
|
||||
#define INTEL_BE_FENCE_H
|
||||
|
||||
#include "pipe/p_defines.h"
|
||||
|
||||
#include "drm.h"
|
||||
#include "intel_bufmgr.h"
|
||||
|
||||
/**
|
||||
* Because gem does not have fence's we have to create our own fences.
|
||||
*
|
||||
* They work by keeping the batchbuffer around and checking if that has
|
||||
* been idled. If bo is NULL fence has expired.
|
||||
*/
|
||||
struct intel_be_fence
|
||||
{
|
||||
struct pipe_reference reference;
|
||||
drm_intel_bo *bo;
|
||||
};
|
||||
|
||||
static INLINE void
|
||||
intel_be_fence_reference(struct intel_be_fence **ptr, struct intel_be_fence *f)
|
||||
{
|
||||
struct intel_be_fence *old_fence = *ptr;
|
||||
|
||||
if (pipe_reference((struct pipe_reference**)ptr, &f->reference)) {
|
||||
if (old_fence->bo)
|
||||
drm_intel_bo_unreference(old_fence->bo);
|
||||
free(old_fence);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,202 @@
|
|||
|
||||
#include "state_tracker/drm_api.h"
|
||||
|
||||
#include "intel_drm_winsys.h"
|
||||
#include "util/u_memory.h"
|
||||
|
||||
#include "i915simple/i915_context.h"
|
||||
#include "i915simple/i915_screen.h"
|
||||
|
||||
|
||||
/*
|
||||
* Helper functions
|
||||
*/
|
||||
|
||||
|
||||
static void
|
||||
intel_drm_get_device_id(unsigned int *device_id)
|
||||
{
|
||||
char path[512];
|
||||
FILE *file;
|
||||
void *shutup_gcc;
|
||||
|
||||
/*
|
||||
* FIXME: Fix this up to use a drm ioctl or whatever.
|
||||
*/
|
||||
|
||||
snprintf(path, sizeof(path), "/sys/class/drm/card0/device/device");
|
||||
file = fopen(path, "r");
|
||||
if (!file) {
|
||||
return;
|
||||
}
|
||||
|
||||
shutup_gcc = fgets(path, sizeof(path), file);
|
||||
sscanf(path, "%x", device_id);
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
static struct intel_buffer *
|
||||
intel_drm_buffer_from_handle(struct intel_drm_winsys *idws,
|
||||
const char* name, unsigned handle)
|
||||
{
|
||||
struct intel_drm_buffer *buf = CALLOC_STRUCT(intel_drm_buffer);
|
||||
|
||||
if (!buf)
|
||||
return NULL;
|
||||
|
||||
buf->magic = 0xDEAD1337;
|
||||
buf->bo = drm_intel_bo_gem_create_from_name(idws->pools.gem, name, handle);
|
||||
buf->flinked = TRUE;
|
||||
buf->flink = handle;
|
||||
|
||||
if (!buf->bo)
|
||||
goto err;
|
||||
|
||||
return (struct intel_buffer *)buf;
|
||||
|
||||
err:
|
||||
FREE(buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Exported functions
|
||||
*/
|
||||
|
||||
|
||||
static struct pipe_texture *
|
||||
intel_drm_texture_from_shared_handle(struct drm_api *api,
|
||||
struct pipe_screen *screen,
|
||||
struct pipe_texture *templ,
|
||||
const char* name,
|
||||
unsigned pitch,
|
||||
unsigned handle)
|
||||
{
|
||||
struct intel_drm_winsys *idws = intel_drm_winsys(i915_screen(screen)->iws);
|
||||
struct intel_buffer *buffer;
|
||||
|
||||
buffer = intel_drm_buffer_from_handle(idws, name, handle);
|
||||
if (!buffer)
|
||||
return NULL;
|
||||
|
||||
return i915_texture_blanket_intel(screen, templ, pitch, buffer);
|
||||
}
|
||||
|
||||
static boolean
|
||||
intel_drm_shared_handle_from_texture(struct drm_api *api,
|
||||
struct pipe_screen *screen,
|
||||
struct pipe_texture *texture,
|
||||
unsigned *pitch,
|
||||
unsigned *handle)
|
||||
{
|
||||
struct intel_drm_buffer *buf = NULL;
|
||||
struct intel_buffer *buffer = NULL;
|
||||
if (!i915_get_texture_buffer_intel(texture, &buffer, pitch))
|
||||
return FALSE;
|
||||
|
||||
buf = intel_drm_buffer(buffer);
|
||||
if (!buf->flinked) {
|
||||
if (drm_intel_bo_flink(buf->bo, &buf->flink))
|
||||
return FALSE;
|
||||
buf->flinked = TRUE;
|
||||
}
|
||||
|
||||
*handle = buf->flink;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static boolean
|
||||
intel_drm_local_handle_from_texture(struct drm_api *api,
|
||||
struct pipe_screen *screen,
|
||||
struct pipe_texture *texture,
|
||||
unsigned *pitch,
|
||||
unsigned *handle)
|
||||
{
|
||||
struct intel_buffer *buffer = NULL;
|
||||
if (!i915_get_texture_buffer_intel(texture, &buffer, pitch))
|
||||
return FALSE;
|
||||
|
||||
*handle = intel_drm_buffer(buffer)->bo->handle;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
intel_drm_winsys_destroy(struct intel_winsys *iws)
|
||||
{
|
||||
struct intel_drm_winsys *idws = intel_drm_winsys(iws);
|
||||
|
||||
drm_intel_bufmgr_destroy(idws->pools.gem);
|
||||
|
||||
FREE(idws);
|
||||
}
|
||||
|
||||
static struct pipe_screen *
|
||||
intel_drm_create_screen(struct drm_api *api, int drmFD,
|
||||
struct drm_create_screen_arg *arg)
|
||||
{
|
||||
struct intel_drm_winsys *idws;
|
||||
unsigned int deviceID;
|
||||
|
||||
if (arg != NULL) {
|
||||
switch(arg->mode) {
|
||||
case DRM_CREATE_NORMAL:
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
idws = CALLOC_STRUCT(intel_drm_winsys);
|
||||
if (!idws)
|
||||
return NULL;
|
||||
|
||||
intel_drm_get_device_id(&deviceID);
|
||||
|
||||
intel_drm_winsys_init_batchbuffer_functions(idws);
|
||||
intel_drm_winsys_init_buffer_functions(idws);
|
||||
intel_drm_winsys_init_fence_functions(idws);
|
||||
|
||||
idws->fd = drmFD;
|
||||
idws->id = deviceID;
|
||||
idws->max_batch_size = 16 * 4096;
|
||||
|
||||
idws->base.destroy = intel_drm_winsys_destroy;
|
||||
|
||||
idws->pools.gem = drm_intel_bufmgr_gem_init(idws->fd, idws->max_batch_size);
|
||||
|
||||
idws->softpipe = FALSE;
|
||||
idws->dump_cmd = debug_get_bool_option("INTEL_DUMP_CMD", FALSE);
|
||||
|
||||
return i915_create_screen(&idws->base, deviceID);
|
||||
}
|
||||
|
||||
static struct pipe_context *
|
||||
intel_drm_create_context(struct drm_api *api, struct pipe_screen *screen)
|
||||
{
|
||||
return i915_create_context(screen);
|
||||
}
|
||||
|
||||
static void
|
||||
destroy(struct drm_api *api)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
struct drm_api intel_drm_api =
|
||||
{
|
||||
.create_context = intel_drm_create_context,
|
||||
.create_screen = intel_drm_create_screen,
|
||||
.texture_from_shared_handle = intel_drm_texture_from_shared_handle,
|
||||
.shared_handle_from_texture = intel_drm_shared_handle_from_texture,
|
||||
.local_handle_from_texture = intel_drm_local_handle_from_texture,
|
||||
.destroy = destroy,
|
||||
};
|
||||
|
||||
struct drm_api *
|
||||
drm_api_create()
|
||||
{
|
||||
return &intel_drm_api;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue