Merge remote-tracking branch 'origin/master' into pipe-video

Conflicts:
	src/gallium/drivers/r600/r600_pipe.c
	src/gallium/drivers/r600/r600_state_inlines.h
This commit is contained in:
Christian König 2011-07-11 10:48:59 +02:00
commit f919547f37
127 changed files with 4018 additions and 2744 deletions

View file

@ -22,8 +22,8 @@ LIBDRM_REQUIRED=2.4.24
LIBDRM_RADEON_REQUIRED=2.4.24
LIBDRM_INTEL_REQUIRED=2.4.24
LIBDRM_NOUVEAU_REQUIRED=0.6
DRI2PROTO_REQUIRED=2.1
GLPROTO_REQUIRED=1.4.11
DRI2PROTO_REQUIRED=2.6
GLPROTO_REQUIRED=1.4.14
LIBDRM_XORG_REQUIRED=2.4.24
LIBKMS_XORG_REQUIRED=1.0.0

View file

@ -19,7 +19,7 @@ Clamping controls (GL_ARB_color_buffer_float) DONE
Float textures, renderbuffers (GL_ARB_texture_float) DONE (gallium r300)
GL_EXT_packed_float DONE (gallium r600)
GL_EXT_texture_shared_exponent DONE (gallium, swrast)
Float depth buffers (GL_ARB_depth_buffer_float) not started
Float depth buffers (GL_ARB_depth_buffer_float) DONE
Framebuffer objects (GL_EXT_framebuffer_object) DONE
Half-float DONE
Multisample blit DONE

View file

@ -923,8 +923,10 @@ dri2_create_image_khr_renderbuffer(_EGLDisplay *disp, _EGLContext *ctx,
return EGL_NO_IMAGE_KHR;
}
if (!_eglInitImage(&dri2_img->base, disp))
if (!_eglInitImage(&dri2_img->base, disp)) {
free(dri2_img);
return EGL_NO_IMAGE_KHR;
}
dri2_img->dri_image =
dri2_dpy->image->createImageFromRenderbuffer(dri2_ctx->dri_context,
@ -1335,8 +1337,10 @@ _EGL_MAIN(const char *args)
memset(dri2_drv, 0, sizeof *dri2_drv);
if (!dri2_load(&dri2_drv->base))
if (!dri2_load(&dri2_drv->base)) {
free(dri2_drv);
return NULL;
}
_eglInitDriverFallbacks(&dri2_drv->base);
dri2_drv->base.API.Initialize = dri2_initialize;

View file

@ -845,6 +845,7 @@ dri2_create_image_khr_pixmap(_EGLDisplay *disp, _EGLContext *ctx,
if (!_eglInitImage(&dri2_img->base, disp)) {
free(buffers_reply);
free(geometry_reply);
free(dri2_img);
return EGL_NO_IMAGE_KHR;
}

View file

@ -104,6 +104,7 @@ drm_create_buffer(struct wl_client *client, struct wl_drm *drm,
wl_client_post_error(client, &drm->object,
WL_DRM_ERROR_INVALID_VISUAL,
"invalid visual");
free(buffer);
return;
}

View file

@ -1235,7 +1235,8 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
draw_llvm_variant_key_samplers(&variant->key),
context_ptr);
fetch_max = LLVMBuildSub(builder, count,
/* fetch_max = start + count - 1 */
fetch_max = LLVMBuildSub(builder, end,
lp_build_const_int32(gallivm, 1),
"fetch_max");

View file

@ -207,21 +207,13 @@ lp_disassemble(const void* func)
}
raw_debug_ostream Out;
#if HAVE_LLVM >= 0x0300
TargetMachine *TM = T->createTargetMachine(Triple, sys::getHostCPUName(), "");
#else
TargetMachine *TM = T->createTargetMachine(Triple, "");
#endif
#if HAVE_LLVM >= 0x0300
unsigned int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
#else
int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
#endif
#if HAVE_LLVM >= 0x0300
OwningPtr<MCInstPrinter> Printer(
T->createMCInstPrinter(*TM, AsmPrinterVariant, *AsmInfo));
#elif HAVE_LLVM >= 0x0208
#if HAVE_LLVM >= 0x0208
OwningPtr<MCInstPrinter> Printer(
T->createMCInstPrinter(AsmPrinterVariant, *AsmInfo));
#else
@ -233,6 +225,12 @@ lp_disassemble(const void* func)
return;
}
#if HAVE_LLVM >= 0x0300
TargetMachine *TM = T->createTargetMachine(Triple, sys::getHostCPUName(), "");
#else
TargetMachine *TM = T->createTargetMachine(Triple, "");
#endif
const TargetInstrInfo *TII = TM->getInstrInfo();
/*

View file

@ -1839,6 +1839,17 @@ exec_tex(struct tgsi_exec_machine *mach,
assert(0);
}
#if 0
debug_printf("fetch r: %g %g %g %g\n",
r[0].f[0], r[0].f[1], r[0].f[2], r[0].f[3]);
debug_printf("fetch g: %g %g %g %g\n",
r[1].f[0], r[1].f[1], r[1].f[2], r[1].f[3]);
debug_printf("fetch b: %g %g %g %g\n",
r[2].f[0], r[2].f[1], r[2].f[2], r[2].f[3]);
debug_printf("fetch a: %g %g %g %g\n",
r[3].f[0], r[3].f[1], r[3].f[2], r[3].f[3]);
#endif
for (chan = 0; chan < NUM_CHANNELS; chan++) {
if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
store_dest(mach, &r[chan], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT);

View file

@ -458,6 +458,19 @@ util_pack_mask_z(enum pipe_format format, uint32_t z)
}
}
static INLINE uint64_t
util_pack64_mask_z(enum pipe_format format, uint32_t z)
{
switch (format) {
case PIPE_FORMAT_Z32_FLOAT_S8X24_USCALED:
return z;
default:
return util_pack_mask_z(format, z);
}
}
static INLINE uint32_t
util_pack_mask_z_stencil(enum pipe_format format, uint32_t z, uint8_t s)
{
@ -481,6 +494,21 @@ util_pack_mask_z_stencil(enum pipe_format format, uint32_t z, uint8_t s)
}
static INLINE uint64_t
util_pack64_mask_z_stencil(enum pipe_format format, uint32_t z, uint8_t s)
{
uint64_t packed;
switch (format) {
case PIPE_FORMAT_Z32_FLOAT_S8X24_USCALED:
packed = util_pack64_mask_z(format, z);
packed |= (uint64_t)s << 32ull;
return packed;
default:
return util_pack_mask_z_stencil(format, z, s);
}
}
/**
* Note: it's assumed that z is in [0,1]
@ -525,6 +553,24 @@ util_pack_z(enum pipe_format format, double z)
return 0;
}
}
static INLINE uint64_t
util_pack64_z(enum pipe_format format, double z)
{
union fi fui;
if (z == 0)
return 0;
switch (format) {
case PIPE_FORMAT_Z32_FLOAT_S8X24_USCALED:
fui.f = (float)z;
return fui.ui;
default:
return util_pack_z(format, z);
}
}
/**
@ -554,6 +600,24 @@ util_pack_z_stencil(enum pipe_format format, double z, uint8_t s)
}
static INLINE uint64_t
util_pack64_z_stencil(enum pipe_format format, double z, uint8_t s)
{
uint64_t packed;
switch (format) {
case PIPE_FORMAT_Z32_FLOAT_S8X24_USCALED:
packed = util_pack64_z(format, z);
packed |= (uint64_t)s << 32ull;
break;
default:
return util_pack_z_stencil(format, z, s);
}
return packed;
}
/**
* Pack 4 ubytes into a 4-byte word
*/

View file

@ -358,8 +358,41 @@ util_clear_depth_stencil(struct pipe_context *pipe,
dst_map += dst_stride;
}
}
break;
break;
case 8:
{
uint64_t zstencil = util_pack64_z_stencil(dst->texture->format,
depth, stencil);
assert(dst->format == PIPE_FORMAT_Z32_FLOAT_S8X24_USCALED);
if (!need_rmw) {
for (i = 0; i < height; i++) {
uint64_t *row = (uint64_t *)dst_map;
for (j = 0; j < width; j++)
*row++ = zstencil;
dst_map += dst_stride;
}
}
else {
uint64_t src_mask;
if (clear_flags & PIPE_CLEAR_DEPTH)
src_mask = 0x00000000ffffffffull;
else
src_mask = 0x000000ff00000000ull;
for (i = 0; i < height; i++) {
uint64_t *row = (uint64_t *)dst_map;
for (j = 0; j < width; j++) {
uint64_t tmp = *row & ~src_mask;
*row++ = tmp | (zstencil & src_mask);
}
dst_map += dst_stride;
}
}
break;
}
default:
assert(0);
break;

View file

@ -318,6 +318,32 @@ z32f_get_tile_rgba(const float *src,
}
}
/*** PIPE_FORMAT_Z32_FLOAT_S8X24_USCALED ***/
/**
* Return each Z value as four floats in [0,1].
*/
static void
z32f_x24s8_get_tile_rgba(const float *src,
unsigned w, unsigned h,
float *p,
unsigned dst_stride)
{
unsigned i, j;
for (i = 0; i < h; i++) {
float *pRow = p;
for (j = 0; j < w; j++, pRow += 4) {
pRow[0] =
pRow[1] =
pRow[2] =
pRow[3] = *src;
src += 2;
}
p += dst_stride;
}
}
void
pipe_tile_raw_to_rgba(enum pipe_format format,
@ -352,6 +378,9 @@ pipe_tile_raw_to_rgba(enum pipe_format format,
case PIPE_FORMAT_Z32_FLOAT:
z32f_get_tile_rgba((float *) src, w, h, dst, dst_stride);
break;
case PIPE_FORMAT_Z32_FLOAT_S8X24_USCALED:
z32f_x24s8_get_tile_rgba((float *) src, w, h, dst, dst_stride);
break;
default:
util_format_read_4f(format,
dst, dst_stride * sizeof(float),
@ -445,6 +474,12 @@ pipe_put_tile_rgba_format(struct pipe_context *pipe,
case PIPE_FORMAT_X8Z24_UNORM:
/*z24s8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
break;
case PIPE_FORMAT_Z32_FLOAT:
/*z32f_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
break;
case PIPE_FORMAT_Z32_FLOAT_S8X24_USCALED:
/*z32f_s8x24_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
break;
default:
util_format_write_4f(format,
p, src_stride * sizeof(float),

View file

@ -27,6 +27,7 @@ C_SOURCES = \
i915_resource_buffer.c \
i915_fpc_emit.c \
i915_fpc_translate.c \
i915_fpc_optimize.c \
i915_surface.c
include ../../Makefile.template

View file

@ -14,6 +14,7 @@ i915 = env.ConvenienceLibrary(
'i915_flush.c',
'i915_fpc_emit.c',
'i915_fpc_translate.c',
'i915_fpc_optimize.c',
'i915_prim_emit.c',
'i915_prim_vbuf.c',
'i915_query.c',

View file

@ -29,6 +29,7 @@
#define I915_BATCH_H
#include "i915_batchbuffer.h"
#include "i915_context.h"
#define BEGIN_BATCH(dwords) \
@ -49,11 +50,26 @@
#define FLUSH_BATCH(fence) \
i915_flush(i915, fence)
/************************************************************************
* i915_flush.c
*/
void i915_flush(struct i915_context *i915, struct pipe_fence_handle **fence);
/*
* Flush if the current color buf is idle and we have more than 256 vertices
* queued, or if the current color buf is busy and we have more than 4096
* vertices queued.
*/
static INLINE void i915_flush_heuristically(struct i915_context* i915,
int num_vertex)
{
struct i915_winsys *iws = i915->iws;
i915->vertices_since_last_flush += num_vertex;
if ( i915->vertices_since_last_flush > 4096
|| ( i915->vertices_since_last_flush > 256 &&
!iws->buffer_is_busy(iws, i915->current.cbuf_bo)) )
FLUSH_BATCH(NULL);
}
#endif

View file

@ -120,6 +120,11 @@ i915_clear_emit(struct pipe_context *pipe, unsigned buffers, const float *rgba,
OUT_BATCH_F(desty + height);
OUT_BATCH_F(destx);
OUT_BATCH_F(desty);
/* Flush after clear, its expected to be a costly operation.
* This is not required, just a heuristic
*/
FLUSH_BATCH(NULL);
}
/**

View file

@ -264,6 +264,8 @@ struct i915_context {
struct util_slab_mempool transfer_pool;
struct util_slab_mempool texture_transfer_pool;
int vertices_since_last_flush;
/** blitter/hw-clear */
struct blitter_context* blitter;

View file

@ -77,4 +77,5 @@ void i915_flush(struct i915_context *i915, struct pipe_fence_handle **fence)
i915->static_dirty = ~0;
/* kernel emits flushes in between batchbuffers */
i915->flush_dirty = 0;
i915->vertices_since_last_flush = 0;
}

View file

@ -33,7 +33,9 @@
#include "i915_context.h"
#include "i915_reg.h"
#include "pipe/p_shader_tokens.h"
#include "tgsi/tgsi_parse.h"
#define I915_PROGRAM_SIZE 192
@ -207,4 +209,90 @@ extern void
i915_program_error(struct i915_fp_compile *p, const char *msg, ...);
/*======================================================================
* i915_fpc_optimize.c
*/
struct i915_src_register
{
unsigned File : 4; /* TGSI_FILE_ */
unsigned Indirect : 1; /* BOOL */
unsigned Dimension : 1; /* BOOL */
int Index : 16; /* SINT */
unsigned SwizzleX : 3; /* TGSI_SWIZZLE_ */
unsigned SwizzleY : 3; /* TGSI_SWIZZLE_ */
unsigned SwizzleZ : 3; /* TGSI_SWIZZLE_ */
unsigned SwizzleW : 3; /* TGSI_SWIZZLE_ */
unsigned Absolute : 1; /* BOOL */
unsigned Negate : 1; /* BOOL */
};
/* Additional swizzle supported in i915 */
#define TGSI_SWIZZLE_ZERO 4
#define TGSI_SWIZZLE_ONE 5
struct i915_dst_register
{
unsigned File : 4; /* TGSI_FILE_ */
unsigned WriteMask : 4; /* TGSI_WRITEMASK_ */
unsigned Indirect : 1; /* BOOL */
unsigned Dimension : 1; /* BOOL */
int Index : 16; /* SINT */
unsigned Padding : 6;
};
struct i915_full_dst_register
{
struct i915_dst_register Register;
/*
struct tgsi_src_register Indirect;
struct tgsi_dimension Dimension;
struct tgsi_src_register DimIndirect;
*/
};
struct i915_full_src_register
{
struct i915_src_register Register;
/*
struct tgsi_src_register Indirect;
struct tgsi_dimension Dimension;
struct tgsi_src_register DimIndirect;
*/
};
struct i915_full_instruction
{
struct tgsi_instruction Instruction;
/*
struct tgsi_instruction_predicate Predicate;
struct tgsi_instruction_label Label;
*/
struct tgsi_instruction_texture Texture;
struct i915_full_dst_register Dst[1];
struct i915_full_src_register Src[3];
};
union i915_full_token
{
struct tgsi_token Token;
struct tgsi_full_declaration FullDeclaration;
struct tgsi_full_immediate FullImmediate;
struct i915_full_instruction FullInstruction;
struct tgsi_full_property FullProperty;
};
struct i915_token_list
{
union i915_full_token* Tokens;
unsigned NumTokens;
};
extern struct i915_token_list* i915_optimize(const struct tgsi_token *tokens);
extern void i915_optimize_free(struct i915_token_list* tokens);
#endif

View file

@ -369,7 +369,6 @@ i915_emit_const4f(struct i915_fp_compile * p,
// XXX emit swizzle here for 0, 1, -1 and any combination thereof
// we can use swizzle + neg for that
printf("const %f %f %f %f\n",c0,c1,c2,c3);
for (reg = 0; reg < I915_MAX_CONSTANT; reg++) {
if (ifs->constant_flags[reg] == 0xf &&
ifs->constants[reg][0] == c0 &&

View file

@ -0,0 +1,259 @@
/**************************************************************************
*
* Copyright 2011 The Chromium OS authors.
* 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 GOOGLE 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 "i915_reg.h"
#include "i915_context.h"
#include "i915_fpc.h"
#include "pipe/p_shader_tokens.h"
#include "util/u_math.h"
#include "util/u_memory.h"
#include "util/u_string.h"
#include "tgsi/tgsi_parse.h"
#include "tgsi/tgsi_dump.h"
static boolean same_dst_reg(struct i915_full_dst_register* d1, struct i915_full_dst_register* d2)
{
return (d1->Register.File == d2->Register.File &&
d1->Register.Indirect == d2->Register.Indirect &&
d1->Register.Dimension == d2->Register.Dimension &&
d1->Register.Index == d2->Register.Index);
}
static boolean same_src_reg(struct i915_full_src_register* d1, struct i915_full_src_register* d2)
{
return (d1->Register.File == d2->Register.File &&
d1->Register.Indirect == d2->Register.Indirect &&
d1->Register.Dimension == d2->Register.Dimension &&
d1->Register.Index == d2->Register.Index &&
d1->Register.Absolute == d2->Register.Absolute &&
d1->Register.Negate == d2->Register.Negate);
}
static boolean is_unswizzled(struct i915_full_src_register* r,
unsigned write_mask)
{
if ( write_mask & TGSI_WRITEMASK_X && r->Register.SwizzleX != TGSI_SWIZZLE_X)
return FALSE;
if ( write_mask & TGSI_WRITEMASK_Y && r->Register.SwizzleY != TGSI_SWIZZLE_Y)
return FALSE;
if ( write_mask & TGSI_WRITEMASK_Z && r->Register.SwizzleZ != TGSI_SWIZZLE_Z)
return FALSE;
if ( write_mask & TGSI_WRITEMASK_W && r->Register.SwizzleW != TGSI_SWIZZLE_W)
return FALSE;
return TRUE;
}
static boolean op_commutes(unsigned opcode)
{
if (opcode == TGSI_OPCODE_ADD) return TRUE;
if (opcode == TGSI_OPCODE_MUL) return TRUE;
return FALSE;
}
static unsigned op_neutral_element(unsigned opcode)
{
if (opcode == TGSI_OPCODE_ADD)
return TGSI_SWIZZLE_ZERO;
if (opcode == TGSI_OPCODE_MUL)
return TGSI_SWIZZLE_ONE;
debug_printf("Unknown opcode %d\n",opcode);
return TGSI_SWIZZLE_ZERO;
}
/*
* Sets the swizzle to the neutral element for the operation for the bits
* of writemask which are set, swizzle to identity otherwise.
*/
static void set_neutral_element_swizzle(struct i915_full_src_register* r,
unsigned write_mask,
unsigned neutral)
{
if ( write_mask & TGSI_WRITEMASK_X )
r->Register.SwizzleX = neutral;
else
r->Register.SwizzleX = TGSI_SWIZZLE_X;
if ( write_mask & TGSI_WRITEMASK_Y )
r->Register.SwizzleY = neutral;
else
r->Register.SwizzleY = TGSI_SWIZZLE_Y;
if ( write_mask & TGSI_WRITEMASK_Z )
r->Register.SwizzleZ = neutral;
else
r->Register.SwizzleZ = TGSI_SWIZZLE_Z;
if ( write_mask & TGSI_WRITEMASK_W )
r->Register.SwizzleW = neutral;
else
r->Register.SwizzleW = TGSI_SWIZZLE_W;
}
/*
* Optimize away things like:
* MUL OUT[0].xyz, TEMP[1], TEMP[2]
* MOV OUT[0].w, TEMP[2]
* into:
* MUL OUT[0].xyzw, TEMP[1].xyz1, TEMP[2]
* This is useful for optimizing texenv.
*/
static void i915_fpc_optimize_mov_after_alu(union i915_full_token* current, union i915_full_token* next)
{
if ( current->Token.Type == TGSI_TOKEN_TYPE_INSTRUCTION &&
next->Token.Type == TGSI_TOKEN_TYPE_INSTRUCTION &&
op_commutes(current->FullInstruction.Instruction.Opcode) &&
current->FullInstruction.Instruction.Saturate == next->FullInstruction.Instruction.Saturate &&
next->FullInstruction.Instruction.Opcode == TGSI_OPCODE_MOV &&
same_dst_reg(&next->FullInstruction.Dst[0], &next->FullInstruction.Dst[0]) &&
same_src_reg(&next->FullInstruction.Src[0], &current->FullInstruction.Src[1]) &&
is_unswizzled(&current->FullInstruction.Src[0], current->FullInstruction.Dst[0].Register.WriteMask) &&
is_unswizzled(&current->FullInstruction.Src[1], current->FullInstruction.Dst[0].Register.WriteMask) &&
is_unswizzled(&next->FullInstruction.Src[0], next->FullInstruction.Dst[0].Register.WriteMask) )
{
next->FullInstruction.Instruction.Opcode = TGSI_OPCODE_NOP;
set_neutral_element_swizzle(&current->FullInstruction.Src[1], 0, 0);
set_neutral_element_swizzle(&current->FullInstruction.Src[0],
next->FullInstruction.Dst[0].Register.WriteMask,
op_neutral_element(current->FullInstruction.Instruction.Opcode));
current->FullInstruction.Dst[0].Register.WriteMask = current->FullInstruction.Dst[0].Register.WriteMask |
next->FullInstruction.Dst[0].Register.WriteMask;
return;
}
if ( current->Token.Type == TGSI_TOKEN_TYPE_INSTRUCTION &&
next->Token.Type == TGSI_TOKEN_TYPE_INSTRUCTION &&
op_commutes(current->FullInstruction.Instruction.Opcode) &&
current->FullInstruction.Instruction.Saturate == next->FullInstruction.Instruction.Saturate &&
next->FullInstruction.Instruction.Opcode == TGSI_OPCODE_MOV &&
same_dst_reg(&next->FullInstruction.Dst[0], &next->FullInstruction.Dst[0]) &&
same_src_reg(&next->FullInstruction.Src[0], &current->FullInstruction.Src[0]) &&
is_unswizzled(&current->FullInstruction.Src[0], current->FullInstruction.Dst[0].Register.WriteMask) &&
is_unswizzled(&current->FullInstruction.Src[1], current->FullInstruction.Dst[0].Register.WriteMask) &&
is_unswizzled(&next->FullInstruction.Src[0], next->FullInstruction.Dst[0].Register.WriteMask) )
{
next->FullInstruction.Instruction.Opcode = TGSI_OPCODE_NOP;
set_neutral_element_swizzle(&current->FullInstruction.Src[0], 0, 0);
set_neutral_element_swizzle(&current->FullInstruction.Src[1],
next->FullInstruction.Dst[0].Register.WriteMask,
op_neutral_element(current->FullInstruction.Instruction.Opcode));
current->FullInstruction.Dst[0].Register.WriteMask = current->FullInstruction.Dst[0].Register.WriteMask |
next->FullInstruction.Dst[0].Register.WriteMask;
return;
}
}
static void copy_src_reg(struct i915_src_register* o, const struct tgsi_src_register* i)
{
o->File = i->File;
o->Indirect = i->Indirect;
o->Dimension = i->Dimension;
o->Index = i->Index;
o->SwizzleX = i->SwizzleX;
o->SwizzleY = i->SwizzleY;
o->SwizzleZ = i->SwizzleZ;
o->SwizzleW = i->SwizzleW;
o->Absolute = i->Absolute;
o->Negate = i->Negate;
}
static void copy_dst_reg(struct i915_dst_register* o, const struct tgsi_dst_register* i)
{
o->File = i->File;
o->WriteMask = i->WriteMask;
o->Indirect = i->Indirect;
o->Dimension = i->Dimension;
o->Index = i->Index;
}
static void copy_instruction(struct i915_full_instruction* o, const struct tgsi_full_instruction* i)
{
memcpy(&o->Instruction, &i->Instruction, sizeof(o->Instruction));
memcpy(&o->Texture, &i->Texture, sizeof(o->Texture));
copy_dst_reg(&o->Dst[0].Register, &i->Dst[0].Register);
copy_src_reg(&o->Src[0].Register, &i->Src[0].Register);
copy_src_reg(&o->Src[1].Register, &i->Src[1].Register);
copy_src_reg(&o->Src[2].Register, &i->Src[2].Register);
}
static void copy_token(union i915_full_token* o, union tgsi_full_token* i)
{
if (i->Token.Type != TGSI_TOKEN_TYPE_INSTRUCTION)
memcpy(o, i, sizeof(*o));
else
copy_instruction(&o->FullInstruction, &i->FullInstruction);
}
struct i915_token_list* i915_optimize(const struct tgsi_token *tokens)
{
struct i915_token_list *out_tokens = MALLOC(sizeof(struct i915_token_list));
struct tgsi_parse_context parse;
int i = 0;
out_tokens->NumTokens = 0;
/* Count the tokens */
tgsi_parse_init( &parse, tokens );
while( !tgsi_parse_end_of_tokens( &parse ) ) {
tgsi_parse_token( &parse );
out_tokens->NumTokens++;
}
tgsi_parse_free (&parse);
/* Allocate our tokens */
out_tokens->Tokens = MALLOC(sizeof(union i915_full_token) * out_tokens->NumTokens);
tgsi_parse_init( &parse, tokens );
while( !tgsi_parse_end_of_tokens( &parse ) ) {
tgsi_parse_token( &parse );
copy_token(&out_tokens->Tokens[i] , &parse.FullToken);
if (i > 0)
i915_fpc_optimize_mov_after_alu(&out_tokens->Tokens[i-1], &out_tokens->Tokens[i]);
i++;
}
tgsi_parse_free (&parse);
return out_tokens;
}
void i915_optimize_free(struct i915_token_list* tokens)
{
free(tokens->Tokens);
free(tokens);
}

View file

@ -172,7 +172,7 @@ static uint get_mapping(struct i915_fragment_shader* fs, int unit)
*/
static uint
src_vector(struct i915_fp_compile *p,
const struct tgsi_full_src_register *source,
const struct i915_full_src_register *source,
struct i915_fragment_shader* fs)
{
uint index = source->Register.Index;
@ -287,7 +287,7 @@ src_vector(struct i915_fp_compile *p,
*/
static uint
get_result_vector(struct i915_fp_compile *p,
const struct tgsi_full_dst_register *dest)
const struct i915_full_dst_register *dest)
{
switch (dest->Register.File) {
case TGSI_FILE_OUTPUT:
@ -316,7 +316,7 @@ get_result_vector(struct i915_fp_compile *p,
* Compute flags for saturation and writemask.
*/
static uint
get_result_flags(const struct tgsi_full_instruction *inst)
get_result_flags(const struct i915_full_instruction *inst)
{
const uint writeMask
= inst->Dst[0].Register.WriteMask;
@ -378,7 +378,7 @@ translate_tex_src_target(struct i915_fp_compile *p, uint tex)
*/
static void
emit_tex(struct i915_fp_compile *p,
const struct tgsi_full_instruction *inst,
const struct i915_full_instruction *inst,
uint opcode,
struct i915_fragment_shader* fs)
{
@ -404,7 +404,7 @@ emit_tex(struct i915_fp_compile *p,
*/
static void
emit_simple_arith(struct i915_fp_compile *p,
const struct tgsi_full_instruction *inst,
const struct i915_full_instruction *inst,
uint opcode, uint numArgs,
struct i915_fragment_shader* fs)
{
@ -429,11 +429,11 @@ emit_simple_arith(struct i915_fp_compile *p,
/** As above, but swap the first two src regs */
static void
emit_simple_arith_swap2(struct i915_fp_compile *p,
const struct tgsi_full_instruction *inst,
const struct i915_full_instruction *inst,
uint opcode, uint numArgs,
struct i915_fragment_shader* fs)
{
struct tgsi_full_instruction inst2;
struct i915_full_instruction inst2;
assert(numArgs == 2);
@ -450,13 +450,14 @@ emit_simple_arith_swap2(struct i915_fp_compile *p,
*
* Possible concerns:
*
* DDX, DDY -- return 0
* SIN, COS -- could use another taylor step?
* LIT -- results seem a little different to sw mesa
* LOG -- different to mesa on negative numbers, but this is conformant.
*/
static void
i915_translate_instruction(struct i915_fp_compile *p,
const struct tgsi_full_instruction *inst,
const struct i915_full_instruction *inst,
struct i915_fragment_shader *fs)
{
uint writemask;
@ -727,6 +728,9 @@ i915_translate_instruction(struct i915_fp_compile *p,
emit_simple_arith(p, inst, A0_MUL, 2, fs);
break;
case TGSI_OPCODE_NOP:
break;
case TGSI_OPCODE_POW:
src0 = src_vector(p, &inst->Src[0], fs);
src1 = src_vector(p, &inst->Src[1], fs);
@ -1043,6 +1047,93 @@ i915_translate_instruction(struct i915_fp_compile *p,
}
static void i915_translate_token(struct i915_fp_compile *p,
const union i915_full_token* token,
struct i915_fragment_shader *fs)
{
struct i915_fragment_shader *ifs = p->shader;
switch( token->Token.Type ) {
case TGSI_TOKEN_TYPE_PROPERTY:
/*
* We only support one cbuf, but we still need to ignore the property
* correctly so we don't hit the assert at the end of the switch case.
*/
assert(token->FullProperty.Property.PropertyName ==
TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS);
break;
case TGSI_TOKEN_TYPE_DECLARATION:
if (token->FullDeclaration.Declaration.File
== TGSI_FILE_CONSTANT) {
uint i;
for (i = token->FullDeclaration.Range.First;
i <= token->FullDeclaration.Range.Last;
i++) {
assert(ifs->constant_flags[i] == 0x0);
ifs->constant_flags[i] = I915_CONSTFLAG_USER;
ifs->num_constants = MAX2(ifs->num_constants, i + 1);
}
}
else if (token->FullDeclaration.Declaration.File
== TGSI_FILE_TEMPORARY) {
uint i;
for (i = token->FullDeclaration.Range.First;
i <= token->FullDeclaration.Range.Last;
i++) {
if (i >= I915_MAX_TEMPORARY)
debug_printf("Too many temps (%d)\n",i);
else
/* XXX just use shader->info->file_mask[TGSI_FILE_TEMPORARY] */
p->temp_flag |= (1 << i); /* mark temp as used */
}
}
break;
case TGSI_TOKEN_TYPE_IMMEDIATE:
{
const struct tgsi_full_immediate *imm
= &token->FullImmediate;
const uint pos = p->num_immediates++;
uint j;
assert( imm->Immediate.NrTokens <= 4 + 1 );
for (j = 0; j < imm->Immediate.NrTokens - 1; j++) {
p->immediates[pos][j] = imm->u[j].Float;
}
}
break;
case TGSI_TOKEN_TYPE_INSTRUCTION:
if (p->first_instruction) {
/* resolve location of immediates */
uint i, j;
for (i = 0; i < p->num_immediates; i++) {
/* find constant slot for this immediate */
for (j = 0; j < I915_MAX_CONSTANT; j++) {
if (ifs->constant_flags[j] == 0x0) {
memcpy(ifs->constants[j],
p->immediates[i],
4 * sizeof(float));
/*printf("immediate %d maps to const %d\n", i, j);*/
ifs->constant_flags[j] = 0xf; /* all four comps used */
p->immediates_map[i] = j;
ifs->num_constants = MAX2(ifs->num_constants, j + 1);
break;
}
}
}
p->first_instruction = FALSE;
}
i915_translate_instruction(p, &token->FullInstruction, fs);
break;
default:
assert( 0 );
}
}
/**
* Translate TGSI fragment shader into i915 hardware instructions.
* \param p the translation state
@ -1050,100 +1141,13 @@ i915_translate_instruction(struct i915_fp_compile *p,
*/
static void
i915_translate_instructions(struct i915_fp_compile *p,
const struct tgsi_token *tokens,
const struct i915_token_list *tokens,
struct i915_fragment_shader *fs)
{
struct i915_fragment_shader *ifs = p->shader;
struct tgsi_parse_context parse;
tgsi_parse_init( &parse, tokens );
while( !tgsi_parse_end_of_tokens( &parse ) ) {
tgsi_parse_token( &parse );
switch( parse.FullToken.Token.Type ) {
case TGSI_TOKEN_TYPE_PROPERTY:
/*
* We only support one cbuf, but we still need to ignore the property
* correctly so we don't hit the assert at the end of the switch case.
*/
assert(parse.FullToken.FullProperty.Property.PropertyName ==
TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS);
break;
case TGSI_TOKEN_TYPE_DECLARATION:
if (parse.FullToken.FullDeclaration.Declaration.File
== TGSI_FILE_CONSTANT) {
uint i;
for (i = parse.FullToken.FullDeclaration.Range.First;
i <= parse.FullToken.FullDeclaration.Range.Last;
i++) {
assert(ifs->constant_flags[i] == 0x0);
ifs->constant_flags[i] = I915_CONSTFLAG_USER;
ifs->num_constants = MAX2(ifs->num_constants, i + 1);
}
}
else if (parse.FullToken.FullDeclaration.Declaration.File
== TGSI_FILE_TEMPORARY) {
uint i;
for (i = parse.FullToken.FullDeclaration.Range.First;
i <= parse.FullToken.FullDeclaration.Range.Last;
i++) {
if (i >= I915_MAX_TEMPORARY)
debug_printf("Too many temps (%d)\n",i);
else
/* XXX just use shader->info->file_mask[TGSI_FILE_TEMPORARY] */
p->temp_flag |= (1 << i); /* mark temp as used */
}
}
break;
case TGSI_TOKEN_TYPE_IMMEDIATE:
{
const struct tgsi_full_immediate *imm
= &parse.FullToken.FullImmediate;
const uint pos = p->num_immediates++;
uint j;
assert( imm->Immediate.NrTokens <= 4 + 1 );
for (j = 0; j < imm->Immediate.NrTokens - 1; j++) {
p->immediates[pos][j] = imm->u[j].Float;
}
}
break;
case TGSI_TOKEN_TYPE_INSTRUCTION:
if (p->first_instruction) {
/* resolve location of immediates */
uint i, j;
for (i = 0; i < p->num_immediates; i++) {
/* find constant slot for this immediate */
for (j = 0; j < I915_MAX_CONSTANT; j++) {
if (ifs->constant_flags[j] == 0x0) {
memcpy(ifs->constants[j],
p->immediates[i],
4 * sizeof(float));
/*printf("immediate %d maps to const %d\n", i, j);*/
ifs->constant_flags[j] = 0xf; /* all four comps used */
p->immediates_map[i] = j;
ifs->num_constants = MAX2(ifs->num_constants, j + 1);
break;
}
}
}
p->first_instruction = FALSE;
}
i915_translate_instruction(p, &parse.FullToken.FullInstruction, fs);
break;
default:
assert( 0 );
}
} /* while */
tgsi_parse_free (&parse);
int i;
for(i = 0; i<tokens->NumTokens; i++) {
i915_translate_token(p, &tokens->Tokens[i], fs);
}
}
@ -1302,8 +1306,10 @@ i915_translate_fragment_program( struct i915_context *i915,
p = i915_init_compile(i915, fs);
i915_translate_instructions(p, tokens, fs);
struct i915_token_list* i_tokens = i915_optimize(tokens);
i915_translate_instructions(p, i_tokens, fs);
i915_fixup_depth_write(p);
i915_fini_compile(i915, p);
i915_optimize_free(i_tokens);
}

View file

@ -166,6 +166,8 @@ emit_prim( struct draw_stage *stage,
for (i = 0; i < nr; i++)
emit_hw_vertex(i915, prim->v[i]);
i915_flush_heuristically(i915, nr);
}

View file

@ -487,6 +487,7 @@ draw_arrays_fallback(struct vbuf_render *render,
draw_arrays_generate_indices(render, start, nr, i915_render->fallback);
i915_flush_heuristically(i915, nr_indices);
out:
return;
}
@ -534,6 +535,7 @@ i915_vbuf_render_draw_arrays(struct vbuf_render *render,
nr);
OUT_BATCH(start); /* Beginning vertex index */
i915_flush_heuristically(i915, nr);
out:
return;
}
@ -657,6 +659,7 @@ i915_vbuf_render_draw_elements(struct vbuf_render *render,
save_nr_indices,
i915_render->fallback);
i915_flush_heuristically(i915, nr_indices);
out:
return;
}

View file

@ -244,7 +244,7 @@ i915_create_sampler_state(struct pipe_context *pipe,
/* Shadow:
*/
if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE)
if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE)
{
cso->state[0] |= (SS2_SHADOW_ENABLE |
i915_translate_shadow_compare_func(sampler->compare_func));

View file

@ -346,97 +346,80 @@ emit_constants(struct i915_context *i915)
static const struct
{
enum pipe_format format;
uint hw_shift_R;
uint hw_shift_G;
uint hw_shift_B;
uint hw_shift_A;
uint hw_swizzle;
} fixup_formats[] = {
{ PIPE_FORMAT_R8G8B8A8_UNORM, 20, 24, 28, 16 /* BGRA */},
{ PIPE_FORMAT_L8_UNORM, 28, 28, 28, 16 /* RRRA */},
{ PIPE_FORMAT_I8_UNORM, 28, 28, 28, 16 /* RRRA */},
{ PIPE_FORMAT_A8_UNORM, 16, 16, 16, 16 /* AAAA */},
{ PIPE_FORMAT_NONE, 0, 0, 0, 0},
{ PIPE_FORMAT_R8G8B8A8_UNORM, 0x21030000 /* BGRA */},
{ PIPE_FORMAT_L8_UNORM, 0x00030000 /* RRRA */},
{ PIPE_FORMAT_I8_UNORM, 0x00030000 /* RRRA */},
{ PIPE_FORMAT_A8_UNORM, 0x33330000 /* AAAA */},
{ PIPE_FORMAT_NONE, 0x00000000},
};
static boolean need_fixup(struct pipe_surface* p)
static uint need_target_fixup(struct pipe_surface* p)
{
enum pipe_format f;
/* if we don't have a surface bound yet, we don't need to fixup the shader */
if (!p)
return FALSE;
return 0;
f = p->format;
for(int i=0; fixup_formats[i].format != PIPE_FORMAT_NONE; i++)
if (fixup_formats[i].format == f)
return TRUE;
return 1;
return FALSE;
return 0;
}
static uint fixup_swizzle(enum pipe_format f, uint v)
static uint fixup_swizzle(enum pipe_format f)
{
int i;
for(i=0; fixup_formats[i].format != PIPE_FORMAT_NONE; i++)
for(int i=0; fixup_formats[i].format != PIPE_FORMAT_NONE; i++)
if (fixup_formats[i].format == f)
break;
return fixup_formats[i].hw_swizzle;
if (fixup_formats[i].format == PIPE_FORMAT_NONE)
return v;
uint rgba = v & 0xFFFF0000;
v &= 0xFFFF;
v |= ((rgba >> fixup_formats[i].hw_shift_R) & 0xF) << 28;
v |= ((rgba >> fixup_formats[i].hw_shift_G) & 0xF) << 24;
v |= ((rgba >> fixup_formats[i].hw_shift_B) & 0xF) << 20;
v |= ((rgba >> fixup_formats[i].hw_shift_A) & 0xF) << 16;
return v;
return 0;
}
static void
validate_program(struct i915_context *i915, unsigned *batch_space)
{
*batch_space = i915->fs->program_len;
struct pipe_surface *cbuf_surface = i915->framebuffer.cbufs[0];
uint additional_size = need_target_fixup(cbuf_surface);
/* we need more batch space if we want to emulate rgba framebuffers */
*batch_space = i915->fs->program_len + 3 * additional_size;
}
static void
emit_program(struct i915_context *i915)
{
struct pipe_surface *cbuf_surface = i915->framebuffer.cbufs[0];
boolean need_format_fixup = need_fixup(cbuf_surface);
int i;
int fixup_offset = -1;
uint target_fixup = need_target_fixup(cbuf_surface);
uint i;
/* we should always have, at least, a pass-through program */
assert(i915->fs->program_len > 0);
if (need_format_fixup) {
/* Find where we emit the output color */
for (i = i915->fs->program_len - 3; i>0; i-=3) {
uint instr = i915->fs->program[i];
if ((instr & (REG_NR_MASK << A0_DEST_TYPE_SHIFT)) ==
(REG_TYPE_OC << A0_DEST_TYPE_SHIFT) ) {
/* Found it! */
fixup_offset = i + 1;
break;
}
}
if (fixup_offset == -1) {
need_format_fixup = FALSE;
debug_printf("couldn't find fixup offset\n");
}
{
/* first word has the size, we have to adjust that */
uint size = (i915->fs->program[0]);
size += target_fixup * 3;
OUT_BATCH(size);
}
/* emit the program to the hw */
for (i = 0; i < i915->fs->program_len; i++) {
if (need_format_fixup && (i == fixup_offset) ) {
uint v = fixup_swizzle(cbuf_surface->format, i915->fs->program[i]);
OUT_BATCH(v);
} else
OUT_BATCH(i915->fs->program[i]);
/* output the declarations of the program */
for (i=1 ; i < i915->fs->program_len; i++)
OUT_BATCH(i915->fs->program[i]);
/* we emit an additional mov with swizzle to fake RGBA framebuffers */
if (target_fixup) {
/* mov out_color, out_color.zyxw */
OUT_BATCH(A0_MOV |
(REG_TYPE_OC << A0_DEST_TYPE_SHIFT) |
A0_DEST_CHANNEL_ALL |
(REG_TYPE_OC << A0_SRC0_TYPE_SHIFT) |
(T_DIFFUSE << A0_SRC0_NR_SHIFT));
OUT_BATCH(fixup_swizzle(cbuf_surface->format));
OUT_BATCH(0);
}
}

View file

@ -207,6 +207,12 @@ struct i915_winsys {
void (*buffer_destroy)(struct i915_winsys *iws,
struct i915_winsys_buffer *buffer);
/**
* Check if a buffer is busy.
*/
boolean (*buffer_is_busy)(struct i915_winsys *iws,
struct i915_winsys_buffer *buffer);
/*@}*/

View file

@ -60,13 +60,13 @@ nv50_texture_barrier(struct pipe_context *pipe)
void
nv50_default_flush_notify(struct nouveau_channel *chan)
{
struct nv50_context *nv50 = chan->user_private;
struct nv50_screen *screen = chan->user_private;
if (!nv50)
if (!screen)
return;
nouveau_fence_update(&nv50->screen->base, TRUE);
nouveau_fence_next(&nv50->screen->base);
nouveau_fence_update(&screen->base, TRUE);
nouveau_fence_next(&screen->base);
}
static void
@ -100,10 +100,8 @@ nv50_destroy(struct pipe_context *pipe)
draw_destroy(nv50->draw);
if (nv50->screen->cur_ctx == nv50) {
nv50->screen->base.channel->user_private = NULL;
if (nv50->screen->cur_ctx == nv50)
nv50->screen->cur_ctx = NULL;
}
FREE(nv50);
}
@ -140,7 +138,6 @@ nv50_create(struct pipe_screen *pscreen, void *priv)
if (!screen->cur_ctx)
screen->cur_ctx = nv50;
screen->base.channel->user_private = nv50;
screen->base.channel->flush_notify = nv50_default_flush_notify;
nv50_init_query_functions(nv50);

View file

@ -215,6 +215,7 @@ nv50_screen_destroy(struct pipe_screen *pscreen)
nouveau_fence_wait(screen->base.fence.current);
nouveau_fence_ref (NULL, &screen->base.fence.current);
}
screen->base.channel->user_private = NULL;
nouveau_bo_ref(NULL, &screen->code);
nouveau_bo_ref(NULL, &screen->tls_bo);
@ -300,6 +301,7 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
FAIL_SCREEN_INIT("nouveau_screen_init failed: %d\n", ret);
chan = screen->base.channel;
chan->user_private = screen;
pscreen->winsys = ws;
pscreen->destroy = nv50_screen_destroy;

View file

@ -282,8 +282,7 @@ nv50_switch_pipe_context(struct nv50_context *ctx_to)
if (!ctx_to->zsa)
ctx_to->dirty &= ~NV50_NEW_ZSA;
ctx_to->screen->base.channel->user_private = ctx_to->screen->cur_ctx =
ctx_to;
ctx_to->screen->cur_ctx = ctx_to;
}
static struct state_validate {

View file

@ -34,25 +34,16 @@
#include "nv50_defs.xml.h"
#define NV50_ENG2D_SUPPORTED_FORMATS 0xff0843e080608409ULL
/* return TRUE for formats that can be converted among each other by NV50_2D */
static INLINE boolean
nv50_2d_format_faithful(enum pipe_format format)
{
switch (format) {
case PIPE_FORMAT_B8G8R8A8_UNORM:
case PIPE_FORMAT_B8G8R8X8_UNORM:
case PIPE_FORMAT_B8G8R8A8_SRGB:
case PIPE_FORMAT_B8G8R8X8_SRGB:
case PIPE_FORMAT_B5G6R5_UNORM:
case PIPE_FORMAT_B5G5R5A1_UNORM:
case PIPE_FORMAT_B10G10R10A2_UNORM:
case PIPE_FORMAT_R8_UNORM:
case PIPE_FORMAT_R32G32B32A32_FLOAT:
case PIPE_FORMAT_R32G32B32_FLOAT:
return TRUE;
default:
return FALSE;
}
uint8_t id = nv50_format_table[format].rt;
return (id >= 0xc0) &&
(NV50_ENG2D_SUPPORTED_FORMATS & (1ULL << (id - 0xc0)));
}
static INLINE uint8_t
@ -63,7 +54,7 @@ nv50_2d_format(enum pipe_format format)
/* Hardware values for color formats range from 0xc0 to 0xff,
* but the 2D engine doesn't support all of them.
*/
if ((id >= 0xc0) && (0xff0843e080608409ULL & (1ULL << (id - 0xc0))))
if ((id >= 0xc0) && (NV50_ENG2D_SUPPORTED_FORMATS & (1ULL << (id - 0xc0))))
return id;
switch (util_format_get_blocksize(format)) {

View file

@ -389,11 +389,11 @@ nv50_prim_gl(unsigned prim)
static void
nv50_draw_vbo_flush_notify(struct nouveau_channel *chan)
{
struct nv50_context *nv50 = chan->user_private;
struct nv50_screen *screen = chan->user_private;
nouveau_fence_update(&nv50->screen->base, TRUE);
nouveau_fence_update(&screen->base, TRUE);
nv50_bufctx_emit_relocs(nv50);
nv50_bufctx_emit_relocs(screen->cur_ctx);
}
static void
@ -650,7 +650,6 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
nv50_state_validate(nv50);
chan->flush_notify = nv50_draw_vbo_flush_notify;
chan->user_private = nv50;
if (nv50->vbo_fifo) {
nv50_push_vbo(nv50, info);

View file

@ -89,10 +89,8 @@ nvc0_destroy(struct pipe_context *pipe)
draw_destroy(nvc0->draw);
if (nvc0->screen->cur_ctx == nvc0) {
nvc0->screen->base.channel->user_private = NULL;
if (nvc0->screen->cur_ctx == nvc0)
nvc0->screen->cur_ctx = NULL;
}
FREE(nvc0);
}
@ -100,13 +98,13 @@ nvc0_destroy(struct pipe_context *pipe)
void
nvc0_default_flush_notify(struct nouveau_channel *chan)
{
struct nvc0_context *nvc0 = chan->user_private;
struct nvc0_screen *screen = chan->user_private;
if (!nvc0)
if (!screen)
return;
nouveau_fence_update(&nvc0->screen->base, TRUE);
nouveau_fence_next(&nvc0->screen->base);
nouveau_fence_update(&screen->base, TRUE);
nouveau_fence_next(&screen->base);
}
struct pipe_context *
@ -141,7 +139,6 @@ nvc0_create(struct pipe_screen *pscreen, void *priv)
if (!screen->cur_ctx)
screen->cur_ctx = nvc0;
screen->base.channel->user_private = nvc0;
screen->base.channel->flush_notify = nvc0_default_flush_notify;
nvc0_init_query_functions(nvc0);

View file

@ -198,8 +198,11 @@ nvc0_screen_destroy(struct pipe_screen *pscreen)
{
struct nvc0_screen *screen = nvc0_screen(pscreen);
nouveau_fence_wait(screen->base.fence.current);
nouveau_fence_ref(NULL, &screen->base.fence.current);
if (screen->base.fence.current) {
nouveau_fence_wait(screen->base.fence.current);
nouveau_fence_ref(NULL, &screen->base.fence.current);
}
screen->base.channel->user_private = NULL;
nouveau_bo_ref(NULL, &screen->text);
nouveau_bo_ref(NULL, &screen->tls);
@ -358,6 +361,7 @@ nvc0_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
return NULL;
}
chan = screen->base.channel;
chan->user_private = screen;
pscreen->winsys = ws;
pscreen->destroy = nvc0_screen_destroy;

View file

@ -428,8 +428,7 @@ nvc0_switch_pipe_context(struct nvc0_context *ctx_to)
if (!ctx_to->zsa)
ctx_to->dirty &= ~NVC0_NEW_ZSA;
ctx_to->screen->base.channel->user_private = ctx_to->screen->cur_ctx =
ctx_to;
ctx_to->screen->cur_ctx = ctx_to;
}
static struct state_validate {

View file

@ -367,11 +367,11 @@ nvc0_prim_gl(unsigned prim)
static void
nvc0_draw_vbo_flush_notify(struct nouveau_channel *chan)
{
struct nvc0_context *nvc0 = chan->user_private;
struct nvc0_screen *screen = chan->user_private;
nouveau_fence_update(&nvc0->screen->base, TRUE);
nouveau_fence_update(&screen->base, TRUE);
nvc0_bufctx_emit_relocs(nvc0);
nvc0_bufctx_emit_relocs(screen->cur_ctx);
}
static void
@ -587,7 +587,6 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
nvc0_state_validate(nvc0);
chan->flush_notify = nvc0_draw_vbo_flush_notify;
chan->user_private = nvc0;
if (nvc0->vbo_fifo) {
nvc0_push_vbo(nvc0, info);

View file

@ -69,7 +69,7 @@ int eg_bc_cf_build(struct r600_bc *bc, struct r600_bc_cf *cf)
S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_W(cf->output.swizzle_w) |
S_SQ_CF_ALLOC_EXPORT_WORD1_BARRIER(cf->output.barrier) |
S_SQ_CF_ALLOC_EXPORT_WORD1_CF_INST(cf->output.inst);
if (bc->chiprev == CHIPREV_EVERGREEN) /* no EOP on cayman */
if (bc->chip_class == EVERGREEN) /* no EOP on cayman */
bc->bytecode[id] |= S_SQ_CF_ALLOC_EXPORT_WORD1_END_OF_PROGRAM(cf->output.end_of_program);
id++;

View file

@ -1,587 +0,0 @@
/*
* Copyright 2010 Red Hat 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
* on 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
* THE AUTHOR(S) AND/OR THEIR 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 EG_STATE_INLINES_H
#define EG_STATE_INLINES_H
#include "util/u_format.h"
#include "evergreend.h"
#include "r600_formats.h"
static INLINE uint32_t r600_translate_blend_function(int blend_func)
{
switch (blend_func) {
case PIPE_BLEND_ADD:
return V_028780_COMB_DST_PLUS_SRC;
case PIPE_BLEND_SUBTRACT:
return V_028780_COMB_SRC_MINUS_DST;
case PIPE_BLEND_REVERSE_SUBTRACT:
return V_028780_COMB_DST_MINUS_SRC;
case PIPE_BLEND_MIN:
return V_028780_COMB_MIN_DST_SRC;
case PIPE_BLEND_MAX:
return V_028780_COMB_MAX_DST_SRC;
default:
R600_ERR("Unknown blend function %d\n", blend_func);
assert(0);
break;
}
return 0;
}
static INLINE uint32_t r600_translate_blend_factor(int blend_fact)
{
switch (blend_fact) {
case PIPE_BLENDFACTOR_ONE:
return V_028780_BLEND_ONE;
case PIPE_BLENDFACTOR_SRC_COLOR:
return V_028780_BLEND_SRC_COLOR;
case PIPE_BLENDFACTOR_SRC_ALPHA:
return V_028780_BLEND_SRC_ALPHA;
case PIPE_BLENDFACTOR_DST_ALPHA:
return V_028780_BLEND_DST_ALPHA;
case PIPE_BLENDFACTOR_DST_COLOR:
return V_028780_BLEND_DST_COLOR;
case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
return V_028780_BLEND_SRC_ALPHA_SATURATE;
case PIPE_BLENDFACTOR_CONST_COLOR:
return V_028780_BLEND_CONST_COLOR;
case PIPE_BLENDFACTOR_CONST_ALPHA:
return V_028780_BLEND_CONST_ALPHA;
case PIPE_BLENDFACTOR_ZERO:
return V_028780_BLEND_ZERO;
case PIPE_BLENDFACTOR_INV_SRC_COLOR:
return V_028780_BLEND_ONE_MINUS_SRC_COLOR;
case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
return V_028780_BLEND_ONE_MINUS_SRC_ALPHA;
case PIPE_BLENDFACTOR_INV_DST_ALPHA:
return V_028780_BLEND_ONE_MINUS_DST_ALPHA;
case PIPE_BLENDFACTOR_INV_DST_COLOR:
return V_028780_BLEND_ONE_MINUS_DST_COLOR;
case PIPE_BLENDFACTOR_INV_CONST_COLOR:
return V_028780_BLEND_ONE_MINUS_CONST_COLOR;
case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
return V_028780_BLEND_ONE_MINUS_CONST_ALPHA;
case PIPE_BLENDFACTOR_SRC1_COLOR:
return V_028780_BLEND_SRC1_COLOR;
case PIPE_BLENDFACTOR_SRC1_ALPHA:
return V_028780_BLEND_SRC1_ALPHA;
case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
return V_028780_BLEND_INV_SRC1_COLOR;
case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
return V_028780_BLEND_INV_SRC1_ALPHA;
default:
R600_ERR("Bad blend factor %d not supported!\n", blend_fact);
assert(0);
break;
}
return 0;
}
static INLINE uint32_t r600_translate_stencil_op(int s_op)
{
switch (s_op) {
case PIPE_STENCIL_OP_KEEP:
return V_028800_STENCIL_KEEP;
case PIPE_STENCIL_OP_ZERO:
return V_028800_STENCIL_ZERO;
case PIPE_STENCIL_OP_REPLACE:
return V_028800_STENCIL_REPLACE;
case PIPE_STENCIL_OP_INCR:
return V_028800_STENCIL_INCR;
case PIPE_STENCIL_OP_DECR:
return V_028800_STENCIL_DECR;
case PIPE_STENCIL_OP_INCR_WRAP:
return V_028800_STENCIL_INCR_WRAP;
case PIPE_STENCIL_OP_DECR_WRAP:
return V_028800_STENCIL_DECR_WRAP;
case PIPE_STENCIL_OP_INVERT:
return V_028800_STENCIL_INVERT;
default:
R600_ERR("Unknown stencil op %d", s_op);
assert(0);
break;
}
return 0;
}
static INLINE uint32_t r600_translate_fill(uint32_t func)
{
switch(func) {
case PIPE_POLYGON_MODE_FILL:
return 2;
case PIPE_POLYGON_MODE_LINE:
return 1;
case PIPE_POLYGON_MODE_POINT:
return 0;
default:
assert(0);
return 0;
}
}
/* translates straight */
static INLINE uint32_t r600_translate_ds_func(int func)
{
return func;
}
static inline unsigned r600_tex_wrap(unsigned wrap)
{
switch (wrap) {
default:
case PIPE_TEX_WRAP_REPEAT:
return V_03C000_SQ_TEX_WRAP;
case PIPE_TEX_WRAP_CLAMP:
return V_03C000_SQ_TEX_CLAMP_HALF_BORDER;
case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
return V_03C000_SQ_TEX_CLAMP_LAST_TEXEL;
case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
return V_03C000_SQ_TEX_CLAMP_BORDER;
case PIPE_TEX_WRAP_MIRROR_REPEAT:
return V_03C000_SQ_TEX_MIRROR;
case PIPE_TEX_WRAP_MIRROR_CLAMP:
return V_03C000_SQ_TEX_MIRROR_ONCE_HALF_BORDER;
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
return V_03C000_SQ_TEX_MIRROR_ONCE_LAST_TEXEL;
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
return V_03C000_SQ_TEX_MIRROR_ONCE_BORDER;
}
}
static inline unsigned r600_tex_filter(unsigned filter)
{
switch (filter) {
default:
case PIPE_TEX_FILTER_NEAREST:
return V_03C000_SQ_TEX_XY_FILTER_POINT;
case PIPE_TEX_FILTER_LINEAR:
return V_03C000_SQ_TEX_XY_FILTER_BILINEAR;
}
}
static inline unsigned r600_tex_mipfilter(unsigned filter)
{
switch (filter) {
case PIPE_TEX_MIPFILTER_NEAREST:
return V_03C000_SQ_TEX_Z_FILTER_POINT;
case PIPE_TEX_MIPFILTER_LINEAR:
return V_03C000_SQ_TEX_Z_FILTER_LINEAR;
default:
case PIPE_TEX_MIPFILTER_NONE:
return V_03C000_SQ_TEX_Z_FILTER_NONE;
}
}
static inline unsigned r600_tex_compare(unsigned compare)
{
switch (compare) {
default:
case PIPE_FUNC_NEVER:
return V_03C000_SQ_TEX_DEPTH_COMPARE_NEVER;
case PIPE_FUNC_LESS:
return V_03C000_SQ_TEX_DEPTH_COMPARE_LESS;
case PIPE_FUNC_EQUAL:
return V_03C000_SQ_TEX_DEPTH_COMPARE_EQUAL;
case PIPE_FUNC_LEQUAL:
return V_03C000_SQ_TEX_DEPTH_COMPARE_LESSEQUAL;
case PIPE_FUNC_GREATER:
return V_03C000_SQ_TEX_DEPTH_COMPARE_GREATER;
case PIPE_FUNC_NOTEQUAL:
return V_03C000_SQ_TEX_DEPTH_COMPARE_NOTEQUAL;
case PIPE_FUNC_GEQUAL:
return V_03C000_SQ_TEX_DEPTH_COMPARE_GREATEREQUAL;
case PIPE_FUNC_ALWAYS:
return V_03C000_SQ_TEX_DEPTH_COMPARE_ALWAYS;
}
}
static inline unsigned r600_tex_swizzle(unsigned swizzle)
{
switch (swizzle) {
case PIPE_SWIZZLE_RED:
return V_030010_SQ_SEL_X;
case PIPE_SWIZZLE_GREEN:
return V_030010_SQ_SEL_Y;
case PIPE_SWIZZLE_BLUE:
return V_030010_SQ_SEL_Z;
case PIPE_SWIZZLE_ALPHA:
return V_030010_SQ_SEL_W;
case PIPE_SWIZZLE_ZERO:
return V_030010_SQ_SEL_0;
default:
case PIPE_SWIZZLE_ONE:
return V_030010_SQ_SEL_1;
}
}
static inline unsigned r600_format_type(unsigned format_type)
{
switch (format_type) {
default:
case UTIL_FORMAT_TYPE_UNSIGNED:
return V_030010_SQ_FORMAT_COMP_UNSIGNED;
case UTIL_FORMAT_TYPE_SIGNED:
return V_030010_SQ_FORMAT_COMP_SIGNED;
case UTIL_FORMAT_TYPE_FIXED:
return V_030010_SQ_FORMAT_COMP_UNSIGNED_BIASED;
}
}
static inline unsigned r600_tex_dim(unsigned dim)
{
switch (dim) {
default:
case PIPE_TEXTURE_1D:
return V_030000_SQ_TEX_DIM_1D;
case PIPE_TEXTURE_1D_ARRAY:
return V_030000_SQ_TEX_DIM_1D_ARRAY;
case PIPE_TEXTURE_2D:
case PIPE_TEXTURE_RECT:
return V_030000_SQ_TEX_DIM_2D;
case PIPE_TEXTURE_2D_ARRAY:
return V_030000_SQ_TEX_DIM_2D_ARRAY;
case PIPE_TEXTURE_3D:
return V_030000_SQ_TEX_DIM_3D;
case PIPE_TEXTURE_CUBE:
return V_030000_SQ_TEX_DIM_CUBEMAP;
}
}
static inline uint32_t r600_translate_dbformat(enum pipe_format format)
{
switch (format) {
case PIPE_FORMAT_Z16_UNORM:
return V_028040_Z_16;
case PIPE_FORMAT_Z24X8_UNORM:
return V_028040_Z_24;
case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
return V_028040_Z_24;
default:
return ~0;
}
}
static inline uint32_t r600_translate_stencilformat(enum pipe_format format)
{
if (format == PIPE_FORMAT_Z24_UNORM_S8_USCALED)
return 1;
else
return 0;
}
static inline uint32_t r600_translate_colorswap(enum pipe_format format)
{
switch (format) {
/* 8-bit buffers. */
case PIPE_FORMAT_L4A4_UNORM:
return V_028C70_SWAP_ALT;
case PIPE_FORMAT_A8_UNORM:
return V_028C70_SWAP_ALT_REV;
case PIPE_FORMAT_I8_UNORM:
case PIPE_FORMAT_L8_UNORM:
case PIPE_FORMAT_L8_SRGB:
case PIPE_FORMAT_R8_UNORM:
case PIPE_FORMAT_R8_SNORM:
return V_028C70_SWAP_STD;
/* 16-bit buffers. */
case PIPE_FORMAT_B5G6R5_UNORM:
return V_028C70_SWAP_STD_REV;
case PIPE_FORMAT_B5G5R5A1_UNORM:
case PIPE_FORMAT_B5G5R5X1_UNORM:
return V_028C70_SWAP_ALT;
case PIPE_FORMAT_B4G4R4A4_UNORM:
case PIPE_FORMAT_B4G4R4X4_UNORM:
return V_028C70_SWAP_ALT;
case PIPE_FORMAT_Z16_UNORM:
return V_028C70_SWAP_STD;
case PIPE_FORMAT_L8A8_UNORM:
case PIPE_FORMAT_L8A8_SRGB:
return V_028C70_SWAP_ALT;
case PIPE_FORMAT_R8G8_UNORM:
return V_028C70_SWAP_STD;
case PIPE_FORMAT_R16_UNORM:
case PIPE_FORMAT_R16_FLOAT:
return V_028C70_SWAP_STD;
/* 32-bit buffers. */
case PIPE_FORMAT_A8B8G8R8_SRGB:
return V_028C70_SWAP_STD_REV;
case PIPE_FORMAT_B8G8R8A8_SRGB:
return V_028C70_SWAP_ALT;
case PIPE_FORMAT_B8G8R8A8_UNORM:
case PIPE_FORMAT_B8G8R8X8_UNORM:
return V_028C70_SWAP_ALT;
case PIPE_FORMAT_A8R8G8B8_UNORM:
case PIPE_FORMAT_X8R8G8B8_UNORM:
return V_028C70_SWAP_ALT_REV;
case PIPE_FORMAT_R8G8B8A8_SNORM:
case PIPE_FORMAT_R8G8B8A8_UNORM:
case PIPE_FORMAT_R8G8B8X8_UNORM:
return V_028C70_SWAP_STD;
case PIPE_FORMAT_A8B8G8R8_UNORM:
case PIPE_FORMAT_X8B8G8R8_UNORM:
/* case PIPE_FORMAT_R8SG8SB8UX8U_NORM: */
return V_028C70_SWAP_STD_REV;
case PIPE_FORMAT_Z24X8_UNORM:
case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
return V_028C70_SWAP_STD;
case PIPE_FORMAT_X8Z24_UNORM:
case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
return V_028C70_SWAP_STD;
case PIPE_FORMAT_R10G10B10A2_UNORM:
case PIPE_FORMAT_R10G10B10X2_SNORM:
case PIPE_FORMAT_R10SG10SB10SA2U_NORM:
return V_028C70_SWAP_STD;
case PIPE_FORMAT_B10G10R10A2_UNORM:
return V_028C70_SWAP_ALT;
case PIPE_FORMAT_R11G11B10_FLOAT:
case PIPE_FORMAT_R32_FLOAT:
case PIPE_FORMAT_R16G16_FLOAT:
case PIPE_FORMAT_R16G16_UNORM:
return V_028C70_SWAP_STD;
/* 64-bit buffers. */
case PIPE_FORMAT_R32G32_FLOAT:
case PIPE_FORMAT_R16G16B16A16_UNORM:
case PIPE_FORMAT_R16G16B16A16_SNORM:
case PIPE_FORMAT_R16G16B16A16_FLOAT:
/* 128-bit buffers. */
case PIPE_FORMAT_R32G32B32A32_FLOAT:
case PIPE_FORMAT_R32G32B32A32_SNORM:
case PIPE_FORMAT_R32G32B32A32_UNORM:
return V_028C70_SWAP_STD;
default:
R600_ERR("unsupported colorswap format %d\n", format);
return ~0;
}
return ~0;
}
static INLINE uint32_t r600_translate_colorformat(enum pipe_format format)
{
switch (format) {
/* 8-bit buffers. */
case PIPE_FORMAT_L4A4_UNORM:
return V_028C70_COLOR_4_4;
case PIPE_FORMAT_A8_UNORM:
case PIPE_FORMAT_I8_UNORM:
case PIPE_FORMAT_L8_UNORM:
case PIPE_FORMAT_L8_SRGB:
case PIPE_FORMAT_R8_UNORM:
case PIPE_FORMAT_R8_SNORM:
return V_028C70_COLOR_8;
/* 16-bit buffers. */
case PIPE_FORMAT_B5G6R5_UNORM:
return V_028C70_COLOR_5_6_5;
case PIPE_FORMAT_B5G5R5A1_UNORM:
case PIPE_FORMAT_B5G5R5X1_UNORM:
return V_028C70_COLOR_1_5_5_5;
case PIPE_FORMAT_B4G4R4A4_UNORM:
case PIPE_FORMAT_B4G4R4X4_UNORM:
return V_028C70_COLOR_4_4_4_4;
case PIPE_FORMAT_Z16_UNORM:
return V_028C70_COLOR_16;
case PIPE_FORMAT_L8A8_UNORM:
case PIPE_FORMAT_L8A8_SRGB:
case PIPE_FORMAT_R8G8_UNORM:
return V_028C70_COLOR_8_8;
case PIPE_FORMAT_R16_UNORM:
return V_028C70_COLOR_16;
case PIPE_FORMAT_R16_FLOAT:
return V_028C70_COLOR_16_FLOAT;
/* 32-bit buffers. */
case PIPE_FORMAT_A8B8G8R8_SRGB:
case PIPE_FORMAT_A8B8G8R8_UNORM:
case PIPE_FORMAT_A8R8G8B8_UNORM:
case PIPE_FORMAT_B8G8R8A8_SRGB:
case PIPE_FORMAT_B8G8R8A8_UNORM:
case PIPE_FORMAT_B8G8R8X8_UNORM:
case PIPE_FORMAT_R8G8B8A8_SNORM:
case PIPE_FORMAT_R8G8B8A8_UNORM:
case PIPE_FORMAT_R8G8B8X8_UNORM:
case PIPE_FORMAT_R8SG8SB8UX8U_NORM:
case PIPE_FORMAT_X8B8G8R8_UNORM:
case PIPE_FORMAT_X8R8G8B8_UNORM:
case PIPE_FORMAT_R8G8B8_UNORM:
return V_028C70_COLOR_8_8_8_8;
case PIPE_FORMAT_R10G10B10A2_UNORM:
case PIPE_FORMAT_R10G10B10X2_SNORM:
case PIPE_FORMAT_B10G10R10A2_UNORM:
case PIPE_FORMAT_R10SG10SB10SA2U_NORM:
return V_028C70_COLOR_2_10_10_10;
case PIPE_FORMAT_Z24X8_UNORM:
case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
return V_028C70_COLOR_8_24;
case PIPE_FORMAT_X8Z24_UNORM:
case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
return V_028C70_COLOR_24_8;
case PIPE_FORMAT_R32_FLOAT:
return V_028C70_COLOR_32_FLOAT;
case PIPE_FORMAT_R16G16_FLOAT:
return V_028C70_COLOR_16_16_FLOAT;
case PIPE_FORMAT_R16G16_SSCALED:
case PIPE_FORMAT_R16G16_UNORM:
return V_028C70_COLOR_16_16;
case PIPE_FORMAT_R11G11B10_FLOAT:
return V_028C70_COLOR_10_11_11_FLOAT;
/* 64-bit buffers. */
case PIPE_FORMAT_R16G16B16_USCALED:
case PIPE_FORMAT_R16G16B16A16_USCALED:
case PIPE_FORMAT_R16G16B16_SSCALED:
case PIPE_FORMAT_R16G16B16A16_SSCALED:
case PIPE_FORMAT_R16G16B16A16_UNORM:
case PIPE_FORMAT_R16G16B16A16_SNORM:
return V_028C70_COLOR_16_16_16_16;
case PIPE_FORMAT_R16G16B16_FLOAT:
case PIPE_FORMAT_R16G16B16A16_FLOAT:
return V_028C70_COLOR_16_16_16_16_FLOAT;
case PIPE_FORMAT_R32G32_FLOAT:
return V_028C70_COLOR_32_32_FLOAT;
case PIPE_FORMAT_R32G32_USCALED:
case PIPE_FORMAT_R32G32_SSCALED:
return V_028C70_COLOR_32_32;
/* 96-bit buffers. */
case PIPE_FORMAT_R32G32B32_FLOAT:
return V_028C70_COLOR_32_32_32_FLOAT;
/* 128-bit buffers. */
case PIPE_FORMAT_R32G32B32A32_SNORM:
case PIPE_FORMAT_R32G32B32A32_UNORM:
return V_028C70_COLOR_32_32_32_32;
case PIPE_FORMAT_R32G32B32A32_FLOAT:
return V_028C70_COLOR_32_32_32_32_FLOAT;
/* YUV buffers. */
case PIPE_FORMAT_UYVY:
case PIPE_FORMAT_YUYV:
default:
return ~0; /* Unsupported. */
}
}
static INLINE uint32_t r600_colorformat_endian_swap(uint32_t colorformat)
{
if (R600_BIG_ENDIAN) {
switch(colorformat) {
case V_028C70_COLOR_4_4:
return(ENDIAN_NONE);
/* 8-bit buffers. */
case V_028C70_COLOR_8:
return(ENDIAN_NONE);
/* 16-bit buffers. */
case V_028C70_COLOR_5_6_5:
case V_028C70_COLOR_1_5_5_5:
case V_028C70_COLOR_4_4_4_4:
case V_028C70_COLOR_16:
case V_028C70_COLOR_8_8:
return(ENDIAN_8IN16);
/* 32-bit buffers. */
case V_028C70_COLOR_8_8_8_8:
case V_028C70_COLOR_2_10_10_10:
case V_028C70_COLOR_8_24:
case V_028C70_COLOR_24_8:
case V_028C70_COLOR_32_FLOAT:
case V_028C70_COLOR_16_16_FLOAT:
case V_028C70_COLOR_16_16:
return(ENDIAN_8IN32);
/* 64-bit buffers. */
case V_028C70_COLOR_16_16_16_16:
case V_028C70_COLOR_16_16_16_16_FLOAT:
return(ENDIAN_8IN16);
case V_028C70_COLOR_32_32_FLOAT:
case V_028C70_COLOR_32_32:
return(ENDIAN_8IN32);
/* 96-bit buffers. */
case V_028C70_COLOR_32_32_32_FLOAT:
/* 128-bit buffers. */
case V_028C70_COLOR_32_32_32_32_FLOAT:
case V_028C70_COLOR_32_32_32_32:
return(ENDIAN_8IN32);
default:
return ENDIAN_NONE; /* Unsupported. */
}
} else {
return ENDIAN_NONE;
}
}
static INLINE boolean r600_is_sampler_format_supported(struct pipe_screen *screen, enum pipe_format format)
{
return r600_translate_texformat(screen, format, NULL, NULL, NULL) != ~0;
}
static INLINE boolean r600_is_colorbuffer_format_supported(enum pipe_format format)
{
return r600_translate_colorformat(format) != ~0 &&
r600_translate_colorswap(format) != ~0;
}
static INLINE boolean r600_is_zs_format_supported(enum pipe_format format)
{
return r600_translate_dbformat(format) != ~0;
}
#endif

View file

@ -46,7 +46,587 @@
#include "r600_resource.h"
#include "r600_shader.h"
#include "r600_pipe.h"
#include "eg_state_inlines.h"
#include "r600_formats.h"
static uint32_t r600_translate_blend_function(int blend_func)
{
switch (blend_func) {
case PIPE_BLEND_ADD:
return V_028780_COMB_DST_PLUS_SRC;
case PIPE_BLEND_SUBTRACT:
return V_028780_COMB_SRC_MINUS_DST;
case PIPE_BLEND_REVERSE_SUBTRACT:
return V_028780_COMB_DST_MINUS_SRC;
case PIPE_BLEND_MIN:
return V_028780_COMB_MIN_DST_SRC;
case PIPE_BLEND_MAX:
return V_028780_COMB_MAX_DST_SRC;
default:
R600_ERR("Unknown blend function %d\n", blend_func);
assert(0);
break;
}
return 0;
}
static uint32_t r600_translate_blend_factor(int blend_fact)
{
switch (blend_fact) {
case PIPE_BLENDFACTOR_ONE:
return V_028780_BLEND_ONE;
case PIPE_BLENDFACTOR_SRC_COLOR:
return V_028780_BLEND_SRC_COLOR;
case PIPE_BLENDFACTOR_SRC_ALPHA:
return V_028780_BLEND_SRC_ALPHA;
case PIPE_BLENDFACTOR_DST_ALPHA:
return V_028780_BLEND_DST_ALPHA;
case PIPE_BLENDFACTOR_DST_COLOR:
return V_028780_BLEND_DST_COLOR;
case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
return V_028780_BLEND_SRC_ALPHA_SATURATE;
case PIPE_BLENDFACTOR_CONST_COLOR:
return V_028780_BLEND_CONST_COLOR;
case PIPE_BLENDFACTOR_CONST_ALPHA:
return V_028780_BLEND_CONST_ALPHA;
case PIPE_BLENDFACTOR_ZERO:
return V_028780_BLEND_ZERO;
case PIPE_BLENDFACTOR_INV_SRC_COLOR:
return V_028780_BLEND_ONE_MINUS_SRC_COLOR;
case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
return V_028780_BLEND_ONE_MINUS_SRC_ALPHA;
case PIPE_BLENDFACTOR_INV_DST_ALPHA:
return V_028780_BLEND_ONE_MINUS_DST_ALPHA;
case PIPE_BLENDFACTOR_INV_DST_COLOR:
return V_028780_BLEND_ONE_MINUS_DST_COLOR;
case PIPE_BLENDFACTOR_INV_CONST_COLOR:
return V_028780_BLEND_ONE_MINUS_CONST_COLOR;
case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
return V_028780_BLEND_ONE_MINUS_CONST_ALPHA;
case PIPE_BLENDFACTOR_SRC1_COLOR:
return V_028780_BLEND_SRC1_COLOR;
case PIPE_BLENDFACTOR_SRC1_ALPHA:
return V_028780_BLEND_SRC1_ALPHA;
case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
return V_028780_BLEND_INV_SRC1_COLOR;
case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
return V_028780_BLEND_INV_SRC1_ALPHA;
default:
R600_ERR("Bad blend factor %d not supported!\n", blend_fact);
assert(0);
break;
}
return 0;
}
static uint32_t r600_translate_stencil_op(int s_op)
{
switch (s_op) {
case PIPE_STENCIL_OP_KEEP:
return V_028800_STENCIL_KEEP;
case PIPE_STENCIL_OP_ZERO:
return V_028800_STENCIL_ZERO;
case PIPE_STENCIL_OP_REPLACE:
return V_028800_STENCIL_REPLACE;
case PIPE_STENCIL_OP_INCR:
return V_028800_STENCIL_INCR;
case PIPE_STENCIL_OP_DECR:
return V_028800_STENCIL_DECR;
case PIPE_STENCIL_OP_INCR_WRAP:
return V_028800_STENCIL_INCR_WRAP;
case PIPE_STENCIL_OP_DECR_WRAP:
return V_028800_STENCIL_DECR_WRAP;
case PIPE_STENCIL_OP_INVERT:
return V_028800_STENCIL_INVERT;
default:
R600_ERR("Unknown stencil op %d", s_op);
assert(0);
break;
}
return 0;
}
static uint32_t r600_translate_fill(uint32_t func)
{
switch(func) {
case PIPE_POLYGON_MODE_FILL:
return 2;
case PIPE_POLYGON_MODE_LINE:
return 1;
case PIPE_POLYGON_MODE_POINT:
return 0;
default:
assert(0);
return 0;
}
}
/* translates straight */
static uint32_t r600_translate_ds_func(int func)
{
return func;
}
static unsigned r600_tex_wrap(unsigned wrap)
{
switch (wrap) {
default:
case PIPE_TEX_WRAP_REPEAT:
return V_03C000_SQ_TEX_WRAP;
case PIPE_TEX_WRAP_CLAMP:
return V_03C000_SQ_TEX_CLAMP_HALF_BORDER;
case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
return V_03C000_SQ_TEX_CLAMP_LAST_TEXEL;
case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
return V_03C000_SQ_TEX_CLAMP_BORDER;
case PIPE_TEX_WRAP_MIRROR_REPEAT:
return V_03C000_SQ_TEX_MIRROR;
case PIPE_TEX_WRAP_MIRROR_CLAMP:
return V_03C000_SQ_TEX_MIRROR_ONCE_HALF_BORDER;
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
return V_03C000_SQ_TEX_MIRROR_ONCE_LAST_TEXEL;
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
return V_03C000_SQ_TEX_MIRROR_ONCE_BORDER;
}
}
static unsigned r600_tex_filter(unsigned filter)
{
switch (filter) {
default:
case PIPE_TEX_FILTER_NEAREST:
return V_03C000_SQ_TEX_XY_FILTER_POINT;
case PIPE_TEX_FILTER_LINEAR:
return V_03C000_SQ_TEX_XY_FILTER_BILINEAR;
}
}
static unsigned r600_tex_mipfilter(unsigned filter)
{
switch (filter) {
case PIPE_TEX_MIPFILTER_NEAREST:
return V_03C000_SQ_TEX_Z_FILTER_POINT;
case PIPE_TEX_MIPFILTER_LINEAR:
return V_03C000_SQ_TEX_Z_FILTER_LINEAR;
default:
case PIPE_TEX_MIPFILTER_NONE:
return V_03C000_SQ_TEX_Z_FILTER_NONE;
}
}
static unsigned r600_tex_compare(unsigned compare)
{
switch (compare) {
default:
case PIPE_FUNC_NEVER:
return V_03C000_SQ_TEX_DEPTH_COMPARE_NEVER;
case PIPE_FUNC_LESS:
return V_03C000_SQ_TEX_DEPTH_COMPARE_LESS;
case PIPE_FUNC_EQUAL:
return V_03C000_SQ_TEX_DEPTH_COMPARE_EQUAL;
case PIPE_FUNC_LEQUAL:
return V_03C000_SQ_TEX_DEPTH_COMPARE_LESSEQUAL;
case PIPE_FUNC_GREATER:
return V_03C000_SQ_TEX_DEPTH_COMPARE_GREATER;
case PIPE_FUNC_NOTEQUAL:
return V_03C000_SQ_TEX_DEPTH_COMPARE_NOTEQUAL;
case PIPE_FUNC_GEQUAL:
return V_03C000_SQ_TEX_DEPTH_COMPARE_GREATEREQUAL;
case PIPE_FUNC_ALWAYS:
return V_03C000_SQ_TEX_DEPTH_COMPARE_ALWAYS;
}
}
static unsigned r600_tex_dim(unsigned dim)
{
switch (dim) {
default:
case PIPE_TEXTURE_1D:
return V_030000_SQ_TEX_DIM_1D;
case PIPE_TEXTURE_1D_ARRAY:
return V_030000_SQ_TEX_DIM_1D_ARRAY;
case PIPE_TEXTURE_2D:
case PIPE_TEXTURE_RECT:
return V_030000_SQ_TEX_DIM_2D;
case PIPE_TEXTURE_2D_ARRAY:
return V_030000_SQ_TEX_DIM_2D_ARRAY;
case PIPE_TEXTURE_3D:
return V_030000_SQ_TEX_DIM_3D;
case PIPE_TEXTURE_CUBE:
return V_030000_SQ_TEX_DIM_CUBEMAP;
}
}
static uint32_t r600_translate_dbformat(enum pipe_format format)
{
switch (format) {
case PIPE_FORMAT_Z16_UNORM:
return V_028040_Z_16;
case PIPE_FORMAT_Z24X8_UNORM:
return V_028040_Z_24;
case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
return V_028040_Z_24;
default:
return ~0U;
}
}
static uint32_t r600_translate_stencilformat(enum pipe_format format)
{
if (format == PIPE_FORMAT_Z24_UNORM_S8_USCALED)
return 1;
else
return 0;
}
static uint32_t r600_translate_colorswap(enum pipe_format format)
{
switch (format) {
/* 8-bit buffers. */
case PIPE_FORMAT_L4A4_UNORM:
return V_028C70_SWAP_ALT;
case PIPE_FORMAT_A8_UNORM:
return V_028C70_SWAP_ALT_REV;
case PIPE_FORMAT_I8_UNORM:
case PIPE_FORMAT_L8_UNORM:
case PIPE_FORMAT_L8_SRGB:
case PIPE_FORMAT_R8_UNORM:
case PIPE_FORMAT_R8_SNORM:
return V_028C70_SWAP_STD;
/* 16-bit buffers. */
case PIPE_FORMAT_B5G6R5_UNORM:
return V_028C70_SWAP_STD_REV;
case PIPE_FORMAT_B5G5R5A1_UNORM:
case PIPE_FORMAT_B5G5R5X1_UNORM:
return V_028C70_SWAP_ALT;
case PIPE_FORMAT_B4G4R4A4_UNORM:
case PIPE_FORMAT_B4G4R4X4_UNORM:
return V_028C70_SWAP_ALT;
case PIPE_FORMAT_Z16_UNORM:
return V_028C70_SWAP_STD;
case PIPE_FORMAT_L8A8_UNORM:
case PIPE_FORMAT_L8A8_SRGB:
return V_028C70_SWAP_ALT;
case PIPE_FORMAT_R8G8_UNORM:
return V_028C70_SWAP_STD;
case PIPE_FORMAT_R16_UNORM:
case PIPE_FORMAT_R16_FLOAT:
return V_028C70_SWAP_STD;
/* 32-bit buffers. */
case PIPE_FORMAT_A8B8G8R8_SRGB:
return V_028C70_SWAP_STD_REV;
case PIPE_FORMAT_B8G8R8A8_SRGB:
return V_028C70_SWAP_ALT;
case PIPE_FORMAT_B8G8R8A8_UNORM:
case PIPE_FORMAT_B8G8R8X8_UNORM:
return V_028C70_SWAP_ALT;
case PIPE_FORMAT_A8R8G8B8_UNORM:
case PIPE_FORMAT_X8R8G8B8_UNORM:
return V_028C70_SWAP_ALT_REV;
case PIPE_FORMAT_R8G8B8A8_SNORM:
case PIPE_FORMAT_R8G8B8A8_UNORM:
case PIPE_FORMAT_R8G8B8X8_UNORM:
return V_028C70_SWAP_STD;
case PIPE_FORMAT_A8B8G8R8_UNORM:
case PIPE_FORMAT_X8B8G8R8_UNORM:
/* case PIPE_FORMAT_R8SG8SB8UX8U_NORM: */
return V_028C70_SWAP_STD_REV;
case PIPE_FORMAT_Z24X8_UNORM:
case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
return V_028C70_SWAP_STD;
case PIPE_FORMAT_X8Z24_UNORM:
case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
return V_028C70_SWAP_STD;
case PIPE_FORMAT_R10G10B10A2_UNORM:
case PIPE_FORMAT_R10G10B10X2_SNORM:
case PIPE_FORMAT_R10SG10SB10SA2U_NORM:
return V_028C70_SWAP_STD;
case PIPE_FORMAT_B10G10R10A2_UNORM:
return V_028C70_SWAP_ALT;
case PIPE_FORMAT_R11G11B10_FLOAT:
case PIPE_FORMAT_R32_FLOAT:
case PIPE_FORMAT_R16G16_FLOAT:
case PIPE_FORMAT_R16G16_UNORM:
return V_028C70_SWAP_STD;
/* 64-bit buffers. */
case PIPE_FORMAT_R32G32_FLOAT:
case PIPE_FORMAT_R16G16B16A16_UNORM:
case PIPE_FORMAT_R16G16B16A16_SNORM:
case PIPE_FORMAT_R16G16B16A16_FLOAT:
/* 128-bit buffers. */
case PIPE_FORMAT_R32G32B32A32_FLOAT:
case PIPE_FORMAT_R32G32B32A32_SNORM:
case PIPE_FORMAT_R32G32B32A32_UNORM:
return V_028C70_SWAP_STD;
default:
R600_ERR("unsupported colorswap format %d\n", format);
return ~0U;
}
return ~0U;
}
static uint32_t r600_translate_colorformat(enum pipe_format format)
{
switch (format) {
/* 8-bit buffers. */
case PIPE_FORMAT_L4A4_UNORM:
return V_028C70_COLOR_4_4;
case PIPE_FORMAT_A8_UNORM:
case PIPE_FORMAT_I8_UNORM:
case PIPE_FORMAT_L8_UNORM:
case PIPE_FORMAT_L8_SRGB:
case PIPE_FORMAT_R8_UNORM:
case PIPE_FORMAT_R8_SNORM:
return V_028C70_COLOR_8;
/* 16-bit buffers. */
case PIPE_FORMAT_B5G6R5_UNORM:
return V_028C70_COLOR_5_6_5;
case PIPE_FORMAT_B5G5R5A1_UNORM:
case PIPE_FORMAT_B5G5R5X1_UNORM:
return V_028C70_COLOR_1_5_5_5;
case PIPE_FORMAT_B4G4R4A4_UNORM:
case PIPE_FORMAT_B4G4R4X4_UNORM:
return V_028C70_COLOR_4_4_4_4;
case PIPE_FORMAT_Z16_UNORM:
return V_028C70_COLOR_16;
case PIPE_FORMAT_L8A8_UNORM:
case PIPE_FORMAT_L8A8_SRGB:
case PIPE_FORMAT_R8G8_UNORM:
return V_028C70_COLOR_8_8;
case PIPE_FORMAT_R16_UNORM:
return V_028C70_COLOR_16;
case PIPE_FORMAT_R16_FLOAT:
return V_028C70_COLOR_16_FLOAT;
/* 32-bit buffers. */
case PIPE_FORMAT_A8B8G8R8_SRGB:
case PIPE_FORMAT_A8B8G8R8_UNORM:
case PIPE_FORMAT_A8R8G8B8_UNORM:
case PIPE_FORMAT_B8G8R8A8_SRGB:
case PIPE_FORMAT_B8G8R8A8_UNORM:
case PIPE_FORMAT_B8G8R8X8_UNORM:
case PIPE_FORMAT_R8G8B8A8_SNORM:
case PIPE_FORMAT_R8G8B8A8_UNORM:
case PIPE_FORMAT_R8G8B8X8_UNORM:
case PIPE_FORMAT_R8SG8SB8UX8U_NORM:
case PIPE_FORMAT_X8B8G8R8_UNORM:
case PIPE_FORMAT_X8R8G8B8_UNORM:
case PIPE_FORMAT_R8G8B8_UNORM:
return V_028C70_COLOR_8_8_8_8;
case PIPE_FORMAT_R10G10B10A2_UNORM:
case PIPE_FORMAT_R10G10B10X2_SNORM:
case PIPE_FORMAT_B10G10R10A2_UNORM:
case PIPE_FORMAT_R10SG10SB10SA2U_NORM:
return V_028C70_COLOR_2_10_10_10;
case PIPE_FORMAT_Z24X8_UNORM:
case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
return V_028C70_COLOR_8_24;
case PIPE_FORMAT_X8Z24_UNORM:
case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
return V_028C70_COLOR_24_8;
case PIPE_FORMAT_R32_FLOAT:
return V_028C70_COLOR_32_FLOAT;
case PIPE_FORMAT_R16G16_FLOAT:
return V_028C70_COLOR_16_16_FLOAT;
case PIPE_FORMAT_R16G16_SSCALED:
case PIPE_FORMAT_R16G16_UNORM:
return V_028C70_COLOR_16_16;
case PIPE_FORMAT_R11G11B10_FLOAT:
return V_028C70_COLOR_10_11_11_FLOAT;
/* 64-bit buffers. */
case PIPE_FORMAT_R16G16B16_USCALED:
case PIPE_FORMAT_R16G16B16A16_USCALED:
case PIPE_FORMAT_R16G16B16_SSCALED:
case PIPE_FORMAT_R16G16B16A16_SSCALED:
case PIPE_FORMAT_R16G16B16A16_UNORM:
case PIPE_FORMAT_R16G16B16A16_SNORM:
return V_028C70_COLOR_16_16_16_16;
case PIPE_FORMAT_R16G16B16_FLOAT:
case PIPE_FORMAT_R16G16B16A16_FLOAT:
return V_028C70_COLOR_16_16_16_16_FLOAT;
case PIPE_FORMAT_R32G32_FLOAT:
return V_028C70_COLOR_32_32_FLOAT;
case PIPE_FORMAT_R32G32_USCALED:
case PIPE_FORMAT_R32G32_SSCALED:
return V_028C70_COLOR_32_32;
/* 96-bit buffers. */
case PIPE_FORMAT_R32G32B32_FLOAT:
return V_028C70_COLOR_32_32_32_FLOAT;
/* 128-bit buffers. */
case PIPE_FORMAT_R32G32B32A32_SNORM:
case PIPE_FORMAT_R32G32B32A32_UNORM:
return V_028C70_COLOR_32_32_32_32;
case PIPE_FORMAT_R32G32B32A32_FLOAT:
return V_028C70_COLOR_32_32_32_32_FLOAT;
/* YUV buffers. */
case PIPE_FORMAT_UYVY:
case PIPE_FORMAT_YUYV:
default:
return ~0U; /* Unsupported. */
}
}
static uint32_t r600_colorformat_endian_swap(uint32_t colorformat)
{
if (R600_BIG_ENDIAN) {
switch(colorformat) {
case V_028C70_COLOR_4_4:
return ENDIAN_NONE;
/* 8-bit buffers. */
case V_028C70_COLOR_8:
return ENDIAN_NONE;
/* 16-bit buffers. */
case V_028C70_COLOR_5_6_5:
case V_028C70_COLOR_1_5_5_5:
case V_028C70_COLOR_4_4_4_4:
case V_028C70_COLOR_16:
case V_028C70_COLOR_8_8:
return ENDIAN_8IN16;
/* 32-bit buffers. */
case V_028C70_COLOR_8_8_8_8:
case V_028C70_COLOR_2_10_10_10:
case V_028C70_COLOR_8_24:
case V_028C70_COLOR_24_8:
case V_028C70_COLOR_32_FLOAT:
case V_028C70_COLOR_16_16_FLOAT:
case V_028C70_COLOR_16_16:
return ENDIAN_8IN32;
/* 64-bit buffers. */
case V_028C70_COLOR_16_16_16_16:
case V_028C70_COLOR_16_16_16_16_FLOAT:
return ENDIAN_8IN16;
case V_028C70_COLOR_32_32_FLOAT:
case V_028C70_COLOR_32_32:
return ENDIAN_8IN32;
/* 96-bit buffers. */
case V_028C70_COLOR_32_32_32_FLOAT:
/* 128-bit buffers. */
case V_028C70_COLOR_32_32_32_32_FLOAT:
case V_028C70_COLOR_32_32_32_32:
return ENDIAN_8IN32;
default:
return ENDIAN_NONE; /* Unsupported. */
}
} else {
return ENDIAN_NONE;
}
}
static bool r600_is_sampler_format_supported(struct pipe_screen *screen, enum pipe_format format)
{
return r600_translate_texformat(screen, format, NULL, NULL, NULL) != ~0U;
}
static bool r600_is_colorbuffer_format_supported(enum pipe_format format)
{
return r600_translate_colorformat(format) != ~0U &&
r600_translate_colorswap(format) != ~0U;
}
static bool r600_is_zs_format_supported(enum pipe_format format)
{
return r600_translate_dbformat(format) != ~0U;
}
boolean evergreen_is_format_supported(struct pipe_screen *screen,
enum pipe_format format,
enum pipe_texture_target target,
unsigned sample_count,
unsigned usage)
{
unsigned retval = 0;
if (target >= PIPE_MAX_TEXTURE_TYPES) {
R600_ERR("r600: unsupported texture type %d\n", target);
return FALSE;
}
if (!util_format_is_supported(format, usage))
return FALSE;
/* Multisample */
if (sample_count > 1)
return FALSE;
if ((usage & PIPE_BIND_SAMPLER_VIEW) &&
r600_is_sampler_format_supported(screen, format)) {
retval |= PIPE_BIND_SAMPLER_VIEW;
}
if ((usage & (PIPE_BIND_RENDER_TARGET |
PIPE_BIND_DISPLAY_TARGET |
PIPE_BIND_SCANOUT |
PIPE_BIND_SHARED)) &&
r600_is_colorbuffer_format_supported(format)) {
retval |= usage &
(PIPE_BIND_RENDER_TARGET |
PIPE_BIND_DISPLAY_TARGET |
PIPE_BIND_SCANOUT |
PIPE_BIND_SHARED);
}
if ((usage & PIPE_BIND_DEPTH_STENCIL) &&
r600_is_zs_format_supported(format)) {
retval |= PIPE_BIND_DEPTH_STENCIL;
}
if ((usage & PIPE_BIND_VERTEX_BUFFER) &&
r600_is_vertex_format_supported(format)) {
retval |= PIPE_BIND_VERTEX_BUFFER;
}
if (usage & PIPE_BIND_TRANSFER_READ)
retval |= PIPE_BIND_TRANSFER_READ;
if (usage & PIPE_BIND_TRANSFER_WRITE)
retval |= PIPE_BIND_TRANSFER_WRITE;
return retval == usage;
}
static void evergreen_set_blend_color(struct pipe_context *ctx,
const struct pipe_blend_color *state)
@ -77,13 +657,11 @@ static void *evergreen_create_blend_state(struct pipe_context *ctx,
u32 color_control, target_mask;
/* FIXME there is more then 8 framebuffer */
unsigned blend_cntl[8];
enum radeon_family family;
if (blend == NULL) {
return NULL;
}
family = r600_get_family(rctx->radeon);
rstate = &blend->rstate;
rstate->id = R600_PIPE_STATE_BLEND;
@ -110,7 +688,7 @@ static void *evergreen_create_blend_state(struct pipe_context *ctx,
r600_pipe_state_add_reg(rstate, R_028808_CB_COLOR_CONTROL,
color_control, 0xFFFFFFFD, NULL);
if (family != CHIP_CAYMAN)
if (rctx->chip_class != CAYMAN)
r600_pipe_state_add_reg(rstate, R_028C3C_PA_SC_AA_MASK, 0xFFFFFFFF, 0xFFFFFFFF, NULL);
else {
r600_pipe_state_add_reg(rstate, CM_R_028C38_PA_SC_AA_MASK_X0Y0_X1Y0, 0xFFFFFFFF, 0xFFFFFFFF, NULL);
@ -247,9 +825,6 @@ static void *evergreen_create_rs_state(struct pipe_context *ctx,
unsigned tmp;
unsigned prov_vtx = 1, polygon_dual_mode;
unsigned clip_rule;
enum radeon_family family;
family = r600_get_family(rctx->radeon);
if (rs == NULL) {
return NULL;
@ -308,7 +883,7 @@ static void *evergreen_create_rs_state(struct pipe_context *ctx,
tmp = (unsigned)state->line_width * 8;
r600_pipe_state_add_reg(rstate, R_028A08_PA_SU_LINE_CNTL, S_028A08_WIDTH(tmp), 0xFFFFFFFF, NULL);
if (family == CHIP_CAYMAN) {
if (rctx->chip_class == CAYMAN) {
r600_pipe_state_add_reg(rstate, CM_R_028BDC_PA_SC_LINE_CNTL, 0x00000400, 0xFFFFFFFF, NULL);
r600_pipe_state_add_reg(rstate, CM_R_028BE4_PA_SU_VTX_CNTL,
S_028C08_PIX_CENTER_HALF(state->gl_rasterization_rules),
@ -867,14 +1442,11 @@ static void evergreen_set_framebuffer_state(struct pipe_context *ctx,
struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state);
u32 shader_mask, tl, br, target_mask;
enum radeon_family family;
int tl_x, tl_y, br_x, br_y;
if (rstate == NULL)
return;
family = r600_get_family(rctx->radeon);
evergreen_context_flush_dest_caches(&rctx->ctx);
rctx->ctx.num_dest_buffers = state->nr_cbufs;
@ -911,7 +1483,7 @@ static void evergreen_set_framebuffer_state(struct pipe_context *ctx,
if (br_y == 0)
tl_y = 1;
/* cayman hw workaround */
if (family == CHIP_CAYMAN) {
if (rctx->chip_class == CAYMAN) {
if (br_x == 1 && br_y == 1)
br_x = 2;
}
@ -955,7 +1527,7 @@ static void evergreen_set_framebuffer_state(struct pipe_context *ctx,
shader_mask, 0xFFFFFFFF, NULL);
if (family == CHIP_CAYMAN) {
if (rctx->chip_class == CAYMAN) {
r600_pipe_state_add_reg(rstate, CM_R_028BE0_PA_SC_AA_CONFIG,
0x00000000, 0xFFFFFFFF, NULL);
} else {
@ -1142,9 +1714,9 @@ void evergreen_init_config(struct r600_pipe_context *rctx)
enum radeon_family family;
unsigned tmp;
family = r600_get_family(rctx->radeon);
family = rctx->family;
if (family == CHIP_CAYMAN) {
if (rctx->chip_class == CAYMAN) {
cayman_init_config(rctx);
return;
}

View file

@ -228,6 +228,7 @@ struct r600_query {
#define R600_QUERY_STATE_STARTED (1 << 0)
#define R600_QUERY_STATE_ENDED (1 << 1)
#define R600_QUERY_STATE_SUSPENDED (1 << 2)
#define R600_QUERY_STATE_FLUSHED (1 << 3)
#define R600_CONTEXT_DRAW_PENDING (1 << 0)
#define R600_CONTEXT_DST_CACHES_DIRTY (1 << 1)
@ -294,7 +295,7 @@ boolean r600_context_query_result(struct r600_context *ctx,
void r600_query_begin(struct r600_context *ctx, struct r600_query *query);
void r600_query_end(struct r600_context *ctx, struct r600_query *query);
void r600_context_queries_suspend(struct r600_context *ctx);
void r600_context_queries_resume(struct r600_context *ctx);
void r600_context_queries_resume(struct r600_context *ctx, boolean flushed);
void r600_query_predication(struct r600_context *ctx, struct r600_query *query, int operation,
int flag_wait);
void r600_context_emit_fence(struct r600_context *ctx, struct r600_bo *fence,

View file

@ -41,9 +41,9 @@ static inline unsigned int r600_bc_get_num_operands(struct r600_bc *bc, struct r
if(alu->is_op3)
return 3;
switch (bc->chiprev) {
case CHIPREV_R600:
case CHIPREV_R700:
switch (bc->chip_class) {
case R600:
case R700:
switch (alu->inst) {
case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP:
return 0;
@ -93,8 +93,8 @@ static inline unsigned int r600_bc_get_num_operands(struct r600_bc *bc, struct r
"Need instruction operand number for 0x%x.\n", alu->inst);
}
break;
case CHIPREV_EVERGREEN:
case CHIPREV_CAYMAN:
case EVERGREEN:
case CAYMAN:
switch (alu->inst) {
case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP:
return 0;
@ -195,48 +195,10 @@ static struct r600_bc_tex *r600_bc_tex(void)
return tex;
}
int r600_bc_init(struct r600_bc *bc, enum radeon_family family)
void r600_bc_init(struct r600_bc *bc, enum chip_class chip_class)
{
LIST_INITHEAD(&bc->cf);
bc->family = family;
switch (bc->family) {
case CHIP_R600:
case CHIP_RV610:
case CHIP_RV630:
case CHIP_RV670:
case CHIP_RV620:
case CHIP_RV635:
case CHIP_RS780:
case CHIP_RS880:
bc->chiprev = CHIPREV_R600;
break;
case CHIP_RV770:
case CHIP_RV730:
case CHIP_RV710:
case CHIP_RV740:
bc->chiprev = CHIPREV_R700;
break;
case CHIP_CEDAR:
case CHIP_REDWOOD:
case CHIP_JUNIPER:
case CHIP_CYPRESS:
case CHIP_HEMLOCK:
case CHIP_PALM:
case CHIP_SUMO:
case CHIP_SUMO2:
case CHIP_BARTS:
case CHIP_TURKS:
case CHIP_CAICOS:
bc->chiprev = CHIPREV_EVERGREEN;
break;
case CHIP_CAYMAN:
bc->chiprev = CHIPREV_CAYMAN;
break;
default:
R600_ERR("unknown family %d\n", bc->family);
return -EINVAL;
}
return 0;
bc->chip_class = chip_class;
}
static int r600_bc_add_cf(struct r600_bc *bc)
@ -301,9 +263,9 @@ int r600_bc_add_output(struct r600_bc *bc, const struct r600_bc_output *output)
/* alu instructions that can ony exits once per group */
static int is_alu_once_inst(struct r600_bc *bc, struct r600_bc_alu *alu)
{
switch (bc->chiprev) {
case CHIPREV_R600:
case CHIPREV_R700:
switch (bc->chip_class) {
case R600:
case R700:
return !alu->is_op3 && (
alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLE ||
alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT ||
@ -339,8 +301,8 @@ static int is_alu_once_inst(struct r600_bc *bc, struct r600_bc_alu *alu)
alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE_PUSH_INT ||
alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETLT_PUSH_INT ||
alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETLE_PUSH_INT);
case CHIPREV_EVERGREEN:
case CHIPREV_CAYMAN:
case EVERGREEN:
case CAYMAN:
default:
return !alu->is_op3 && (
alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLE ||
@ -382,16 +344,16 @@ static int is_alu_once_inst(struct r600_bc *bc, struct r600_bc_alu *alu)
static int is_alu_reduction_inst(struct r600_bc *bc, struct r600_bc_alu *alu)
{
switch (bc->chiprev) {
case CHIPREV_R600:
case CHIPREV_R700:
switch (bc->chip_class) {
case R600:
case R700:
return !alu->is_op3 && (
alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_CUBE ||
alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4 ||
alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4_IEEE ||
alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX4);
case CHIPREV_EVERGREEN:
case CHIPREV_CAYMAN:
case EVERGREEN:
case CAYMAN:
default:
return !alu->is_op3 && (
alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_CUBE ||
@ -403,13 +365,13 @@ static int is_alu_reduction_inst(struct r600_bc *bc, struct r600_bc_alu *alu)
static int is_alu_cube_inst(struct r600_bc *bc, struct r600_bc_alu *alu)
{
switch (bc->chiprev) {
case CHIPREV_R600:
case CHIPREV_R700:
switch (bc->chip_class) {
case R600:
case R700:
return !alu->is_op3 &&
alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_CUBE;
case CHIPREV_EVERGREEN:
case CHIPREV_CAYMAN:
case EVERGREEN:
case CAYMAN:
default:
return !alu->is_op3 &&
alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_CUBE;
@ -418,15 +380,15 @@ static int is_alu_cube_inst(struct r600_bc *bc, struct r600_bc_alu *alu)
static int is_alu_mova_inst(struct r600_bc *bc, struct r600_bc_alu *alu)
{
switch (bc->chiprev) {
case CHIPREV_R600:
case CHIPREV_R700:
switch (bc->chip_class) {
case R600:
case R700:
return !alu->is_op3 && (
alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA ||
alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_FLOOR ||
alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_INT);
case CHIPREV_EVERGREEN:
case CHIPREV_CAYMAN:
case EVERGREEN:
case CAYMAN:
default:
return !alu->is_op3 && (
alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_INT);
@ -438,16 +400,16 @@ static int is_alu_vec_unit_inst(struct r600_bc *bc, struct r600_bc_alu *alu)
{
return is_alu_reduction_inst(bc, alu) ||
is_alu_mova_inst(bc, alu) ||
(bc->chiprev == CHIPREV_EVERGREEN &&
(bc->chip_class == EVERGREEN &&
alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLT_TO_INT_FLOOR);
}
/* alu instructions that can only execute on the trans unit */
static int is_alu_trans_unit_inst(struct r600_bc *bc, struct r600_bc_alu *alu)
{
switch (bc->chiprev) {
case CHIPREV_R600:
case CHIPREV_R700:
switch (bc->chip_class) {
case R600:
case R700:
if (!alu->is_op3)
return alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ASHR_INT ||
alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLT_TO_INT ||
@ -478,8 +440,8 @@ static int is_alu_trans_unit_inst(struct r600_bc *bc, struct r600_bc_alu *alu)
alu->inst == V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT_D2 ||
alu->inst == V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT_M2 ||
alu->inst == V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT_M4;
case CHIPREV_EVERGREEN:
case CHIPREV_CAYMAN:
case EVERGREEN:
case CAYMAN:
default:
if (!alu->is_op3)
/* Note that FLT_TO_INT_* instructions are vector-only instructions
@ -525,7 +487,7 @@ static int assign_alu_units(struct r600_bc *bc, struct r600_bc_alu *alu_first,
{
struct r600_bc_alu *alu;
unsigned i, chan, trans;
int max_slots = bc->chiprev == CHIPREV_CAYMAN ? 4 : 5;
int max_slots = bc->chip_class == CAYMAN ? 4 : 5;
for (i = 0; i < max_slots; i++)
assignment[i] = NULL;
@ -612,7 +574,7 @@ static int reserve_gpr(struct alu_bank_swizzle *bs, unsigned sel, unsigned chan,
static int reserve_cfile(struct r600_bc *bc, struct alu_bank_swizzle *bs, unsigned sel, unsigned chan)
{
int res, num_res = 4;
if (bc->chiprev >= CHIPREV_R700) {
if (bc->chip_class >= R700) {
num_res = 2;
chan /= 2;
}
@ -733,8 +695,8 @@ static int check_and_set_bank_swizzle(struct r600_bc *bc,
struct alu_bank_swizzle bs;
int bank_swizzle[5];
int i, r = 0, forced = 0;
boolean scalar_only = bc->chiprev == CHIPREV_CAYMAN ? false : true;
int max_slots = bc->chiprev == CHIPREV_CAYMAN ? 4 : 5;
boolean scalar_only = bc->chip_class == CAYMAN ? false : true;
int max_slots = bc->chip_class == CAYMAN ? 4 : 5;
for (i = 0; i < max_slots; i++) {
if (slots[i] && slots[i]->bank_swizzle_force) {
@ -806,7 +768,7 @@ static int replace_gpr_with_pv_ps(struct r600_bc *bc,
struct r600_bc_alu *prev[5];
int gpr[5], chan[5];
int i, j, r, src, num_src;
int max_slots = bc->chiprev == CHIPREV_CAYMAN ? 4 : 5;
int max_slots = bc->chip_class == CAYMAN ? 4 : 5;
r = assign_alu_units(bc, alu_prev, prev);
if (r)
@ -834,7 +796,7 @@ static int replace_gpr_with_pv_ps(struct r600_bc *bc,
if (!is_gpr(alu->src[src].sel) || alu->src[src].rel)
continue;
if (bc->chiprev < CHIPREV_CAYMAN) {
if (bc->chip_class < CAYMAN) {
if (alu->src[src].sel == gpr[4] &&
alu->src[src].chan == chan[4]) {
alu->src[src].sel = V_SQ_ALU_SRC_PS;
@ -948,7 +910,7 @@ static int merge_inst_groups(struct r600_bc *bc, struct r600_bc_alu *slots[5],
int i, j, r, src, num_src;
int num_once_inst = 0;
int have_mova = 0, have_rel = 0;
int max_slots = bc->chiprev == CHIPREV_CAYMAN ? 4 : 5;
int max_slots = bc->chip_class == CAYMAN ? 4 : 5;
r = assign_alu_units(bc, alu_prev, prev);
if (r)
@ -1252,7 +1214,7 @@ int r600_bc_add_alu_type(struct r600_bc *bc, const struct r600_bc_alu *alu, int
uint32_t literal[4];
unsigned nliteral;
struct r600_bc_alu *slots[5];
int max_slots = bc->chiprev == CHIPREV_CAYMAN ? 4 : 5;
int max_slots = bc->chip_class == CAYMAN ? 4 : 5;
r = assign_alu_units(bc, bc->cf_last->curr_bs_head, slots);
if (r)
return r;
@ -1302,26 +1264,26 @@ int r600_bc_add_alu(struct r600_bc *bc, const struct r600_bc_alu *alu)
static unsigned r600_bc_num_tex_and_vtx_instructions(const struct r600_bc *bc)
{
switch (bc->chiprev) {
case CHIPREV_R600:
switch (bc->chip_class) {
case R600:
return 8;
case CHIPREV_R700:
case R700:
return 16;
case CHIPREV_EVERGREEN:
case CHIPREV_CAYMAN:
case EVERGREEN:
case CAYMAN:
return 64;
default:
R600_ERR("Unknown chiprev %d.\n", bc->chiprev);
R600_ERR("Unknown chip class %d.\n", bc->chip_class);
return 8;
}
}
static inline boolean last_inst_was_vtx_fetch(struct r600_bc *bc)
{
if (bc->chiprev == CHIPREV_CAYMAN) {
if (bc->chip_class == CAYMAN) {
if (bc->cf_last->inst != CM_V_SQ_CF_WORD1_SQ_CF_INST_TC)
return TRUE;
} else {
@ -1350,7 +1312,7 @@ int r600_bc_add_vtx(struct r600_bc *bc, const struct r600_bc_vtx *vtx)
free(nvtx);
return r;
}
if (bc->chiprev == CHIPREV_CAYMAN)
if (bc->chip_class == CAYMAN)
bc->cf_last->inst = CM_V_SQ_CF_WORD1_SQ_CF_INST_TC;
else
bc->cf_last->inst = V_SQ_CF_WORD1_SQ_CF_INST_VTX;
@ -1438,7 +1400,7 @@ static int r600_bc_vtx_build(struct r600_bc *bc, struct r600_bc_vtx *vtx, unsign
S_SQ_VTX_WORD0_FETCH_TYPE(vtx->fetch_type) |
S_SQ_VTX_WORD0_SRC_GPR(vtx->src_gpr) |
S_SQ_VTX_WORD0_SRC_SEL_X(vtx->src_sel_x);
if (bc->chiprev < CHIPREV_CAYMAN)
if (bc->chip_class < CAYMAN)
bc->bytecode[id] |= S_SQ_VTX_WORD0_MEGA_FETCH_COUNT(vtx->mega_fetch_count);
id++;
bc->bytecode[id++] = S_SQ_VTX_WORD1_DST_SEL_X(vtx->dst_sel_x) |
@ -1453,7 +1415,7 @@ static int r600_bc_vtx_build(struct r600_bc *bc, struct r600_bc_vtx *vtx, unsign
S_SQ_VTX_WORD1_GPR_DST_GPR(vtx->dst_gpr);
bc->bytecode[id] = S_SQ_VTX_WORD2_OFFSET(vtx->offset)|
S_SQ_VTX_WORD2_ENDIAN_SWAP(vtx->endian);
if (bc->chiprev < CHIPREV_CAYMAN)
if (bc->chip_class < CAYMAN)
bc->bytecode[id] |= S_SQ_VTX_WORD2_MEGA_FETCH(1);
id++;
bc->bytecode[id++] = 0;
@ -1560,13 +1522,13 @@ static int r600_bc_cf_build(struct r600_bc *bc, struct r600_bc_cf *cf)
S_SQ_CF_ALU_WORD1_KCACHE_ADDR0(cf->kcache[0].addr) |
S_SQ_CF_ALU_WORD1_KCACHE_ADDR1(cf->kcache[1].addr) |
S_SQ_CF_ALU_WORD1_BARRIER(1) |
S_SQ_CF_ALU_WORD1_USES_WATERFALL(bc->chiprev == CHIPREV_R600 ? cf->r6xx_uses_waterfall : 0) |
S_SQ_CF_ALU_WORD1_USES_WATERFALL(bc->chip_class == R600 ? cf->r6xx_uses_waterfall : 0) |
S_SQ_CF_ALU_WORD1_COUNT((cf->ndw / 2) - 1);
break;
case V_SQ_CF_WORD1_SQ_CF_INST_TEX:
case V_SQ_CF_WORD1_SQ_CF_INST_VTX:
case V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC:
if (bc->chiprev == CHIPREV_R700)
if (bc->chip_class == R700)
r700_bc_cf_vtx_build(&bc->bytecode[id], cf);
else
r600_bc_cf_vtx_build(&bc->bytecode[id], cf);
@ -1673,7 +1635,7 @@ int r600_bc_build(struct r600_bc *bc)
return -ENOMEM;
LIST_FOR_EACH_ENTRY(cf, &bc->cf, list) {
addr = cf->addr;
if (bc->chiprev >= CHIPREV_EVERGREEN)
if (bc->chip_class >= EVERGREEN)
r = eg_bc_cf_build(bc, cf);
else
r = r600_bc_cf_build(bc, cf);
@ -1691,17 +1653,17 @@ int r600_bc_build(struct r600_bc *bc)
if (r)
return r;
r600_bc_alu_adjust_literals(bc, alu, literal, nliteral);
switch(bc->chiprev) {
case CHIPREV_R600:
switch(bc->chip_class) {
case R600:
r = r600_bc_alu_build(bc, alu, addr);
break;
case CHIPREV_R700:
case CHIPREV_EVERGREEN: /* eg alu is same encoding as r700 */
case CHIPREV_CAYMAN: /* eg alu is same encoding as r700 */
case R700:
case EVERGREEN: /* eg alu is same encoding as r700 */
case CAYMAN: /* eg alu is same encoding as r700 */
r = r700_bc_alu_build(bc, alu, addr);
break;
default:
R600_ERR("unknown family %d\n", bc->family);
R600_ERR("unknown chip class %d.\n", bc->chip_class);
return -EINVAL;
}
if (r)
@ -1726,7 +1688,7 @@ int r600_bc_build(struct r600_bc *bc)
}
break;
case V_SQ_CF_WORD1_SQ_CF_INST_TEX:
if (bc->chiprev == CHIPREV_CAYMAN) {
if (bc->chip_class == CAYMAN) {
LIST_FOR_EACH_ENTRY(vtx, &cf->vtx, list) {
r = r600_bc_vtx_build(bc, vtx, addr);
if (r)
@ -1812,17 +1774,17 @@ void r600_bc_dump(struct r600_bc *bc)
unsigned nliteral;
char chip = '6';
switch (bc->chiprev) {
case 1:
switch (bc->chip_class) {
case R700:
chip = '7';
break;
case 2:
case EVERGREEN:
chip = 'E';
break;
case 3:
case CAYMAN:
chip = 'C';
break;
case 0:
case R600:
default:
chip = '6';
break;
@ -1993,7 +1955,7 @@ void r600_bc_dump(struct r600_bc *bc)
fprintf(stderr, "%04d %08X ", id, bc->bytecode[id]);
fprintf(stderr, "SRC(GPR:%d ", vtx->src_gpr);
fprintf(stderr, "SEL_X:%d) ", vtx->src_sel_x);
if (bc->chiprev < CHIPREV_CAYMAN)
if (bc->chip_class < CAYMAN)
fprintf(stderr, "MEGA_FETCH_COUNT:%d ", vtx->mega_fetch_count);
else
fprintf(stderr, "SEL_Y:%d) ", 0);
@ -2162,7 +2124,7 @@ int r600_vertex_elements_build_fetch_shader(struct r600_pipe_context *rctx, stru
struct r600_bc_vtx vtx;
struct pipe_vertex_element *elements = ve->elements;
const struct util_format_description *desc;
unsigned fetch_resource_start = rctx->family >= CHIP_CEDAR ? 0 : 160;
unsigned fetch_resource_start = rctx->chip_class >= EVERGREEN ? 0 : 160;
unsigned format, num_format, format_comp, endian;
u32 *bytecode;
int i, r;
@ -2180,9 +2142,7 @@ int r600_vertex_elements_build_fetch_shader(struct r600_pipe_context *rctx, stru
}
memset(&bc, 0, sizeof(bc));
r = r600_bc_init(&bc, r600_get_family(rctx->radeon));
if (r)
return r;
r600_bc_init(&bc, rctx->chip_class);
for (i = 0; i < ve->count; i++) {
if (elements[i].instance_divisor > 1) {
@ -2287,7 +2247,7 @@ int r600_vertex_elements_build_fetch_shader(struct r600_pipe_context *rctx, stru
r600_bo_unmap(rctx->radeon, ve->fetch_shader);
r600_bc_clear(&bc);
if (rctx->family >= CHIP_CEDAR)
if (rctx->chip_class >= EVERGREEN)
evergreen_fetch_shader(&rctx->context, ve);
else
r600_fetch_shader(&rctx->context, ve);

View file

@ -171,8 +171,7 @@ struct r600_cf_callstack {
};
struct r600_bc {
enum radeon_family family;
int chiprev; /* 0 - r600, 1 - r700, 2 - evergreen */
enum chip_class chip_class;
int type;
struct list_head cf;
struct r600_bc_cf *cf_last;
@ -193,7 +192,7 @@ struct r600_bc {
int eg_bc_cf_build(struct r600_bc *bc, struct r600_bc_cf *cf);
/* r600_asm.c */
int r600_bc_init(struct r600_bc *bc, enum radeon_family family);
void r600_bc_init(struct r600_bc *bc, enum chip_class chip_class);
void r600_bc_clear(struct r600_bc *bc);
int r600_bc_add_alu(struct r600_bc *bc, const struct r600_bc_alu *alu);
int r600_bc_add_vtx(struct r600_bc *bc, const struct r600_bc_vtx *vtx);

View file

@ -97,7 +97,7 @@ static void r600_blitter_end(struct pipe_context *ctx)
rctx->saved_render_cond_mode);
rctx->saved_render_cond = NULL;
}
r600_context_queries_resume(&rctx->ctx);
r600_context_queries_resume(&rctx->ctx, FALSE);
rctx->blit = false;
}

View file

@ -81,4 +81,36 @@ static INLINE unsigned r600_endian_swap(unsigned size)
}
}
static INLINE bool r600_is_vertex_format_supported(enum pipe_format format)
{
const struct util_format_description *desc = util_format_description(format);
unsigned i;
if (!desc)
return false;
/* Find the first non-VOID channel. */
for (i = 0; i < 4; i++) {
if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID)
break;
}
if (i == 4)
return false;
/* No fixed, no double. */
if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN ||
desc->channel[i].type == UTIL_FORMAT_TYPE_FIXED ||
(desc->channel[i].size == 64 &&
desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT))
return false;
/* No scaled/norm formats with 32 bits per channel. */
if (desc->channel[i].size == 32 &&
(desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED ||
desc->channel[i].type == UTIL_FORMAT_TYPE_UNSIGNED))
return false;
return true;
}
#endif

View file

@ -409,14 +409,8 @@
#define EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_EXPORT_COMBINED 0x0000005B
#define EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_RAT_COMBINED_CACHELESS 0x0000005C
#define BC_INST(bc, x) ((bc)->chip_class >= EVERGREEN ? EG_##x : x)
#define CHIPREV_R600 0
#define CHIPREV_R700 1
#define CHIPREV_EVERGREEN 2
#define CHIPREV_CAYMAN 3
#define BC_INST(bc, x) ((bc)->chiprev >= CHIPREV_EVERGREEN ? EG_##x : x)
#define CTX_INST(x) (ctx->bc->chiprev >= CHIPREV_EVERGREEN ? EG_##x : x)
#define CTX_INST(x) (ctx->bc->chip_class >= EVERGREEN ? EG_##x : x)
#endif

View file

@ -47,7 +47,6 @@
#include "r600_resource.h"
#include "r600_shader.h"
#include "r600_pipe.h"
#include "r600_state_inlines.h"
/*
* pipe_context
@ -197,7 +196,6 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void
{
struct r600_pipe_context *rctx = CALLOC_STRUCT(r600_pipe_context);
struct r600_screen* rscreen = (struct r600_screen *)screen;
enum chip_class class;
if (rctx == NULL)
return NULL;
@ -214,6 +212,7 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void
rctx->screen = rscreen;
rctx->radeon = rscreen->radeon;
rctx->family = r600_get_family(rctx->radeon);
rctx->chip_class = r600_get_family_class(rctx->radeon);
rctx->fences.bo = NULL;
rctx->fences.data = NULL;
@ -230,47 +229,29 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void
rctx->context.create_video_decoder = vl_create_decoder;
rctx->context.create_video_buffer = vl_video_buffer_create;
switch (r600_get_family(rctx->radeon)) {
case CHIP_R600:
case CHIP_RV610:
case CHIP_RV630:
case CHIP_RV670:
case CHIP_RV620:
case CHIP_RV635:
case CHIP_RS780:
case CHIP_RS880:
case CHIP_RV770:
case CHIP_RV730:
case CHIP_RV710:
case CHIP_RV740:
switch (rctx->chip_class) {
case R600:
case R700:
r600_init_state_functions(rctx);
if (r600_context_init(&rctx->ctx, rctx->radeon)) {
r600_destroy_context(&rctx->context);
return NULL;
}
r600_init_config(rctx);
rctx->custom_dsa_flush = r600_create_db_flush_dsa(rctx);
break;
case CHIP_CEDAR:
case CHIP_REDWOOD:
case CHIP_JUNIPER:
case CHIP_CYPRESS:
case CHIP_HEMLOCK:
case CHIP_PALM:
case CHIP_SUMO:
case CHIP_SUMO2:
case CHIP_BARTS:
case CHIP_TURKS:
case CHIP_CAICOS:
case CHIP_CAYMAN:
case EVERGREEN:
case CAYMAN:
evergreen_init_state_functions(rctx);
if (evergreen_context_init(&rctx->ctx, rctx->radeon)) {
r600_destroy_context(&rctx->context);
return NULL;
}
evergreen_init_config(rctx);
rctx->custom_dsa_flush = evergreen_create_db_flush_dsa(rctx);
break;
default:
R600_ERR("unsupported family %d\n", r600_get_family(rctx->radeon));
R600_ERR("Unsupported chip class %d.\n", rctx->chip_class);
r600_destroy_context(&rctx->context);
return NULL;
}
@ -295,12 +276,6 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void
return NULL;
}
class = r600_get_family_class(rctx->radeon);
if (class == R600 || class == R700)
rctx->custom_dsa_flush = r600_create_db_flush_dsa(rctx);
else
rctx->custom_dsa_flush = evergreen_create_db_flush_dsa(rctx);
return &rctx->context;
}
@ -523,64 +498,6 @@ static int r600_get_video_param(struct pipe_screen *screen,
}
}
static boolean r600_is_format_supported(struct pipe_screen* screen,
enum pipe_format format,
enum pipe_texture_target target,
unsigned sample_count,
unsigned usage)
{
unsigned retval = 0;
if (target >= PIPE_MAX_TEXTURE_TYPES) {
R600_ERR("r600: unsupported texture type %d\n", target);
return FALSE;
}
if (!util_format_is_supported(format, usage))
return FALSE;
/* Multisample */
if (sample_count > 1)
return FALSE;
if ((usage & PIPE_BIND_SAMPLER_VIEW) &&
r600_is_sampler_format_supported(screen, format)) {
retval |= PIPE_BIND_SAMPLER_VIEW;
}
if ((usage & (PIPE_BIND_RENDER_TARGET |
PIPE_BIND_DISPLAY_TARGET |
PIPE_BIND_SCANOUT |
PIPE_BIND_SHARED)) &&
r600_is_colorbuffer_format_supported(format)) {
retval |= usage &
(PIPE_BIND_RENDER_TARGET |
PIPE_BIND_DISPLAY_TARGET |
PIPE_BIND_SCANOUT |
PIPE_BIND_SHARED);
}
if ((usage & PIPE_BIND_DEPTH_STENCIL) &&
r600_is_zs_format_supported(format)) {
retval |= PIPE_BIND_DEPTH_STENCIL;
}
if (usage & PIPE_BIND_VERTEX_BUFFER) {
struct r600_screen *rscreen = (struct r600_screen *)screen;
enum radeon_family family = r600_get_family(rscreen->radeon);
if (r600_is_vertex_format_supported(format, family)) {
retval |= PIPE_BIND_VERTEX_BUFFER;
}
}
if (usage & PIPE_BIND_TRANSFER_READ)
retval |= PIPE_BIND_TRANSFER_READ;
if (usage & PIPE_BIND_TRANSFER_WRITE)
retval |= PIPE_BIND_TRANSFER_WRITE;
return retval == usage;
}
static void r600_destroy_screen(struct pipe_screen* pscreen)
{
struct r600_screen *rscreen = (struct r600_screen *)pscreen;
@ -670,7 +587,11 @@ struct pipe_screen *r600_screen_create(struct radeon *radeon)
rscreen->screen.get_shader_param = r600_get_shader_param;
rscreen->screen.get_paramf = r600_get_paramf;
rscreen->screen.get_video_param = r600_get_video_param;
rscreen->screen.is_format_supported = r600_is_format_supported;
if (r600_get_family_class(radeon) >= EVERGREEN) {
rscreen->screen.is_format_supported = evergreen_is_format_supported;
} else {
rscreen->screen.is_format_supported = r600_is_format_supported;
}
rscreen->screen.is_video_format_supported = vl_video_buffer_is_format_supported;
rscreen->screen.context_create = r600_create_context;
rscreen->screen.fence_reference = r600_fence_reference;

View file

@ -175,7 +175,8 @@ struct r600_pipe_fences {
struct r600_pipe_context {
struct pipe_context context;
struct blitter_context *blitter;
unsigned family;
enum radeon_family family;
enum chip_class chip_class;
void *custom_dsa_flush;
struct r600_screen *screen;
struct radeon *radeon;
@ -247,6 +248,11 @@ void evergreen_pipe_init_buffer_resource(struct r600_pipe_context *rctx,
void evergreen_pipe_mod_buffer_resource(struct r600_pipe_resource_state *rstate,
struct r600_resource *rbuffer,
unsigned offset, unsigned stride);
boolean evergreen_is_format_supported(struct pipe_screen *screen,
enum pipe_format format,
enum pipe_texture_target target,
unsigned sample_count,
unsigned usage);
/* r600_blit.c */
void r600_init_blit_functions(struct r600_pipe_context *rctx);
@ -290,6 +296,11 @@ void r600_pipe_mod_buffer_resource(struct r600_pipe_resource_state *rstate,
struct r600_resource *rbuffer,
unsigned offset, unsigned stride);
void r600_adjust_gprs(struct r600_pipe_context *rctx);
boolean r600_is_format_supported(struct pipe_screen *screen,
enum pipe_format format,
enum pipe_texture_target target,
unsigned sample_count,
unsigned usage);
/* r600_texture.c */
void r600_init_screen_texture_functions(struct pipe_screen *screen);

View file

@ -61,10 +61,7 @@ static boolean r600_get_query_result(struct pipe_context *ctx,
struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
struct r600_query *rquery = (struct r600_query *)query;
if (rquery->num_results) {
ctx->flush(ctx, NULL);
}
return r600_context_query_result(&rctx->ctx, (struct r600_query *)query, wait, vresult);
return r600_context_query_result(&rctx->ctx, rquery, wait, vresult);
}
static void r600_render_condition(struct pipe_context *ctx,

View file

@ -99,14 +99,14 @@ static int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *s
/* build state */
switch (rshader->processor_type) {
case TGSI_PROCESSOR_VERTEX:
if (rshader->family >= CHIP_CEDAR) {
if (rctx->chip_class >= EVERGREEN) {
evergreen_pipe_shader_vs(ctx, shader);
} else {
r600_pipe_shader_vs(ctx, shader);
}
break;
case TGSI_PROCESSOR_FRAGMENT:
if (rshader->family >= CHIP_CEDAR) {
if (rctx->chip_class >= EVERGREEN) {
evergreen_pipe_shader_ps(ctx, shader);
} else {
r600_pipe_shader_ps(ctx, shader);
@ -135,7 +135,6 @@ int r600_pipe_shader_create(struct pipe_context *ctx, struct r600_pipe_shader *s
fprintf(stderr, "--------------------------------------------------------------\n");
tgsi_dump(shader->tokens, 0);
}
shader->shader.family = r600_get_family(rctx->radeon);
r = r600_shader_from_tgsi(rctx, shader);
if (r) {
R600_ERR("translation from TGSI failed !\n");
@ -317,7 +316,7 @@ static int tgsi_declaration(struct r600_shader_ctx *ctx)
ctx->shader->input[i].interpolate = d->Declaration.Interpolate;
ctx->shader->input[i].centroid = d->Declaration.Centroid;
ctx->shader->input[i].gpr = ctx->file_offset[TGSI_FILE_INPUT] + i;
if (ctx->type == TGSI_PROCESSOR_FRAGMENT && ctx->bc->chiprev >= CHIPREV_EVERGREEN) {
if (ctx->type == TGSI_PROCESSOR_FRAGMENT && ctx->bc->chip_class >= EVERGREEN) {
/* turn input into interpolate on EG */
if (ctx->shader->input[i].name != TGSI_SEMANTIC_POSITION) {
if (ctx->shader->input[i].interpolate > 0) {
@ -610,9 +609,7 @@ static int r600_shader_from_tgsi(struct r600_pipe_context * rctx, struct r600_pi
ctx.bc = &shader->bc;
ctx.shader = shader;
r = r600_bc_init(ctx.bc, shader->family);
if (r)
return r;
r600_bc_init(ctx.bc, rctx->chip_class);
ctx.tokens = tokens;
tgsi_scan_shader(tokens, &ctx.info);
tgsi_parse_init(&ctx.parse, tokens);
@ -651,13 +648,13 @@ static int r600_shader_from_tgsi(struct r600_pipe_context * rctx, struct r600_pi
}
if (ctx.type == TGSI_PROCESSOR_VERTEX) {
ctx.file_offset[TGSI_FILE_INPUT] = 1;
if (ctx.bc->chiprev >= CHIPREV_EVERGREEN) {
if (ctx.bc->chip_class >= EVERGREEN) {
r600_bc_add_cfinst(ctx.bc, EG_V_SQ_CF_WORD1_SQ_CF_INST_CALL_FS);
} else {
r600_bc_add_cfinst(ctx.bc, V_SQ_CF_WORD1_SQ_CF_INST_CALL_FS);
}
}
if (ctx.type == TGSI_PROCESSOR_FRAGMENT && ctx.bc->chiprev >= CHIPREV_EVERGREEN) {
if (ctx.type == TGSI_PROCESSOR_FRAGMENT && ctx.bc->chip_class >= EVERGREEN) {
ctx.file_offset[TGSI_FILE_INPUT] = evergreen_gpr_count(&ctx);
}
ctx.file_offset[TGSI_FILE_OUTPUT] = ctx.file_offset[TGSI_FILE_INPUT] +
@ -711,9 +708,9 @@ static int r600_shader_from_tgsi(struct r600_pipe_context * rctx, struct r600_pi
goto out_err;
if ((r = tgsi_split_literal_constant(&ctx)))
goto out_err;
if (ctx.bc->chiprev == CHIPREV_CAYMAN)
if (ctx.bc->chip_class == CAYMAN)
ctx.inst_info = &cm_shader_tgsi_instruction[opcode];
else if (ctx.bc->chiprev >= CHIPREV_EVERGREEN)
else if (ctx.bc->chip_class >= EVERGREEN)
ctx.inst_info = &eg_shader_tgsi_instruction[opcode];
else
ctx.inst_info = &r600_shader_tgsi_instruction[opcode];
@ -802,7 +799,7 @@ static int r600_shader_from_tgsi(struct r600_pipe_context * rctx, struct r600_pi
if (shader->output[i].name == TGSI_SEMANTIC_COLOR) {
output[i + j].array_base = shader->output[i].sid;
output[i + j].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL;
if (shader->fs_write_all && (shader->family >= CHIP_CEDAR)) {
if (shader->fs_write_all && (rctx->chip_class >= EVERGREEN)) {
for (j = 1; j < shader->nr_cbufs; j++) {
memset(&output[i + j], 0, sizeof(struct r600_bc_output));
output[i + j].gpr = shader->output[i].gpr;
@ -886,7 +883,7 @@ static int r600_shader_from_tgsi(struct r600_pipe_context * rctx, struct r600_pi
}
/* set export done on last export of each type */
for (i = noutput - 1, output_done = 0; i >= 0; i--) {
if (ctx.bc->chiprev < CHIPREV_CAYMAN) {
if (ctx.bc->chip_class < CAYMAN) {
if (i == (noutput - 1)) {
output[i].end_of_program = 1;
}
@ -903,7 +900,7 @@ static int r600_shader_from_tgsi(struct r600_pipe_context * rctx, struct r600_pi
goto out_err;
}
/* add program end */
if (ctx.bc->chiprev == CHIPREV_CAYMAN)
if (ctx.bc->chip_class == CAYMAN)
cm_bc_add_cf_end(ctx.bc);
free(ctx.literals);
@ -939,6 +936,17 @@ static void r600_bc_src(struct r600_bc_alu_src *bc_src,
bc_src->value = shader_src->value[bc_src->chan];
}
static void r600_bc_src_set_abs(struct r600_bc_alu_src *bc_src)
{
bc_src->abs = 1;
bc_src->neg = 0;
}
static void r600_bc_src_toggle_neg(struct r600_bc_alu_src *bc_src)
{
bc_src->neg = !bc_src->neg;
}
static void tgsi_dst(struct r600_shader_ctx *ctx,
const struct tgsi_full_dst_register *tgsi_dst,
unsigned swizzle,
@ -995,12 +1003,10 @@ static int tgsi_op2_s(struct r600_shader_ctx *ctx, int swap)
/* handle some special cases */
switch (ctx->inst_info->tgsi_opcode) {
case TGSI_OPCODE_SUB:
alu.src[1].neg = 1;
r600_bc_src_toggle_neg(&alu.src[1]);
break;
case TGSI_OPCODE_ABS:
alu.src[0].abs = 1;
if (alu.src[0].neg)
alu.src[0].neg = 0;
r600_bc_src_set_abs(&alu.src[0]);
break;
default:
break;
@ -1114,7 +1120,7 @@ static int tgsi_setup_trig(struct r600_shader_ctx *ctx)
alu.src[2].sel = V_SQ_ALU_SRC_LITERAL;
alu.src[2].chan = 0;
if (ctx->bc->chiprev == CHIPREV_R600) {
if (ctx->bc->chip_class == R600) {
alu.src[1].value = *(uint32_t *)&double_pi;
alu.src[2].value = *(uint32_t *)&neg_pi;
} else {
@ -1221,7 +1227,7 @@ static int tgsi_scs(struct r600_shader_ctx *ctx)
/* dst.x = COS */
if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_X) {
if (ctx->bc->chiprev == CHIPREV_CAYMAN) {
if (ctx->bc->chip_class == CAYMAN) {
for (i = 0 ; i < 3; i++) {
memset(&alu, 0, sizeof(struct r600_bc_alu));
alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_COS);
@ -1255,7 +1261,7 @@ static int tgsi_scs(struct r600_shader_ctx *ctx)
/* dst.y = SIN */
if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Y) {
if (ctx->bc->chiprev == CHIPREV_CAYMAN) {
if (ctx->bc->chip_class == CAYMAN) {
for (i = 0 ; i < 3; i++) {
memset(&alu, 0, sizeof(struct r600_bc_alu));
alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SIN);
@ -1364,19 +1370,37 @@ static int tgsi_lit(struct r600_shader_ctx *ctx)
struct r600_bc_alu alu;
int r;
/* tmp.x = max(src.y, 0.0) */
memset(&alu, 0, sizeof(struct r600_bc_alu));
alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX);
r600_bc_src(&alu.src[0], &ctx->src[0], 1);
alu.src[1].sel = V_SQ_ALU_SRC_0; /*0.0*/
alu.src[1].chan = 1;
alu.dst.sel = ctx->temp_reg;
alu.dst.chan = 0;
alu.dst.write = 1;
alu.last = 1;
r = r600_bc_add_alu(ctx->bc, &alu);
if (r)
return r;
if (inst->Dst[0].Register.WriteMask & (1 << 2))
{
int chan;
int sel;
int i;
if (ctx->bc->chiprev == CHIPREV_CAYMAN) {
if (ctx->bc->chip_class == CAYMAN) {
for (i = 0; i < 3; i++) {
/* dst.z = log(src.y) */
/* tmp.z = log(tmp.x) */
memset(&alu, 0, sizeof(struct r600_bc_alu));
alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_CLAMPED);
r600_bc_src(&alu.src[0], &ctx->src[0], 1);
tgsi_dst(ctx, &inst->Dst[0], i, &alu.dst);
alu.src[0].sel = ctx->temp_reg;
alu.src[0].chan = 0;
alu.dst.sel = ctx->temp_reg;
alu.dst.chan = i;
if (i == 2) {
alu.dst.write = 1;
alu.last = 1;
@ -1388,10 +1412,11 @@ static int tgsi_lit(struct r600_shader_ctx *ctx)
return r;
}
} else {
/* dst.z = log(src.y) */
/* tmp.z = log(tmp.x) */
memset(&alu, 0, sizeof(struct r600_bc_alu));
alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_CLAMPED);
r600_bc_src(&alu.src[0], &ctx->src[0], 1);
alu.src[0].sel = ctx->temp_reg;
alu.src[0].chan = 0;
alu.dst.sel = ctx->temp_reg;
alu.dst.chan = 2;
alu.dst.write = 1;
@ -1404,13 +1429,12 @@ static int tgsi_lit(struct r600_shader_ctx *ctx)
chan = alu.dst.chan;
sel = alu.dst.sel;
/* tmp.x = amd MUL_LIT(src.w, dst.z, src.x ) */
/* tmp.x = amd MUL_LIT(tmp.z, src.w, src.x ) */
memset(&alu, 0, sizeof(struct r600_bc_alu));
alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT);
r600_bc_src(&alu.src[0], &ctx->src[0], 3);
alu.src[1].sel = sel;
alu.src[1].chan = chan;
alu.src[0].sel = sel;
alu.src[0].chan = chan;
r600_bc_src(&alu.src[1], &ctx->src[0], 3);
r600_bc_src(&alu.src[2], &ctx->src[0], 0);
alu.dst.sel = ctx->temp_reg;
alu.dst.chan = 0;
@ -1421,7 +1445,7 @@ static int tgsi_lit(struct r600_shader_ctx *ctx)
if (r)
return r;
if (ctx->bc->chiprev == CHIPREV_CAYMAN) {
if (ctx->bc->chip_class == CAYMAN) {
for (i = 0; i < 3; i++) {
/* dst.z = exp(tmp.x) */
memset(&alu, 0, sizeof(struct r600_bc_alu));
@ -1506,7 +1530,7 @@ static int tgsi_rsq(struct r600_shader_ctx *ctx)
for (i = 0; i < inst->Instruction.NumSrcRegs; i++) {
r600_bc_src(&alu.src[i], &ctx->src[i], 0);
alu.src[i].abs = 1;
r600_bc_src_set_abs(&alu.src[i]);
}
alu.dst.sel = ctx->temp_reg;
alu.dst.write = 1;
@ -1898,7 +1922,7 @@ static int tgsi_tex(struct r600_shader_ctx *ctx)
} else if (inst->Instruction.Opcode == TGSI_OPCODE_TXP) {
int out_chan;
/* Add perspective divide */
if (ctx->bc->chiprev == CHIPREV_CAYMAN) {
if (ctx->bc->chip_class == CAYMAN) {
out_chan = 2;
for (i = 0; i < 3; i++) {
memset(&alu, 0, sizeof(struct r600_bc_alu));
@ -1980,7 +2004,7 @@ static int tgsi_tex(struct r600_shader_ctx *ctx)
}
/* tmp1.z = RCP_e(|tmp1.z|) */
if (ctx->bc->chiprev == CHIPREV_CAYMAN) {
if (ctx->bc->chip_class == CAYMAN) {
for (i = 0; i < 3; i++) {
memset(&alu, 0, sizeof(struct r600_bc_alu));
alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_IEEE);
@ -2192,7 +2216,7 @@ static int tgsi_lrp(struct r600_shader_ctx *ctx)
alu.src[0].sel = V_SQ_ALU_SRC_1;
alu.src[0].chan = 0;
r600_bc_src(&alu.src[1], &ctx->src[0], i);
alu.src[1].neg = 1;
r600_bc_src_toggle_neg(&alu.src[1]);
alu.dst.sel = ctx->temp_reg;
alu.dst.chan = i;
if (i == lasti) {
@ -2373,7 +2397,7 @@ static int tgsi_exp(struct r600_shader_ctx *ctx)
if (r)
return r;
if (ctx->bc->chiprev == CHIPREV_CAYMAN) {
if (ctx->bc->chip_class == CAYMAN) {
for (i = 0; i < 3; i++) {
alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_EXP_IEEE);
alu.src[0].sel = ctx->temp_reg;
@ -2429,7 +2453,7 @@ static int tgsi_exp(struct r600_shader_ctx *ctx)
/* result.z = RoughApprox2ToX(tmp);*/
if ((inst->Dst[0].Register.WriteMask >> 2) & 0x1) {
if (ctx->bc->chiprev == CHIPREV_CAYMAN) {
if (ctx->bc->chip_class == CAYMAN) {
for (i = 0; i < 3; i++) {
memset(&alu, 0, sizeof(struct r600_bc_alu));
alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_EXP_IEEE);
@ -2489,14 +2513,15 @@ static int tgsi_log(struct r600_shader_ctx *ctx)
int r;
int i;
/* result.x = floor(log2(src)); */
/* result.x = floor(log2(|src|)); */
if (inst->Dst[0].Register.WriteMask & 1) {
if (ctx->bc->chiprev == CHIPREV_CAYMAN) {
if (ctx->bc->chip_class == CAYMAN) {
for (i = 0; i < 3; i++) {
memset(&alu, 0, sizeof(struct r600_bc_alu));
alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_IEEE);
r600_bc_src(&alu.src[0], &ctx->src[0], 0);
r600_bc_src_set_abs(&alu.src[0]);
alu.dst.sel = ctx->temp_reg;
alu.dst.chan = i;
@ -2514,6 +2539,7 @@ static int tgsi_log(struct r600_shader_ctx *ctx)
alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_IEEE);
r600_bc_src(&alu.src[0], &ctx->src[0], 0);
r600_bc_src_set_abs(&alu.src[0]);
alu.dst.sel = ctx->temp_reg;
alu.dst.chan = 0;
@ -2538,15 +2564,16 @@ static int tgsi_log(struct r600_shader_ctx *ctx)
return r;
}
/* result.y = src.x / (2 ^ floor(log2(src.x))); */
/* result.y = |src.x| / (2 ^ floor(log2(|src.x|))); */
if ((inst->Dst[0].Register.WriteMask >> 1) & 1) {
if (ctx->bc->chiprev == CHIPREV_CAYMAN) {
if (ctx->bc->chip_class == CAYMAN) {
for (i = 0; i < 3; i++) {
memset(&alu, 0, sizeof(struct r600_bc_alu));
alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_IEEE);
r600_bc_src(&alu.src[0], &ctx->src[0], 0);
r600_bc_src_set_abs(&alu.src[0]);
alu.dst.sel = ctx->temp_reg;
alu.dst.chan = i;
@ -2564,6 +2591,7 @@ static int tgsi_log(struct r600_shader_ctx *ctx)
alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_IEEE);
r600_bc_src(&alu.src[0], &ctx->src[0], 0);
r600_bc_src_set_abs(&alu.src[0]);
alu.dst.sel = ctx->temp_reg;
alu.dst.chan = 1;
@ -2590,7 +2618,7 @@ static int tgsi_log(struct r600_shader_ctx *ctx)
if (r)
return r;
if (ctx->bc->chiprev == CHIPREV_CAYMAN) {
if (ctx->bc->chip_class == CAYMAN) {
for (i = 0; i < 3; i++) {
memset(&alu, 0, sizeof(struct r600_bc_alu));
alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_EXP_IEEE);
@ -2624,7 +2652,7 @@ static int tgsi_log(struct r600_shader_ctx *ctx)
return r;
}
if (ctx->bc->chiprev == CHIPREV_CAYMAN) {
if (ctx->bc->chip_class == CAYMAN) {
for (i = 0; i < 3; i++) {
memset(&alu, 0, sizeof(struct r600_bc_alu));
alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_IEEE);
@ -2663,6 +2691,7 @@ static int tgsi_log(struct r600_shader_ctx *ctx)
alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL);
r600_bc_src(&alu.src[0], &ctx->src[0], 0);
r600_bc_src_set_abs(&alu.src[0]);
alu.src[1].sel = ctx->temp_reg;
alu.src[1].chan = 1;
@ -2677,14 +2706,15 @@ static int tgsi_log(struct r600_shader_ctx *ctx)
return r;
}
/* result.z = log2(src);*/
/* result.z = log2(|src|);*/
if ((inst->Dst[0].Register.WriteMask >> 2) & 1) {
if (ctx->bc->chiprev == CHIPREV_CAYMAN) {
if (ctx->bc->chip_class == CAYMAN) {
for (i = 0; i < 3; i++) {
memset(&alu, 0, sizeof(struct r600_bc_alu));
alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_IEEE);
r600_bc_src(&alu.src[0], &ctx->src[0], 0);
r600_bc_src_set_abs(&alu.src[0]);
alu.dst.sel = ctx->temp_reg;
if (i == 2)
@ -2702,6 +2732,7 @@ static int tgsi_log(struct r600_shader_ctx *ctx)
alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_IEEE);
r600_bc_src(&alu.src[0], &ctx->src[0], 0);
r600_bc_src_set_abs(&alu.src[0]);
alu.dst.sel = ctx->temp_reg;
alu.dst.write = 1;

View file

@ -43,7 +43,6 @@ struct r600_shader {
unsigned nlds;
struct r600_shader_io input[32];
struct r600_shader_io output[32];
enum radeon_family family;
boolean uses_kill;
boolean fs_write_all;
boolean clamp_color;

View file

@ -44,7 +44,590 @@
#include "r600_resource.h"
#include "r600_shader.h"
#include "r600_pipe.h"
#include "r600_state_inlines.h"
#include "r600_formats.h"
static uint32_t r600_translate_blend_function(int blend_func)
{
switch (blend_func) {
case PIPE_BLEND_ADD:
return V_028804_COMB_DST_PLUS_SRC;
case PIPE_BLEND_SUBTRACT:
return V_028804_COMB_SRC_MINUS_DST;
case PIPE_BLEND_REVERSE_SUBTRACT:
return V_028804_COMB_DST_MINUS_SRC;
case PIPE_BLEND_MIN:
return V_028804_COMB_MIN_DST_SRC;
case PIPE_BLEND_MAX:
return V_028804_COMB_MAX_DST_SRC;
default:
R600_ERR("Unknown blend function %d\n", blend_func);
assert(0);
break;
}
return 0;
}
static uint32_t r600_translate_blend_factor(int blend_fact)
{
switch (blend_fact) {
case PIPE_BLENDFACTOR_ONE:
return V_028804_BLEND_ONE;
case PIPE_BLENDFACTOR_SRC_COLOR:
return V_028804_BLEND_SRC_COLOR;
case PIPE_BLENDFACTOR_SRC_ALPHA:
return V_028804_BLEND_SRC_ALPHA;
case PIPE_BLENDFACTOR_DST_ALPHA:
return V_028804_BLEND_DST_ALPHA;
case PIPE_BLENDFACTOR_DST_COLOR:
return V_028804_BLEND_DST_COLOR;
case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
return V_028804_BLEND_SRC_ALPHA_SATURATE;
case PIPE_BLENDFACTOR_CONST_COLOR:
return V_028804_BLEND_CONST_COLOR;
case PIPE_BLENDFACTOR_CONST_ALPHA:
return V_028804_BLEND_CONST_ALPHA;
case PIPE_BLENDFACTOR_ZERO:
return V_028804_BLEND_ZERO;
case PIPE_BLENDFACTOR_INV_SRC_COLOR:
return V_028804_BLEND_ONE_MINUS_SRC_COLOR;
case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
return V_028804_BLEND_ONE_MINUS_SRC_ALPHA;
case PIPE_BLENDFACTOR_INV_DST_ALPHA:
return V_028804_BLEND_ONE_MINUS_DST_ALPHA;
case PIPE_BLENDFACTOR_INV_DST_COLOR:
return V_028804_BLEND_ONE_MINUS_DST_COLOR;
case PIPE_BLENDFACTOR_INV_CONST_COLOR:
return V_028804_BLEND_ONE_MINUS_CONST_COLOR;
case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
return V_028804_BLEND_ONE_MINUS_CONST_ALPHA;
case PIPE_BLENDFACTOR_SRC1_COLOR:
return V_028804_BLEND_SRC1_COLOR;
case PIPE_BLENDFACTOR_SRC1_ALPHA:
return V_028804_BLEND_SRC1_ALPHA;
case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
return V_028804_BLEND_INV_SRC1_COLOR;
case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
return V_028804_BLEND_INV_SRC1_ALPHA;
default:
R600_ERR("Bad blend factor %d not supported!\n", blend_fact);
assert(0);
break;
}
return 0;
}
static uint32_t r600_translate_stencil_op(int s_op)
{
switch (s_op) {
case PIPE_STENCIL_OP_KEEP:
return V_028800_STENCIL_KEEP;
case PIPE_STENCIL_OP_ZERO:
return V_028800_STENCIL_ZERO;
case PIPE_STENCIL_OP_REPLACE:
return V_028800_STENCIL_REPLACE;
case PIPE_STENCIL_OP_INCR:
return V_028800_STENCIL_INCR;
case PIPE_STENCIL_OP_DECR:
return V_028800_STENCIL_DECR;
case PIPE_STENCIL_OP_INCR_WRAP:
return V_028800_STENCIL_INCR_WRAP;
case PIPE_STENCIL_OP_DECR_WRAP:
return V_028800_STENCIL_DECR_WRAP;
case PIPE_STENCIL_OP_INVERT:
return V_028800_STENCIL_INVERT;
default:
R600_ERR("Unknown stencil op %d", s_op);
assert(0);
break;
}
return 0;
}
static uint32_t r600_translate_fill(uint32_t func)
{
switch(func) {
case PIPE_POLYGON_MODE_FILL:
return 2;
case PIPE_POLYGON_MODE_LINE:
return 1;
case PIPE_POLYGON_MODE_POINT:
return 0;
default:
assert(0);
return 0;
}
}
/* translates straight */
static uint32_t r600_translate_ds_func(int func)
{
return func;
}
static unsigned r600_tex_wrap(unsigned wrap)
{
switch (wrap) {
default:
case PIPE_TEX_WRAP_REPEAT:
return V_03C000_SQ_TEX_WRAP;
case PIPE_TEX_WRAP_CLAMP:
return V_03C000_SQ_TEX_CLAMP_HALF_BORDER;
case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
return V_03C000_SQ_TEX_CLAMP_LAST_TEXEL;
case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
return V_03C000_SQ_TEX_CLAMP_BORDER;
case PIPE_TEX_WRAP_MIRROR_REPEAT:
return V_03C000_SQ_TEX_MIRROR;
case PIPE_TEX_WRAP_MIRROR_CLAMP:
return V_03C000_SQ_TEX_MIRROR_ONCE_HALF_BORDER;
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
return V_03C000_SQ_TEX_MIRROR_ONCE_LAST_TEXEL;
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
return V_03C000_SQ_TEX_MIRROR_ONCE_BORDER;
}
}
static unsigned r600_tex_filter(unsigned filter)
{
switch (filter) {
default:
case PIPE_TEX_FILTER_NEAREST:
return V_03C000_SQ_TEX_XY_FILTER_POINT;
case PIPE_TEX_FILTER_LINEAR:
return V_03C000_SQ_TEX_XY_FILTER_BILINEAR;
}
}
static unsigned r600_tex_mipfilter(unsigned filter)
{
switch (filter) {
case PIPE_TEX_MIPFILTER_NEAREST:
return V_03C000_SQ_TEX_Z_FILTER_POINT;
case PIPE_TEX_MIPFILTER_LINEAR:
return V_03C000_SQ_TEX_Z_FILTER_LINEAR;
default:
case PIPE_TEX_MIPFILTER_NONE:
return V_03C000_SQ_TEX_Z_FILTER_NONE;
}
}
static unsigned r600_tex_compare(unsigned compare)
{
switch (compare) {
default:
case PIPE_FUNC_NEVER:
return V_03C000_SQ_TEX_DEPTH_COMPARE_NEVER;
case PIPE_FUNC_LESS:
return V_03C000_SQ_TEX_DEPTH_COMPARE_LESS;
case PIPE_FUNC_EQUAL:
return V_03C000_SQ_TEX_DEPTH_COMPARE_EQUAL;
case PIPE_FUNC_LEQUAL:
return V_03C000_SQ_TEX_DEPTH_COMPARE_LESSEQUAL;
case PIPE_FUNC_GREATER:
return V_03C000_SQ_TEX_DEPTH_COMPARE_GREATER;
case PIPE_FUNC_NOTEQUAL:
return V_03C000_SQ_TEX_DEPTH_COMPARE_NOTEQUAL;
case PIPE_FUNC_GEQUAL:
return V_03C000_SQ_TEX_DEPTH_COMPARE_GREATEREQUAL;
case PIPE_FUNC_ALWAYS:
return V_03C000_SQ_TEX_DEPTH_COMPARE_ALWAYS;
}
}
static unsigned r600_tex_dim(unsigned dim)
{
switch (dim) {
default:
case PIPE_TEXTURE_1D:
return V_038000_SQ_TEX_DIM_1D;
case PIPE_TEXTURE_1D_ARRAY:
return V_038000_SQ_TEX_DIM_1D_ARRAY;
case PIPE_TEXTURE_2D:
case PIPE_TEXTURE_RECT:
return V_038000_SQ_TEX_DIM_2D;
case PIPE_TEXTURE_2D_ARRAY:
return V_038000_SQ_TEX_DIM_2D_ARRAY;
case PIPE_TEXTURE_3D:
return V_038000_SQ_TEX_DIM_3D;
case PIPE_TEXTURE_CUBE:
return V_038000_SQ_TEX_DIM_CUBEMAP;
}
}
static uint32_t r600_translate_dbformat(enum pipe_format format)
{
switch (format) {
case PIPE_FORMAT_Z16_UNORM:
return V_028010_DEPTH_16;
case PIPE_FORMAT_Z24X8_UNORM:
return V_028010_DEPTH_X8_24;
case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
return V_028010_DEPTH_8_24;
case PIPE_FORMAT_Z32_FLOAT:
return V_028010_DEPTH_32_FLOAT;
case PIPE_FORMAT_Z32_FLOAT_S8X24_USCALED:
return V_028010_DEPTH_X24_8_32_FLOAT;
default:
return ~0U;
}
}
static uint32_t r600_translate_colorswap(enum pipe_format format)
{
switch (format) {
/* 8-bit buffers. */
case PIPE_FORMAT_A8_UNORM:
return V_0280A0_SWAP_ALT_REV;
case PIPE_FORMAT_I8_UNORM:
case PIPE_FORMAT_L8_UNORM:
case PIPE_FORMAT_L8_SRGB:
case PIPE_FORMAT_R8_UNORM:
case PIPE_FORMAT_R8_SNORM:
return V_0280A0_SWAP_STD;
case PIPE_FORMAT_L4A4_UNORM:
return V_0280A0_SWAP_ALT;
/* 16-bit buffers. */
case PIPE_FORMAT_B5G6R5_UNORM:
return V_0280A0_SWAP_STD_REV;
case PIPE_FORMAT_B5G5R5A1_UNORM:
case PIPE_FORMAT_B5G5R5X1_UNORM:
return V_0280A0_SWAP_ALT;
case PIPE_FORMAT_B4G4R4A4_UNORM:
case PIPE_FORMAT_B4G4R4X4_UNORM:
return V_0280A0_SWAP_ALT;
case PIPE_FORMAT_Z16_UNORM:
return V_0280A0_SWAP_STD;
case PIPE_FORMAT_L8A8_UNORM:
case PIPE_FORMAT_L8A8_SRGB:
return V_0280A0_SWAP_ALT;
case PIPE_FORMAT_R8G8_UNORM:
return V_0280A0_SWAP_STD;
case PIPE_FORMAT_R16_UNORM:
case PIPE_FORMAT_R16_FLOAT:
return V_0280A0_SWAP_STD;
/* 32-bit buffers. */
case PIPE_FORMAT_A8B8G8R8_SRGB:
return V_0280A0_SWAP_STD_REV;
case PIPE_FORMAT_B8G8R8A8_SRGB:
return V_0280A0_SWAP_ALT;
case PIPE_FORMAT_B8G8R8A8_UNORM:
case PIPE_FORMAT_B8G8R8X8_UNORM:
return V_0280A0_SWAP_ALT;
case PIPE_FORMAT_A8R8G8B8_UNORM:
case PIPE_FORMAT_X8R8G8B8_UNORM:
return V_0280A0_SWAP_ALT_REV;
case PIPE_FORMAT_R8G8B8A8_SNORM:
case PIPE_FORMAT_R8G8B8A8_UNORM:
case PIPE_FORMAT_R8G8B8X8_UNORM:
return V_0280A0_SWAP_STD;
case PIPE_FORMAT_A8B8G8R8_UNORM:
case PIPE_FORMAT_X8B8G8R8_UNORM:
/* case PIPE_FORMAT_R8SG8SB8UX8U_NORM: */
return V_0280A0_SWAP_STD_REV;
case PIPE_FORMAT_Z24X8_UNORM:
case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
return V_0280A0_SWAP_STD;
case PIPE_FORMAT_X8Z24_UNORM:
case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
return V_0280A0_SWAP_STD;
case PIPE_FORMAT_R10G10B10A2_UNORM:
case PIPE_FORMAT_R10G10B10X2_SNORM:
case PIPE_FORMAT_R10SG10SB10SA2U_NORM:
return V_0280A0_SWAP_STD;
case PIPE_FORMAT_B10G10R10A2_UNORM:
return V_0280A0_SWAP_ALT;
case PIPE_FORMAT_R11G11B10_FLOAT:
case PIPE_FORMAT_R16G16_UNORM:
case PIPE_FORMAT_R16G16_FLOAT:
case PIPE_FORMAT_R32_FLOAT:
case PIPE_FORMAT_Z32_FLOAT:
return V_0280A0_SWAP_STD;
/* 64-bit buffers. */
case PIPE_FORMAT_R32G32_FLOAT:
case PIPE_FORMAT_R16G16B16A16_UNORM:
case PIPE_FORMAT_R16G16B16A16_SNORM:
case PIPE_FORMAT_R16G16B16A16_FLOAT:
case PIPE_FORMAT_Z32_FLOAT_S8X24_USCALED:
/* 128-bit buffers. */
case PIPE_FORMAT_R32G32B32A32_FLOAT:
case PIPE_FORMAT_R32G32B32A32_SNORM:
case PIPE_FORMAT_R32G32B32A32_UNORM:
return V_0280A0_SWAP_STD;
default:
R600_ERR("unsupported colorswap format %d\n", format);
return ~0U;
}
return ~0U;
}
static uint32_t r600_translate_colorformat(enum pipe_format format)
{
switch (format) {
case PIPE_FORMAT_L4A4_UNORM:
return V_0280A0_COLOR_4_4;
/* 8-bit buffers. */
case PIPE_FORMAT_A8_UNORM:
case PIPE_FORMAT_I8_UNORM:
case PIPE_FORMAT_L8_UNORM:
case PIPE_FORMAT_L8_SRGB:
case PIPE_FORMAT_R8_UNORM:
case PIPE_FORMAT_R8_SNORM:
return V_0280A0_COLOR_8;
/* 16-bit buffers. */
case PIPE_FORMAT_B5G6R5_UNORM:
return V_0280A0_COLOR_5_6_5;
case PIPE_FORMAT_B5G5R5A1_UNORM:
case PIPE_FORMAT_B5G5R5X1_UNORM:
return V_0280A0_COLOR_1_5_5_5;
case PIPE_FORMAT_B4G4R4A4_UNORM:
case PIPE_FORMAT_B4G4R4X4_UNORM:
return V_0280A0_COLOR_4_4_4_4;
case PIPE_FORMAT_Z16_UNORM:
return V_0280A0_COLOR_16;
case PIPE_FORMAT_L8A8_UNORM:
case PIPE_FORMAT_L8A8_SRGB:
case PIPE_FORMAT_R8G8_UNORM:
return V_0280A0_COLOR_8_8;
case PIPE_FORMAT_R16_UNORM:
return V_0280A0_COLOR_16;
case PIPE_FORMAT_R16_FLOAT:
return V_0280A0_COLOR_16_FLOAT;
/* 32-bit buffers. */
case PIPE_FORMAT_A8B8G8R8_SRGB:
case PIPE_FORMAT_A8B8G8R8_UNORM:
case PIPE_FORMAT_A8R8G8B8_UNORM:
case PIPE_FORMAT_B8G8R8A8_SRGB:
case PIPE_FORMAT_B8G8R8A8_UNORM:
case PIPE_FORMAT_B8G8R8X8_UNORM:
case PIPE_FORMAT_R8G8B8A8_SNORM:
case PIPE_FORMAT_R8G8B8A8_UNORM:
case PIPE_FORMAT_R8G8B8X8_UNORM:
case PIPE_FORMAT_R8SG8SB8UX8U_NORM:
case PIPE_FORMAT_X8B8G8R8_UNORM:
case PIPE_FORMAT_X8R8G8B8_UNORM:
case PIPE_FORMAT_R8G8B8_UNORM:
return V_0280A0_COLOR_8_8_8_8;
case PIPE_FORMAT_R10G10B10A2_UNORM:
case PIPE_FORMAT_R10G10B10X2_SNORM:
case PIPE_FORMAT_B10G10R10A2_UNORM:
case PIPE_FORMAT_R10SG10SB10SA2U_NORM:
return V_0280A0_COLOR_2_10_10_10;
case PIPE_FORMAT_Z24X8_UNORM:
case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
return V_0280A0_COLOR_8_24;
case PIPE_FORMAT_X8Z24_UNORM:
case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
return V_0280A0_COLOR_24_8;
case PIPE_FORMAT_Z32_FLOAT_S8X24_USCALED:
return V_0280A0_COLOR_X24_8_32_FLOAT;
case PIPE_FORMAT_R32_FLOAT:
case PIPE_FORMAT_Z32_FLOAT:
return V_0280A0_COLOR_32_FLOAT;
case PIPE_FORMAT_R16G16_FLOAT:
return V_0280A0_COLOR_16_16_FLOAT;
case PIPE_FORMAT_R16G16_SSCALED:
case PIPE_FORMAT_R16G16_UNORM:
return V_0280A0_COLOR_16_16;
case PIPE_FORMAT_R11G11B10_FLOAT:
return V_0280A0_COLOR_10_11_11_FLOAT;
/* 64-bit buffers. */
case PIPE_FORMAT_R16G16B16_USCALED:
case PIPE_FORMAT_R16G16B16A16_USCALED:
case PIPE_FORMAT_R16G16B16_SSCALED:
case PIPE_FORMAT_R16G16B16A16_SSCALED:
case PIPE_FORMAT_R16G16B16A16_UNORM:
case PIPE_FORMAT_R16G16B16A16_SNORM:
return V_0280A0_COLOR_16_16_16_16;
case PIPE_FORMAT_R16G16B16_FLOAT:
case PIPE_FORMAT_R16G16B16A16_FLOAT:
return V_0280A0_COLOR_16_16_16_16_FLOAT;
case PIPE_FORMAT_R32G32_FLOAT:
return V_0280A0_COLOR_32_32_FLOAT;
case PIPE_FORMAT_R32G32_USCALED:
case PIPE_FORMAT_R32G32_SSCALED:
return V_0280A0_COLOR_32_32;
/* 96-bit buffers. */
case PIPE_FORMAT_R32G32B32_FLOAT:
return V_0280A0_COLOR_32_32_32_FLOAT;
/* 128-bit buffers. */
case PIPE_FORMAT_R32G32B32A32_FLOAT:
return V_0280A0_COLOR_32_32_32_32_FLOAT;
case PIPE_FORMAT_R32G32B32A32_SNORM:
case PIPE_FORMAT_R32G32B32A32_UNORM:
return V_0280A0_COLOR_32_32_32_32;
/* YUV buffers. */
case PIPE_FORMAT_UYVY:
case PIPE_FORMAT_YUYV:
default:
return ~0U; /* Unsupported. */
}
}
static uint32_t r600_colorformat_endian_swap(uint32_t colorformat)
{
if (R600_BIG_ENDIAN) {
switch(colorformat) {
case V_0280A0_COLOR_4_4:
return ENDIAN_NONE;
/* 8-bit buffers. */
case V_0280A0_COLOR_8:
return ENDIAN_NONE;
/* 16-bit buffers. */
case V_0280A0_COLOR_5_6_5:
case V_0280A0_COLOR_1_5_5_5:
case V_0280A0_COLOR_4_4_4_4:
case V_0280A0_COLOR_16:
case V_0280A0_COLOR_8_8:
return ENDIAN_8IN16;
/* 32-bit buffers. */
case V_0280A0_COLOR_8_8_8_8:
case V_0280A0_COLOR_2_10_10_10:
case V_0280A0_COLOR_8_24:
case V_0280A0_COLOR_24_8:
case V_0280A0_COLOR_32_FLOAT:
case V_0280A0_COLOR_16_16_FLOAT:
case V_0280A0_COLOR_16_16:
return ENDIAN_8IN32;
/* 64-bit buffers. */
case V_0280A0_COLOR_16_16_16_16:
case V_0280A0_COLOR_16_16_16_16_FLOAT:
return ENDIAN_8IN16;
case V_0280A0_COLOR_32_32_FLOAT:
case V_0280A0_COLOR_32_32:
case V_0280A0_COLOR_X24_8_32_FLOAT:
return ENDIAN_8IN32;
/* 128-bit buffers. */
case V_0280A0_COLOR_32_32_32_FLOAT:
case V_0280A0_COLOR_32_32_32_32_FLOAT:
case V_0280A0_COLOR_32_32_32_32:
return ENDIAN_8IN32;
default:
return ENDIAN_NONE; /* Unsupported. */
}
} else {
return ENDIAN_NONE;
}
}
static bool r600_is_sampler_format_supported(struct pipe_screen *screen, enum pipe_format format)
{
return r600_translate_texformat(screen, format, NULL, NULL, NULL) != ~0U;
}
static bool r600_is_colorbuffer_format_supported(enum pipe_format format)
{
return r600_translate_colorformat(format) != ~0U &&
r600_translate_colorswap(format) != ~0U;
}
static bool r600_is_zs_format_supported(enum pipe_format format)
{
return r600_translate_dbformat(format) != ~0U;
}
boolean r600_is_format_supported(struct pipe_screen *screen,
enum pipe_format format,
enum pipe_texture_target target,
unsigned sample_count,
unsigned usage)
{
unsigned retval = 0;
if (target >= PIPE_MAX_TEXTURE_TYPES) {
R600_ERR("r600: unsupported texture type %d\n", target);
return FALSE;
}
if (!util_format_is_supported(format, usage))
return FALSE;
/* Multisample */
if (sample_count > 1)
return FALSE;
if ((usage & PIPE_BIND_SAMPLER_VIEW) &&
r600_is_sampler_format_supported(screen, format)) {
retval |= PIPE_BIND_SAMPLER_VIEW;
}
if ((usage & (PIPE_BIND_RENDER_TARGET |
PIPE_BIND_DISPLAY_TARGET |
PIPE_BIND_SCANOUT |
PIPE_BIND_SHARED)) &&
r600_is_colorbuffer_format_supported(format)) {
retval |= usage &
(PIPE_BIND_RENDER_TARGET |
PIPE_BIND_DISPLAY_TARGET |
PIPE_BIND_SCANOUT |
PIPE_BIND_SHARED);
}
if ((usage & PIPE_BIND_DEPTH_STENCIL) &&
r600_is_zs_format_supported(format)) {
retval |= PIPE_BIND_DEPTH_STENCIL;
}
if ((usage & PIPE_BIND_VERTEX_BUFFER) &&
r600_is_vertex_format_supported(format)) {
retval |= PIPE_BIND_VERTEX_BUFFER;
}
if (usage & PIPE_BIND_TRANSFER_READ)
retval |= PIPE_BIND_TRANSFER_READ;
if (usage & PIPE_BIND_TRANSFER_WRITE)
retval |= PIPE_BIND_TRANSFER_WRITE;
return retval == usage;
}
void r600_polygon_offset_update(struct r600_pipe_context *rctx)
{
@ -63,6 +646,7 @@ void r600_polygon_offset_update(struct r600_pipe_context *rctx)
offset_units *= 2.0f;
break;
case PIPE_FORMAT_Z32_FLOAT:
case PIPE_FORMAT_Z32_FLOAT_S8X24_USCALED:
depth = -23;
offset_units *= 1.0f;
offset_db_fmt_cntl |= S_028DF8_POLY_OFFSET_DB_IS_FLOAT_FMT(1);
@ -831,7 +1415,7 @@ static void r600_cb(struct r600_pipe_context *rctx, struct r600_pipe_state *rsta
/* EXPORT_NORM is an optimzation that can be enabled for better
* performance in certain cases
*/
if (rctx->family < CHIP_RV770) {
if (rctx->chip_class == R600) {
/* EXPORT_NORM can be enabled if:
* - 11-bit or smaller UNORM/SNORM/SRGB
* - BLEND_CLAMP is enabled
@ -992,7 +1576,7 @@ static void r600_set_framebuffer_state(struct pipe_context *ctx,
r600_pipe_state_add_reg(rstate,
R_028200_PA_SC_WINDOW_OFFSET, 0x00000000,
0xFFFFFFFF, NULL);
if (rctx->family >= CHIP_RV770) {
if (rctx->chip_class >= R700) {
r600_pipe_state_add_reg(rstate,
R_028230_PA_SC_EDGERULE, 0xAAAAAAAA,
0xFFFFFFFF, NULL);
@ -1086,16 +1670,13 @@ void r600_init_state_functions(struct r600_pipe_context *rctx)
void r600_adjust_gprs(struct r600_pipe_context *rctx)
{
enum radeon_family family;
struct r600_pipe_state rstate;
unsigned num_ps_gprs = rctx->default_ps_gprs;
unsigned num_vs_gprs = rctx->default_vs_gprs;
unsigned tmp;
int diff;
family = r600_get_family(rctx->radeon);
if (family >= CHIP_CEDAR)
if (rctx->chip_class >= EVERGREEN)
return;
if (!rctx->ps_shader && !rctx->vs_shader)
@ -1147,7 +1728,7 @@ void r600_init_config(struct r600_pipe_context *rctx)
struct r600_pipe_state *rstate = &rctx->config;
u32 tmp;
family = r600_get_family(rctx->radeon);
family = rctx->family;
ps_prio = 0;
vs_prio = 1;
gs_prio = 2;
@ -1328,7 +1909,7 @@ void r600_init_config(struct r600_pipe_context *rctx)
r600_pipe_state_add_reg(rstate, R_009714_VC_ENHANCE, 0x00000000, 0xFFFFFFFF, NULL);
r600_pipe_state_add_reg(rstate, R_028350_SX_MISC, 0x00000000, 0xFFFFFFFF, NULL);
if (family >= CHIP_RV770) {
if (rctx->chip_class >= R700) {
r600_pipe_state_add_reg(rstate, R_008D8C_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, 0x00004000, 0xFFFFFFFF, NULL);
r600_pipe_state_add_reg(rstate, R_009508_TA_CNTL_AUX,
S_009508_DISABLE_CUBE_ANISO(1) |

View file

@ -109,7 +109,7 @@ void r600_bind_rs_state(struct pipe_context *ctx, void *state)
rctx->states[rs->rstate.id] = &rs->rstate;
r600_context_pipe_state_set(&rctx->ctx, &rs->rstate);
if (rctx->family >= CHIP_CEDAR) {
if (rctx->chip_class >= EVERGREEN) {
evergreen_polygon_offset_update(rctx);
} else {
r600_polygon_offset_update(rctx);
@ -212,7 +212,7 @@ void r600_set_vertex_buffers(struct pipe_context *ctx, unsigned count,
/* Zero states. */
for (i = 0; i < count; i++) {
if (!buffers[i].buffer) {
if (rctx->family >= CHIP_CEDAR) {
if (rctx->chip_class >= EVERGREEN) {
evergreen_context_pipe_state_set_fs_resource(&rctx->ctx, NULL, i);
} else {
r600_context_pipe_state_set_fs_resource(&rctx->ctx, NULL, i);
@ -220,7 +220,7 @@ void r600_set_vertex_buffers(struct pipe_context *ctx, unsigned count,
}
}
for (; i < rctx->vbuf_mgr->nr_real_vertex_buffers; i++) {
if (rctx->family >= CHIP_CEDAR) {
if (rctx->chip_class >= EVERGREEN) {
evergreen_context_pipe_state_set_fs_resource(&rctx->ctx, NULL, i);
} else {
r600_context_pipe_state_set_fs_resource(&rctx->ctx, NULL, i);
@ -367,7 +367,7 @@ static void r600_spi_update(struct r600_pipe_context *rctx)
for (i = 0; i < rshader->ninput; i++) {
if (rshader->input[i].name == TGSI_SEMANTIC_POSITION ||
rshader->input[i].name == TGSI_SEMANTIC_FACE)
if (rctx->family >= CHIP_CEDAR)
if (rctx->chip_class >= EVERGREEN)
continue;
else
sid=0;
@ -387,7 +387,7 @@ static void r600_spi_update(struct r600_pipe_context *rctx)
tmp |= S_028644_PT_SPRITE_TEX(1);
}
if (rctx->family < CHIP_CEDAR) {
if (rctx->chip_class < EVERGREEN) {
if (rshader->input[i].centroid)
tmp |= S_028644_SEL_CENTROID(1);
@ -434,14 +434,14 @@ void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index,
rstate = &rctx->vs_const_buffer_resource[index];
if (!rstate->id) {
if (rctx->family >= CHIP_CEDAR) {
if (rctx->chip_class >= EVERGREEN) {
evergreen_pipe_init_buffer_resource(rctx, rstate);
} else {
r600_pipe_init_buffer_resource(rctx, rstate);
}
}
if (rctx->family >= CHIP_CEDAR) {
if (rctx->chip_class >= EVERGREEN) {
evergreen_pipe_mod_buffer_resource(rstate, &rbuffer->r, offset, 16);
evergreen_context_pipe_state_set_vs_resource(&rctx->ctx, rstate, index);
} else {
@ -462,13 +462,13 @@ void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index,
rstate = &rctx->ps_const_buffer_resource[index];
if (!rstate->id) {
if (rctx->family >= CHIP_CEDAR) {
if (rctx->chip_class >= EVERGREEN) {
evergreen_pipe_init_buffer_resource(rctx, rstate);
} else {
r600_pipe_init_buffer_resource(rctx, rstate);
}
}
if (rctx->family >= CHIP_CEDAR) {
if (rctx->chip_class >= EVERGREEN) {
evergreen_pipe_mod_buffer_resource(rstate, &rbuffer->r, offset, 16);
evergreen_context_pipe_state_set_ps_resource(&rctx->ctx, rstate, index);
} else {
@ -521,14 +521,14 @@ static void r600_vertex_buffer_update(struct r600_pipe_context *rctx)
offset += vertex_buffer->buffer_offset + r600_bo_offset(rbuffer->bo);
if (!rstate->id) {
if (rctx->family >= CHIP_CEDAR) {
if (rctx->chip_class >= EVERGREEN) {
evergreen_pipe_init_buffer_resource(rctx, rstate);
} else {
r600_pipe_init_buffer_resource(rctx, rstate);
}
}
if (rctx->family >= CHIP_CEDAR) {
if (rctx->chip_class >= EVERGREEN) {
evergreen_pipe_mod_buffer_resource(rstate, rbuffer, offset, vertex_buffer->stride);
evergreen_context_pipe_state_set_fs_resource(&rctx->ctx, rstate, i);
} else {
@ -600,7 +600,7 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
r600_shader_rebuild(ctx, rctx->vs_shader);
if ((rctx->ps_shader->shader.clamp_color != rctx->clamp_fragment_color) ||
((rctx->family >= CHIP_CEDAR) && rctx->ps_shader->shader.fs_write_all &&
((rctx->chip_class >= EVERGREEN) && rctx->ps_shader->shader.fs_write_all &&
(rctx->ps_shader->shader.nr_cbufs != rctx->nr_cbufs)))
r600_shader_rebuild(ctx, rctx->ps_shader);
@ -655,7 +655,7 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
rdraw.indices_bo_offset = draw.index_buffer_offset;
}
if (rctx->family >= CHIP_CEDAR) {
if (rctx->chip_class >= EVERGREEN) {
evergreen_context_draw(&rctx->ctx, &rdraw);
} else {
r600_context_draw(&rctx->ctx, &rdraw);

View file

@ -1,614 +0,0 @@
/*
* Copyright 2010 Red Hat 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
* on 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
* THE AUTHOR(S) AND/OR THEIR 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 R600_STATE_INLINES_H
#define R600_STATE_INLINES_H
#include "util/u_format.h"
#include "r600d.h"
#include "r600_formats.h"
static INLINE uint32_t r600_translate_blend_function(int blend_func)
{
switch (blend_func) {
case PIPE_BLEND_ADD:
return V_028804_COMB_DST_PLUS_SRC;
case PIPE_BLEND_SUBTRACT:
return V_028804_COMB_SRC_MINUS_DST;
case PIPE_BLEND_REVERSE_SUBTRACT:
return V_028804_COMB_DST_MINUS_SRC;
case PIPE_BLEND_MIN:
return V_028804_COMB_MIN_DST_SRC;
case PIPE_BLEND_MAX:
return V_028804_COMB_MAX_DST_SRC;
default:
R600_ERR("Unknown blend function %d\n", blend_func);
assert(0);
break;
}
return 0;
}
static INLINE uint32_t r600_translate_blend_factor(int blend_fact)
{
switch (blend_fact) {
case PIPE_BLENDFACTOR_ONE:
return V_028804_BLEND_ONE;
case PIPE_BLENDFACTOR_SRC_COLOR:
return V_028804_BLEND_SRC_COLOR;
case PIPE_BLENDFACTOR_SRC_ALPHA:
return V_028804_BLEND_SRC_ALPHA;
case PIPE_BLENDFACTOR_DST_ALPHA:
return V_028804_BLEND_DST_ALPHA;
case PIPE_BLENDFACTOR_DST_COLOR:
return V_028804_BLEND_DST_COLOR;
case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
return V_028804_BLEND_SRC_ALPHA_SATURATE;
case PIPE_BLENDFACTOR_CONST_COLOR:
return V_028804_BLEND_CONST_COLOR;
case PIPE_BLENDFACTOR_CONST_ALPHA:
return V_028804_BLEND_CONST_ALPHA;
case PIPE_BLENDFACTOR_ZERO:
return V_028804_BLEND_ZERO;
case PIPE_BLENDFACTOR_INV_SRC_COLOR:
return V_028804_BLEND_ONE_MINUS_SRC_COLOR;
case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
return V_028804_BLEND_ONE_MINUS_SRC_ALPHA;
case PIPE_BLENDFACTOR_INV_DST_ALPHA:
return V_028804_BLEND_ONE_MINUS_DST_ALPHA;
case PIPE_BLENDFACTOR_INV_DST_COLOR:
return V_028804_BLEND_ONE_MINUS_DST_COLOR;
case PIPE_BLENDFACTOR_INV_CONST_COLOR:
return V_028804_BLEND_ONE_MINUS_CONST_COLOR;
case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
return V_028804_BLEND_ONE_MINUS_CONST_ALPHA;
case PIPE_BLENDFACTOR_SRC1_COLOR:
return V_028804_BLEND_SRC1_COLOR;
case PIPE_BLENDFACTOR_SRC1_ALPHA:
return V_028804_BLEND_SRC1_ALPHA;
case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
return V_028804_BLEND_INV_SRC1_COLOR;
case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
return V_028804_BLEND_INV_SRC1_ALPHA;
default:
R600_ERR("Bad blend factor %d not supported!\n", blend_fact);
assert(0);
break;
}
return 0;
}
static INLINE uint32_t r600_translate_stencil_op(int s_op)
{
switch (s_op) {
case PIPE_STENCIL_OP_KEEP:
return V_028800_STENCIL_KEEP;
case PIPE_STENCIL_OP_ZERO:
return V_028800_STENCIL_ZERO;
case PIPE_STENCIL_OP_REPLACE:
return V_028800_STENCIL_REPLACE;
case PIPE_STENCIL_OP_INCR:
return V_028800_STENCIL_INCR;
case PIPE_STENCIL_OP_DECR:
return V_028800_STENCIL_DECR;
case PIPE_STENCIL_OP_INCR_WRAP:
return V_028800_STENCIL_INCR_WRAP;
case PIPE_STENCIL_OP_DECR_WRAP:
return V_028800_STENCIL_DECR_WRAP;
case PIPE_STENCIL_OP_INVERT:
return V_028800_STENCIL_INVERT;
default:
R600_ERR("Unknown stencil op %d", s_op);
assert(0);
break;
}
return 0;
}
static INLINE uint32_t r600_translate_fill(uint32_t func)
{
switch(func) {
case PIPE_POLYGON_MODE_FILL:
return 2;
case PIPE_POLYGON_MODE_LINE:
return 1;
case PIPE_POLYGON_MODE_POINT:
return 0;
default:
assert(0);
return 0;
}
}
/* translates straight */
static INLINE uint32_t r600_translate_ds_func(int func)
{
return func;
}
static inline unsigned r600_tex_wrap(unsigned wrap)
{
switch (wrap) {
default:
case PIPE_TEX_WRAP_REPEAT:
return V_03C000_SQ_TEX_WRAP;
case PIPE_TEX_WRAP_CLAMP:
return V_03C000_SQ_TEX_CLAMP_HALF_BORDER;
case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
return V_03C000_SQ_TEX_CLAMP_LAST_TEXEL;
case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
return V_03C000_SQ_TEX_CLAMP_BORDER;
case PIPE_TEX_WRAP_MIRROR_REPEAT:
return V_03C000_SQ_TEX_MIRROR;
case PIPE_TEX_WRAP_MIRROR_CLAMP:
return V_03C000_SQ_TEX_MIRROR_ONCE_HALF_BORDER;
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
return V_03C000_SQ_TEX_MIRROR_ONCE_LAST_TEXEL;
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
return V_03C000_SQ_TEX_MIRROR_ONCE_BORDER;
}
}
static inline unsigned r600_tex_filter(unsigned filter)
{
switch (filter) {
default:
case PIPE_TEX_FILTER_NEAREST:
return V_03C000_SQ_TEX_XY_FILTER_POINT;
case PIPE_TEX_FILTER_LINEAR:
return V_03C000_SQ_TEX_XY_FILTER_BILINEAR;
}
}
static inline unsigned r600_tex_mipfilter(unsigned filter)
{
switch (filter) {
case PIPE_TEX_MIPFILTER_NEAREST:
return V_03C000_SQ_TEX_Z_FILTER_POINT;
case PIPE_TEX_MIPFILTER_LINEAR:
return V_03C000_SQ_TEX_Z_FILTER_LINEAR;
default:
case PIPE_TEX_MIPFILTER_NONE:
return V_03C000_SQ_TEX_Z_FILTER_NONE;
}
}
static inline unsigned r600_tex_compare(unsigned compare)
{
switch (compare) {
default:
case PIPE_FUNC_NEVER:
return V_03C000_SQ_TEX_DEPTH_COMPARE_NEVER;
case PIPE_FUNC_LESS:
return V_03C000_SQ_TEX_DEPTH_COMPARE_LESS;
case PIPE_FUNC_EQUAL:
return V_03C000_SQ_TEX_DEPTH_COMPARE_EQUAL;
case PIPE_FUNC_LEQUAL:
return V_03C000_SQ_TEX_DEPTH_COMPARE_LESSEQUAL;
case PIPE_FUNC_GREATER:
return V_03C000_SQ_TEX_DEPTH_COMPARE_GREATER;
case PIPE_FUNC_NOTEQUAL:
return V_03C000_SQ_TEX_DEPTH_COMPARE_NOTEQUAL;
case PIPE_FUNC_GEQUAL:
return V_03C000_SQ_TEX_DEPTH_COMPARE_GREATEREQUAL;
case PIPE_FUNC_ALWAYS:
return V_03C000_SQ_TEX_DEPTH_COMPARE_ALWAYS;
}
}
static inline unsigned r600_tex_swizzle(unsigned swizzle)
{
switch (swizzle) {
case PIPE_SWIZZLE_RED:
return V_038010_SQ_SEL_X;
case PIPE_SWIZZLE_GREEN:
return V_038010_SQ_SEL_Y;
case PIPE_SWIZZLE_BLUE:
return V_038010_SQ_SEL_Z;
case PIPE_SWIZZLE_ALPHA:
return V_038010_SQ_SEL_W;
case PIPE_SWIZZLE_ZERO:
return V_038010_SQ_SEL_0;
default:
case PIPE_SWIZZLE_ONE:
return V_038010_SQ_SEL_1;
}
}
static inline unsigned r600_format_type(unsigned format_type)
{
switch (format_type) {
default:
case UTIL_FORMAT_TYPE_UNSIGNED:
return V_038010_SQ_FORMAT_COMP_UNSIGNED;
case UTIL_FORMAT_TYPE_SIGNED:
return V_038010_SQ_FORMAT_COMP_SIGNED;
case UTIL_FORMAT_TYPE_FIXED:
return V_038010_SQ_FORMAT_COMP_UNSIGNED_BIASED;
}
}
static inline unsigned r600_tex_dim(unsigned dim)
{
switch (dim) {
default:
case PIPE_TEXTURE_1D:
return V_038000_SQ_TEX_DIM_1D;
case PIPE_TEXTURE_1D_ARRAY:
return V_038000_SQ_TEX_DIM_1D_ARRAY;
case PIPE_TEXTURE_2D:
case PIPE_TEXTURE_RECT:
return V_038000_SQ_TEX_DIM_2D;
case PIPE_TEXTURE_2D_ARRAY:
return V_038000_SQ_TEX_DIM_2D_ARRAY;
case PIPE_TEXTURE_3D:
return V_038000_SQ_TEX_DIM_3D;
case PIPE_TEXTURE_CUBE:
return V_038000_SQ_TEX_DIM_CUBEMAP;
}
}
static inline uint32_t r600_translate_dbformat(enum pipe_format format)
{
switch (format) {
case PIPE_FORMAT_Z16_UNORM:
return V_028010_DEPTH_16;
case PIPE_FORMAT_Z24X8_UNORM:
return V_028010_DEPTH_X8_24;
case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
return V_028010_DEPTH_8_24;
default:
return ~0;
}
}
static inline uint32_t r600_translate_colorswap(enum pipe_format format)
{
switch (format) {
/* 8-bit buffers. */
case PIPE_FORMAT_A8_UNORM:
return V_0280A0_SWAP_ALT_REV;
case PIPE_FORMAT_I8_UNORM:
case PIPE_FORMAT_L8_UNORM:
case PIPE_FORMAT_L8_SRGB:
case PIPE_FORMAT_R8_UNORM:
case PIPE_FORMAT_R8_SNORM:
return V_0280A0_SWAP_STD;
case PIPE_FORMAT_L4A4_UNORM:
return V_0280A0_SWAP_ALT;
/* 16-bit buffers. */
case PIPE_FORMAT_B5G6R5_UNORM:
return V_0280A0_SWAP_STD_REV;
case PIPE_FORMAT_B5G5R5A1_UNORM:
case PIPE_FORMAT_B5G5R5X1_UNORM:
return V_0280A0_SWAP_ALT;
case PIPE_FORMAT_B4G4R4A4_UNORM:
case PIPE_FORMAT_B4G4R4X4_UNORM:
return V_0280A0_SWAP_ALT;
case PIPE_FORMAT_Z16_UNORM:
return V_0280A0_SWAP_STD;
case PIPE_FORMAT_L8A8_UNORM:
case PIPE_FORMAT_L8A8_SRGB:
return V_0280A0_SWAP_ALT;
case PIPE_FORMAT_R8G8_UNORM:
return V_0280A0_SWAP_STD;
case PIPE_FORMAT_R16_UNORM:
case PIPE_FORMAT_R16_SNORM:
case PIPE_FORMAT_R16_FLOAT:
return V_0280A0_SWAP_STD;
/* 32-bit buffers. */
case PIPE_FORMAT_A8B8G8R8_SRGB:
return V_0280A0_SWAP_STD_REV;
case PIPE_FORMAT_B8G8R8A8_SRGB:
return V_0280A0_SWAP_ALT;
case PIPE_FORMAT_B8G8R8A8_UNORM:
case PIPE_FORMAT_B8G8R8X8_UNORM:
return V_0280A0_SWAP_ALT;
case PIPE_FORMAT_A8R8G8B8_UNORM:
case PIPE_FORMAT_X8R8G8B8_UNORM:
return V_0280A0_SWAP_ALT_REV;
case PIPE_FORMAT_R8G8B8A8_SNORM:
case PIPE_FORMAT_R8G8B8A8_UNORM:
case PIPE_FORMAT_R8G8B8X8_UNORM:
return V_0280A0_SWAP_STD;
case PIPE_FORMAT_A8B8G8R8_UNORM:
case PIPE_FORMAT_X8B8G8R8_UNORM:
/* case PIPE_FORMAT_R8SG8SB8UX8U_NORM: */
return V_0280A0_SWAP_STD_REV;
case PIPE_FORMAT_Z24X8_UNORM:
case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
return V_0280A0_SWAP_STD;
case PIPE_FORMAT_X8Z24_UNORM:
case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
return V_0280A0_SWAP_STD;
case PIPE_FORMAT_R10G10B10A2_UNORM:
case PIPE_FORMAT_R10G10B10X2_SNORM:
case PIPE_FORMAT_R10SG10SB10SA2U_NORM:
return V_0280A0_SWAP_STD;
case PIPE_FORMAT_B10G10R10A2_UNORM:
return V_0280A0_SWAP_ALT;
case PIPE_FORMAT_R11G11B10_FLOAT:
case PIPE_FORMAT_R16G16_UNORM:
case PIPE_FORMAT_R16G16_FLOAT:
case PIPE_FORMAT_R32_FLOAT:
return V_0280A0_SWAP_STD;
/* 64-bit buffers. */
case PIPE_FORMAT_R32G32_FLOAT:
case PIPE_FORMAT_R16G16B16A16_UNORM:
case PIPE_FORMAT_R16G16B16A16_SNORM:
case PIPE_FORMAT_R16G16B16A16_FLOAT:
/* 128-bit buffers. */
case PIPE_FORMAT_R32G32B32A32_FLOAT:
case PIPE_FORMAT_R32G32B32A32_SNORM:
case PIPE_FORMAT_R32G32B32A32_UNORM:
return V_0280A0_SWAP_STD;
default:
R600_ERR("unsupported colorswap format %d\n", format);
return ~0;
}
return ~0;
}
static INLINE uint32_t r600_translate_colorformat(enum pipe_format format)
{
switch (format) {
case PIPE_FORMAT_L4A4_UNORM:
return V_0280A0_COLOR_4_4;
/* 8-bit buffers. */
case PIPE_FORMAT_A8_UNORM:
case PIPE_FORMAT_I8_UNORM:
case PIPE_FORMAT_L8_UNORM:
case PIPE_FORMAT_L8_SRGB:
case PIPE_FORMAT_R8_UNORM:
case PIPE_FORMAT_R8_SNORM:
return V_0280A0_COLOR_8;
/* 16-bit buffers. */
case PIPE_FORMAT_B5G6R5_UNORM:
return V_0280A0_COLOR_5_6_5;
case PIPE_FORMAT_B5G5R5A1_UNORM:
case PIPE_FORMAT_B5G5R5X1_UNORM:
return V_0280A0_COLOR_1_5_5_5;
case PIPE_FORMAT_B4G4R4A4_UNORM:
case PIPE_FORMAT_B4G4R4X4_UNORM:
return V_0280A0_COLOR_4_4_4_4;
case PIPE_FORMAT_Z16_UNORM:
return V_0280A0_COLOR_16;
case PIPE_FORMAT_L8A8_UNORM:
case PIPE_FORMAT_L8A8_SRGB:
case PIPE_FORMAT_R8G8_UNORM:
return V_0280A0_COLOR_8_8;
case PIPE_FORMAT_R16_UNORM:
case PIPE_FORMAT_R16_SNORM:
return V_0280A0_COLOR_16;
case PIPE_FORMAT_R16_FLOAT:
return V_0280A0_COLOR_16_FLOAT;
/* 32-bit buffers. */
case PIPE_FORMAT_A8B8G8R8_SRGB:
case PIPE_FORMAT_A8B8G8R8_UNORM:
case PIPE_FORMAT_A8R8G8B8_UNORM:
case PIPE_FORMAT_B8G8R8A8_SRGB:
case PIPE_FORMAT_B8G8R8A8_UNORM:
case PIPE_FORMAT_B8G8R8X8_UNORM:
case PIPE_FORMAT_R8G8B8A8_SNORM:
case PIPE_FORMAT_R8G8B8A8_UNORM:
case PIPE_FORMAT_R8G8B8X8_UNORM:
case PIPE_FORMAT_R8SG8SB8UX8U_NORM:
case PIPE_FORMAT_X8B8G8R8_UNORM:
case PIPE_FORMAT_X8R8G8B8_UNORM:
case PIPE_FORMAT_R8G8B8_UNORM:
return V_0280A0_COLOR_8_8_8_8;
case PIPE_FORMAT_R10G10B10A2_UNORM:
case PIPE_FORMAT_R10G10B10X2_SNORM:
case PIPE_FORMAT_B10G10R10A2_UNORM:
case PIPE_FORMAT_R10SG10SB10SA2U_NORM:
return V_0280A0_COLOR_2_10_10_10;
case PIPE_FORMAT_Z24X8_UNORM:
case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
return V_0280A0_COLOR_8_24;
case PIPE_FORMAT_X8Z24_UNORM:
case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
return V_0280A0_COLOR_24_8;
case PIPE_FORMAT_R32_FLOAT:
return V_0280A0_COLOR_32_FLOAT;
case PIPE_FORMAT_R16G16_FLOAT:
return V_0280A0_COLOR_16_16_FLOAT;
case PIPE_FORMAT_R16G16_SSCALED:
case PIPE_FORMAT_R16G16_UNORM:
return V_0280A0_COLOR_16_16;
case PIPE_FORMAT_R11G11B10_FLOAT:
return V_0280A0_COLOR_10_11_11_FLOAT;
/* 64-bit buffers. */
case PIPE_FORMAT_R16G16B16_USCALED:
case PIPE_FORMAT_R16G16B16A16_USCALED:
case PIPE_FORMAT_R16G16B16_SSCALED:
case PIPE_FORMAT_R16G16B16A16_SSCALED:
case PIPE_FORMAT_R16G16B16A16_UNORM:
case PIPE_FORMAT_R16G16B16A16_SNORM:
return V_0280A0_COLOR_16_16_16_16;
case PIPE_FORMAT_R16G16B16_FLOAT:
case PIPE_FORMAT_R16G16B16A16_FLOAT:
return V_0280A0_COLOR_16_16_16_16_FLOAT;
case PIPE_FORMAT_R32G32_FLOAT:
return V_0280A0_COLOR_32_32_FLOAT;
case PIPE_FORMAT_R32G32_USCALED:
case PIPE_FORMAT_R32G32_SSCALED:
return V_0280A0_COLOR_32_32;
/* 96-bit buffers. */
case PIPE_FORMAT_R32G32B32_FLOAT:
return V_0280A0_COLOR_32_32_32_FLOAT;
/* 128-bit buffers. */
case PIPE_FORMAT_R32G32B32A32_FLOAT:
return V_0280A0_COLOR_32_32_32_32_FLOAT;
case PIPE_FORMAT_R32G32B32A32_SNORM:
case PIPE_FORMAT_R32G32B32A32_UNORM:
return V_0280A0_COLOR_32_32_32_32;
/* YUV buffers. */
case PIPE_FORMAT_UYVY:
case PIPE_FORMAT_YUYV:
default:
return ~0; /* Unsupported. */
}
}
static INLINE uint32_t r600_colorformat_endian_swap(uint32_t colorformat)
{
if (R600_BIG_ENDIAN) {
switch(colorformat) {
case V_0280A0_COLOR_4_4:
return(ENDIAN_NONE);
/* 8-bit buffers. */
case V_0280A0_COLOR_8:
return(ENDIAN_NONE);
/* 16-bit buffers. */
case V_0280A0_COLOR_5_6_5:
case V_0280A0_COLOR_1_5_5_5:
case V_0280A0_COLOR_4_4_4_4:
case V_0280A0_COLOR_16:
case V_0280A0_COLOR_8_8:
return(ENDIAN_8IN16);
/* 32-bit buffers. */
case V_0280A0_COLOR_8_8_8_8:
case V_0280A0_COLOR_2_10_10_10:
case V_0280A0_COLOR_8_24:
case V_0280A0_COLOR_24_8:
case V_0280A0_COLOR_32_FLOAT:
case V_0280A0_COLOR_16_16_FLOAT:
case V_0280A0_COLOR_16_16:
return(ENDIAN_8IN32);
/* 64-bit buffers. */
case V_0280A0_COLOR_16_16_16_16:
case V_0280A0_COLOR_16_16_16_16_FLOAT:
return(ENDIAN_8IN16);
case V_0280A0_COLOR_32_32_FLOAT:
case V_0280A0_COLOR_32_32:
return(ENDIAN_8IN32);
/* 128-bit buffers. */
case V_0280A0_COLOR_32_32_32_FLOAT:
case V_0280A0_COLOR_32_32_32_32_FLOAT:
case V_0280A0_COLOR_32_32_32_32:
return(ENDIAN_8IN32);
default:
return ENDIAN_NONE; /* Unsupported. */
}
} else {
return ENDIAN_NONE;
}
}
static INLINE boolean r600_is_sampler_format_supported(struct pipe_screen *screen, enum pipe_format format)
{
return r600_translate_texformat(screen, format, NULL, NULL, NULL) != ~0;
}
static INLINE boolean r600_is_colorbuffer_format_supported(enum pipe_format format)
{
return r600_translate_colorformat(format) != ~0 &&
r600_translate_colorswap(format) != ~0;
}
static INLINE boolean r600_is_zs_format_supported(enum pipe_format format)
{
return r600_translate_dbformat(format) != ~0;
}
static INLINE boolean r600_is_vertex_format_supported(enum pipe_format format,
enum radeon_family family)
{
unsigned i;
const struct util_format_description *desc = util_format_description(format);
if (!desc)
return FALSE;
/* Find the first non-VOID channel. */
for (i = 0; i < 4; i++) {
if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) {
break;
}
}
if (i == 4)
return FALSE;
/* No fixed, no double. */
if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN ||
desc->channel[i].type == UTIL_FORMAT_TYPE_FIXED ||
(desc->channel[i].size == 64 &&
desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT))
return FALSE;
/* No scaled/norm formats with 32 bits per channel. */
if (desc->channel[i].size == 32 &&
(desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED ||
desc->channel[i].type == UTIL_FORMAT_TYPE_UNSIGNED))
return FALSE;
return TRUE;
}
#endif

View file

@ -35,7 +35,6 @@
#include "pipebuffer/pb_buffer.h"
#include "r600_pipe.h"
#include "r600_resource.h"
#include "r600_state_inlines.h"
#include "r600d.h"
#include "r600_formats.h"
@ -861,6 +860,12 @@ uint32_t r600_translate_texformat(struct pipe_screen *screen,
result = FMT_8;
word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT);
goto out_word4;
case PIPE_FORMAT_Z32_FLOAT:
result = FMT_32_FLOAT;
goto out_word4;
case PIPE_FORMAT_Z32_FLOAT_S8X24_USCALED:
result = FMT_X24_8_32_FLOAT;
goto out_word4;
default:
goto out_unknown;
}

View file

@ -189,7 +189,8 @@ convert_quad_depth( struct depth_data *data,
/**
* Compute the depth_data::shader_stencil_refs[] values from the float fragment stencil values.
* Compute the depth_data::shader_stencil_refs[] values from the float
* fragment stencil values.
*/
static void
convert_quad_stencil( struct depth_data *data,
@ -205,10 +206,9 @@ convert_quad_stencil( struct depth_data *data,
case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
case PIPE_FORMAT_X8Z24_UNORM:
case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
{
for (j = 0; j < QUAD_SIZE; j++) {
data->shader_stencil_refs[j] = ((unsigned)(quad->output.stencil[j]));
}
case PIPE_FORMAT_S8_USCALED:
for (j = 0; j < QUAD_SIZE; j++) {
data->shader_stencil_refs[j] = ((unsigned)(quad->output.stencil[j]));
}
break;
default:
@ -216,6 +216,7 @@ convert_quad_stencil( struct depth_data *data,
}
}
/**
* Write data->bzzzz[] values and data->stencilVals into the Z/stencil buffer.
*/

View file

@ -143,8 +143,6 @@ dri_unbind_context(__DRIcontext * cPriv)
/* dri_util.c ensures cPriv is not null */
struct dri_screen *screen = dri_screen(cPriv->driScreenPriv);
struct dri_context *ctx = dri_context(cPriv);
struct dri_drawable *draw = dri_drawable(ctx->dPriv);
struct dri_drawable *read = dri_drawable(ctx->rPriv);
struct st_api *stapi = screen->st_api;
if (--ctx->bind_count == 0) {

View file

@ -452,6 +452,12 @@ dri2InvalidateBuffers(Display *dpy, XID drawable)
extern unsigned
dri2GetSwapEventType(Display *dpy, XID drawable);
extern void *
dri2GetGlxDrawableFromXDrawableId(Display *dpy, XID id);
extern void *
GetGLXDrawable(Display *dpy, XID drawable);
/**
* This is also called from src/glx/dri2.c.
*/
@ -460,4 +466,16 @@ unsigned dri2GetSwapEventType(Display *dpy, XID drawable)
return 0;
}
void *
dri2GetGlxDrawableFromXDrawableId(Display *dpy, XID id)
{
return NULL;
}
void *
GetGLXDrawable(Display *dpy, XID drawable)
{
return NULL;
}
#endif /* GLX_DIRECT_RENDERING */

View file

@ -79,6 +79,25 @@ static const struct xa_composite_blend xa_blends[] = {
};
/*
* The alpha value stored in a luminance texture is read by the
* hardware as color.
*/
static unsigned
xa_convert_blend_for_luminance(unsigned factor)
{
switch(factor) {
case PIPE_BLENDFACTOR_DST_ALPHA:
return PIPE_BLENDFACTOR_DST_COLOR;
case PIPE_BLENDFACTOR_INV_DST_ALPHA:
return PIPE_BLENDFACTOR_INV_DST_COLOR;
default:
break;
}
return factor;
}
static boolean
blend_for_op(struct xa_composite_blend *blend,
enum xa_composite_op op,
@ -91,10 +110,16 @@ blend_for_op(struct xa_composite_blend *blend,
int i;
boolean supported = FALSE;
/*
* Temporarily disable component alpha since it appears buggy.
*/
if (src_pic->component_alpha ||
(mask_pic && mask_pic->component_alpha))
return FALSE;
/*
* our default in case something goes wrong
*/
*blend = xa_blends[XA_BLEND_OP_OVER];
for (i = 0; i < num_blends; ++i) {
@ -104,15 +129,20 @@ blend_for_op(struct xa_composite_blend *blend,
}
}
if (!dst_pic->srf)
return supported;
if (dst_pic->srf->tex->format == PIPE_FORMAT_L8_UNORM) {
blend->rgb_src = xa_convert_blend_for_luminance(blend->rgb_src);
blend->rgb_dst = xa_convert_blend_for_luminance(blend->rgb_dst);
}
/*
* If there's no dst alpha channel, adjust the blend op so that we'll treat
* it as always 1.
*/
if (dst_pic &&
xa_format_a(dst_pic->pict_format) == 0 &&
blend->alpha_dst) {
if (xa_format_a(dst_pic->pict_format) == 0 && blend->alpha_dst) {
if (blend->rgb_src == PIPE_BLENDFACTOR_DST_ALPHA)
blend->rgb_src = PIPE_BLENDFACTOR_ONE;
else if (blend->rgb_src == PIPE_BLENDFACTOR_INV_DST_ALPHA)
@ -191,13 +221,13 @@ xa_composite_check_accelerated(const struct xa_composite *comp)
if (!xa_is_filter_accelerated(src_pic) ||
!xa_is_filter_accelerated(comp->mask)) {
return XA_ERR_INVAL;
return -XA_ERR_INVAL;
}
if (src_pic->src_pict) {
if (src_pic->src_pict->type != xa_src_pict_solid_fill)
return XA_ERR_INVAL;
return -XA_ERR_INVAL;
}
if (blend_for_op(&blend, comp->op, comp->src, comp->mask, comp->dst)) {
@ -205,23 +235,24 @@ xa_composite_check_accelerated(const struct xa_composite *comp)
if (mask && mask->component_alpha &&
xa_format_rgb(mask->pict_format)) {
if (blend.alpha_src && blend.rgb_src != PIPE_BLENDFACTOR_ZERO) {
return XA_ERR_INVAL;
return -XA_ERR_INVAL;
}
}
return XA_ERR_NONE;
}
return XA_ERR_INVAL;
return -XA_ERR_INVAL;
}
static void
static int
bind_composite_blend_state(struct xa_context *ctx,
const struct xa_composite *comp)
{
struct xa_composite_blend blend_opt;
struct pipe_blend_state blend;
blend_for_op(&blend_opt, comp->op, comp->src, comp->mask, comp->dst);
if (!blend_for_op(&blend_opt, comp->op, comp->src, comp->mask, comp->dst))
return -XA_ERR_INVAL;
memset(&blend, 0, sizeof(struct pipe_blend_state));
blend.rt[0].blend_enable = 1;
@ -233,11 +264,11 @@ bind_composite_blend_state(struct xa_context *ctx,
blend.rt[0].alpha_dst_factor = blend_opt.rgb_dst;
cso_set_blend(ctx->cso, &blend);
return XA_ERR_NONE;
}
static unsigned int
picture_format_fixups(struct xa_picture *src_pic,
struct xa_picture *dst_pic,
int mask)
{
boolean set_alpha = FALSE;
@ -253,22 +284,17 @@ picture_format_fixups(struct xa_picture *src_pic,
src_hw_format = xa_surface_format(src);
src_pic_format = src_pic->pict_format;
if (!src || src_hw_format == src_pic_format) {
if (src_pic_format == xa_format_a8) {
if (mask)
return FS_MASK_LUMINANCE;
else if (dst_pic->pict_format != xa_format_a8) {
set_alpha = (xa_format_type_is_color(src_pic_format) &&
xa_format_a(src_pic_format) == 0);
/*
* if both dst and src are luminance then
* we don't want to swizzle the alpha (X) of the
* source into W component of the dst because
* it will break our destination
*/
return FS_SRC_LUMINANCE;
}
}
return 0;
if (set_alpha)
ret |= mask ? FS_MASK_SET_ALPHA : FS_SRC_SET_ALPHA;
if (src_hw_format == src_pic_format) {
if (src->tex->format == PIPE_FORMAT_L8_UNORM)
return ((mask) ? FS_MASK_LUMINANCE : FS_SRC_LUMINANCE);
return ret;
}
src_hw_type = xa_format_type(src_hw_format);
@ -280,27 +306,21 @@ picture_format_fixups(struct xa_picture *src_pic,
src_pic_type == xa_type_argb)));
if (!swizzle && (src_hw_type != src_pic_type))
return 0;
return ret;
set_alpha = (xa_format_type_is_color(src_pic_format) &&
xa_format_a(src_pic_type) == 0);
if (set_alpha)
ret |= mask ? FS_MASK_SET_ALPHA : FS_SRC_SET_ALPHA;
if (swizzle)
ret |= mask ? FS_MASK_SWIZZLE_RGB : FS_SRC_SWIZZLE_RGB;
return ret;
}
static void
static int
bind_shaders(struct xa_context *ctx, const struct xa_composite *comp)
{
unsigned vs_traits = 0, fs_traits = 0;
struct xa_shader shader;
struct xa_picture *src_pic = comp->src;
struct xa_picture *mask_pic = comp->mask;
struct xa_picture *dst_pic = comp->dst;
ctx->has_solid_color = FALSE;
@ -321,7 +341,7 @@ bind_shaders(struct xa_context *ctx, const struct xa_composite *comp)
vs_traits |= VS_COMPOSITE;
}
fs_traits |= picture_format_fixups(src_pic, dst_pic, 0);
fs_traits |= picture_format_fixups(src_pic, 0);
}
if (mask_pic) {
@ -333,19 +353,25 @@ bind_shaders(struct xa_context *ctx, const struct xa_composite *comp)
if (mask_pic->component_alpha) {
struct xa_composite_blend blend;
blend_for_op(&blend, comp->op, src_pic, mask_pic, NULL);
if (!blend_for_op(&blend, comp->op, src_pic, mask_pic, NULL))
return -XA_ERR_INVAL;
if (blend.alpha_src) {
fs_traits |= FS_CA_SRCALPHA;
} else
fs_traits |= FS_CA_FULL;
}
fs_traits |= picture_format_fixups(mask_pic, dst_pic, 1);
fs_traits |= picture_format_fixups(mask_pic, 1);
}
if (ctx->dst->srf->format == PIPE_FORMAT_L8_UNORM)
fs_traits |= FS_DST_LUMINANCE;
shader = xa_shaders_get(ctx->shaders, vs_traits, fs_traits);
cso_set_vertex_shader_handle(ctx->cso, shader.vs);
cso_set_fragment_shader_handle(ctx->cso, shader.fs);
return XA_ERR_NONE;
}
static void
@ -433,12 +459,17 @@ xa_composite_prepare(struct xa_context *ctx,
if (ret != XA_ERR_NONE)
return ret;
ctx->dst = dst_srf;
renderer_bind_destination(ctx, dst_srf->srf,
dst_srf->srf->width,
dst_srf->srf->height);
bind_composite_blend_state(ctx, comp);
bind_shaders(ctx, comp);
ret = bind_composite_blend_state(ctx, comp);
if (ret != XA_ERR_NONE)
return ret;
ret = bind_shaders(ctx, comp);
if (ret != XA_ERR_NONE)
return ret;
bind_samplers(ctx, comp);
if (ctx->num_bound_samplers == 0 ) { /* solid fill */

View file

@ -278,13 +278,16 @@ xa_solid_prepare(struct xa_context *ctx, struct xa_surface *dst,
int width, height;
int ret;
xa_pixel_to_float4(fg, ctx->solid_color);
ctx->has_solid_color = 1;
ret = xa_surface_psurf_create(ctx, dst);
if (ret != XA_ERR_NONE)
return ret;
if (dst->srf->format == PIPE_FORMAT_L8_UNORM)
xa_pixel_to_float4_a8(fg, ctx->solid_color);
else
xa_pixel_to_float4(fg, ctx->solid_color);
ctx->has_solid_color = 1;
ctx->dst = dst;
width = dst->srf->width;
height = dst->srf->height;

View file

@ -135,6 +135,7 @@ enum xa_fs_traits {
FS_MASK_SET_ALPHA = 1 << 13,
FS_SRC_LUMINANCE = 1 << 14,
FS_MASK_LUMINANCE = 1 << 15,
FS_DST_LUMINANCE = 1 << 16,
FS_FILL = (FS_SOLID_FILL | FS_LINGRAD_FILL | FS_RADGRAD_FILL),
FS_COMPONENT_ALPHA = (FS_CA_FULL | FS_CA_SRCALPHA)
@ -172,6 +173,17 @@ xa_pixel_to_float4(uint32_t pixel, float *color)
color[3] = ((float)a) / 255.;
}
static INLINE void
xa_pixel_to_float4_a8(uint32_t pixel, float *color)
{
uint32_t a;
a = (pixel >> 24) & 0xff;
color[0] = ((float)a) / 255.;
color[1] = ((float)a) / 255.;
color[2] = ((float)a) / 255.;
color[3] = ((float)a) / 255.;
}
/*
* xa_tgsi.c

View file

@ -418,6 +418,7 @@ renderer_copy_prepare(struct xa_context *r,
struct pipe_context *pipe = r->pipe;
struct pipe_screen *screen = pipe->screen;
struct xa_shader shader;
uint32_t fs_traits = FS_COMPOSITE;
assert(screen->is_format_supported(screen, dst_surface->format,
PIPE_TEXTURE_2D, 0,
@ -469,7 +470,12 @@ renderer_copy_prepare(struct xa_context *r,
}
/* shaders */
shader = xa_shaders_get(r->shaders, VS_COMPOSITE, FS_COMPOSITE);
if (src_texture->format == PIPE_FORMAT_L8_UNORM)
fs_traits |= FS_SRC_LUMINANCE;
if (dst_surface->format == PIPE_FORMAT_L8_UNORM)
fs_traits |= FS_DST_LUMINANCE;
shader = xa_shaders_get(r->shaders, VS_COMPOSITE, fs_traits);
cso_set_vertex_shader_handle(r->cso, shader.vs);
cso_set_fragment_shader_handle(r->cso, shader.fs);

View file

@ -85,6 +85,7 @@ print_fs_traits(int fs_traits)
"FS_MASK_SET_ALPHA", /* = 1 << 13, */
"FS_SRC_LUMINANCE", /* = 1 << 14, */
"FS_MASK_LUMINANCE", /* = 1 << 15, */
"FS_DST_LUMINANCE", /* = 1 << 15, */
};
int i, k;
@ -454,6 +455,7 @@ create_fs(struct pipe_context *pipe, unsigned fs_traits)
unsigned mask_set_alpha = (fs_traits & FS_MASK_SET_ALPHA) != 0;
unsigned src_luminance = (fs_traits & FS_SRC_LUMINANCE) != 0;
unsigned mask_luminance = (fs_traits & FS_MASK_LUMINANCE) != 0;
unsigned dst_luminance = (fs_traits & FS_DST_LUMINANCE) != 0;
#if 0
print_fs_traits(fs_traits);
@ -508,7 +510,7 @@ create_fs(struct pipe_context *pipe, unsigned fs_traits)
#endif
if (is_composite) {
if (has_mask || src_luminance)
if (has_mask || src_luminance || dst_luminance)
src = ureg_DECL_temporary(ureg);
else
src = out;
@ -516,14 +518,14 @@ create_fs(struct pipe_context *pipe, unsigned fs_traits)
src_repeat_none, src_swizzle, src_set_alpha);
} else if (is_fill) {
if (is_solid) {
if (has_mask || src_luminance)
if (has_mask || src_luminance || dst_luminance)
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_luminance)
if (has_mask || src_luminance || dst_luminance)
src = ureg_DECL_temporary(ureg);
else
src = out;
@ -550,7 +552,7 @@ create_fs(struct pipe_context *pipe, unsigned fs_traits)
ureg_MOV(ureg, src, ureg_scalar(ureg_src(src), TGSI_SWIZZLE_X));
ureg_MOV(ureg, ureg_writemask(src, TGSI_WRITEMASK_XYZ),
ureg_scalar(imm0, TGSI_SWIZZLE_X));
if (!has_mask)
if (!has_mask && !dst_luminance)
ureg_MOV(ureg, out, ureg_src(src));
}
@ -559,11 +561,21 @@ create_fs(struct pipe_context *pipe, unsigned fs_traits)
xrender_tex(ureg, mask, mask_pos, mask_sampler, imm0,
mask_repeat_none, mask_swizzle, mask_set_alpha);
/* src IN mask */
src_in_mask(ureg, out, ureg_src(src), ureg_src(mask),
src_in_mask(ureg, (dst_luminance) ? src : out, ureg_src(src),
ureg_src(mask),
comp_alpha_mask, mask_luminance);
ureg_release_temporary(ureg, mask);
}
if (dst_luminance) {
/*
* Make sure the alpha channel goes into the output L8 surface.
*/
ureg_MOV(ureg, out, ureg_scalar(ureg_src(src), TGSI_SWIZZLE_W));
}
ureg_END(ureg);
return ureg_create_shader_and_destroy(ureg, pipe);

View file

@ -48,14 +48,17 @@ if False:
env.Append(CPPDEFINES = 'GALLIUM_CELL')
env.Prepend(LIBS = [cell])
# TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions
libgl = env.SharedLibrary(
# libGL.so.1.5
libgl_1_5 = env.SharedLibrary(
target ='GL',
source = sources,
SHLIBSUFFIX = env['SHLIBSUFFIX'] + '.1.5',
)
if False:
# XXX: Only install this libGL.so if DRI not enabled
libgl = env.InstallSharedLibrary(libgl, version=(1, 5))
# libGL.so.1
libgl = env.subst('${SHLIBPREFIX}GL${SHLIBSUFFIX}')
libgl_1 = libgl + '.1'
env.Command(libgl_1, libgl_1_5, "ln -sf ${SOURCE.file} ${TARGET}")
env.Command(libgl, libgl_1, "ln -sf ${SOURCE.file} ${TARGET}")
env.Alias('libgl-xlib', libgl)

View file

@ -213,6 +213,15 @@ i915_drm_buffer_destroy(struct i915_winsys *iws,
FREE(buffer);
}
static boolean
i915_drm_buffer_is_busy(struct i915_winsys *iws,
struct i915_winsys_buffer *buffer)
{
struct i915_drm_buffer* i915_buffer = i915_drm_buffer(buffer);
return drm_intel_bo_busy(i915_buffer->bo);
}
void
i915_drm_winsys_init_buffer_functions(struct i915_drm_winsys *idws)
{
@ -224,4 +233,5 @@ i915_drm_winsys_init_buffer_functions(struct i915_drm_winsys *idws)
idws->base.buffer_unmap = i915_drm_buffer_unmap;
idws->base.buffer_write = i915_drm_buffer_write;
idws->base.buffer_destroy = i915_drm_buffer_destroy;
idws->base.buffer_is_busy = i915_drm_buffer_is_busy;
}

View file

@ -186,7 +186,7 @@ static int eg_interpret_tiling(struct radeon *radeon, uint32_t tiling_config)
static int radeon_drm_get_tiling(struct radeon *radeon)
{
struct drm_radeon_info info;
struct drm_radeon_info info = {};
int r;
uint32_t tiling_config = 0;
@ -208,8 +208,8 @@ static int radeon_drm_get_tiling(struct radeon *radeon)
static int radeon_get_clock_crystal_freq(struct radeon *radeon)
{
struct drm_radeon_info info;
uint32_t clock_crystal_freq;
struct drm_radeon_info info = {};
uint32_t clock_crystal_freq = 0;
int r;
info.request = RADEON_INFO_CLOCK_CRYSTAL_FREQ;
@ -226,8 +226,8 @@ static int radeon_get_clock_crystal_freq(struct radeon *radeon)
static int radeon_get_num_backends(struct radeon *radeon)
{
struct drm_radeon_info info;
uint32_t num_backends;
struct drm_radeon_info info = {};
uint32_t num_backends = 0;
int r;
info.request = RADEON_INFO_NUM_BACKENDS;

View file

@ -1506,7 +1506,7 @@ void r600_context_flush(struct r600_context *ctx)
/* suspend queries */
r600_context_queries_suspend(ctx);
if (ctx->radeon->family >= CHIP_CEDAR)
if (ctx->radeon->chip_class >= EVERGREEN)
evergreen_context_flush_dest_caches(ctx);
else
r600_context_flush_dest_caches(ctx);
@ -1567,7 +1567,7 @@ void r600_context_flush(struct r600_context *ctx)
r600_init_cs(ctx);
/* resume queries */
r600_context_queries_resume(ctx);
r600_context_queries_resume(ctx, TRUE);
/* set all valid group as dirty so they get reemited on
* next draw command
@ -1727,7 +1727,7 @@ static boolean r600_query_result(struct r600_context *ctx, struct r600_query *qu
void r600_query_begin(struct r600_context *ctx, struct r600_query *query)
{
unsigned required_space;
unsigned required_space, required_buffer;
int num_backends = r600_get_num_backends(ctx->radeon);
/* query request needs 6/8 dwords for begin + 6/8 dwords for end */
@ -1741,9 +1741,13 @@ void r600_query_begin(struct r600_context *ctx, struct r600_query *query)
r600_context_flush(ctx);
}
required_buffer = query->num_results +
4 * (query->type == PIPE_QUERY_OCCLUSION_COUNTER ? ctx->max_db : 1);
/* if query buffer is full force a flush */
if (query->num_results*4 >= query->buffer_size - 16) {
r600_context_flush(ctx);
if (required_buffer*4 > query->buffer_size) {
if (!(query->state & R600_QUERY_STATE_FLUSHED))
r600_context_flush(ctx);
r600_query_result(ctx, query, TRUE);
}
@ -1753,9 +1757,9 @@ void r600_query_begin(struct r600_context *ctx, struct r600_query *query)
u32 *results;
int i;
results = r600_bo_map(ctx->radeon, query->buffer, PB_USAGE_DONTBLOCK | PB_USAGE_CPU_WRITE, NULL);
results = r600_bo_map(ctx->radeon, query->buffer, PB_USAGE_CPU_WRITE, NULL);
if (results) {
memset(results + (query->num_results * 4), 0, ctx->max_db * 4 * 4);
memset(results + query->num_results, 0, ctx->max_db * 4 * 4);
for (i = num_backends; i < ctx->max_db; i++) {
results[(i * 4)+1] = 0x80000000;
@ -1811,6 +1815,7 @@ void r600_query_end(struct r600_context *ctx, struct r600_query *query)
query->num_results += 4 * (query->type == PIPE_QUERY_OCCLUSION_COUNTER ? ctx->max_db : 1);
query->state ^= R600_QUERY_STATE_STARTED;
query->state |= R600_QUERY_STATE_ENDED;
query->state &= ~R600_QUERY_STATE_FLUSHED;
ctx->num_query_running--;
}
@ -1879,7 +1884,7 @@ boolean r600_context_query_result(struct r600_context *ctx,
{
uint64_t *result = (uint64_t*)vresult;
if (query->num_results) {
if (query->num_results && !(query->state & R600_QUERY_STATE_FLUSHED)) {
r600_context_flush(ctx);
}
if (!r600_query_result(ctx, query, wait))
@ -1904,7 +1909,7 @@ void r600_context_queries_suspend(struct r600_context *ctx)
}
}
void r600_context_queries_resume(struct r600_context *ctx)
void r600_context_queries_resume(struct r600_context *ctx, boolean flushed)
{
struct r600_query *query;
@ -1912,6 +1917,7 @@ void r600_context_queries_resume(struct r600_context *ctx)
if (query->state & R600_QUERY_STATE_SUSPENDED) {
r600_query_begin(ctx, query);
query->state ^= R600_QUERY_STATE_SUSPENDED;
}
} else if (flushed && query->state==R600_QUERY_STATE_ENDED)
query->state |= R600_QUERY_STATE_FLUSHED;
}
}

View file

@ -154,7 +154,7 @@ clean: clean-dricore
-rm -f $(APPS)
clean-dricore:
-rm -f $(DRICORE_OBJ_DIR) $(TOP)/$(LIB_DIR)/libglsl.so libglsl.so
-rm -f $(OBJECTS_DRICORE) $(TOP)/$(LIB_DIR)/libglsl.so libglsl.so
ifneq (,$(DRICORE_GLSL_LIBS))
DRICORE_INSTALL_TARGET = install-dricore

View file

@ -165,7 +165,7 @@ ir_function_signature *
ir_function::matching_signature(const exec_list *actual_parameters)
{
ir_function_signature *match = NULL;
int matched_score;
int matched_score = 0;
foreach_iter(exec_list_iterator, iter, signatures) {
ir_function_signature *const sig =

View file

@ -56,10 +56,8 @@ bool do_if_simplification(exec_list *instructions);
bool do_discard_simplification(exec_list *instructions);
bool lower_if_to_cond_assign(exec_list *instructions, unsigned max_depth = 0);
bool do_mat_op_to_vec(exec_list *instructions);
bool do_mod_to_fract(exec_list *instructions);
bool do_noop_swizzle(exec_list *instructions);
bool do_structure_splitting(exec_list *instructions);
bool do_sub_to_add_neg(exec_list *instructions);
bool do_swizzle_swizzle(exec_list *instructions);
bool do_tree_grafting(exec_list *instructions);
bool do_vec_index_to_cond_assign(exec_list *instructions);

View file

@ -96,6 +96,16 @@ void ir_print_visitor::indent(void)
const char *
ir_print_visitor::unique_name(ir_variable *var)
{
/* var->name can be NULL in function prototypes when a type is given for a
* parameter but no name is given. In that case, just return an empty
* string. Don't worry about tracking the generated name in the printable
* names hash because this is the only scope where it can ever appear.
*/
if (var->name == NULL) {
static unsigned arg = 1;
return ralloc_asprintf(this->mem_ctx, "parameter@%u", arg++);
}
/* Do we already have a name for this variable? */
const char *name = (const char *) hash_table_find(this->printable_names, var);
if (name != NULL)

View file

@ -482,19 +482,21 @@ ir_reader::read_return(s_expression *expr)
{
s_expression *s_retval;
s_pattern pat[] = { "return", s_retval};
if (!MATCH(expr, pat)) {
ir_read_error(expr, "expected (return <rvalue>)");
s_pattern return_value_pat[] = { "return", s_retval};
s_pattern return_void_pat[] = { "return" };
if (MATCH(expr, return_value_pat)) {
ir_rvalue *retval = read_rvalue(s_retval);
if (retval == NULL) {
ir_read_error(NULL, "when reading return value");
return NULL;
}
return new(mem_ctx) ir_return(retval);
} else if (MATCH(expr, return_void_pat)) {
return new(mem_ctx) ir_return;
} else {
ir_read_error(expr, "expected (return <rvalue>) or (return)");
return NULL;
}
ir_rvalue *retval = read_rvalue(s_retval);
if (retval == NULL) {
ir_read_error(NULL, "when reading return value");
return NULL;
}
return new(mem_ctx) ir_return(retval);
}

View file

@ -1194,16 +1194,43 @@ find_available_slots(unsigned used_mask, unsigned needed_count)
}
/**
* Assign locations for either VS inputs for FS outputs
*
* \param prog Shader program whose variables need locations assigned
* \param target_index Selector for the program target to receive location
* assignmnets. Must be either \c MESA_SHADER_VERTEX or
* \c MESA_SHADER_FRAGMENT.
* \param max_index Maximum number of generic locations. This corresponds
* to either the maximum number of draw buffers or the
* maximum number of generic attributes.
*
* \return
* If locations are successfully assigned, true is returned. Otherwise an
* error is emitted to the shader link log and false is returned.
*
* \bug
* Locations set via \c glBindFragDataLocation are not currently supported.
* Only locations assigned automatically by the linker, explicitly set by a
* layout qualifier, or explicitly set by a built-in variable (e.g., \c
* gl_FragColor) are supported for fragment shaders.
*/
bool
assign_attribute_locations(gl_shader_program *prog, unsigned max_attribute_index)
assign_attribute_or_color_locations(gl_shader_program *prog,
unsigned target_index,
unsigned max_index)
{
/* Mark invalid attribute locations as being used.
/* Mark invalid locations as being used.
*/
unsigned used_locations = (max_attribute_index >= 32)
? ~0 : ~((1 << max_attribute_index) - 1);
unsigned used_locations = (max_index >= 32)
? ~0 : ~((1 << max_index) - 1);
gl_shader *const sh = prog->_LinkedShaders[0];
assert(sh->Type == GL_VERTEX_SHADER);
assert((target_index == MESA_SHADER_VERTEX)
|| (target_index == MESA_SHADER_FRAGMENT));
gl_shader *const sh = prog->_LinkedShaders[target_index];
if (sh == NULL)
return true;
/* Operate in a total of four passes.
*
@ -1220,9 +1247,16 @@ assign_attribute_locations(gl_shader_program *prog, unsigned max_attribute_index
* 4. Assign locations to any inputs without assigned locations.
*/
invalidate_variable_locations(sh, ir_var_in, VERT_ATTRIB_GENERIC0);
const int generic_base = (target_index == MESA_SHADER_VERTEX)
? (int) VERT_ATTRIB_GENERIC0 : (int) FRAG_RESULT_DATA0;
if (prog->Attributes != NULL) {
const enum ir_variable_mode direction =
(target_index == MESA_SHADER_VERTEX) ? ir_var_in : ir_var_out;
invalidate_variable_locations(sh, direction, generic_base);
if ((target_index == MESA_SHADER_VERTEX) && (prog->Attributes != NULL)) {
for (unsigned i = 0; i < prog->Attributes->NumParameters; i++) {
ir_variable *const var =
sh->symbols->get_variable(prog->Attributes->Parameters[i].Name);
@ -1309,15 +1343,15 @@ assign_attribute_locations(gl_shader_program *prog, unsigned max_attribute_index
foreach_list(node, sh->ir) {
ir_variable *const var = ((ir_instruction *) node)->as_variable();
if ((var == NULL) || (var->mode != ir_var_in))
if ((var == NULL) || (var->mode != direction))
continue;
if (var->explicit_location) {
const unsigned slots = count_attribute_slots(var->type);
const unsigned use_mask = (1 << slots) - 1;
const int attr = var->location - VERT_ATTRIB_GENERIC0;
const int attr = var->location - generic_base;
if ((var->location >= (int)(max_attribute_index + VERT_ATTRIB_GENERIC0))
if ((var->location >= (int)(max_index + generic_base))
|| (var->location < 0)) {
linker_error_printf(prog,
"invalid explicit location %d specified for "
@ -1325,7 +1359,7 @@ assign_attribute_locations(gl_shader_program *prog, unsigned max_attribute_index
(var->location < 0) ? var->location : attr,
var->name);
return false;
} else if (var->location >= VERT_ATTRIB_GENERIC0) {
} else if (var->location >= generic_base) {
used_locations |= (use_mask << attr);
}
}
@ -1349,14 +1383,16 @@ assign_attribute_locations(gl_shader_program *prog, unsigned max_attribute_index
qsort(to_assign, num_attr, sizeof(to_assign[0]), temp_attr::compare);
/* VERT_ATTRIB_GENERIC0 is a pseudo-alias for VERT_ATTRIB_POS. It can only
* be explicitly assigned by via glBindAttribLocation. Mark it as reserved
* to prevent it from being automatically allocated below.
*/
find_deref_visitor find("gl_Vertex");
find.run(sh->ir);
if (find.variable_found())
used_locations |= (1 << 0);
if (target_index == MESA_SHADER_VERTEX) {
/* VERT_ATTRIB_GENERIC0 is a pseudo-alias for VERT_ATTRIB_POS. It can
* only be explicitly assigned by via glBindAttribLocation. Mark it as
* reserved to prevent it from being automatically allocated below.
*/
find_deref_visitor find("gl_Vertex");
find.run(sh->ir);
if (find.variable_found())
used_locations |= (1 << 0);
}
for (unsigned i = 0; i < num_attr; i++) {
/* Mask representing the contiguous slots that will be used by this
@ -1367,14 +1403,17 @@ assign_attribute_locations(gl_shader_program *prog, unsigned max_attribute_index
int location = find_available_slots(used_locations, to_assign[i].slots);
if (location < 0) {
const char *const string = (target_index == MESA_SHADER_VERTEX)
? "vertex shader input" : "fragment shader output";
linker_error_printf(prog,
"insufficient contiguous attribute locations "
"available for vertex shader input `%s'",
to_assign[i].var->name);
"available for %s `%s'",
string, to_assign[i].var->name);
return false;
}
to_assign[i].var->location = VERT_ATTRIB_GENERIC0 + location;
to_assign[i].var->location = generic_base + location;
used_locations |= (use_mask << location);
}
@ -1671,16 +1710,19 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
assign_uniform_locations(prog);
if (prog->_LinkedShaders[MESA_SHADER_VERTEX] != NULL) {
/* FINISHME: The value of the max_attribute_index parameter is
* FINISHME: implementation dependent based on the value of
* FINISHME: GL_MAX_VERTEX_ATTRIBS. GL_MAX_VERTEX_ATTRIBS must be
* FINISHME: at least 16, so hardcode 16 for now.
*/
if (!assign_attribute_locations(prog, 16)) {
prog->LinkStatus = false;
goto done;
}
/* FINISHME: The value of the max_attribute_index parameter is
* FINISHME: implementation dependent based on the value of
* FINISHME: GL_MAX_VERTEX_ATTRIBS. GL_MAX_VERTEX_ATTRIBS must be
* FINISHME: at least 16, so hardcode 16 for now.
*/
if (!assign_attribute_or_color_locations(prog, MESA_SHADER_VERTEX, 16)) {
prog->LinkStatus = false;
goto done;
}
if (!assign_attribute_or_color_locations(prog, MESA_SHADER_FRAGMENT, ctx->Const.MaxDrawBuffers)) {
prog->LinkStatus = false;
goto done;
}
unsigned prev;

View file

@ -60,12 +60,76 @@
#include <string.h>
#include "ir.h"
/**
* Enum recording the result of analyzing how control flow might exit
* an IR node.
*
* Each possible value of jump_strength indicates a strictly stronger
* guarantee on control flow than the previous value.
*
* The ordering of strengths roughly reflects the way jumps are
* lowered: jumps with higher strength tend to be lowered to jumps of
* lower strength. Accordingly, strength is used as a heuristic to
* determine which lowering to perform first.
*
* This enum is also used by get_jump_strength() to categorize
* instructions as either break, continue, return, or other. When
* used in this fashion, strength_always_clears_execute_flag is not
* used.
*
* The control flow analysis made by this optimization pass makes two
* simplifying assumptions:
*
* - It ignores discard instructions, since they are lowered by a
* separate pass (lower_discard.cpp).
*
* - It assumes it is always possible for control to flow from a loop
* to the instruction immediately following it. Technically, this
* is not true (since all execution paths through the loop might
* jump back to the top, or return from the function).
*
* Both of these simplifying assumtions are safe, since they can never
* cause reachable code to be incorrectly classified as unreachable;
* they can only do the opposite.
*/
enum jump_strength
{
/**
* Analysis has produced no guarantee on how control flow might
* exit this IR node. It might fall out the bottom (with or
* without clearing the execute flag, if present), or it might
* continue to the top of the innermost enclosing loop, break out
* of it, or return from the function.
*/
strength_none,
/**
* The only way control can fall out the bottom of this node is
* through a code path that clears the execute flag. It might also
* continue to the top of the innermost enclosing loop, break out
* of it, or return from the function.
*/
strength_always_clears_execute_flag,
/**
* Control cannot fall out the bottom of this node. It might
* continue to the top of the innermost enclosing loop, break out
* of it, or return from the function.
*/
strength_continue,
/**
* Control cannot fall out the bottom of this node, or continue the
* top of the innermost enclosing loop. It can only break out of
* it or return from the function.
*/
strength_break,
/**
* Control cannot fall out the bottom of this node, continue to the
* top of the innermost enclosing loop, or break out of it. It can
* only return from the function.
*/
strength_return
};
@ -146,16 +210,17 @@ struct function_record
ir_function_signature* signature;
ir_variable* return_flag; /* used to break out of all loops and then jump to the return instruction */
ir_variable* return_value;
bool is_main;
bool lower_return;
unsigned nesting_depth;
function_record(ir_function_signature* p_signature = 0)
function_record(ir_function_signature* p_signature = 0,
bool lower_return = false)
{
this->signature = p_signature;
this->return_flag = 0;
this->return_value = 0;
this->nesting_depth = 0;
this->is_main = this->signature && (strcmp(this->signature->function_name(), "main") == 0);
this->lower_return = lower_return;
}
ir_variable* get_return_flag()
@ -180,6 +245,27 @@ struct function_record
};
struct ir_lower_jumps_visitor : public ir_control_flow_visitor {
/* Postconditions: on exit of any visit() function:
*
* ANALYSIS: this->block.min_strength,
* this->block.may_clear_execute_flag, and
* this->loop.may_set_return_flag are updated to reflect the
* characteristics of the visited statement.
*
* DEAD_CODE_ELIMINATION: If this->block.min_strength is not
* strength_none, the visited node is at the end of its exec_list.
* In other words, any unreachable statements that follow the
* visited statement in its exec_list have been removed.
*
* CONTAINED_JUMPS_LOWERED: If the visited statement contains other
* statements, then should_lower_jump() is false for all of the
* return, break, or continue statements it contains.
*
* Note that visiting a jump does not lower it. That is the
* responsibility of the statement (or function signature) that
* contains the jump.
*/
bool progress;
struct function_record function;
@ -218,20 +304,140 @@ struct ir_lower_jumps_visitor : public ir_control_flow_visitor {
}
}
/**
* Insert the instructions necessary to lower a return statement,
* before the given return instruction.
*/
void insert_lowered_return(ir_return *ir)
{
ir_variable* return_flag = this->function.get_return_flag();
if(!this->function.signature->return_type->is_void()) {
ir_variable* return_value = this->function.get_return_value();
ir->insert_before(
new(ir) ir_assignment(
new (ir) ir_dereference_variable(return_value),
ir->value));
}
ir->insert_before(
new(ir) ir_assignment(
new (ir) ir_dereference_variable(return_flag),
new (ir) ir_constant(true)));
this->loop.may_set_return_flag = true;
}
/**
* If the given instruction is a return, lower it to instructions
* that store the return value (if there is one), set the return
* flag, and then break.
*
* It is safe to pass NULL to this function.
*/
void lower_return_unconditionally(ir_instruction *ir)
{
if (get_jump_strength(ir) != strength_return) {
return;
}
insert_lowered_return((ir_return*)ir);
ir->replace_with(new(ir) ir_loop_jump(ir_loop_jump::jump_break));
}
/**
* Create the necessary instruction to replace a break instruction.
*/
ir_instruction *create_lowered_break()
{
void *ctx = this->function.signature;
return new(ctx) ir_assignment(
new(ctx) ir_dereference_variable(this->loop.get_break_flag()),
new(ctx) ir_constant(true),
0);
}
/**
* If the given instruction is a break, lower it to an instruction
* that sets the break flag, without consulting
* should_lower_jump().
*
* It is safe to pass NULL to this function.
*/
void lower_break_unconditionally(ir_instruction *ir)
{
if (get_jump_strength(ir) != strength_break) {
return;
}
ir->replace_with(create_lowered_break());
}
/**
* If the block ends in a conditional or unconditional break, lower
* it, even though should_lower_jump() says it needn't be lowered.
*/
void lower_final_breaks(exec_list *block)
{
ir_instruction *ir = (ir_instruction *) block->get_tail();
lower_break_unconditionally(ir);
ir_if *ir_if = ir->as_if();
if (ir_if) {
lower_break_unconditionally(
(ir_instruction *) ir_if->then_instructions.get_tail());
lower_break_unconditionally(
(ir_instruction *) ir_if->else_instructions.get_tail());
}
}
virtual void visit(class ir_loop_jump * ir)
{
/* Eliminate all instructions after each one, since they are
* unreachable. This satisfies the DEAD_CODE_ELIMINATION
* postcondition.
*/
truncate_after_instruction(ir);
/* Set this->block.min_strength based on this instruction. This
* satisfies the ANALYSIS postcondition. It is not necessary to
* update this->block.may_clear_execute_flag or
* this->loop.may_set_return_flag, because an unlowered jump
* instruction can't change any flags.
*/
this->block.min_strength = ir->is_break() ? strength_break : strength_continue;
/* The CONTAINED_JUMPS_LOWERED postcondition is already
* satisfied, because jump statements can't contain other
* statements.
*/
}
virtual void visit(class ir_return * ir)
{
/* Eliminate all instructions after each one, since they are
* unreachable. This satisfies the DEAD_CODE_ELIMINATION
* postcondition.
*/
truncate_after_instruction(ir);
/* Set this->block.min_strength based on this instruction. This
* satisfies the ANALYSIS postcondition. It is not necessary to
* update this->block.may_clear_execute_flag or
* this->loop.may_set_return_flag, because an unlowered return
* instruction can't change any flags.
*/
this->block.min_strength = strength_return;
/* The CONTAINED_JUMPS_LOWERED postcondition is already
* satisfied, because jump statements can't contain other
* statements.
*/
}
virtual void visit(class ir_discard * ir)
{
/* Nothing needs to be done. The ANALYSIS and
* DEAD_CODE_ELIMINATION postconditions are already satisfied,
* because discard statements are ignored by this optimization
* pass. The CONTAINED_JUMPS_LOWERED postcondition is already
* satisfied, because discard statements can't contain other
* statements.
*/
}
enum jump_strength get_jump_strength(ir_instruction* ir)
@ -274,10 +480,8 @@ struct ir_lower_jumps_visitor : public ir_control_flow_visitor {
/* never lower return at the end of a this->function */
if(this->function.nesting_depth == 0 && ir->get_next()->is_tail_sentinel())
lower = false;
else if (this->function.is_main)
lower = lower_main_return;
else
lower = lower_sub_return;
lower = this->function.lower_return;
break;
}
return lower;
@ -285,9 +489,20 @@ struct ir_lower_jumps_visitor : public ir_control_flow_visitor {
block_record visit_block(exec_list* list)
{
/* Note: since visiting a node may change that node's next
* pointer, we can't use visit_exec_list(), because
* visit_exec_list() caches the node's next pointer before
* visiting it. So we use foreach_list() instead.
*
* foreach_list() isn't safe if the node being visited gets
* removed, but fortunately this visitor doesn't do that.
*/
block_record saved_block = this->block;
this->block = block_record();
visit_exec_list(list, this);
foreach_list(node, list) {
((ir_instruction *) node)->accept(this);
}
block_record ret = this->block;
this->block = saved_block;
return ret;
@ -304,18 +519,34 @@ struct ir_lower_jumps_visitor : public ir_control_flow_visitor {
block_record block_records[2];
ir_jump* jumps[2];
/* Recursively lower nested jumps. This satisfies the
* CONTAINED_JUMPS_LOWERED postcondition, except in the case of
* unconditional jumps at the end of ir->then_instructions and
* ir->else_instructions, which are handled below.
*/
block_records[0] = visit_block(&ir->then_instructions);
block_records[1] = visit_block(&ir->else_instructions);
retry: /* we get here if we put code after the if inside a branch */
for(unsigned i = 0; i < 2; ++i) {
exec_list& list = i ? ir->else_instructions : ir->then_instructions;
jumps[i] = 0;
if(!list.is_empty() && get_jump_strength((ir_instruction*)list.get_tail()))
jumps[i] = (ir_jump*)list.get_tail();
}
/* Determine which of ir->then_instructions and
* ir->else_instructions end with an unconditional jump.
*/
for(unsigned i = 0; i < 2; ++i) {
exec_list& list = i ? ir->else_instructions : ir->then_instructions;
jumps[i] = 0;
if(!list.is_empty() && get_jump_strength((ir_instruction*)list.get_tail()))
jumps[i] = (ir_jump*)list.get_tail();
}
/* Loop until we have satisfied the CONTAINED_JUMPS_LOWERED
* postcondition by lowering jumps in both then_instructions and
* else_instructions.
*/
for(;;) {
/* Determine the types of the jumps that terminate
* ir->then_instructions and ir->else_instructions.
*/
jump_strength jump_strengths[2];
for(unsigned i = 0; i < 2; ++i) {
@ -326,7 +557,12 @@ retry: /* we get here if we put code after the if inside a branch */
jump_strengths[i] = strength_none;
}
/* move both jumps out if possible */
/* If both code paths end in a jump, and the jumps are the
* same, and we are pulling out jumps, replace them with a
* single jump that comes after the if instruction. The new
* jump will be visited next, and it will be lowered if
* necessary by the loop or conditional that encloses it.
*/
if(pull_out_jumps && jump_strengths[0] == jump_strengths[1]) {
bool unify = true;
if(jump_strengths[0] == strength_continue)
@ -344,10 +580,19 @@ retry: /* we get here if we put code after the if inside a branch */
jumps[1]->remove();
this->progress = true;
/* Update jumps[] to reflect the fact that the jumps
* are gone, and update block_records[] to reflect the
* fact that control can now flow to the next
* instruction.
*/
jumps[0] = 0;
jumps[1] = 0;
block_records[0].min_strength = strength_none;
block_records[1].min_strength = strength_none;
/* The CONTAINED_JUMPS_LOWERED postcondition is now
* satisfied, so we can break out of the loop.
*/
break;
}
}
@ -367,50 +612,91 @@ retry: /* we get here if we put code after the if inside a branch */
else if(should_lower[1])
lower = 1;
else
/* Neither code path ends in a jump that needs to be
* lowered, so the CONTAINED_JUMPS_LOWERED postcondition
* is satisfied and we can break out of the loop.
*/
break;
if(jump_strengths[lower] == strength_return) {
ir_variable* return_flag = this->function.get_return_flag();
if(!this->function.signature->return_type->is_void()) {
ir_variable* return_value = this->function.get_return_value();
jumps[lower]->insert_before(new(ir) ir_assignment(new (ir) ir_dereference_variable(return_value), ((ir_return*)jumps[lower])->value, NULL));
}
jumps[lower]->insert_before(new(ir) ir_assignment(new (ir) ir_dereference_variable(return_flag), new (ir) ir_constant(true), NULL));
this->loop.may_set_return_flag = true;
/* To lower a return, we create a return flag (if the
* function doesn't have one already) and add instructions
* that: 1. store the return value (if this function has a
* non-void return) and 2. set the return flag
*/
insert_lowered_return((ir_return*)jumps[lower]);
if(this->loop.loop) {
/* If we are in a loop, replace the return instruction
* with a break instruction, and then loop so that the
* break instruction can be lowered if necessary.
*/
ir_loop_jump* lowered = 0;
lowered = new(ir) ir_loop_jump(ir_loop_jump::jump_break);
/* Note: we must update block_records and jumps to
* reflect the fact that the control path has been
* altered from a return to a break.
*/
block_records[lower].min_strength = strength_break;
jumps[lower]->replace_with(lowered);
jumps[lower] = lowered;
} else
} else {
/* If we are not in a loop, we then proceed as we would
* for a continue statement (set the execute flag to
* false to prevent the rest of the function from
* executing).
*/
goto lower_continue;
}
this->progress = true;
} else if(jump_strengths[lower] == strength_break) {
/* We can't lower to an actual continue because that would execute the increment.
/* To lower a break, we create a break flag (if the loop
* doesn't have one already) and add an instruction that
* sets it.
*
* In the lowered code, we instead put the break check between the this->loop body and the increment,
* which is impossible with a real continue as defined by the GLSL IR currently.
* Then we proceed as we would for a continue statement
* (set the execute flag to false to prevent the rest of
* the loop body from executing).
*
* Smarter options (such as undoing the increment) are possible but it's not worth implementing them,
* because if break is lowered, continue is almost surely lowered too.
* The visit() function for the loop will ensure that the
* break flag is checked after executing the loop body.
*/
jumps[lower]->insert_before(new(ir) ir_assignment(new (ir) ir_dereference_variable(this->loop.get_break_flag()), new (ir) ir_constant(true), 0));
jumps[lower]->insert_before(create_lowered_break());
goto lower_continue;
} else if(jump_strengths[lower] == strength_continue) {
lower_continue:
/* To lower a continue, we create an execute flag (if the
* loop doesn't have one already) and replace the continue
* with an instruction that clears it.
*
* Note that this code path gets exercised when lowering
* return statements that are not inside a loop, so
* this->loop must be initialized even outside of loops.
*/
ir_variable* execute_flag = this->loop.get_execute_flag();
jumps[lower]->replace_with(new(ir) ir_assignment(new (ir) ir_dereference_variable(execute_flag), new (ir) ir_constant(false), 0));
/* Note: we must update block_records and jumps to reflect
* the fact that the control path has been altered to an
* instruction that clears the execute flag.
*/
jumps[lower] = 0;
block_records[lower].min_strength = strength_always_clears_execute_flag;
block_records[lower].may_clear_execute_flag = true;
this->progress = true;
break;
/* Let the loop run again, in case the other branch of the
* if needs to be lowered too.
*/
}
}
/* move out a jump out if possible */
if(pull_out_jumps) {
/* If one of the branches ends in a jump, and control cannot
* fall out the bottom of the other branch, then we can move
* the jump after the if.
*
* Set move_out to the branch we are moving a jump out of.
*/
int move_out = -1;
if(jumps[0] && block_records[1].min_strength >= strength_continue)
move_out = 0;
@ -421,22 +707,46 @@ lower_continue:
{
jumps[move_out]->remove();
ir->insert_after(jumps[move_out]);
/* Note: we must update block_records and jumps to reflect
* the fact that the jump has been moved out of the if.
*/
jumps[move_out] = 0;
block_records[move_out].min_strength = strength_none;
this->progress = true;
}
}
/* Now satisfy the ANALYSIS postcondition by setting
* this->block.min_strength and
* this->block.may_clear_execute_flag based on the
* characteristics of the two branches.
*/
if(block_records[0].min_strength < block_records[1].min_strength)
this->block.min_strength = block_records[0].min_strength;
else
this->block.min_strength = block_records[1].min_strength;
this->block.may_clear_execute_flag = this->block.may_clear_execute_flag || block_records[0].may_clear_execute_flag || block_records[1].may_clear_execute_flag;
/* Now we need to clean up the instructions that follow the
* if.
*
* If those instructions are unreachable, then satisfy the
* DEAD_CODE_ELIMINATION postcondition by eliminating them.
* Otherwise that postcondition is already satisfied.
*/
if(this->block.min_strength)
truncate_after_instruction(ir);
else if(this->block.may_clear_execute_flag)
{
/* If the "if" instruction might clear the execute flag, then
* we need to guard any instructions that follow so that they
* are only executed if the execute flag is set.
*
* If one of the branches of the "if" always clears the
* execute flag, and the other branch never clears it, then
* this is easy: just move all the instructions following the
* "if" into the branch that never clears it.
*/
int move_into = -1;
if(block_records[0].min_strength && !block_records[1].may_clear_execute_flag)
move_into = 1;
@ -451,14 +761,34 @@ lower_continue:
if(!next->is_tail_sentinel()) {
move_outer_block_inside(ir, list);
/* If any instructions moved, then we need to visit
* them (since they are now inside the "if"). Since
* block_records[move_into] is in its default state
* (see assertion above), we can safely replace
* block_records[move_into] with the result of this
* analysis.
*/
exec_list list;
list.head = next;
block_records[move_into] = visit_block(&list);
/*
* Then we need to re-start our jump lowering, since one
* of the instructions we moved might be a jump that
* needs to be lowered.
*/
this->progress = true;
goto retry;
}
} else {
/* If we get here, then the simple case didn't apply; we
* need to actually guard the instructions that follow.
*
* To avoid creating unnecessarily-deep nesting, first
* look through the instructions that follow and unwrap
* any instructions that that are already wrapped in the
* appropriate guard.
*/
ir_instruction* ir_after;
for(ir_after = (ir_instruction*)ir->get_next(); !ir_after->is_tail_sentinel();)
{
@ -479,6 +809,9 @@ lower_continue:
this->progress = true;
}
/* Then, wrap all the instructions that follow in a single
* guard.
*/
if(!ir->get_next()->is_tail_sentinel()) {
assert(this->loop.execute_flag);
ir_if* if_execute = new(ir) ir_if(new(ir) ir_dereference_variable(this->loop.execute_flag));
@ -493,29 +826,111 @@ lower_continue:
virtual void visit(ir_loop *ir)
{
/* Visit the body of the loop, with a fresh data structure in
* this->loop so that the analysis we do here won't bleed into
* enclosing loops.
*
* We assume that all code after a loop is reachable from the
* loop (see comments on enum jump_strength), so the
* DEAD_CODE_ELIMINATION postcondition is automatically
* satisfied, as is the block.min_strength portion of the
* ANALYSIS postcondition.
*
* The block.may_clear_execute_flag portion of the ANALYSIS
* postcondition is automatically satisfied because execute
* flags do not propagate outside of loops.
*
* The loop.may_set_return_flag portion of the ANALYSIS
* postcondition is handled below.
*/
++this->function.nesting_depth;
loop_record saved_loop = this->loop;
this->loop = loop_record(this->function.signature, ir);
/* Recursively lower nested jumps. This satisfies the
* CONTAINED_JUMPS_LOWERED postcondition, except in the case of
* an unconditional continue or return at the bottom of the
* loop, which are handled below.
*/
block_record body = visit_block(&ir->body_instructions);
/* If the loop ends in an unconditional continue, eliminate it
* because it is redundant.
*/
ir_instruction *ir_last
= (ir_instruction *) ir->body_instructions.get_tail();
if (get_jump_strength(ir_last) == strength_continue) {
ir_last->remove();
}
/* If the loop ends in an unconditional return, and we are
* lowering returns, lower it.
*/
if (this->function.lower_return)
lower_return_unconditionally(ir_last);
if(body.min_strength >= strength_break) {
/* FINISHME: turn the this->loop into an if, or replace it with its body */
/* FINISHME: If the min_strength of the loop body is
* strength_break or strength_return, that means that it
* isn't a loop at all, since control flow always leaves the
* body of the loop via break or return. In principle the
* loop could be eliminated in this case. This optimization
* is not implemented yet.
*/
}
if(this->loop.break_flag) {
/* We only get here if we are lowering breaks */
assert (lower_break);
/* If a break flag was generated while visiting the body of
* the loop, then at least one break was lowered, so we need
* to generate an if statement at the end of the loop that
* does a "break" if the break flag is set. The break we
* generate won't violate the CONTAINED_JUMPS_LOWERED
* postcondition, because should_lower_jump() always returns
* false for a break that happens at the end of a loop.
*
* However, if the loop already ends in a conditional or
* unconditional break, then we need to lower that break,
* because it won't be at the end of the loop anymore.
*/
lower_final_breaks(&ir->body_instructions);
ir_if* break_if = new(ir) ir_if(new(ir) ir_dereference_variable(this->loop.break_flag));
break_if->then_instructions.push_tail(new(ir) ir_loop_jump(ir_loop_jump::jump_break));
ir->body_instructions.push_tail(break_if);
}
/* If the body of the loop may set the return flag, then at
* least one return was lowered to a break, so we need to ensure
* that the return flag is checked after the body of the loop is
* executed.
*/
if(this->loop.may_set_return_flag) {
assert(this->function.return_flag);
/* Generate the if statement to check the return flag */
ir_if* return_if = new(ir) ir_if(new(ir) ir_dereference_variable(this->function.return_flag));
/* Note: we also need to propagate the knowledge that the
* return flag may get set to the outer context. This
* satisfies the loop.may_set_return_flag part of the
* ANALYSIS postcondition.
*/
saved_loop.may_set_return_flag = true;
if(saved_loop.loop)
/* If this loop is nested inside another one, then the if
* statement that we generated should break out of that
* loop if the return flag is set. Caller will lower that
* break statement if necessary.
*/
return_if->then_instructions.push_tail(new(ir) ir_loop_jump(ir_loop_jump::jump_break));
else
/* Otherwise, all we need to do is ensure that the
* instructions that follow are only executed if the
* return flag is clear. We can do that by moving those
* instructions into the else clause of the generated if
* statement.
*/
move_outer_block_inside(ir, &return_if->else_instructions);
ir->insert_after(return_if);
}
@ -530,14 +945,39 @@ lower_continue:
assert(!this->function.signature);
assert(!this->loop.loop);
bool lower_return;
if (strcmp(ir->function_name(), "main") == 0)
lower_return = lower_main_return;
else
lower_return = lower_sub_return;
function_record saved_function = this->function;
loop_record saved_loop = this->loop;
this->function = function_record(ir);
this->function = function_record(ir, lower_return);
this->loop = loop_record(ir);
assert(!this->loop.loop);
/* Visit the body of the function to lower any jumps that occur
* in it, except possibly an unconditional return statement at
* the end of it.
*/
visit_block(&ir->body);
/* If the body ended in an unconditional return of non-void,
* then we don't need to lower it because it's the one canonical
* return.
*
* If the body ended in a return of void, eliminate it because
* it is redundant.
*/
if (ir->return_type->is_void() &&
get_jump_strength((ir_instruction *) ir->body.get_tail())) {
ir_jump *jump = (ir_jump *) ir->body.get_tail();
assert (jump->ir_type == ir_type_return);
jump->remove();
}
if(this->function.return_value)
ir->body.push_tail(new(ir) ir_return(new (ir) ir_dereference_variable(this->function.return_value)));

View file

@ -51,11 +51,23 @@ public:
this->var = var;
this->write_mask = write_mask;
this->constant = constant;
this->initial_values = write_mask;
}
acp_entry(const acp_entry *src)
{
this->var = src->var;
this->write_mask = src->write_mask;
this->constant = src->constant;
this->initial_values = src->initial_values;
}
ir_variable *var;
ir_constant *constant;
unsigned write_mask;
/** Mask of values initially available in the constant. */
unsigned initial_values;
};
@ -172,7 +184,7 @@ ir_constant_propagation_visitor::handle_rvalue(ir_rvalue **rvalue)
for (int j = 0; j < 4; j++) {
if (j == channel)
break;
if (found->write_mask & (1 << j))
if (found->initial_values & (1 << j))
rhs_channel++;
}
@ -285,8 +297,7 @@ ir_constant_propagation_visitor::handle_if_block(exec_list *instructions)
/* Populate the initial acp with a constant of the original */
foreach_iter(exec_list_iterator, iter, *orig_acp) {
acp_entry *a = (acp_entry *)iter.get();
this->acp->push_tail(new(this->mem_ctx) acp_entry(a->var, a->write_mask,
a->constant));
this->acp->push_tail(new(this->mem_ctx) acp_entry(a));
}
visit_list_elements(this, instructions);

View file

@ -88,6 +88,7 @@ static Bool
DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire)
{
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
struct glx_drawable *glxDraw;
XextCheckExtension(dpy, info, dri2ExtensionName, False);
@ -97,7 +98,10 @@ DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire)
case DRI2_BufferSwapComplete:
{
GLXBufferSwapComplete *aevent = (GLXBufferSwapComplete *)event;
xDRI2BufferSwapComplete *awire = (xDRI2BufferSwapComplete *)wire;
xDRI2BufferSwapComplete2 *awire = (xDRI2BufferSwapComplete2 *)wire;
__GLXDRIdrawable *pdraw;
pdraw = dri2GetGlxDrawableFromXDrawableId(dpy, awire->drawable);
/* Ignore swap events if we're not looking for them */
aevent->type = dri2GetSwapEventType(dpy, awire->drawable);
@ -124,7 +128,13 @@ DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire)
}
aevent->ust = ((CARD64)awire->ust_hi << 32) | awire->ust_lo;
aevent->msc = ((CARD64)awire->msc_hi << 32) | awire->msc_lo;
aevent->sbc = ((CARD64)awire->sbc_hi << 32) | awire->sbc_lo;
glxDraw = GetGLXDrawable(dpy, pdraw->drawable);
if (awire->sbc < glxDraw->lastEventSbc)
glxDraw->eventSbcWrap += 0x100000000;
glxDraw->lastEventSbc = awire->sbc;
aevent->sbc = awire->sbc + glxDraw->eventSbcWrap;
return True;
}
#endif

View file

@ -396,6 +396,7 @@ CreateDrawable(Display *dpy, struct glx_config *config,
Drawable drawable, const int *attrib_list, CARD8 glxCode)
{
xGLXCreateWindowReq *req;
struct glx_drawable *glxDraw;
CARD32 *data;
unsigned int i;
CARD8 opcode;
@ -411,6 +412,10 @@ CreateDrawable(Display *dpy, struct glx_config *config,
if (!opcode)
return None;
glxDraw = Xmalloc(sizeof(*glxDraw));
if (!glxDraw)
return None;
LockDisplay(dpy);
GetReqExtra(GLXCreateWindow, 8 * i, req);
data = (CARD32 *) (req + 1);
@ -429,6 +434,11 @@ CreateDrawable(Display *dpy, struct glx_config *config,
UnlockDisplay(dpy);
SyncHandle();
if (InitGLXDrawable(dpy, glxDraw, drawable, xid)) {
free(glxDraw);
return None;
}
if (!CreateDRIDrawable(dpy, config, drawable, xid, attrib_list, i)) {
if (glxCode == X_GLXCreatePixmap)
glxCode = X_GLXDestroyPixmap;
@ -454,6 +464,7 @@ DestroyDrawable(Display * dpy, GLXDrawable drawable, CARD32 glxCode)
protocolDestroyDrawable(dpy, drawable, glxCode);
DestroyGLXDrawable(dpy, drawable);
DestroyDRIDrawable(dpy, drawable, GL_FALSE);
return;

View file

@ -567,6 +567,8 @@ struct glx_display
*/
struct glx_screen **screens;
__glxHashTable *glXDrawHash;
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
__glxHashTable *drawHash;
@ -579,6 +581,14 @@ struct glx_display
#endif
};
struct glx_drawable {
XID xDrawable;
XID drawable;
uint32_t lastEventSbc;
int64_t eventSbcWrap;
};
extern int
glx_screen_init(struct glx_screen *psc,
int screen, struct glx_display * priv);
@ -784,6 +794,12 @@ extern int
applegl_create_display(struct glx_display *display);
#endif
extern struct glx_drawable *GetGLXDrawable(Display *dpy, GLXDrawable drawable);
extern int InitGLXDrawable(Display *dpy, struct glx_drawable *glxDraw,
XID xDrawable, GLXDrawable drawable);
extern void DestroyGLXDrawable(Display *dpy, GLXDrawable drawable);
extern struct glx_context dummyContext;
extern struct glx_screen *

View file

@ -90,6 +90,51 @@ GetGLXDRIDrawable(Display * dpy, GLXDrawable drawable)
#endif
_X_HIDDEN struct glx_drawable *
GetGLXDrawable(Display *dpy, GLXDrawable drawable)
{
struct glx_display *priv = __glXInitialize(dpy);
struct glx_drawable *glxDraw;
if (priv == NULL)
return NULL;
if (__glxHashLookup(priv->glXDrawHash, drawable, (void *) &glxDraw) == 0)
return glxDraw;
return NULL;
}
_X_HIDDEN int
InitGLXDrawable(Display *dpy, struct glx_drawable *glxDraw, XID xDrawable,
GLXDrawable drawable)
{
struct glx_display *priv = __glXInitialize(dpy);
if (!priv)
return -1;
glxDraw->xDrawable = xDrawable;
glxDraw->drawable = drawable;
glxDraw->lastEventSbc = 0;
glxDraw->eventSbcWrap = 0;
return __glxHashInsert(priv->glXDrawHash, drawable, glxDraw);
}
_X_HIDDEN void
DestroyGLXDrawable(Display *dpy, GLXDrawable drawable)
{
struct glx_display *priv = __glXInitialize(dpy);
struct glx_drawable *glxDraw;
if (!priv)
return;
glxDraw = GetGLXDrawable(dpy, drawable);
__glxHashDelete(priv->glXDrawHash, drawable);
free(glxDraw);
}
/**
* Get the GLX per-screen data structure associated with a GLX context.
@ -608,6 +653,7 @@ glXCreateGLXPixmap(Display * dpy, XVisualInfo * vis, Pixmap pixmap)
return pixmap;
#else
xGLXCreateGLXPixmapReq *req;
struct glx_drawable *glxDraw;
GLXPixmap xid;
CARD8 opcode;
@ -616,6 +662,10 @@ glXCreateGLXPixmap(Display * dpy, XVisualInfo * vis, Pixmap pixmap)
return None;
}
glxDraw = Xmalloc(sizeof(*glxDraw));
if (!glxDraw)
return None;
/* Send the glXCreateGLXPixmap request */
LockDisplay(dpy);
GetReq(GLXCreateGLXPixmap, req);
@ -628,6 +678,11 @@ glXCreateGLXPixmap(Display * dpy, XVisualInfo * vis, Pixmap pixmap)
UnlockDisplay(dpy);
SyncHandle();
if (InitGLXDrawable(dpy, glxDraw, pixmap, req->glxpixmap)) {
free(glxDraw);
return None;
}
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
do {
/* FIXME: Maybe delay __DRIdrawable creation until the drawable
@ -700,6 +755,8 @@ glXDestroyGLXPixmap(Display * dpy, GLXPixmap glxpixmap)
UnlockDisplay(dpy);
SyncHandle();
DestroyGLXDrawable(dpy, glxpixmap);
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
{
struct glx_display *const priv = __glXInitialize(dpy);

View file

@ -133,12 +133,20 @@ __glXWireToEvent(Display *dpy, XEvent *event, xEvent *wire)
case GLX_BufferSwapComplete:
{
GLXBufferSwapComplete *aevent = (GLXBufferSwapComplete *)event;
xGLXBufferSwapComplete *awire = (xGLXBufferSwapComplete *)wire;
xGLXBufferSwapComplete2 *awire = (xGLXBufferSwapComplete2 *)wire;
struct glx_drawable *glxDraw = GetGLXDrawable(dpy, awire->drawable);
aevent->event_type = awire->event_type;
aevent->drawable = awire->drawable;
aevent->ust = ((CARD64)awire->ust_hi << 32) | awire->ust_lo;
aevent->msc = ((CARD64)awire->msc_hi << 32) | awire->msc_lo;
aevent->sbc = ((CARD64)awire->sbc_hi << 32) | awire->sbc_lo;
if (!glxDraw)
return False;
if (awire->sbc < glxDraw->lastEventSbc)
glxDraw->eventSbcWrap += 0x100000000;
glxDraw->lastEventSbc = awire->sbc;
aevent->sbc = awire->sbc + glxDraw->eventSbcWrap;
return True;
}
default:
@ -227,6 +235,8 @@ glx_display_free(struct glx_display *priv)
if (priv->serverGLXversion)
Xfree((char *) priv->serverGLXversion);
__glxHashDestroy(priv->glXDrawHash);
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
__glxHashDestroy(priv->drawHash);
@ -847,6 +857,8 @@ __glXInitialize(Display * dpy)
XESetCloseDisplay(dpy, dpyPriv->codes->extension, __glXCloseDisplay);
XESetErrorString (dpy, dpyPriv->codes->extension,__glXErrorString);
dpyPriv->glXDrawHash = __glxHashCreate();
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
glx_direct = (getenv("LIBGL_ALWAYS_INDIRECT") == NULL);
glx_accel = (getenv("LIBGL_ALWAYS_SOFTWARE") == NULL);

View file

@ -618,11 +618,9 @@ i830_set_draw_region(struct intel_context *intel,
uint32_t draw_x, draw_y;
if (state->draw_region != color_regions[0]) {
intel_region_release(&state->draw_region);
intel_region_reference(&state->draw_region, color_regions[0]);
}
if (state->depth_region != depth_region) {
intel_region_release(&state->depth_region);
intel_region_reference(&state->depth_region, depth_region);
}

View file

@ -570,11 +570,9 @@ i915_set_draw_region(struct intel_context *intel,
uint32_t draw_x, draw_y, draw_offset;
if (state->draw_region != color_regions[0]) {
intel_region_release(&state->draw_region);
intel_region_reference(&state->draw_region, color_regions[0]);
}
if (state->depth_region != depth_region) {
intel_region_release(&state->depth_region);
intel_region_reference(&state->depth_region, depth_region);
}

View file

@ -867,7 +867,7 @@
#define CMD_CONST_BUFFER 0x6002
#define CMD_STATE_BASE_ADDRESS 0x6101
#define CMD_STATE_INSN_POINTER 0x6102
#define CMD_STATE_SIP 0x6102
#define CMD_PIPELINE_SELECT_965 0x6104
#define CMD_PIPELINE_SELECT_GM45 0x6904

View file

@ -1791,7 +1791,8 @@ fs_visitor::emit_fb_writes()
{
this->current_annotation = "FB write header";
GLboolean header_present = GL_TRUE;
int nr = 2;
int base_mrf = 2;
int nr = base_mrf;
int reg_width = c->dispatch_width / 8;
if (intel->gen >= 6 &&
@ -1870,8 +1871,8 @@ fs_visitor::emit_fb_writes()
fs_inst *inst = emit(FS_OPCODE_FB_WRITE);
inst->target = target;
inst->base_mrf = 2;
inst->mlen = nr;
inst->base_mrf = base_mrf;
inst->mlen = nr - base_mrf;
if (target == c->key.nr_color_regions - 1)
inst->eot = true;
inst->header_present = header_present;
@ -1888,8 +1889,8 @@ fs_visitor::emit_fb_writes()
}
fs_inst *inst = emit(FS_OPCODE_FB_WRITE);
inst->base_mrf = 2;
inst->mlen = nr;
inst->base_mrf = base_mrf;
inst->mlen = nr - base_mrf;
inst->eot = true;
inst->header_present = header_present;
}

View file

@ -609,28 +609,17 @@ static void upload_invarient_state( struct brw_context *brw )
if (intel->gen == 6)
intel_emit_post_sync_nonzero_flush(intel);
{
/* 0x61040000 Pipeline Select */
/* PipelineSelect : 0 */
struct brw_pipeline_select ps;
memset(&ps, 0, sizeof(ps));
ps.header.opcode = brw->CMD_PIPELINE_SELECT;
ps.header.pipeline_select = 0;
BRW_BATCH_STRUCT(brw, &ps);
}
/* Select the 3D pipeline (as opposed to media) */
BEGIN_BATCH(1);
OUT_BATCH(brw->CMD_PIPELINE_SELECT << 16 | 0);
ADVANCE_BATCH();
if (intel->gen < 6) {
struct brw_global_depth_offset_clamp gdo;
memset(&gdo, 0, sizeof(gdo));
/* Disable depth offset clamping.
*/
gdo.header.opcode = _3DSTATE_GLOBAL_DEPTH_OFFSET_CLAMP;
gdo.header.length = sizeof(gdo)/4 - 2;
gdo.depth_offset_clamp = 0.0;
BRW_BATCH_STRUCT(brw, &gdo);
/* Disable depth offset clamping. */
BEGIN_BATCH(2);
OUT_BATCH(_3DSTATE_GLOBAL_DEPTH_OFFSET_CLAMP << 16 | (2 - 2));
OUT_BATCH_F(0.0);
ADVANCE_BATCH();
}
if (intel->gen >= 6) {
@ -663,30 +652,15 @@ static void upload_invarient_state( struct brw_context *brw )
}
}
/* 0x61020000 State Instruction Pointer */
{
struct brw_system_instruction_pointer sip;
memset(&sip, 0, sizeof(sip));
BEGIN_BATCH(2);
OUT_BATCH(CMD_STATE_SIP << 16 | (2 - 2));
OUT_BATCH(0);
ADVANCE_BATCH();
sip.header.opcode = CMD_STATE_INSN_POINTER;
sip.header.length = 0;
sip.bits0.pad = 0;
sip.bits0.system_instruction_pointer = 0;
BRW_BATCH_STRUCT(brw, &sip);
}
{
struct brw_vf_statistics vfs;
memset(&vfs, 0, sizeof(vfs));
vfs.opcode = brw->CMD_VF_STATISTICS;
if (unlikely(INTEL_DEBUG & DEBUG_STATS))
vfs.statistics_enable = 1;
BRW_BATCH_STRUCT(brw, &vfs);
}
BEGIN_BATCH(1);
OUT_BATCH(brw->CMD_VF_STATISTICS << 16 |
(unlikely(INTEL_DEBUG & DEBUG_STATS) ? 1 : 0));
ADVANCE_BATCH();
}
const struct brw_tracked_state brw_invarient_state = {

View file

@ -40,46 +40,6 @@
/** Number of message register file registers */
#define BRW_MAX_MRF 16
/* Command packets:
*/
struct header
{
GLuint length:16;
GLuint opcode:16;
};
union header_union
{
struct header bits;
GLuint dword;
};
struct brw_3d_control
{
struct
{
GLuint length:8;
GLuint notify_enable:1;
GLuint pad:3;
GLuint wc_flush_enable:1;
GLuint depth_stall_enable:1;
GLuint operation:2;
GLuint opcode:16;
} header;
struct
{
GLuint pad:2;
GLuint dest_addr_type:1;
GLuint dest_addr:29;
} dest;
GLuint dword2;
GLuint dword3;
};
/* These seem to be passed around as function args, so it works out
* better to keep them as #defines:
*/
@ -88,314 +48,6 @@ struct brw_3d_control
#define BRW_INHIBIT_FLUSH_RENDER_CACHE 0x4
#define BRW_FLUSH_SNAPSHOT_COUNTERS 0x8
struct brw_mi_flush
{
GLuint flags:4;
GLuint pad:12;
GLuint opcode:16;
};
struct brw_vf_statistics
{
GLuint statistics_enable:1;
GLuint pad:15;
GLuint opcode:16;
};
struct brw_binding_table_pointers
{
struct header header;
GLuint vs;
GLuint gs;
GLuint clp;
GLuint sf;
GLuint wm;
};
struct brw_blend_constant_color
{
struct header header;
GLfloat blend_constant_color[4];
};
struct brw_depthbuffer
{
union header_union header;
union {
struct {
GLuint pitch:18;
GLuint format:3;
GLuint pad:2;
GLuint software_tiled_rendering_mode:2;
GLuint depth_offset_disable:1;
GLuint tile_walk:1;
GLuint tiled_surface:1;
GLuint pad2:1;
GLuint surface_type:3;
} bits;
GLuint dword;
} dword1;
GLuint dword2_base_addr;
union {
struct {
GLuint pad:1;
GLuint mipmap_layout:1;
GLuint lod:4;
GLuint width:13;
GLuint height:13;
} bits;
GLuint dword;
} dword3;
union {
struct {
GLuint pad:10;
GLuint min_array_element:11;
GLuint depth:11;
} bits;
GLuint dword;
} dword4;
};
struct brw_depthbuffer_g4x
{
union header_union header;
union {
struct {
GLuint pitch:18;
GLuint format:3;
GLuint pad:2;
GLuint software_tiled_rendering_mode:2;
GLuint depth_offset_disable:1;
GLuint tile_walk:1;
GLuint tiled_surface:1;
GLuint pad2:1;
GLuint surface_type:3;
} bits;
GLuint dword;
} dword1;
GLuint dword2_base_addr;
union {
struct {
GLuint pad:1;
GLuint mipmap_layout:1;
GLuint lod:4;
GLuint width:13;
GLuint height:13;
} bits;
GLuint dword;
} dword3;
union {
struct {
GLuint pad:10;
GLuint min_array_element:11;
GLuint depth:11;
} bits;
GLuint dword;
} dword4;
union {
struct {
GLuint xoffset:16;
GLuint yoffset:16;
} bits;
GLuint dword;
} dword5; /* NEW in Integrated Graphics Device */
};
struct brw_drawrect
{
struct header header;
GLuint xmin:16;
GLuint ymin:16;
GLuint xmax:16;
GLuint ymax:16;
GLuint xorg:16;
GLuint yorg:16;
};
struct brw_global_depth_offset_clamp
{
struct header header;
GLfloat depth_offset_clamp;
};
struct brw_indexbuffer
{
union {
struct
{
GLuint length:8;
GLuint index_format:2;
GLuint cut_index_enable:1;
GLuint pad:5;
GLuint opcode:16;
} bits;
GLuint dword;
} header;
GLuint buffer_start;
GLuint buffer_end;
};
/* NEW in Integrated Graphics Device */
struct brw_aa_line_parameters
{
struct header header;
struct {
GLuint aa_coverage_slope:8;
GLuint pad0:8;
GLuint aa_coverage_bias:8;
GLuint pad1:8;
} bits0;
struct {
GLuint aa_coverage_endcap_slope:8;
GLuint pad0:8;
GLuint aa_coverage_endcap_bias:8;
GLuint pad1:8;
} bits1;
};
struct brw_line_stipple
{
struct header header;
struct
{
GLuint pattern:16;
GLuint pad:16;
} bits0;
struct
{
GLuint repeat_count:9;
GLuint pad:7;
GLuint inverse_repeat_count:16;
} bits1;
};
struct brw_pipelined_state_pointers
{
struct header header;
struct {
GLuint pad:5;
GLuint offset:27; /* Offset from GENERAL_STATE_BASE */
} vs;
struct
{
GLuint enable:1;
GLuint pad:4;
GLuint offset:27; /* Offset from GENERAL_STATE_BASE */
} gs;
struct
{
GLuint enable:1;
GLuint pad:4;
GLuint offset:27; /* Offset from GENERAL_STATE_BASE */
} clp;
struct
{
GLuint pad:5;
GLuint offset:27; /* Offset from GENERAL_STATE_BASE */
} sf;
struct
{
GLuint pad:5;
GLuint offset:27; /* Offset from GENERAL_STATE_BASE */
} wm;
struct
{
GLuint pad:5;
GLuint offset:27; /* Offset from GENERAL_STATE_BASE. KW: check me! */
} cc;
};
struct brw_polygon_stipple_offset
{
struct header header;
struct {
GLuint y_offset:5;
GLuint pad:3;
GLuint x_offset:5;
GLuint pad0:19;
} bits0;
};
struct brw_polygon_stipple
{
struct header header;
GLuint stipple[32];
};
struct brw_pipeline_select
{
struct
{
GLuint pipeline_select:1;
GLuint pad:15;
GLuint opcode:16;
} header;
};
struct brw_pipe_control
{
struct
{
GLuint length:8;
GLuint notify_enable:1;
GLuint texture_cache_flush_enable:1;
GLuint indirect_state_pointers_disable:1;
GLuint instruction_state_cache_flush_enable:1;
GLuint write_cache_flush_enable:1;
GLuint depth_stall_enable:1;
GLuint post_sync_operation:2;
GLuint opcode:16;
} header;
struct
{
GLuint pad:2;
GLuint dest_addr_type:1;
GLuint dest_addr:29;
} bits1;
GLuint data0;
GLuint data1;
};
struct brw_urb_fence
{
struct
@ -428,102 +80,6 @@ struct brw_urb_fence
} bits1;
};
struct brw_cs_urb_state
{
struct header header;
struct
{
GLuint nr_urb_entries:3;
GLuint pad:1;
GLuint urb_entry_size:5;
GLuint pad0:23;
} bits0;
};
struct brw_constant_buffer
{
struct
{
GLuint length:8;
GLuint valid:1;
GLuint pad:7;
GLuint opcode:16;
} header;
struct
{
GLuint buffer_length:6;
GLuint buffer_address:26;
} bits0;
};
struct brw_state_base_address
{
struct header header;
struct
{
GLuint modify_enable:1;
GLuint pad:4;
GLuint general_state_address:27;
} bits0;
struct
{
GLuint modify_enable:1;
GLuint pad:4;
GLuint surface_state_address:27;
} bits1;
struct
{
GLuint modify_enable:1;
GLuint pad:4;
GLuint indirect_object_state_address:27;
} bits2;
struct
{
GLuint modify_enable:1;
GLuint pad:11;
GLuint general_state_upper_bound:20;
} bits3;
struct
{
GLuint modify_enable:1;
GLuint pad:11;
GLuint indirect_object_state_upper_bound:20;
} bits4;
};
struct brw_state_prefetch
{
struct header header;
struct
{
GLuint prefetch_count:3;
GLuint pad:3;
GLuint prefetch_pointer:26;
} bits0;
};
struct brw_system_instruction_pointer
{
struct header header;
struct
{
GLuint pad:4;
GLuint system_instruction_pointer:28;
} bits0;
};
/* State structs for the various fixed function units:
*/
@ -1327,12 +883,6 @@ struct brw_vertex_element_state
#define BRW_VEP_MAX 18
struct brw_vertex_element_packet {
struct header header;
struct brw_vertex_element_state ve[BRW_VEP_MAX]; /* note: less than _TNL_ATTRIB_MAX */
};
struct brw_urb_immediate {
GLuint opcode:4;
GLuint offset:6;

View file

@ -47,6 +47,7 @@ brw_prepare_vs_unit(struct brw_context *brw)
memset(vs, 0, sizeof(*vs));
/* BRW_NEW_PROGRAM_CACHE | CACHE_NEW_VS_PROG */
vs->thread0.grf_reg_count = ALIGN(brw->vs.prog_data->total_grf, 16) / 16 - 1;
vs->thread0.kernel_start_pointer =
brw_program_reloc(brw,
brw->vs.state_offset +
@ -54,7 +55,6 @@ brw_prepare_vs_unit(struct brw_context *brw)
brw->vs.prog_offset +
(vs->thread0.grf_reg_count << 1)) >> 6;
vs->thread0.grf_reg_count = ALIGN(brw->vs.prog_data->total_grf, 16) / 16 - 1;
vs->thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754;
/* Choosing multiple program flow means that we may get 2-vertex threads,
* which will have the channel mask for dwords 4-7 enabled in the thread,

View file

@ -138,11 +138,9 @@ upload_wm_state(struct brw_context *brw)
const struct brw_tracked_state gen7_wm_state = {
.dirty = {
.mesa = (_NEW_LINE | _NEW_POLYGON | _NEW_POLYGONSTIPPLE |
.mesa = (_NEW_LINE | _NEW_POLYGON |
_NEW_COLOR | _NEW_BUFFERS),
.brw = (BRW_NEW_CURBE_OFFSETS |
BRW_NEW_FRAGMENT_PROGRAM |
BRW_NEW_NR_WM_SURFACES |
.brw = (BRW_NEW_FRAGMENT_PROGRAM |
BRW_NEW_URB_FENCE |
BRW_NEW_BATCH),
.cache = 0,
@ -240,10 +238,7 @@ upload_ps_state(struct brw_context *brw)
const struct brw_tracked_state gen7_ps_state = {
.dirty = {
.mesa = (_NEW_LINE |
_NEW_POLYGON |
_NEW_POLYGONSTIPPLE |
_NEW_PROGRAM_CONSTANTS),
.mesa = _NEW_PROGRAM_CONSTANTS,
.brw = (BRW_NEW_CURBE_OFFSETS |
BRW_NEW_FRAGMENT_PROGRAM |
BRW_NEW_NR_WM_SURFACES |

View file

@ -118,7 +118,6 @@ intelClear(struct gl_context *ctx, GLbitfield mask)
/* HW color buffers (front, back, aux, generic FBO, etc) */
if (colorMask == ~0) {
/* clear all R,G,B,A */
/* XXX FBO: need to check if colorbuffers are software RBOs! */
blit_mask |= (mask & BUFFER_BITS_COLOR);
}
else {

View file

@ -661,7 +661,7 @@ intelInitContext(struct intel_context *intel,
/* Depth and stencil */
ctx->TextureFormatSupported[MESA_FORMAT_S8_Z24] = GL_TRUE;
ctx->TextureFormatSupported[MESA_FORMAT_X8_Z24] = intel->has_separate_stencil;
ctx->TextureFormatSupported[MESA_FORMAT_X8_Z24] = GL_TRUE;
ctx->TextureFormatSupported[MESA_FORMAT_S8] = intel->has_separate_stencil;
/*
@ -922,6 +922,8 @@ intelDestroyContext(__DRIcontext * driContextPriv)
/* free the Mesa context */
_mesa_free_context_data(&intel->ctx);
_math_matrix_dtr(&intel->ViewportMatrix);
FREE(intel);
driContextPriv->driverPrivate = NULL;
}
@ -1112,7 +1114,6 @@ intel_query_dri2_buffers_no_separate_stencil(struct intel_context *intel,
*
* \see intel_update_renderbuffers()
* \see intel_region_alloc_for_handle()
* \see intel_renderbuffer_set_region()
*/
static void
intel_process_dri2_buffer_no_separate_stencil(struct intel_context *intel,
@ -1124,7 +1125,6 @@ intel_process_dri2_buffer_no_separate_stencil(struct intel_context *intel,
assert(!intel->must_use_separate_stencil);
struct gl_framebuffer *fb = drawable->driverPrivate;
struct intel_region *region = NULL;
struct intel_renderbuffer *depth_rb = NULL;
if (!rb)
@ -1151,20 +1151,18 @@ intel_process_dri2_buffer_no_separate_stencil(struct intel_context *intel,
if (unlikely(INTEL_DEBUG & DEBUG_DRI)) {
fprintf(stderr, "(reusing depth buffer as stencil)\n");
}
intel_region_reference(&region, depth_rb->region);
intel_region_reference(&rb->region, depth_rb->region);
} else {
region = intel_region_alloc_for_handle(intel->intelScreen,
buffer->cpp,
drawable->w,
drawable->h,
buffer->pitch / buffer->cpp,
buffer->name,
buffer_name);
intel_region_release(&rb->region);
rb->region = intel_region_alloc_for_handle(intel->intelScreen,
buffer->cpp,
drawable->w,
drawable->h,
buffer->pitch / buffer->cpp,
buffer->name,
buffer_name);
}
intel_renderbuffer_set_region(intel, rb, region);
intel_region_release(&region);
if (buffer->attachment == __DRI_BUFFER_DEPTH_STENCIL) {
struct intel_renderbuffer *stencil_rb =
intel_get_renderbuffer(fb, BUFFER_STENCIL);
@ -1172,10 +1170,10 @@ intel_process_dri2_buffer_no_separate_stencil(struct intel_context *intel,
if (!stencil_rb)
return;
if (stencil_rb->region && stencil_rb->region->name == buffer->name)
return;
intel_renderbuffer_set_region(intel, stencil_rb, region);
/* The rb passed in is the BUFFER_DEPTH attachment, and we need
* to associate this region to BUFFER_STENCIL as well.
*/
intel_region_reference(&stencil_rb->region, rb->region);
}
}
@ -1300,7 +1298,6 @@ intel_query_dri2_buffers_with_separate_stencil(struct intel_context *intel,
*
* \see intel_update_renderbuffers()
* \see intel_region_alloc_for_handle()
* \see intel_renderbuffer_set_region()
* \see enum intel_dri2_has_hiz
*/
static void
@ -1360,9 +1357,9 @@ intel_process_dri2_buffer_with_separate_stencil(struct intel_context *intel,
buffer_name);
if (buffer->attachment == __DRI_BUFFER_HIZ) {
intel_renderbuffer_set_hiz_region(intel, rb, region);
intel_region_reference(&rb->hiz_region, region);
} else {
intel_renderbuffer_set_region(intel, rb, region);
intel_region_reference(&rb->region, region);
}
intel_region_release(&region);
@ -1511,12 +1508,10 @@ intel_verify_dri2_has_hiz(struct intel_context *intel,
/ depth_stencil_buffer->cpp,
depth_stencil_buffer->name,
"dri2 depth / stencil buffer");
intel_renderbuffer_set_region(intel,
intel_get_renderbuffer(fb, BUFFER_DEPTH),
region);
intel_renderbuffer_set_region(intel,
intel_get_renderbuffer(fb, BUFFER_STENCIL),
region);
intel_region_reference(&intel_get_renderbuffer(fb, BUFFER_DEPTH)->region,
region);
intel_region_reference(&intel_get_renderbuffer(fb, BUFFER_STENCIL)->region,
region);
intel_region_release(&region);
}
}

View file

@ -70,24 +70,15 @@ intel_new_framebuffer(struct gl_context * ctx, GLuint name)
static void
intel_delete_renderbuffer(struct gl_renderbuffer *rb)
{
GET_CURRENT_CONTEXT(ctx);
struct intel_context *intel = intel_context(ctx);
struct intel_renderbuffer *irb = intel_renderbuffer(rb);
ASSERT(irb);
if (intel && irb->region) {
intel_region_release(&irb->region);
}
if (intel && irb->hiz_region) {
intel_region_release(&irb->hiz_region);
}
if (intel && irb->wrapped_depth) {
_mesa_reference_renderbuffer(&irb->wrapped_depth, NULL);
}
if (intel && irb->wrapped_stencil) {
_mesa_reference_renderbuffer(&irb->wrapped_stencil, NULL);
}
intel_region_release(&irb->region);
intel_region_release(&irb->hiz_region);
_mesa_reference_renderbuffer(&irb->wrapped_depth, NULL);
_mesa_reference_renderbuffer(&irb->wrapped_stencil, NULL);
free(irb);
}
@ -277,8 +268,6 @@ intel_image_target_renderbuffer_storage(struct gl_context *ctx,
return;
irb = intel_renderbuffer(rb);
if (irb->region)
intel_region_release(&irb->region);
intel_region_reference(&irb->region, image->region);
rb->InternalFormat = image->internal_format;
@ -345,33 +334,6 @@ intel_nop_alloc_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
return GL_FALSE;
}
void
intel_renderbuffer_set_region(struct intel_context *intel,
struct intel_renderbuffer *rb,
struct intel_region *region)
{
struct intel_region *old;
old = rb->region;
rb->region = NULL;
intel_region_reference(&rb->region, region);
intel_region_release(&old);
}
void
intel_renderbuffer_set_hiz_region(struct intel_context *intel,
struct intel_renderbuffer *rb,
struct intel_region *region)
{
struct intel_region *old = rb->hiz_region;
rb->hiz_region = NULL;
intel_region_reference(&rb->hiz_region, region);
intel_region_release(&old);
}
/**
* Create a new intel_renderbuffer which corresponds to an on-screen window,
* not a user-created renderbuffer.
@ -572,7 +534,6 @@ intel_update_tex_wrapper_regions(struct intel_context *intel,
/* Point the renderbuffer's region to the texture's region. */
if (irb->region != intel_image->mt->region) {
intel_region_release(&irb->region);
intel_region_reference(&irb->region, intel_image->mt->region);
}
@ -592,7 +553,6 @@ intel_update_tex_wrapper_regions(struct intel_context *intel,
/* Point the renderbuffer's hiz region to the texture's hiz region. */
if (irb->hiz_region != intel_image->mt->hiz_region) {
intel_region_release(&irb->hiz_region);
intel_region_reference(&irb->hiz_region, intel_image->mt->hiz_region);
}
@ -770,7 +730,6 @@ intel_render_texture(struct gl_context * ctx,
intel_image->mt = new_mt;
intel_renderbuffer_set_draw_offset(irb, intel_image, att->Zoffset);
intel_region_release(&irb->region);
intel_region_reference(&irb->region, intel_image->mt->region);
}
#endif

View file

@ -155,18 +155,6 @@ intel_framebuffer_has_hiz(struct gl_framebuffer *fb)
return intel_framebuffer_get_hiz_region(fb) != NULL;
}
extern void
intel_renderbuffer_set_region(struct intel_context *intel,
struct intel_renderbuffer *irb,
struct intel_region *region);
extern void
intel_renderbuffer_set_hiz_region(struct intel_context *intel,
struct intel_renderbuffer *rb,
struct intel_region *region);
extern struct intel_renderbuffer *
intel_create_renderbuffer(gl_format format);

View file

@ -175,7 +175,7 @@ do_blit_bitmap( struct gl_context *ctx,
const GLubyte *bitmap )
{
struct intel_context *intel = intel_context(ctx);
struct intel_region *dst = intel_drawbuf_region(intel);
struct intel_region *dst;
struct gl_framebuffer *fb = ctx->DrawBuffer;
GLfloat tmpColor[4];
GLubyte ubcolor[4];
@ -198,6 +198,9 @@ do_blit_bitmap( struct gl_context *ctx,
return GL_FALSE;
}
intel_prepare_render(intel);
dst = intel_drawbuf_region(intel);
if (!dst)
return GL_FALSE;
@ -226,8 +229,6 @@ do_blit_bitmap( struct gl_context *ctx,
if (!intel_check_blit_fragment_ops(ctx, tmpColor[3] == 1.0F))
return GL_FALSE;
intel_prepare_render(intel);
/* Clip to buffer bounds and scissor. */
if (!_mesa_clip_to_region(fb->_Xmin, fb->_Ymin,
fb->_Xmax, fb->_Ymax,

View file

@ -264,12 +264,15 @@ intel_region_alloc_for_handle(struct intel_screen *screen,
void
intel_region_reference(struct intel_region **dst, struct intel_region *src)
{
if (src)
_DBG("%s %p %d\n", __FUNCTION__, src, src->refcount);
_DBG("%s: %p(%d) -> %p(%d)\n", __FUNCTION__,
*dst, *dst ? (*dst)->refcount : 0, src, src ? src->refcount : 0);
assert(*dst == NULL);
if (src) {
src->refcount++;
if (src != *dst) {
if (*dst)
intel_region_release(dst);
if (src)
src->refcount++;
*dst = src;
}
}

View file

@ -291,7 +291,6 @@ intel_dup_image(__DRIimage *orig_image, void *loaderPrivate)
if (image == NULL)
return NULL;
image->region = NULL;
intel_region_reference(&image->region, orig_image->region);
if (image->region == NULL) {
FREE(image);

View file

@ -55,15 +55,11 @@ get_teximage_readbuffer(struct intel_context *intel, GLenum internalFormat)
DBG("%s %s\n", __FUNCTION__,
_mesa_lookup_enum_by_nr(internalFormat));
switch (internalFormat) {
case GL_DEPTH_COMPONENT:
case GL_DEPTH_COMPONENT16:
case GL_DEPTH24_STENCIL8_EXT:
case GL_DEPTH_STENCIL_EXT:
if (_mesa_is_depth_format(internalFormat) ||
_mesa_is_depthstencil_format(internalFormat))
return intel_get_renderbuffer(intel->ctx.ReadBuffer, BUFFER_DEPTH);
default:
return intel_renderbuffer(intel->ctx.ReadBuffer->_ColorReadBuffer);
}
return intel_renderbuffer(intel->ctx.ReadBuffer->_ColorReadBuffer);
}

View file

@ -269,6 +269,71 @@ _mesa_IsProgramARB(GLuint id)
return GL_FALSE;
}
static GLboolean
get_local_param_pointer(struct gl_context *ctx, const char *func,
GLenum target, GLuint index, GLfloat **param)
{
struct gl_program *prog;
GLuint maxParams;
if (target == GL_VERTEX_PROGRAM_ARB
&& ctx->Extensions.ARB_vertex_program) {
prog = &(ctx->VertexProgram.Current->Base);
maxParams = ctx->Const.VertexProgram.MaxLocalParams;
}
else if (target == GL_FRAGMENT_PROGRAM_ARB
&& ctx->Extensions.ARB_fragment_program) {
prog = &(ctx->FragmentProgram.Current->Base);
maxParams = ctx->Const.FragmentProgram.MaxLocalParams;
}
else if (target == GL_FRAGMENT_PROGRAM_NV
&& ctx->Extensions.NV_fragment_program) {
prog = &(ctx->FragmentProgram.Current->Base);
maxParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
}
else {
_mesa_error(ctx, GL_INVALID_ENUM,
"%s(target)", func);
return GL_FALSE;
}
if (index >= maxParams) {
_mesa_error(ctx, GL_INVALID_VALUE, "%s(index)", func);
return GL_FALSE;
}
*param = prog->LocalParams[index];
return GL_TRUE;
}
static GLboolean
get_env_param_pointer(struct gl_context *ctx, const char *func,
GLenum target, GLuint index, GLfloat **param)
{
if (target == GL_FRAGMENT_PROGRAM_ARB
&& ctx->Extensions.ARB_fragment_program) {
if (index >= ctx->Const.FragmentProgram.MaxEnvParams) {
_mesa_error(ctx, GL_INVALID_VALUE, "%s(index)", func);
return GL_FALSE;
}
*param = ctx->FragmentProgram.Parameters[index];
return GL_TRUE;
}
else if (target == GL_VERTEX_PROGRAM_ARB &&
(ctx->Extensions.ARB_vertex_program ||
ctx->Extensions.NV_vertex_program)) {
if (index >= ctx->Const.VertexProgram.MaxEnvParams) {
_mesa_error(ctx, GL_INVALID_VALUE, "%s(index)", func);
return GL_FALSE;
}
*param = ctx->VertexProgram.Parameters[index];
return GL_TRUE;
} else {
_mesa_error(ctx, GL_INVALID_ENUM, "%s(target)", func);
return GL_FALSE;
}
}
void GLAPIENTRY
_mesa_ProgramStringARB(GLenum target, GLenum format, GLsizei len,
@ -383,30 +448,16 @@ void GLAPIENTRY
_mesa_ProgramEnvParameter4fARB(GLenum target, GLuint index,
GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
GLfloat *param;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
if (target == GL_FRAGMENT_PROGRAM_ARB
&& ctx->Extensions.ARB_fragment_program) {
if (index >= ctx->Const.FragmentProgram.MaxEnvParams) {
_mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter(index)");
return;
}
ASSIGN_4V(ctx->FragmentProgram.Parameters[index], x, y, z, w);
}
else if (target == GL_VERTEX_PROGRAM_ARB /* == GL_VERTEX_PROGRAM_NV */
&& (ctx->Extensions.ARB_vertex_program || ctx->Extensions.NV_vertex_program)) {
if (index >= ctx->Const.VertexProgram.MaxEnvParams) {
_mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter(index)");
return;
}
ASSIGN_4V(ctx->VertexProgram.Parameters[index], x, y, z, w);
}
else {
_mesa_error(ctx, GL_INVALID_ENUM, "glProgramEnvParameter(target)");
return;
if (get_env_param_pointer(ctx, "glProgramEnvParameter",
target, index, &param)) {
ASSIGN_4V(param, x, y, z, w);
}
}
@ -422,32 +473,16 @@ void GLAPIENTRY
_mesa_ProgramEnvParameter4fvARB(GLenum target, GLuint index,
const GLfloat *params)
{
GLfloat *param;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
if (target == GL_FRAGMENT_PROGRAM_ARB
&& ctx->Extensions.ARB_fragment_program) {
if (index >= ctx->Const.FragmentProgram.MaxEnvParams) {
_mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter4fv(index)");
return;
}
memcpy(ctx->FragmentProgram.Parameters[index], params,
4 * sizeof(GLfloat));
}
else if (target == GL_VERTEX_PROGRAM_ARB /* == GL_VERTEX_PROGRAM_NV */
&& (ctx->Extensions.ARB_vertex_program || ctx->Extensions.NV_vertex_program)) {
if (index >= ctx->Const.VertexProgram.MaxEnvParams) {
_mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter4fv(index)");
return;
}
memcpy(ctx->VertexProgram.Parameters[index], params,
4 * sizeof(GLfloat));
}
else {
_mesa_error(ctx, GL_INVALID_ENUM, "glProgramEnvParameter4fv(target)");
return;
if (get_env_param_pointer(ctx, "glProgramEnvParameter4fv",
target, index, &param)) {
memcpy(param, params, 4 * sizeof(GLfloat));
}
}
@ -496,14 +531,11 @@ _mesa_GetProgramEnvParameterdvARB(GLenum target, GLuint index,
GLdouble *params)
{
GET_CURRENT_CONTEXT(ctx);
GLfloat fparams[4];
GLfloat *fparam;
_mesa_GetProgramEnvParameterfvARB(target, index, fparams);
if (ctx->ErrorValue == GL_NO_ERROR) {
params[0] = fparams[0];
params[1] = fparams[1];
params[2] = fparams[2];
params[3] = fparams[3];
if (get_env_param_pointer(ctx, "glGetProgramEnvParameterdv",
target, index, &fparam)) {
COPY_4V(params, fparam);
}
}
@ -512,29 +544,15 @@ void GLAPIENTRY
_mesa_GetProgramEnvParameterfvARB(GLenum target, GLuint index,
GLfloat *params)
{
GLfloat *param;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
if (target == GL_FRAGMENT_PROGRAM_ARB
&& ctx->Extensions.ARB_fragment_program) {
if (index >= ctx->Const.FragmentProgram.MaxEnvParams) {
_mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramEnvParameter(index)");
return;
}
COPY_4V(params, ctx->FragmentProgram.Parameters[index]);
}
else if (target == GL_VERTEX_PROGRAM_ARB
&& ctx->Extensions.ARB_vertex_program) {
if (index >= ctx->Const.VertexProgram.MaxEnvParams) {
_mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramEnvParameter(index)");
return;
}
COPY_4V(params, ctx->VertexProgram.Parameters[index]);
}
else {
_mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramEnvParameter(target)");
return;
if (get_env_param_pointer(ctx, "glGetProgramEnvParameterfv",
target, index, &param)) {
COPY_4V(params, param);
}
}
@ -547,39 +565,16 @@ _mesa_ProgramLocalParameter4fARB(GLenum target, GLuint index,
GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
GET_CURRENT_CONTEXT(ctx);
struct gl_program *prog;
GLfloat *param;
ASSERT_OUTSIDE_BEGIN_END(ctx);
FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
if ((target == GL_FRAGMENT_PROGRAM_NV
&& ctx->Extensions.NV_fragment_program) ||
(target == GL_FRAGMENT_PROGRAM_ARB
&& ctx->Extensions.ARB_fragment_program)) {
if (index >= ctx->Const.FragmentProgram.MaxLocalParams) {
_mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameterARB");
return;
}
prog = &(ctx->FragmentProgram.Current->Base);
if (get_local_param_pointer(ctx, "glProgramLocalParameterARB",
target, index, &param)) {
ASSERT(index < MAX_PROGRAM_LOCAL_PARAMS);
ASSIGN_4V(param, x, y, z, w);
}
else if (target == GL_VERTEX_PROGRAM_ARB
&& ctx->Extensions.ARB_vertex_program) {
if (index >= ctx->Const.VertexProgram.MaxLocalParams) {
_mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameterARB");
return;
}
prog = &(ctx->VertexProgram.Current->Base);
}
else {
_mesa_error(ctx, GL_INVALID_ENUM, "glProgramLocalParameterARB");
return;
}
ASSERT(index < MAX_PROGRAM_LOCAL_PARAMS);
prog->LocalParams[index][0] = x;
prog->LocalParams[index][1] = y;
prog->LocalParams[index][2] = z;
prog->LocalParams[index][3] = w;
}
@ -667,41 +662,14 @@ void GLAPIENTRY
_mesa_GetProgramLocalParameterfvARB(GLenum target, GLuint index,
GLfloat *params)
{
const struct gl_program *prog;
GLuint maxParams;
GLfloat *param;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
if (target == GL_VERTEX_PROGRAM_ARB
&& ctx->Extensions.ARB_vertex_program) {
prog = &(ctx->VertexProgram.Current->Base);
maxParams = ctx->Const.VertexProgram.MaxLocalParams;
if (get_local_param_pointer(ctx, "glProgramLocalParameters4fvEXT",
target, index, &param)) {
COPY_4V(params, param);
}
else if (target == GL_FRAGMENT_PROGRAM_ARB
&& ctx->Extensions.ARB_fragment_program) {
prog = &(ctx->FragmentProgram.Current->Base);
maxParams = ctx->Const.FragmentProgram.MaxLocalParams;
}
else if (target == GL_FRAGMENT_PROGRAM_NV
&& ctx->Extensions.NV_fragment_program) {
prog = &(ctx->FragmentProgram.Current->Base);
maxParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
}
else {
_mesa_error(ctx, GL_INVALID_ENUM,
"glGetProgramLocalParameterARB(target)");
return;
}
if (index >= maxParams) {
_mesa_error(ctx, GL_INVALID_VALUE,
"glGetProgramLocalParameterARB(index)");
return;
}
ASSERT(prog);
ASSERT(index < MAX_PROGRAM_LOCAL_PARAMS);
COPY_4V(params, prog->LocalParams[index]);
}
@ -712,12 +680,13 @@ void GLAPIENTRY
_mesa_GetProgramLocalParameterdvARB(GLenum target, GLuint index,
GLdouble *params)
{
GLfloat *param;
GET_CURRENT_CONTEXT(ctx);
GLfloat floatParams[4];
ASSIGN_4V(floatParams, 0.0F, 0.0F, 0.0F, 0.0F);
_mesa_GetProgramLocalParameterfvARB(target, index, floatParams);
if (ctx->ErrorValue == GL_NO_ERROR) {
COPY_4V(params, floatParams);
ASSERT_OUTSIDE_BEGIN_END(ctx);
if (get_local_param_pointer(ctx, "glProgramLocalParameters4fvEXT",
target, index, &param)) {
COPY_4V(params, param);
}
}

View file

@ -393,6 +393,217 @@ _mesa_new_z24_renderbuffer_wrapper(struct gl_context *ctx,
}
static void
get_row_z32f(struct gl_context *ctx, struct gl_renderbuffer *z32frb, GLuint count,
GLint x, GLint y, void *values)
{
struct gl_renderbuffer *dsrb = z32frb->Wrapped;
GLfloat temp[MAX_WIDTH*2];
GLfloat *dst = (GLfloat *) values;
const GLfloat *src = (const GLfloat *) dsrb->GetPointer(ctx, dsrb, x, y);
GLuint i;
ASSERT(z32frb->DataType == GL_FLOAT);
ASSERT(dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
ASSERT(dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8);
if (!src) {
dsrb->GetRow(ctx, dsrb, count, x, y, temp);
src = temp;
}
for (i = 0; i < count; i++) {
dst[i] = src[i*2];
}
}
static void
get_values_z32f(struct gl_context *ctx, struct gl_renderbuffer *z32frb, GLuint count,
const GLint x[], const GLint y[], void *values)
{
struct gl_renderbuffer *dsrb = z32frb->Wrapped;
GLfloat temp[MAX_WIDTH*2];
GLfloat *dst = (GLfloat *) values;
GLuint i;
ASSERT(z32frb->DataType == GL_FLOAT);
ASSERT(dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
ASSERT(dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8);
ASSERT(count <= MAX_WIDTH);
/* don't bother trying direct access */
dsrb->GetValues(ctx, dsrb, count, x, y, temp);
for (i = 0; i < count; i++) {
dst[i] = temp[i*2];
}
}
static void
put_row_z32f(struct gl_context *ctx, struct gl_renderbuffer *z32frb, GLuint count,
GLint x, GLint y, const void *values, const GLubyte *mask)
{
struct gl_renderbuffer *dsrb = z32frb->Wrapped;
const GLfloat *src = (const GLfloat *) values;
GLfloat *dst = (GLfloat *) dsrb->GetPointer(ctx, dsrb, x, y);
ASSERT(z32frb->DataType == GL_FLOAT);
ASSERT(dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
ASSERT(dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8);
if (dst) {
/* direct access */
GLuint i;
for (i = 0; i < count; i++) {
if (!mask || mask[i]) {
dst[i*2] = src[i];
}
}
}
else {
/* get, modify, put */
GLfloat temp[MAX_WIDTH*2];
GLuint i;
dsrb->GetRow(ctx, dsrb, count, x, y, temp);
for (i = 0; i < count; i++) {
if (!mask || mask[i]) {
temp[i*2] = src[i];
}
}
dsrb->PutRow(ctx, dsrb, count, x, y, temp, mask);
}
}
static void
put_mono_row_z32f(struct gl_context *ctx, struct gl_renderbuffer *z32frb, GLuint count,
GLint x, GLint y, const void *value, const GLubyte *mask)
{
struct gl_renderbuffer *dsrb = z32frb->Wrapped;
GLfloat *dst = (GLfloat *) dsrb->GetPointer(ctx, dsrb, x, y);
ASSERT(z32frb->DataType == GL_FLOAT);
ASSERT(dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
ASSERT(dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8);
if (dst) {
/* direct access */
GLuint i;
const GLfloat val = *(GLfloat*)value;
for (i = 0; i < count; i++) {
if (!mask || mask[i]) {
dst[i*2] = val;
}
}
}
else {
/* get, modify, put */
GLfloat temp[MAX_WIDTH*2];
GLuint i;
const GLfloat val = *(GLfloat *)value;
dsrb->GetRow(ctx, dsrb, count, x, y, temp);
for (i = 0; i < count; i++) {
if (!mask || mask[i]) {
temp[i*2] = val;
}
}
dsrb->PutRow(ctx, dsrb, count, x, y, temp, mask);
}
}
static void
put_values_z32f(struct gl_context *ctx, struct gl_renderbuffer *z32frb, GLuint count,
const GLint x[], const GLint y[],
const void *values, const GLubyte *mask)
{
struct gl_renderbuffer *dsrb = z32frb->Wrapped;
const GLfloat *src = (const GLfloat *) values;
ASSERT(z32frb->DataType == GL_FLOAT);
ASSERT(dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
ASSERT(dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8);
if (dsrb->GetPointer(ctx, dsrb, 0, 0)) {
/* direct access */
GLuint i;
for (i = 0; i < count; i++) {
if (!mask || mask[i]) {
GLfloat *dst = (GLfloat *) dsrb->GetPointer(ctx, dsrb, x[i], y[i]);
*dst = src[i];
}
}
}
else {
/* get, modify, put */
GLfloat temp[MAX_WIDTH*2];
GLuint i;
dsrb->GetValues(ctx, dsrb, count, x, y, temp);
for (i = 0; i < count; i++) {
if (!mask || mask[i]) {
temp[i*2] = src[i];
}
}
dsrb->PutValues(ctx, dsrb, count, x, y, temp, mask);
}
}
static void
put_mono_values_z32f(struct gl_context *ctx, struct gl_renderbuffer *z32frb,
GLuint count, const GLint x[], const GLint y[],
const void *value, const GLubyte *mask)
{
struct gl_renderbuffer *dsrb = z32frb->Wrapped;
GLfloat temp[MAX_WIDTH*2];
GLuint i;
const GLfloat val = *(GLfloat *)value;
ASSERT(z32frb->DataType == GL_FLOAT);
ASSERT(dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
ASSERT(dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8);
/* get, modify, put */
dsrb->GetValues(ctx, dsrb, count, x, y, temp);
for (i = 0; i < count; i++) {
if (!mask || mask[i]) {
temp[i*2] = val;
}
}
dsrb->PutValues(ctx, dsrb, count, x, y, temp, mask);
}
/**
* Wrap the given GL_DEPTH_STENCIL renderbuffer so that it acts like
* a depth renderbuffer.
* \return new depth renderbuffer
*/
struct gl_renderbuffer *
_mesa_new_z32f_renderbuffer_wrapper(struct gl_context *ctx,
struct gl_renderbuffer *dsrb)
{
struct gl_renderbuffer *z32frb;
ASSERT(dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8);
ASSERT(dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
z32frb = ctx->Driver.NewRenderbuffer(ctx, 0);
if (!z32frb)
return NULL;
/* NOTE: need to do manual refcounting here */
z32frb->Wrapped = dsrb;
dsrb->RefCount++;
z32frb->Name = dsrb->Name;
z32frb->RefCount = 0;
z32frb->Width = dsrb->Width;
z32frb->Height = dsrb->Height;
z32frb->RowStride = dsrb->RowStride;
z32frb->InternalFormat = GL_DEPTH_COMPONENT32F;
z32frb->Format = MESA_FORMAT_Z32_FLOAT;
z32frb->_BaseFormat = GL_DEPTH_COMPONENT;
z32frb->DataType = GL_FLOAT;
z32frb->Data = NULL;
z32frb->Delete = delete_wrapper;
z32frb->AllocStorage = alloc_wrapper_storage;
z32frb->GetPointer = nop_get_pointer;
z32frb->GetRow = get_row_z32f;
z32frb->GetValues = get_values_z32f;
z32frb->PutRow = put_row_z32f;
z32frb->PutRowRGB = NULL;
z32frb->PutMonoRow = put_mono_row_z32f;
z32frb->PutValues = put_values_z32f;
z32frb->PutMonoValues = put_mono_values_z32f;
return z32frb;
}
/*======================================================================
* Stencil wrapper around depth/stencil renderbuffer
*/
@ -402,16 +613,22 @@ get_row_s8(struct gl_context *ctx, struct gl_renderbuffer *s8rb, GLuint count,
GLint x, GLint y, void *values)
{
struct gl_renderbuffer *dsrb = s8rb->Wrapped;
GLuint temp[MAX_WIDTH], i;
GLuint temp[MAX_WIDTH*2], i;
GLubyte *dst = (GLubyte *) values;
const GLuint *src = (const GLuint *) dsrb->GetPointer(ctx, dsrb, x, y);
ASSERT(s8rb->DataType == GL_UNSIGNED_BYTE);
ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT ||
dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
if (!src) {
dsrb->GetRow(ctx, dsrb, count, x, y, temp);
src = temp;
}
if (dsrb->Format == MESA_FORMAT_Z24_S8) {
if (dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8) {
for (i = 0; i < count; i++) {
dst[i] = src[i*2+1] & 0xff;
}
}
else if (dsrb->Format == MESA_FORMAT_Z24_S8) {
for (i = 0; i < count; i++) {
dst[i] = src[i] & 0xff;
}
@ -429,14 +646,20 @@ get_values_s8(struct gl_context *ctx, struct gl_renderbuffer *s8rb, GLuint count
const GLint x[], const GLint y[], void *values)
{
struct gl_renderbuffer *dsrb = s8rb->Wrapped;
GLuint temp[MAX_WIDTH], i;
GLuint temp[MAX_WIDTH*2], i;
GLubyte *dst = (GLubyte *) values;
ASSERT(s8rb->DataType == GL_UNSIGNED_BYTE);
ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT ||
dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
ASSERT(count <= MAX_WIDTH);
/* don't bother trying direct access */
dsrb->GetValues(ctx, dsrb, count, x, y, temp);
if (dsrb->Format == MESA_FORMAT_Z24_S8) {
if (dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8) {
for (i = 0; i < count; i++) {
dst[i] = temp[i*2+1] & 0xff;
}
}
else if (dsrb->Format == MESA_FORMAT_Z24_S8) {
for (i = 0; i < count; i++) {
dst[i] = temp[i] & 0xff;
}
@ -457,11 +680,19 @@ put_row_s8(struct gl_context *ctx, struct gl_renderbuffer *s8rb, GLuint count,
const GLubyte *src = (const GLubyte *) values;
GLuint *dst = (GLuint *) dsrb->GetPointer(ctx, dsrb, x, y);
ASSERT(s8rb->DataType == GL_UNSIGNED_BYTE);
ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT ||
dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
if (dst) {
/* direct access */
GLuint i;
if (dsrb->Format == MESA_FORMAT_Z24_S8) {
if (dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8) {
for (i = 0; i < count; i++) {
if (!mask || mask[i]) {
dst[i*2+1] = src[i];
}
}
}
else if (dsrb->Format == MESA_FORMAT_Z24_S8) {
for (i = 0; i < count; i++) {
if (!mask || mask[i]) {
dst[i] = (dst[i] & 0xffffff00) | src[i];
@ -479,9 +710,16 @@ put_row_s8(struct gl_context *ctx, struct gl_renderbuffer *s8rb, GLuint count,
}
else {
/* get, modify, put */
GLuint temp[MAX_WIDTH], i;
GLuint temp[MAX_WIDTH*2], i;
dsrb->GetRow(ctx, dsrb, count, x, y, temp);
if (dsrb->Format == MESA_FORMAT_Z24_S8) {
if (dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8) {
for (i = 0; i < count; i++) {
if (!mask || mask[i]) {
temp[i*2+1] = src[i];
}
}
}
else if (dsrb->Format == MESA_FORMAT_Z24_S8) {
for (i = 0; i < count; i++) {
if (!mask || mask[i]) {
temp[i] = (temp[i] & 0xffffff00) | src[i];
@ -508,11 +746,19 @@ put_mono_row_s8(struct gl_context *ctx, struct gl_renderbuffer *s8rb, GLuint cou
const GLubyte val = *((GLubyte *) value);
GLuint *dst = (GLuint *) dsrb->GetPointer(ctx, dsrb, x, y);
ASSERT(s8rb->DataType == GL_UNSIGNED_BYTE);
ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT ||
dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
if (dst) {
/* direct access */
GLuint i;
if (dsrb->Format == MESA_FORMAT_Z24_S8) {
if (dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8) {
for (i = 0; i < count; i++) {
if (!mask || mask[i]) {
dst[i*2+1] = val;
}
}
}
else if (dsrb->Format == MESA_FORMAT_Z24_S8) {
for (i = 0; i < count; i++) {
if (!mask || mask[i]) {
dst[i] = (dst[i] & 0xffffff00) | val;
@ -530,9 +776,16 @@ put_mono_row_s8(struct gl_context *ctx, struct gl_renderbuffer *s8rb, GLuint cou
}
else {
/* get, modify, put */
GLuint temp[MAX_WIDTH], i;
GLuint temp[MAX_WIDTH*2], i;
dsrb->GetRow(ctx, dsrb, count, x, y, temp);
if (dsrb->Format == MESA_FORMAT_Z24_S8) {
if (dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8) {
for (i = 0; i < count; i++) {
if (!mask || mask[i]) {
temp[i*2+1] = val;
}
}
}
else if (dsrb->Format == MESA_FORMAT_Z24_S8) {
for (i = 0; i < count; i++) {
if (!mask || mask[i]) {
temp[i] = (temp[i] & 0xffffff00) | val;
@ -559,11 +812,20 @@ put_values_s8(struct gl_context *ctx, struct gl_renderbuffer *s8rb, GLuint count
struct gl_renderbuffer *dsrb = s8rb->Wrapped;
const GLubyte *src = (const GLubyte *) values;
ASSERT(s8rb->DataType == GL_UNSIGNED_BYTE);
ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT ||
dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
if (dsrb->GetPointer(ctx, dsrb, 0, 0)) {
/* direct access */
GLuint i;
if (dsrb->Format == MESA_FORMAT_Z24_S8) {
if (dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8) {
for (i = 0; i < count; i++) {
if (!mask || mask[i]) {
GLuint *dst = (GLuint *) dsrb->GetPointer(ctx, dsrb, x[i], y[i]);
dst[1] = src[i];
}
}
}
else if (dsrb->Format == MESA_FORMAT_Z24_S8) {
for (i = 0; i < count; i++) {
if (!mask || mask[i]) {
GLuint *dst = (GLuint *) dsrb->GetPointer(ctx, dsrb, x[i], y[i]);
@ -583,9 +845,16 @@ put_values_s8(struct gl_context *ctx, struct gl_renderbuffer *s8rb, GLuint count
}
else {
/* get, modify, put */
GLuint temp[MAX_WIDTH], i;
GLuint temp[MAX_WIDTH*2], i;
dsrb->GetValues(ctx, dsrb, count, x, y, temp);
if (dsrb->Format == MESA_FORMAT_Z24_S8) {
if (dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8) {
for (i = 0; i < count; i++) {
if (!mask || mask[i]) {
temp[i*2+1] = src[i];
}
}
}
else if (dsrb->Format == MESA_FORMAT_Z24_S8) {
for (i = 0; i < count; i++) {
if (!mask || mask[i]) {
temp[i] = (temp[i] & 0xffffff00) | src[i];
@ -610,11 +879,18 @@ put_mono_values_s8(struct gl_context *ctx, struct gl_renderbuffer *s8rb, GLuint
const void *value, const GLubyte *mask)
{
struct gl_renderbuffer *dsrb = s8rb->Wrapped;
GLuint temp[MAX_WIDTH], i;
GLuint temp[MAX_WIDTH*2], i;
const GLubyte val = *((GLubyte *) value);
/* get, modify, put */
dsrb->GetValues(ctx, dsrb, count, x, y, temp);
if (dsrb->Format == MESA_FORMAT_Z24_S8) {
if (dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8) {
for (i = 0; i < count; i++) {
if (!mask || mask[i]) {
temp[i*2+1] = val;
}
}
}
else if (dsrb->Format == MESA_FORMAT_Z24_S8) {
for (i = 0; i < count; i++) {
if (!mask || mask[i]) {
temp[i] = (temp[i] & 0xffffff00) | val;
@ -644,8 +920,10 @@ _mesa_new_s8_renderbuffer_wrapper(struct gl_context *ctx, struct gl_renderbuffer
struct gl_renderbuffer *s8rb;
ASSERT(dsrb->Format == MESA_FORMAT_Z24_S8 ||
dsrb->Format == MESA_FORMAT_S8_Z24);
ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
dsrb->Format == MESA_FORMAT_S8_Z24 ||
dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8);
ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT ||
dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
s8rb = ctx->Driver.NewRenderbuffer(ctx, 0);
if (!s8rb)

View file

@ -33,6 +33,11 @@ _mesa_new_z24_renderbuffer_wrapper(struct gl_context *ctx,
struct gl_renderbuffer *dsrb);
extern struct gl_renderbuffer *
_mesa_new_z32f_renderbuffer_wrapper(struct gl_context *ctx,
struct gl_renderbuffer *dsrb);
extern struct gl_renderbuffer *
_mesa_new_s8_renderbuffer_wrapper(struct gl_context *ctx,
struct gl_renderbuffer *dsrb);

View file

@ -1131,6 +1131,16 @@ _mesa_base_fbo_format(struct gl_context *ctx, GLenum internalFormat)
return GL_DEPTH_STENCIL_EXT;
else
return 0;
case GL_DEPTH_COMPONENT32F:
if (ctx->Extensions.ARB_depth_buffer_float)
return GL_DEPTH_COMPONENT;
else
return 0;
case GL_DEPTH32F_STENCIL8:
if (ctx->Extensions.ARB_depth_buffer_float)
return GL_DEPTH_STENCIL;
else
return 0;
case GL_RED:
case GL_R8:
case GL_R16:
@ -2266,6 +2276,15 @@ _mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment,
/* special cases */
*params = GL_INDEX;
}
else if (format == MESA_FORMAT_Z32_FLOAT_X24S8) {
/* depends on the attachment parameter */
if (attachment == GL_STENCIL_ATTACHMENT) {
*params = GL_INDEX;
}
else {
*params = GL_FLOAT;
}
}
else {
*params = _mesa_get_format_datatype(format);
}
@ -2584,6 +2603,10 @@ _mesa_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
}
}
if (!mask) {
return;
}
ASSERT(ctx->Driver.BlitFramebuffer);
ctx->Driver.BlitFramebuffer(ctx,
srcX0, srcY0, srcX1, srcY1,

View file

@ -64,7 +64,7 @@ _mesa_FeedbackBuffer( GLsizei size, GLenum type, GLfloat *buffer )
_mesa_error( ctx, GL_INVALID_VALUE, "glFeedbackBuffer(size<0)" );
return;
}
if (!buffer) {
if (!buffer && size > 0) {
_mesa_error( ctx, GL_INVALID_VALUE, "glFeedbackBuffer(buffer==NULL)" );
ctx->Feedback.BufferSize = 0;
return;

View file

@ -1091,6 +1091,25 @@ static struct gl_format_info format_info[MESA_FORMAT_COUNT] =
0, 0, 0, 0, 0,
1, 1, 4
},
/* ARB_depth_buffer_float */
{
MESA_FORMAT_Z32_FLOAT, /* Name */
"MESA_FORMAT_Z32_FLOAT", /* StrName */
GL_DEPTH_COMPONENT, /* BaseFormat */
GL_FLOAT, /* DataType */
0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */
0, 0, 0, 32, 0, /* Lum/Int/Index/Depth/StencilBits */
1, 1, 4 /* BlockWidth/Height,Bytes */
},
{
MESA_FORMAT_Z32_FLOAT_X24S8, /* Name */
"MESA_FORMAT_Z32_FLOAT_X24S8", /* StrName */
GL_DEPTH_STENCIL, /* BaseFormat */
GL_NONE /* XXX */, /* DataType */
0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */
0, 0, 0, 32, 8, /* Lum/Int/Index/Depth/StencilBits */
1, 1, 8 /* BlockWidth/Height,Bytes */
},
};
@ -1654,6 +1673,16 @@ _mesa_format_to_type_and_comps(gl_format format,
*comps = 1;
return;
case MESA_FORMAT_Z32_FLOAT:
*datatype = GL_FLOAT;
*comps = 1;
return;
case MESA_FORMAT_Z32_FLOAT_X24S8:
*datatype = GL_FLOAT_32_UNSIGNED_INT_24_8_REV;
*comps = 1;
return;
case MESA_FORMAT_DUDV8:
*datatype = GL_BYTE;
*comps = 2;

Some files were not shown because too many files have changed in this diff Show more