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$GCC" = xyes; then
CFLAGS="$CFLAGS -m32"
ARCH_FLAGS="$ARCH_FLAGS -m32"
fi
if test "x$GXX" = xyes; then
CXXFLAGS="$CXXFLAGS -m32"

View File

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

View File

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

View File

@ -11,6 +11,13 @@
<H1>News</H1>
<h2>September 3, 2009</h2>
<p>
<a href="relnotes-7.5.1.html">Mesa 7.5.1</a> is released.
This is a bug-fix release which fixes bugs found in version 7.5.
</p>
<h2>July 17, 2009</h2>
<p>
<a href="relnotes-7.5.html">Mesa 7.5</a> is released.

View File

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

View File

@ -8,7 +8,7 @@
<body bgcolor="#eeeeee">
<H1>Mesa 7.5.1 Release Notes / (date TBD)</H1>
<H1>Mesa 7.5.1 Release Notes, 3 September 2009</H1>
<p>
Mesa 7.5.1 is a bug-fix release fixing issues found since the 7.5 release.
@ -31,7 +31,15 @@ for DRI hardware acceleration.
<h2>MD5 checksums</h2>
<pre>
tbd
d7269e93bc7484430637d54ced250876 MesaLib-7.5.1.tar.gz
877d6a4b24efc2b1d02aa553f262cba8 MesaLib-7.5.1.tar.bz2
23f4fb757a05c8396425681234ae20e5 MesaLib-7.5.1.zip
5af4bd113652108f5cec5113dad813f2 MesaDemos-7.5.1.tar.gz
785402e3b9f0e335538fcc6bf19f6987 MesaDemos-7.5.1.tar.bz2
950058cc6d6106e9c7d5876a03789fe9 MesaDemos-7.5.1.zip
cb52ce2c93389c2711cbe8d857ec5303 MesaGLUT-7.5.1.tar.gz
e3a9892e056d625c5353617a7c5b7e9c MesaGLUT-7.5.1.tar.bz2
da1de364df148c94b4994006191a1e69 MesaGLUT-7.5.1.zip
</pre>
@ -54,12 +62,11 @@ tbd
<li>Fixed Gallium glBitmap() Z position bug
<li>Setting arrays of sampler uniforms did not work
<li>Selection/Feedback mode didn't handle polygon culling correctly (bug 16866)
<li>Fixed 32/64-bit cross compilation issue in gen_matypes.c
<li>Fixed glXCreateGLXPixmap() for direct rendering.
<li>Fixed Gallium glCopyPixels(GL_STENCIL_INDEX) mispositioned image bug.
</ul>
<h2>Changes</h2>
<ul>
</ul>
</body>
</html>

View File

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

View File

@ -92,6 +92,12 @@ static void Init(void)
numObjects = 10;
InitObjects(numObjects);
glGetIntegerv(GL_VIEWPORT, vp);
#if 0 /* debug - test culling */
glCullFace(GL_BACK);
glFrontFace(GL_CW);
glEnable(GL_CULL_FACE);
#endif
}
static void Reshape(int width, int height)

View File

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

View File

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

View File

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

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
dst.x = (src2.x >= 0.0) ? src0.x : src1.x
dst.y = (src2.y >= 0.0) ? src0.y : src1.y
dst.z = (src2.z >= 0.0) ? src0.z : src1.z
dst.w = (src2.w >= 0.0) ? src0.w : src1.w
Removed. Use (CMP src2, src1, src0) instead.
1.2.7 DOT2ADD - 2-component Dot Product And Add
@ -1031,12 +1027,12 @@ TGSI Instruction Specification
1.18.1 EXPP - Approximate Exponential Base 2
Alias for EXP.
Use EXP. See also 1.19.3.
1.18.2 LOGP - Logarithm Base 2
Alias for LG2.
Use LOG. See also 1.19.4.
1.19 vs_2_0
@ -1053,6 +1049,16 @@ TGSI Instruction Specification
Alias for ARR.
1.19.3 EXPP - Approximate Exponential Base 2
Use EX2.
1.19.4 LOGP - Logarithm Base 2
Use LG2.
2 Explanation of symbols used
==============================

View File

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

View File

@ -2329,16 +2329,6 @@ exec_instruction(
}
break;
case TGSI_OPCODE_CND0:
FOR_EACH_ENABLED_CHANNEL(*inst, chan_index) {
FETCH(&r[0], 0, chan_index);
FETCH(&r[1], 1, chan_index);
FETCH(&r[2], 2, chan_index);
micro_le(&r[0], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &r[2], &r[0], &r[1]);
STORE(&r[0], 0, chan_index);
}
break;
case TGSI_OPCODE_DP2A:
FETCH( &r[0], 0, CHAN_X );
FETCH( &r[1], 1, CHAN_X );
@ -3104,6 +3094,12 @@ exec_instruction(
break;
case TGSI_OPCODE_BGNFOR:
assert(mach->LoopCounterStackTop < TGSI_EXEC_MAX_LOOP_NESTING);
for (chan_index = 0; chan_index < 3; chan_index++) {
FETCH( &mach->LoopCounterStack[mach->LoopCounterStackTop].xyzw[chan_index], 0, chan_index );
}
STORE( &mach->LoopCounterStack[mach->LoopCounterStackTop].xyzw[CHAN_Y], 0, CHAN_X );
++mach->LoopCounterStackTop;
/* fall-through (for now) */
case TGSI_OPCODE_BGNLOOP:
/* push LoopMask and ContMasks */
@ -3111,18 +3107,42 @@ exec_instruction(
mach->LoopStack[mach->LoopStackTop++] = mach->LoopMask;
assert(mach->ContStackTop < TGSI_EXEC_MAX_LOOP_NESTING);
mach->ContStack[mach->ContStackTop++] = mach->ContMask;
assert(mach->LoopLabelStackTop < TGSI_EXEC_MAX_LOOP_NESTING);
mach->LoopLabelStack[mach->LoopLabelStackTop++] = *pc - 1;
break;
case TGSI_OPCODE_ENDFOR:
/* fall-through (for now at least) */
case TGSI_OPCODE_ENDLOOP:
assert(mach->LoopCounterStackTop > 0);
micro_sub( &mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_X],
&mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_X],
&mach->Temps[TEMP_1_I].xyzw[TEMP_1_C] );
/* update LoopMask */
if( mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_X].f[0] <= 0) {
mach->LoopMask &= ~0x1;
}
if( mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_X].f[1] <= 0 ) {
mach->LoopMask &= ~0x2;
}
if( mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_X].f[2] <= 0 ) {
mach->LoopMask &= ~0x4;
}
if( mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_X].f[3] <= 0 ) {
mach->LoopMask &= ~0x8;
}
micro_add( &mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_Y],
&mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_Y],
&mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_Z]);
assert(mach->LoopLabelStackTop > 0);
inst = mach->Instructions + mach->LoopLabelStack[mach->LoopLabelStackTop - 1];
STORE( &mach->LoopCounterStack[mach->LoopCounterStackTop].xyzw[CHAN_Y], 0, CHAN_X );
/* Restore ContMask, but don't pop */
assert(mach->ContStackTop > 0);
mach->ContMask = mach->ContStack[mach->ContStackTop - 1];
UPDATE_EXEC_MASK(mach);
if (mach->ExecMask) {
/* repeat loop: jump to instruction just past BGNLOOP */
*pc = inst->InstructionExtLabel.Label + 1;
assert(mach->LoopLabelStackTop > 0);
*pc = mach->LoopLabelStack[mach->LoopLabelStackTop - 1] + 1;
}
else {
/* exit loop: pop LoopMask */
@ -3131,6 +3151,33 @@ exec_instruction(
/* pop ContMask */
assert(mach->ContStackTop > 0);
mach->ContMask = mach->ContStack[--mach->ContStackTop];
assert(mach->LoopLabelStackTop > 0);
--mach->LoopLabelStackTop;
assert(mach->LoopCounterStackTop > 0);
--mach->LoopCounterStackTop;
}
UPDATE_EXEC_MASK(mach);
break;
case TGSI_OPCODE_ENDLOOP:
/* Restore ContMask, but don't pop */
assert(mach->ContStackTop > 0);
mach->ContMask = mach->ContStack[mach->ContStackTop - 1];
UPDATE_EXEC_MASK(mach);
if (mach->ExecMask) {
/* repeat loop: jump to instruction just past BGNLOOP */
assert(mach->LoopLabelStackTop > 0);
*pc = mach->LoopLabelStack[mach->LoopLabelStackTop - 1] + 1;
}
else {
/* exit loop: pop LoopMask */
assert(mach->LoopStackTop > 0);
mach->LoopMask = mach->LoopStack[--mach->LoopStackTop];
/* pop ContMask */
assert(mach->ContStackTop > 0);
mach->ContMask = mach->ContStack[--mach->ContStackTop];
assert(mach->LoopLabelStackTop > 0);
--mach->LoopLabelStackTop;
}
UPDATE_EXEC_MASK(mach);
break;

View File

@ -232,6 +232,14 @@ struct tgsi_exec_machine
uint LoopStack[TGSI_EXEC_MAX_LOOP_NESTING];
int LoopStackTop;
/** Loop label stack */
uint LoopLabelStack[TGSI_EXEC_MAX_LOOP_NESTING];
int LoopLabelStackTop;
/** Loop counter stack (x = count, y = current, z = step) */
struct tgsi_exec_vector LoopCounterStack[TGSI_EXEC_MAX_LOOP_NESTING];
int LoopCounterStackTop;
/** Loop continue mask stack (see comments in tgsi_exec.c) */
uint ContStack[TGSI_EXEC_MAX_LOOP_NESTING];
int ContStackTop;

View File

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

View File

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

View File

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

View File

@ -199,10 +199,10 @@ iter_instruction(
}
if (info->num_dst != inst->Instruction.NumDstRegs) {
report_error( ctx, "Invalid number of destination operands, should be %u", info->num_dst );
report_error( ctx, "%s: Invalid number of destination operands, should be %u", info->mnemonic, info->num_dst );
}
if (info->num_src != inst->Instruction.NumSrcRegs) {
report_error( ctx, "Invalid number of source operands, should be %u", info->num_src );
report_error( ctx, "%s: Invalid number of source operands, should be %u", info->mnemonic, info->num_src );
}
/* Check destination and source registers' validity.

View File

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

View File

@ -29,6 +29,7 @@
#include "pipe/p_context.h"
#include "pipe/p_state.h"
#include "tgsi/tgsi_ureg.h"
#include "tgsi/tgsi_info.h"
#include "tgsi/tgsi_dump.h"
#include "util/u_memory.h"
#include "util/u_math.h"
@ -71,6 +72,7 @@ struct ureg_tokens {
#define UREG_MAX_OUTPUT PIPE_MAX_ATTRIBS
#define UREG_MAX_IMMEDIATE 32
#define UREG_MAX_TEMP 256
#define UREG_MAX_ADDR 2
#define DOMAIN_DECL 0
#define DOMAIN_INSN 1
@ -99,11 +101,15 @@ struct ureg_program
} immediate[UREG_MAX_IMMEDIATE];
unsigned nr_immediates;
struct ureg_src sampler[PIPE_MAX_SAMPLERS];
unsigned nr_samplers;
unsigned temps_active[UREG_MAX_TEMP / 32];
unsigned nr_temps;
unsigned nr_addrs;
unsigned nr_constants;
unsigned nr_samplers;
unsigned nr_instructions;
struct ureg_tokens domain[2];
@ -187,6 +193,8 @@ ureg_dst_register( unsigned file,
dst.File = file;
dst.WriteMask = TGSI_WRITEMASK_XYZW;
dst.Indirect = 0;
dst.IndirectIndex = 0;
dst.IndirectSwizzle = 0;
dst.Saturate = 0;
dst.Index = index;
dst.Pad1 = 0;
@ -208,6 +216,8 @@ ureg_src_register( unsigned file,
src.SwizzleW = TGSI_SWIZZLE_W;
src.Pad = 0;
src.Indirect = 0;
src.IndirectIndex = 0;
src.IndirectSwizzle = 0;
src.Absolute = 0;
src.Index = index;
src.Negate = 0;
@ -254,6 +264,7 @@ ureg_DECL_fs_input( struct ureg_program *ureg,
unsigned index,
unsigned interp )
{
assert(ureg->processor == TGSI_PROCESSOR_FRAGMENT);
return ureg_DECL_input( ureg, name, index, interp );
}
@ -263,6 +274,7 @@ ureg_DECL_vs_input( struct ureg_program *ureg,
unsigned name,
unsigned index )
{
assert(ureg->processor == TGSI_PROCESSOR_VERTEX);
return ureg_DECL_input( ureg, name, index, TGSI_INTERPOLATE_CONSTANT );
}
@ -346,11 +358,36 @@ void ureg_release_temporary( struct ureg_program *ureg,
}
/* Allocate a new address register.
*/
struct ureg_dst ureg_DECL_address( struct ureg_program *ureg )
{
if (ureg->nr_addrs < UREG_MAX_ADDR)
return ureg_dst_register( TGSI_FILE_ADDRESS, ureg->nr_addrs++ );
assert( 0 );
return ureg_dst_register( TGSI_FILE_ADDRESS, 0 );
}
/* Allocate a new sampler.
*/
struct ureg_src ureg_DECL_sampler( struct ureg_program *ureg )
struct ureg_src ureg_DECL_sampler( struct ureg_program *ureg,
unsigned nr )
{
return ureg_src_register( TGSI_FILE_SAMPLER, ureg->nr_samplers++ );
unsigned i;
for (i = 0; i < ureg->nr_samplers; i++)
if (ureg->sampler[i].Index == nr)
return ureg->sampler[i];
if (i < PIPE_MAX_SAMPLERS) {
ureg->sampler[i] = ureg_src_register( TGSI_FILE_SAMPLER, nr );
ureg->nr_samplers++;
return ureg->sampler[i];
}
assert( 0 );
return ureg->sampler[0];
}
@ -363,6 +400,8 @@ static int match_or_expand_immediate( const float *v,
unsigned *swizzle )
{
unsigned i, j;
*swizzle = 0;
for (i = 0; i < nr; i++) {
boolean found = FALSE;
@ -394,8 +433,8 @@ struct ureg_src ureg_DECL_immediate( struct ureg_program *ureg,
const float *v,
unsigned nr )
{
unsigned i;
unsigned swizzle = 0;
unsigned i, j;
unsigned swizzle;
/* Could do a first pass where we examine all existing immediates
* without expanding.
@ -423,6 +462,12 @@ struct ureg_src ureg_DECL_immediate( struct ureg_program *ureg,
set_bad( ureg );
out:
/* Make sure that all referenced elements are from this immediate.
* Has the effect of making size-one immediates into scalars.
*/
for (j = nr; j < 4; j++)
swizzle |= (swizzle & 0x3) << (j * 2);
return ureg_swizzle( ureg_src_register( TGSI_FILE_IMMEDIATE, i ),
(swizzle >> 0) & 0x3,
(swizzle >> 2) & 0x3,
@ -442,31 +487,39 @@ ureg_emit_src( struct ureg_program *ureg,
union tgsi_any_token *out = get_tokens( ureg, DOMAIN_INSN, size );
unsigned n = 0;
assert(src.File != TGSI_FILE_NULL);
assert(src.File != TGSI_FILE_OUTPUT);
assert(src.File < TGSI_FILE_COUNT);
out[n].value = 0;
out[n].src.File = src.File;
out[n].src.SwizzleX = src.SwizzleX;
out[n].src.SwizzleY = src.SwizzleY;
out[n].src.SwizzleZ = src.SwizzleZ;
out[n].src.SwizzleW = src.SwizzleW;
out[n].src.Indirect = src.Indirect;
out[n].src.Index = src.Index;
out[n].src.Negate = src.Negate;
n++;
if (src.Absolute) {
out[0].src.Extended = 1;
out[0].src.Negate = 0;
out[n].value = 0;
out[n].src_ext_mod.Type = TGSI_SRC_REGISTER_EXT_TYPE_MOD;
out[n].src_ext_mod.Absolute = 1;
out[n].src_ext_mod.Negate = src.Negate;
n++;
}
if (src.Indirect) {
out[0].src.Indirect = 1;
out[n].value = 0;
out[n].src.File = TGSI_FILE_ADDRESS;
out[n].src.SwizzleX = TGSI_SWIZZLE_X;
out[n].src.SwizzleY = TGSI_SWIZZLE_X;
out[n].src.SwizzleZ = TGSI_SWIZZLE_X;
out[n].src.SwizzleW = TGSI_SWIZZLE_X;
out[n].src.Indirect = 0;
out[n].src.Index = 0;
out[n].src.SwizzleX = src.IndirectSwizzle;
out[n].src.SwizzleY = src.IndirectSwizzle;
out[n].src.SwizzleZ = src.IndirectSwizzle;
out[n].src.SwizzleW = src.IndirectSwizzle;
out[n].src.Index = src.IndirectIndex;
n++;
}
@ -484,6 +537,13 @@ ureg_emit_dst( struct ureg_program *ureg,
union tgsi_any_token *out = get_tokens( ureg, DOMAIN_INSN, size );
unsigned n = 0;
assert(dst.File != TGSI_FILE_NULL);
assert(dst.File != TGSI_FILE_CONSTANT);
assert(dst.File != TGSI_FILE_INPUT);
assert(dst.File != TGSI_FILE_SAMPLER);
assert(dst.File != TGSI_FILE_IMMEDIATE);
assert(dst.File < TGSI_FILE_COUNT);
out[n].value = 0;
out[n].dst.File = dst.File;
out[n].dst.WriteMask = dst.WriteMask;
@ -494,12 +554,11 @@ ureg_emit_dst( struct ureg_program *ureg,
if (dst.Indirect) {
out[n].value = 0;
out[n].src.File = TGSI_FILE_ADDRESS;
out[n].src.SwizzleX = TGSI_SWIZZLE_X;
out[n].src.SwizzleY = TGSI_SWIZZLE_X;
out[n].src.SwizzleZ = TGSI_SWIZZLE_X;
out[n].src.SwizzleW = TGSI_SWIZZLE_X;
out[n].src.Indirect = 0;
out[n].src.Index = 0;
out[n].src.SwizzleX = dst.IndirectSwizzle;
out[n].src.SwizzleY = dst.IndirectSwizzle;
out[n].src.SwizzleZ = dst.IndirectSwizzle;
out[n].src.SwizzleW = dst.IndirectSwizzle;
out[n].src.Index = dst.IndirectIndex;
n++;
}
@ -523,7 +582,6 @@ ureg_emit_insn(struct ureg_program *ureg,
out[0].insn.NrTokens = 0;
out[0].insn.Opcode = opcode;
out[0].insn.Saturate = saturate;
out[0].insn.NrTokens = 0;
out[0].insn.NumDstRegs = num_dst;
out[0].insn.NumSrcRegs = num_src;
out[0].insn.Padding = 0;
@ -542,6 +600,9 @@ ureg_emit_label(struct ureg_program *ureg,
{
union tgsi_any_token *out, *insn;
if(!label_token)
return;
out = get_tokens( ureg, DOMAIN_INSN, 1 );
insn = retrieve_token( ureg, DOMAIN_INSN, insn_token );
@ -617,6 +678,17 @@ ureg_insn(struct ureg_program *ureg,
unsigned insn, i;
boolean saturate;
#ifdef DEBUG
{
const struct tgsi_opcode_info *info = tgsi_get_opcode_info( opcode );
assert(info);
if(info) {
assert(nr_dst == info->num_dst);
assert(nr_src == info->num_src);
}
}
#endif
saturate = nr_dst ? dst[0].Saturate : FALSE;
insn = ureg_emit_insn( ureg, opcode, saturate, nr_dst, nr_src );
@ -723,10 +795,10 @@ static void emit_decls( struct ureg_program *ureg )
TGSI_INTERPOLATE_CONSTANT );
}
if (ureg->nr_samplers) {
for (i = 0; i < ureg->nr_samplers; i++) {
emit_decl_range( ureg,
TGSI_FILE_SAMPLER,
0, ureg->nr_samplers );
ureg->sampler[i].Index, 1 );
}
if (ureg->nr_constants) {
@ -741,6 +813,12 @@ static void emit_decls( struct ureg_program *ureg )
0, ureg->nr_temps );
}
if (ureg->nr_addrs) {
emit_decl_range( ureg,
TGSI_FILE_ADDRESS,
0, ureg->nr_addrs );
}
for (i = 0; i < ureg->nr_immediates; i++) {
emit_immediate( ureg,
ureg->immediate[i].v );
@ -764,7 +842,7 @@ static void copy_instructions( struct ureg_program *ureg )
static void
fixup_header_size(struct ureg_program *ureg )
fixup_header_size(struct ureg_program *ureg)
{
union tgsi_any_token *out = retrieve_token( ureg, DOMAIN_DECL, 1 );

View File

@ -31,6 +31,10 @@
#include "pipe/p_compiler.h"
#include "pipe/p_shader_tokens.h"
#ifdef __cplusplus
extern "C" {
#endif
struct ureg_program;
/* Almost a tgsi_src_register, but we need to pull in the Absolute
@ -48,6 +52,8 @@ struct ureg_src
unsigned Absolute : 1; /* BOOL */
int Index : 16; /* SINT */
unsigned Negate : 1; /* BOOL */
int IndirectIndex : 16; /* SINT */
int IndirectSwizzle : 2; /* TGSI_SWIZZLE_ */
};
/* Very similar to a tgsi_dst_register, removing unsupported fields
@ -64,6 +70,8 @@ struct ureg_dst
int Index : 16; /* SINT */
unsigned Pad1 : 5;
unsigned Pad2 : 1; /* BOOL */
int IndirectIndex : 16; /* SINT */
int IndirectSwizzle : 2; /* TGSI_SWIZZLE_ */
};
struct pipe_context;
@ -131,12 +139,21 @@ void
ureg_release_temporary( struct ureg_program *ureg,
struct ureg_dst tmp );
struct ureg_dst
ureg_DECL_address( struct ureg_program * );
/* Supply an index to the sampler declaration as this is the hook to
* the external pipe_sampler state. Users of this function probably
* don't want just any sampler, but a specific one which they've set
* up state for in the context.
*/
struct ureg_src
ureg_DECL_sampler( struct ureg_program * );
ureg_DECL_sampler( struct ureg_program *,
unsigned index );
static INLINE struct ureg_src
ureg_DECL_immediate4f( struct ureg_program *ureg,
ureg_imm4f( struct ureg_program *ureg,
float a, float b,
float c, float d)
{
@ -149,7 +166,7 @@ ureg_DECL_immediate4f( struct ureg_program *ureg,
}
static INLINE struct ureg_src
ureg_DECL_immediate3f( struct ureg_program *ureg,
ureg_imm3f( struct ureg_program *ureg,
float a, float b,
float c)
{
@ -161,7 +178,7 @@ ureg_DECL_immediate3f( struct ureg_program *ureg,
}
static INLINE struct ureg_src
ureg_DECL_immediate2f( struct ureg_program *ureg,
ureg_imm2f( struct ureg_program *ureg,
float a, float b)
{
float v[2];
@ -171,7 +188,7 @@ ureg_DECL_immediate2f( struct ureg_program *ureg,
}
static INLINE struct ureg_src
ureg_DECL_immediate1f( struct ureg_program *ureg,
ureg_imm1f( struct ureg_program *ureg,
float a)
{
float v[1];
@ -392,6 +409,7 @@ static INLINE void ureg_##op( struct ureg_program *ureg, \
static INLINE struct ureg_src
ureg_negate( struct ureg_src reg )
{
assert(reg.File != TGSI_FILE_NULL);
reg.Negate ^= 1;
return reg;
}
@ -399,6 +417,7 @@ ureg_negate( struct ureg_src reg )
static INLINE struct ureg_src
ureg_abs( struct ureg_src reg )
{
assert(reg.File != TGSI_FILE_NULL);
reg.Absolute = 1;
reg.Negate = 0;
return reg;
@ -413,6 +432,12 @@ ureg_swizzle( struct ureg_src reg,
(reg.SwizzleZ << 4) |
(reg.SwizzleW << 6));
assert(reg.File != TGSI_FILE_NULL);
assert(x < 4);
assert(y < 4);
assert(z < 4);
assert(w < 4);
reg.SwizzleX = (swz >> (x*2)) & 0x3;
reg.SwizzleY = (swz >> (y*2)) & 0x3;
reg.SwizzleZ = (swz >> (z*2)) & 0x3;
@ -430,6 +455,7 @@ static INLINE struct ureg_dst
ureg_writemask( struct ureg_dst reg,
unsigned writemask )
{
assert(reg.File != TGSI_FILE_NULL);
reg.WriteMask &= writemask;
return reg;
}
@ -437,10 +463,33 @@ ureg_writemask( struct ureg_dst reg,
static INLINE struct ureg_dst
ureg_saturate( struct ureg_dst reg )
{
assert(reg.File != TGSI_FILE_NULL);
reg.Saturate = 1;
return reg;
}
static INLINE struct ureg_dst
ureg_dst_indirect( struct ureg_dst reg, struct ureg_src addr )
{
assert(reg.File != TGSI_FILE_NULL);
assert(addr.File == TGSI_FILE_ADDRESS);
reg.Indirect = 1;
reg.IndirectIndex = addr.Index;
reg.IndirectSwizzle = addr.SwizzleX;
return reg;
}
static INLINE struct ureg_src
ureg_src_indirect( struct ureg_src reg, struct ureg_src addr )
{
assert(reg.File != TGSI_FILE_NULL);
assert(addr.File == TGSI_FILE_ADDRESS);
reg.Indirect = 1;
reg.IndirectIndex = addr.Index;
reg.IndirectSwizzle = addr.SwizzleX;
return reg;
}
static INLINE struct ureg_dst
ureg_dst( struct ureg_src src )
{
@ -449,6 +498,8 @@ ureg_dst( struct ureg_src src )
dst.File = src.File;
dst.WriteMask = TGSI_WRITEMASK_XYZW;
dst.Indirect = src.Indirect;
dst.IndirectIndex = src.IndirectIndex;
dst.IndirectSwizzle = src.IndirectSwizzle;
dst.Saturate = 0;
dst.Index = src.Index;
dst.Pad1 = 0;
@ -469,6 +520,8 @@ ureg_src( struct ureg_dst dst )
src.SwizzleW = TGSI_SWIZZLE_W;
src.Pad = 0;
src.Indirect = dst.Indirect;
src.IndirectIndex = dst.IndirectIndex;
src.IndirectSwizzle = dst.IndirectSwizzle;
src.Absolute = 0;
src.Index = dst.Index;
src.Negate = 0;
@ -478,4 +531,60 @@ ureg_src( struct ureg_dst dst )
static INLINE struct ureg_dst
ureg_dst_undef( void )
{
struct ureg_dst dst;
dst.File = TGSI_FILE_NULL;
dst.WriteMask = 0;
dst.Indirect = 0;
dst.IndirectIndex = 0;
dst.IndirectSwizzle = 0;
dst.Saturate = 0;
dst.Index = 0;
dst.Pad1 = 0;
dst.Pad2 = 0;
return dst;
}
static INLINE struct ureg_src
ureg_src_undef( void )
{
struct ureg_src src;
src.File = TGSI_FILE_NULL;
src.SwizzleX = 0;
src.SwizzleY = 0;
src.SwizzleZ = 0;
src.SwizzleW = 0;
src.Pad = 0;
src.Indirect = 0;
src.IndirectIndex = 0;
src.IndirectSwizzle = 0;
src.Absolute = 0;
src.Index = 0;
src.Negate = 0;
return src;
}
static INLINE boolean
ureg_src_is_undef( struct ureg_src src )
{
return src.File == TGSI_FILE_NULL;
}
static INLINE boolean
ureg_dst_is_undef( struct ureg_dst dst )
{
return dst.File == TGSI_FILE_NULL;
}
#ifdef __cplusplus
}
#endif
#endif

View File

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

View File

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

View File

@ -60,6 +60,17 @@ util_blit_pixels(struct blit_state *ctx,
int dstX1, int dstY1,
float z, uint filter);
void
util_blit_pixels_writemask(struct blit_state *ctx,
struct pipe_surface *src,
int srcX0, int srcY0,
int srcX1, int srcY1,
struct pipe_surface *dst,
int dstX0, int dstY0,
int dstX1, int dstY1,
float z, uint filter,
uint writemask);
extern void
util_blit_pixels_tex(struct blit_state *ctx,
struct pipe_texture *tex,

View File

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

View File

@ -88,11 +88,14 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe,
/**
* Make simple fragment texture shader:
* TEX OUT[0], IN[0], SAMP[0], 2D;
* IMM {0,0,0,1} // (if writemask != 0xf)
* MOV OUT[0], IMM[0] // (if writemask != 0xf)
* TEX OUT[0].writemask, IN[0], SAMP[0], 2D;
* END;
*/
void *
util_make_fragment_tex_shader(struct pipe_context *pipe)
util_make_fragment_tex_shader_writemask(struct pipe_context *pipe,
unsigned writemask )
{
struct ureg_program *ureg;
struct ureg_src sampler;
@ -103,7 +106,7 @@ util_make_fragment_tex_shader(struct pipe_context *pipe)
if (ureg == NULL)
return NULL;
sampler = ureg_DECL_sampler( ureg );
sampler = ureg_DECL_sampler( ureg, 0 );
tex = ureg_DECL_fs_input( ureg,
TGSI_SEMANTIC_GENERIC, 0,
@ -119,6 +122,13 @@ util_make_fragment_tex_shader(struct pipe_context *pipe)
return ureg_create_shader_and_destroy( ureg, pipe );
}
void *
util_make_fragment_tex_shader(struct pipe_context *pipe )
{
return util_make_fragment_tex_shader_writemask( pipe,
TGSI_WRITEMASK_XYZW );
}

View File

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

View File

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

View File

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

View File

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

View File

@ -28,89 +28,20 @@
#ifndef I915_BATCH_H
#define I915_BATCH_H
#include "i915_winsys.h"
#include "intel_batchbuffer.h"
struct i915_batchbuffer
{
struct pipe_buffer *buffer;
struct i915_winsys *winsys;
#define BEGIN_BATCH(dwords, relocs) \
(intel_batchbuffer_check(i915->batch, dwords, relocs))
unsigned char *map;
unsigned char *ptr;
#define OUT_BATCH(dword) \
intel_batchbuffer_dword(i915->batch, dword)
size_t size;
size_t actual_size;
#define OUT_RELOC(buf, usage, offset) \
intel_batchbuffer_reloc(i915->batch, buf, usage, offset)
size_t relocs;
size_t max_relocs;
};
static INLINE boolean
i915_batchbuffer_check( struct i915_batchbuffer *batch,
size_t dwords,
size_t relocs )
{
return dwords * 4 <= batch->size - (batch->ptr - batch->map) &&
relocs <= (batch->max_relocs - batch->relocs);
}
static INLINE size_t
i915_batchbuffer_space( struct i915_batchbuffer *batch )
{
return batch->size - (batch->ptr - batch->map);
}
static INLINE void
i915_batchbuffer_dword( struct i915_batchbuffer *batch,
unsigned dword )
{
if (i915_batchbuffer_space(batch) < 4)
return;
*(unsigned *)batch->ptr = dword;
batch->ptr += 4;
}
static INLINE void
i915_batchbuffer_write( struct i915_batchbuffer *batch,
void *data,
size_t size )
{
if (i915_batchbuffer_space(batch) < size)
return;
memcpy(data, batch->ptr, size);
batch->ptr += size;
}
static INLINE void
i915_batchbuffer_reloc( struct i915_batchbuffer *batch,
struct pipe_buffer *buffer,
size_t flags,
size_t offset )
{
batch->winsys->batch_reloc( batch->winsys, buffer, flags, offset );
}
static INLINE void
i915_batchbuffer_flush( struct i915_batchbuffer *batch,
struct pipe_fence_handle **fence )
{
batch->winsys->batch_flush( batch->winsys, fence );
}
#define BEGIN_BATCH( dwords, relocs ) \
(i915_batchbuffer_check( i915->batch, dwords, relocs ))
#define OUT_BATCH( dword ) \
i915_batchbuffer_dword( i915->batch, dword )
#define OUT_RELOC( buf, flags, delta ) \
i915_batchbuffer_reloc( i915->batch, buf, flags, delta )
#define FLUSH_BATCH(fence) do { \
i915->winsys->batch_flush( i915->winsys, fence ); \
i915->hardware_dirty = ~0; \
#define FLUSH_BATCH(fence) do { \
intel_batchbuffer_flush(i915->batch, fence); \
i915->hardware_dirty = ~0; \
} while (0)
#endif

View File

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

View File

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

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

View File

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

View File

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

View File

@ -104,9 +104,9 @@ I915_DBG(
#endif
struct i915_batchbuffer;
struct intel_batchbuffer;
void i915_dump_batchbuffer( struct i915_batchbuffer *i915 );
void i915_dump_batchbuffer( struct intel_batchbuffer *i915 );
void i915_debug_init( struct i915_context *i915 );

View File

@ -45,6 +45,7 @@ static void i915_flush( struct pipe_context *pipe,
draw_flush(i915->draw);
#if 0
/* Do we need to emit an MI_FLUSH command to flush the hardware
* caches?
*/
@ -63,6 +64,13 @@ static void i915_flush( struct pipe_context *pipe,
}
OUT_BATCH( flush );
}
#endif
#if 0
if (i915->batch->map == i915->batch->ptr) {
return;
}
#endif
/* If there are no flags, just flush pending commands to hardware:
*/
@ -74,5 +82,5 @@ static void i915_flush( struct pipe_context *pipe,
void i915_init_flush_functions( struct i915_context *i915 )
{
i915->pipe.flush = i915_flush;
i915->base.flush = i915_flush;
}

View File

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

View File

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

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 "util/u_memory.h"
#include "util/u_string.h"
#include "i915_reg.h"
#include "i915_context.h"
#include "i915_screen.h"
#include "i915_buffer.h"
#include "i915_texture.h"
#include "i915_winsys.h"
#include "intel_winsys.h"
/*
* Probe functions
*/
static const char *
i915_get_vendor( struct pipe_screen *pscreen )
i915_get_vendor(struct pipe_screen *screen)
{
return "Tungsten Graphics, Inc.";
}
static const char *
i915_get_name( struct pipe_screen *pscreen )
i915_get_name(struct pipe_screen *screen)
{
static char buffer[128];
const char *chipset;
switch (i915_screen(pscreen)->pci_id) {
switch (i915_screen(screen)->pci_id) {
case PCI_CHIP_I915_G:
chipset = "915G";
break;
@ -86,7 +89,6 @@ i915_get_name( struct pipe_screen *pscreen )
return buffer;
}
static int
i915_get_param(struct pipe_screen *screen, int param)
{
@ -122,7 +124,6 @@ i915_get_param(struct pipe_screen *screen, int param)
}
}
static float
i915_get_paramf(struct pipe_screen *screen, int param)
{
@ -148,13 +149,12 @@ i915_get_paramf(struct pipe_screen *screen, int param)
}
}
static boolean
i915_is_format_supported( struct pipe_screen *screen,
enum pipe_format format,
enum pipe_texture_target target,
unsigned tex_usage,
unsigned geom_flags )
i915_is_format_supported(struct pipe_screen *screen,
enum pipe_format format,
enum pipe_texture_target target,
unsigned tex_usage,
unsigned geom_flags)
{
static const enum pipe_format tex_supported[] = {
PIPE_FORMAT_R8G8B8A8_UNORM,
@ -173,7 +173,6 @@ i915_is_format_supported( struct pipe_screen *screen,
PIPE_FORMAT_A8R8G8B8_UNORM,
PIPE_FORMAT_R5G6B5_UNORM,
PIPE_FORMAT_S8Z24_UNORM,
/*PIPE_FORMAT_R16G16B16A16_SNORM,*/
PIPE_FORMAT_NONE /* list terminator */
};
const enum pipe_format *list;
@ -193,122 +192,73 @@ i915_is_format_supported( struct pipe_screen *screen,
}
static void
i915_destroy_screen( struct pipe_screen *screen )
{
struct pipe_winsys *winsys = screen->winsys;
/*
* Fence functions
*/
if(winsys->destroy)
winsys->destroy(winsys);
FREE(screen);
}
static struct pipe_transfer*
i915_get_tex_transfer(struct pipe_screen *screen,
struct pipe_texture *texture,
unsigned face, unsigned level, unsigned zslice,
enum pipe_transfer_usage usage, unsigned x, unsigned y,
unsigned w, unsigned h)
{
struct i915_texture *tex = (struct i915_texture *)texture;
struct i915_transfer *trans;
unsigned offset; /* in bytes */
if (texture->target == PIPE_TEXTURE_CUBE) {
offset = tex->image_offset[level][face];
}
else if (texture->target == PIPE_TEXTURE_3D) {
offset = tex->image_offset[level][zslice];
}
else {
offset = tex->image_offset[level][0];
assert(face == 0);
assert(zslice == 0);
}
trans = CALLOC_STRUCT(i915_transfer);
if (trans) {
pipe_texture_reference(&trans->base.texture, texture);
trans->base.format = trans->base.format;
trans->base.x = x;
trans->base.y = y;
trans->base.width = w;
trans->base.height = h;
trans->base.block = texture->block;
trans->base.nblocksx = texture->nblocksx[level];
trans->base.nblocksy = texture->nblocksy[level];
trans->base.stride = tex->stride;
trans->offset = offset;
trans->base.usage = usage;
}
return &trans->base;
}
static void
i915_tex_transfer_destroy(struct pipe_transfer *trans)
i915_fence_reference(struct pipe_screen *screen,
struct pipe_fence_handle **ptr,
struct pipe_fence_handle *fence)
{
pipe_texture_reference(&trans->texture, NULL);
FREE(trans);
struct i915_screen *is = i915_screen(screen);
is->iws->fence_reference(is->iws, ptr, fence);
}
static void *
i915_transfer_map( struct pipe_screen *screen,
struct pipe_transfer *transfer )
static int
i915_fence_signalled(struct pipe_screen *screen,
struct pipe_fence_handle *fence,
unsigned flags)
{
struct i915_texture *tex = (struct i915_texture *)transfer->texture;
char *map;
unsigned flags = 0;
struct i915_screen *is = i915_screen(screen);
if (transfer->usage != PIPE_TRANSFER_WRITE)
flags |= PIPE_BUFFER_USAGE_CPU_READ;
if (transfer->usage != PIPE_TRANSFER_READ)
flags |= PIPE_BUFFER_USAGE_CPU_WRITE;
map = pipe_buffer_map( screen, tex->buffer, flags );
if (map == NULL)
return NULL;
if (transfer->texture &&
(flags & PIPE_BUFFER_USAGE_CPU_WRITE))
{
/* Do something to notify contexts of a texture change.
*/
/* i915_screen(screen)->timestamp++; */
}
return map + i915_transfer(transfer)->offset +
transfer->y / transfer->block.height * transfer->stride +
transfer->x / transfer->block.width * transfer->block.size;
return is->iws->fence_signalled(is->iws, fence);
}
static int
i915_fence_finish(struct pipe_screen *screen,
struct pipe_fence_handle *fence,
unsigned flags)
{
struct i915_screen *is = i915_screen(screen);
return is->iws->fence_finish(is->iws, fence);
}
/*
* Generic functions
*/
static void
i915_transfer_unmap(struct pipe_screen *screen,
struct pipe_transfer *transfer)
i915_destroy_screen(struct pipe_screen *screen)
{
struct i915_texture *tex = (struct i915_texture *)transfer->texture;
pipe_buffer_unmap( screen, tex->buffer );
struct i915_screen *is = i915_screen(screen);
if (is->iws)
is->iws->destroy(is->iws);
FREE(is);
}
/**
* Create a new i915_screen object
*/
struct pipe_screen *
i915_create_screen(struct pipe_winsys *winsys, uint pci_id)
i915_create_screen(struct intel_winsys *iws, uint pci_id)
{
struct i915_screen *i915screen = CALLOC_STRUCT(i915_screen);
struct i915_screen *is = CALLOC_STRUCT(i915_screen);
if (!i915screen)
if (!is)
return NULL;
switch (pci_id) {
case PCI_CHIP_I915_G:
case PCI_CHIP_I915_GM:
i915screen->is_i945 = FALSE;
is->is_i945 = FALSE;
break;
case PCI_CHIP_I945_G:
@ -317,7 +267,7 @@ i915_create_screen(struct pipe_winsys *winsys, uint pci_id)
case PCI_CHIP_G33_G:
case PCI_CHIP_Q33_G:
case PCI_CHIP_Q35_G:
i915screen->is_i945 = TRUE;
is->is_i945 = TRUE;
break;
default:
@ -326,24 +276,25 @@ i915_create_screen(struct pipe_winsys *winsys, uint pci_id)
return NULL;
}
i915screen->pci_id = pci_id;
is->pci_id = pci_id;
is->iws = iws;
i915screen->screen.winsys = winsys;
is->base.winsys = NULL;
i915screen->screen.destroy = i915_destroy_screen;
is->base.destroy = i915_destroy_screen;
i915screen->screen.get_name = i915_get_name;
i915screen->screen.get_vendor = i915_get_vendor;
i915screen->screen.get_param = i915_get_param;
i915screen->screen.get_paramf = i915_get_paramf;
i915screen->screen.is_format_supported = i915_is_format_supported;
i915screen->screen.get_tex_transfer = i915_get_tex_transfer;
i915screen->screen.tex_transfer_destroy = i915_tex_transfer_destroy;
i915screen->screen.transfer_map = i915_transfer_map;
i915screen->screen.transfer_unmap = i915_transfer_unmap;
is->base.get_name = i915_get_name;
is->base.get_vendor = i915_get_vendor;
is->base.get_param = i915_get_param;
is->base.get_paramf = i915_get_paramf;
is->base.is_format_supported = i915_is_format_supported;
i915_init_screen_texture_functions(&i915screen->screen);
u_simple_screen_init(&i915screen->screen);
is->base.fence_reference = i915_fence_reference;
is->base.fence_signalled = i915_fence_signalled;
is->base.fence_finish = i915_fence_finish;
return &i915screen->screen;
i915_init_screen_texture_functions(is);
i915_init_screen_buffer_functions(is);
return &is->base;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -42,12 +42,14 @@
#include "i915_texture.h"
#include "i915_debug.h"
#include "i915_screen.h"
#include "i915_winsys.h"
#include "intel_winsys.h"
/*
* Helper function and arrays
*/
/**
* Initial offset for Cube map.
*/
@ -133,7 +135,7 @@ i915_miptree_set_level_info(struct i915_texture *tex,
static void
i915_miptree_set_image_offset(struct i915_texture *tex,
unsigned level, unsigned img, unsigned x, unsigned y)
unsigned level, unsigned img, unsigned x, unsigned y)
{
if (img == 0 && level == 0)
assert(x == 0 && y == 0);
@ -150,7 +152,7 @@ i915_miptree_set_image_offset(struct i915_texture *tex,
/*
* Layout functions
* i915 layout functions, some used by i945
*/
@ -165,37 +167,174 @@ i915_scanout_layout(struct i915_texture *tex)
if (pt->last_level > 0 || pt->block.size != 4)
return 0;
i915_miptree_set_level_info( tex, 0, 1,
tex->base.width[0],
tex->base.height[0],
1 );
i915_miptree_set_image_offset( tex, 0, 0, 0, 0 );
i915_miptree_set_level_info(tex, 0, 1,
tex->base.width[0],
tex->base.height[0],
1);
i915_miptree_set_image_offset(tex, 0, 0, 0, 0);
#if 0 /* TODO use this code when backend is smarter */
if (tex->base.width[0] >= 240) {
tex->stride = power_of_two(tex->base.nblocksx[0] * pt->block.size);
tex->total_nblocksy = round_up(tex->base.nblocksy[0], 8);
#else
if (tex->base.width[0] >= 240) {
tex->stride = 2048 * 4;
tex->total_nblocksy = round_up(tex->base.nblocksy[0], 8);
#endif
tex->hw_tiled = INTEL_TILE_X;
} else if (tex->base.width[0] == 64 && tex->base.height[0] == 64) {
tex->stride = power_of_two(tex->base.nblocksx[0] * pt->block.size);
tex->total_nblocksy = round_up(tex->base.nblocksy[0], 8);
} else {
return 0;
return FALSE;
}
debug_printf("%s size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__,
tex->base.width[0], tex->base.height[0], pt->block.size,
tex->stride, tex->total_nblocksy, tex->stride * tex->total_nblocksy);
return 1;
return TRUE;
}
static void
i945_miptree_layout_2d( struct i915_texture *tex )
i915_miptree_layout_2d(struct i915_texture *tex)
{
struct pipe_texture *pt = &tex->base;
unsigned level;
unsigned width = pt->width[0];
unsigned height = pt->height[0];
unsigned nblocksx = pt->nblocksx[0];
unsigned nblocksy = pt->nblocksy[0];
tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4);
tex->total_nblocksy = 0;
for (level = 0; level <= pt->last_level; level++) {
i915_miptree_set_level_info(tex, level, 1, width, height, 1);
i915_miptree_set_image_offset(tex, level, 0, 0, tex->total_nblocksy);
nblocksy = round_up(MAX2(2, nblocksy), 2);
tex->total_nblocksy += nblocksy;
width = minify(width);
height = minify(height);
nblocksx = pf_get_nblocksx(&pt->block, width);
nblocksy = pf_get_nblocksy(&pt->block, height);
}
}
static void
i915_miptree_layout_3d(struct i915_texture *tex)
{
struct pipe_texture *pt = &tex->base;
unsigned level;
unsigned width = pt->width[0];
unsigned height = pt->height[0];
unsigned depth = pt->depth[0];
unsigned nblocksx = pt->nblocksx[0];
unsigned nblocksy = pt->nblocksy[0];
unsigned stack_nblocksy = 0;
/* Calculate the size of a single slice.
*/
tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4);
/* XXX: hardware expects/requires 9 levels at minimum.
*/
for (level = 0; level <= MAX2(8, pt->last_level); level++) {
i915_miptree_set_level_info(tex, level, depth, width, height, depth);
stack_nblocksy += MAX2(2, nblocksy);
width = minify(width);
height = minify(height);
depth = minify(depth);
nblocksx = pf_get_nblocksx(&pt->block, width);
nblocksy = pf_get_nblocksy(&pt->block, height);
}
/* Fixup depth image_offsets:
*/
depth = pt->depth[0];
for (level = 0; level <= pt->last_level; level++) {
unsigned i;
for (i = 0; i < depth; i++)
i915_miptree_set_image_offset(tex, level, i, 0, i * stack_nblocksy);
depth = minify(depth);
}
/* Multiply slice size by texture depth for total size. It's
* remarkable how wasteful of memory the i915 texture layouts
* are. They are largely fixed in the i945.
*/
tex->total_nblocksy = stack_nblocksy * pt->depth[0];
}
static void
i915_miptree_layout_cube(struct i915_texture *tex)
{
struct pipe_texture *pt = &tex->base;
unsigned width = pt->width[0], height = pt->height[0];
const unsigned nblocks = pt->nblocksx[0];
unsigned level;
unsigned face;
assert(width == height); /* cubemap images are square */
/* double pitch for cube layouts */
tex->stride = round_up(nblocks * pt->block.size * 2, 4);
tex->total_nblocksy = nblocks * 4;
for (level = 0; level <= pt->last_level; level++) {
i915_miptree_set_level_info(tex, level, 6, width, height, 1);
width /= 2;
height /= 2;
}
for (face = 0; face < 6; face++) {
unsigned x = initial_offsets[face][0] * nblocks;
unsigned y = initial_offsets[face][1] * nblocks;
unsigned d = nblocks;
for (level = 0; level <= pt->last_level; level++) {
i915_miptree_set_image_offset(tex, level, face, x, y);
d >>= 1;
x += step_offsets[face][0] * d;
y += step_offsets[face][1] * d;
}
}
}
static boolean
i915_miptree_layout(struct i915_texture * tex)
{
struct pipe_texture *pt = &tex->base;
switch (pt->target) {
case PIPE_TEXTURE_1D:
case PIPE_TEXTURE_2D:
i915_miptree_layout_2d(tex);
break;
case PIPE_TEXTURE_3D:
i915_miptree_layout_3d(tex);
break;
case PIPE_TEXTURE_CUBE:
i915_miptree_layout_cube(tex);
break;
default:
assert(0);
return FALSE;
}
return TRUE;
}
/*
* i945 layout functions
*/
static void
i945_miptree_layout_2d(struct i915_texture *tex)
{
struct pipe_texture *pt = &tex->base;
const int align_x = 2, align_y = 4;
@ -210,7 +349,7 @@ i945_miptree_layout_2d( struct i915_texture *tex )
/* used for scanouts that need special layouts */
if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_PRIMARY)
if (i915_scanout_layout(tex))
return;
return;
tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4);
@ -221,11 +360,11 @@ i945_miptree_layout_2d( struct i915_texture *tex )
*/
if (pt->last_level > 0) {
unsigned mip1_nblocksx
= align(pf_get_nblocksx(&pt->block, minify(width)), align_x)
= align(pf_get_nblocksx(&pt->block, minify(width)), align_x)
+ pf_get_nblocksx(&pt->block, minify(minify(width)));
if (mip1_nblocksx > nblocksx)
tex->stride = mip1_nblocksx * pt->block.size;
tex->stride = mip1_nblocksx * pt->block.size;
}
/* Pitch must be a whole number of dwords
@ -247,10 +386,10 @@ i945_miptree_layout_2d( struct i915_texture *tex )
/* Layout_below: step right after second mipmap level.
*/
if (level == 1) {
x += align(nblocksx, align_x);
x += align(nblocksx, align_x);
}
else {
y += nblocksy;
y += nblocksy;
}
width = minify(width);
@ -260,6 +399,63 @@ i945_miptree_layout_2d( struct i915_texture *tex )
}
}
static void
i945_miptree_layout_3d(struct i915_texture *tex)
{
struct pipe_texture *pt = &tex->base;
unsigned width = pt->width[0];
unsigned height = pt->height[0];
unsigned depth = pt->depth[0];
unsigned nblocksx = pt->nblocksx[0];
unsigned nblocksy = pt->nblocksy[0];
unsigned pack_x_pitch, pack_x_nr;
unsigned pack_y_pitch;
unsigned level;
tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4);
tex->total_nblocksy = 0;
pack_y_pitch = MAX2(pt->nblocksy[0], 2);
pack_x_pitch = tex->stride / pt->block.size;
pack_x_nr = 1;
for (level = 0; level <= pt->last_level; level++) {
int x = 0;
int y = 0;
unsigned q, j;
i915_miptree_set_level_info(tex, level, depth, width, height, depth);
for (q = 0; q < depth;) {
for (j = 0; j < pack_x_nr && q < depth; j++, q++) {
i915_miptree_set_image_offset(tex, level, q, x, y + tex->total_nblocksy);
x += pack_x_pitch;
}
x = 0;
y += pack_y_pitch;
}
tex->total_nblocksy += y;
if (pack_x_pitch > 4) {
pack_x_pitch >>= 1;
pack_x_nr <<= 1;
assert(pack_x_pitch * pack_x_nr * pt->block.size <= tex->stride);
}
if (pack_y_pitch > 2) {
pack_y_pitch >>= 1;
}
width = minify(width);
height = minify(height);
depth = minify(depth);
nblocksx = pf_get_nblocksx(&pt->block, width);
nblocksy = pf_get_nblocksy(&pt->block, height);
}
}
static void
i945_miptree_layout_cube(struct i915_texture *tex)
{
@ -361,225 +557,42 @@ i945_miptree_layout_cube(struct i915_texture *tex)
}
}
static boolean
i915_miptree_layout(struct i915_texture * tex)
{
struct pipe_texture *pt = &tex->base;
unsigned level;
switch (pt->target) {
case PIPE_TEXTURE_CUBE: {
const unsigned nblocks = pt->nblocksx[0];
unsigned face;
unsigned width = pt->width[0], height = pt->height[0];
assert(width == height); /* cubemap images are square */
/* double pitch for cube layouts */
tex->stride = round_up(nblocks * pt->block.size * 2, 4);
tex->total_nblocksy = nblocks * 4;
for (level = 0; level <= pt->last_level; level++) {
i915_miptree_set_level_info(tex, level, 6,
width, height,
1);
width /= 2;
height /= 2;
}
for (face = 0; face < 6; face++) {
unsigned x = initial_offsets[face][0] * nblocks;
unsigned y = initial_offsets[face][1] * nblocks;
unsigned d = nblocks;
for (level = 0; level <= pt->last_level; level++) {
i915_miptree_set_image_offset(tex, level, face, x, y);
d >>= 1;
x += step_offsets[face][0] * d;
y += step_offsets[face][1] * d;
}
}
break;
}
case PIPE_TEXTURE_3D:{
unsigned width = pt->width[0];
unsigned height = pt->height[0];
unsigned depth = pt->depth[0];
unsigned nblocksx = pt->nblocksx[0];
unsigned nblocksy = pt->nblocksy[0];
unsigned stack_nblocksy = 0;
/* Calculate the size of a single slice.
*/
tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4);
/* XXX: hardware expects/requires 9 levels at minimum.
*/
for (level = 0; level <= MAX2(8, pt->last_level);
level++) {
i915_miptree_set_level_info(tex, level, depth,
width, height, depth);
stack_nblocksy += MAX2(2, nblocksy);
width = minify(width);
height = minify(height);
depth = minify(depth);
nblocksx = pf_get_nblocksx(&pt->block, width);
nblocksy = pf_get_nblocksy(&pt->block, height);
}
/* Fixup depth image_offsets:
*/
depth = pt->depth[0];
for (level = 0; level <= pt->last_level; level++) {
unsigned i;
for (i = 0; i < depth; i++)
i915_miptree_set_image_offset(tex, level, i,
0, i * stack_nblocksy);
depth = minify(depth);
}
/* Multiply slice size by texture depth for total size. It's
* remarkable how wasteful of memory the i915 texture layouts
* are. They are largely fixed in the i945.
*/
tex->total_nblocksy = stack_nblocksy * pt->depth[0];
break;
}
default:{
unsigned width = pt->width[0];
unsigned height = pt->height[0];
unsigned nblocksx = pt->nblocksx[0];
unsigned nblocksy = pt->nblocksy[0];
tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4);
tex->total_nblocksy = 0;
for (level = 0; level <= pt->last_level; level++) {
i915_miptree_set_level_info(tex, level, 1,
width, height, 1);
i915_miptree_set_image_offset(tex, level, 0,
0, tex->total_nblocksy);
nblocksy = round_up(MAX2(2, nblocksy), 2);
tex->total_nblocksy += nblocksy;
width = minify(width);
height = minify(height);
nblocksx = pf_get_nblocksx(&pt->block, width);
nblocksy = pf_get_nblocksy(&pt->block, height);
}
break;
}
}
/*
DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__,
tex->pitch,
tex->total_nblocksy, pt->block.size, tex->stride * tex->total_nblocksy);
*/
return TRUE;
}
static boolean
i945_miptree_layout(struct i915_texture * tex)
{
struct pipe_texture *pt = &tex->base;
unsigned level;
switch (pt->target) {
case PIPE_TEXTURE_1D:
case PIPE_TEXTURE_2D:
i945_miptree_layout_2d(tex);
break;
case PIPE_TEXTURE_3D:
i945_miptree_layout_3d(tex);
break;
case PIPE_TEXTURE_CUBE:
i945_miptree_layout_cube(tex);
break;
case PIPE_TEXTURE_3D:{
unsigned width = pt->width[0];
unsigned height = pt->height[0];
unsigned depth = pt->depth[0];
unsigned nblocksx = pt->nblocksx[0];
unsigned nblocksy = pt->nblocksy[0];
unsigned pack_x_pitch, pack_x_nr;
unsigned pack_y_pitch;
tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4);
tex->total_nblocksy = 0;
pack_y_pitch = MAX2(pt->nblocksy[0], 2);
pack_x_pitch = tex->stride / pt->block.size;
pack_x_nr = 1;
for (level = 0; level <= pt->last_level; level++) {
unsigned nr_images = pt->target == PIPE_TEXTURE_3D ? depth : 6;
int x = 0;
int y = 0;
unsigned q, j;
i915_miptree_set_level_info(tex, level, nr_images,
width, height, depth);
for (q = 0; q < nr_images;) {
for (j = 0; j < pack_x_nr && q < nr_images; j++, q++) {
i915_miptree_set_image_offset(tex, level, q, x, y + tex->total_nblocksy);
x += pack_x_pitch;
}
x = 0;
y += pack_y_pitch;
}
tex->total_nblocksy += y;
if (pack_x_pitch > 4) {
pack_x_pitch >>= 1;
pack_x_nr <<= 1;
assert(pack_x_pitch * pack_x_nr * pt->block.size <= tex->stride);
}
if (pack_y_pitch > 2) {
pack_y_pitch >>= 1;
}
width = minify(width);
height = minify(height);
depth = minify(depth);
nblocksx = pf_get_nblocksx(&pt->block, width);
nblocksy = pf_get_nblocksy(&pt->block, height);
}
break;
}
case PIPE_TEXTURE_1D:
case PIPE_TEXTURE_2D:
// case PIPE_TEXTURE_RECTANGLE:
i945_miptree_layout_2d(tex);
break;
default:
assert(0);
return FALSE;
}
/*
DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__,
tex->pitch,
tex->total_nblocksy, pt->block.size, tex->stride * tex->total_nblocksy);
*/
return TRUE;
}
/*
* Screen texture functions
*/
static struct pipe_texture *
i915_texture_create(struct pipe_screen *screen,
const struct pipe_texture *templat)
{
struct i915_screen *i915screen = i915_screen(screen);
struct i915_screen *is = i915_screen(screen);
struct intel_winsys *iws = is->iws;
struct i915_texture *tex = CALLOC_STRUCT(i915_texture);
size_t tex_size;
unsigned buf_usage = 0;
@ -594,27 +607,35 @@ i915_texture_create(struct pipe_screen *screen,
tex->base.nblocksx[0] = pf_get_nblocksx(&tex->base.block, tex->base.width[0]);
tex->base.nblocksy[0] = pf_get_nblocksy(&tex->base.block, tex->base.height[0]);
if (i915screen->is_i945) {
if (is->is_i945) {
if (!i945_miptree_layout(tex))
goto fail;
goto fail;
} else {
if (!i915_miptree_layout(tex))
goto fail;
goto fail;
}
tex_size = tex->stride * tex->total_nblocksy;
buf_usage = PIPE_BUFFER_USAGE_PIXEL;
/* for scanouts and cursors, cursors don't have the scanout tag */
/* for scanouts and cursors, cursors arn't scanouts */
if (templat->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY && templat->width[0] != 64)
buf_usage |= I915_BUFFER_USAGE_SCANOUT;
tex->buffer = screen->buffer_create(screen, 64, buf_usage, tex_size);
buf_usage = INTEL_NEW_SCANOUT;
else
buf_usage = INTEL_NEW_TEXTURE;
tex->buffer = iws->buffer_create(iws, tex_size, 64, buf_usage);
if (!tex->buffer)
goto fail;
/* setup any hw fences */
if (tex->hw_tiled) {
assert(tex->sw_tiled == INTEL_TILE_NONE);
iws->buffer_set_fence_reg(iws, tex->buffer, tex->stride, tex->hw_tiled);
}
#if 0
void *ptr = ws->buffer_map(ws, tex->buffer,
PIPE_BUFFER_USAGE_CPU_WRITE);
@ -629,18 +650,56 @@ fail:
return NULL;
}
static struct pipe_texture *
i915_texture_blanket(struct pipe_screen * screen,
const struct pipe_texture *base,
const unsigned *stride,
struct pipe_buffer *buffer)
{
#if 0
struct i915_texture *tex;
assert(screen);
/* Only supports one type */
if (base->target != PIPE_TEXTURE_2D ||
base->last_level != 0 ||
base->depth[0] != 1) {
return NULL;
}
tex = CALLOC_STRUCT(i915_texture);
if (!tex)
return NULL;
tex->base = *base;
pipe_reference_init(&tex->base.reference, 1);
tex->base.screen = screen;
tex->stride = stride[0];
i915_miptree_set_level_info(tex, 0, 1, base->width[0], base->height[0], 1);
i915_miptree_set_image_offset(tex, 0, 0, 0, 0);
pipe_buffer_reference(&tex->buffer, buffer);
return &tex->base;
#else
return NULL;
#endif
}
static void
i915_texture_destroy(struct pipe_texture *pt)
{
struct i915_texture *tex = (struct i915_texture *)pt;
struct intel_winsys *iws = i915_screen(pt->screen)->iws;
uint i;
/*
DBG("%s deleting %p\n", __FUNCTION__, (void *) tex);
*/
pipe_buffer_reference(&tex->buffer, NULL);
iws->buffer_destroy(iws, tex->buffer);
for (i = 0; i < PIPE_MAX_TEXTURE_LEVELS; i++)
if (tex->image_offset[i])
@ -649,6 +708,12 @@ i915_texture_destroy(struct pipe_texture *pt)
FREE(tex);
}
/*
* Screen surface functions
*/
static struct pipe_surface *
i915_get_tex_surface(struct pipe_screen *screen,
struct pipe_texture *pt,
@ -684,11 +749,122 @@ i915_get_tex_surface(struct pipe_screen *screen,
return ps;
}
static struct pipe_texture *
i915_texture_blanket(struct pipe_screen * screen,
const struct pipe_texture *base,
const unsigned *stride,
struct pipe_buffer *buffer)
static void
i915_tex_surface_destroy(struct pipe_surface *surf)
{
pipe_texture_reference(&surf->texture, NULL);
FREE(surf);
}
/*
* Screen transfer functions
*/
static struct pipe_transfer*
i915_get_tex_transfer(struct pipe_screen *screen,
struct pipe_texture *texture,
unsigned face, unsigned level, unsigned zslice,
enum pipe_transfer_usage usage, unsigned x, unsigned y,
unsigned w, unsigned h)
{
struct i915_texture *tex = (struct i915_texture *)texture;
struct i915_transfer *trans;
unsigned offset; /* in bytes */
if (texture->target == PIPE_TEXTURE_CUBE) {
offset = tex->image_offset[level][face];
}
else if (texture->target == PIPE_TEXTURE_3D) {
offset = tex->image_offset[level][zslice];
}
else {
offset = tex->image_offset[level][0];
assert(face == 0);
assert(zslice == 0);
}
trans = CALLOC_STRUCT(i915_transfer);
if (trans) {
pipe_texture_reference(&trans->base.texture, texture);
trans->base.format = trans->base.format;
trans->base.x = x;
trans->base.y = y;
trans->base.width = w;
trans->base.height = h;
trans->base.block = texture->block;
trans->base.nblocksx = texture->nblocksx[level];
trans->base.nblocksy = texture->nblocksy[level];
trans->base.stride = tex->stride;
trans->offset = offset;
trans->base.usage = usage;
}
return &trans->base;
}
static void *
i915_transfer_map(struct pipe_screen *screen,
struct pipe_transfer *transfer)
{
struct i915_texture *tex = (struct i915_texture *)transfer->texture;
struct intel_winsys *iws = i915_screen(tex->base.screen)->iws;
char *map;
boolean write = FALSE;
if (transfer->usage != PIPE_TRANSFER_READ)
write = TRUE;
map = iws->buffer_map(iws, tex->buffer, write);
if (map == NULL)
return NULL;
return map + i915_transfer(transfer)->offset +
transfer->y / transfer->block.height * transfer->stride +
transfer->x / transfer->block.width * transfer->block.size;
}
static void
i915_transfer_unmap(struct pipe_screen *screen,
struct pipe_transfer *transfer)
{
struct i915_texture *tex = (struct i915_texture *)transfer->texture;
struct intel_winsys *iws = i915_screen(tex->base.screen)->iws;
iws->buffer_unmap(iws, tex->buffer);
}
static void
i915_tex_transfer_destroy(struct pipe_transfer *trans)
{
pipe_texture_reference(&trans->texture, NULL);
FREE(trans);
}
/*
* Other texture functions
*/
void
i915_init_screen_texture_functions(struct i915_screen *is)
{
is->base.texture_create = i915_texture_create;
is->base.texture_blanket = i915_texture_blanket;
is->base.texture_destroy = i915_texture_destroy;
is->base.get_tex_surface = i915_get_tex_surface;
is->base.tex_surface_destroy = i915_tex_surface_destroy;
is->base.get_tex_transfer = i915_get_tex_transfer;
is->base.transfer_map = i915_transfer_map;
is->base.transfer_unmap = i915_transfer_unmap;
is->base.tex_transfer_destroy = i915_tex_transfer_destroy;
}
struct pipe_texture *
i915_texture_blanket_intel(struct pipe_screen *screen,
struct pipe_texture *base,
unsigned stride,
struct intel_buffer *buffer)
{
struct i915_texture *tex;
assert(screen);
@ -708,52 +884,28 @@ i915_texture_blanket(struct pipe_screen * screen,
pipe_reference_init(&tex->base.reference, 1);
tex->base.screen = screen;
tex->stride = stride[0];
tex->stride = stride;
i915_miptree_set_level_info(tex, 0, 1, base->width[0], base->height[0], 1);
i915_miptree_set_image_offset(tex, 0, 0, 0, 0);
pipe_buffer_reference(&tex->buffer, buffer);
tex->buffer = buffer;
return &tex->base;
}
void
i915_init_texture_functions(struct i915_context *i915)
{
// i915->pipe.texture_update = i915_texture_update;
}
static void
i915_tex_surface_destroy(struct pipe_surface *surf)
{
pipe_texture_reference(&surf->texture, NULL);
FREE(surf);
}
void
i915_init_screen_texture_functions(struct pipe_screen *screen)
{
screen->texture_create = i915_texture_create;
screen->texture_destroy = i915_texture_destroy;
screen->get_tex_surface = i915_get_tex_surface;
screen->texture_blanket = i915_texture_blanket;
screen->tex_surface_destroy = i915_tex_surface_destroy;
}
boolean i915_get_texture_buffer( struct pipe_texture *texture,
struct pipe_buffer **buf,
unsigned *stride )
boolean
i915_get_texture_buffer_intel(struct pipe_texture *texture,
struct intel_buffer **buffer,
unsigned *stride)
{
struct i915_texture *tex = (struct i915_texture *)texture;
if (!tex)
if (!texture)
return FALSE;
pipe_buffer_reference(buf, tex->buffer);
if (stride)
*stride = tex->stride;
*stride = tex->stride;
*buffer = tex->buffer;
return TRUE;
}

View File

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

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.Tool('llvm')
if 'LLVM_VERSION' not in env:
print 'warning: LLVM not found: not building llvmpipe'
Return()
env.Tool('udis86')
env.ParseConfig('llvm-config --cppflags')
llvmpipe = env.ConvenienceLibrary(
target = 'llvmpipe',
@ -57,8 +61,6 @@ llvmpipe = env.ConvenienceLibrary(
env = env.Clone()
env['LINK'] = env['CXX']
env.ParseConfig('llvm-config --libs jit interpreter nativecodegen bitwriter')
env.Prepend(LIBS = [llvmpipe] + auxiliaries)
env.Program(

View File

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

View File

@ -33,7 +33,6 @@
*/
#include "pipe/p_defines.h"
#include "lp_bld_type.h"
#include "lp_bld_const.h"
#include "lp_bld_intr.h"
@ -52,6 +51,8 @@ lp_build_cmp(struct lp_build_context *bld,
LLVMValueRef zeros = LLVMConstNull(int_vec_type);
LLVMValueRef ones = LLVMConstAllOnes(int_vec_type);
LLVMValueRef cond;
LLVMValueRef res;
unsigned i;
if(func == PIPE_FUNC_NEVER)
return zeros;
@ -68,7 +69,6 @@ lp_build_cmp(struct lp_build_context *bld,
LLVMValueRef args[3];
unsigned cc;
boolean swap;
LLVMValueRef res;
swap = FALSE;
switch(func) {
@ -219,7 +219,28 @@ lp_build_cmp(struct lp_build_context *bld,
assert(0);
return bld->undef;
}
#if 0
/* XXX: Although valid IR, no LLVM target currently support this */
cond = LLVMBuildFCmp(bld->builder, op, a, b, "");
res = LLVMBuildSelect(bld->builder, cond, ones, zeros, "");
#else
debug_printf("%s: warning: using slow element-wise vector comparison\n",
__FUNCTION__);
res = LLVMGetUndef(int_vec_type);
for(i = 0; i < type.length; ++i) {
LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
cond = LLVMBuildFCmp(bld->builder, op,
LLVMBuildExtractElement(bld->builder, a, index, ""),
LLVMBuildExtractElement(bld->builder, b, index, ""),
"");
cond = LLVMBuildSelect(bld->builder, cond,
LLVMConstExtractElement(ones, index),
LLVMConstExtractElement(zeros, index),
"");
res = LLVMBuildInsertElement(bld->builder, res, cond, index, "");
}
#endif
}
else {
LLVMIntPredicate op;
@ -246,10 +267,31 @@ lp_build_cmp(struct lp_build_context *bld,
assert(0);
return bld->undef;
}
#if 0
/* XXX: Although valid IR, no LLVM target currently support this */
cond = LLVMBuildICmp(bld->builder, op, a, b, "");
res = LLVMBuildSelect(bld->builder, cond, ones, zeros, "");
#else
debug_printf("%s: warning: using slow element-wise vector comparison\n",
__FUNCTION__);
res = LLVMGetUndef(int_vec_type);
for(i = 0; i < type.length; ++i) {
LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
cond = LLVMBuildICmp(bld->builder, op,
LLVMBuildExtractElement(bld->builder, a, index, ""),
LLVMBuildExtractElement(bld->builder, b, index, ""),
"");
cond = LLVMBuildSelect(bld->builder, cond,
LLVMConstExtractElement(ones, index),
LLVMConstExtractElement(zeros, index),
"");
res = LLVMBuildInsertElement(bld->builder, res, cond, index, "");
}
#endif
}
return LLVMBuildSelect(bld->builder, cond, ones, zeros, "");
return res;
}

View File

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

View File

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

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 *);
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

View File

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

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

View File

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

View File

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

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

View File

@ -29,7 +29,7 @@ static int
nv50_tex_construct(struct nv50_context *nv50, struct nouveau_stateobj *so,
struct nv50_miptree *mt, int unit)
{
switch (mt->base.format) {
switch (mt->base.base.format) {
case PIPE_FORMAT_A8R8G8B8_UNORM:
so_data(so, NV50TIC_0_0_MAPA_C3 | NV50TIC_0_0_TYPEA_UNORM |
NV50TIC_0_0_MAPR_C2 | NV50TIC_0_0_TYPER_UNORM |
@ -118,18 +118,18 @@ nv50_tex_construct(struct nv50_context *nv50, struct nouveau_stateobj *so,
return 1;
}
so_reloc(so, mt->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_LOW |
so_reloc(so, mt->base.bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_LOW |
NOUVEAU_BO_RD, 0, 0);
if (nv50->sampler[unit]->normalized)
so_data (so, 0xd0005000 | mt->bo->tile_mode << 22);
so_data (so, 0xd0005000 | mt->base.bo->tile_mode << 22);
else
so_data (so, 0x5001d000 | mt->bo->tile_mode << 22);
so_data (so, 0x5001d000 | mt->base.bo->tile_mode << 22);
so_data (so, 0x00300000);
so_data (so, mt->base.width[0]);
so_data (so, (mt->base.last_level << 28) |
(mt->base.depth[0] << 16) | mt->base.height[0]);
so_data (so, mt->base.base.width[0]);
so_data (so, (mt->base.base.last_level << 28) |
(mt->base.base.depth[0] << 16) | mt->base.base.height[0]);
so_data (so, 0x03000000);
so_data (so, mt->base.last_level << 4);
so_data (so, mt->base.base.last_level << 4);
return 0;
}

View File

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

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);
for (i = 0; i < nr; i += 2)
OUT_RING (chan, (map[1] << 16) | map[0]);
OUT_RING (chan, (map[i + 1] << 16) | map[i]);
count -= nr;
map += nr;
@ -207,7 +207,7 @@ nv50_draw_elements_inline_u16(struct nv50_context *nv50, uint16_t *map,
BEGIN_RING(chan, tesla, 0x400015f0, nr >> 1);
for (i = 0; i < nr; i += 2)
OUT_RING (chan, (map[1] << 16) | map[0]);
OUT_RING (chan, (map[i + 1] << 16) | map[i]);
count -= nr;
map += nr;
@ -313,18 +313,18 @@ nv50_vbo_static_attrib(struct nv50_context *nv50, unsigned attrib,
so_data (so, fui(v[3]));
break;
case 3:
so_method(so, tesla, NV50TCL_VTX_ATTR_3F_X(attrib), 4);
so_method(so, tesla, NV50TCL_VTX_ATTR_3F_X(attrib), 3);
so_data (so, fui(v[0]));
so_data (so, fui(v[1]));
so_data (so, fui(v[2]));
break;
case 2:
so_method(so, tesla, NV50TCL_VTX_ATTR_2F_X(attrib), 4);
so_method(so, tesla, NV50TCL_VTX_ATTR_2F_X(attrib), 2);
so_data (so, fui(v[0]));
so_data (so, fui(v[1]));
break;
case 1:
so_method(so, tesla, NV50TCL_VTX_ATTR_1F(attrib), 4);
so_method(so, tesla, NV50TCL_VTX_ATTR_1F(attrib), 1);
so_data (so, fui(v[0]));
break;
default:

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);
END_CS; */
BEGIN_CS(2 + (count+1)/2);
BEGIN_CS(4 + (count+1)/2);
OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, count);
OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, (count+1)/2);
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) |
r300render->hwprim);

View File

@ -429,6 +429,9 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state)
r300->rs_state = rs;
r300->dirty_state |= R300_NEW_RASTERIZER;
r300->dirty_state |= R300_NEW_RS_BLOCK;
r300->dirty_state |= R300_NEW_SCISSOR;
r300->dirty_state |= R300_NEW_VIEWPORT;
}
/* Free rasterizer state. */

View File

@ -38,7 +38,9 @@ void r300_emit_invariant_state(struct r300_context* r300)
/*** Graphics Backend (GB) ***/
/* Various GB enables */
OUT_CS_REG(R300_GB_ENABLE, 0x0);
OUT_CS_REG(R300_GB_ENABLE, R300_GB_POINT_STUFF_ENABLE |
R300_GB_LINE_STUFF_ENABLE |
R300_GB_TRIANGLE_STUFF_ENABLE);
/* Subpixel multisampling for AA
* These are commented out because glisse's CS checker doesn't like them.
* I presume these will be re-enabled later.

View File

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

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

View File

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

View File

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

View File

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

View File

@ -286,6 +286,18 @@ choose_pixel_format(XMesaVisual v)
return PIPE_FORMAT_B8G8R8A8_UNORM;
}
}
else if ( GET_REDMASK(v) == 0x0000ff00
&& GET_GREENMASK(v) == 0x00ff0000
&& GET_BLUEMASK(v) == 0xff000000
&& v->BitsPerPixel == 32) {
if (native_byte_order) {
/* no byteswapping needed */
return PIPE_FORMAT_B8G8R8A8_UNORM;
}
else {
return PIPE_FORMAT_A8R8G8B8_UNORM;
}
}
else if ( GET_REDMASK(v) == 0xf800
&& GET_GREENMASK(v) == 0x07e0
&& GET_BLUEMASK(v) == 0x001f
@ -656,7 +668,7 @@ XMesaVisual XMesaCreateVisual( Display *display,
* at a later time.
*/
v->visinfo = (XVisualInfo *) MALLOC(sizeof(*visinfo));
if(!v->visinfo) {
if (!v->visinfo) {
_mesa_free(v);
return NULL;
}
@ -743,7 +755,7 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
{
static GLboolean firstTime = GL_TRUE;
static struct pipe_screen *screen = NULL;
struct pipe_context *pipe;
struct pipe_context *pipe = NULL;
XMesaContext c;
GLcontext *mesaCtx;
uint pf;
@ -769,8 +781,7 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
if (screen == NULL)
goto fail;
pipe = driver.create_pipe_context( screen,
(void *)c );
pipe = driver.create_pipe_context(screen, (void *) c);
if (pipe == NULL)
goto fail;
@ -783,23 +794,15 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
mesaCtx = c->st->ctx;
c->st->ctx->DriverCtx = c;
#if 00
_mesa_enable_sw_extensions(mesaCtx);
_mesa_enable_1_3_extensions(mesaCtx);
_mesa_enable_1_4_extensions(mesaCtx);
_mesa_enable_1_5_extensions(mesaCtx);
_mesa_enable_2_0_extensions(mesaCtx);
#endif
return c;
fail:
fail:
if (c->st)
st_destroy_context(c->st);
else if (pipe)
pipe->destroy(pipe);
FREE(c);
_mesa_free(c);
return NULL;
}
@ -1153,7 +1156,7 @@ void XMesaFlush( XMesaContext c )
XMesaBuffer XMesaFindBuffer( Display *dpy, Drawable d )
{
XMesaBuffer b;
for (b=XMesaBufferList; b; b=b->Next) {
for (b = XMesaBufferList; b; b = b->Next) {
if (b->drawable == d && b->xm_visual->display == dpy) {
return b;
}

View File

@ -2,9 +2,10 @@
#include "xorg_exa_tgsi.h"
#include <cso_cache/cso_context.h>
#include "cso_cache/cso_context.h"
#include "util/u_draw_quad.h"
#include <pipe/p_inlines.h>
#include "pipe/p_inlines.h"
struct xorg_composite_blend {
int op:8;
@ -39,6 +40,24 @@ static const struct xorg_composite_blend xorg_blends[] = {
PIPE_BLENDFACTOR_INV_SRC_ALPHA, PIPE_BLENDFACTOR_INV_SRC_ALPHA },
};
static INLINE void
pixel_to_float4(PictFormatPtr format,
CARD32 pixel, float *color)
{
CARD32 r, g, b, a;
debug_assert(format->type == PictTypeDirect);
r = (pixel >> format->direct.red) & format->direct.redMask;
g = (pixel >> format->direct.green) & format->direct.greenMask;
b = (pixel >> format->direct.blue) & format->direct.blueMask;
a = (pixel >> format->direct.alpha) & format->direct.alphaMask;
color[0] = ((float)r) / ((float)format->direct.redMask);
color[1] = ((float)g) / ((float)format->direct.greenMask);
color[2] = ((float)b) / ((float)format->direct.blueMask);
color[3] = ((float)a) / ((float)format->direct.alphaMask);
}
struct acceleration_info {
int op : 16;
int with_mask : 1;
@ -75,19 +94,168 @@ blend_for_op(int op)
return xorg_blends[BLEND_OP_OVER];
}
static void
draw_texture(struct exa_context *exa)
static INLINE int
render_repeat_to_gallium(int mode)
{
#if 0
if (buf) {
util_draw_vertex_buffer(pipe, buf, 0,
PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */
2); /* attribs/vert */
pipe_buffer_reference(&buf, NULL);
switch(mode) {
case RepeatNone:
return PIPE_TEX_WRAP_CLAMP;
case RepeatNormal:
return PIPE_TEX_WRAP_REPEAT;
case RepeatReflect:
return PIPE_TEX_WRAP_MIRROR_REPEAT;
case RepeatPad:
return PIPE_TEX_WRAP_CLAMP_TO_EDGE;
default:
debug_printf("Unsupported repeat mode\n");
}
#endif
return PIPE_TEX_WRAP_REPEAT;
}
static INLINE void
setup_vertex0(float vertex[2][4], float x, float y,
float color[4])
{
vertex[0][0] = x;
vertex[0][1] = y;
vertex[0][2] = 0.f; /*z*/
vertex[0][3] = 1.f; /*w*/
vertex[1][0] = color[0]; /*r*/
vertex[1][1] = color[1]; /*g*/
vertex[1][2] = color[2]; /*b*/
vertex[1][3] = color[3]; /*a*/
}
static struct pipe_buffer *
setup_vertex_data0(struct exa_context *ctx,
int srcX, int srcY, int maskX, int maskY,
int dstX, int dstY, int width, int height)
{
float vertices[4][2][4];
/* 1st vertex */
setup_vertex0(vertices[0], dstX, dstY,
ctx->solid_color);
/* 2nd vertex */
setup_vertex0(vertices[1], dstX + width, dstY,
ctx->solid_color);
/* 3rd vertex */
setup_vertex0(vertices[2], dstX + width, dstY + height,
ctx->solid_color);
/* 4th vertex */
setup_vertex0(vertices[3], dstX, dstY + height,
ctx->solid_color);
return pipe_user_buffer_create(ctx->ctx->screen,
vertices,
sizeof(vertices));
}
static INLINE void
setup_vertex1(float vertex[2][4], float x, float y, float s, float t)
{
vertex[0][0] = x;
vertex[0][1] = y;
vertex[0][2] = 0.f; /*z*/
vertex[0][3] = 1.f; /*w*/
vertex[1][0] = s; /*s*/
vertex[1][1] = t; /*t*/
vertex[1][2] = 0.f; /*r*/
vertex[1][3] = 1.f; /*q*/
}
static struct pipe_buffer *
setup_vertex_data1(struct exa_context *ctx,
int srcX, int srcY, int maskX, int maskY,
int dstX, int dstY, int width, int height)
{
float vertices[4][2][4];
float s0, t0, s1, t1;
struct pipe_texture *src = ctx->bound_textures[0];
s0 = srcX / src->width[0];
s1 = srcX + width / src->width[0];
t0 = srcY / src->height[0];
t1 = srcY + height / src->height[0];
/* 1st vertex */
setup_vertex1(vertices[0], dstX, dstY,
s0, t0);
/* 2nd vertex */
setup_vertex1(vertices[1], dstX + width, dstY,
s1, t0);
/* 3rd vertex */
setup_vertex1(vertices[2], dstX + width, dstY + height,
s1, t1);
/* 4th vertex */
setup_vertex1(vertices[3], dstX, dstY + height,
s0, t1);
return pipe_user_buffer_create(ctx->ctx->screen,
vertices,
sizeof(vertices));
}
static INLINE void
setup_vertex2(float vertex[3][4], float x, float y,
float s0, float t0, float s1, float t1)
{
vertex[0][0] = x;
vertex[0][1] = y;
vertex[0][2] = 0.f; /*z*/
vertex[0][3] = 1.f; /*w*/
vertex[1][0] = s0; /*s*/
vertex[1][1] = t0; /*t*/
vertex[1][2] = 0.f; /*r*/
vertex[1][3] = 1.f; /*q*/
vertex[2][0] = s1; /*s*/
vertex[2][1] = t1; /*t*/
vertex[2][2] = 0.f; /*r*/
vertex[2][3] = 1.f; /*q*/
}
static struct pipe_buffer *
setup_vertex_data2(struct exa_context *ctx,
int srcX, int srcY, int maskX, int maskY,
int dstX, int dstY, int width, int height)
{
float vertices[4][3][4];
float st0[4], st1[4];
struct pipe_texture *src = ctx->bound_textures[0];
struct pipe_texture *mask = ctx->bound_textures[0];
st0[0] = srcX / src->width[0];
st0[1] = srcY / src->height[0];
st0[2] = srcX + width / src->width[0];
st0[3] = srcY + height / src->height[0];
st1[0] = maskX / mask->width[0];
st1[1] = maskY / mask->height[0];
st1[2] = maskX + width / mask->width[0];
st1[3] = maskY + height / mask->height[0];
/* 1st vertex */
setup_vertex2(vertices[0], dstX, dstY,
st0[0], st0[1], st1[0], st1[1]);
/* 2nd vertex */
setup_vertex2(vertices[1], dstX + width, dstY,
st0[2], st0[1], st1[2], st1[1]);
/* 3rd vertex */
setup_vertex2(vertices[2], dstX + width, dstY + height,
st0[2], st0[3], st1[2], st1[3]);
/* 4th vertex */
setup_vertex2(vertices[3], dstX, dstY + height,
st0[0], st0[3], st1[0], st1[3]);
return pipe_user_buffer_create(ctx->ctx->screen,
vertices,
sizeof(vertices));
}
boolean xorg_composite_accelerated(int op,
@ -172,27 +340,10 @@ set_viewport(struct exa_context *exa, int width, int height,
static void
bind_viewport_state(struct exa_context *exa, PicturePtr pDstPicture)
{
const int param_bytes = 8 * sizeof(float);
int width = pDstPicture->pDrawable->width;
int height = pDstPicture->pDrawable->height;
float vs_consts[8] = {
2.f/width, 2.f/height, 1, 1,
-1, -1, 0, 0
};
struct pipe_constant_buffer *cbuf = &exa->vs_const_buffer;
set_viewport(exa, width, height, Y0_BOTTOM);
pipe_buffer_reference(&cbuf->buffer, NULL);
cbuf->buffer = pipe_buffer_create(exa->ctx->screen, 16,
PIPE_BUFFER_USAGE_CONSTANT,
param_bytes);
if (cbuf->buffer) {
pipe_buffer_write(exa->ctx->screen, cbuf->buffer,
0, param_bytes, vs_consts);
}
exa->ctx->set_constant_buffer(exa->ctx, PIPE_SHADER_VERTEX, 0, cbuf);
set_viewport(exa, width, height, Y0_TOP);
}
static void
@ -240,8 +391,20 @@ bind_shaders(struct exa_context *exa, int op,
struct xorg_shader shader;
if (pSrcPicture) {
vs_traits |= VS_COMPOSITE;
fs_traits |= FS_COMPOSITE;
if (pSrcPicture->pSourcePict) {
if (pSrcPicture->pSourcePict->type == SourcePictTypeSolidFill) {
fs_traits |= FS_SOLID_FILL;
vs_traits |= VS_SOLID_FILL;
pixel_to_float4(pSrcPicture->pFormat,
pSrcPicture->pSourcePict->solidFill.color,
exa->solid_color);
} else {
debug_assert("!gradients not supported");
}
} else {
fs_traits |= FS_COMPOSITE;
vs_traits |= VS_COMPOSITE;
}
}
if (pMaskPicture) {
@ -264,35 +427,98 @@ bind_samplers(struct exa_context *exa, int op,
struct exa_pixmap_priv *pDst)
{
struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
struct pipe_texture *textures[PIPE_MAX_SAMPLERS];
struct pipe_sampler_state src_sampler, mask_sampler;
exa->num_bound_samplers = 0;
memset(&src_sampler, 0, sizeof(struct pipe_sampler_state));
memset(&mask_sampler, 0, sizeof(struct pipe_sampler_state));
if (pSrcPicture && pSrc) {
src_sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
src_sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
unsigned src_wrap = render_repeat_to_gallium(
pSrcPicture->repeatType);
src_sampler.wrap_s = src_wrap;
src_sampler.wrap_t = src_wrap;
src_sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST;
src_sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST;
src_sampler.normalized_coords = 1;
samplers[0] = &src_sampler;
textures[0] = pSrc->tex;
exa->bound_textures[0] = pSrc->tex;
++exa->num_bound_samplers;
}
if (pMaskPicture && pMask) {
mask_sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
mask_sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
unsigned mask_wrap = render_repeat_to_gallium(
pMaskPicture->repeatType);
mask_sampler.wrap_s = mask_wrap;
mask_sampler.wrap_t = mask_wrap;
mask_sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST;
mask_sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST;
mask_sampler.normalized_coords = 1;
samplers[1] = &mask_sampler;
textures[1] = pMask->tex;
exa->bound_textures[1] = pMask->tex;
++exa->num_bound_samplers;
}
cso_set_samplers(exa->cso, 3,
cso_set_samplers(exa->cso, exa->num_bound_samplers,
(const struct pipe_sampler_state **)samplers);
cso_set_sampler_textures(exa->cso, 3, textures);
cso_set_sampler_textures(exa->cso, exa->num_bound_samplers,
exa->bound_textures);
}
static void
setup_vs_constant_buffer(struct exa_context *exa,
int width, int height)
{
const int param_bytes = 8 * sizeof(float);
float vs_consts[8] = {
2.f/width, 2.f/height, 1, 1,
-1, -1, 0, 0
};
struct pipe_constant_buffer *cbuf = &exa->vs_const_buffer;
pipe_buffer_reference(&cbuf->buffer, NULL);
cbuf->buffer = pipe_buffer_create(exa->ctx->screen, 16,
PIPE_BUFFER_USAGE_CONSTANT,
param_bytes);
if (cbuf->buffer) {
pipe_buffer_write(exa->ctx->screen, cbuf->buffer,
0, param_bytes, vs_consts);
}
exa->ctx->set_constant_buffer(exa->ctx, PIPE_SHADER_VERTEX, 0, cbuf);
}
static void
setup_fs_constant_buffer(struct exa_context *exa)
{
const int param_bytes = 4 * sizeof(float);
float fs_consts[8] = {
0, 0, 0, 1,
};
struct pipe_constant_buffer *cbuf = &exa->fs_const_buffer;
pipe_buffer_reference(&cbuf->buffer, NULL);
cbuf->buffer = pipe_buffer_create(exa->ctx->screen, 16,
PIPE_BUFFER_USAGE_CONSTANT,
param_bytes);
if (cbuf->buffer) {
pipe_buffer_write(exa->ctx->screen, cbuf->buffer,
0, param_bytes, fs_consts);
}
exa->ctx->set_constant_buffer(exa->ctx, PIPE_SHADER_FRAGMENT, 0, cbuf);
}
static void
setup_constant_buffers(struct exa_context *exa, PicturePtr pDstPicture)
{
int width = pDstPicture->pDrawable->width;
int height = pDstPicture->pDrawable->height;
setup_vs_constant_buffer(exa, width, height);
setup_fs_constant_buffer(exa);
}
boolean xorg_composite_bind_state(struct exa_context *exa,
@ -309,8 +535,10 @@ boolean xorg_composite_bind_state(struct exa_context *exa,
bind_blend_state(exa, op, pSrcPicture, pMaskPicture);
bind_rasterizer_state(exa);
bind_shaders(exa, op, pSrcPicture, pMaskPicture);
bind_samplers(exa, op, pSrcPicture, pMaskPicture, pDstPicture,
pSrc, pMask, pDst);
bind_samplers(exa, op, pSrcPicture, pMaskPicture,
pDstPicture, pSrc, pMask, pDst);
setup_constant_buffers(exa, pDstPicture);
return FALSE;
}
@ -320,5 +548,37 @@ void xorg_composite(struct exa_context *exa,
int srcX, int srcY, int maskX, int maskY,
int dstX, int dstY, int width, int height)
{
struct pipe_context *pipe = exa->ctx;
struct pipe_buffer *buf = 0;
if (exa->num_bound_samplers == 0 ) { /* solid fill */
buf = setup_vertex_data0(exa,
srcX, srcY, maskX, maskY,
dstX, dstY, width, height);
} else if (exa->num_bound_samplers == 1 ) /* src */
buf = setup_vertex_data1(exa,
srcX, srcY, maskX, maskY,
dstX, dstY, width, height);
else if (exa->num_bound_samplers == 2) /* src + mask */
buf = setup_vertex_data2(exa,
srcX, srcY, maskX, maskY,
dstX, dstY, width, height);
else if (exa->num_bound_samplers == 3) { /* src + mask + dst */
debug_assert(!"src/mask/dst not handled right now");
#if 0
buf = setup_vertex_data2(exa,
srcX, srcY, maskX, maskY,
dstX, dstY, width, height);
#endif
}
if (buf) {
util_draw_vertex_buffer(pipe, buf, 0,
PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */
1 + exa->num_bound_samplers); /* attribs/vert */
pipe_buffer_reference(&buf, NULL);
}
}

View File

@ -33,6 +33,7 @@
#include "xf86_OSproc.h"
#include "xorg_tracker.h"
#include "xorg_exa.h"
#include "dri2.h"
@ -47,19 +48,156 @@ typedef struct {
struct pipe_fence_handle *fence;
} *BufferPrivatePtr;
static DRI2BufferPtr
driCreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count)
static Bool
driDoCreateBuffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int format)
{
struct pipe_texture *depth, *tex;
struct pipe_buffer *buf;
struct pipe_texture *tex = NULL;
ScreenPtr pScreen = pDraw->pScreen;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
modesettingPtr ms = modesettingPTR(pScrn);
BufferPrivatePtr privates;
DRI2BufferPtr buffers;
struct exa_pixmap_priv *exa_priv;
BufferPrivatePtr private = buffer->driverPrivate;
PixmapPtr pPixmap;
unsigned stride, handle;
boolean have_depth = FALSE, have_stencil = FALSE;
if (pDraw->type == DRAWABLE_PIXMAP)
pPixmap = (PixmapPtr) pDraw;
else
pPixmap = (*pScreen->GetWindowPixmap)((WindowPtr) pDraw);
exa_priv = exaGetPixmapDriverPrivate(pPixmap);
switch (buffer->attachment) {
default:
if (buffer->attachment != DRI2BufferFakeFrontLeft ||
pDraw->type != DRAWABLE_PIXMAP) {
private->pPixmap = (*pScreen->CreatePixmap)(pScreen, pDraw->width,
pDraw->height,
pDraw->depth,
0);
}
break;
case DRI2BufferFrontLeft:
break;
case DRI2BufferStencil:
#if defined(DRI2INFOREC_VERSION) && DRI2INFOREC_VERSION > 2
case DRI2BufferDepthStencil:
if (exa_priv->depth_stencil_tex &&
!pf_is_depth_stencil(exa_priv->depth_stencil_tex->format))
exa_priv->depth_stencil_tex = NULL;
/* Fall through */
#endif
case DRI2BufferDepth:
if (exa_priv->depth_stencil_tex)
pipe_texture_reference(&tex, exa_priv->depth_stencil_tex);
else {
struct pipe_texture template;
memset(&template, 0, sizeof(template));
template.target = PIPE_TEXTURE_2D;
if (buffer->attachment == DRI2BufferDepth)
template.format = ms->ds_depth_bits_last ?
PIPE_FORMAT_X8Z24_UNORM : PIPE_FORMAT_Z24X8_UNORM;
else
template.format = ms->ds_depth_bits_last ?
PIPE_FORMAT_S8Z24_UNORM : PIPE_FORMAT_Z24S8_UNORM;
pf_get_block(template.format, &template.block);
template.width[0] = pDraw->width;
template.height[0] = pDraw->height;
template.depth[0] = 1;
template.last_level = 0;
template.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL |
PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
tex = ms->screen->texture_create(ms->screen, &template);
pipe_texture_reference(&exa_priv->depth_stencil_tex, tex);
}
break;
}
if (!private->pPixmap) {
private->pPixmap = pPixmap;
pPixmap->refcnt++;
}
if (!tex) {
xorg_exa_set_shared_usage(private->pPixmap);
pScreen->ModifyPixmapHeader(private->pPixmap, 0, 0, 0, 0, 0, NULL);
tex = xorg_exa_get_texture(private->pPixmap);
}
if (!tex)
FatalError("NO TEXTURE IN DRI2\n");
ms->api->shared_handle_from_texture(ms->api, ms->screen, tex, &stride, &handle);
buffer->name = handle;
buffer->pitch = stride;
buffer->cpp = 4;
buffer->driverPrivate = private;
buffer->flags = 0; /* not tiled */
private->tex = tex;
return TRUE;
}
static void
driDoDestroyBuffer(DrawablePtr pDraw, DRI2BufferPtr buffer)
{
ScreenPtr pScreen = pDraw->pScreen;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
modesettingPtr ms = modesettingPTR(pScrn);
BufferPrivatePtr private = buffer->driverPrivate;
struct exa_pixmap_priv *exa_priv = exaGetPixmapDriverPrivate(private->pPixmap);
pipe_texture_reference(&private->tex, NULL);
ms->screen->fence_reference(ms->screen, &private->fence, NULL);
pipe_texture_reference(&exa_priv->depth_stencil_tex, NULL);
(*pScreen->DestroyPixmap)(private->pPixmap);
}
#if defined(DRI2INFOREC_VERSION) && DRI2INFOREC_VERSION > 2
static DRI2BufferPtr
driCreateBuffer(DrawablePtr pDraw, unsigned int attachment, unsigned int format)
{
DRI2BufferPtr buffer;
BufferPrivatePtr private;
buffer = xcalloc(1, sizeof *buffer);
if (!buffer)
return NULL;
private = xcalloc(1, sizeof *private);
if (!private) {
goto fail;
}
buffer->attachment = attachment;
buffer->driverPrivate = private;
if (driDoCreateBuffer(pDraw, buffer, format))
return buffer;
xfree(private);
fail:
xfree(buffer);
return NULL;
}
static void
driDestroyBuffer(DrawablePtr pDraw, DRI2BufferPtr buffer)
{
driDoDestroyBuffer(pDraw, buffer);
xfree(buffer->driverPrivate);
xfree(buffer);
}
#else /* DRI2INFOREC_VERSION <= 2 */
static DRI2BufferPtr
driCreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count)
{
BufferPrivatePtr privates;
DRI2BufferPtr buffers;
int i;
buffers = xcalloc(count, sizeof *buffers);
@ -71,81 +209,17 @@ driCreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count)
goto fail_privates;
for (i = 0; i < count; i++) {
if (attachments[i] == DRI2BufferDepth)
have_depth = TRUE;
else if (attachments[i] == DRI2BufferStencil)
have_stencil = TRUE;
}
if (have_stencil && !have_depth)
FatalError("Doesn't support only stencil yet\n");
depth = NULL;
for (i = 0; i < count; i++) {
pPixmap = NULL;
tex = NULL;
buf = NULL;
if (attachments[i] == DRI2BufferFrontLeft) {
if (pDraw->type == DRAWABLE_PIXMAP)
pPixmap = (PixmapPtr) pDraw;
else
pPixmap = (*pScreen->GetWindowPixmap)((WindowPtr) pDraw);
pPixmap->refcnt++;
} else if (attachments[i] == DRI2BufferStencil) {
pipe_texture_reference(&tex, depth);
} else if (attachments[i] == DRI2BufferDepth) {
struct pipe_texture template;
memset(&template, 0, sizeof(template));
template.target = PIPE_TEXTURE_2D;
if (have_stencil)
template.format = ms->ds_depth_bits_last ?
PIPE_FORMAT_S8Z24_UNORM : PIPE_FORMAT_Z24S8_UNORM;
else
template.format = ms->d_depth_bits_last ?
PIPE_FORMAT_X8Z24_UNORM : PIPE_FORMAT_Z24X8_UNORM;
pf_get_block(template.format, &template.block);
template.width[0] = pDraw->width;
template.height[0] = pDraw->height;
template.depth[0] = 1;
template.last_level = 0;
template.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL |
PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
tex = ms->screen->texture_create(ms->screen, &template);
depth = tex;
} else if (attachments[i] == DRI2BufferFakeFrontLeft &&
pDraw->type == DRAWABLE_PIXMAP) {
pPixmap = (PixmapPtr) pDraw;
pPixmap->refcnt++;
} else {
pPixmap = (*pScreen->CreatePixmap)(pScreen, pDraw->width,
pDraw->height,
pDraw->depth,
0);
}
if (pPixmap) {
xorg_exa_set_shared_usage(pPixmap);
pScreen->ModifyPixmapHeader(pPixmap, 0, 0, 0, 0, 0, NULL);
tex = xorg_exa_get_texture(pPixmap);
}
if (!tex)
FatalError("NO TEXTURE IN DRI2\n");
ms->api->shared_handle_from_texture(ms->api, ms->screen, tex, &stride, &handle);
buffers[i].name = handle;
buffers[i].attachment = attachments[i];
buffers[i].pitch = stride;
buffers[i].cpp = 4;
buffers[i].driverPrivate = &privates[i];
buffers[i].flags = 0; /* not tiled */
privates[i].pPixmap = pPixmap;
privates[i].tex = tex;
if (!driDoCreateBuffer(pDraw, &buffers[i], 0))
goto fail;
}
return buffers;
fail:
xfree(privates);
fail_privates:
xfree(buffers);
fail_buffers:
@ -155,21 +229,10 @@ fail_buffers:
static void
driDestroyBuffers(DrawablePtr pDraw, DRI2BufferPtr buffers, int count)
{
ScreenPtr pScreen = pDraw->pScreen;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
modesettingPtr ms = modesettingPTR(pScrn);
BufferPrivatePtr private;
int i;
(void)ms;
for (i = 0; i < count; i++) {
private = buffers[i].driverPrivate;
pipe_texture_reference(&private->tex, NULL);
ms->screen->fence_reference(ms->screen, &private->fence, NULL);
if (private->pPixmap)
(*pScreen->DestroyPixmap)(private->pPixmap);
driDoDestroyBuffer(pDraw, &buffers[i]);
}
if (buffers) {
@ -178,6 +241,8 @@ driDestroyBuffers(DrawablePtr pDraw, DRI2BufferPtr buffers, int count)
}
}
#endif /* DRI2INFOREC_VERSION */
static void
driCopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
DRI2BufferPtr pDestBuffer, DRI2BufferPtr pSrcBuffer)
@ -273,15 +338,25 @@ driScreenInit(ScreenPtr pScreen)
modesettingPtr ms = modesettingPTR(pScrn);
DRI2InfoRec dri2info;
#if defined(DRI2INFOREC_VERSION)
dri2info.version = DRI2INFOREC_VERSION;
#else
dri2info.version = 1;
#endif
dri2info.fd = ms->fd;
dri2info.driverName = pScrn->driverName;
dri2info.deviceName = "/dev/dri/card0"; /* FIXME */
#if defined(DRI2INFOREC_VERSION) && DRI2INFOREC_VERSION > 2
dri2info.CreateBuffer = driCreateBuffer;
dri2info.DestroyBuffer = driDestroyBuffer;
#else
dri2info.CreateBuffers = driCreateBuffers;
dri2info.DestroyBuffers = driDestroyBuffers;
#endif
dri2info.CopyRegion = driCopyRegion;
dri2info.Wait = NULL;
ms->d_depth_bits_last =
ms->screen->is_format_supported(ms->screen, PIPE_FORMAT_X8Z24_UNORM,

View File

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

View File

@ -97,6 +97,68 @@ ExaMarkSync(ScreenPtr pScreen)
return 1;
}
static Bool
ExaDownloadFromScreen(PixmapPtr pPix, int x, int y, int w, int h, char *dst,
int dst_pitch)
{
ScreenPtr pScreen = pPix->drawable.pScreen;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
modesettingPtr ms = modesettingPTR(pScrn);
struct exa_context *exa = ms->exa;
struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPix);
struct pipe_transfer *transfer;
if (!priv || !priv->tex)
return FALSE;
if (exa->ctx->is_texture_referenced(exa->ctx, priv->tex, 0, 0) &
PIPE_REFERENCED_FOR_WRITE)
exa->ctx->flush(exa->ctx, 0, NULL);
transfer = exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0,
PIPE_TRANSFER_READ, x, y, w, h);
if (!transfer)
return FALSE;
util_copy_rect((unsigned char*)dst, &priv->tex->block, dst_pitch, 0, 0,
w, h, exa->scrn->transfer_map(exa->scrn, transfer),
transfer->stride, 0, 0);
exa->scrn->transfer_unmap(exa->scrn, transfer);
exa->scrn->tex_transfer_destroy(transfer);
return TRUE;
}
static Bool
ExaUploadToScreen(PixmapPtr pPix, int x, int y, int w, int h, char *src,
int src_pitch)
{
ScreenPtr pScreen = pPix->drawable.pScreen;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
modesettingPtr ms = modesettingPTR(pScrn);
struct exa_context *exa = ms->exa;
struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPix);
struct pipe_transfer *transfer;
if (!priv || !priv->tex)
return FALSE;
transfer = exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0,
PIPE_TRANSFER_WRITE, x, y, w, h);
if (!transfer)
return FALSE;
util_copy_rect(exa->scrn->transfer_map(exa->scrn, transfer),
&priv->tex->block, transfer->stride, 0, 0, w, h,
(unsigned char*)src, src_pitch, 0, 0);
exa->scrn->transfer_unmap(exa->scrn, transfer);
exa->scrn->tex_transfer_destroy(transfer);
return TRUE;
}
static Bool
ExaPrepareAccess(PixmapPtr pPix, int index)
{
@ -188,9 +250,6 @@ ExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg)
struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
struct exa_context *exa = ms->exa;
if (1)
return FALSE;
if (pPixmap->drawable.depth < 15)
return FALSE;
@ -430,7 +489,7 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
modesettingPtr ms = modesettingPTR(pScrn);
struct exa_context *exa = ms->exa;
if (!priv)
if (!priv || pPixData)
return FALSE;
if (depth <= 0)
@ -452,65 +511,69 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
bitsPerPixel, devKind, NULL);
/* Deal with screen resize */
if (priv->tex && (priv->tex->width[0] != width ||
priv->tex->height[0] != height ||
priv->tex_flags != priv->flags)) {
pipe_texture_reference(&priv->tex, NULL);
}
if (!priv->tex
#ifdef DRM_MODE_FEATURE_DIRTYFB
&& priv->flags
#endif
) {
struct pipe_texture template;
memset(&template, 0, sizeof(template));
template.target = PIPE_TEXTURE_2D;
exa_get_pipe_format(depth, &template.format, &bitsPerPixel);
pf_get_block(template.format, &template.block);
template.width[0] = width;
template.height[0] = height;
template.depth[0] = 1;
template.last_level = 0;
template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET | priv->flags;
priv->tex_flags = priv->flags;
priv->tex = exa->scrn->texture_create(exa->scrn, &template);
}
if (!priv->tex ||
(priv->tex->width[0] != width ||
priv->tex->height[0] != height ||
priv->tex_flags != priv->flags)) {
struct pipe_texture *texture = NULL;
#ifdef DRM_MODE_FEATURE_DIRTYFB
if (!priv->tex) {
if (pPixData)
pPixmap->devPrivate.ptr = pPixData;
else
pPixmap->devPrivate.ptr = xalloc(pPixmap->drawable.height * pPixmap->devKind);
} else
if (priv->flags)
#endif
if (pPixData) {
struct pipe_transfer *transfer =
exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0,
PIPE_TRANSFER_WRITE,
0, 0, width, height);
util_copy_rect(exa->scrn->transfer_map(exa->scrn, transfer),
&priv->tex->block, transfer->stride, 0, 0,
width, height, pPixData, pPixmap->devKind, 0, 0);
exa->scrn->transfer_unmap(exa->scrn, transfer);
exa->scrn->tex_transfer_destroy(transfer);
} else if (priv->tex && pPixmap->devPrivate.ptr) {
struct pipe_transfer *transfer;
{
struct pipe_texture template;
if (priv->map_count != 0)
FatalError("doing ExaModifyPixmapHeader on mapped buffer\n");
memset(&template, 0, sizeof(template));
template.target = PIPE_TEXTURE_2D;
exa_get_pipe_format(depth, &template.format, &bitsPerPixel);
pf_get_block(template.format, &template.block);
template.width[0] = width;
template.height[0] = height;
template.depth[0] = 1;
template.last_level = 0;
template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET | priv->flags;
priv->tex_flags = priv->flags;
texture = exa->scrn->texture_create(exa->scrn, &template);
transfer =
exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0,
PIPE_TRANSFER_WRITE,
0, 0, width, height);
util_copy_rect(exa->scrn->transfer_map(exa->scrn, transfer),
&priv->tex->block, transfer->stride, 0, 0,
width, height, pPixmap->devPrivate.ptr, pPixmap->devKind, 0, 0);
exa->scrn->transfer_unmap(exa->scrn, transfer);
exa->scrn->tex_transfer_destroy(transfer);
if (priv->tex) {
struct pipe_surface *dst_surf;
dst_surf = exa->scrn->get_tex_surface(exa->scrn, texture, 0, 0, 0,
PIPE_BUFFER_USAGE_GPU_WRITE);
priv->src_surf = exa_gpu_surface(exa, priv);
exa->ctx->surface_copy(exa->ctx, dst_surf, 0, 0, priv->src_surf,
0, 0, min(width, texture->width[0]),
min(height, texture->height[0]));
exa->scrn->tex_surface_destroy(dst_surf);
exa->scrn->tex_surface_destroy(priv->src_surf);
priv->src_surf = NULL;
} else if (pPixmap->devPrivate.ptr) {
struct pipe_transfer *transfer;
if (priv->map_count != 0)
FatalError("doing ExaModifyPixmapHeader on mapped buffer\n");
transfer =
exa->scrn->get_tex_transfer(exa->scrn, texture, 0, 0, 0,
PIPE_TRANSFER_WRITE,
0, 0, width, height);
util_copy_rect(exa->scrn->transfer_map(exa->scrn, transfer),
&texture->block, transfer->stride, 0, 0,
width, height, pPixmap->devPrivate.ptr,
pPixmap->devKind, 0, 0);
exa->scrn->transfer_unmap(exa->scrn, transfer);
exa->scrn->tex_transfer_destroy(transfer);
}
}
#ifdef DRM_MODE_FEATURE_DIRTYFB
else {
xfree(pPixmap->devPrivate.ptr);
pPixmap->devPrivate.ptr = xalloc(pPixmap->drawable.height *
pPixmap->devKind);
}
#endif
pipe_texture_reference(&priv->tex, texture);
}
return TRUE;
@ -598,6 +661,8 @@ xorg_exa_init(ScrnInfoPtr pScrn)
pExa->Composite = ExaComposite;
pExa->DoneComposite = ExaDoneComposite;
pExa->PixmapIsOffscreen = ExaPixmapIsOffscreen;
pExa->DownloadFromScreen = ExaDownloadFromScreen;
pExa->UploadToScreen = ExaUploadToScreen;
pExa->PrepareAccess = ExaPrepareAccess;
pExa->FinishAccess = ExaFinishAccess;
pExa->CreatePixmap = ExaCreatePixmap;

View File

@ -8,6 +8,9 @@
struct cso_context;
struct xorg_shaders;
/* src + mask + dst */
#define MAX_EXA_SAMPLERS 3
struct exa_context
{
ExaDriverPtr pExa;
@ -18,6 +21,11 @@ struct exa_context
struct pipe_constant_buffer vs_const_buffer;
struct pipe_constant_buffer fs_const_buffer;
struct pipe_texture *bound_textures[MAX_EXA_SAMPLERS];
int num_bound_samplers;
float solid_color[4];
};
@ -27,6 +35,7 @@ struct exa_pixmap_priv
int tex_flags;
struct pipe_texture *tex;
struct pipe_texture *depth_stencil_tex;
unsigned int color;
struct pipe_surface *src_surf; /* for copies */

View File

@ -18,22 +18,24 @@
#include "cso_cache/cso_hash.h"
/* Vertex shader:
* IN[0] = src_pos
* IN[1] = mask_pos
* IN[2] = dst_pos
* IN[0] = vertex pos
* IN[1] = src tex coord | solid fill color
* IN[2] = mask tex coord
* IN[3] = dst tex coord
* CONST[0] = (2/dst_width, 2/dst_height, 1, 1)
* CONST[1] = (-1, -1, 0, 0)
*
* OUT[0] = src_pos
* OUT[1] = mask_pos
* OUT[2] = dst_pos
* OUT[0] = vertex pos
* OUT[1] = src tex coord | solid fill color
* OUT[2] = mask tex coord
* OUT[3] = dst tex coord
*/
/* Fragment shader:
* SAMP[0] = src
* SAMP[1] = mask
* SAMP[2] = dst
* IN[0] = pos src
* IN[0] = pos src | solid fill color
* IN[1] = pos mask
* IN[2] = pos dst
* CONST[0] = (0, 0, 0, 1)
@ -84,6 +86,150 @@ vs_normalize_coords(struct ureg_program *ureg, struct ureg_src coords,
return ret;
}
static void
linear_gradient(struct ureg_program *ureg,
struct ureg_dst out,
struct ureg_src pos,
struct ureg_src sampler,
struct ureg_src coords,
struct ureg_src const0124,
struct ureg_src matrow0,
struct ureg_src matrow1,
struct ureg_src matrow2)
{
struct ureg_dst temp0 = ureg_DECL_temporary(ureg);
struct ureg_dst temp1 = ureg_DECL_temporary(ureg);
struct ureg_dst temp2 = ureg_DECL_temporary(ureg);
struct ureg_dst temp3 = ureg_DECL_temporary(ureg);
struct ureg_dst temp4 = ureg_DECL_temporary(ureg);
struct ureg_dst temp5 = ureg_DECL_temporary(ureg);
ureg_MOV(ureg,
ureg_writemask(temp0, TGSI_WRITEMASK_XY), pos);
ureg_MOV(ureg,
ureg_writemask(temp0, TGSI_WRITEMASK_Z),
ureg_scalar(const0124, TGSI_SWIZZLE_Y));
ureg_DP3(ureg, temp1, matrow0, ureg_src(temp0));
ureg_DP3(ureg, temp2, matrow1, ureg_src(temp0));
ureg_DP3(ureg, temp3, matrow2, ureg_src(temp0));
ureg_RCP(ureg, temp3, ureg_src(temp3));
ureg_MUL(ureg, temp1, ureg_src(temp1), ureg_src(temp3));
ureg_MUL(ureg, temp2, ureg_src(temp2), ureg_src(temp3));
ureg_MOV(ureg, ureg_writemask(temp4, TGSI_WRITEMASK_X),
ureg_src(temp1));
ureg_MOV(ureg, ureg_writemask(temp4, TGSI_WRITEMASK_Y),
ureg_src(temp2));
ureg_MUL(ureg, temp0,
ureg_scalar(coords, TGSI_SWIZZLE_Y),
ureg_scalar(ureg_src(temp4), TGSI_SWIZZLE_Y));
ureg_MAD(ureg, temp1,
ureg_scalar(coords, TGSI_SWIZZLE_X),
ureg_scalar(ureg_src(temp4), TGSI_SWIZZLE_X),
ureg_src(temp0));
ureg_MUL(ureg, temp2,
ureg_src(temp1),
ureg_scalar(coords, TGSI_SWIZZLE_Z));
ureg_TEX(ureg, out,
TGSI_TEXTURE_1D, ureg_src(temp2), sampler);
ureg_release_temporary(ureg, temp0);
ureg_release_temporary(ureg, temp1);
ureg_release_temporary(ureg, temp2);
ureg_release_temporary(ureg, temp3);
ureg_release_temporary(ureg, temp4);
ureg_release_temporary(ureg, temp5);
}
static void
radial_gradient(struct ureg_program *ureg,
struct ureg_dst out,
struct ureg_src pos,
struct ureg_src sampler,
struct ureg_src coords,
struct ureg_src const0124,
struct ureg_src matrow0,
struct ureg_src matrow1,
struct ureg_src matrow2)
{
struct ureg_dst temp0 = ureg_DECL_temporary(ureg);
struct ureg_dst temp1 = ureg_DECL_temporary(ureg);
struct ureg_dst temp2 = ureg_DECL_temporary(ureg);
struct ureg_dst temp3 = ureg_DECL_temporary(ureg);
struct ureg_dst temp4 = ureg_DECL_temporary(ureg);
struct ureg_dst temp5 = ureg_DECL_temporary(ureg);
ureg_MOV(ureg,
ureg_writemask(temp0, TGSI_WRITEMASK_XY),
pos);
ureg_MOV(ureg,
ureg_writemask(temp0, TGSI_WRITEMASK_Z),
ureg_scalar(const0124, TGSI_SWIZZLE_Y));
ureg_DP3(ureg, temp1, matrow0, ureg_src(temp0));
ureg_DP3(ureg, temp2, matrow1, ureg_src(temp0));
ureg_DP3(ureg, temp3, matrow2, ureg_src(temp0));
ureg_RCP(ureg, temp3, ureg_src(temp3));
ureg_MUL(ureg, temp1, ureg_src(temp1), ureg_src(temp3));
ureg_MUL(ureg, temp2, ureg_src(temp2), ureg_src(temp3));
ureg_MOV(ureg, ureg_writemask(temp5, TGSI_WRITEMASK_X),
ureg_src(temp1));
ureg_MOV(ureg, ureg_writemask(temp5, TGSI_WRITEMASK_Y),
ureg_src(temp2));
ureg_MUL(ureg, temp0, ureg_scalar(coords, TGSI_SWIZZLE_Y),
ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_Y));
ureg_MAD(ureg, temp1,
ureg_scalar(coords, TGSI_SWIZZLE_X),
ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_X),
ureg_src(temp0));
ureg_ADD(ureg, temp1,
ureg_src(temp1), ureg_src(temp1));
ureg_MUL(ureg, temp3,
ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_Y),
ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_Y));
ureg_MAD(ureg, temp4,
ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_X),
ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_X),
ureg_src(temp3));
ureg_MOV(ureg, temp4, ureg_negate(ureg_src(temp4)));
ureg_MUL(ureg, temp2,
ureg_scalar(coords, TGSI_SWIZZLE_Z),
ureg_src(temp4));
ureg_MUL(ureg, temp0,
ureg_scalar(const0124, TGSI_SWIZZLE_W),
ureg_src(temp2));
ureg_MUL(ureg, temp3,
ureg_src(temp1), ureg_src(temp1));
ureg_SUB(ureg, temp2,
ureg_src(temp3), ureg_src(temp0));
ureg_RSQ(ureg, temp2, ureg_abs(ureg_src(temp2)));
ureg_RCP(ureg, temp2, ureg_src(temp2));
ureg_SUB(ureg, temp1,
ureg_src(temp2), ureg_src(temp1));
ureg_ADD(ureg, temp0,
ureg_scalar(coords, TGSI_SWIZZLE_Z),
ureg_scalar(coords, TGSI_SWIZZLE_Z));
ureg_RCP(ureg, temp0, ureg_src(temp0));
ureg_MUL(ureg, temp2,
ureg_src(temp1), ureg_src(temp0));
ureg_TEX(ureg, out, TGSI_TEXTURE_1D,
ureg_src(temp2), sampler);
ureg_release_temporary(ureg, temp0);
ureg_release_temporary(ureg, temp1);
ureg_release_temporary(ureg, temp2);
ureg_release_temporary(ureg, temp3);
ureg_release_temporary(ureg, temp4);
ureg_release_temporary(ureg, temp5);
}
static void *
create_vs(struct pipe_context *pipe,
unsigned vs_traits)
@ -92,6 +238,9 @@ create_vs(struct pipe_context *pipe,
struct ureg_src src;
struct ureg_dst dst;
struct ureg_src const0, const1;
boolean is_fill = vs_traits & VS_FILL;
boolean is_composite = vs_traits & VS_COMPOSITE;
boolean has_mask = vs_traits & VS_MASK;
ureg = ureg_create(TGSI_PROCESSOR_VERTEX);
if (ureg == NULL)
@ -100,18 +249,34 @@ create_vs(struct pipe_context *pipe,
const0 = ureg_DECL_constant(ureg);
const1 = ureg_DECL_constant(ureg);
if ((vs_traits & VS_COMPOSITE)) {
/* it has to be either a fill or a composite op */
debug_assert(is_fill ^ is_composite);
src = ureg_DECL_vs_input(ureg,
TGSI_SEMANTIC_POSITION, 0);
dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0);
src = vs_normalize_coords(ureg, src,
const0, const1);
ureg_MOV(ureg, dst, src);
if (is_composite) {
src = ureg_DECL_vs_input(ureg,
TGSI_SEMANTIC_POSITION, 0);
dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0);
src = vs_normalize_coords(ureg, src,
const0, const1);
TGSI_SEMANTIC_GENERIC, 1);
dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 1);
ureg_MOV(ureg, dst, src);
}
if ((vs_traits & VS_MASK)) {
if (is_fill) {
src = ureg_DECL_vs_input(ureg,
TGSI_SEMANTIC_POSITION, 1);
dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 1);
TGSI_SEMANTIC_COLOR, 1);
dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 1);
ureg_MOV(ureg, dst, src);
}
if (has_mask) {
src = ureg_DECL_vs_input(ureg,
TGSI_SEMANTIC_GENERIC, 2);
dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 2);
ureg_MOV(ureg, dst, src);
}
@ -125,27 +290,50 @@ create_fs(struct pipe_context *pipe,
unsigned fs_traits)
{
struct ureg_program *ureg;
struct ureg_src dst_sampler, src_sampler, mask_sampler;
struct ureg_src dst_pos, src_pos, mask_pos;
struct ureg_src src, mask;
struct ureg_src /*dst_sampler,*/ src_sampler, mask_sampler;
struct ureg_src /*dst_pos,*/ src_input, mask_pos;
struct ureg_dst src, mask;
struct ureg_dst out;
boolean has_mask = fs_traits & FS_MASK;
boolean is_fill = fs_traits & FS_FILL;
boolean is_composite = fs_traits & FS_COMPOSITE;
boolean is_solid = fs_traits & FS_SOLID_FILL;
boolean is_lingrad = fs_traits & FS_LINGRAD_FILL;
boolean is_radgrad = fs_traits & FS_RADGRAD_FILL;
ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT);
if (ureg == NULL)
return 0;
/* it has to be either a fill or a composite op */
debug_assert(is_fill ^ is_composite);
out = ureg_DECL_output(ureg,
TGSI_SEMANTIC_COLOR,
0);
src_sampler = ureg_DECL_sampler(ureg);
src_pos = ureg_DECL_fs_input(ureg,
TGSI_SEMANTIC_POSITION,
0,
TGSI_INTERPOLATE_PERSPECTIVE);
if (is_composite) {
src_sampler = ureg_DECL_sampler(ureg, 0);
src_input = ureg_DECL_fs_input(ureg,
TGSI_SEMANTIC_POSITION,
0,
TGSI_INTERPOLATE_PERSPECTIVE);
}
if (is_fill) {
if (is_solid)
src_input = ureg_DECL_fs_input(ureg,
TGSI_SEMANTIC_COLOR,
0,
TGSI_INTERPOLATE_PERSPECTIVE);
else
src_input = ureg_DECL_fs_input(ureg,
TGSI_SEMANTIC_POSITION,
0,
TGSI_INTERPOLATE_PERSPECTIVE);
}
if ((fs_traits & FS_MASK)) {
mask_sampler = ureg_DECL_sampler(ureg);
if (has_mask) {
mask_sampler = ureg_DECL_sampler(ureg, 1);
mask_pos = ureg_DECL_fs_input(ureg,
TGSI_SEMANTIC_POSITION,
1,
@ -153,21 +341,63 @@ create_fs(struct pipe_context *pipe,
}
#if 0 /* unused right now */
dst_sampler = ureg_DECL_sampler(ureg);
dst_sampler = ureg_DECL_sampler(ureg, 2);
dst_pos = ureg_DECL_fs_input(ureg,
TGSI_SEMANTIC_POSITION,
2,
TGSI_INTERPOLATE_PERSPECTIVE);
#endif
if ((fs_traits & FS_MASK)) {
ureg_TEX(ureg, ureg_dst(mask),
if (is_composite) {
if (has_mask)
src = ureg_DECL_temporary(ureg);
else
src = out;
ureg_TEX(ureg, src,
TGSI_TEXTURE_2D, src_input, src_sampler);
} else if (is_fill) {
if (is_solid) {
if (has_mask)
src = ureg_dst(src_input);
else
ureg_MOV(ureg, out, src_input);
} else if (is_lingrad || is_radgrad) {
struct ureg_src coords, const0124,
matrow0, matrow1, matrow2;
if (has_mask)
src = ureg_DECL_temporary(ureg);
else
src = out;
coords = ureg_DECL_constant(ureg);
const0124 = ureg_DECL_constant(ureg);
matrow0 = ureg_DECL_constant(ureg);
matrow1 = ureg_DECL_constant(ureg);
matrow2 = ureg_DECL_constant(ureg);
if (is_lingrad) {
linear_gradient(ureg, src,
src_input, src_sampler,
coords, const0124,
matrow0, matrow1, matrow2);
} else if (is_radgrad) {
radial_gradient(ureg, src,
src_input, src_sampler,
coords, const0124,
matrow0, matrow1, matrow2);
}
} else
debug_assert(!"Unknown fill type!");
}
if (has_mask) {
mask = ureg_DECL_temporary(ureg);
ureg_TEX(ureg, mask,
TGSI_TEXTURE_2D, mask_pos, mask_sampler);
/* src IN mask */
src_in_mask(ureg, out, src, mask);
} else {
ureg_TEX(ureg, out,
TGSI_TEXTURE_2D, src_pos, src_sampler);
src_in_mask(ureg, out, ureg_src(src), ureg_src(mask));
ureg_release_temporary(ureg, mask);
}
ureg_END(ureg);

View File

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

View File

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

View File

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

View File

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

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