Merge branch 'master' into r300-compiler

Conflicts:
	src/gallium/drivers/r300/r300_tgsi_to_rc.c
This commit is contained in:
Nicolai Hähnle 2009-09-06 13:15:04 +02:00
commit f02f63997c
295 changed files with 17391 additions and 12739 deletions

View File

@ -126,6 +126,7 @@ AC_ARG_ENABLE([32-bit],
if test "x$enable_32bit" = xyes; then if test "x$enable_32bit" = xyes; then
if test "x$GCC" = xyes; then if test "x$GCC" = xyes; then
CFLAGS="$CFLAGS -m32" CFLAGS="$CFLAGS -m32"
ARCH_FLAGS="$ARCH_FLAGS -m32"
fi fi
if test "x$GXX" = xyes; then if test "x$GXX" = xyes; then
CXXFLAGS="$CXXFLAGS -m32" CXXFLAGS="$CXXFLAGS -m32"

View File

@ -39,7 +39,6 @@ a:visited {
<ul> <ul>
<li><a href="download.html" target="MainFrame">Downloading / Unpacking</a> <li><a href="download.html" target="MainFrame">Downloading / Unpacking</a>
<li><a href="install.html" target="MainFrame">Compiling / Installing</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> <li><a href="precompiled.html" target="MainFrame">Precompiled Libraries</a>
</ul> </ul>
@ -68,6 +67,7 @@ a:visited {
<li><a href="repository.html" target="MainFrame">Source Code Repository</a> <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="memory.html" target="MainFrame">DRI Memory Management</a>
<li><a href="shading.html" target="MainFrame">Shading Language</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="utilities.html" target="MainFrame">Utilities</a>
<li><a href="helpwanted.html" target="MainFrame">Help Wanted</a> <li><a href="helpwanted.html" target="MainFrame">Help Wanted</a>
<li><a href="devinfo.html" target="MainFrame">Development Notes</a> <li><a href="devinfo.html" target="MainFrame">Development Notes</a>

View File

@ -9,14 +9,14 @@
<H1>Downloading</H1> <H1>Downloading</H1>
<p> <p>
Primary download site: Primary Mesa download site:
<a href="http://sourceforge.net/project/showfiles.php?group_id=3" <a href="ftp://ftp.freedesktop.org/pub/mesa/"
target="_parent">SourceForge</a> target="_parent">freedesktop.org</a> (FTP)
</p> </p>
<p> <p>
When a new release is coming, release candidates (betas) can be found When a new release is coming, release candidates (betas) may be found
<a href="http://www.mesa3d.org/beta/">here</a>. <a href="ftp://ftp.freedesktop.org/pub/mesa/beta/" target="_parent">here</a>.
</p> </p>

View File

@ -11,6 +11,13 @@
<H1>News</H1> <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> <h2>July 17, 2009</h2>
<p> <p>
<a href="relnotes-7.5.html">Mesa 7.5</a> is released. <a href="relnotes-7.5.html">Mesa 7.5</a> is released.

View File

@ -9,17 +9,11 @@
<H1>Precompiled Libraries</H1> <H1>Precompiled Libraries</H1>
<p> <p>
In general, precompiled libraries are not available. In general, precompiled Mesa libraries are not available.
However, people occasionally prepare packages of precompiled libraries
for some systems.
</p> </p>
<H2>Mesa-6.0 for Solaris</H2>
<p> <p>
Steve Christensen has submitted precompiled Mesa-6.0 libraries for However, some Linux distros (such as Ubuntu) seem to closely track
Solaris at <a href="http://sunfreeware.com/" target="_parent"> Mesa and often have the latest Mesa release available as an update.
sunfreeware.com</a>.
</p> </p>
</BODY> </BODY>

View File

@ -8,7 +8,7 @@
<body bgcolor="#eeeeee"> <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> <p>
Mesa 7.5.1 is a bug-fix release fixing issues found since the 7.5 release. 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> <h2>MD5 checksums</h2>
<pre> <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> </pre>
@ -54,12 +62,11 @@ tbd
<li>Fixed Gallium glBitmap() Z position bug <li>Fixed Gallium glBitmap() Z position bug
<li>Setting arrays of sampler uniforms did not work <li>Setting arrays of sampler uniforms did not work
<li>Selection/Feedback mode didn't handle polygon culling correctly (bug 16866) <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> </ul>
<h2>Changes</h2>
<ul>
</ul>
</body> </body>
</html> </html>

View File

@ -36,18 +36,25 @@ tbd
<ul> <ul>
<li><a href="openvg.html">OpenVG</a> front-end (state tracker for Gallium). <li><a href="openvg.html">OpenVG</a> front-end (state tracker for Gallium).
This was written by Zack Rusin at Tungsten Graphics. 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 and GL_APPLE_vertex_array_object extensions
<li>GL_ARB_vertex_array_object for Gallium drivers, software drivers and (supported in Gallium drivers, Intel DRI drivers, and software drivers)</li>
Intel DRI drivers. <li>GL_ARB_copy_buffer extension
<li>GL_ARB_copy_buffer extension (supported in Gallium and swrast drivers) (supported in Gallium drivers, Intel DRI drivers, and software drivers)</li>
<LI>GL_ARB_map_buffer_range extension (supported in Gallium and software drivers) <li>GL_ARB_map_buffer_range extension
<li>GL_EXT_provoking_vertex extension (supported in Gallium and software drivers) (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>Rewritten radeon/r200/r300 driver using a buffer manager
<li>radeon/r200/r300 GL_EXT_framebuffer_object support when used with <li>radeon/r200/r300 GL_EXT_framebuffer_object support when used with
kernel memory manager kernel memory manager
<li>r300 driver support for GL_EXT_vertex_array_bgra, GL_EXT_texture_sRGB <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 <li>i915/945 driver support for GL_ARB_point_sprite, GL_EXT_stencil_two_side
and GL_ATI_separate_stencil extensions 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 <li>Added configure --with-max-width=W, --with-max-height=H options to specify
max framebuffer, viewport size. max framebuffer, viewport size.
</ul> </ul>

View File

@ -92,6 +92,12 @@ static void Init(void)
numObjects = 10; numObjects = 10;
InitObjects(numObjects); InitObjects(numObjects);
glGetIntegerv(GL_VIEWPORT, vp); 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) static void Reshape(int width, int height)

View File

@ -127,7 +127,7 @@ Init( void )
if (!glutExtensionSupported("GL_EXT_framebuffer_object")) { if (!glutExtensionSupported("GL_EXT_framebuffer_object")) {
printf("GL_EXT_framebuffer_object not found!\n"); printf("GL_EXT_framebuffer_object not found!\n");
/*exit(0);*/ exit(0);
} }
printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));

View File

@ -371,11 +371,11 @@ int main( int argc, char *argv[] )
glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE ); glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
if (glutCreateWindow(argv[0]) <= 0) { if (glutCreateWindow(argv[0]) <= 0) {
glewInit();
printf("Couldn't create window\n"); printf("Couldn't create window\n");
exit(0); exit(0);
} }
glewInit();
gl_version = atof( (const char *) glGetString( GL_VERSION ) ); gl_version = atof( (const char *) glGetString( GL_VERSION ) );
if ( (gl_version < 1.3) if ( (gl_version < 1.3)
&& !glutExtensionSupported("GL_ARB_texture_compression") ) { && !glutExtensionSupported("GL_ARB_texture_compression") ) {

View File

@ -24,6 +24,8 @@ static void Display(void)
glClearColor(0.5, 0.5, 0.5, 1.0); glClearColor(0.5, 0.5, 0.5, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
/* draw a sphere */ /* draw a sphere */
glViewport(0, 0, 100, 100); glViewport(0, 0, 100, 100);
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);
@ -46,9 +48,12 @@ static void Display(void)
/* draw depth image with scaling (into z buffer) */ /* draw depth image with scaling (into z buffer) */
glPixelZoom(4.0, 4.0); glPixelZoom(4.0, 4.0);
glColor4f(1, 0, 0, 0);
glWindowPos2i(100, 0); glWindowPos2i(100, 0);
glDrawPixels(100, 100, GL_DEPTH_COMPONENT, GL_FLOAT, depth); glDrawPixels(100, 100, GL_DEPTH_COMPONENT, GL_FLOAT, depth);
glDisable(GL_DEPTH_TEST);
/* read back scaled depth image */ /* read back scaled depth image */
glReadPixels(100, 0, 400, 400, GL_DEPTH_COMPONENT, GL_FLOAT, depth2); glReadPixels(100, 0, 400, 400, GL_DEPTH_COMPONENT, GL_FLOAT, depth2);
/* draw as luminance */ /* draw as luminance */
@ -96,7 +101,6 @@ static void Init(void)
glLightfv(GL_LIGHT0, GL_POSITION, pos); glLightfv(GL_LIGHT0, GL_POSITION, pos);
glEnable(GL_LIGHTING); glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0); glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
} }

72
scons/llvm.py Normal file
View File

@ -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:

View File

@ -187,11 +187,7 @@ TGSI Instruction Specification
1.2.6 CND0 - Condition Zero 1.2.6 CND0 - Condition Zero
dst.x = (src2.x >= 0.0) ? src0.x : src1.x Removed. Use (CMP src2, src1, src0) instead.
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
1.2.7 DOT2ADD - 2-component Dot Product And Add 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 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 1.18.2 LOGP - Logarithm Base 2
Alias for LG2. Use LOG. See also 1.19.4.
1.19 vs_2_0 1.19 vs_2_0
@ -1053,6 +1049,16 @@ TGSI Instruction Specification
Alias for ARR. 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 2 Explanation of symbols used
============================== ==============================

View File

@ -43,6 +43,7 @@ struct dump_ctx
struct tgsi_iterate_context iter; struct tgsi_iterate_context iter;
uint instno; uint instno;
int indent;
uint indentation; uint indentation;
@ -335,14 +336,6 @@ tgsi_dump_immediate(
iter_immediate( &ctx.iter, (struct tgsi_full_immediate *)imm ); 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 static boolean
iter_instruction( iter_instruction(
struct tgsi_iterate_context *iter, struct tgsi_iterate_context *iter,
@ -350,22 +343,19 @@ iter_instruction(
{ {
struct dump_ctx *ctx = (struct dump_ctx *) iter; struct dump_ctx *ctx = (struct dump_ctx *) iter;
uint instno = ctx->instno++; uint instno = ctx->instno++;
const struct tgsi_opcode_info *info = tgsi_get_opcode_info( inst->Instruction.Opcode );
uint i; uint i;
boolean first_reg = TRUE; boolean first_reg = TRUE;
INSTID( instno ); INSTID( instno );
TXT( ": " ); TXT( ": " );
/* update indentation */ ctx->indent -= info->pre_dedent;
if (inst->Instruction.Opcode == TGSI_OPCODE_ENDIF || for(i = 0; (int)i < ctx->indent; ++i)
inst->Instruction.Opcode == TGSI_OPCODE_ENDFOR || TXT( " " );
inst->Instruction.Opcode == TGSI_OPCODE_ENDLOOP) { ctx->indent += info->post_indent;
ctx->indentation -= indent_spaces;
} TXT( info->mnemonic );
indent(ctx);
TXT( tgsi_get_opcode_info( inst->Instruction.Opcode )->mnemonic );
switch (inst->Instruction.Saturate) { switch (inst->Instruction.Saturate) {
case TGSI_SAT_NONE: case TGSI_SAT_NONE:
@ -526,6 +516,7 @@ tgsi_dump_instruction(
struct dump_ctx ctx; struct dump_ctx ctx;
ctx.instno = instno; ctx.instno = instno;
ctx.indent = 0;
ctx.printf = dump_ctx_printf; ctx.printf = dump_ctx_printf;
ctx.indentation = 0; ctx.indentation = 0;
@ -559,6 +550,7 @@ tgsi_dump(
ctx.iter.epilog = NULL; ctx.iter.epilog = NULL;
ctx.instno = 0; ctx.instno = 0;
ctx.indent = 0;
ctx.printf = dump_ctx_printf; ctx.printf = dump_ctx_printf;
ctx.indentation = 0; ctx.indentation = 0;
@ -612,6 +604,7 @@ tgsi_dump_str(
ctx.base.iter.epilog = NULL; ctx.base.iter.epilog = NULL;
ctx.base.instno = 0; ctx.base.instno = 0;
ctx.base.indent = 0;
ctx.base.printf = &str_dump_ctx_printf; ctx.base.printf = &str_dump_ctx_printf;
ctx.base.indentation = 0; ctx.base.indentation = 0;

View File

@ -2329,16 +2329,6 @@ exec_instruction(
} }
break; 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: case TGSI_OPCODE_DP2A:
FETCH( &r[0], 0, CHAN_X ); FETCH( &r[0], 0, CHAN_X );
FETCH( &r[1], 1, CHAN_X ); FETCH( &r[1], 1, CHAN_X );
@ -3104,6 +3094,12 @@ exec_instruction(
break; break;
case TGSI_OPCODE_BGNFOR: 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) */ /* fall-through (for now) */
case TGSI_OPCODE_BGNLOOP: case TGSI_OPCODE_BGNLOOP:
/* push LoopMask and ContMasks */ /* push LoopMask and ContMasks */
@ -3111,18 +3107,42 @@ exec_instruction(
mach->LoopStack[mach->LoopStackTop++] = mach->LoopMask; mach->LoopStack[mach->LoopStackTop++] = mach->LoopMask;
assert(mach->ContStackTop < TGSI_EXEC_MAX_LOOP_NESTING); assert(mach->ContStackTop < TGSI_EXEC_MAX_LOOP_NESTING);
mach->ContStack[mach->ContStackTop++] = mach->ContMask; mach->ContStack[mach->ContStackTop++] = mach->ContMask;
assert(mach->LoopLabelStackTop < TGSI_EXEC_MAX_LOOP_NESTING);
mach->LoopLabelStack[mach->LoopLabelStackTop++] = *pc - 1;
break; break;
case TGSI_OPCODE_ENDFOR: case TGSI_OPCODE_ENDFOR:
/* fall-through (for now at least) */ assert(mach->LoopCounterStackTop > 0);
case TGSI_OPCODE_ENDLOOP: 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 */ /* Restore ContMask, but don't pop */
assert(mach->ContStackTop > 0); assert(mach->ContStackTop > 0);
mach->ContMask = mach->ContStack[mach->ContStackTop - 1]; mach->ContMask = mach->ContStack[mach->ContStackTop - 1];
UPDATE_EXEC_MASK(mach); UPDATE_EXEC_MASK(mach);
if (mach->ExecMask) { if (mach->ExecMask) {
/* repeat loop: jump to instruction just past BGNLOOP */ /* 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 { else {
/* exit loop: pop LoopMask */ /* exit loop: pop LoopMask */
@ -3131,6 +3151,33 @@ exec_instruction(
/* pop ContMask */ /* pop ContMask */
assert(mach->ContStackTop > 0); assert(mach->ContStackTop > 0);
mach->ContMask = mach->ContStack[--mach->ContStackTop]; 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); UPDATE_EXEC_MASK(mach);
break; break;

View File

@ -232,6 +232,14 @@ struct tgsi_exec_machine
uint LoopStack[TGSI_EXEC_MAX_LOOP_NESTING]; uint LoopStack[TGSI_EXEC_MAX_LOOP_NESTING];
int LoopStackTop; 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) */ /** Loop continue mask stack (see comments in tgsi_exec.c) */
uint ContStack[TGSI_EXEC_MAX_LOOP_NESTING]; uint ContStack[TGSI_EXEC_MAX_LOOP_NESTING];
int ContStackTop; int ContStackTop;

View File

@ -31,125 +31,125 @@
static const struct tgsi_opcode_info opcode_info[TGSI_OPCODE_LAST] = static const struct tgsi_opcode_info opcode_info[TGSI_OPCODE_LAST] =
{ {
{ 1, 1, 0, 0, "ARL", TGSI_OPCODE_ARL }, { 1, 1, 0, 0, 0, 0, "ARL", TGSI_OPCODE_ARL },
{ 1, 1, 0, 0, "MOV", TGSI_OPCODE_MOV }, { 1, 1, 0, 0, 0, 0, "MOV", TGSI_OPCODE_MOV },
{ 1, 1, 0, 0, "LIT", TGSI_OPCODE_LIT }, { 1, 1, 0, 0, 0, 0, "LIT", TGSI_OPCODE_LIT },
{ 1, 1, 0, 0, "RCP", TGSI_OPCODE_RCP }, { 1, 1, 0, 0, 0, 0, "RCP", TGSI_OPCODE_RCP },
{ 1, 1, 0, 0, "RSQ", TGSI_OPCODE_RSQ }, { 1, 1, 0, 0, 0, 0, "RSQ", TGSI_OPCODE_RSQ },
{ 1, 1, 0, 0, "EXP", TGSI_OPCODE_EXP }, { 1, 1, 0, 0, 0, 0, "EXP", TGSI_OPCODE_EXP },
{ 1, 1, 0, 0, "LOG", TGSI_OPCODE_LOG }, { 1, 1, 0, 0, 0, 0, "LOG", TGSI_OPCODE_LOG },
{ 1, 2, 0, 0, "MUL", TGSI_OPCODE_MUL }, { 1, 2, 0, 0, 0, 0, "MUL", TGSI_OPCODE_MUL },
{ 1, 2, 0, 0, "ADD", TGSI_OPCODE_ADD }, { 1, 2, 0, 0, 0, 0, "ADD", TGSI_OPCODE_ADD },
{ 1, 2, 0, 0, "DP3", TGSI_OPCODE_DP3 }, { 1, 2, 0, 0, 0, 0, "DP3", TGSI_OPCODE_DP3 },
{ 1, 2, 0, 0, "DP4", TGSI_OPCODE_DP4 }, { 1, 2, 0, 0, 0, 0, "DP4", TGSI_OPCODE_DP4 },
{ 1, 2, 0, 0, "DST", TGSI_OPCODE_DST }, { 1, 2, 0, 0, 0, 0, "DST", TGSI_OPCODE_DST },
{ 1, 2, 0, 0, "MIN", TGSI_OPCODE_MIN }, { 1, 2, 0, 0, 0, 0, "MIN", TGSI_OPCODE_MIN },
{ 1, 2, 0, 0, "MAX", TGSI_OPCODE_MAX }, { 1, 2, 0, 0, 0, 0, "MAX", TGSI_OPCODE_MAX },
{ 1, 2, 0, 0, "SLT", TGSI_OPCODE_SLT }, { 1, 2, 0, 0, 0, 0, "SLT", TGSI_OPCODE_SLT },
{ 1, 2, 0, 0, "SGE", TGSI_OPCODE_SGE }, { 1, 2, 0, 0, 0, 0, "SGE", TGSI_OPCODE_SGE },
{ 1, 3, 0, 0, "MAD", TGSI_OPCODE_MAD }, { 1, 3, 0, 0, 0, 0, "MAD", TGSI_OPCODE_MAD },
{ 1, 2, 0, 0, "SUB", TGSI_OPCODE_SUB }, { 1, 2, 0, 0, 0, 0, "SUB", TGSI_OPCODE_SUB },
{ 1, 3, 0, 0, "LRP", TGSI_OPCODE_LRP }, { 1, 3, 0, 0, 0, 0, "LRP", TGSI_OPCODE_LRP },
{ 1, 3, 0, 0, "CND", TGSI_OPCODE_CND }, { 1, 3, 0, 0, 0, 0, "CND", TGSI_OPCODE_CND },
{ 1, 3, 0, 0, "CND0", TGSI_OPCODE_CND0 }, { 0, 0, 0, 0, 0, 0, "", 20 }, /* removed */
{ 1, 3, 0, 0, "DP2A", TGSI_OPCODE_DP2A }, { 1, 3, 0, 0, 0, 0, "DP2A", TGSI_OPCODE_DP2A },
{ 0, 0, 0, 0, "", 22 }, /* removed */ { 0, 0, 0, 0, 0, 0, "", 22 }, /* removed */
{ 0, 0, 0, 0, "", 23 }, /* removed */ { 0, 0, 0, 0, 0, 0, "", 23 }, /* removed */
{ 1, 1, 0, 0, "FRC", TGSI_OPCODE_FRC }, { 1, 1, 0, 0, 0, 0, "FRC", TGSI_OPCODE_FRC },
{ 1, 3, 0, 0, "CLAMP", TGSI_OPCODE_CLAMP }, { 1, 3, 0, 0, 0, 0, "CLAMP", TGSI_OPCODE_CLAMP },
{ 1, 1, 0, 0, "FLR", TGSI_OPCODE_FLR }, { 1, 1, 0, 0, 0, 0, "FLR", TGSI_OPCODE_FLR },
{ 1, 1, 0, 0, "ROUND", TGSI_OPCODE_ROUND }, { 1, 1, 0, 0, 0, 0, "ROUND", TGSI_OPCODE_ROUND },
{ 1, 1, 0, 0, "EX2", TGSI_OPCODE_EX2 }, { 1, 1, 0, 0, 0, 0, "EX2", TGSI_OPCODE_EX2 },
{ 1, 1, 0, 0, "LG2", TGSI_OPCODE_LG2 }, { 1, 1, 0, 0, 0, 0, "LG2", TGSI_OPCODE_LG2 },
{ 1, 2, 0, 0, "POW", TGSI_OPCODE_POW }, { 1, 2, 0, 0, 0, 0, "POW", TGSI_OPCODE_POW },
{ 1, 2, 0, 0, "XPD", TGSI_OPCODE_XPD }, { 1, 2, 0, 0, 0, 0, "XPD", TGSI_OPCODE_XPD },
{ 0, 0, 0, 0, "", 32 }, /* removed */ { 0, 0, 0, 0, 0, 0, "", 32 }, /* removed */
{ 1, 1, 0, 0, "ABS", TGSI_OPCODE_ABS }, { 1, 1, 0, 0, 0, 0, "ABS", TGSI_OPCODE_ABS },
{ 1, 1, 0, 0, "RCC", TGSI_OPCODE_RCC }, { 1, 1, 0, 0, 0, 0, "RCC", TGSI_OPCODE_RCC },
{ 1, 2, 0, 0, "DPH", TGSI_OPCODE_DPH }, { 1, 2, 0, 0, 0, 0, "DPH", TGSI_OPCODE_DPH },
{ 1, 1, 0, 0, "COS", TGSI_OPCODE_COS }, { 1, 1, 0, 0, 0, 0, "COS", TGSI_OPCODE_COS },
{ 1, 1, 0, 0, "DDX", TGSI_OPCODE_DDX }, { 1, 1, 0, 0, 0, 0, "DDX", TGSI_OPCODE_DDX },
{ 1, 1, 0, 0, "DDY", TGSI_OPCODE_DDY }, { 1, 1, 0, 0, 0, 0, "DDY", TGSI_OPCODE_DDY },
{ 0, 0, 0, 0, "KILP", TGSI_OPCODE_KILP }, { 0, 0, 0, 0, 0, 0, "KILP", TGSI_OPCODE_KILP },
{ 1, 1, 0, 0, "PK2H", TGSI_OPCODE_PK2H }, { 1, 1, 0, 0, 0, 0, "PK2H", TGSI_OPCODE_PK2H },
{ 1, 1, 0, 0, "PK2US", TGSI_OPCODE_PK2US }, { 1, 1, 0, 0, 0, 0, "PK2US", TGSI_OPCODE_PK2US },
{ 1, 1, 0, 0, "PK4B", TGSI_OPCODE_PK4B }, { 1, 1, 0, 0, 0, 0, "PK4B", TGSI_OPCODE_PK4B },
{ 1, 1, 0, 0, "PK4UB", TGSI_OPCODE_PK4UB }, { 1, 1, 0, 0, 0, 0, "PK4UB", TGSI_OPCODE_PK4UB },
{ 1, 2, 0, 0, "RFL", TGSI_OPCODE_RFL }, { 1, 2, 0, 0, 0, 0, "RFL", TGSI_OPCODE_RFL },
{ 1, 2, 0, 0, "SEQ", TGSI_OPCODE_SEQ }, { 1, 2, 0, 0, 0, 0, "SEQ", TGSI_OPCODE_SEQ },
{ 1, 2, 0, 0, "SFL", TGSI_OPCODE_SFL }, { 1, 2, 0, 0, 0, 0, "SFL", TGSI_OPCODE_SFL },
{ 1, 2, 0, 0, "SGT", TGSI_OPCODE_SGT }, { 1, 2, 0, 0, 0, 0, "SGT", TGSI_OPCODE_SGT },
{ 1, 1, 0, 0, "SIN", TGSI_OPCODE_SIN }, { 1, 1, 0, 0, 0, 0, "SIN", TGSI_OPCODE_SIN },
{ 1, 2, 0, 0, "SLE", TGSI_OPCODE_SLE }, { 1, 2, 0, 0, 0, 0, "SLE", TGSI_OPCODE_SLE },
{ 1, 2, 0, 0, "SNE", TGSI_OPCODE_SNE }, { 1, 2, 0, 0, 0, 0, "SNE", TGSI_OPCODE_SNE },
{ 1, 2, 0, 0, "STR", TGSI_OPCODE_STR }, { 1, 2, 0, 0, 0, 0, "STR", TGSI_OPCODE_STR },
{ 1, 2, 1, 0, "TEX", TGSI_OPCODE_TEX }, { 1, 2, 1, 0, 0, 0, "TEX", TGSI_OPCODE_TEX },
{ 1, 4, 1, 0, "TXD", TGSI_OPCODE_TXD }, { 1, 4, 1, 0, 0, 0, "TXD", TGSI_OPCODE_TXD },
{ 1, 2, 1, 0, "TXP", TGSI_OPCODE_TXP }, { 1, 2, 1, 0, 0, 0, "TXP", TGSI_OPCODE_TXP },
{ 1, 1, 0, 0, "UP2H", TGSI_OPCODE_UP2H }, { 1, 1, 0, 0, 0, 0, "UP2H", TGSI_OPCODE_UP2H },
{ 1, 1, 0, 0, "UP2US", TGSI_OPCODE_UP2US }, { 1, 1, 0, 0, 0, 0, "UP2US", TGSI_OPCODE_UP2US },
{ 1, 1, 0, 0, "UP4B", TGSI_OPCODE_UP4B }, { 1, 1, 0, 0, 0, 0, "UP4B", TGSI_OPCODE_UP4B },
{ 1, 1, 0, 0, "UP4UB", TGSI_OPCODE_UP4UB }, { 1, 1, 0, 0, 0, 0, "UP4UB", TGSI_OPCODE_UP4UB },
{ 1, 3, 0, 0, "X2D", TGSI_OPCODE_X2D }, { 1, 3, 0, 0, 0, 0, "X2D", TGSI_OPCODE_X2D },
{ 1, 1, 0, 0, "ARA", TGSI_OPCODE_ARA }, { 1, 1, 0, 0, 0, 0, "ARA", TGSI_OPCODE_ARA },
{ 1, 1, 0, 0, "ARR", TGSI_OPCODE_ARR }, { 1, 1, 0, 0, 0, 0, "ARR", TGSI_OPCODE_ARR },
{ 0, 1, 0, 0, "BRA", TGSI_OPCODE_BRA }, { 0, 1, 0, 0, 0, 0, "BRA", TGSI_OPCODE_BRA },
{ 0, 0, 0, 1, "CAL", TGSI_OPCODE_CAL }, { 0, 0, 0, 1, 0, 0, "CAL", TGSI_OPCODE_CAL },
{ 0, 0, 0, 0, "RET", TGSI_OPCODE_RET }, { 0, 0, 0, 0, 0, 0, "RET", TGSI_OPCODE_RET },
{ 1, 1, 0, 0, "SSG", TGSI_OPCODE_SSG }, { 1, 1, 0, 0, 0, 0, "SSG", TGSI_OPCODE_SSG },
{ 1, 3, 0, 0, "CMP", TGSI_OPCODE_CMP }, { 1, 3, 0, 0, 0, 0, "CMP", TGSI_OPCODE_CMP },
{ 1, 1, 0, 0, "SCS", TGSI_OPCODE_SCS }, { 1, 1, 0, 0, 0, 0, "SCS", TGSI_OPCODE_SCS },
{ 1, 2, 1, 0, "TXB", TGSI_OPCODE_TXB }, { 1, 2, 1, 0, 0, 0, "TXB", TGSI_OPCODE_TXB },
{ 1, 1, 0, 0, "NRM", TGSI_OPCODE_NRM }, { 1, 1, 0, 0, 0, 0, "NRM", TGSI_OPCODE_NRM },
{ 1, 2, 0, 0, "DIV", TGSI_OPCODE_DIV }, { 1, 2, 0, 0, 0, 0, "DIV", TGSI_OPCODE_DIV },
{ 1, 2, 0, 0, "DP2", TGSI_OPCODE_DP2 }, { 1, 2, 0, 0, 0, 0, "DP2", TGSI_OPCODE_DP2 },
{ 1, 2, 1, 0, "TXL", TGSI_OPCODE_TXL }, { 1, 2, 1, 0, 0, 0, "TXL", TGSI_OPCODE_TXL },
{ 0, 0, 0, 0, "BRK", TGSI_OPCODE_BRK }, { 0, 0, 0, 0, 0, 0, "BRK", TGSI_OPCODE_BRK },
{ 0, 1, 0, 1, "IF", TGSI_OPCODE_IF }, { 0, 1, 0, 1, 0, 1, "IF", TGSI_OPCODE_IF },
{ 1, 1, 0, 0, "BGNFOR", TGSI_OPCODE_BGNFOR }, { 1, 1, 0, 0, 0, 1, "BGNFOR", TGSI_OPCODE_BGNFOR },
{ 0, 1, 0, 0, "REP", TGSI_OPCODE_REP }, { 0, 1, 0, 0, 0, 1, "REP", TGSI_OPCODE_REP },
{ 0, 0, 0, 1, "ELSE", TGSI_OPCODE_ELSE }, { 0, 0, 0, 1, 1, 1, "ELSE", TGSI_OPCODE_ELSE },
{ 0, 0, 0, 0, "ENDIF", TGSI_OPCODE_ENDIF }, { 0, 0, 0, 0, 1, 0, "ENDIF", TGSI_OPCODE_ENDIF },
{ 1, 0, 0, 0, "ENDFOR", TGSI_OPCODE_ENDFOR }, { 1, 0, 0, 0, 1, 0, "ENDFOR", TGSI_OPCODE_ENDFOR },
{ 0, 0, 0, 0, "ENDREP", TGSI_OPCODE_ENDREP }, { 0, 0, 0, 0, 1, 0, "ENDREP", TGSI_OPCODE_ENDREP },
{ 0, 1, 0, 0, "PUSHA", TGSI_OPCODE_PUSHA }, { 0, 1, 0, 0, 0, 0, "PUSHA", TGSI_OPCODE_PUSHA },
{ 1, 0, 0, 0, "POPA", TGSI_OPCODE_POPA }, { 1, 0, 0, 0, 0, 0, "POPA", TGSI_OPCODE_POPA },
{ 1, 1, 0, 0, "CEIL", TGSI_OPCODE_CEIL }, { 1, 1, 0, 0, 0, 0, "CEIL", TGSI_OPCODE_CEIL },
{ 1, 1, 0, 0, "I2F", TGSI_OPCODE_I2F }, { 1, 1, 0, 0, 0, 0, "I2F", TGSI_OPCODE_I2F },
{ 1, 1, 0, 0, "NOT", TGSI_OPCODE_NOT }, { 1, 1, 0, 0, 0, 0, "NOT", TGSI_OPCODE_NOT },
{ 1, 1, 0, 0, "TRUNC", TGSI_OPCODE_TRUNC }, { 1, 1, 0, 0, 0, 0, "TRUNC", TGSI_OPCODE_TRUNC },
{ 1, 2, 0, 0, "SHL", TGSI_OPCODE_SHL }, { 1, 2, 0, 0, 0, 0, "SHL", TGSI_OPCODE_SHL },
{ 1, 2, 0, 0, "SHR", TGSI_OPCODE_SHR }, { 1, 2, 0, 0, 0, 0, "SHR", TGSI_OPCODE_SHR },
{ 1, 2, 0, 0, "AND", TGSI_OPCODE_AND }, { 1, 2, 0, 0, 0, 0, "AND", TGSI_OPCODE_AND },
{ 1, 2, 0, 0, "OR", TGSI_OPCODE_OR }, { 1, 2, 0, 0, 0, 0, "OR", TGSI_OPCODE_OR },
{ 1, 2, 0, 0, "MOD", TGSI_OPCODE_MOD }, { 1, 2, 0, 0, 0, 0, "MOD", TGSI_OPCODE_MOD },
{ 1, 2, 0, 0, "XOR", TGSI_OPCODE_XOR }, { 1, 2, 0, 0, 0, 0, "XOR", TGSI_OPCODE_XOR },
{ 1, 3, 0, 0, "SAD", TGSI_OPCODE_SAD }, { 1, 3, 0, 0, 0, 0, "SAD", TGSI_OPCODE_SAD },
{ 1, 2, 1, 0, "TXF", TGSI_OPCODE_TXF }, { 1, 2, 1, 0, 0, 0, "TXF", TGSI_OPCODE_TXF },
{ 1, 2, 1, 0, "TXQ", TGSI_OPCODE_TXQ }, { 1, 2, 1, 0, 0, 0, "TXQ", TGSI_OPCODE_TXQ },
{ 0, 0, 0, 0, "CONT", TGSI_OPCODE_CONT }, { 0, 0, 0, 0, 0, 0, "CONT", TGSI_OPCODE_CONT },
{ 0, 0, 0, 0, "EMIT", TGSI_OPCODE_EMIT }, { 0, 0, 0, 0, 0, 0, "EMIT", TGSI_OPCODE_EMIT },
{ 0, 0, 0, 0, "ENDPRIM", TGSI_OPCODE_ENDPRIM }, { 0, 0, 0, 0, 0, 0, "ENDPRIM", TGSI_OPCODE_ENDPRIM },
{ 0, 0, 0, 1, "BGNLOOP", TGSI_OPCODE_BGNLOOP }, { 0, 0, 0, 1, 0, 1, "BGNLOOP", TGSI_OPCODE_BGNLOOP },
{ 0, 0, 0, 0, "BGNSUB", TGSI_OPCODE_BGNSUB }, { 0, 0, 0, 0, 0, 1, "BGNSUB", TGSI_OPCODE_BGNSUB },
{ 0, 0, 0, 1, "ENDLOOP", TGSI_OPCODE_ENDLOOP }, { 0, 0, 0, 1, 1, 0, "ENDLOOP", TGSI_OPCODE_ENDLOOP },
{ 0, 0, 0, 0, "ENDSUB", TGSI_OPCODE_ENDSUB }, { 0, 0, 0, 0, 1, 0, "ENDSUB", TGSI_OPCODE_ENDSUB },
{ 1, 1, 0, 0, "NOISE1", TGSI_OPCODE_NOISE1 }, { 1, 1, 0, 0, 0, 0, "NOISE1", TGSI_OPCODE_NOISE1 },
{ 1, 1, 0, 0, "NOISE2", TGSI_OPCODE_NOISE2 }, { 1, 1, 0, 0, 0, 0, "NOISE2", TGSI_OPCODE_NOISE2 },
{ 1, 1, 0, 0, "NOISE3", TGSI_OPCODE_NOISE3 }, { 1, 1, 0, 0, 0, 0, "NOISE3", TGSI_OPCODE_NOISE3 },
{ 1, 1, 0, 0, "NOISE4", TGSI_OPCODE_NOISE4 }, { 1, 1, 0, 0, 0, 0, "NOISE4", TGSI_OPCODE_NOISE4 },
{ 0, 0, 0, 0, "NOP", TGSI_OPCODE_NOP }, { 0, 0, 0, 0, 0, 0, "NOP", TGSI_OPCODE_NOP },
{ 0, 0, 0, 0, "", 108 }, /* removed */ { 0, 0, 0, 0, 0, 0, "", 108 }, /* removed */
{ 0, 0, 0, 0, "", 109 }, /* removed */ { 0, 0, 0, 0, 0, 0, "", 109 }, /* removed */
{ 0, 0, 0, 0, "", 110 }, /* removed */ { 0, 0, 0, 0, 0, 0, "", 110 }, /* removed */
{ 0, 0, 0, 0, "", 111 }, /* removed */ { 0, 0, 0, 0, 0, 0, "", 111 }, /* removed */
{ 1, 1, 0, 0, "NRM4", TGSI_OPCODE_NRM4 }, { 1, 1, 0, 0, 0, 0, "NRM4", TGSI_OPCODE_NRM4 },
{ 0, 1, 0, 0, "CALLNZ", TGSI_OPCODE_CALLNZ }, { 0, 1, 0, 0, 0, 0, "CALLNZ", TGSI_OPCODE_CALLNZ },
{ 0, 1, 0, 0, "IFC", TGSI_OPCODE_IFC }, { 0, 1, 0, 0, 0, 0, "IFC", TGSI_OPCODE_IFC },
{ 0, 1, 0, 0, "BREAKC", TGSI_OPCODE_BREAKC }, { 0, 1, 0, 0, 0, 0, "BREAKC", TGSI_OPCODE_BREAKC },
{ 0, 1, 0, 0, "KIL", TGSI_OPCODE_KIL }, { 0, 1, 0, 0, 0, 0, "KIL", TGSI_OPCODE_KIL },
{ 0, 0, 0, 0, "END", TGSI_OPCODE_END }, { 0, 0, 0, 0, 0, 0, "END", TGSI_OPCODE_END },
{ 1, 1, 0, 0, "SWZ", TGSI_OPCODE_SWZ } { 1, 1, 0, 0, 0, 0, "SWZ", TGSI_OPCODE_SWZ }
}; };
const struct tgsi_opcode_info * const struct tgsi_opcode_info *

View File

@ -36,10 +36,12 @@ extern "C" {
struct tgsi_opcode_info struct tgsi_opcode_info
{ {
uint num_dst; unsigned num_dst:3;
uint num_src; unsigned num_src:3;
boolean is_tex; unsigned is_tex:1;
boolean is_branch; unsigned is_branch:1;
int pre_dedent:2;
int post_indent:2;
const char *mnemonic; const char *mnemonic;
uint opcode; uint opcode;
}; };

View File

@ -60,7 +60,6 @@ OP13(MAD)
OP12(SUB) OP12(SUB)
OP13(LRP) OP13(LRP)
OP13(CND) OP13(CND)
OP13(CND0)
OP13(DP2A) OP13(DP2A)
OP11(FRC) OP11(FRC)
OP13(CLAMP) OP13(CLAMP)

View File

@ -199,10 +199,10 @@ iter_instruction(
} }
if (info->num_dst != inst->Instruction.NumDstRegs) { 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) { 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. /* Check destination and source registers' validity.

View File

@ -2089,10 +2089,6 @@ emit_instruction(
return 0; return 0;
break; break;
case TGSI_OPCODE_CND0:
return 0;
break;
case TGSI_OPCODE_DP2A: case TGSI_OPCODE_DP2A:
FETCH( func, *inst, 0, 0, CHAN_X ); /* xmm0 = src[0].x */ FETCH( func, *inst, 0, 0, CHAN_X ); /* xmm0 = src[0].x */
FETCH( func, *inst, 1, 1, CHAN_X ); /* xmm1 = src[1].x */ FETCH( func, *inst, 1, 1, CHAN_X ); /* xmm1 = src[1].x */

View File

@ -29,6 +29,7 @@
#include "pipe/p_context.h" #include "pipe/p_context.h"
#include "pipe/p_state.h" #include "pipe/p_state.h"
#include "tgsi/tgsi_ureg.h" #include "tgsi/tgsi_ureg.h"
#include "tgsi/tgsi_info.h"
#include "tgsi/tgsi_dump.h" #include "tgsi/tgsi_dump.h"
#include "util/u_memory.h" #include "util/u_memory.h"
#include "util/u_math.h" #include "util/u_math.h"
@ -71,6 +72,7 @@ struct ureg_tokens {
#define UREG_MAX_OUTPUT PIPE_MAX_ATTRIBS #define UREG_MAX_OUTPUT PIPE_MAX_ATTRIBS
#define UREG_MAX_IMMEDIATE 32 #define UREG_MAX_IMMEDIATE 32
#define UREG_MAX_TEMP 256 #define UREG_MAX_TEMP 256
#define UREG_MAX_ADDR 2
#define DOMAIN_DECL 0 #define DOMAIN_DECL 0
#define DOMAIN_INSN 1 #define DOMAIN_INSN 1
@ -99,11 +101,15 @@ struct ureg_program
} immediate[UREG_MAX_IMMEDIATE]; } immediate[UREG_MAX_IMMEDIATE];
unsigned nr_immediates; unsigned nr_immediates;
struct ureg_src sampler[PIPE_MAX_SAMPLERS];
unsigned nr_samplers;
unsigned temps_active[UREG_MAX_TEMP / 32]; unsigned temps_active[UREG_MAX_TEMP / 32];
unsigned nr_temps; unsigned nr_temps;
unsigned nr_addrs;
unsigned nr_constants; unsigned nr_constants;
unsigned nr_samplers;
unsigned nr_instructions; unsigned nr_instructions;
struct ureg_tokens domain[2]; struct ureg_tokens domain[2];
@ -187,6 +193,8 @@ ureg_dst_register( unsigned file,
dst.File = file; dst.File = file;
dst.WriteMask = TGSI_WRITEMASK_XYZW; dst.WriteMask = TGSI_WRITEMASK_XYZW;
dst.Indirect = 0; dst.Indirect = 0;
dst.IndirectIndex = 0;
dst.IndirectSwizzle = 0;
dst.Saturate = 0; dst.Saturate = 0;
dst.Index = index; dst.Index = index;
dst.Pad1 = 0; dst.Pad1 = 0;
@ -208,6 +216,8 @@ ureg_src_register( unsigned file,
src.SwizzleW = TGSI_SWIZZLE_W; src.SwizzleW = TGSI_SWIZZLE_W;
src.Pad = 0; src.Pad = 0;
src.Indirect = 0; src.Indirect = 0;
src.IndirectIndex = 0;
src.IndirectSwizzle = 0;
src.Absolute = 0; src.Absolute = 0;
src.Index = index; src.Index = index;
src.Negate = 0; src.Negate = 0;
@ -254,6 +264,7 @@ ureg_DECL_fs_input( struct ureg_program *ureg,
unsigned index, unsigned index,
unsigned interp ) unsigned interp )
{ {
assert(ureg->processor == TGSI_PROCESSOR_FRAGMENT);
return ureg_DECL_input( ureg, name, index, interp ); return ureg_DECL_input( ureg, name, index, interp );
} }
@ -263,6 +274,7 @@ ureg_DECL_vs_input( struct ureg_program *ureg,
unsigned name, unsigned name,
unsigned index ) unsigned index )
{ {
assert(ureg->processor == TGSI_PROCESSOR_VERTEX);
return ureg_DECL_input( ureg, name, index, TGSI_INTERPOLATE_CONSTANT ); 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. /* 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 *swizzle )
{ {
unsigned i, j; unsigned i, j;
*swizzle = 0;
for (i = 0; i < nr; i++) { for (i = 0; i < nr; i++) {
boolean found = FALSE; boolean found = FALSE;
@ -394,8 +433,8 @@ struct ureg_src ureg_DECL_immediate( struct ureg_program *ureg,
const float *v, const float *v,
unsigned nr ) unsigned nr )
{ {
unsigned i; unsigned i, j;
unsigned swizzle = 0; unsigned swizzle;
/* Could do a first pass where we examine all existing immediates /* Could do a first pass where we examine all existing immediates
* without expanding. * without expanding.
@ -423,6 +462,12 @@ struct ureg_src ureg_DECL_immediate( struct ureg_program *ureg,
set_bad( ureg ); set_bad( ureg );
out: 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 ), return ureg_swizzle( ureg_src_register( TGSI_FILE_IMMEDIATE, i ),
(swizzle >> 0) & 0x3, (swizzle >> 0) & 0x3,
(swizzle >> 2) & 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 ); union tgsi_any_token *out = get_tokens( ureg, DOMAIN_INSN, size );
unsigned n = 0; 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].value = 0;
out[n].src.File = src.File; out[n].src.File = src.File;
out[n].src.SwizzleX = src.SwizzleX; out[n].src.SwizzleX = src.SwizzleX;
out[n].src.SwizzleY = src.SwizzleY; out[n].src.SwizzleY = src.SwizzleY;
out[n].src.SwizzleZ = src.SwizzleZ; out[n].src.SwizzleZ = src.SwizzleZ;
out[n].src.SwizzleW = src.SwizzleW; out[n].src.SwizzleW = src.SwizzleW;
out[n].src.Indirect = src.Indirect;
out[n].src.Index = src.Index; out[n].src.Index = src.Index;
out[n].src.Negate = src.Negate;
n++; n++;
if (src.Absolute) { if (src.Absolute) {
out[0].src.Extended = 1;
out[0].src.Negate = 0;
out[n].value = 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.Absolute = 1;
out[n].src_ext_mod.Negate = src.Negate;
n++; n++;
} }
if (src.Indirect) { if (src.Indirect) {
out[0].src.Indirect = 1;
out[n].value = 0; out[n].value = 0;
out[n].src.File = TGSI_FILE_ADDRESS; out[n].src.File = TGSI_FILE_ADDRESS;
out[n].src.SwizzleX = TGSI_SWIZZLE_X; out[n].src.SwizzleX = src.IndirectSwizzle;
out[n].src.SwizzleY = TGSI_SWIZZLE_X; out[n].src.SwizzleY = src.IndirectSwizzle;
out[n].src.SwizzleZ = TGSI_SWIZZLE_X; out[n].src.SwizzleZ = src.IndirectSwizzle;
out[n].src.SwizzleW = TGSI_SWIZZLE_X; out[n].src.SwizzleW = src.IndirectSwizzle;
out[n].src.Indirect = 0; out[n].src.Index = src.IndirectIndex;
out[n].src.Index = 0;
n++; n++;
} }
@ -484,6 +537,13 @@ ureg_emit_dst( struct ureg_program *ureg,
union tgsi_any_token *out = get_tokens( ureg, DOMAIN_INSN, size ); union tgsi_any_token *out = get_tokens( ureg, DOMAIN_INSN, size );
unsigned n = 0; 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].value = 0;
out[n].dst.File = dst.File; out[n].dst.File = dst.File;
out[n].dst.WriteMask = dst.WriteMask; out[n].dst.WriteMask = dst.WriteMask;
@ -494,12 +554,11 @@ ureg_emit_dst( struct ureg_program *ureg,
if (dst.Indirect) { if (dst.Indirect) {
out[n].value = 0; out[n].value = 0;
out[n].src.File = TGSI_FILE_ADDRESS; out[n].src.File = TGSI_FILE_ADDRESS;
out[n].src.SwizzleX = TGSI_SWIZZLE_X; out[n].src.SwizzleX = dst.IndirectSwizzle;
out[n].src.SwizzleY = TGSI_SWIZZLE_X; out[n].src.SwizzleY = dst.IndirectSwizzle;
out[n].src.SwizzleZ = TGSI_SWIZZLE_X; out[n].src.SwizzleZ = dst.IndirectSwizzle;
out[n].src.SwizzleW = TGSI_SWIZZLE_X; out[n].src.SwizzleW = dst.IndirectSwizzle;
out[n].src.Indirect = 0; out[n].src.Index = dst.IndirectIndex;
out[n].src.Index = 0;
n++; n++;
} }
@ -523,7 +582,6 @@ ureg_emit_insn(struct ureg_program *ureg,
out[0].insn.NrTokens = 0; out[0].insn.NrTokens = 0;
out[0].insn.Opcode = opcode; out[0].insn.Opcode = opcode;
out[0].insn.Saturate = saturate; out[0].insn.Saturate = saturate;
out[0].insn.NrTokens = 0;
out[0].insn.NumDstRegs = num_dst; out[0].insn.NumDstRegs = num_dst;
out[0].insn.NumSrcRegs = num_src; out[0].insn.NumSrcRegs = num_src;
out[0].insn.Padding = 0; out[0].insn.Padding = 0;
@ -542,6 +600,9 @@ ureg_emit_label(struct ureg_program *ureg,
{ {
union tgsi_any_token *out, *insn; union tgsi_any_token *out, *insn;
if(!label_token)
return;
out = get_tokens( ureg, DOMAIN_INSN, 1 ); out = get_tokens( ureg, DOMAIN_INSN, 1 );
insn = retrieve_token( ureg, DOMAIN_INSN, insn_token ); insn = retrieve_token( ureg, DOMAIN_INSN, insn_token );
@ -617,6 +678,17 @@ ureg_insn(struct ureg_program *ureg,
unsigned insn, i; unsigned insn, i;
boolean saturate; 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; saturate = nr_dst ? dst[0].Saturate : FALSE;
insn = ureg_emit_insn( ureg, opcode, saturate, nr_dst, nr_src ); 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 ); TGSI_INTERPOLATE_CONSTANT );
} }
if (ureg->nr_samplers) { for (i = 0; i < ureg->nr_samplers; i++) {
emit_decl_range( ureg, emit_decl_range( ureg,
TGSI_FILE_SAMPLER, TGSI_FILE_SAMPLER,
0, ureg->nr_samplers ); ureg->sampler[i].Index, 1 );
} }
if (ureg->nr_constants) { if (ureg->nr_constants) {
@ -741,6 +813,12 @@ static void emit_decls( struct ureg_program *ureg )
0, ureg->nr_temps ); 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++) { for (i = 0; i < ureg->nr_immediates; i++) {
emit_immediate( ureg, emit_immediate( ureg,
ureg->immediate[i].v ); ureg->immediate[i].v );
@ -764,7 +842,7 @@ static void copy_instructions( struct ureg_program *ureg )
static void 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 ); union tgsi_any_token *out = retrieve_token( ureg, DOMAIN_DECL, 1 );

View File

@ -31,6 +31,10 @@
#include "pipe/p_compiler.h" #include "pipe/p_compiler.h"
#include "pipe/p_shader_tokens.h" #include "pipe/p_shader_tokens.h"
#ifdef __cplusplus
extern "C" {
#endif
struct ureg_program; struct ureg_program;
/* Almost a tgsi_src_register, but we need to pull in the Absolute /* Almost a tgsi_src_register, but we need to pull in the Absolute
@ -48,6 +52,8 @@ struct ureg_src
unsigned Absolute : 1; /* BOOL */ unsigned Absolute : 1; /* BOOL */
int Index : 16; /* SINT */ int Index : 16; /* SINT */
unsigned Negate : 1; /* BOOL */ unsigned Negate : 1; /* BOOL */
int IndirectIndex : 16; /* SINT */
int IndirectSwizzle : 2; /* TGSI_SWIZZLE_ */
}; };
/* Very similar to a tgsi_dst_register, removing unsupported fields /* Very similar to a tgsi_dst_register, removing unsupported fields
@ -64,6 +70,8 @@ struct ureg_dst
int Index : 16; /* SINT */ int Index : 16; /* SINT */
unsigned Pad1 : 5; unsigned Pad1 : 5;
unsigned Pad2 : 1; /* BOOL */ unsigned Pad2 : 1; /* BOOL */
int IndirectIndex : 16; /* SINT */
int IndirectSwizzle : 2; /* TGSI_SWIZZLE_ */
}; };
struct pipe_context; struct pipe_context;
@ -131,12 +139,21 @@ void
ureg_release_temporary( struct ureg_program *ureg, ureg_release_temporary( struct ureg_program *ureg,
struct ureg_dst tmp ); 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 struct ureg_src
ureg_DECL_sampler( struct ureg_program * ); ureg_DECL_sampler( struct ureg_program *,
unsigned index );
static INLINE struct ureg_src static INLINE struct ureg_src
ureg_DECL_immediate4f( struct ureg_program *ureg, ureg_imm4f( struct ureg_program *ureg,
float a, float b, float a, float b,
float c, float d) float c, float d)
{ {
@ -149,7 +166,7 @@ ureg_DECL_immediate4f( struct ureg_program *ureg,
} }
static INLINE struct ureg_src static INLINE struct ureg_src
ureg_DECL_immediate3f( struct ureg_program *ureg, ureg_imm3f( struct ureg_program *ureg,
float a, float b, float a, float b,
float c) float c)
{ {
@ -161,7 +178,7 @@ ureg_DECL_immediate3f( struct ureg_program *ureg,
} }
static INLINE struct ureg_src static INLINE struct ureg_src
ureg_DECL_immediate2f( struct ureg_program *ureg, ureg_imm2f( struct ureg_program *ureg,
float a, float b) float a, float b)
{ {
float v[2]; float v[2];
@ -171,7 +188,7 @@ ureg_DECL_immediate2f( struct ureg_program *ureg,
} }
static INLINE struct ureg_src static INLINE struct ureg_src
ureg_DECL_immediate1f( struct ureg_program *ureg, ureg_imm1f( struct ureg_program *ureg,
float a) float a)
{ {
float v[1]; float v[1];
@ -392,6 +409,7 @@ static INLINE void ureg_##op( struct ureg_program *ureg, \
static INLINE struct ureg_src static INLINE struct ureg_src
ureg_negate( struct ureg_src reg ) ureg_negate( struct ureg_src reg )
{ {
assert(reg.File != TGSI_FILE_NULL);
reg.Negate ^= 1; reg.Negate ^= 1;
return reg; return reg;
} }
@ -399,6 +417,7 @@ ureg_negate( struct ureg_src reg )
static INLINE struct ureg_src static INLINE struct ureg_src
ureg_abs( struct ureg_src reg ) ureg_abs( struct ureg_src reg )
{ {
assert(reg.File != TGSI_FILE_NULL);
reg.Absolute = 1; reg.Absolute = 1;
reg.Negate = 0; reg.Negate = 0;
return reg; return reg;
@ -413,6 +432,12 @@ ureg_swizzle( struct ureg_src reg,
(reg.SwizzleZ << 4) | (reg.SwizzleZ << 4) |
(reg.SwizzleW << 6)); (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.SwizzleX = (swz >> (x*2)) & 0x3;
reg.SwizzleY = (swz >> (y*2)) & 0x3; reg.SwizzleY = (swz >> (y*2)) & 0x3;
reg.SwizzleZ = (swz >> (z*2)) & 0x3; reg.SwizzleZ = (swz >> (z*2)) & 0x3;
@ -430,6 +455,7 @@ static INLINE struct ureg_dst
ureg_writemask( struct ureg_dst reg, ureg_writemask( struct ureg_dst reg,
unsigned writemask ) unsigned writemask )
{ {
assert(reg.File != TGSI_FILE_NULL);
reg.WriteMask &= writemask; reg.WriteMask &= writemask;
return reg; return reg;
} }
@ -437,10 +463,33 @@ ureg_writemask( struct ureg_dst reg,
static INLINE struct ureg_dst static INLINE struct ureg_dst
ureg_saturate( struct ureg_dst reg ) ureg_saturate( struct ureg_dst reg )
{ {
assert(reg.File != TGSI_FILE_NULL);
reg.Saturate = 1; reg.Saturate = 1;
return reg; 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 static INLINE struct ureg_dst
ureg_dst( struct ureg_src src ) ureg_dst( struct ureg_src src )
{ {
@ -449,6 +498,8 @@ ureg_dst( struct ureg_src src )
dst.File = src.File; dst.File = src.File;
dst.WriteMask = TGSI_WRITEMASK_XYZW; dst.WriteMask = TGSI_WRITEMASK_XYZW;
dst.Indirect = src.Indirect; dst.Indirect = src.Indirect;
dst.IndirectIndex = src.IndirectIndex;
dst.IndirectSwizzle = src.IndirectSwizzle;
dst.Saturate = 0; dst.Saturate = 0;
dst.Index = src.Index; dst.Index = src.Index;
dst.Pad1 = 0; dst.Pad1 = 0;
@ -469,6 +520,8 @@ ureg_src( struct ureg_dst dst )
src.SwizzleW = TGSI_SWIZZLE_W; src.SwizzleW = TGSI_SWIZZLE_W;
src.Pad = 0; src.Pad = 0;
src.Indirect = dst.Indirect; src.Indirect = dst.Indirect;
src.IndirectIndex = dst.IndirectIndex;
src.IndirectSwizzle = dst.IndirectSwizzle;
src.Absolute = 0; src.Absolute = 0;
src.Index = dst.Index; src.Index = dst.Index;
src.Negate = 0; 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 #endif

View File

@ -32,6 +32,10 @@
extern "C" { extern "C" {
#endif #endif
struct tgsi_src_register;
struct tgsi_src_register_ext_swz;
struct tgsi_full_src_register;
void * void *
tgsi_align_128bit( tgsi_align_128bit(
void *unaligned ); void *unaligned );

View File

@ -62,7 +62,7 @@ struct blit_state
struct pipe_viewport_state viewport; struct pipe_viewport_state viewport;
void *vs; void *vs;
void *fs; void *fs[TGSI_WRITEMASK_XYZW + 1];
struct pipe_buffer *vbuf; /**< quad vertices */ struct pipe_buffer *vbuf; /**< quad vertices */
unsigned vbuf_slot; unsigned vbuf_slot;
@ -125,7 +125,7 @@ util_create_blit(struct pipe_context *pipe, struct cso_context *cso)
} }
/* fragment shader */ /* fragment shader */
ctx->fs = util_make_fragment_tex_shader(pipe); ctx->fs[TGSI_WRITEMASK_XYZW] = util_make_fragment_tex_shader(pipe);
ctx->vbuf = NULL; ctx->vbuf = NULL;
/* init vertex data that doesn't change */ /* init vertex data that doesn't change */
@ -146,9 +146,13 @@ void
util_destroy_blit(struct blit_state *ctx) util_destroy_blit(struct blit_state *ctx)
{ {
struct pipe_context *pipe = ctx->pipe; struct pipe_context *pipe = ctx->pipe;
unsigned i;
pipe->delete_vs_state(pipe, ctx->vs); 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); 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. * XXX need some control over blitting Z and/or stencil.
*/ */
void void
util_blit_pixels(struct blit_state *ctx, util_blit_pixels_writemask(struct blit_state *ctx,
struct pipe_surface *src, struct pipe_surface *src,
int srcX0, int srcY0, int srcX0, int srcY0,
int srcX1, int srcY1, int srcX1, int srcY1,
struct pipe_surface *dst, struct pipe_surface *dst,
int dstX0, int dstY0, int dstX0, int dstY0,
int dstX1, int dstY1, int dstX1, int dstY1,
float z, uint filter) float z, uint filter,
uint writemask)
{ {
struct pipe_context *pipe = ctx->pipe; struct pipe_context *pipe = ctx->pipe;
struct pipe_screen *screen = pipe->screen; struct pipe_screen *screen = pipe->screen;
@ -426,8 +431,11 @@ util_blit_pixels(struct blit_state *ctx,
/* texture */ /* texture */
cso_set_sampler_textures(ctx->cso, 1, &tex); 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 */ /* 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); cso_set_vertex_shader_handle(ctx->cso, ctx->vs);
/* drawing dest */ /* 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 /* Release vertex buffer at end of frame to avoid synchronous
* rendering. * rendering.
*/ */
@ -535,7 +564,7 @@ util_blit_pixels_tex(struct blit_state *ctx,
cso_set_sampler_textures(ctx->cso, 1, &tex); cso_set_sampler_textures(ctx->cso, 1, &tex);
/* shaders */ /* 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); cso_set_vertex_shader_handle(ctx->cso, ctx->vs);
/* drawing dest */ /* drawing dest */

View File

@ -60,6 +60,17 @@ util_blit_pixels(struct blit_state *ctx,
int dstX1, int dstY1, int dstX1, int dstY1,
float z, uint filter); 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 extern void
util_blit_pixels_tex(struct blit_state *ctx, util_blit_pixels_tex(struct blit_state *ctx,
struct pipe_texture *tex, struct pipe_texture *tex,

View File

@ -374,6 +374,10 @@ unsigned ffs( unsigned u )
#define ffs __builtin_ffs #define ffs __builtin_ffs
#endif #endif
#ifdef __MINGW32__
#define ffs __builtin_ffs
#endif
/* Could also binary search for the highest bit. /* Could also binary search for the highest bit.
*/ */

View File

@ -88,11 +88,14 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe,
/** /**
* Make simple fragment texture shader: * 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; * END;
*/ */
void * 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_program *ureg;
struct ureg_src sampler; struct ureg_src sampler;
@ -103,7 +106,7 @@ util_make_fragment_tex_shader(struct pipe_context *pipe)
if (ureg == NULL) if (ureg == NULL)
return NULL; return NULL;
sampler = ureg_DECL_sampler( ureg ); sampler = ureg_DECL_sampler( ureg, 0 );
tex = ureg_DECL_fs_input( ureg, tex = ureg_DECL_fs_input( ureg,
TGSI_SEMANTIC_GENERIC, 0, 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 ); 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 );
}

View File

@ -49,6 +49,10 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe,
const uint *semantic_indexes); const uint *semantic_indexes);
extern void *
util_make_fragment_tex_shader_writemask(struct pipe_context *pipe,
unsigned writemask );
extern void * extern void *
util_make_fragment_tex_shader(struct pipe_context *pipe); util_make_fragment_tex_shader(struct pipe_context *pipe);

View File

@ -1150,10 +1150,6 @@ exec_instruction(
ASSERT (0); ASSERT (0);
break; break;
case TGSI_OPCODE_CND0:
ASSERT (0);
break;
case TGSI_OPCODE_DP2A: case TGSI_OPCODE_DP2A:
ASSERT (0); ASSERT (0);
break; break;

View File

@ -5,6 +5,7 @@ LIBNAME = i915simple
C_SOURCES = \ C_SOURCES = \
i915_blit.c \ i915_blit.c \
i915_buffer.c \
i915_clear.c \ i915_clear.c \
i915_flush.c \ i915_flush.c \
i915_context.c \ i915_context.c \

View File

@ -6,6 +6,7 @@ i915simple = env.ConvenienceLibrary(
target = 'i915simple', target = 'i915simple',
source = [ source = [
'i915_blit.c', 'i915_blit.c',
'i915_buffer.c',
'i915_clear.c', 'i915_clear.c',
'i915_context.c', 'i915_context.c',
'i915_debug.c', 'i915_debug.c',

View File

@ -28,89 +28,20 @@
#ifndef I915_BATCH_H #ifndef I915_BATCH_H
#define I915_BATCH_H #define I915_BATCH_H
#include "i915_winsys.h" #include "intel_batchbuffer.h"
struct i915_batchbuffer #define BEGIN_BATCH(dwords, relocs) \
{ (intel_batchbuffer_check(i915->batch, dwords, relocs))
struct pipe_buffer *buffer;
struct i915_winsys *winsys;
unsigned char *map; #define OUT_BATCH(dword) \
unsigned char *ptr; intel_batchbuffer_dword(i915->batch, dword)
size_t size; #define OUT_RELOC(buf, usage, offset) \
size_t actual_size; intel_batchbuffer_reloc(i915->batch, buf, usage, offset)
size_t relocs; #define FLUSH_BATCH(fence) do { \
size_t max_relocs; intel_batchbuffer_flush(i915->batch, fence); \
}; i915->hardware_dirty = ~0; \
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; \
} while (0) } while (0)
#endif #endif

View File

@ -26,8 +26,6 @@
**************************************************************************/ **************************************************************************/
#include "i915_context.h"
#include "i915_winsys.h"
#include "i915_blit.h" #include "i915_blit.h"
#include "i915_reg.h" #include "i915_reg.h"
#include "i915_batch.h" #include "i915_batch.h"
@ -37,33 +35,33 @@
void void
i915_fill_blit(struct i915_context *i915, i915_fill_blit(struct i915_context *i915,
unsigned cpp, unsigned cpp,
unsigned short dst_pitch, unsigned short dst_pitch,
struct pipe_buffer *dst_buffer, struct intel_buffer *dst_buffer,
unsigned dst_offset, unsigned dst_offset,
short x, short y, short x, short y,
short w, short h, short w, short h,
unsigned color) unsigned color)
{ {
unsigned BR13, CMD; unsigned BR13, CMD;
I915_DBG(i915, I915_DBG(i915,
"%s dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n", "%s dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n",
__FUNCTION__, __FUNCTION__,
dst_buffer, dst_pitch, dst_offset, x, y, w, h); dst_buffer, dst_pitch, dst_offset, x, y, w, h);
switch (cpp) { switch (cpp) {
case 1: case 1:
case 2: case 2:
case 3: case 3:
BR13 = (((int) dst_pitch) & 0xffff) | BR13 = (((int) dst_pitch) & 0xffff) |
(0xF0 << 16) | (1 << 24); (0xF0 << 16) | (1 << 24);
CMD = XY_COLOR_BLT_CMD; CMD = XY_COLOR_BLT_CMD;
break; break;
case 4: case 4:
BR13 = (((int) dst_pitch) & 0xffff) | 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 | CMD = (XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA |
XY_COLOR_BLT_WRITE_RGB); XY_COLOR_BLT_WRITE_RGB);
break; break;
@ -79,25 +77,24 @@ i915_fill_blit(struct i915_context *i915,
OUT_BATCH(BR13); OUT_BATCH(BR13);
OUT_BATCH((y << 16) | x); OUT_BATCH((y << 16) | x);
OUT_BATCH(((y + h) << 16) | (x + w)); 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); OUT_BATCH(color);
FLUSH_BATCH(NULL); FLUSH_BATCH(NULL);
} }
void void
i915_copy_blit( struct i915_context *i915, i915_copy_blit(struct i915_context *i915,
unsigned do_flip, unsigned do_flip,
unsigned cpp, unsigned cpp,
unsigned short src_pitch, unsigned short src_pitch,
struct pipe_buffer *src_buffer, struct intel_buffer *src_buffer,
unsigned src_offset, unsigned src_offset,
unsigned short dst_pitch, unsigned short dst_pitch,
struct pipe_buffer *dst_buffer, struct intel_buffer *dst_buffer,
unsigned dst_offset, unsigned dst_offset,
short src_x, short src_y, short src_x, short src_y,
short dst_x, short dst_y, short dst_x, short dst_y,
short w, short h ) short w, short h)
{ {
unsigned CMD, BR13; unsigned CMD, BR13;
int dst_y2 = dst_y + h; int dst_y2 = dst_y + h;
@ -105,32 +102,30 @@ i915_copy_blit( struct i915_context *i915,
I915_DBG(i915, I915_DBG(i915,
"%s src:buf(%p)/%d+%d %d,%d dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n", "%s src:buf(%p)/%d+%d %d,%d dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n",
__FUNCTION__, __FUNCTION__,
src_buffer, src_pitch, src_offset, src_x, src_y, src_buffer, src_pitch, src_offset, src_x, src_y,
dst_buffer, dst_pitch, dst_offset, dst_x, dst_y, w, h); dst_buffer, dst_pitch, dst_offset, dst_x, dst_y, w, h);
switch (cpp) { switch (cpp) {
case 1: case 1:
case 2: case 2:
case 3: case 3:
BR13 = (((int) dst_pitch) & 0xffff) | BR13 = (((int) dst_pitch) & 0xffff) |
(0xCC << 16) | (1 << 24); (0xCC << 16) | (1 << 24);
CMD = XY_SRC_COPY_BLT_CMD; CMD = XY_SRC_COPY_BLT_CMD;
break; break;
case 4: case 4:
BR13 = (((int) dst_pitch) & 0xffff) | BR13 = (((int) dst_pitch) & 0xffff) |
(0xCC << 16) | (1 << 24) | (1 << 25); (0xCC << 16) | (1 << 24) | (1 << 25);
CMD = CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
(XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | XY_SRC_COPY_BLT_WRITE_RGB);
XY_SRC_COPY_BLT_WRITE_RGB);
break; break;
default: default:
return; return;
} }
if (dst_y2 < dst_y || if (dst_y2 < dst_y || dst_x2 < dst_x) {
dst_x2 < dst_x) {
return; return;
} }
@ -140,7 +135,6 @@ i915_copy_blit( struct i915_context *i915,
*/ */
assert (dst_pitch > 0 && src_pitch > 0); assert (dst_pitch > 0 && src_pitch > 0);
if (!BEGIN_BATCH(8, 2)) { if (!BEGIN_BATCH(8, 2)) {
FLUSH_BATCH(NULL); FLUSH_BATCH(NULL);
assert(BEGIN_BATCH(8, 2)); assert(BEGIN_BATCH(8, 2));
@ -149,11 +143,9 @@ i915_copy_blit( struct i915_context *i915,
OUT_BATCH(BR13); OUT_BATCH(BR13);
OUT_BATCH((dst_y << 16) | dst_x); OUT_BATCH((dst_y << 16) | dst_x);
OUT_BATCH((dst_y2 << 16) | dst_x2); 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((src_y << 16) | src_x);
OUT_BATCH(((int) src_pitch & 0xffff)); 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); FLUSH_BATCH(NULL);
} }

View File

@ -32,24 +32,24 @@
extern void i915_copy_blit(struct i915_context *i915, extern void i915_copy_blit(struct i915_context *i915,
unsigned do_flip, unsigned do_flip,
unsigned cpp, unsigned cpp,
unsigned short src_pitch, unsigned short src_pitch,
struct pipe_buffer *src_buffer, struct intel_buffer *src_buffer,
unsigned src_offset, unsigned src_offset,
unsigned short dst_pitch, unsigned short dst_pitch,
struct pipe_buffer *dst_buffer, struct intel_buffer *dst_buffer,
unsigned dst_offset, unsigned dst_offset,
short srcx, short srcy, short srcx, short srcy,
short dstx, short dsty, short dstx, short dsty,
short w, short h ); short w, short h);
extern void i915_fill_blit(struct i915_context *i915, extern void i915_fill_blit(struct i915_context *i915,
unsigned cpp, unsigned cpp,
unsigned short dst_pitch, unsigned short dst_pitch,
struct pipe_buffer *dst_buffer, struct intel_buffer *dst_buffer,
unsigned dst_offset, unsigned dst_offset,
short x, short y, short x, short y,
short w, short h, unsigned color); short w, short h, unsigned color);
#endif #endif

View File

@ -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;
}

View File

@ -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

View File

@ -26,8 +26,8 @@
**************************************************************************/ **************************************************************************/
#include "i915_context.h" #include "i915_context.h"
#include "i915_winsys.h"
#include "i915_state.h" #include "i915_state.h"
#include "i915_screen.h"
#include "i915_batch.h" #include "i915_batch.h"
#include "i915_texture.h" #include "i915_texture.h"
#include "i915_reg.h" #include "i915_reg.h"
@ -40,66 +40,58 @@
#include "pipe/p_screen.h" #include "pipe/p_screen.h"
static void i915_destroy( struct pipe_context *pipe ) /*
{ * Draw functions
struct i915_context *i915 = i915_context( pipe ); */
draw_destroy( i915->draw );
if(i915->winsys->destroy)
i915->winsys->destroy(i915->winsys);
FREE( i915 );
}
static boolean static boolean
i915_draw_range_elements(struct pipe_context *pipe, i915_draw_range_elements(struct pipe_context *pipe,
struct pipe_buffer *indexBuffer, struct pipe_buffer *indexBuffer,
unsigned indexSize, unsigned indexSize,
unsigned min_index, unsigned min_index,
unsigned max_index, unsigned max_index,
unsigned prim, unsigned start, unsigned count) 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; struct draw_context *draw = i915->draw;
unsigned i; unsigned i;
if (i915->dirty) if (i915->dirty)
i915_update_derived( i915 ); i915_update_derived(i915);
/* /*
* Map vertex buffers * Map vertex buffers
*/ */
for (i = 0; i < i915->num_vertex_buffers; i++) { for (i = 0; i < i915->num_vertex_buffers; i++) {
void *buf void *buf = pipe_buffer_map(pipe->screen, i915->vertex_buffer[i].buffer,
= pipe_buffer_map(pipe->screen, PIPE_BUFFER_USAGE_CPU_READ);
i915->vertex_buffer[i].buffer,
PIPE_BUFFER_USAGE_CPU_READ);
draw_set_mapped_vertex_buffer(draw, i, buf); draw_set_mapped_vertex_buffer(draw, i, buf);
} }
/* Map index buffer, if present */
/*
* Map index buffer, if present
*/
if (indexBuffer) { if (indexBuffer) {
void *mapped_indexes void *mapped_indexes = pipe_buffer_map(pipe->screen, indexBuffer,
= pipe_buffer_map(pipe->screen, indexBuffer, PIPE_BUFFER_USAGE_CPU_READ);
PIPE_BUFFER_USAGE_CPU_READ);
draw_set_mapped_element_buffer_range(draw, indexSize, draw_set_mapped_element_buffer_range(draw, indexSize,
min_index, min_index,
max_index, max_index,
mapped_indexes); mapped_indexes);
} } else {
else {
/* no index/element buffer */
draw_set_mapped_element_buffer(draw, 0, NULL); draw_set_mapped_element_buffer(draw, 0, NULL);
} }
draw_set_mapped_constant_buffer(draw, draw_set_mapped_constant_buffer(draw,
i915->current.constants[PIPE_SHADER_VERTEX], i915->current.constants[PIPE_SHADER_VERTEX],
( i915->current.num_user_constants[PIPE_SHADER_VERTEX] * (i915->current.num_user_constants[PIPE_SHADER_VERTEX] *
4 * sizeof(float) )); 4 * sizeof(float)));
/* draw! */ /*
* Do the drawing
*/
draw_arrays(i915->draw, prim, start, count); 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); pipe_buffer_unmap(pipe->screen, i915->vertex_buffer[i].buffer);
draw_set_mapped_vertex_buffer(draw, i, NULL); draw_set_mapped_vertex_buffer(draw, i, NULL);
} }
if (indexBuffer) { if (indexBuffer) {
pipe_buffer_unmap(pipe->screen, indexBuffer); pipe_buffer_unmap(pipe->screen, indexBuffer);
draw_set_mapped_element_buffer_range(draw, 0, start, start + count - 1, NULL); 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 static boolean
i915_draw_elements( struct pipe_context *pipe, i915_draw_elements(struct pipe_context *pipe,
struct pipe_buffer *indexBuffer, struct pipe_buffer *indexBuffer,
unsigned indexSize, unsigned indexSize,
unsigned prim, unsigned start, unsigned count) unsigned prim, unsigned start, unsigned count)
{ {
return i915_draw_range_elements( pipe, indexBuffer, return i915_draw_range_elements(pipe, indexBuffer,
indexSize, indexSize,
0, 0xffffffff, 0, 0xffffffff,
prim, start, count ); prim, start, count);
} }
static boolean i915_draw_arrays( struct pipe_context *pipe, static boolean
unsigned prim, unsigned start, unsigned count) i915_draw_arrays(struct pipe_context *pipe,
unsigned prim, unsigned start, unsigned count)
{ {
return i915_draw_elements(pipe, NULL, 0, prim, start, count); return i915_draw_elements(pipe, NULL, 0, prim, start, count);
} }
/*
* Is referenced functions
*/
static unsigned int static unsigned int
i915_is_texture_referenced( struct pipe_context *pipe, i915_is_texture_referenced(struct pipe_context *pipe,
struct pipe_texture *texture, struct pipe_texture *texture,
unsigned face, unsigned level) unsigned face, unsigned level)
{ {
/** /**
* FIXME: Return the corrent result. We can't alays return referenced * 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 static unsigned int
i915_is_buffer_referenced( struct pipe_context *pipe, i915_is_buffer_referenced(struct pipe_context *pipe,
struct pipe_buffer *buf) struct pipe_buffer *buf)
{ {
/** /**
* FIXME: Return the corrent result. We can't alays return referenced * 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, * Generic context functions
struct i915_winsys *i915_winsys ) */
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; struct i915_context *i915;
@ -178,21 +193,20 @@ struct pipe_context *i915_create_context( struct pipe_screen *screen,
if (i915 == NULL) if (i915 == NULL)
return NULL; return NULL;
i915->winsys = i915_winsys; i915->iws = i915_screen(screen)->iws;
i915->pipe.winsys = pipe_winsys; i915->base.winsys = NULL;
i915->pipe.screen = screen; 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->base.is_texture_referenced = i915_is_texture_referenced;
i915->pipe.draw_elements = i915_draw_elements; i915->base.is_buffer_referenced = i915_is_buffer_referenced;
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;
/* /*
* Create drawing context and plug our rendering stage into it. * 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); assert(i915->draw);
if (!debug_get_bool_option("I915_NO_VBUF", FALSE)) { if (!debug_get_bool_option("I915_NO_VBUF", FALSE)) {
draw_set_rasterize_stage(i915->draw, i915_draw_vbuf_stage(i915)); draw_set_rasterize_stage(i915->draw, i915_draw_vbuf_stage(i915));
} } else {
else {
draw_set_rasterize_stage(i915->draw, i915_draw_render_stage(i915)); draw_set_rasterize_stage(i915->draw, i915_draw_render_stage(i915));
} }
i915_init_surface_functions(i915); i915_init_surface_functions(i915);
i915_init_state_functions(i915); i915_init_state_functions(i915);
i915_init_flush_functions(i915); i915_init_flush_functions(i915);
i915_init_texture_functions(i915);
draw_install_aaline_stage(i915->draw, &i915->pipe); draw_install_aaline_stage(i915->draw, &i915->base);
draw_install_aapoint_stage(i915->draw, &i915->pipe); draw_install_aapoint_stage(i915->draw, &i915->base);
i915->dirty = ~0; i915->dirty = ~0;
i915->hardware_dirty = ~0; i915->hardware_dirty = ~0;
/* Batch stream debugging is a bit hacked up at the moment: /* Batch stream debugging is a bit hacked up at the moment:
*/ */
i915->batch = i915_winsys->batch_get(i915_winsys); i915->batch = i915->iws->batchbuffer_create(i915->iws);
i915->batch->winsys = i915_winsys;
return &i915->pipe; return &i915->base;
} }

View File

@ -38,6 +38,11 @@
#include "tgsi/tgsi_scan.h" #include "tgsi/tgsi_scan.h"
struct intel_winsys;
struct intel_buffer;
struct intel_batchbuffer;
#define I915_TEX_UNITS 8 #define I915_TEX_UNITS 8
#define I915_DYNAMIC_MODES4 0 #define I915_DYNAMIC_MODES4 0
@ -182,7 +187,6 @@ struct i915_sampler_state {
unsigned maxlod; unsigned maxlod;
}; };
struct i915_texture { struct i915_texture {
struct pipe_texture base; struct pipe_texture base;
@ -192,7 +196,8 @@ struct i915_texture {
unsigned depth_stride; /* per-image on i945? */ unsigned depth_stride; /* per-image on i945? */
unsigned total_nblocksy; 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]; unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS];
@ -206,15 +211,15 @@ struct i915_texture {
/* The data is held here: /* The data is held here:
*/ */
struct pipe_buffer *buffer; struct intel_buffer *buffer;
}; };
struct i915_batchbuffer;
struct i915_context struct i915_context
{ {
struct pipe_context pipe; struct pipe_context base;
struct i915_winsys *winsys;
struct intel_winsys *iws;
struct draw_context *draw; struct draw_context *draw;
/* The most recent drawing state as set by the driver: /* The most recent drawing state as set by the driver:
@ -243,10 +248,10 @@ struct i915_context
unsigned num_vertex_elements; unsigned num_vertex_elements;
unsigned num_vertex_buffers; unsigned num_vertex_buffers;
struct i915_batchbuffer *batch; struct intel_batchbuffer *batch;
/** Vertex buffer */ /** Vertex buffer */
struct pipe_buffer *vbo; struct intel_buffer *vbo;
size_t vbo_offset; size_t vbo_offset;
unsigned vbo_flushed; unsigned vbo_flushed;

View File

@ -27,7 +27,6 @@
#include "i915_reg.h" #include "i915_reg.h"
#include "i915_context.h" #include "i915_context.h"
#include "i915_winsys.h"
#include "i915_debug.h" #include "i915_debug.h"
#include "i915_batch.h" #include "i915_batch.h"
#include "pipe/internal/p_winsys_screen.h" #include "pipe/internal/p_winsys_screen.h"
@ -864,7 +863,7 @@ static boolean i915_debug_packet( struct debug_stream *stream )
void void
i915_dump_batchbuffer( struct i915_batchbuffer *batch ) i915_dump_batchbuffer( struct intel_batchbuffer *batch )
{ {
struct debug_stream stream; struct debug_stream stream;
unsigned *start = (unsigned*)batch->map; unsigned *start = (unsigned*)batch->map;

View File

@ -104,9 +104,9 @@ I915_DBG(
#endif #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 ); void i915_debug_init( struct i915_context *i915 );

View File

@ -45,6 +45,7 @@ static void i915_flush( struct pipe_context *pipe,
draw_flush(i915->draw); draw_flush(i915->draw);
#if 0
/* Do we need to emit an MI_FLUSH command to flush the hardware /* Do we need to emit an MI_FLUSH command to flush the hardware
* caches? * caches?
*/ */
@ -63,6 +64,13 @@ static void i915_flush( struct pipe_context *pipe,
} }
OUT_BATCH( flush ); 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: /* 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 ) void i915_init_flush_functions( struct i915_context *i915 )
{ {
i915->pipe.flush = i915_flush; i915->base.flush = i915_flush;
} }

View File

@ -32,7 +32,6 @@
#include "util/u_pack_color.h" #include "util/u_pack_color.h"
#include "i915_context.h" #include "i915_context.h"
#include "i915_winsys.h"
#include "i915_reg.h" #include "i915_reg.h"
#include "i915_state.h" #include "i915_state.h"
#include "i915_batch.h" #include "i915_batch.h"

View File

@ -42,13 +42,11 @@
#include "draw/draw_vbuf.h" #include "draw/draw_vbuf.h"
#include "util/u_debug.h" #include "util/u_debug.h"
#include "pipe/p_inlines.h" #include "pipe/p_inlines.h"
#include "pipe/internal/p_winsys_screen.h"
#include "util/u_math.h" #include "util/u_math.h"
#include "util/u_memory.h" #include "util/u_memory.h"
#include "i915_context.h" #include "i915_context.h"
#include "i915_reg.h" #include "i915_reg.h"
#include "i915_winsys.h"
#include "i915_batch.h" #include "i915_batch.h"
#include "i915_state.h" #include "i915_state.h"
@ -59,7 +57,7 @@
struct i915_vbuf_render { struct i915_vbuf_render {
struct vbuf_render base; struct vbuf_render base;
struct i915_context *i915; struct i915_context *i915;
/** Vertex size in bytes */ /** Vertex size in bytes */
size_t vertex_size; size_t vertex_size;
@ -74,7 +72,7 @@ struct i915_vbuf_render {
unsigned fallback; unsigned fallback;
/* Stuff for the vbo */ /* Stuff for the vbo */
struct pipe_buffer *vbo; struct intel_buffer *vbo;
size_t vbo_size; size_t vbo_size;
size_t vbo_offset; size_t vbo_offset;
void *vbo_ptr; void *vbo_ptr;
@ -87,36 +85,34 @@ struct i915_vbuf_render {
* Basically a cast wrapper. * Basically a cast wrapper.
*/ */
static INLINE struct i915_vbuf_render * static INLINE struct i915_vbuf_render *
i915_vbuf_render( struct vbuf_render *render ) i915_vbuf_render(struct vbuf_render *render)
{ {
assert(render); assert(render);
return (struct i915_vbuf_render *)render; return (struct i915_vbuf_render *)render;
} }
static const struct vertex_info * 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_vbuf_render *i915_render = i915_vbuf_render(render);
struct i915_context *i915 = i915_render->i915; struct i915_context *i915 = i915_render->i915;
if (i915->dirty) { if (i915->dirty) {
/* make sure we have up to date vertex layout */ /* make sure we have up to date vertex layout */
i915_update_derived( i915 ); i915_update_derived(i915);
} }
return &i915->current.vertex_info; return &i915->current.vertex_info;
} }
static boolean static boolean
i915_vbuf_render_allocate_vertices( struct vbuf_render *render, i915_vbuf_render_allocate_vertices(struct vbuf_render *render,
ushort vertex_size, ushort vertex_size,
ushort nr_vertices ) ushort nr_vertices)
{ {
struct i915_vbuf_render *i915_render = i915_vbuf_render(render); struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
struct i915_context *i915 = i915_render->i915; 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; size_t size = (size_t)vertex_size * (size_t)nr_vertices;
/* FIXME: handle failure */ /* 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) { if (i915_render->vbo_size > size + i915_render->vbo_offset && !i915->vbo_flushed) {
} else { } else {
i915->vbo_flushed = 0; i915->vbo_flushed = 0;
if (i915_render->vbo) if (i915_render->vbo) {
pipe_buffer_reference(&i915_render->vbo, NULL); iws->buffer_destroy(iws, i915_render->vbo);
i915_render->vbo = NULL;
}
} }
if (!i915_render->vbo) { if (!i915_render->vbo) {
i915_render->vbo_size = MAX2(size, i915_render->vbo_alloc_size); i915_render->vbo_size = MAX2(size, i915_render->vbo_alloc_size);
i915_render->vbo_offset = 0; i915_render->vbo_offset = 0;
i915_render->vbo = pipe_buffer_create(screen, i915_render->vbo = iws->buffer_create(iws, i915_render->vbo_size, 64,
64, INTEL_NEW_VERTEX);
I915_BUFFER_USAGE_LIT_VERTEX,
i915_render->vbo_size);
} }
@ -149,40 +145,37 @@ i915_vbuf_render_allocate_vertices( struct vbuf_render *render,
return TRUE; return TRUE;
} }
static void * 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_vbuf_render *i915_render = i915_vbuf_render(render);
struct i915_context *i915 = i915_render->i915; struct i915_context *i915 = i915_render->i915;
struct pipe_screen *screen = i915->pipe.screen; struct intel_winsys *iws = i915->iws;
if (i915->vbo_flushed) if (i915->vbo_flushed)
debug_printf("%s bad vbo flush occured stalling on hw\n"); debug_printf("%s bad vbo flush occured stalling on hw\n");
i915_render->vbo_ptr = pipe_buffer_map(screen, i915_render->vbo_ptr = iws->buffer_map(iws, i915_render->vbo, TRUE);
i915_render->vbo,
PIPE_BUFFER_USAGE_CPU_WRITE);
return (unsigned char *)i915_render->vbo_ptr + i915->vbo_offset; return (unsigned char *)i915_render->vbo_ptr + i915->vbo_offset;
} }
static void static void
i915_vbuf_render_unmap_vertices( struct vbuf_render *render, i915_vbuf_render_unmap_vertices(struct vbuf_render *render,
ushort min_index, ushort min_index,
ushort max_index ) ushort max_index)
{ {
struct i915_vbuf_render *i915_render = i915_vbuf_render(render); struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
struct i915_context *i915 = i915_render->i915; 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)); 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 static boolean
i915_vbuf_render_set_primitive( struct vbuf_render *render, i915_vbuf_render_set_primitive(struct vbuf_render *render,
unsigned prim ) unsigned prim)
{ {
struct i915_vbuf_render *i915_render = i915_vbuf_render(render); struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
i915_render->prim = prim; i915_render->prim = prim;
@ -234,15 +227,13 @@ i915_vbuf_render_set_primitive( struct vbuf_render *render,
} }
} }
/** /**
* Used for fallbacks in draw_arrays * Used for fallbacks in draw_arrays
*/ */
static void static void
draw_arrays_generate_indices( struct vbuf_render *render, draw_arrays_generate_indices(struct vbuf_render *render,
unsigned start, uint nr, unsigned start, uint nr,
unsigned type ) unsigned type)
{ {
struct i915_vbuf_render *i915_render = i915_vbuf_render(render); struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
struct i915_context *i915 = i915_render->i915; struct i915_context *i915 = i915_render->i915;
@ -251,29 +242,29 @@ draw_arrays_generate_indices( struct vbuf_render *render,
switch(type) { switch(type) {
case 0: case 0:
for (i = start; i+1 < end; i += 2) 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) if (i < end)
OUT_BATCH( i ); OUT_BATCH(i);
break; break;
case PIPE_PRIM_LINE_LOOP: case PIPE_PRIM_LINE_LOOP:
if (nr >= 2) { if (nr >= 2) {
for (i = start + 1; i < end; i++) for (i = start + 1; i < end; i++)
OUT_BATCH( (i-0) | (i+0) << 16 ); OUT_BATCH((i-0) | (i+0) << 16);
OUT_BATCH( (i-0) | ( start) << 16 ); OUT_BATCH((i-0) | ( start) << 16);
} }
break; break;
case PIPE_PRIM_QUADS: case PIPE_PRIM_QUADS:
for (i = start; i + 3 < end; i += 4) { for (i = start; i + 3 < end; i += 4) {
OUT_BATCH( (i+0) | (i+1) << 16 ); OUT_BATCH((i+0) | (i+1) << 16);
OUT_BATCH( (i+3) | (i+1) << 16 ); OUT_BATCH((i+3) | (i+1) << 16);
OUT_BATCH( (i+2) | (i+3) << 16 ); OUT_BATCH((i+2) | (i+3) << 16);
} }
break; break;
case PIPE_PRIM_QUAD_STRIP: case PIPE_PRIM_QUAD_STRIP:
for (i = start; i + 3 < end; i += 2) { for (i = start; i + 3 < end; i += 2) {
OUT_BATCH( (i+0) | (i+1) << 16 ); OUT_BATCH((i+0) | (i+1) << 16);
OUT_BATCH( (i+3) | (i+2) << 16 ); OUT_BATCH((i+3) | (i+2) << 16);
OUT_BATCH( (i+0) | (i+3) << 16 ); OUT_BATCH((i+0) | (i+3) << 16);
} }
break; break;
default: default:
@ -282,16 +273,16 @@ draw_arrays_generate_indices( struct vbuf_render *render,
} }
static unsigned static unsigned
draw_arrays_calc_nr_indices( uint nr, unsigned type ) draw_arrays_calc_nr_indices(uint nr, unsigned type)
{ {
switch (type) { switch (type) {
case 0: case 0:
return nr; return nr;
case PIPE_PRIM_LINE_LOOP: case PIPE_PRIM_LINE_LOOP:
if (nr >= 2) if (nr >= 2)
return nr * 2; return nr * 2;
else else
return 0; return 0;
case PIPE_PRIM_QUADS: case PIPE_PRIM_QUADS:
return (nr / 4) * 6; return (nr / 4) * 6;
case PIPE_PRIM_QUAD_STRIP: case PIPE_PRIM_QUAD_STRIP:
@ -303,64 +294,64 @@ draw_arrays_calc_nr_indices( uint nr, unsigned type )
} }
static void static void
draw_arrays_fallback( struct vbuf_render *render, draw_arrays_fallback(struct vbuf_render *render,
unsigned start, unsigned start,
uint nr ) uint nr)
{ {
struct i915_vbuf_render *i915_render = i915_vbuf_render(render); struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
struct i915_context *i915 = i915_render->i915; struct i915_context *i915 = i915_render->i915;
unsigned nr_indices; unsigned nr_indices;
if (i915->dirty) if (i915->dirty)
i915_update_derived( i915 ); i915_update_derived(i915);
if (i915->hardware_dirty) 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) if (!nr_indices)
return; return;
if (!BEGIN_BATCH( 1 + (nr_indices + 1)/2, 1 )) { if (!BEGIN_BATCH(1 + (nr_indices + 1)/2, 1)) {
FLUSH_BATCH(NULL); FLUSH_BATCH(NULL);
/* Make sure state is re-emitted after a flush: /* Make sure state is re-emitted after a flush:
*/ */
i915_update_derived( i915 ); i915_update_derived(i915);
i915_emit_hardware_state( i915 ); i915_emit_hardware_state(i915);
i915->vbo_flushed = 1; i915->vbo_flushed = 1;
if (!BEGIN_BATCH( 1 + (nr_indices + 1)/2, 1 )) { if (!BEGIN_BATCH(1 + (nr_indices + 1)/2, 1)) {
assert(0); assert(0);
goto out; goto out;
} }
} }
OUT_BATCH( _3DPRIMITIVE | OUT_BATCH(_3DPRIMITIVE |
PRIM_INDIRECT | PRIM_INDIRECT |
i915_render->hwprim | i915_render->hwprim |
PRIM_INDIRECT_ELTS | PRIM_INDIRECT_ELTS |
nr_indices ); nr_indices);
draw_arrays_generate_indices( render, start, nr, i915_render->fallback ); draw_arrays_generate_indices(render, start, nr, i915_render->fallback);
out: out:
return; return;
} }
static void static void
i915_vbuf_render_draw_arrays( struct vbuf_render *render, i915_vbuf_render_draw_arrays(struct vbuf_render *render,
unsigned start, unsigned start,
uint nr ) uint nr)
{ {
struct i915_vbuf_render *i915_render = i915_vbuf_render(render); struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
if (i915_render->fallback) { if (i915_render->fallback) {
draw_arrays_fallback( render, start, nr ); draw_arrays_fallback(render, start, nr);
return; return;
} }
/* JB: TODO submit direct cmds */ /* 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. * If type is zero normal operation assumed.
*/ */
static void static void
draw_generate_indices( struct vbuf_render *render, draw_generate_indices(struct vbuf_render *render,
const ushort *indices, const ushort *indices,
uint nr_indices, uint nr_indices,
unsigned type ) unsigned type)
{ {
struct i915_vbuf_render *i915_render = i915_vbuf_render(render); struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
struct i915_context *i915 = i915_render->i915; struct i915_context *i915 = i915_render->i915;
@ -380,31 +371,31 @@ draw_generate_indices( struct vbuf_render *render,
switch(type) { switch(type) {
case 0: case 0:
for (i = 0; i + 1 < nr_indices; i += 2) { 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) { if (i < nr_indices) {
OUT_BATCH( indices[i] ); OUT_BATCH(indices[i]);
} }
break; break;
case PIPE_PRIM_LINE_LOOP: case PIPE_PRIM_LINE_LOOP:
if (nr_indices >= 2) { if (nr_indices >= 2) {
for (i = 1; i < nr_indices; i++) for (i = 1; i < nr_indices; i++)
OUT_BATCH( indices[i-1] | indices[i] << 16 ); OUT_BATCH(indices[i-1] | indices[i] << 16);
OUT_BATCH( indices[i-1] | indices[0] << 16 ); OUT_BATCH(indices[i-1] | indices[0] << 16);
} }
break; break;
case PIPE_PRIM_QUADS: case PIPE_PRIM_QUADS:
for (i = 0; i + 3 < nr_indices; i += 4) { for (i = 0; i + 3 < nr_indices; i += 4) {
OUT_BATCH( indices[i+0] | indices[i+1] << 16 ); OUT_BATCH(indices[i+0] | indices[i+1] << 16);
OUT_BATCH( indices[i+3] | 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+2] | indices[i+3] << 16);
} }
break; break;
case PIPE_PRIM_QUAD_STRIP: case PIPE_PRIM_QUAD_STRIP:
for (i = 0; i + 3 < nr_indices; i += 2) { for (i = 0; i + 3 < nr_indices; i += 2) {
OUT_BATCH( indices[i+0] | indices[i+1] << 16 ); OUT_BATCH(indices[i+0] | indices[i+1] << 16);
OUT_BATCH( indices[i+3] | indices[i+2] << 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+3] << 16);
} }
break; break;
default: default:
@ -414,16 +405,16 @@ draw_generate_indices( struct vbuf_render *render,
} }
static unsigned static unsigned
draw_calc_nr_indices( uint nr_indices, unsigned type ) draw_calc_nr_indices(uint nr_indices, unsigned type)
{ {
switch (type) { switch (type) {
case 0: case 0:
return nr_indices; return nr_indices;
case PIPE_PRIM_LINE_LOOP: case PIPE_PRIM_LINE_LOOP:
if (nr_indices >= 2) if (nr_indices >= 2)
return nr_indices * 2; return nr_indices * 2;
else else
return 0; return 0;
case PIPE_PRIM_QUADS: case PIPE_PRIM_QUADS:
return (nr_indices / 4) * 6; return (nr_indices / 4) * 6;
case PIPE_PRIM_QUAD_STRIP: case PIPE_PRIM_QUAD_STRIP:
@ -435,9 +426,9 @@ draw_calc_nr_indices( uint nr_indices, unsigned type )
} }
static void static void
i915_vbuf_render_draw( struct vbuf_render *render, i915_vbuf_render_draw(struct vbuf_render *render,
const ushort *indices, const ushort *indices,
uint nr_indices) uint nr_indices)
{ {
struct i915_vbuf_render *i915_render = i915_vbuf_render(render); struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
struct i915_context *i915 = i915_render->i915; struct i915_context *i915 = i915_render->i915;
@ -445,48 +436,47 @@ i915_vbuf_render_draw( struct vbuf_render *render,
save_nr_indices = nr_indices; 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) if (!nr_indices)
return; return;
if (i915->dirty) if (i915->dirty)
i915_update_derived( i915 ); i915_update_derived(i915);
if (i915->hardware_dirty) 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); FLUSH_BATCH(NULL);
/* Make sure state is re-emitted after a flush: /* Make sure state is re-emitted after a flush:
*/ */
i915_update_derived( i915 ); i915_update_derived(i915);
i915_emit_hardware_state( i915 ); i915_emit_hardware_state(i915);
i915->vbo_flushed = 1; i915->vbo_flushed = 1;
if (!BEGIN_BATCH( 1 + (nr_indices + 1)/2, 1 )) { if (!BEGIN_BATCH(1 + (nr_indices + 1)/2, 1)) {
assert(0); assert(0);
goto out; goto out;
} }
} }
OUT_BATCH( _3DPRIMITIVE | OUT_BATCH(_3DPRIMITIVE |
PRIM_INDIRECT | PRIM_INDIRECT |
i915_render->hwprim | i915_render->hwprim |
PRIM_INDIRECT_ELTS | PRIM_INDIRECT_ELTS |
nr_indices ); nr_indices);
draw_generate_indices( render, draw_generate_indices(render,
indices, indices,
save_nr_indices, save_nr_indices,
i915_render->fallback ); i915_render->fallback);
out: out:
return; return;
} }
static void 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_vbuf_render *i915_render = i915_vbuf_render(render);
struct i915_context *i915 = i915_render->i915; 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; i915->dirty |= I915_NEW_VBO;
} }
static void 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); struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
FREE(i915_render); FREE(i915_render);
} }
/** /**
* Create a new primitive render. * Create a new primitive render.
*/ */
static struct vbuf_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 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; 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_alloc_size = 128 * 4096;
i915_render->vbo_size = i915_render->vbo_alloc_size; i915_render->vbo_size = i915_render->vbo_alloc_size;
i915_render->vbo_offset = 0; i915_render->vbo_offset = 0;
i915_render->vbo = pipe_buffer_create(screen, i915_render->vbo = iws->buffer_create(iws, i915_render->vbo_size, 64,
64, INTEL_NEW_VERTEX);
I915_BUFFER_USAGE_LIT_VERTEX, /* TODO JB: is this realy needed? */
i915_render->vbo_size); i915_render->vbo_ptr = iws->buffer_map(iws, i915_render->vbo, TRUE);
i915_render->vbo_ptr = pipe_buffer_map(screen, iws->buffer_unmap(iws, i915_render->vbo);
i915_render->vbo,
PIPE_BUFFER_USAGE_CPU_WRITE);
pipe_buffer_unmap(screen, i915_render->vbo);
return &i915_render->base; return &i915_render->base;
} }
/** /**
* Create a new primitive vbuf/render stage. * 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 vbuf_render *render;
struct draw_stage *stage; struct draw_stage *stage;
@ -564,7 +548,7 @@ struct draw_stage *i915_draw_vbuf_stage( struct i915_context *i915 )
if(!render) if(!render)
return NULL; return NULL;
stage = draw_vbuf_stage( i915->draw, render ); stage = draw_vbuf_stage(i915->draw, render);
if(!stage) { if(!stage) {
render->destroy(render); render->destroy(render);
return NULL; return NULL;

View File

@ -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 "pipe/p_inlines.h"
#include "util/u_memory.h"
#include "util/u_string.h" #include "util/u_string.h"
#include "i915_reg.h" #include "i915_reg.h"
#include "i915_context.h" #include "i915_context.h"
#include "i915_screen.h" #include "i915_screen.h"
#include "i915_buffer.h"
#include "i915_texture.h" #include "i915_texture.h"
#include "i915_winsys.h" #include "intel_winsys.h"
/*
* Probe functions
*/
static const char * static const char *
i915_get_vendor( struct pipe_screen *pscreen ) i915_get_vendor(struct pipe_screen *screen)
{ {
return "Tungsten Graphics, Inc."; return "Tungsten Graphics, Inc.";
} }
static const char * static const char *
i915_get_name( struct pipe_screen *pscreen ) i915_get_name(struct pipe_screen *screen)
{ {
static char buffer[128]; static char buffer[128];
const char *chipset; const char *chipset;
switch (i915_screen(pscreen)->pci_id) { switch (i915_screen(screen)->pci_id) {
case PCI_CHIP_I915_G: case PCI_CHIP_I915_G:
chipset = "915G"; chipset = "915G";
break; break;
@ -86,7 +89,6 @@ i915_get_name( struct pipe_screen *pscreen )
return buffer; return buffer;
} }
static int static int
i915_get_param(struct pipe_screen *screen, int param) i915_get_param(struct pipe_screen *screen, int param)
{ {
@ -122,7 +124,6 @@ i915_get_param(struct pipe_screen *screen, int param)
} }
} }
static float static float
i915_get_paramf(struct pipe_screen *screen, int param) i915_get_paramf(struct pipe_screen *screen, int param)
{ {
@ -148,13 +149,12 @@ i915_get_paramf(struct pipe_screen *screen, int param)
} }
} }
static boolean static boolean
i915_is_format_supported( struct pipe_screen *screen, i915_is_format_supported(struct pipe_screen *screen,
enum pipe_format format, enum pipe_format format,
enum pipe_texture_target target, enum pipe_texture_target target,
unsigned tex_usage, unsigned tex_usage,
unsigned geom_flags ) unsigned geom_flags)
{ {
static const enum pipe_format tex_supported[] = { static const enum pipe_format tex_supported[] = {
PIPE_FORMAT_R8G8B8A8_UNORM, PIPE_FORMAT_R8G8B8A8_UNORM,
@ -173,7 +173,6 @@ i915_is_format_supported( struct pipe_screen *screen,
PIPE_FORMAT_A8R8G8B8_UNORM, PIPE_FORMAT_A8R8G8B8_UNORM,
PIPE_FORMAT_R5G6B5_UNORM, PIPE_FORMAT_R5G6B5_UNORM,
PIPE_FORMAT_S8Z24_UNORM, PIPE_FORMAT_S8Z24_UNORM,
/*PIPE_FORMAT_R16G16B16A16_SNORM,*/
PIPE_FORMAT_NONE /* list terminator */ PIPE_FORMAT_NONE /* list terminator */
}; };
const enum pipe_format *list; 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 ) * Fence functions
{ */
struct pipe_winsys *winsys = screen->winsys;
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 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); struct i915_screen *is = i915_screen(screen);
FREE(trans);
is->iws->fence_reference(is->iws, ptr, fence);
} }
static void * static int
i915_transfer_map( struct pipe_screen *screen, i915_fence_signalled(struct pipe_screen *screen,
struct pipe_transfer *transfer ) struct pipe_fence_handle *fence,
unsigned flags)
{ {
struct i915_texture *tex = (struct i915_texture *)transfer->texture; struct i915_screen *is = i915_screen(screen);
char *map;
unsigned flags = 0;
if (transfer->usage != PIPE_TRANSFER_WRITE) return is->iws->fence_signalled(is->iws, fence);
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;
} }
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 static void
i915_transfer_unmap(struct pipe_screen *screen, i915_destroy_screen(struct pipe_screen *screen)
struct pipe_transfer *transfer)
{ {
struct i915_texture *tex = (struct i915_texture *)transfer->texture; struct i915_screen *is = i915_screen(screen);
pipe_buffer_unmap( screen, tex->buffer );
if (is->iws)
is->iws->destroy(is->iws);
FREE(is);
} }
/** /**
* Create a new i915_screen object * Create a new i915_screen object
*/ */
struct pipe_screen * 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; return NULL;
switch (pci_id) { switch (pci_id) {
case PCI_CHIP_I915_G: case PCI_CHIP_I915_G:
case PCI_CHIP_I915_GM: case PCI_CHIP_I915_GM:
i915screen->is_i945 = FALSE; is->is_i945 = FALSE;
break; break;
case PCI_CHIP_I945_G: 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_G33_G:
case PCI_CHIP_Q33_G: case PCI_CHIP_Q33_G:
case PCI_CHIP_Q35_G: case PCI_CHIP_Q35_G:
i915screen->is_i945 = TRUE; is->is_i945 = TRUE;
break; break;
default: default:
@ -326,24 +276,25 @@ i915_create_screen(struct pipe_winsys *winsys, uint pci_id)
return NULL; 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; is->base.get_name = i915_get_name;
i915screen->screen.get_vendor = i915_get_vendor; is->base.get_vendor = i915_get_vendor;
i915screen->screen.get_param = i915_get_param; is->base.get_param = i915_get_param;
i915screen->screen.get_paramf = i915_get_paramf; is->base.get_paramf = i915_get_paramf;
i915screen->screen.is_format_supported = i915_is_format_supported; is->base.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;
i915_init_screen_texture_functions(&i915screen->screen); is->base.fence_reference = i915_fence_reference;
u_simple_screen_init(&i915screen->screen); 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;
} }

View File

@ -25,17 +25,14 @@
* *
**************************************************************************/ **************************************************************************/
#ifndef I915_SCREEN_H #ifndef I915_SCREEN_H
#define I915_SCREEN_H #define I915_SCREEN_H
#include "pipe/p_state.h"
#include "pipe/p_screen.h" #include "pipe/p_screen.h"
#ifdef __cplusplus struct intel_winsys;
extern "C" {
#endif
/** /**
@ -43,13 +40,14 @@ extern "C" {
*/ */
struct i915_screen struct i915_screen
{ {
struct pipe_screen screen; struct pipe_screen base;
struct intel_winsys *iws;
boolean is_i945; boolean is_i945;
uint pci_id; uint pci_id;
}; };
/** /**
* Subclass of pipe_transfer * Subclass of pipe_transfer
*/ */
@ -61,7 +59,11 @@ struct i915_transfer
}; };
/** cast wrappers */ /*
* Cast wrappers
*/
static INLINE struct i915_screen * static INLINE struct i915_screen *
i915_screen(struct pipe_screen *pscreen) i915_screen(struct pipe_screen *pscreen)
{ {
@ -69,14 +71,10 @@ i915_screen(struct pipe_screen *pscreen)
} }
static INLINE struct i915_transfer * static INLINE struct i915_transfer *
i915_transfer( struct pipe_transfer *transfer ) i915_transfer(struct pipe_transfer *transfer)
{ {
return (struct i915_transfer *)transfer; return (struct i915_transfer *)transfer;
} }
#ifdef __cplusplus
}
#endif
#endif /* I915_SCREEN_H */ #endif /* I915_SCREEN_H */

View File

@ -518,7 +518,7 @@ static void i915_set_constant_buffer(struct pipe_context *pipe,
const struct pipe_constant_buffer *buf) const struct pipe_constant_buffer *buf)
{ {
struct i915_context *i915 = i915_context(pipe); struct i915_context *i915 = i915_context(pipe);
struct pipe_winsys *ws = pipe->winsys; struct pipe_screen *screen = pipe->screen;
draw_flush(i915->draw); draw_flush(i915->draw);
assert(shader < PIPE_SHADER_TYPES); assert(shader < PIPE_SHADER_TYPES);
@ -536,10 +536,10 @@ static void i915_set_constant_buffer(struct pipe_context *pipe,
if (buf) { if (buf) {
void *mapped; void *mapped;
if (buf->buffer && buf->buffer->size && 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))) { PIPE_BUFFER_USAGE_CPU_READ))) {
memcpy(i915->current.constants[shader], mapped, buf->buffer->size); 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] i915->current.num_user_constants[shader]
= buf->buffer->size / (4 * sizeof(float)); = buf->buffer->size / (4 * sizeof(float));
} }
@ -751,38 +751,38 @@ static void i915_set_edgeflags(struct pipe_context *pipe,
void void
i915_init_state_functions( struct i915_context *i915 ) i915_init_state_functions( struct i915_context *i915 )
{ {
i915->pipe.set_edgeflags = i915_set_edgeflags; i915->base.set_edgeflags = i915_set_edgeflags;
i915->pipe.create_blend_state = i915_create_blend_state; i915->base.create_blend_state = i915_create_blend_state;
i915->pipe.bind_blend_state = i915_bind_blend_state; i915->base.bind_blend_state = i915_bind_blend_state;
i915->pipe.delete_blend_state = i915_delete_blend_state; i915->base.delete_blend_state = i915_delete_blend_state;
i915->pipe.create_sampler_state = i915_create_sampler_state; i915->base.create_sampler_state = i915_create_sampler_state;
i915->pipe.bind_sampler_states = i915_bind_sampler_states; i915->base.bind_sampler_states = i915_bind_sampler_states;
i915->pipe.delete_sampler_state = i915_delete_sampler_state; i915->base.delete_sampler_state = i915_delete_sampler_state;
i915->pipe.create_depth_stencil_alpha_state = i915_create_depth_stencil_state; i915->base.create_depth_stencil_alpha_state = i915_create_depth_stencil_state;
i915->pipe.bind_depth_stencil_alpha_state = i915_bind_depth_stencil_state; i915->base.bind_depth_stencil_alpha_state = i915_bind_depth_stencil_state;
i915->pipe.delete_depth_stencil_alpha_state = i915_delete_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->base.create_rasterizer_state = i915_create_rasterizer_state;
i915->pipe.bind_rasterizer_state = i915_bind_rasterizer_state; i915->base.bind_rasterizer_state = i915_bind_rasterizer_state;
i915->pipe.delete_rasterizer_state = i915_delete_rasterizer_state; i915->base.delete_rasterizer_state = i915_delete_rasterizer_state;
i915->pipe.create_fs_state = i915_create_fs_state; i915->base.create_fs_state = i915_create_fs_state;
i915->pipe.bind_fs_state = i915_bind_fs_state; i915->base.bind_fs_state = i915_bind_fs_state;
i915->pipe.delete_fs_state = i915_delete_fs_state; i915->base.delete_fs_state = i915_delete_fs_state;
i915->pipe.create_vs_state = i915_create_vs_state; i915->base.create_vs_state = i915_create_vs_state;
i915->pipe.bind_vs_state = i915_bind_vs_state; i915->base.bind_vs_state = i915_bind_vs_state;
i915->pipe.delete_vs_state = i915_delete_vs_state; i915->base.delete_vs_state = i915_delete_vs_state;
i915->pipe.set_blend_color = i915_set_blend_color; i915->base.set_blend_color = i915_set_blend_color;
i915->pipe.set_clip_state = i915_set_clip_state; i915->base.set_clip_state = i915_set_clip_state;
i915->pipe.set_constant_buffer = i915_set_constant_buffer; i915->base.set_constant_buffer = i915_set_constant_buffer;
i915->pipe.set_framebuffer_state = i915_set_framebuffer_state; i915->base.set_framebuffer_state = i915_set_framebuffer_state;
i915->pipe.set_polygon_stipple = i915_set_polygon_stipple; i915->base.set_polygon_stipple = i915_set_polygon_stipple;
i915->pipe.set_scissor_state = i915_set_scissor_state; i915->base.set_scissor_state = i915_set_scissor_state;
i915->pipe.set_sampler_textures = i915_set_sampler_textures; i915->base.set_sampler_textures = i915_set_sampler_textures;
i915->pipe.set_viewport_state = i915_set_viewport_state; i915->base.set_viewport_state = i915_set_viewport_state;
i915->pipe.set_vertex_buffers = i915_set_vertex_buffers; i915->base.set_vertex_buffers = i915_set_vertex_buffers;
i915->pipe.set_vertex_elements = i915_set_vertex_elements; i915->base.set_vertex_elements = i915_set_vertex_elements;
} }

View File

@ -28,7 +28,6 @@
#include "i915_reg.h" #include "i915_reg.h"
#include "i915_context.h" #include "i915_context.h"
#include "i915_winsys.h"
#include "i915_batch.h" #include "i915_batch.h"
#include "i915_reg.h" #include "i915_reg.h"
@ -107,7 +106,7 @@ i915_emit_hardware_state(struct i915_context *i915 )
6 6
) * 3/2; /* plus 50% margin */ ) * 3/2; /* plus 50% margin */
const unsigned relocs = ( I915_TEX_UNITS + const unsigned relocs = ( I915_TEX_UNITS +
3 3
) * 3/2; /* plus 50% margin */ ) * 3/2; /* plus 50% margin */
#if 0 #if 0
@ -123,9 +122,9 @@ i915_emit_hardware_state(struct i915_context *i915 )
if (i915->hardware_dirty & I915_HW_INVARIENT) if (i915->hardware_dirty & I915_HW_INVARIENT)
{ {
OUT_BATCH(_3DSTATE_AA_CMD | OUT_BATCH(_3DSTATE_AA_CMD |
AA_LINE_ECAAR_WIDTH_ENABLE | AA_LINE_ECAAR_WIDTH_ENABLE |
AA_LINE_ECAAR_WIDTH_1_0 | AA_LINE_ECAAR_WIDTH_1_0 |
AA_LINE_REGION_WIDTH_ENABLE | AA_LINE_REGION_WIDTH_1_0); AA_LINE_REGION_WIDTH_ENABLE | AA_LINE_REGION_WIDTH_1_0);
OUT_BATCH(_3DSTATE_DFLT_DIFFUSE_CMD); OUT_BATCH(_3DSTATE_DFLT_DIFFUSE_CMD);
OUT_BATCH(0); OUT_BATCH(0);
@ -137,24 +136,24 @@ i915_emit_hardware_state(struct i915_context *i915 )
OUT_BATCH(0); OUT_BATCH(0);
OUT_BATCH(_3DSTATE_COORD_SET_BINDINGS | OUT_BATCH(_3DSTATE_COORD_SET_BINDINGS |
CSB_TCB(0, 0) | CSB_TCB(0, 0) |
CSB_TCB(1, 1) | CSB_TCB(1, 1) |
CSB_TCB(2, 2) | CSB_TCB(2, 2) |
CSB_TCB(3, 3) | CSB_TCB(3, 3) |
CSB_TCB(4, 4) | CSB_TCB(4, 4) |
CSB_TCB(5, 5) | CSB_TCB(5, 5) |
CSB_TCB(6, 6) | CSB_TCB(6, 6) |
CSB_TCB(7, 7)); CSB_TCB(7, 7));
OUT_BATCH(_3DSTATE_RASTER_RULES_CMD | OUT_BATCH(_3DSTATE_RASTER_RULES_CMD |
ENABLE_POINT_RASTER_RULE | ENABLE_POINT_RASTER_RULE |
OGL_POINT_RASTER_RULE | OGL_POINT_RASTER_RULE |
ENABLE_LINE_STRIP_PROVOKE_VRTX | ENABLE_LINE_STRIP_PROVOKE_VRTX |
ENABLE_TRI_FAN_PROVOKE_VRTX | ENABLE_TRI_FAN_PROVOKE_VRTX |
LINE_STRIP_PROVOKE_VRTX(1) | LINE_STRIP_PROVOKE_VRTX(1) |
TRI_FAN_PROVOKE_VRTX(2) | TRI_FAN_PROVOKE_VRTX(2) |
ENABLE_TEXKILL_3D_4D | ENABLE_TEXKILL_3D_4D |
TEXKILL_4D); TEXKILL_4D);
/* Need to initialize this to zero. /* 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) if (i915->hardware_dirty & I915_HW_IMMEDIATE)
{ {
OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 |
I1_LOAD_S(0) | I1_LOAD_S(0) |
I1_LOAD_S(1) | I1_LOAD_S(1) |
I1_LOAD_S(2) | I1_LOAD_S(2) |
I1_LOAD_S(4) | I1_LOAD_S(4) |
I1_LOAD_S(5) | I1_LOAD_S(5) |
I1_LOAD_S(6) | I1_LOAD_S(6) |
(5)); (5));
if(i915->vbo) if(i915->vbo)
OUT_RELOC(i915->vbo, OUT_RELOC(i915->vbo,
I915_BUFFER_ACCESS_READ, INTEL_USAGE_VERTEX,
i915->current.immediate[I915_IMMEDIATE_S0]); i915->current.immediate[I915_IMMEDIATE_S0]);
else else
/* FIXME: we should not do this */ /* FIXME: we should not do this */
OUT_BATCH(0); OUT_BATCH(0);
OUT_BATCH(i915->current.immediate[I915_IMMEDIATE_S1]); OUT_BATCH(i915->current.immediate[I915_IMMEDIATE_S1]);
OUT_BATCH(i915->current.immediate[I915_IMMEDIATE_S2]); OUT_BATCH(i915->current.immediate[I915_IMMEDIATE_S2]);
OUT_BATCH(i915->current.immediate[I915_IMMEDIATE_S4]); OUT_BATCH(i915->current.immediate[I915_IMMEDIATE_S4]);
@ -200,7 +199,7 @@ i915_emit_hardware_state(struct i915_context *i915 )
{ {
int i; int i;
for (i = 0; i < I915_MAX_DYNAMIC; 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; struct pipe_surface *depth_surface = i915->framebuffer.zsbuf;
if (cbuf_surface) { if (cbuf_surface) {
unsigned ctile = BUF_3D_USE_FENCE; unsigned ctile = BUF_3D_USE_FENCE;
struct i915_texture *tex = (struct i915_texture *) struct i915_texture *tex = (struct i915_texture *)
cbuf_surface->texture; cbuf_surface->texture;
assert(tex); assert(tex);
if (tex && tex->tiled) { if (tex && tex->sw_tiled) {
ctile = BUF_3D_TILED_SURFACE; ctile = BUF_3D_TILED_SURFACE;
} }
OUT_BATCH(_3DSTATE_BUF_INFO_CMD); OUT_BATCH(_3DSTATE_BUF_INFO_CMD);
OUT_BATCH(BUF_3D_ID_COLOR_BACK | OUT_BATCH(BUF_3D_ID_COLOR_BACK |
BUF_3D_PITCH(tex->stride) | /* pitch in bytes */ BUF_3D_PITCH(tex->stride) | /* pitch in bytes */
ctile); ctile);
OUT_RELOC(tex->buffer, OUT_RELOC(tex->buffer,
I915_BUFFER_ACCESS_WRITE, INTEL_USAGE_RENDER,
cbuf_surface->offset); cbuf_surface->offset);
} }
/* What happens if no zbuf?? /* What happens if no zbuf??
*/ */
if (depth_surface) { if (depth_surface) {
unsigned ztile = BUF_3D_USE_FENCE; unsigned ztile = BUF_3D_USE_FENCE;
struct i915_texture *tex = (struct i915_texture *) struct i915_texture *tex = (struct i915_texture *)
depth_surface->texture; depth_surface->texture;
assert(tex); assert(tex);
if (tex && tex->tiled) { if (tex && tex->sw_tiled) {
ztile = BUF_3D_TILED_SURFACE; ztile = BUF_3D_TILED_SURFACE;
} }
OUT_BATCH(_3DSTATE_BUF_INFO_CMD); OUT_BATCH(_3DSTATE_BUF_INFO_CMD);
OUT_BATCH(BUF_3D_ID_DEPTH | OUT_BATCH(BUF_3D_ID_DEPTH |
BUF_3D_PITCH(tex->stride) | /* pitch in bytes */ BUF_3D_PITCH(tex->stride) | /* pitch in bytes */
ztile); ztile);
OUT_RELOC(tex->buffer, OUT_RELOC(tex->buffer,
I915_BUFFER_ACCESS_WRITE, INTEL_USAGE_RENDER,
depth_surface->offset); depth_surface->offset);
} }
{ {
unsigned cformat, zformat = 0; unsigned cformat, zformat = 0;
if (cbuf_surface) if (cbuf_surface)
cformat = cbuf_surface->format; cformat = cbuf_surface->format;
else else
cformat = PIPE_FORMAT_A8R8G8B8_UNORM; /* arbitrary */ cformat = PIPE_FORMAT_A8R8G8B8_UNORM; /* arbitrary */
cformat = translate_format(cformat); cformat = translate_format(cformat);
if (depth_surface) if (depth_surface)
zformat = translate_depth_format( i915->framebuffer.zsbuf->format ); zformat = translate_depth_format( i915->framebuffer.zsbuf->format );
OUT_BATCH(_3DSTATE_DST_BUF_VARS_CMD); OUT_BATCH(_3DSTATE_DST_BUF_VARS_CMD);
OUT_BATCH(DSTORG_HORT_BIAS(0x8) | /* .5 */ OUT_BATCH(DSTORG_HORT_BIAS(0x8) | /* .5 */
DSTORG_VERT_BIAS(0x8) | /* .5 */ DSTORG_VERT_BIAS(0x8) | /* .5 */
LOD_PRECLAMP_OGL | LOD_PRECLAMP_OGL |
TEX_DEFAULT_COLOR_OGL | TEX_DEFAULT_COLOR_OGL |
cformat | cformat |
zformat ); zformat );
} }
} }
@ -290,16 +289,13 @@ i915_emit_hardware_state(struct i915_context *i915 )
OUT_BATCH(enabled); OUT_BATCH(enabled);
for (unit = 0; unit < I915_TEX_UNITS; unit++) { for (unit = 0; unit < I915_TEX_UNITS; unit++) {
if (enabled & (1 << unit)) { if (enabled & (1 << unit)) {
struct pipe_buffer *buf = struct intel_buffer *buf = i915->texture[unit]->buffer;
i915->texture[unit]->buffer;
uint offset = 0; uint offset = 0;
assert(buf); assert(buf);
count++; count++;
OUT_RELOC(buf, OUT_RELOC(buf, INTEL_USAGE_SAMPLER, offset);
I915_BUFFER_ACCESS_READ,
offset);
OUT_BATCH(i915->current.texbuffer[unit][0]); /* MS3 */ OUT_BATCH(i915->current.texbuffer[unit][0]); /* MS3 */
OUT_BATCH(i915->current.texbuffer[unit][1]); /* MS4 */ 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->hardware_dirty & I915_HW_SAMPLER)
{ {
if (i915->current.sampler_enable_nr) { if (i915->current.sampler_enable_nr) {
int i; int i;
OUT_BATCH( _3DSTATE_SAMPLER_STATE | OUT_BATCH( _3DSTATE_SAMPLER_STATE |
(3 * i915->current.sampler_enable_nr) ); (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++) { for (i = 0; i < I915_TEX_UNITS; i++) {
if (i915->current.sampler_enable_flags & (1<<i)) { if (i915->current.sampler_enable_flags & (1<<i)) {
OUT_BATCH( i915->current.sampler[i][0] ); OUT_BATCH( i915->current.sampler[i][0] );
OUT_BATCH( i915->current.sampler[i][1] ); OUT_BATCH( i915->current.sampler[i][1] );
OUT_BATCH( i915->current.sampler[i][2] ); OUT_BATCH( i915->current.sampler[i][2] );
} }
} }
} }
} }
#endif #endif

View File

@ -247,7 +247,7 @@ i915_update_texture(struct i915_context *i915,
assert(format); assert(format);
assert(pitch); assert(pitch);
if (tex->tiled) { if (tex->sw_tiled) {
assert(!((pitch - 1) & pitch)); assert(!((pitch - 1) & pitch));
tiled = MS3_TILED_SURFACE; tiled = MS3_TILED_SURFACE;
} }

View File

@ -89,6 +89,6 @@ i915_surface_fill(struct pipe_context *pipe,
void void
i915_init_surface_functions(struct i915_context *i915) i915_init_surface_functions(struct i915_context *i915)
{ {
i915->pipe.surface_copy = i915_surface_copy; i915->base.surface_copy = i915_surface_copy;
i915->pipe.surface_fill = i915_surface_fill; i915->base.surface_fill = i915_surface_fill;
} }

View File

@ -42,12 +42,14 @@
#include "i915_texture.h" #include "i915_texture.h"
#include "i915_debug.h" #include "i915_debug.h"
#include "i915_screen.h" #include "i915_screen.h"
#include "i915_winsys.h" #include "intel_winsys.h"
/* /*
* Helper function and arrays * Helper function and arrays
*/ */
/** /**
* Initial offset for Cube map. * Initial offset for Cube map.
*/ */
@ -133,7 +135,7 @@ i915_miptree_set_level_info(struct i915_texture *tex,
static void static void
i915_miptree_set_image_offset(struct i915_texture *tex, 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) if (img == 0 && level == 0)
assert(x == 0 && y == 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) if (pt->last_level > 0 || pt->block.size != 4)
return 0; return 0;
i915_miptree_set_level_info( tex, 0, 1, i915_miptree_set_level_info(tex, 0, 1,
tex->base.width[0], tex->base.width[0],
tex->base.height[0], tex->base.height[0],
1 ); 1);
i915_miptree_set_image_offset( tex, 0, 0, 0, 0 ); 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) { if (tex->base.width[0] >= 240) {
tex->stride = power_of_two(tex->base.nblocksx[0] * pt->block.size); tex->stride = power_of_two(tex->base.nblocksx[0] * pt->block.size);
tex->total_nblocksy = round_up(tex->base.nblocksy[0], 8); tex->total_nblocksy = round_up(tex->base.nblocksy[0], 8);
#else tex->hw_tiled = INTEL_TILE_X;
if (tex->base.width[0] >= 240) {
tex->stride = 2048 * 4;
tex->total_nblocksy = round_up(tex->base.nblocksy[0], 8);
#endif
} else if (tex->base.width[0] == 64 && tex->base.height[0] == 64) { } 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->stride = power_of_two(tex->base.nblocksx[0] * pt->block.size);
tex->total_nblocksy = round_up(tex->base.nblocksy[0], 8); tex->total_nblocksy = round_up(tex->base.nblocksy[0], 8);
} else { } else {
return 0; return FALSE;
} }
debug_printf("%s size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__, 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->base.width[0], tex->base.height[0], pt->block.size,
tex->stride, tex->total_nblocksy, tex->stride * tex->total_nblocksy); tex->stride, tex->total_nblocksy, tex->stride * tex->total_nblocksy);
return 1; return TRUE;
} }
static void 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; struct pipe_texture *pt = &tex->base;
const int align_x = 2, align_y = 4; 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 */ /* used for scanouts that need special layouts */
if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_PRIMARY) if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_PRIMARY)
if (i915_scanout_layout(tex)) if (i915_scanout_layout(tex))
return; return;
tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4); 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) { if (pt->last_level > 0) {
unsigned mip1_nblocksx 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))); + pf_get_nblocksx(&pt->block, minify(minify(width)));
if (mip1_nblocksx > nblocksx) 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 /* 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. /* Layout_below: step right after second mipmap level.
*/ */
if (level == 1) { if (level == 1) {
x += align(nblocksx, align_x); x += align(nblocksx, align_x);
} }
else { else {
y += nblocksy; y += nblocksy;
} }
width = minify(width); 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 static void
i945_miptree_layout_cube(struct i915_texture *tex) 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 static boolean
i945_miptree_layout(struct i915_texture * tex) i945_miptree_layout(struct i915_texture * tex)
{ {
struct pipe_texture *pt = &tex->base; struct pipe_texture *pt = &tex->base;
unsigned level;
switch (pt->target) { 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: case PIPE_TEXTURE_CUBE:
i945_miptree_layout_cube(tex); i945_miptree_layout_cube(tex);
break; 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: default:
assert(0); assert(0);
return FALSE; 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; return TRUE;
} }
/*
* Screen texture functions
*/
static struct pipe_texture * static struct pipe_texture *
i915_texture_create(struct pipe_screen *screen, i915_texture_create(struct pipe_screen *screen,
const struct pipe_texture *templat) 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); struct i915_texture *tex = CALLOC_STRUCT(i915_texture);
size_t tex_size; size_t tex_size;
unsigned buf_usage = 0; 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.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]); 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)) if (!i945_miptree_layout(tex))
goto fail; goto fail;
} else { } else {
if (!i915_miptree_layout(tex)) if (!i915_miptree_layout(tex))
goto fail; goto fail;
} }
tex_size = tex->stride * tex->total_nblocksy; 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) if (templat->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY && templat->width[0] != 64)
buf_usage |= I915_BUFFER_USAGE_SCANOUT; buf_usage = INTEL_NEW_SCANOUT;
else
tex->buffer = screen->buffer_create(screen, 64, buf_usage, tex_size); buf_usage = INTEL_NEW_TEXTURE;
tex->buffer = iws->buffer_create(iws, tex_size, 64, buf_usage);
if (!tex->buffer) if (!tex->buffer)
goto fail; 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 #if 0
void *ptr = ws->buffer_map(ws, tex->buffer, void *ptr = ws->buffer_map(ws, tex->buffer,
PIPE_BUFFER_USAGE_CPU_WRITE); PIPE_BUFFER_USAGE_CPU_WRITE);
@ -629,18 +650,56 @@ fail:
return NULL; 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 static void
i915_texture_destroy(struct pipe_texture *pt) i915_texture_destroy(struct pipe_texture *pt)
{ {
struct i915_texture *tex = (struct i915_texture *)pt; struct i915_texture *tex = (struct i915_texture *)pt;
struct intel_winsys *iws = i915_screen(pt->screen)->iws;
uint i; uint i;
/* /*
DBG("%s deleting %p\n", __FUNCTION__, (void *) tex); 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++) for (i = 0; i < PIPE_MAX_TEXTURE_LEVELS; i++)
if (tex->image_offset[i]) if (tex->image_offset[i])
@ -649,6 +708,12 @@ i915_texture_destroy(struct pipe_texture *pt)
FREE(tex); FREE(tex);
} }
/*
* Screen surface functions
*/
static struct pipe_surface * static struct pipe_surface *
i915_get_tex_surface(struct pipe_screen *screen, i915_get_tex_surface(struct pipe_screen *screen,
struct pipe_texture *pt, struct pipe_texture *pt,
@ -684,11 +749,122 @@ i915_get_tex_surface(struct pipe_screen *screen,
return ps; return ps;
} }
static struct pipe_texture * static void
i915_texture_blanket(struct pipe_screen * screen, i915_tex_surface_destroy(struct pipe_surface *surf)
const struct pipe_texture *base, {
const unsigned *stride, pipe_texture_reference(&surf->texture, NULL);
struct pipe_buffer *buffer) 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; struct i915_texture *tex;
assert(screen); assert(screen);
@ -708,52 +884,28 @@ i915_texture_blanket(struct pipe_screen * screen,
pipe_reference_init(&tex->base.reference, 1); pipe_reference_init(&tex->base.reference, 1);
tex->base.screen = screen; 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_level_info(tex, 0, 1, base->width[0], base->height[0], 1);
i915_miptree_set_image_offset(tex, 0, 0, 0, 0); i915_miptree_set_image_offset(tex, 0, 0, 0, 0);
pipe_buffer_reference(&tex->buffer, buffer); tex->buffer = buffer;
return &tex->base; return &tex->base;
} }
void boolean
i915_init_texture_functions(struct i915_context *i915) i915_get_texture_buffer_intel(struct pipe_texture *texture,
{ struct intel_buffer **buffer,
// i915->pipe.texture_update = i915_texture_update; unsigned *stride)
}
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 )
{ {
struct i915_texture *tex = (struct i915_texture *)texture; struct i915_texture *tex = (struct i915_texture *)texture;
if (!tex) if (!texture)
return FALSE; return FALSE;
pipe_buffer_reference(buf, tex->buffer); *stride = tex->stride;
*buffer = tex->buffer;
if (stride)
*stride = tex->stride;
return TRUE; return TRUE;
} }

View File

@ -28,16 +28,9 @@
#ifndef I915_TEXTURE_H #ifndef I915_TEXTURE_H
#define I915_TEXTURE_H #define I915_TEXTURE_H
struct i915_context; struct i915_screen;
struct pipe_screen;
extern void extern void
i915_init_texture_functions(struct i915_context *i915); i915_init_screen_texture_functions(struct i915_screen *is);
extern void
i915_init_screen_texture_functions(struct pipe_screen *screen);
#endif /* I915_TEXTURE_H */ #endif /* I915_TEXTURE_H */

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -2,8 +2,12 @@ Import('*')
env = env.Clone() 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.Tool('udis86')
env.ParseConfig('llvm-config --cppflags')
llvmpipe = env.ConvenienceLibrary( llvmpipe = env.ConvenienceLibrary(
target = 'llvmpipe', target = 'llvmpipe',
@ -57,8 +61,6 @@ llvmpipe = env.ConvenienceLibrary(
env = env.Clone() env = env.Clone()
env['LINK'] = env['CXX']
env.ParseConfig('llvm-config --libs jit interpreter nativecodegen bitwriter')
env.Prepend(LIBS = [llvmpipe] + auxiliaries) env.Prepend(LIBS = [llvmpipe] + auxiliaries)
env.Program( env.Program(

View File

@ -52,6 +52,7 @@
#include "lp_bld_type.h" #include "lp_bld_type.h"
#include "lp_bld_const.h" #include "lp_bld_const.h"
#include "lp_bld_intr.h" #include "lp_bld_intr.h"
#include "lp_bld_logic.h"
#include "lp_bld_arit.h" #include "lp_bld_arit.h"
@ -98,11 +99,8 @@ lp_build_min_simple(struct lp_build_context *bld,
if(intrinsic) if(intrinsic)
return lp_build_intrinsic_binary(bld->builder, intrinsic, lp_build_vec_type(bld->type), a, b); return lp_build_intrinsic_binary(bld->builder, intrinsic, lp_build_vec_type(bld->type), a, b);
if(type.floating) cond = lp_build_cmp(bld, PIPE_FUNC_LESS, a, b);
cond = LLVMBuildFCmp(bld->builder, LLVMRealULT, a, b, ""); return lp_build_select(bld, cond, a, b);
else
cond = LLVMBuildICmp(bld->builder, type.sign ? LLVMIntSLT : LLVMIntULT, a, b, "");
return LLVMBuildSelect(bld->builder, cond, a, b, "");
} }
@ -149,11 +147,8 @@ lp_build_max_simple(struct lp_build_context *bld,
if(intrinsic) if(intrinsic)
return lp_build_intrinsic_binary(bld->builder, intrinsic, lp_build_vec_type(bld->type), a, b); return lp_build_intrinsic_binary(bld->builder, intrinsic, lp_build_vec_type(bld->type), a, b);
if(type.floating) cond = lp_build_cmp(bld, PIPE_FUNC_GREATER, a, b);
cond = LLVMBuildFCmp(bld->builder, LLVMRealULT, a, b, ""); return lp_build_select(bld, cond, a, b);
else
cond = LLVMBuildICmp(bld->builder, type.sign ? LLVMIntSLT : LLVMIntULT, a, b, "");
return LLVMBuildSelect(bld->builder, cond, b, a, "");
} }

View File

@ -33,7 +33,6 @@
*/ */
#include "pipe/p_defines.h"
#include "lp_bld_type.h" #include "lp_bld_type.h"
#include "lp_bld_const.h" #include "lp_bld_const.h"
#include "lp_bld_intr.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 zeros = LLVMConstNull(int_vec_type);
LLVMValueRef ones = LLVMConstAllOnes(int_vec_type); LLVMValueRef ones = LLVMConstAllOnes(int_vec_type);
LLVMValueRef cond; LLVMValueRef cond;
LLVMValueRef res;
unsigned i;
if(func == PIPE_FUNC_NEVER) if(func == PIPE_FUNC_NEVER)
return zeros; return zeros;
@ -68,7 +69,6 @@ lp_build_cmp(struct lp_build_context *bld,
LLVMValueRef args[3]; LLVMValueRef args[3];
unsigned cc; unsigned cc;
boolean swap; boolean swap;
LLVMValueRef res;
swap = FALSE; swap = FALSE;
switch(func) { switch(func) {
@ -219,7 +219,28 @@ lp_build_cmp(struct lp_build_context *bld,
assert(0); assert(0);
return bld->undef; return bld->undef;
} }
#if 0
/* XXX: Although valid IR, no LLVM target currently support this */
cond = LLVMBuildFCmp(bld->builder, op, a, b, ""); 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 { else {
LLVMIntPredicate op; LLVMIntPredicate op;
@ -246,10 +267,31 @@ lp_build_cmp(struct lp_build_context *bld,
assert(0); assert(0);
return bld->undef; return bld->undef;
} }
#if 0
/* XXX: Although valid IR, no LLVM target currently support this */
cond = LLVMBuildICmp(bld->builder, op, a, b, ""); 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;
} }

View File

@ -39,6 +39,8 @@
#include <llvm-c/Core.h> #include <llvm-c/Core.h>
#include "pipe/p_defines.h" /* For PIPE_FUNC_xxx */
union lp_type type; union lp_type type;
struct lp_build_context; struct lp_build_context;

View File

@ -687,10 +687,6 @@ emit_instruction(
return 0; return 0;
break; break;
case TGSI_OPCODE_CND0:
return 0;
break;
case TGSI_OPCODE_DP2A: case TGSI_OPCODE_DP2A:
tmp0 = emit_fetch( bld, inst, 0, CHAN_X ); /* xmm0 = src[0].x */ tmp0 = emit_fetch( bld, inst, 0, CHAN_X ); /* xmm0 = src[0].x */
tmp1 = emit_fetch( bld, inst, 1, CHAN_X ); /* xmm1 = src[1].x */ tmp1 = emit_fetch( bld, inst, 1, CHAN_X ); /* xmm1 = src[1].x */

View File

@ -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;
}

View File

@ -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 */

View File

@ -22,4 +22,15 @@ nouveau_bo(struct pipe_buffer *pb)
int nouveau_screen_init(struct nouveau_screen *, struct nouveau_device *); int nouveau_screen_init(struct nouveau_screen *, struct nouveau_device *);
void nouveau_screen_fini(struct nouveau_screen *); 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 #endif

View File

@ -75,9 +75,7 @@ struct nv50_miptree_level {
}; };
struct nv50_miptree { struct nv50_miptree {
struct pipe_texture base; struct nouveau_miptree base;
struct nouveau_bo *bo;
struct nv50_miptree_level level[PIPE_MAX_TEXTURE_LEVELS]; struct nv50_miptree_level level[PIPE_MAX_TEXTURE_LEVELS];
int image_nr; int image_nr;

View File

@ -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 nouveau_device *dev = nouveau_screen(pscreen)->device;
struct nv50_miptree *mt = CALLOC_STRUCT(nv50_miptree); 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 width = tmp->width[0], height = tmp->height[0];
unsigned depth = tmp->depth[0]; unsigned depth = tmp->depth[0];
uint32_t tile_mode, tile_flags, tile_h; uint32_t tile_mode, tile_flags, tile_h;
int ret, i, l; int ret, i, l;
mt->base = *tmp; *pt = *tmp;
pipe_reference_init(&mt->base.reference, 1); pipe_reference_init(&pt->reference, 1);
mt->base.screen = pscreen; pt->screen = pscreen;
switch (pt->format) { switch (pt->format) {
case PIPE_FORMAT_Z32_FLOAT: 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, 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) { if (ret) {
FREE(mt); FREE(mt);
return NULL; return NULL;
} }
return &mt->base; return pt;
} }
static struct pipe_texture * static struct pipe_texture *
@ -141,15 +142,15 @@ nv50_miptree_blanket(struct pipe_screen *pscreen, const struct pipe_texture *pt,
if (!mt) if (!mt)
return NULL; return NULL;
mt->base = *pt; mt->base.base = *pt;
pipe_reference_init(&mt->base.reference, 1); pipe_reference_init(&mt->base.base.reference, 1);
mt->base.screen = pscreen; mt->base.base.screen = pscreen;
mt->image_nr = 1; mt->image_nr = 1;
mt->level[0].pitch = *stride; mt->level[0].pitch = *stride;
mt->level[0].image_offset = CALLOC(1, sizeof(unsigned)); mt->level[0].image_offset = CALLOC(1, sizeof(unsigned));
nouveau_bo_ref(bo, &mt->bo); nouveau_bo_ref(bo, &mt->base.bo);
return &mt->base; return &mt->base.base;
} }
static void static void
@ -157,7 +158,7 @@ nv50_miptree_destroy(struct pipe_texture *pt)
{ {
struct nv50_miptree *mt = nv50_miptree(pt); struct nv50_miptree *mt = nv50_miptree(pt);
nouveau_bo_ref(NULL, &mt->bo); nouveau_bo_ref(NULL, &mt->base.bo);
FREE(mt); FREE(mt);
} }

View File

@ -1106,10 +1106,10 @@ convert_to_long(struct nv50_pc *pc, struct nv50_program_exec *e)
m = 0xffff7fff; m = 0xffff7fff;
break; break;
case 0x8: case 0x8:
/* INTERP */ /* INTERP (move centroid, perspective and flat bits) */
m = ~0x02000000; m = ~0x03000100;
if (e->inst[0] & 0x02000000) q = (e->inst[0] & (3 << 24)) >> (24 - 16);
q = 0x00020000; q |= (e->inst[0] & (1 << 8)) << (18 - 8);
break; break;
case 0x9: case 0x9:
/* RCP */ /* RCP */
@ -1495,6 +1495,7 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok)
} }
break; break;
case TGSI_OPCODE_MOV: case TGSI_OPCODE_MOV:
case TGSI_OPCODE_SWZ:
for (c = 0; c < 4; c++) { for (c = 0; c < 4; c++) {
if (!(mask & (1 << c))) if (!(mask & (1 << c)))
continue; continue;

View File

@ -33,7 +33,7 @@ nv50_state_validate_fb(struct nv50_context *nv50)
for (i = 0; i < fb->nr_cbufs; i++) { for (i = 0; i < fb->nr_cbufs; i++) {
struct pipe_texture *pt = fb->cbufs[i]->texture; 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) { if (!gw) {
w = fb->cbufs[i]->width; w = fb->cbufs[i]->width;
@ -75,7 +75,7 @@ nv50_state_validate_fb(struct nv50_context *nv50)
if (fb->zsbuf) { if (fb->zsbuf) {
struct pipe_texture *pt = fb->zsbuf->texture; 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) { if (!gw) {
w = fb->zsbuf->width; w = fb->zsbuf->width;

View File

@ -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 nv50_miptree *mt = nv50_miptree(ps->texture);
struct nouveau_channel *chan = screen->eng2d->channel; struct nouveau_channel *chan = screen->eng2d->channel;
struct nouveau_grobj *eng2d = screen->eng2d; 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 format, mthd = dst ? NV50_2D_DST_FORMAT : NV50_2D_SRC_FORMAT;
int flags = NOUVEAU_BO_VRAM | (dst ? NOUVEAU_BO_WR : NOUVEAU_BO_RD); int flags = NOUVEAU_BO_VRAM | (dst ? NOUVEAU_BO_WR : NOUVEAU_BO_RD);

View File

@ -29,7 +29,7 @@ static int
nv50_tex_construct(struct nv50_context *nv50, struct nouveau_stateobj *so, nv50_tex_construct(struct nv50_context *nv50, struct nouveau_stateobj *so,
struct nv50_miptree *mt, int unit) struct nv50_miptree *mt, int unit)
{ {
switch (mt->base.format) { switch (mt->base.base.format) {
case PIPE_FORMAT_A8R8G8B8_UNORM: case PIPE_FORMAT_A8R8G8B8_UNORM:
so_data(so, NV50TIC_0_0_MAPA_C3 | NV50TIC_0_0_TYPEA_UNORM | so_data(so, NV50TIC_0_0_MAPA_C3 | NV50TIC_0_0_TYPEA_UNORM |
NV50TIC_0_0_MAPR_C2 | NV50TIC_0_0_TYPER_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; 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); NOUVEAU_BO_RD, 0, 0);
if (nv50->sampler[unit]->normalized) 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 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, 0x00300000);
so_data (so, mt->base.width[0]); so_data (so, mt->base.base.width[0]);
so_data (so, (mt->base.last_level << 28) | so_data (so, (mt->base.base.last_level << 28) |
(mt->base.depth[0] << 16) | mt->base.height[0]); (mt->base.base.depth[0] << 16) | mt->base.base.height[0]);
so_data (so, 0x03000000); so_data (so, 0x03000000);
so_data (so, mt->base.last_level << 4); so_data (so, mt->base.base.last_level << 4);
return 0; return 0;
} }

View File

@ -148,8 +148,8 @@ nv50_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
tx->base.usage = usage; tx->base.usage = usage;
tx->level_pitch = lvl->pitch; tx->level_pitch = lvl->pitch;
tx->level_width = mt->base.width[level]; tx->level_width = mt->base.base.width[level];
tx->level_height = mt->base.height[level]; tx->level_height = mt->base.base.height[level];
tx->level_offset = lvl->image_offset[image]; tx->level_offset = lvl->image_offset[image];
tx->level_tiling = lvl->tile_mode; tx->level_tiling = lvl->tile_mode;
tx->level_x = x; tx->level_x = x;
@ -162,7 +162,7 @@ nv50_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
} }
if (usage != PIPE_TRANSFER_WRITE) { 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, tx->level_pitch, tx->level_tiling,
x, y, x, y,
tx->level_width, tx->level_height, 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, nv50_transfer_rect_m2mf(pscreen, tx->bo, 0, tx->base.stride,
tx->bo->tile_mode, 0, 0, tx->bo->tile_mode, 0, 0,
tx->base.width, tx->base.height, 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_pitch, tx->level_tiling,
tx->level_x, tx->level_y, tx->level_x, tx->level_y,
tx->level_width, tx->level_height, tx->level_width, tx->level_height,

View File

@ -178,7 +178,7 @@ nv50_draw_elements_inline_u08(struct nv50_context *nv50, uint8_t *map,
BEGIN_RING(chan, tesla, 0x400015f0, nr >> 1); BEGIN_RING(chan, tesla, 0x400015f0, nr >> 1);
for (i = 0; i < nr; i += 2) 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; count -= nr;
map += 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); BEGIN_RING(chan, tesla, 0x400015f0, nr >> 1);
for (i = 0; i < nr; i += 2) 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; count -= nr;
map += nr; map += nr;
@ -313,18 +313,18 @@ nv50_vbo_static_attrib(struct nv50_context *nv50, unsigned attrib,
so_data (so, fui(v[3])); so_data (so, fui(v[3]));
break; break;
case 3: 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[0]));
so_data (so, fui(v[1])); so_data (so, fui(v[1]));
so_data (so, fui(v[2])); so_data (so, fui(v[2]));
break; break;
case 2: 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[0]));
so_data (so, fui(v[1])); so_data (so, fui(v[1]));
break; break;
case 1: 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])); so_data (so, fui(v[0]));
break; break;
default: default:

View File

@ -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); OUT_CS_INDEX_RELOC(index_buffer, 0, count, RADEON_GEM_DOMAIN_GTT, 0, 0);
END_CS; */ 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_PKT3(R300_PACKET3_3D_DRAW_INDX_2, (count+1)/2);
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) | OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) |
r300render->hwprim); r300render->hwprim);

View File

@ -429,6 +429,9 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state)
r300->rs_state = rs; r300->rs_state = rs;
r300->dirty_state |= R300_NEW_RASTERIZER; 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. */ /* Free rasterizer state. */

View File

@ -38,7 +38,9 @@ void r300_emit_invariant_state(struct r300_context* r300)
/*** Graphics Backend (GB) ***/ /*** Graphics Backend (GB) ***/
/* Various GB enables */ /* 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 /* Subpixel multisampling for AA
* These are commented out because glisse's CS checker doesn't like them. * These are commented out because glisse's CS checker doesn't like them.
* I presume these will be re-enabled later. * I presume these will be re-enabled later.

View File

@ -73,9 +73,9 @@ static struct r300_rs_state rs_clear_state = {
}; };
static struct r300_rs_block r3xx_rs_block_clear_state = { static struct r300_rs_block r3xx_rs_block_clear_state = {
.ip[0] = R500_RS_SEL_S(R300_RS_SEL_K0) | .ip[0] = R500_RS_SEL_S(R300_RS_SEL_C0) |
R500_RS_SEL_T(R300_RS_SEL_K0) | R500_RS_SEL_T(R300_RS_SEL_C0) |
R500_RS_SEL_R(R300_RS_SEL_K0) | R500_RS_SEL_R(R300_RS_SEL_C0) |
R500_RS_SEL_Q(R300_RS_SEL_K1), R500_RS_SEL_Q(R300_RS_SEL_K1),
.inst[0] = R300_RS_INST_COL_CN_WRITE, .inst[0] = R300_RS_INST_COL_CN_WRITE,
.count = R300_IT_COUNT(0) | R300_IC_COUNT(1) | R300_HIRES_EN, .count = R300_IT_COUNT(0) | R300_IC_COUNT(1) | R300_HIRES_EN,

View File

@ -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_sampler_textures = trace_context_set_sampler_textures;
tr_ctx->base.set_vertex_buffers = trace_context_set_vertex_buffers; 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.set_vertex_elements = trace_context_set_vertex_elements;
tr_ctx->base.surface_copy = trace_context_surface_copy; if (pipe->surface_copy)
tr_ctx->base.surface_fill = trace_context_surface_fill; 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.clear = trace_context_clear;
tr_ctx->base.flush = trace_context_flush; tr_ctx->base.flush = trace_context_flush;
tr_ctx->base.is_texture_referenced = trace_is_texture_referenced; tr_ctx->base.is_texture_referenced = trace_is_texture_referenced;

View File

@ -184,7 +184,7 @@ union tgsi_immediate_data
#define TGSI_OPCODE_SUB 17 #define TGSI_OPCODE_SUB 17
#define TGSI_OPCODE_LRP 18 #define TGSI_OPCODE_LRP 18
#define TGSI_OPCODE_CND 19 #define TGSI_OPCODE_CND 19
#define TGSI_OPCODE_CND0 20 /* gap */
#define TGSI_OPCODE_DP2A 21 #define TGSI_OPCODE_DP2A 21
/* gap */ /* gap */
#define TGSI_OPCODE_FRC 24 #define TGSI_OPCODE_FRC 24

View File

@ -189,12 +189,10 @@ dri_get_buffers(__DRIdrawablePrivate * dPriv)
format = drawable->color_format; format = drawable->color_format;
break; break;
case __DRI_BUFFER_DEPTH: case __DRI_BUFFER_DEPTH:
index = ST_SURFACE_DEPTH; case __DRI_BUFFER_DEPTH_STENCIL:
format = drawable->depth_format;
break;
case __DRI_BUFFER_STENCIL: case __DRI_BUFFER_STENCIL:
index = ST_SURFACE_DEPTH; index = ST_SURFACE_DEPTH;
format = drawable->stencil_format; format = drawable->depth_stencil_format;
break; break;
case __DRI_BUFFER_ACCUM: case __DRI_BUFFER_ACCUM:
default: default:
@ -215,6 +213,18 @@ dri_get_buffers(__DRIdrawablePrivate * dPriv)
dri_drawable->w, dri_drawable->w,
dri_drawable->h, buffers[i].pitch); 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); st_set_framebuffer_surface(drawable->stfb, index, surface);
pipe_surface_reference(&surface, NULL); 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_get_framebuffer_surface(drawable->stfb, ST_SURFACE_FRONT_LEFT, &ps);
st_bind_texture_surface(ps, target == GL_TEXTURE_2D ? ST_TEXTURE_2D : st_bind_texture_surface(ps, target == GL_TEXTURE_2D ? ST_TEXTURE_2D :
ST_TEXTURE_RECT, 0, ST_TEXTURE_RECT, 0, drawable->color_format);
format == GLX_TEXTURE_FORMAT_RGBA_EXT ?
PIPE_FORMAT_R8G8B8A8_UNORM : PIPE_FORMAT_R8G8B8X8_UNORM);
} }
void dri2_set_tex_buffer(__DRIcontext *pDRICtx, GLint target, void dri2_set_tex_buffer(__DRIcontext *pDRICtx, GLint target,
@ -311,43 +319,31 @@ dri_create_buffer(__DRIscreenPrivate * sPriv,
switch(visual->depthBits) { switch(visual->depthBits) {
default: default:
case 0: case 0:
drawable->depth_format = PIPE_FORMAT_NONE; drawable->depth_stencil_format = PIPE_FORMAT_NONE;
break; break;
case 16: case 16:
drawable->depth_format = PIPE_FORMAT_Z16_UNORM; drawable->depth_stencil_format = PIPE_FORMAT_Z16_UNORM;
break; break;
case 24: case 24:
if (visual->stencilBits == 0) { 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_X8Z24_UNORM:
PIPE_FORMAT_Z24X8_UNORM; PIPE_FORMAT_Z24X8_UNORM;
} else { } else {
drawable->depth_format = (screen->sd_depth_bits_last) ? drawable->depth_stencil_format = (screen->sd_depth_bits_last) ?
PIPE_FORMAT_S8Z24_UNORM: PIPE_FORMAT_S8Z24_UNORM:
PIPE_FORMAT_Z24S8_UNORM; PIPE_FORMAT_Z24S8_UNORM;
} }
break; break;
case 32: case 32:
drawable->depth_format = PIPE_FORMAT_Z32_UNORM; drawable->depth_stencil_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;
break; break;
} }
drawable->stfb = st_create_framebuffer(visual, drawable->stfb = st_create_framebuffer(visual,
drawable->color_format, drawable->color_format,
drawable->depth_format, drawable->depth_stencil_format,
drawable->stencil_format, drawable->depth_stencil_format,
dPriv->w, dPriv->w,
dPriv->h, (void *)drawable); dPriv->h, (void *)drawable);
if (drawable->stfb == NULL) if (drawable->stfb == NULL)
@ -366,9 +362,11 @@ dri_create_buffer(__DRIscreenPrivate * sPriv,
drawable->attachments[i++] = __DRI_BUFFER_BACK_LEFT; drawable->attachments[i++] = __DRI_BUFFER_BACK_LEFT;
else else
drawable->attachments[i++] = __DRI_BUFFER_FAKE_FRONT_LEFT; 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; drawable->attachments[i++] = __DRI_BUFFER_DEPTH;
if (visual->stencilBits) else if (visual->stencilBits)
drawable->attachments[i++] = __DRI_BUFFER_STENCIL; drawable->attachments[i++] = __DRI_BUFFER_STENCIL;
drawable->num_attachments = i; drawable->num_attachments = i;

View File

@ -63,8 +63,7 @@ struct dri_drawable
unsigned int cur_fences; unsigned int cur_fences;
enum pipe_format color_format; enum pipe_format color_format;
enum pipe_format depth_format; enum pipe_format depth_stencil_format;
enum pipe_format stencil_format;
}; };
static INLINE struct dri_drawable * static INLINE struct dri_drawable *

View File

@ -286,6 +286,18 @@ choose_pixel_format(XMesaVisual v)
return PIPE_FORMAT_B8G8R8A8_UNORM; 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 else if ( GET_REDMASK(v) == 0xf800
&& GET_GREENMASK(v) == 0x07e0 && GET_GREENMASK(v) == 0x07e0
&& GET_BLUEMASK(v) == 0x001f && GET_BLUEMASK(v) == 0x001f
@ -656,7 +668,7 @@ XMesaVisual XMesaCreateVisual( Display *display,
* at a later time. * at a later time.
*/ */
v->visinfo = (XVisualInfo *) MALLOC(sizeof(*visinfo)); v->visinfo = (XVisualInfo *) MALLOC(sizeof(*visinfo));
if(!v->visinfo) { if (!v->visinfo) {
_mesa_free(v); _mesa_free(v);
return NULL; return NULL;
} }
@ -743,7 +755,7 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
{ {
static GLboolean firstTime = GL_TRUE; static GLboolean firstTime = GL_TRUE;
static struct pipe_screen *screen = NULL; static struct pipe_screen *screen = NULL;
struct pipe_context *pipe; struct pipe_context *pipe = NULL;
XMesaContext c; XMesaContext c;
GLcontext *mesaCtx; GLcontext *mesaCtx;
uint pf; uint pf;
@ -769,8 +781,7 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
if (screen == NULL) if (screen == NULL)
goto fail; goto fail;
pipe = driver.create_pipe_context( screen, pipe = driver.create_pipe_context(screen, (void *) c);
(void *)c );
if (pipe == NULL) if (pipe == NULL)
goto fail; goto fail;
@ -783,23 +794,15 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
mesaCtx = c->st->ctx; mesaCtx = c->st->ctx;
c->st->ctx->DriverCtx = c; 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; return c;
fail: fail:
if (c->st) if (c->st)
st_destroy_context(c->st); st_destroy_context(c->st);
else if (pipe) else if (pipe)
pipe->destroy(pipe); pipe->destroy(pipe);
FREE(c); _mesa_free(c);
return NULL; return NULL;
} }
@ -1153,7 +1156,7 @@ void XMesaFlush( XMesaContext c )
XMesaBuffer XMesaFindBuffer( Display *dpy, Drawable d ) XMesaBuffer XMesaFindBuffer( Display *dpy, Drawable d )
{ {
XMesaBuffer b; 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) { if (b->drawable == d && b->xm_visual->display == dpy) {
return b; return b;
} }

View File

@ -2,9 +2,10 @@
#include "xorg_exa_tgsi.h" #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 { struct xorg_composite_blend {
int op:8; 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 }, 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 { struct acceleration_info {
int op : 16; int op : 16;
int with_mask : 1; int with_mask : 1;
@ -75,19 +94,168 @@ blend_for_op(int op)
return xorg_blends[BLEND_OP_OVER]; return xorg_blends[BLEND_OP_OVER];
} }
static void static INLINE int
draw_texture(struct exa_context *exa) render_repeat_to_gallium(int mode)
{ {
#if 0 switch(mode) {
if (buf) { case RepeatNone:
util_draw_vertex_buffer(pipe, buf, 0, return PIPE_TEX_WRAP_CLAMP;
PIPE_PRIM_TRIANGLE_FAN, case RepeatNormal:
4, /* verts */ return PIPE_TEX_WRAP_REPEAT;
2); /* attribs/vert */ case RepeatReflect:
return PIPE_TEX_WRAP_MIRROR_REPEAT;
pipe_buffer_reference(&buf, NULL); 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, boolean xorg_composite_accelerated(int op,
@ -172,27 +340,10 @@ set_viewport(struct exa_context *exa, int width, int height,
static void static void
bind_viewport_state(struct exa_context *exa, PicturePtr pDstPicture) bind_viewport_state(struct exa_context *exa, PicturePtr pDstPicture)
{ {
const int param_bytes = 8 * sizeof(float);
int width = pDstPicture->pDrawable->width; int width = pDstPicture->pDrawable->width;
int height = pDstPicture->pDrawable->height; 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); set_viewport(exa, width, height, Y0_TOP);
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 static void
@ -240,8 +391,20 @@ bind_shaders(struct exa_context *exa, int op,
struct xorg_shader shader; struct xorg_shader shader;
if (pSrcPicture) { if (pSrcPicture) {
vs_traits |= VS_COMPOSITE; if (pSrcPicture->pSourcePict) {
fs_traits |= FS_COMPOSITE; 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) { if (pMaskPicture) {
@ -264,35 +427,98 @@ bind_samplers(struct exa_context *exa, int op,
struct exa_pixmap_priv *pDst) struct exa_pixmap_priv *pDst)
{ {
struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS]; struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
struct pipe_texture *textures[PIPE_MAX_SAMPLERS];
struct pipe_sampler_state src_sampler, mask_sampler; struct pipe_sampler_state src_sampler, mask_sampler;
exa->num_bound_samplers = 0;
memset(&src_sampler, 0, sizeof(struct pipe_sampler_state)); memset(&src_sampler, 0, sizeof(struct pipe_sampler_state));
memset(&mask_sampler, 0, sizeof(struct pipe_sampler_state)); memset(&mask_sampler, 0, sizeof(struct pipe_sampler_state));
if (pSrcPicture && pSrc) { if (pSrcPicture && pSrc) {
src_sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; unsigned src_wrap = render_repeat_to_gallium(
src_sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 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.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST;
src_sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST; src_sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST;
src_sampler.normalized_coords = 1; src_sampler.normalized_coords = 1;
samplers[0] = &src_sampler; samplers[0] = &src_sampler;
textures[0] = pSrc->tex; exa->bound_textures[0] = pSrc->tex;
++exa->num_bound_samplers;
} }
if (pMaskPicture && pMask) { if (pMaskPicture && pMask) {
mask_sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; unsigned mask_wrap = render_repeat_to_gallium(
mask_sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 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.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST;
mask_sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST; mask_sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST;
mask_sampler.normalized_coords = 1; mask_sampler.normalized_coords = 1;
samplers[1] = &mask_sampler; 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); (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, 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_blend_state(exa, op, pSrcPicture, pMaskPicture);
bind_rasterizer_state(exa); bind_rasterizer_state(exa);
bind_shaders(exa, op, pSrcPicture, pMaskPicture); bind_shaders(exa, op, pSrcPicture, pMaskPicture);
bind_samplers(exa, op, pSrcPicture, pMaskPicture, pDstPicture, bind_samplers(exa, op, pSrcPicture, pMaskPicture,
pSrc, pMask, pDst); pDstPicture, pSrc, pMask, pDst);
setup_constant_buffers(exa, pDstPicture);
return FALSE; return FALSE;
} }
@ -320,5 +548,37 @@ void xorg_composite(struct exa_context *exa,
int srcX, int srcY, int maskX, int maskY, int srcX, int srcY, int maskX, int maskY,
int dstX, int dstY, int width, int height) 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);
}
} }

View File

@ -33,6 +33,7 @@
#include "xf86_OSproc.h" #include "xf86_OSproc.h"
#include "xorg_tracker.h" #include "xorg_tracker.h"
#include "xorg_exa.h"
#include "dri2.h" #include "dri2.h"
@ -47,19 +48,156 @@ typedef struct {
struct pipe_fence_handle *fence; struct pipe_fence_handle *fence;
} *BufferPrivatePtr; } *BufferPrivatePtr;
static DRI2BufferPtr static Bool
driCreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count) driDoCreateBuffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int format)
{ {
struct pipe_texture *depth, *tex; struct pipe_texture *tex = NULL;
struct pipe_buffer *buf;
ScreenPtr pScreen = pDraw->pScreen; ScreenPtr pScreen = pDraw->pScreen;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
modesettingPtr ms = modesettingPTR(pScrn); modesettingPtr ms = modesettingPTR(pScrn);
BufferPrivatePtr privates; struct exa_pixmap_priv *exa_priv;
DRI2BufferPtr buffers; BufferPrivatePtr private = buffer->driverPrivate;
PixmapPtr pPixmap; PixmapPtr pPixmap;
unsigned stride, handle; 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; int i;
buffers = xcalloc(count, sizeof *buffers); buffers = xcalloc(count, sizeof *buffers);
@ -71,81 +209,17 @@ driCreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count)
goto fail_privates; goto fail_privates;
for (i = 0; i < count; i++) { 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].attachment = attachments[i];
buffers[i].pitch = stride;
buffers[i].cpp = 4;
buffers[i].driverPrivate = &privates[i]; buffers[i].driverPrivate = &privates[i];
buffers[i].flags = 0; /* not tiled */
privates[i].pPixmap = pPixmap; if (!driDoCreateBuffer(pDraw, &buffers[i], 0))
privates[i].tex = tex; goto fail;
} }
return buffers; return buffers;
fail:
xfree(privates);
fail_privates: fail_privates:
xfree(buffers); xfree(buffers);
fail_buffers: fail_buffers:
@ -155,21 +229,10 @@ fail_buffers:
static void static void
driDestroyBuffers(DrawablePtr pDraw, DRI2BufferPtr buffers, int count) driDestroyBuffers(DrawablePtr pDraw, DRI2BufferPtr buffers, int count)
{ {
ScreenPtr pScreen = pDraw->pScreen;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
modesettingPtr ms = modesettingPTR(pScrn);
BufferPrivatePtr private;
int i; int i;
(void)ms;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
private = buffers[i].driverPrivate; driDoDestroyBuffer(pDraw, &buffers[i]);
pipe_texture_reference(&private->tex, NULL);
ms->screen->fence_reference(ms->screen, &private->fence, NULL);
if (private->pPixmap)
(*pScreen->DestroyPixmap)(private->pPixmap);
} }
if (buffers) { if (buffers) {
@ -178,6 +241,8 @@ driDestroyBuffers(DrawablePtr pDraw, DRI2BufferPtr buffers, int count)
} }
} }
#endif /* DRI2INFOREC_VERSION */
static void static void
driCopyRegion(DrawablePtr pDraw, RegionPtr pRegion, driCopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
DRI2BufferPtr pDestBuffer, DRI2BufferPtr pSrcBuffer) DRI2BufferPtr pDestBuffer, DRI2BufferPtr pSrcBuffer)
@ -273,15 +338,25 @@ driScreenInit(ScreenPtr pScreen)
modesettingPtr ms = modesettingPTR(pScrn); modesettingPtr ms = modesettingPTR(pScrn);
DRI2InfoRec dri2info; DRI2InfoRec dri2info;
#if defined(DRI2INFOREC_VERSION)
dri2info.version = DRI2INFOREC_VERSION;
#else
dri2info.version = 1; dri2info.version = 1;
#endif
dri2info.fd = ms->fd; dri2info.fd = ms->fd;
dri2info.driverName = pScrn->driverName; dri2info.driverName = pScrn->driverName;
dri2info.deviceName = "/dev/dri/card0"; /* FIXME */ dri2info.deviceName = "/dev/dri/card0"; /* FIXME */
#if defined(DRI2INFOREC_VERSION) && DRI2INFOREC_VERSION > 2
dri2info.CreateBuffer = driCreateBuffer;
dri2info.DestroyBuffer = driDestroyBuffer;
#else
dri2info.CreateBuffers = driCreateBuffers; dri2info.CreateBuffers = driCreateBuffers;
dri2info.DestroyBuffers = driDestroyBuffers; dri2info.DestroyBuffers = driDestroyBuffers;
#endif
dri2info.CopyRegion = driCopyRegion; dri2info.CopyRegion = driCopyRegion;
dri2info.Wait = NULL;
ms->d_depth_bits_last = ms->d_depth_bits_last =
ms->screen->is_format_supported(ms->screen, PIPE_FORMAT_X8Z24_UNORM, ms->screen->is_format_supported(ms->screen, PIPE_FORMAT_X8Z24_UNORM,

View File

@ -33,10 +33,8 @@
#include "xf86.h" #include "xf86.h"
#include "xf86_OSproc.h" #include "xf86_OSproc.h"
#include "compiler.h" #include "compiler.h"
#include "xf86RAC.h"
#include "xf86PciInfo.h" #include "xf86PciInfo.h"
#include "xf86Pci.h" #include "xf86Pci.h"
#include "xf86Resources.h"
#include "mipointer.h" #include "mipointer.h"
#include "micmap.h" #include "micmap.h"
#include <X11/extensions/randr.h> #include <X11/extensions/randr.h>
@ -84,42 +82,10 @@ static const OptionInfoRec Options[] = {
{-1, NULL, OPTV_NONE, {0}, FALSE} {-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 * Exported Xorg driver functions to winsys
*/ */
void
xorg_tracker_loader_ref_sym_lists()
{
LoaderRefSymLists(exaSymbols, fbSymbols, ddcSymbols, NULL);
}
const OptionInfoRec * const OptionInfoRec *
xorg_tracker_available_options(int chipid, int busid) xorg_tracker_available_options(int chipid, int busid)
{ {
@ -288,10 +254,6 @@ PreInit(ScrnInfoPtr pScrn, int flags)
} else } else
ms->entityPrivate = NULL; ms->entityPrivate = NULL;
if (xf86RegisterResources(ms->pEnt->index, NULL, ResNone)) {
return FALSE;
}
if (xf86IsEntityShared(pScrn->entityList[0])) { if (xf86IsEntityShared(pScrn->entityList[0])) {
if (xf86IsPrimInitDone(pScrn->entityList[0])) { if (xf86IsPrimInitDone(pScrn->entityList[0])) {
/* do something */ /* do something */
@ -312,7 +274,6 @@ PreInit(ScrnInfoPtr pScrn, int flags)
if (ms->fd < 0) if (ms->fd < 0)
return FALSE; return FALSE;
pScrn->racMemFlags = RAC_FB | RAC_COLORMAP;
pScrn->monitor = pScrn->confScreen->monitor; pScrn->monitor = pScrn->confScreen->monitor;
pScrn->progClock = TRUE; pScrn->progClock = TRUE;
pScrn->rgbBits = 8; pScrn->rgbBits = 8;
@ -398,8 +359,6 @@ PreInit(ScrnInfoPtr pScrn, int flags)
return FALSE; return FALSE;
} }
xf86LoaderReqSymLists(fbSymbols, NULL);
xf86LoadSubModule(pScrn, "exa"); xf86LoadSubModule(pScrn, "exa");
#ifdef DRI2 #ifdef DRI2

View File

@ -97,6 +97,68 @@ ExaMarkSync(ScreenPtr pScreen)
return 1; 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 static Bool
ExaPrepareAccess(PixmapPtr pPix, int index) 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_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
struct exa_context *exa = ms->exa; struct exa_context *exa = ms->exa;
if (1)
return FALSE;
if (pPixmap->drawable.depth < 15) if (pPixmap->drawable.depth < 15)
return FALSE; return FALSE;
@ -430,7 +489,7 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
modesettingPtr ms = modesettingPTR(pScrn); modesettingPtr ms = modesettingPTR(pScrn);
struct exa_context *exa = ms->exa; struct exa_context *exa = ms->exa;
if (!priv) if (!priv || pPixData)
return FALSE; return FALSE;
if (depth <= 0) if (depth <= 0)
@ -452,65 +511,69 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
bitsPerPixel, devKind, NULL); bitsPerPixel, devKind, NULL);
/* Deal with screen resize */ /* Deal with screen resize */
if (priv->tex && (priv->tex->width[0] != width || if (!priv->tex ||
priv->tex->height[0] != height || (priv->tex->width[0] != width ||
priv->tex_flags != priv->flags)) { priv->tex->height[0] != height ||
pipe_texture_reference(&priv->tex, NULL); priv->tex_flags != priv->flags)) {
} struct pipe_texture *texture = 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);
}
#ifdef DRM_MODE_FEATURE_DIRTYFB #ifdef DRM_MODE_FEATURE_DIRTYFB
if (!priv->tex) { if (priv->flags)
if (pPixData)
pPixmap->devPrivate.ptr = pPixData;
else
pPixmap->devPrivate.ptr = xalloc(pPixmap->drawable.height * pPixmap->devKind);
} else
#endif #endif
if (pPixData) { {
struct pipe_transfer *transfer = struct pipe_texture template;
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;
if (priv->map_count != 0) memset(&template, 0, sizeof(template));
FatalError("doing ExaModifyPixmapHeader on mapped buffer\n"); 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 = if (priv->tex) {
exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0, struct pipe_surface *dst_surf;
PIPE_TRANSFER_WRITE,
0, 0, width, height); dst_surf = exa->scrn->get_tex_surface(exa->scrn, texture, 0, 0, 0,
util_copy_rect(exa->scrn->transfer_map(exa->scrn, transfer), PIPE_BUFFER_USAGE_GPU_WRITE);
&priv->tex->block, transfer->stride, 0, 0, priv->src_surf = exa_gpu_surface(exa, priv);
width, height, pPixmap->devPrivate.ptr, pPixmap->devKind, 0, 0); exa->ctx->surface_copy(exa->ctx, dst_surf, 0, 0, priv->src_surf,
exa->scrn->transfer_unmap(exa->scrn, transfer); 0, 0, min(width, texture->width[0]),
exa->scrn->tex_transfer_destroy(transfer); 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; return TRUE;
@ -598,6 +661,8 @@ xorg_exa_init(ScrnInfoPtr pScrn)
pExa->Composite = ExaComposite; pExa->Composite = ExaComposite;
pExa->DoneComposite = ExaDoneComposite; pExa->DoneComposite = ExaDoneComposite;
pExa->PixmapIsOffscreen = ExaPixmapIsOffscreen; pExa->PixmapIsOffscreen = ExaPixmapIsOffscreen;
pExa->DownloadFromScreen = ExaDownloadFromScreen;
pExa->UploadToScreen = ExaUploadToScreen;
pExa->PrepareAccess = ExaPrepareAccess; pExa->PrepareAccess = ExaPrepareAccess;
pExa->FinishAccess = ExaFinishAccess; pExa->FinishAccess = ExaFinishAccess;
pExa->CreatePixmap = ExaCreatePixmap; pExa->CreatePixmap = ExaCreatePixmap;

View File

@ -8,6 +8,9 @@
struct cso_context; struct cso_context;
struct xorg_shaders; struct xorg_shaders;
/* src + mask + dst */
#define MAX_EXA_SAMPLERS 3
struct exa_context struct exa_context
{ {
ExaDriverPtr pExa; ExaDriverPtr pExa;
@ -18,6 +21,11 @@ struct exa_context
struct pipe_constant_buffer vs_const_buffer; struct pipe_constant_buffer vs_const_buffer;
struct pipe_constant_buffer fs_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; int tex_flags;
struct pipe_texture *tex; struct pipe_texture *tex;
struct pipe_texture *depth_stencil_tex;
unsigned int color; unsigned int color;
struct pipe_surface *src_surf; /* for copies */ struct pipe_surface *src_surf; /* for copies */

View File

@ -18,22 +18,24 @@
#include "cso_cache/cso_hash.h" #include "cso_cache/cso_hash.h"
/* Vertex shader: /* Vertex shader:
* IN[0] = src_pos * IN[0] = vertex pos
* IN[1] = mask_pos * IN[1] = src tex coord | solid fill color
* IN[2] = dst_pos * IN[2] = mask tex coord
* IN[3] = dst tex coord
* CONST[0] = (2/dst_width, 2/dst_height, 1, 1) * CONST[0] = (2/dst_width, 2/dst_height, 1, 1)
* CONST[1] = (-1, -1, 0, 0) * CONST[1] = (-1, -1, 0, 0)
* *
* OUT[0] = src_pos * OUT[0] = vertex pos
* OUT[1] = mask_pos * OUT[1] = src tex coord | solid fill color
* OUT[2] = dst_pos * OUT[2] = mask tex coord
* OUT[3] = dst tex coord
*/ */
/* Fragment shader: /* Fragment shader:
* SAMP[0] = src * SAMP[0] = src
* SAMP[1] = mask * SAMP[1] = mask
* SAMP[2] = dst * SAMP[2] = dst
* IN[0] = pos src * IN[0] = pos src | solid fill color
* IN[1] = pos mask * IN[1] = pos mask
* IN[2] = pos dst * IN[2] = pos dst
* CONST[0] = (0, 0, 0, 1) * CONST[0] = (0, 0, 0, 1)
@ -84,6 +86,150 @@ vs_normalize_coords(struct ureg_program *ureg, struct ureg_src coords,
return ret; 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 * static void *
create_vs(struct pipe_context *pipe, create_vs(struct pipe_context *pipe,
unsigned vs_traits) unsigned vs_traits)
@ -92,6 +238,9 @@ create_vs(struct pipe_context *pipe,
struct ureg_src src; struct ureg_src src;
struct ureg_dst dst; struct ureg_dst dst;
struct ureg_src const0, const1; 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); ureg = ureg_create(TGSI_PROCESSOR_VERTEX);
if (ureg == NULL) if (ureg == NULL)
@ -100,18 +249,34 @@ create_vs(struct pipe_context *pipe,
const0 = ureg_DECL_constant(ureg); const0 = ureg_DECL_constant(ureg);
const1 = 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, src = ureg_DECL_vs_input(ureg,
TGSI_SEMANTIC_POSITION, 0); TGSI_SEMANTIC_GENERIC, 1);
dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0); dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 1);
src = vs_normalize_coords(ureg, src,
const0, const1);
ureg_MOV(ureg, dst, src); ureg_MOV(ureg, dst, src);
} }
if ((vs_traits & VS_MASK)) { if (is_fill) {
src = ureg_DECL_vs_input(ureg, src = ureg_DECL_vs_input(ureg,
TGSI_SEMANTIC_POSITION, 1); TGSI_SEMANTIC_COLOR, 1);
dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 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); ureg_MOV(ureg, dst, src);
} }
@ -125,27 +290,50 @@ create_fs(struct pipe_context *pipe,
unsigned fs_traits) unsigned fs_traits)
{ {
struct ureg_program *ureg; struct ureg_program *ureg;
struct ureg_src dst_sampler, src_sampler, mask_sampler; struct ureg_src /*dst_sampler,*/ src_sampler, mask_sampler;
struct ureg_src dst_pos, src_pos, mask_pos; struct ureg_src /*dst_pos,*/ src_input, mask_pos;
struct ureg_src src, mask; struct ureg_dst src, mask;
struct ureg_dst out; 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); ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT);
if (ureg == NULL) if (ureg == NULL)
return 0; return 0;
/* it has to be either a fill or a composite op */
debug_assert(is_fill ^ is_composite);
out = ureg_DECL_output(ureg, out = ureg_DECL_output(ureg,
TGSI_SEMANTIC_COLOR, TGSI_SEMANTIC_COLOR,
0); 0);
src_sampler = ureg_DECL_sampler(ureg); if (is_composite) {
src_pos = ureg_DECL_fs_input(ureg, src_sampler = ureg_DECL_sampler(ureg, 0);
TGSI_SEMANTIC_POSITION, src_input = ureg_DECL_fs_input(ureg,
0, TGSI_SEMANTIC_POSITION,
TGSI_INTERPOLATE_PERSPECTIVE); 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)) { if (has_mask) {
mask_sampler = ureg_DECL_sampler(ureg); mask_sampler = ureg_DECL_sampler(ureg, 1);
mask_pos = ureg_DECL_fs_input(ureg, mask_pos = ureg_DECL_fs_input(ureg,
TGSI_SEMANTIC_POSITION, TGSI_SEMANTIC_POSITION,
1, 1,
@ -153,21 +341,63 @@ create_fs(struct pipe_context *pipe,
} }
#if 0 /* unused right now */ #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, dst_pos = ureg_DECL_fs_input(ureg,
TGSI_SEMANTIC_POSITION, TGSI_SEMANTIC_POSITION,
2, 2,
TGSI_INTERPOLATE_PERSPECTIVE); TGSI_INTERPOLATE_PERSPECTIVE);
#endif #endif
if ((fs_traits & FS_MASK)) { if (is_composite) {
ureg_TEX(ureg, ureg_dst(mask), 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); TGSI_TEXTURE_2D, mask_pos, mask_sampler);
/* src IN mask */ /* src IN mask */
src_in_mask(ureg, out, src, mask); src_in_mask(ureg, out, ureg_src(src), ureg_src(mask));
} else { ureg_release_temporary(ureg, mask);
ureg_TEX(ureg, out,
TGSI_TEXTURE_2D, src_pos, src_sampler);
} }
ureg_END(ureg); ureg_END(ureg);

View File

@ -6,16 +6,24 @@
enum xorg_vs_traits { enum xorg_vs_traits {
VS_COMPOSITE = 1 << 0, VS_COMPOSITE = 1 << 0,
VS_MASK = 1 << 1, VS_MASK = 1 << 1,
VS_FILL = 1 << 2 VS_SOLID_FILL = 1 << 2,
/*VS_TRANSFORM = 1 << 3*/ 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 { enum xorg_fs_traits {
FS_COMPOSITE = 1 << 0, FS_COMPOSITE = 1 << 0,
FS_MASK = 1 << 1, FS_MASK = 1 << 1,
FS_FILL = 1 << 2, FS_SOLID_FILL = 1 << 2,
FS_LINEAR_GRADIENT = 1 << 3, FS_LINGRAD_FILL = 1 << 3,
FS_RADIAL_GRADIENT = 1 << 4 FS_RADGRAD_FILL = 1 << 4,
FS_FILL = (FS_SOLID_FILL |
FS_LINGRAD_FILL |
FS_RADGRAD_FILL)
}; };
struct xorg_shader { struct xorg_shader {

View File

@ -37,7 +37,6 @@
#include "xorg-server.h" #include "xorg-server.h"
#include "xf86.h" #include "xf86.h"
#include "xf86Resources.h"
#include "pciaccess.h" #include "pciaccess.h"
#ifndef XSERVER_LIBPCIACCESS #ifndef XSERVER_LIBPCIACCESS
@ -46,6 +45,5 @@
void xorg_tracker_set_functions(ScrnInfoPtr scrn); void xorg_tracker_set_functions(ScrnInfoPtr scrn);
const OptionInfoRec * xorg_tracker_available_options(int chipid, int busid); const OptionInfoRec * xorg_tracker_available_options(int chipid, int busid);
void xorg_tracker_loader_ref_sym_lists(void);
#endif #endif

View File

@ -4,10 +4,10 @@ include $(TOP)/configs/current
LIBNAME = inteldrm LIBNAME = inteldrm
C_SOURCES = \ C_SOURCES = \
intel_be_batchbuffer.c \ intel_drm_batchbuffer.c \
intel_be_context.c \ intel_drm_buffer.c \
intel_be_device.c \ intel_drm_fence.c \
intel_be_api.c intel_drm_api.c
LIBRARY_INCLUDES = $(shell pkg-config libdrm --cflags-only-I) LIBRARY_INCLUDES = $(shell pkg-config libdrm --cflags-only-I)

View File

@ -3,10 +3,10 @@ Import('*')
env = drienv.Clone() env = drienv.Clone()
inteldrm_sources = [ inteldrm_sources = [
'intel_be_api.c', 'intel_drm_api.c',
'intel_be_batchbuffer.c', 'intel_drm_batchbuffer.c',
'intel_be_context.c', 'intel_drm_buffer.c',
'intel_be_device.c', 'intel_drm_fence.c',
] ]
inteldrm = env.ConvenienceLibrary( inteldrm = env.ConvenienceLibrary(

View File

@ -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
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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