mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-08 04:48:08 +02:00
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:
commit
f919547f37
127 changed files with 4018 additions and 2744 deletions
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 &&
|
||||
|
|
|
|||
259
src/gallium/drivers/i915/i915_fpc_optimize.c
Normal file
259
src/gallium/drivers/i915/i915_fpc_optimize.c
Normal 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], ¤t->FullInstruction.Src[1]) &&
|
||||
is_unswizzled(¤t->FullInstruction.Src[0], current->FullInstruction.Dst[0].Register.WriteMask) &&
|
||||
is_unswizzled(¤t->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(¤t->FullInstruction.Src[1], 0, 0);
|
||||
set_neutral_element_swizzle(¤t->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], ¤t->FullInstruction.Src[0]) &&
|
||||
is_unswizzled(¤t->FullInstruction.Src[0], current->FullInstruction.Dst[0].Register.WriteMask) &&
|
||||
is_unswizzled(¤t->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(¤t->FullInstruction.Src[0], 0, 0);
|
||||
set_neutral_element_swizzle(¤t->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);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
/*@}*/
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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++;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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) |
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 =
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)));
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 *
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 = {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 |
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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(®ion, 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(®ion);
|
||||
|
||||
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(®ion);
|
||||
|
|
@ -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(®ion);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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, ¶m)) {
|
||||
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, ¶m)) {
|
||||
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, ¶m)) {
|
||||
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, ¶m)) {
|
||||
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, ¶m)) {
|
||||
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, ¶m)) {
|
||||
COPY_4V(params, param);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Add table
Reference in a new issue