diff options
author | Christian König <[email protected]> | 2011-05-07 14:11:40 +0200 |
---|---|---|
committer | Christian König <[email protected]> | 2011-05-07 14:11:40 +0200 |
commit | 213b9004a6ee033a16af3dcd187aa68b56c39858 (patch) | |
tree | f577f4dc276f70dad63f102f69f87f4d566186ef /src/gallium | |
parent | 6ad846ee78d9d8ba93dcecdefbf89f2b981333ef (diff) | |
parent | 03615c02d81437cf546609fc6a39c6c73be39360 (diff) |
Merge remote-tracking branch 'origin/master' into pipe-video
Conflicts:
src/gallium/drivers/r600/r600_state.c
Diffstat (limited to 'src/gallium')
74 files changed, 2257 insertions, 851 deletions
diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index 7db75b71b43..5523e44563b 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -243,7 +243,7 @@ boolean draw_need_pipeline(const struct draw_context *draw, unsigned prim ); static INLINE int -draw_get_shader_param(unsigned shader, enum pipe_cap param) +draw_get_shader_param(unsigned shader, enum pipe_shader_cap param) { switch(shader) { case PIPE_SHADER_VERTEX: diff --git a/src/gallium/auxiliary/draw/draw_vertex.c b/src/gallium/auxiliary/draw/draw_vertex.c index a4f5e882c0a..a1b2b8ff975 100644 --- a/src/gallium/auxiliary/draw/draw_vertex.c +++ b/src/gallium/auxiliary/draw/draw_vertex.c @@ -60,10 +60,9 @@ draw_compute_vertex_size(struct vertex_info *vinfo) void draw_dump_emitted_vertex(const struct vertex_info *vinfo, const uint8_t *data) { - unsigned i, j; + unsigned i; for (i = 0; i < vinfo->num_attribs; i++) { - j = vinfo->attrib[i].src_index; switch (vinfo->attrib[i].emit) { case EMIT_OMIT: debug_printf("EMIT_OMIT:"); diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c index d1585c8e2b7..d8adb9fbfaf 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c @@ -2565,7 +2565,7 @@ lp_build_system_values_array(struct gallivm_state *gallivm, for (i = 0; i < info->num_system_values; i++) { LLVMValueRef index = lp_build_const_int32(gallivm, i * 4); - LLVMValueRef ptr, value; + LLVMValueRef ptr, value = 0; switch (info->system_value_semantic_name[i]) { case TGSI_SEMANTIC_INSTANCEID: diff --git a/src/gallium/auxiliary/os/os_time.c b/src/gallium/auxiliary/os/os_time.c index 84907215fe6..325f316784c 100644 --- a/src/gallium/auxiliary/os/os_time.c +++ b/src/gallium/auxiliary/os/os_time.c @@ -37,7 +37,7 @@ #if !defined(PIPE_OS_EMBEDDED) -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_CYGWIN) +#if defined(PIPE_OS_UNIX) # include <sys/time.h> /* timeval */ #elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) # include <windows.h> diff --git a/src/gallium/auxiliary/rbug/rbug_context.c b/src/gallium/auxiliary/rbug/rbug_context.c index 36824058c7d..1188dd966e4 100644 --- a/src/gallium/auxiliary/rbug/rbug_context.c +++ b/src/gallium/auxiliary/rbug/rbug_context.c @@ -470,9 +470,6 @@ int rbug_send_context_draw_blocked(struct rbug_connection *__con, struct rbug_proto_context_list * rbug_demarshal_context_list(struct rbug_proto_header *header) { - uint32_t len = 0; - uint32_t pos = 0; - uint8_t *data = NULL; struct rbug_proto_context_list *ret; if (!header) @@ -480,9 +477,6 @@ struct rbug_proto_context_list * rbug_demarshal_context_list(struct rbug_proto_h if (header->opcode != (int32_t)RBUG_OP_CONTEXT_LIST) return NULL; - pos = 0; - len = header->length * 4; - data = (uint8_t*)&header[1]; ret = MALLOC(sizeof(*ret)); if (!ret) return NULL; @@ -490,7 +484,6 @@ struct rbug_proto_context_list * rbug_demarshal_context_list(struct rbug_proto_h ret->header.__message = header; ret->header.opcode = header->opcode; - return ret; } diff --git a/src/gallium/auxiliary/rbug/rbug_core.c b/src/gallium/auxiliary/rbug/rbug_core.c index 1d47d13c9f3..514a10932bc 100644 --- a/src/gallium/auxiliary/rbug/rbug_core.c +++ b/src/gallium/auxiliary/rbug/rbug_core.c @@ -226,9 +226,6 @@ int rbug_send_error_reply(struct rbug_connection *__con, struct rbug_proto_noop * rbug_demarshal_noop(struct rbug_proto_header *header) { - uint32_t len = 0; - uint32_t pos = 0; - uint8_t *data = NULL; struct rbug_proto_noop *ret; if (!header) @@ -236,9 +233,6 @@ struct rbug_proto_noop * rbug_demarshal_noop(struct rbug_proto_header *header) if (header->opcode != (int32_t)RBUG_OP_NOOP) return NULL; - pos = 0; - len = header->length * 4; - data = (uint8_t*)&header[1]; ret = MALLOC(sizeof(*ret)); if (!ret) return NULL; @@ -246,15 +240,11 @@ struct rbug_proto_noop * rbug_demarshal_noop(struct rbug_proto_header *header) ret->header.__message = header; ret->header.opcode = header->opcode; - return ret; } struct rbug_proto_ping * rbug_demarshal_ping(struct rbug_proto_header *header) { - uint32_t len = 0; - uint32_t pos = 0; - uint8_t *data = NULL; struct rbug_proto_ping *ret; if (!header) @@ -262,9 +252,6 @@ struct rbug_proto_ping * rbug_demarshal_ping(struct rbug_proto_header *header) if (header->opcode != (int32_t)RBUG_OP_PING) return NULL; - pos = 0; - len = header->length * 4; - data = (uint8_t*)&header[1]; ret = MALLOC(sizeof(*ret)); if (!ret) return NULL; @@ -272,7 +259,6 @@ struct rbug_proto_ping * rbug_demarshal_ping(struct rbug_proto_header *header) ret->header.__message = header; ret->header.opcode = header->opcode; - return ret; } diff --git a/src/gallium/auxiliary/rbug/rbug_texture.c b/src/gallium/auxiliary/rbug/rbug_texture.c index 2ad577915e8..017c8d0b99b 100644 --- a/src/gallium/auxiliary/rbug/rbug_texture.c +++ b/src/gallium/auxiliary/rbug/rbug_texture.c @@ -410,9 +410,6 @@ int rbug_send_texture_read_reply(struct rbug_connection *__con, struct rbug_proto_texture_list * rbug_demarshal_texture_list(struct rbug_proto_header *header) { - uint32_t len = 0; - uint32_t pos = 0; - uint8_t *data = NULL; struct rbug_proto_texture_list *ret; if (!header) @@ -420,9 +417,6 @@ struct rbug_proto_texture_list * rbug_demarshal_texture_list(struct rbug_proto_h if (header->opcode != (int32_t)RBUG_OP_TEXTURE_LIST) return NULL; - pos = 0; - len = header->length * 4; - data = (uint8_t*)&header[1]; ret = MALLOC(sizeof(*ret)); if (!ret) return NULL; @@ -430,7 +424,6 @@ struct rbug_proto_texture_list * rbug_demarshal_texture_list(struct rbug_proto_h ret->header.__message = header; ret->header.opcode = header->opcode; - return ret; } diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.c b/src/gallium/auxiliary/tgsi/tgsi_build.c index d2cb98e84af..269940ec840 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_build.c +++ b/src/gallium/auxiliary/tgsi/tgsi_build.c @@ -917,7 +917,6 @@ tgsi_build_full_instruction( for( i = 0; i < full_inst->Instruction.NumDstRegs; i++ ) { const struct tgsi_full_dst_register *reg = &full_inst->Dst[i]; struct tgsi_dst_register *dst_register; - struct tgsi_token *prev_token; if( maxsize <= size ) return 0; @@ -932,7 +931,6 @@ tgsi_build_full_instruction( reg->Register.Index, instruction, header ); - prev_token = (struct tgsi_token *) dst_register; if( reg->Register.Indirect ) { struct tgsi_src_register *ind; @@ -1001,7 +999,6 @@ tgsi_build_full_instruction( for( i = 0; i < full_inst->Instruction.NumSrcRegs; i++ ) { const struct tgsi_full_src_register *reg = &full_inst->Src[i]; struct tgsi_src_register *src_register; - struct tgsi_token *prev_token; if( maxsize <= size ) return 0; @@ -1021,7 +1018,6 @@ tgsi_build_full_instruction( reg->Register.Index, instruction, header ); - prev_token = (struct tgsi_token *) src_register; if( reg->Register.Indirect ) { struct tgsi_src_register *ind; diff --git a/src/gallium/auxiliary/util/u_format.csv b/src/gallium/auxiliary/util/u_format.csv index e4b3f5df6ee..347e2beb8dd 100644 --- a/src/gallium/auxiliary/util/u_format.csv +++ b/src/gallium/auxiliary/util/u_format.csv @@ -147,7 +147,7 @@ PIPE_FORMAT_G8R8_G8B8_UNORM , subsampled, 2, 1, x32 , , , , xyz # some special formats not fitting anywhere else PIPE_FORMAT_R10G10B10A2_USCALED , plain, 1, 1, u10 , u10 , u10 , u2 , xyzw, rgb -PIPE_FORMAT_R11G11B10_FLOAT , plain, 1, 1, f11 , f11 , f10 , , xyz1, rgb +PIPE_FORMAT_R11G11B10_FLOAT , other, 1, 1, x32 , , , , xyz1, rgb PIPE_FORMAT_R9G9B9E5_FLOAT , other, 1, 1, x32 , , , , xyz1, rgb PIPE_FORMAT_R1_UNORM , other, 8, 1, x8 , , , , x001, rgb # A.k.a. D3DFMT_CxV8U8 diff --git a/src/gallium/auxiliary/util/u_format_other.c b/src/gallium/auxiliary/util/u_format_other.c index fa42ec37138..c23f4ee4ac5 100644 --- a/src/gallium/auxiliary/util/u_format_other.c +++ b/src/gallium/auxiliary/util/u_format_other.c @@ -28,6 +28,8 @@ #include "u_math.h" #include "u_format_other.h" +#include "u_format_rgb9e5.h" +#include "u_format_r11g11b10f.h" void @@ -35,7 +37,23 @@ util_format_r9g9b9e5_float_unpack_rgba_float(float *dst_row, unsigned dst_stride const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) { - + unsigned x, y; + for(y = 0; y < height; y += 1) { + float *dst = dst_row; + const uint8_t *src = src_row; + for(x = 0; x < width; x += 1) { + uint32_t value = *(const uint32_t *)src; +#ifdef PIPE_ARCH_BIG_ENDIAN + value = util_bswap32(value); +#endif + rgb9e5_to_float3(value, dst); + dst[3] = 1; /* a */ + src += 4; + dst += 4; + } + src_row += src_stride; + dst_row += dst_stride/sizeof(*dst_row); + } } void @@ -43,14 +61,34 @@ util_format_r9g9b9e5_float_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride const float *src_row, unsigned src_stride, unsigned width, unsigned height) { - + unsigned x, y; + for(y = 0; y < height; y += 1) { + const float *src = src_row; + uint8_t *dst = dst_row; + for(x = 0; x < width; x += 1) { + uint32_t value = float3_to_rgb9e5(src); +#ifdef PIPE_ARCH_BIG_ENDIAN + value = util_bswap32(value); +#endif + *(uint32_t *)dst = value; + src += 4; + dst += 4; + } + dst_row += dst_stride; + src_row += src_stride/sizeof(*src_row); + } } void util_format_r9g9b9e5_float_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) { - + uint32_t value = *(const uint32_t *)src; +#ifdef PIPE_ARCH_BIG_ENDIAN + value = util_bswap32(value); +#endif + rgb9e5_to_float3(value, dst); + dst[3] = 1; /* a */ } @@ -59,7 +97,27 @@ util_format_r9g9b9e5_float_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_str const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) { - + unsigned x, y; + float p[3]; + for(y = 0; y < height; y += 1) { + uint8_t *dst = dst_row; + const uint8_t *src = src_row; + for(x = 0; x < width; x += 1) { + uint32_t value = *(const uint32_t *)src; +#ifdef PIPE_ARCH_BIG_ENDIAN + value = util_bswap32(value); +#endif + rgb9e5_to_float3(value, p); + dst[0] = float_to_ubyte(p[0]); /* r */ + dst[1] = float_to_ubyte(p[1]); /* g */ + dst[2] = float_to_ubyte(p[2]); /* b */ + dst[3] = 255; /* a */ + src += 4; + dst += 4; + } + src_row += src_stride; + dst_row += dst_stride/sizeof(*dst_row); + } } @@ -68,7 +126,145 @@ util_format_r9g9b9e5_float_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_strid const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) { + unsigned x, y; + float p[3]; + for(y = 0; y < height; y += 1) { + const uint8_t *src = src_row; + uint8_t *dst = dst_row; + for(x = 0; x < width; x += 1) { + uint32_t value; + p[0] = ubyte_to_float(src[0]); + p[1] = ubyte_to_float(src[1]); + p[2] = ubyte_to_float(src[2]); + value = float3_to_rgb9e5(p); +#ifdef PIPE_ARCH_BIG_ENDIAN + value = util_bswap32(value); +#endif + *(uint32_t *)dst = value; + src += 4; + dst += 4; + } + dst_row += dst_stride; + src_row += src_stride/sizeof(*src_row); + } +} + +void +util_format_r11g11b10_float_unpack_rgba_float(float *dst_row, unsigned dst_stride, + const uint8_t *src_row, unsigned src_stride, + unsigned width, unsigned height) +{ + unsigned x, y; + for(y = 0; y < height; y += 1) { + float *dst = dst_row; + const uint8_t *src = src_row; + for(x = 0; x < width; x += 1) { + uint32_t value = *(const uint32_t *)src; +#ifdef PIPE_ARCH_BIG_ENDIAN + value = util_bswap32(value); +#endif + r11g11b10f_to_float3(value, dst); + dst[3] = 1; /* a */ + src += 4; + dst += 4; + } + src_row += src_stride; + dst_row += dst_stride/sizeof(*dst_row); + } +} + +void +util_format_r11g11b10_float_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, + const float *src_row, unsigned src_stride, + unsigned width, unsigned height) +{ + unsigned x, y; + for(y = 0; y < height; y += 1) { + const float *src = src_row; + uint8_t *dst = dst_row; + for(x = 0; x < width; x += 1) { + uint32_t value = float3_to_r11g11b10f(src); +#ifdef PIPE_ARCH_BIG_ENDIAN + value = util_bswap32(value); +#endif + *(uint32_t *)dst = value; + src += 4; + dst += 4; + } + dst_row += dst_stride; + src_row += src_stride/sizeof(*src_row); + } +} + +void +util_format_r11g11b10_float_fetch_rgba_float(float *dst, const uint8_t *src, + unsigned i, unsigned j) +{ + uint32_t value = *(const uint32_t *)src; +#ifdef PIPE_ARCH_BIG_ENDIAN + value = util_bswap32(value); +#endif + r11g11b10f_to_float3(value, dst); + dst[3] = 1; /* a */ +} + + +void +util_format_r11g11b10_float_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, + const uint8_t *src_row, unsigned src_stride, + unsigned width, unsigned height) +{ + unsigned x, y; + float p[3]; + for(y = 0; y < height; y += 1) { + uint8_t *dst = dst_row; + const uint8_t *src = src_row; + for(x = 0; x < width; x += 1) { + uint32_t value = *(const uint32_t *)src; +#ifdef PIPE_ARCH_BIG_ENDIAN + value = util_bswap32(value); +#endif + r11g11b10f_to_float3(value, p); + dst[0] = float_to_ubyte(p[0]); /* r */ + dst[1] = float_to_ubyte(p[1]); /* g */ + dst[2] = float_to_ubyte(p[2]); /* b */ + dst[3] = 255; /* a */ + src += 4; + dst += 4; + } + src_row += src_stride; + dst_row += dst_stride/sizeof(*dst_row); + } +} + + +void +util_format_r11g11b10_float_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, + const uint8_t *src_row, unsigned src_stride, + unsigned width, unsigned height) +{ + unsigned x, y; + float p[3]; + for(y = 0; y < height; y += 1) { + const uint8_t *src = src_row; + uint8_t *dst = dst_row; + for(x = 0; x < width; x += 1) { + uint32_t value; + p[0] = ubyte_to_float(src[0]); + p[1] = ubyte_to_float(src[1]); + p[2] = ubyte_to_float(src[2]); + value = float3_to_r11g11b10f(p); +#ifdef PIPE_ARCH_BIG_ENDIAN + value = util_bswap32(value); +#endif + *(uint32_t *)dst = value; + src += 4; + dst += 4; + } + dst_row += dst_stride; + src_row += src_stride/sizeof(*src_row); + } } diff --git a/src/gallium/auxiliary/util/u_format_other.h b/src/gallium/auxiliary/util/u_format_other.h index 98c97be33fa..2f6a908bbe8 100644 --- a/src/gallium/auxiliary/util/u_format_other.h +++ b/src/gallium/auxiliary/util/u_format_other.h @@ -57,6 +57,32 @@ util_format_r9g9b9e5_float_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_strid const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); + +void +util_format_r11g11b10_float_unpack_rgba_float(float *dst_row, unsigned dst_stride, + const uint8_t *src_row, unsigned src_stride, + unsigned width, unsigned height); + +void +util_format_r11g11b10_float_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, + const float *src_row, unsigned src_stride, + unsigned width, unsigned height); + +void +util_format_r11g11b10_float_fetch_rgba_float(float *dst, const uint8_t *src, + unsigned i, unsigned j); + +void +util_format_r11g11b10_float_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, + const uint8_t *src_row, unsigned src_stride, + unsigned width, unsigned height); + +void +util_format_r11g11b10_float_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, + const uint8_t *src_row, unsigned src_stride, + unsigned width, unsigned height); + + void util_format_r1_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, diff --git a/src/gallium/auxiliary/util/u_format_r11g11b10f.h b/src/gallium/auxiliary/util/u_format_r11g11b10f.h new file mode 100644 index 00000000000..c4181d0e34e --- /dev/null +++ b/src/gallium/auxiliary/util/u_format_r11g11b10f.h @@ -0,0 +1,190 @@ +/* + * Copyright (C) 2011 Marek Olšák <[email protected]> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/* Based on code from The OpenGL Programming Guide / 7th Edition, Appendix J. + * Available here: http://www.opengl-redbook.com/appendices/ + * The algorithm in the book contains a bug though, which is fixed in the code + * below. + */ + +#define UF11_EXPONENT_BIAS 15 +#define UF11_EXPONENT_BITS 0x1F +#define UF11_EXPONENT_SHIFT 6 +#define UF11_MANTISSA_BITS 0x3F +#define UF11_MANTISSA_SHIFT (23 - UF11_EXPONENT_SHIFT) +#define UF11_MAX_EXPONENT (UF11_EXPONENT_BITS << UF11_EXPONENT_SHIFT) + +#define UF10_EXPONENT_BIAS 15 +#define UF10_EXPONENT_BITS 0x1F +#define UF10_EXPONENT_SHIFT 5 +#define UF10_MANTISSA_BITS 0x3F +#define UF10_MANTISSA_SHIFT (23 - UF10_EXPONENT_SHIFT) +#define UF10_MAX_EXPONENT (UF10_EXPONENT_BITS << UF10_EXPONENT_SHIFT) + +#define F32_INFINITY 0x7f800000 + +static INLINE unsigned f32_to_uf11(float val) +{ + uint32_t f32 = (*(uint32_t *) &val); + uint16_t uf11 = 0; + + /* Decode little-endian 32-bit floating-point value */ + int sign = (f32 >> 16) & 0x8000; + /* Map exponent to the range [-127,128] */ + int exponent = ((f32 >> 23) & 0xff) - 127; + int mantissa = f32 & 0x007fffff; + + if (sign) return 0; + + if (exponent == 128) { /* Infinity or NaN */ + uf11 = UF11_MAX_EXPONENT; + if (mantissa) uf11 |= (mantissa & UF11_MANTISSA_BITS); + } + else if (exponent > 15) { /* Overflow - flush to Infinity */ + uf11 = UF11_MAX_EXPONENT; + } + else if (exponent > -15) { /* Representable value */ + exponent += UF11_EXPONENT_BIAS; + mantissa >>= UF11_MANTISSA_SHIFT; + uf11 = exponent << UF11_EXPONENT_SHIFT | mantissa; + } + + return uf11; +} + +static INLINE float uf11_to_f32(uint16_t val) +{ + union { + float f; + uint32_t ui; + } f32; + + int exponent = (val & 0x07c0) >> UF11_EXPONENT_SHIFT; + int mantissa = (val & 0x003f); + + f32.f = 0.0; + + if (exponent == 0) { + if (mantissa != 0) { + const float scale = 1.0 / (1 << 20); + f32.f = scale * mantissa; + } + } + else if (exponent == 31) { + f32.ui = F32_INFINITY | mantissa; + } + else { + float scale, decimal; + exponent -= 15; + if (exponent < 0) { + scale = 1.0 / (1 << -exponent); + } + else { + scale = 1 << exponent; + } + decimal = 1.0 + (float) mantissa / 64; + f32.f = scale * decimal; + } + + return f32.f; +} + +static INLINE unsigned f32_to_uf10(float val) +{ + uint32_t f32 = (*(uint32_t *) &val); + uint16_t uf10 = 0; + + /* Decode little-endian 32-bit floating-point value */ + int sign = (f32 >> 16) & 0x8000; + /* Map exponent to the range [-127,128] */ + int exponent = ((f32 >> 23) & 0xff) - 127; + int mantissa = f32 & 0x007fffff; + + if (sign) return 0; + + if (exponent == 128) { /* Infinity or NaN */ + uf10 = UF10_MAX_EXPONENT; + if (mantissa) uf10 |= (mantissa & UF10_MANTISSA_BITS); + } + else if (exponent > 15) { /* Overflow - flush to Infinity */ + uf10 = UF10_MAX_EXPONENT; + } + else if (exponent > -15) { /* Representable value */ + exponent += UF10_EXPONENT_BIAS; + mantissa >>= UF10_MANTISSA_SHIFT; + uf10 = exponent << UF10_EXPONENT_SHIFT | mantissa; + } + + return uf10; +} + +static INLINE float uf10_to_f32(uint16_t val) +{ + union { + float f; + uint32_t ui; + } f32; + + int exponent = (val & 0x07c0) >> UF10_EXPONENT_SHIFT; + int mantissa = (val & 0x003f); + + f32.f = 0.0; + + if (exponent == 0) { + if (mantissa != 0) { + const float scale = 1.0 / (1 << 20); + f32.f = scale * mantissa; + } + } + else if (exponent == 31) { + f32.ui = F32_INFINITY | mantissa; + } + else { + float scale, decimal; + exponent -= 15; + if (exponent < 0) { + scale = 1.0 / (1 << -exponent); + } + else { + scale = 1 << exponent; + } + decimal = 1.0 + (float) mantissa / 32; + f32.f = scale * decimal; + } + + return f32.f; +} + +static INLINE unsigned float3_to_r11g11b10f(const float rgb[3]) +{ + return ( f32_to_uf11(rgb[0]) & 0x7ff) | + ((f32_to_uf11(rgb[1]) & 0x7ff) << 11) | + ((f32_to_uf10(rgb[2]) & 0x3ff) << 22); +} + +static INLINE void r11g11b10f_to_float3(unsigned rgb, float retval[3]) +{ + retval[0] = uf11_to_f32( rgb & 0x7ff); + retval[1] = uf11_to_f32((rgb >> 11) & 0x7ff); + retval[2] = uf10_to_f32((rgb >> 22) & 0x3ff); +} diff --git a/src/gallium/auxiliary/util/u_format_rgb9e5.h b/src/gallium/auxiliary/util/u_format_rgb9e5.h new file mode 100644 index 00000000000..c2a3f6f3e9d --- /dev/null +++ b/src/gallium/auxiliary/util/u_format_rgb9e5.h @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2011 Marek Olšák <[email protected]> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/* Copied from EXT_texture_shared_exponent and edited. */ + +#ifndef RGB9E5_H +#define RGB9E5_H + +#include <math.h> +#include <assert.h> + +#define RGB9E5_EXPONENT_BITS 5 +#define RGB9E5_MANTISSA_BITS 9 +#define RGB9E5_EXP_BIAS 15 +#define RGB9E5_MAX_VALID_BIASED_EXP 31 + +#define MAX_RGB9E5_EXP (RGB9E5_MAX_VALID_BIASED_EXP - RGB9E5_EXP_BIAS) +#define RGB9E5_MANTISSA_VALUES (1<<RGB9E5_MANTISSA_BITS) +#define MAX_RGB9E5_MANTISSA (RGB9E5_MANTISSA_VALUES-1) +#define MAX_RGB9E5 (((float)MAX_RGB9E5_MANTISSA)/RGB9E5_MANTISSA_VALUES * (1<<MAX_RGB9E5_EXP)) +#define EPSILON_RGB9E5 ((1.0/RGB9E5_MANTISSA_VALUES) / (1<<RGB9E5_EXP_BIAS)) + +typedef union { + unsigned int raw; + float value; + struct { +#if defined(MESA_BIG_ENDIAN) || defined(PIPE_ARCH_BIG_ENDIAN) + unsigned int negative:1; + unsigned int biasedexponent:8; + unsigned int mantissa:23; +#else + unsigned int mantissa:23; + unsigned int biasedexponent:8; + unsigned int negative:1; +#endif + } field; +} float754; + +typedef union { + unsigned int raw; + struct { +#if defined(MESA_BIG_ENDIAN) || defined(PIPE_ARCH_BIG_ENDIAN) + unsigned int biasedexponent:RGB9E5_EXPONENT_BITS; + unsigned int b:RGB9E5_MANTISSA_BITS; + unsigned int g:RGB9E5_MANTISSA_BITS; + unsigned int r:RGB9E5_MANTISSA_BITS; +#else + unsigned int r:RGB9E5_MANTISSA_BITS; + unsigned int g:RGB9E5_MANTISSA_BITS; + unsigned int b:RGB9E5_MANTISSA_BITS; + unsigned int biasedexponent:RGB9E5_EXPONENT_BITS; +#endif + } field; +} rgb9e5; + +static INLINE float rgb9e5_ClampRange(float x) +{ + if (x > 0.0) { + if (x >= MAX_RGB9E5) { + return MAX_RGB9E5; + } else { + return x; + } + } else { + /* NaN gets here too since comparisons with NaN always fail! */ + return 0.0; + } +} + +/* Ok, FloorLog2 is not correct for the denorm and zero values, but we + are going to do a max of this value with the minimum rgb9e5 exponent + that will hide these problem cases. */ +static INLINE int rgb9e5_FloorLog2(float x) +{ + float754 f; + + f.value = x; + return (f.field.biasedexponent - 127); +} + +static INLINE unsigned float3_to_rgb9e5(const float rgb[3]) +{ + rgb9e5 retval; + float maxrgb; + int rm, gm, bm; + float rc, gc, bc; + int exp_shared, maxm; + double denom; + + rc = rgb9e5_ClampRange(rgb[0]); + gc = rgb9e5_ClampRange(rgb[1]); + bc = rgb9e5_ClampRange(rgb[2]); + + maxrgb = MAX3(rc, gc, bc); + exp_shared = MAX2(-RGB9E5_EXP_BIAS-1, rgb9e5_FloorLog2(maxrgb)) + 1 + RGB9E5_EXP_BIAS; + assert(exp_shared <= RGB9E5_MAX_VALID_BIASED_EXP); + assert(exp_shared >= 0); + /* This pow function could be replaced by a table. */ + denom = pow(2, exp_shared - RGB9E5_EXP_BIAS - RGB9E5_MANTISSA_BITS); + + maxm = (int) floor(maxrgb / denom + 0.5); + if (maxm == MAX_RGB9E5_MANTISSA+1) { + denom *= 2; + exp_shared += 1; + assert(exp_shared <= RGB9E5_MAX_VALID_BIASED_EXP); + } else { + assert(maxm <= MAX_RGB9E5_MANTISSA); + } + + rm = (int) floor(rc / denom + 0.5); + gm = (int) floor(gc / denom + 0.5); + bm = (int) floor(bc / denom + 0.5); + + assert(rm <= MAX_RGB9E5_MANTISSA); + assert(gm <= MAX_RGB9E5_MANTISSA); + assert(bm <= MAX_RGB9E5_MANTISSA); + assert(rm >= 0); + assert(gm >= 0); + assert(bm >= 0); + + retval.field.r = rm; + retval.field.g = gm; + retval.field.b = bm; + retval.field.biasedexponent = exp_shared; + + return retval.raw; +} + +static INLINE void rgb9e5_to_float3(unsigned rgb, float retval[3]) +{ + rgb9e5 v; + int exponent; + float scale; + + v.raw = rgb; + exponent = v.field.biasedexponent - RGB9E5_EXP_BIAS - RGB9E5_MANTISSA_BITS; + scale = (float) pow(2, exponent); + + retval[0] = v.field.r * scale; + retval[1] = v.field.g * scale; + retval[2] = v.field.b * scale; +} + +#endif diff --git a/src/gallium/auxiliary/util/u_math.h b/src/gallium/auxiliary/util/u_math.h index e3d4c06b6f9..dad6a101fd7 100644 --- a/src/gallium/auxiliary/util/u_math.h +++ b/src/gallium/auxiliary/util/u_math.h @@ -581,11 +581,11 @@ util_bswap16(uint16_t n) #define MIN2( A, B ) ( (A)<(B) ? (A) : (B) ) #define MAX2( A, B ) ( (A)>(B) ? (A) : (B) ) -#define MIN3( A, B, C ) MIN2( MIN2( A, B ), C ) -#define MAX3( A, B, C ) MAX2( MAX2( A, B ), C ) +#define MIN3( A, B, C ) ((A) < (B) ? MIN2(A, C) : MIN2(B, C)) +#define MAX3( A, B, C ) ((A) > (B) ? MAX2(A, C) : MAX2(B, C)) -#define MIN4( A, B, C, D ) MIN2( MIN2( A, B ), MIN2(C, D) ) -#define MAX4( A, B, C, D ) MAX2( MAX2( A, B ), MAX2(C, D) ) +#define MIN4( A, B, C, D ) ((A) < (B) ? MIN3(A, C, D) : MIN3(B, C, D)) +#define MAX4( A, B, C, D ) ((A) > (B) ? MAX3(A, C, D) : MAX3(B, C, D)) /** diff --git a/src/gallium/docs/source/cso/sampler.rst b/src/gallium/docs/source/cso/sampler.rst index 9bbb784de8e..648b5cc60ea 100644 --- a/src/gallium/docs/source/cso/sampler.rst +++ b/src/gallium/docs/source/cso/sampler.rst @@ -107,3 +107,7 @@ max_anisotropy Set to zero to disable anisotropic filtering. Any other setting enables anisotropic filtering, however it's not unexpected some drivers only will change their filtering with a setting of 2 and higher. +seamless_cube_map + If set, the bilinear filter of a cube map may take samples from adjacent + cube map faces when sampled near a texture border to produce a seamless + look.
\ No newline at end of file diff --git a/src/gallium/drivers/i915/i915_resource_texture.c b/src/gallium/drivers/i915/i915_resource_texture.c index 7816925d230..e05b059706d 100644 --- a/src/gallium/drivers/i915/i915_resource_texture.c +++ b/src/gallium/drivers/i915/i915_resource_texture.c @@ -181,8 +181,7 @@ i915_texture_tiling(struct i915_screen *is, struct i915_texture *tex) return I915_TILE_NONE; if (util_format_is_s3tc(tex->b.b.format)) - /* XXX X-tiling might make sense */ - return I915_TILE_NONE; + return I915_TILE_X; if (is->debug.use_blitter) return I915_TILE_X; diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c index 0f4327fdc81..0e427749636 100644 --- a/src/gallium/drivers/i915/i915_screen.c +++ b/src/gallium/drivers/i915/i915_screen.c @@ -28,6 +28,7 @@ #include "draw/draw_context.h" #include "util/u_format.h" +#include "util/u_format_s3tc.h" #include "util/u_inlines.h" #include "util/u_memory.h" #include "util/u_string.h" @@ -267,6 +268,10 @@ i915_is_format_supported(struct pipe_screen *screen, PIPE_FORMAT_YUYV, /* XXX why not? PIPE_FORMAT_Z16_UNORM, */ + PIPE_FORMAT_DXT1_RGB, + PIPE_FORMAT_DXT1_RGBA, + PIPE_FORMAT_DXT3_RGBA, + PIPE_FORMAT_DXT5_RGBA, PIPE_FORMAT_Z24X8_UNORM, PIPE_FORMAT_Z24_UNORM_S8_USCALED, PIPE_FORMAT_NONE /* list terminator */ @@ -432,5 +437,7 @@ i915_screen_create(struct i915_winsys *iws) i915_debug_init(is); + util_format_s3tc_init(); + return &is->base; } diff --git a/src/gallium/drivers/i915/i915_state_sampler.c b/src/gallium/drivers/i915/i915_state_sampler.c index 916cb767536..be70e7a92c9 100644 --- a/src/gallium/drivers/i915/i915_state_sampler.c +++ b/src/gallium/drivers/i915/i915_state_sampler.c @@ -223,15 +223,13 @@ static uint translate_texture_format(enum pipe_format pipeFormat) #endif case PIPE_FORMAT_Z16_UNORM: return (MAPSURF_16BIT | MT_16BIT_L16); -#if 0 - case PIPE_FORMAT_RGBA_DXT1: - case PIPE_FORMAT_RGB_DXT1: + case PIPE_FORMAT_DXT1_RGBA: + case PIPE_FORMAT_DXT1_RGB: return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT1); - case PIPE_FORMAT_RGBA_DXT3: + case PIPE_FORMAT_DXT3_RGBA: return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT2_3); - case PIPE_FORMAT_RGBA_DXT5: + case PIPE_FORMAT_DXT5_RGBA: return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT4_5); -#endif case PIPE_FORMAT_Z24_UNORM_S8_USCALED: case PIPE_FORMAT_Z24X8_UNORM: return (MAPSURF_32BIT | MT_32BIT_xI824); diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index c82ab821c7e..cbe06e58a78 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -1065,6 +1065,8 @@ lp_setup_begin_query(struct lp_setup_context *setup, set_scene_state(setup, SETUP_ACTIVE, "begin_query"); + setup->active_query = pq; + if (setup->scene) { if (!lp_scene_bin_everywhere(setup->scene, LP_RAST_OP_BEGIN_QUERY, @@ -1080,8 +1082,6 @@ lp_setup_begin_query(struct lp_setup_context *setup, } } } - - setup->active_query = pq; } diff --git a/src/gallium/drivers/nouveau/nouveau_mm.c b/src/gallium/drivers/nouveau/nouveau_mm.c index 7edeb4d21d6..6c6d28c17f6 100644 --- a/src/gallium/drivers/nouveau/nouveau_mm.c +++ b/src/gallium/drivers/nouveau/nouveau_mm.c @@ -143,7 +143,7 @@ mm_slab_new(struct nouveau_mman *cache, int chunk_order) cache->allocated += size; - debug_printf("MM: new slab, total memory = %lu KiB\n", + debug_printf("MM: new slab, total memory = %llu KiB\n", cache->allocated / 1024); return PIPE_OK; diff --git a/src/gallium/drivers/nv50/nv50_formats.c b/src/gallium/drivers/nv50/nv50_formats.c index c65189d0671..96ed9a7d6d4 100644 --- a/src/gallium/drivers/nv50/nv50_formats.c +++ b/src/gallium/drivers/nv50/nv50_formats.c @@ -571,4 +571,22 @@ const struct nv50_format nv50_format_table[PIPE_FORMAT_COUNT] = [PIPE_FORMAT_A8B8G8R8_UNORM] = { 0, B_(C3, C2, C1, C0, UNORM, UNORM, UNORM, UNORM, 8_8_8_8, 0), SAMPLER_VIEW }, + + /* FIXED FORMATS - hw doesn't support these, convert on vbo push for now */ + + [PIPE_FORMAT_R32G32B32A32_FIXED] = { 0, + B_(C0, C1, C2, C3, FLOAT, FLOAT, FLOAT, FLOAT, 32_32_32_32, 0), + VERTEX_BUFFER }, + + [PIPE_FORMAT_R32G32B32_FIXED] = { 0, + B_(C0, C1, C2, ONE_FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, 32_32_32, 0), + VERTEX_BUFFER }, + + [PIPE_FORMAT_R32G32_FIXED] = { 0, + B_(C0, C1, ZERO, ONE_FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, 32_32, 0), + VERTEX_BUFFER }, + + [PIPE_FORMAT_R32_FIXED] = { 0, + B_(C0, ZERO, ZERO, ONE_FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, 32, 0), + VERTEX_BUFFER }, }; diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c index 9eeca05ada3..486b368ae98 100644 --- a/src/gallium/drivers/nv50/nv50_miptree.c +++ b/src/gallium/drivers/nv50/nv50_miptree.c @@ -158,6 +158,9 @@ nv50_miptree_create(struct pipe_screen *pscreen, tile_flags = 0x6000; break; default: + if (pt->bind & PIPE_BIND_CURSOR) + tile_flags = 0; + else if ((pt->bind & PIPE_BIND_SCANOUT) && util_format_get_blocksizebits(pt->format) == 32) tile_flags = 0x7a00; @@ -165,6 +168,8 @@ nv50_miptree_create(struct pipe_screen *pscreen, tile_flags = 0x7000; break; } + if (pt->bind & (PIPE_BIND_SCANOUT | PIPE_BIND_CURSOR)) + tile_flags |= NOUVEAU_BO_TILE_SCANOUT; /* For 3D textures, a mipmap is spanned by all the layers, for array * textures and cube maps, each layer contains its own mipmaps. @@ -176,7 +181,10 @@ nv50_miptree_create(struct pipe_screen *pscreen, unsigned blocksize = util_format_get_blocksize(pt->format); lvl->offset = mt->total_size; - lvl->tile_mode = get_tile_dims(nbx, nby, d); + + if (tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK) + lvl->tile_mode = get_tile_dims(nbx, nby, d); + lvl->pitch = align(nbx * blocksize, NV50_TILE_PITCH(lvl->tile_mode)); mt->total_size += lvl->pitch * diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 641ad7e2780..4dad8599870 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -89,7 +89,10 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_TEXTURE_SHADOW_MAP: case PIPE_CAP_NPOT_TEXTURES: case PIPE_CAP_ANISOTROPIC_FILTER: - return 1; + case PIPE_CAP_SEAMLESS_CUBE_MAP: + return nv50_screen(pscreen)->tesla->grclass >= NVA0_3D; + case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE: + return 0; case PIPE_CAP_TWO_SIDED_STENCIL: case PIPE_CAP_DEPTH_CLAMP: case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE: @@ -417,6 +420,11 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) BEGIN_RING(chan, RING_3D(BLEND_SEPARATE_ALPHA), 1); OUT_RING (chan, 1); + if (tesla_class >= NVA0_3D) { + BEGIN_RING(chan, RING_3D_(NVA0_3D_TEX_MISC), 1); + OUT_RING (chan, NVA0_3D_TEX_MISC_SEAMLESS_CUBE_MAP); + } + BEGIN_RING(chan, RING_3D(SCREEN_Y_CONTROL), 1); OUT_RING (chan, 0); BEGIN_RING(chan, RING_3D(WINDOW_OFFSET_X), 2); @@ -469,7 +477,7 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) screen->tls_size = tls_space * max_warps * 32; - debug_printf("max_warps = %i, tls_size = %lu KiB\n", + debug_printf("max_warps = %i, tls_size = %llu KiB\n", max_warps, screen->tls_size >> 10); ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, screen->tls_size, diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index 799f49619d2..8d75dd07c4d 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -34,6 +34,36 @@ #include "nouveau/nouveau_gldefs.h" +/* Caveats: + * ! pipe_sampler_state.normalized_coords is ignored - rectangle textures will + * use non-normalized coordinates, everything else won't + * (The relevant bit is in the TIC entry and not the TSC entry.) + * + * ! pipe_sampler_state.seamless_cube_map is ignored - seamless filtering is + * always activated on NVA0 + + * (Give me the global bit, otherwise it's not worth the CPU work.) + * + * ! pipe_sampler_state.border_color is not swizzled according to the texture + * swizzle in pipe_sampler_view + * (This will be ugly with indirect independent texture/sampler access, + * we'd have to emulate the logic in the shader. GL doesn't have that, + * D3D doesn't have swizzle, if we knew what we were implementing we'd be + * good.) + * + * ! pipe_rasterizer_state.line_last_pixel is ignored - it is never drawn + * + * ! pipe_rasterizer_state.flatshade_first also applies to QUADS + * (There's a GL query for that, forcing an exception is just ridiculous.) + * + * ! pipe_rasterizer_state.gl_rasterization_rules is ignored - pixel centers + * are always at half integer coordinates and the top-left rule applies + * (There does not seem to be a hardware switch for this.) + * + * ! pipe_rasterizer_state.sprite_coord_enable is masked with 0xff on NVC0 + * (The hardware only has 8 slots meant for TexCoord and we have to assign + * in advance to maintain elegant separate shader objects.) + */ + static INLINE uint32_t nv50_colormask(unsigned mask) { diff --git a/src/gallium/drivers/nvc0/nvc0_formats.c b/src/gallium/drivers/nvc0/nvc0_formats.c index 678e9b563ee..81077a7fa80 100644 --- a/src/gallium/drivers/nvc0/nvc0_formats.c +++ b/src/gallium/drivers/nvc0/nvc0_formats.c @@ -576,4 +576,22 @@ const struct nvc0_format nvc0_format_table[PIPE_FORMAT_COUNT] = [PIPE_FORMAT_A8B8G8R8_UNORM] = { 0, B_(C3, C2, C1, C0, UNORM, UNORM, UNORM, UNORM, 8_8_8_8, 0), SAMPLER_VIEW }, + + /* FIXED FORMATS - hw doesn't support these, convert on vbo push for now */ + + [PIPE_FORMAT_R32G32B32A32_FIXED] = { 0, + B_(C0, C1, C2, C3, FLOAT, FLOAT, FLOAT, FLOAT, 32_32_32_32, 0), + VERTEX_BUFFER }, + + [PIPE_FORMAT_R32G32B32_FIXED] = { 0, + B_(C0, C1, C2, ONE_FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, 32_32_32, 0), + VERTEX_BUFFER }, + + [PIPE_FORMAT_R32G32_FIXED] = { 0, + B_(C0, C1, ZERO, ONE_FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, 32_32, 0), + VERTEX_BUFFER }, + + [PIPE_FORMAT_R32_FIXED] = { 0, + B_(C0, ZERO, ZERO, ONE_FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, 32, 0), + VERTEX_BUFFER }, }; diff --git a/src/gallium/drivers/nvc0/nvc0_screen.c b/src/gallium/drivers/nvc0/nvc0_screen.c index ca0691d2aee..34bf0f0a2ad 100644 --- a/src/gallium/drivers/nvc0/nvc0_screen.c +++ b/src/gallium/drivers/nvc0/nvc0_screen.c @@ -74,7 +74,10 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_TEXTURE_SHADOW_MAP: case PIPE_CAP_NPOT_TEXTURES: case PIPE_CAP_ANISOTROPIC_FILTER: + case PIPE_CAP_SEAMLESS_CUBE_MAP: return 1; + case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE: + return 0; case PIPE_CAP_TWO_SIDED_STENCIL: case PIPE_CAP_DEPTH_CLAMP: case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE: @@ -441,6 +444,8 @@ nvc0_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) OUT_RING (chan, 1); BEGIN_RING(chan, RING_3D(BLEND_ENABLE_COMMON), 1); OUT_RING (chan, 0); + BEGIN_RING(chan, RING_3D(TEX_MISC), 1); + OUT_RING (chan, NVC0_3D_TEX_MISC_SEAMLESS_CUBE_MAP); nvc0_magic_3d_init(chan); diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index 9ec16c6562f..7a1366a4f8f 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -113,14 +113,21 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_TEXTURE_MIRROR_REPEAT: case PIPE_CAP_BLEND_EQUATION_SEPARATE: case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: - case PIPE_CAP_FRAGMENT_COLOR_CLAMP_CONTROL: - return is_r500 ? 1 : 0; + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: + return 1; + + /* r300 cannot do swizzling of compressed textures. Supported otherwise. */ case PIPE_CAP_TEXTURE_SWIZZLE: return util_format_s3tc_enabled ? r300screen->caps.dxtc_swizzle : 1; + + /* Supported on r500 only. */ + case PIPE_CAP_FRAGMENT_COLOR_CLAMP_CONTROL: case PIPE_CAP_MIXED_COLORBUFFER_FORMATS: + case PIPE_CAP_SM3: return is_r500 ? 1 : 0; - /* Unsupported features (boolean caps). */ + /* Unsupported features. */ case PIPE_CAP_TIMER_QUERY: case PIPE_CAP_DUAL_SOURCE_BLEND: case PIPE_CAP_INDEP_BLEND_ENABLE: @@ -130,6 +137,11 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_SHADER_STENCIL_EXPORT: case PIPE_CAP_ARRAY_TEXTURES: case PIPE_CAP_TGSI_INSTANCEID: + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: + case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS: + case PIPE_CAP_SEAMLESS_CUBE_MAP: + case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE: return 0; /* SWTCL-only features. */ @@ -141,8 +153,6 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: case PIPE_CAP_MAX_COMBINED_SAMPLERS: return r300screen->caps.num_tex_units; - case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS: - return 0; case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: @@ -153,16 +163,6 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_MAX_RENDER_TARGETS: return 4; - /* General shader limits and features. */ - case PIPE_CAP_SM3: - return is_r500 ? 1 : 0; - /* Fragment coordinate conventions. */ - case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: - case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: - return 1; - case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: - case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: - return 0; default: debug_printf("r300: Warning: Unknown CAP %d in get_param.\n", param); diff --git a/src/gallium/drivers/r300/r300_tgsi_to_rc.c b/src/gallium/drivers/r300/r300_tgsi_to_rc.c index 6a000cfe2c6..0561ab9bfa4 100644 --- a/src/gallium/drivers/r300/r300_tgsi_to_rc.c +++ b/src/gallium/drivers/r300/r300_tgsi_to_rc.c @@ -266,6 +266,7 @@ static void transform_texture(struct rc_instruction * dst, struct tgsi_instructi *shadowSamplers |= 1 << dst->U.I.TexSrcUnit; break; } + dst->U.I.TexSwizzle = RC_SWIZZLE_XYZW; } static void transform_instruction(struct tgsi_to_rc * ttr, struct tgsi_full_instruction * src) diff --git a/src/gallium/drivers/r600/Makefile b/src/gallium/drivers/r600/Makefile index 436de9c4dbd..3dda3a6339f 100644 --- a/src/gallium/drivers/r600/Makefile +++ b/src/gallium/drivers/r600/Makefile @@ -10,7 +10,6 @@ C_SOURCES = \ r600_asm.c \ r600_blit.c \ r600_buffer.c \ - r600_helper.c \ r600_pipe.c \ r600_query.c \ r600_resource.c \ diff --git a/src/gallium/drivers/r600/SConscript b/src/gallium/drivers/r600/SConscript index 5a5fa6d65fd..0135808f10a 100644 --- a/src/gallium/drivers/r600/SConscript +++ b/src/gallium/drivers/r600/SConscript @@ -19,7 +19,6 @@ r600 = env.ConvenienceLibrary( 'r600_asm.c', 'r600_buffer.c', 'r600_blit.c', - 'r600_helper.c', 'r600_pipe.c', 'r600_query.c', 'r600_resource.c', diff --git a/src/gallium/drivers/r600/eg_state_inlines.h b/src/gallium/drivers/r600/eg_state_inlines.h index f20d45f48de..a2ba73febdd 100644 --- a/src/gallium/drivers/r600/eg_state_inlines.h +++ b/src/gallium/drivers/r600/eg_state_inlines.h @@ -348,7 +348,7 @@ static inline uint32_t r600_translate_colorswap(enum pipe_format format) case PIPE_FORMAT_A8B8G8R8_UNORM: case PIPE_FORMAT_X8B8G8R8_UNORM: - // case PIPE_FORMAT_R8SG8SB8UX8U_NORM: + /* case PIPE_FORMAT_R8SG8SB8UX8U_NORM: */ return V_028C70_SWAP_STD_REV; case PIPE_FORMAT_Z24X8_UNORM: @@ -367,6 +367,7 @@ static inline uint32_t r600_translate_colorswap(enum pipe_format format) 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: @@ -469,6 +470,9 @@ static INLINE uint32_t r600_translate_colorformat(enum pipe_format format) 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: @@ -502,60 +506,60 @@ static INLINE uint32_t r600_translate_colorformat(enum pipe_format format) case PIPE_FORMAT_UYVY: case PIPE_FORMAT_YUYV: default: - //R600_ERR("unsupported color format %d\n", format); + /* R600_ERR("unsupported color format %d\n", format); */ return ~0; /* Unsupported. */ } } static INLINE uint32_t r600_colorformat_endian_swap(uint32_t colorformat) { -#ifdef PIPE_ARCH_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. */ + 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); + + /* 128-bit buffers. */ + case V_028C70_COLOR_32_32_32_FLOAT: + 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; } -#else - return ENDIAN_NONE; -#endif } static INLINE boolean r600_is_sampler_format_supported(struct pipe_screen *screen, enum pipe_format format) diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index a972f82fb1d..502f2663e8b 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -143,14 +143,17 @@ static void *evergreen_create_blend_state(struct pipe_context *ctx, static void *evergreen_create_dsa_state(struct pipe_context *ctx, const struct pipe_depth_stencil_alpha_state *state) { - struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state); + struct r600_pipe_dsa *dsa = CALLOC_STRUCT(r600_pipe_dsa); unsigned db_depth_control, alpha_test_control, alpha_ref, db_shader_control; unsigned stencil_ref_mask, stencil_ref_mask_bf, db_render_override, db_render_control; + struct r600_pipe_state *rstate; - if (rstate == NULL) { + if (dsa == NULL) { return NULL; } + rstate = &dsa->rstate; + rstate->id = R600_PIPE_STATE_DSA; /* depth TODO some of those db_shader_control field depend on shader adjust mask & add it to shader */ db_shader_control = S_02880C_Z_ORDER(V_02880C_EARLY_Z_THEN_LATE_Z); @@ -190,6 +193,7 @@ static void *evergreen_create_dsa_state(struct pipe_context *ctx, alpha_test_control |= S_028410_ALPHA_TEST_ENABLE(1); alpha_ref = fui(state->alpha.ref_value); } + dsa->alpha_ref = alpha_ref; /* misc */ db_render_control = 0; @@ -206,7 +210,6 @@ static void *evergreen_create_dsa_state(struct pipe_context *ctx, r600_pipe_state_add_reg(rstate, R_028434_DB_STENCILREFMASK_BF, stencil_ref_mask_bf, 0xFFFFFFFF & C_028434_STENCILREF_BF, NULL); - r600_pipe_state_add_reg(rstate, R_028438_SX_ALPHA_REF, alpha_ref, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_0286DC_SPI_FOG_CNTL, 0x00000000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028800_DB_DEPTH_CONTROL, db_depth_control, 0xFFFFFFFF, NULL); /* The DB_SHADER_CONTROL mask is 0xFFFFFFBC since Z_EXPORT_ENABLE, @@ -307,16 +310,11 @@ static void *evergreen_create_sampler_state(struct pipe_context *ctx, { struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state); union util_color uc; - uint32_t coord_trunc = 0; if (rstate == NULL) { return NULL; } - if ((state->mag_img_filter == PIPE_TEX_FILTER_NEAREST) || - (state->min_img_filter == PIPE_TEX_FILTER_NEAREST)) - coord_trunc = 1; - rstate->id = R600_PIPE_STATE_SAMPLER; util_pack_color(state->border_color, PIPE_FORMAT_B8G8R8A8_UNORM, &uc); r600_pipe_state_add_reg(rstate, R_03C000_SQ_TEX_SAMPLER_WORD0_0, @@ -328,14 +326,13 @@ static void *evergreen_create_sampler_state(struct pipe_context *ctx, S_03C000_MIP_FILTER(r600_tex_mipfilter(state->min_mip_filter)) | S_03C000_DEPTH_COMPARE_FUNCTION(r600_tex_compare(state->compare_func)) | S_03C000_BORDER_COLOR_TYPE(uc.ui ? V_03C000_SQ_TEX_BORDER_COLOR_REGISTER : 0), 0xFFFFFFFF, NULL); - /* FIXME LOD it depends on texture base level ... */ r600_pipe_state_add_reg(rstate, R_03C004_SQ_TEX_SAMPLER_WORD1_0, S_03C004_MIN_LOD(S_FIXED(CLAMP(state->min_lod, 0, 15), 8)) | S_03C004_MAX_LOD(S_FIXED(CLAMP(state->max_lod, 0, 15), 8)), 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_03C008_SQ_TEX_SAMPLER_WORD2_0, S_03C008_LOD_BIAS(S_FIXED(CLAMP(state->lod_bias, -16, 16), 8)) | - S_03C008_MC_COORD_TRUNCATE(coord_trunc) | + (state->seamless_cube_map ? 0 : S_03C008_DISABLE_CUBE_WRAP(1)) | S_03C008_TYPE(1), 0xFFFFFFFF, NULL); @@ -409,7 +406,6 @@ static struct pipe_sampler_view *evergreen_create_sampler_view(struct pipe_conte array_mode = tmp->array_mode[0]; tile_type = tmp->tile_type; - /* FIXME properly handle first level != 0 */ r600_pipe_state_add_reg(rstate, R_030000_RESOURCE0_WORD0, S_030000_DIM(r600_tex_dim(texture->target)) | S_030000_PITCH((pitch / 8) - 1) | @@ -715,12 +711,26 @@ static void evergreen_cb(struct r600_pipe_context *rctx, struct r600_pipe_state S_028C70_ENDIAN(endian); - /* we can only set the export size if any thing is snorm/unorm component is > 11 bits, - if we aren't a float, sint or uint */ + /* EXPORT_NORM is an optimzation that can be enabled for better + * performance in certain cases. + * EXPORT_NORM can be enabled if: + * - 11-bit or smaller UNORM/SNORM/SRGB + * - 16-bit or smaller FLOAT + */ + /* FIXME: This should probably be the same for all CBs if we want + * useful alpha tests. */ if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS && - desc->channel[i].size < 12 && desc->channel[i].type != UTIL_FORMAT_TYPE_FLOAT && - ntype != V_028C70_NUMBER_UINT && ntype != V_028C70_NUMBER_SINT) + ((desc->channel[i].size < 12 && + desc->channel[i].type != UTIL_FORMAT_TYPE_FLOAT && + ntype != V_028C70_NUMBER_UINT && ntype != V_028C70_NUMBER_SINT) || + (desc->channel[i].size < 17 && + desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT))) { color_info |= S_028C70_SOURCE_FORMAT(V_028C70_EXPORT_4C_16BPC); + rctx->export_16bpc = true; + } else { + rctx->export_16bpc = false; + } + rctx->alpha_ref_dirty = true; if (rtex->array_mode[level] > V_028C70_ARRAY_LINEAR_ALIGNED) { tile_type = rtex->tile_type; @@ -922,7 +932,7 @@ void evergreen_init_state_functions(struct r600_pipe_context *rctx) rctx->context.create_vertex_elements_state = r600_create_vertex_elements; rctx->context.create_vs_state = r600_create_shader_state; rctx->context.bind_blend_state = r600_bind_blend_state; - rctx->context.bind_depth_stencil_alpha_state = r600_bind_state; + rctx->context.bind_depth_stencil_alpha_state = r600_bind_dsa_state; rctx->context.bind_fragment_sampler_states = evergreen_bind_ps_sampler; rctx->context.bind_fs_state = r600_bind_ps_shader; rctx->context.bind_rasterizer_state = r600_bind_rs_state; @@ -1232,9 +1242,11 @@ void evergreen_init_config(struct r600_pipe_context *rctx) r600_pipe_state_add_reg(rstate, R_009100_SPI_CONFIG_CNTL, 0x0, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_00913C_SPI_CONFIG_CNTL_1, S_00913C_VTX_DONE_DELAY(4), 0xFFFFFFFF, NULL); -// r600_pipe_state_add_reg(rstate, R_028350_SX_MISC, 0x0, 0xFFFFFFFF, NULL); +#if 0 + r600_pipe_state_add_reg(rstate, R_028350_SX_MISC, 0x0, 0xFFFFFFFF, NULL); -// r600_pipe_state_add_reg(rstate, R_008D8C_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, 0x0, 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(rstate, R_008D8C_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, 0x0, 0xFFFFFFFF, NULL); +#endif r600_pipe_state_add_reg(rstate, R_028A48_PA_SC_MODE_CNTL_0, 0x0, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028A4C_PA_SC_MODE_CNTL_1, 0x0, 0xFFFFFFFF, NULL); @@ -1574,9 +1586,7 @@ void evergreen_pipe_set_buffer_resource(struct r600_pipe_context *rctx, r600_pipe_state_add_reg(rstate, R_030004_RESOURCE0_WORD1, rbuffer->bo_size - offset - 1, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_030008_RESOURCE0_WORD2, -#ifdef PIPE_ARCH_BIG_ENDIAN - S_030008_ENDIAN_SWAP(ENDIAN_8IN32) | -#endif + S_030008_ENDIAN_SWAP(r600_endian_swap(32)) | S_030008_STRIDE(stride), 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_03000C_RESOURCE0_WORD3, S_03000C_DST_SEL_X(V_03000C_SQ_SEL_X) | diff --git a/src/gallium/drivers/r600/evergreend.h b/src/gallium/drivers/r600/evergreend.h index de445b879a1..670606d9b07 100644 --- a/src/gallium/drivers/r600/evergreend.h +++ b/src/gallium/drivers/r600/evergreend.h @@ -1194,6 +1194,15 @@ #define S_03C008_FORCE_DEGAMMA(x) (((x) & 0x1) << 21) #define G_03C008_FORCE_DEGAMMA(x) (((x) >> 21) & 0x1) #define C_03C008_FORCE_DEGAMMA 0xFFDFFFFF +#define S_03C008_ANISO_BIAS(x) (((x) & 0x3f) << 22) +#define G_03C008_ANISO_BIAS(x) (((x) >> 22) & 0x3f) +#define C_03C008_ANISO_BIAS (~(0x3f << 22)) +#define S_03C008_TRUNCATE_COORD(x) (((x) & 0x1) << 28) +#define G_03C008_TRUNCATE_COORD(x) (((x) >> 28) & 0x1) +#define C_03C008_TRUNCATE_COORD (~(1 << 28)) +#define S_03C008_DISABLE_CUBE_WRAP(x) (((x) & 0x1) << 29) +#define G_03C008_DISABLE_CUBE_WRAP(x) (((x) >> 29) & 0x1) +#define C_03C008_DISABLE_CUBE_WRAP (~(1 << 29)) #define S_03C008_TYPE(x) (((x) & 0x1) << 31) #define G_03C008_TYPE(x) (((x) >> 31) & 0x1) #define C_03C008_TYPE 0x7FFFFFFF diff --git a/src/gallium/drivers/r600/r600.h b/src/gallium/drivers/r600/r600.h index 0b0df9d019b..33aa45088a8 100644 --- a/src/gallium/drivers/r600/r600.h +++ b/src/gallium/drivers/r600/r600.h @@ -235,6 +235,7 @@ struct r600_query { #define R600_CONTEXT_DRAW_PENDING (1 << 0) #define R600_CONTEXT_DST_CACHES_DIRTY (1 << 1) +#define R600_CONTEXT_CHECK_EVENT_FLUSH (1 << 2) struct r600_context { struct radeon *radeon; diff --git a/src/gallium/drivers/r600/r600_asm.c b/src/gallium/drivers/r600/r600_asm.c index 7e854b1b81d..033e84665f5 100644 --- a/src/gallium/drivers/r600/r600_asm.c +++ b/src/gallium/drivers/r600/r600_asm.c @@ -33,12 +33,6 @@ #include "r600_formats.h" #include "r600d.h" -#ifdef PIPE_ARCH_BIG_ENDIAN -#define CPU_TO_LE32(x) bswap_32(x) -#else -#define CPU_TO_LE32(x) (x) -#endif - #define NUM_OF_CYCLES 3 #define NUM_OF_COMPONENTS 4 @@ -531,19 +525,19 @@ static int assign_alu_units(struct r600_bc *bc, struct r600_bc_alu *alu_first, else if (is_alu_vec_unit_inst(bc, alu)) trans = 0; else if (assignment[chan]) - trans = 1; // assume ALU_INST_PREFER_VECTOR + trans = 1; /* Assume ALU_INST_PREFER_VECTOR. */ else trans = 0; if (trans) { if (assignment[4]) { - assert(0); //ALU.Trans has already been allocated + assert(0); /* ALU.Trans has already been allocated. */ return -1; } assignment[4] = alu; } else { if (assignment[chan]) { - assert(0); //ALU.chan has already been allocated + assert(0); /* ALU.chan has already been allocated. */ return -1; } assignment[chan] = alu; @@ -595,7 +589,7 @@ static int reserve_gpr(struct alu_bank_swizzle *bs, unsigned sel, unsigned chan, if (bs->hw_gpr[cycle][chan] == -1) bs->hw_gpr[cycle][chan] = sel; else if (bs->hw_gpr[cycle][chan] != (int)sel) { - // Another scalar operation has already used GPR read port for channel + /* Another scalar operation has already used the GPR read port for the channel. */ return -1; } return 0; @@ -615,9 +609,9 @@ static int reserve_cfile(struct r600_bc *bc, struct alu_bank_swizzle *bs, unsign return 0; } else if (bs->hw_cfile_addr[res] == sel && bs->hw_cfile_elem[res] == chan) - return 0; // Read for this scalar element already reserved, nothing to do here. + return 0; /* Read for this scalar element already reserved, nothing to do here. */ } - // All cfile read ports are used, cannot reference vector element + /* All cfile read ports are used, cannot reference vector element. */ return -1; } @@ -632,8 +626,8 @@ static int is_gpr(unsigned sel) static int is_cfile(unsigned sel) { return (sel > 255 && sel < 512) || - (sel > 511 && sel < 4607) || // Kcache before translate - (sel > 127 && sel < 192); // Kcache after translate + (sel > 511 && sel < 4607) || /* Kcache before translation. */ + (sel > 127 && sel < 192); /* Kcache after translation. */ } static int is_const(int sel) @@ -655,8 +649,8 @@ static int check_vector(struct r600_bc *bc, struct r600_bc_alu *alu, if (is_gpr(sel)) { cycle = cycle_for_bank_swizzle_vec[bank_swizzle][src]; if (src == 1 && sel == alu->src[0].sel && elem == alu->src[0].chan) - // Nothing to do; special-case optimization, - // second source uses first source’s reservation + /* Nothing to do; special-case optimization, + * second source uses first source’s reservation. */ continue; else { r = reserve_gpr(bs, sel, elem, cycle); @@ -668,7 +662,7 @@ static int check_vector(struct r600_bc *bc, struct r600_bc_alu *alu, if (r) return r; } - // No restrictions on PV, PS, literal or special constants + /* No restrictions on PV, PS, literal or special constants. */ } return 0; } @@ -682,10 +676,10 @@ static int check_scalar(struct r600_bc *bc, struct r600_bc_alu *alu, for (const_count = 0, src = 0; src < num_src; ++src) { sel = alu->src[src].sel; elem = alu->src[src].chan; - if (is_const(sel)) { // Any constant, including literal and inline constants + if (is_const(sel)) { /* Any constant, including literal and inline constants. */ if (const_count >= 2) - // More than two references to a constant in - // transcendental operation. + /* More than two references to a constant in + * transcendental operation. */ return -1; else const_count++; @@ -702,15 +696,19 @@ static int check_scalar(struct r600_bc *bc, struct r600_bc_alu *alu, if (is_gpr(sel)) { cycle = cycle_for_bank_swizzle_scl[bank_swizzle][src]; if (cycle < const_count) - // Cycle for GPR load conflicts with - // constant load in transcendental operation. + /* Cycle for GPR load conflicts with + * constant load in transcendental operation. */ return -1; r = reserve_gpr(bs, sel, elem, cycle); if (r) return r; } - // Constants already processed - // No restrictions on PV, PS + /* PV PS restrictions */ + if (const_count && (sel == 254 || sel == 255)) { + cycle = cycle_for_bank_swizzle_scl[bank_swizzle][src]; + if (cycle < const_count) + return -1; + } } return 0; } @@ -721,30 +719,36 @@ 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; - - for (i = 0; i < 5; i++) + boolean scalar_only = true; + for (i = 0; i < 5; i++) { if (slots[i] && slots[i]->bank_swizzle_force) { slots[i]->bank_swizzle = slots[i]->bank_swizzle_force; forced = 1; } - + if (i < 4 && slots[i]) + scalar_only = false; + } if (forced) return 0; - // just check every possible combination of bank swizzle - // not very efficent, but works on the first try in most of the cases + /* Just check every possible combination of bank swizzle. + * Not very efficent, but works on the first try in most of the cases. */ for (i = 0; i < 4; i++) bank_swizzle[i] = SQ_ALU_VEC_012; bank_swizzle[4] = SQ_ALU_SCL_210; while(bank_swizzle[4] <= SQ_ALU_SCL_221) { init_bank_swizzle(&bs); - for (i = 0; i < 4; i++) { - if (slots[i]) { - r = check_vector(bc, slots[i], &bs, bank_swizzle[i]); - if (r) - break; + if (scalar_only == false) { + for (i = 0; i < 4; i++) { + if (slots[i]) { + r = check_vector(bc, slots[i], &bs, bank_swizzle[i]); + if (r) + break; + } } - } + } else + r = 0; + if (!r && slots[4]) { r = check_scalar(bc, slots[4], &bs, bank_swizzle[4]); } @@ -756,16 +760,20 @@ static int check_and_set_bank_swizzle(struct r600_bc *bc, return 0; } - for (i = 0; i < 5; i++) { - bank_swizzle[i]++; - if (bank_swizzle[i] <= SQ_ALU_VEC_210) - break; - else - bank_swizzle[i] = SQ_ALU_VEC_012; + if (scalar_only) { + bank_swizzle[4]++; + } else { + for (i = 0; i < 5; i++) { + bank_swizzle[i]++; + if (bank_swizzle[i] <= SQ_ALU_VEC_210) + break; + else + bank_swizzle[i] = SQ_ALU_VEC_012; + } } } - // couldn't find a working swizzle + /* Couldn't find a working swizzle. */ return -1; } @@ -835,17 +843,17 @@ void r600_bc_special_constants(u32 value, unsigned *sel, unsigned *neg) case -1: *sel = V_SQ_ALU_SRC_M_1_INT; break; - case 0x3F800000: // 1.0f + case 0x3F800000: /* 1.0f */ *sel = V_SQ_ALU_SRC_1; break; - case 0x3F000000: // 0.5f + case 0x3F000000: /* 0.5f */ *sel = V_SQ_ALU_SRC_0_5; break; - case 0xBF800000: // -1.0f + case 0xBF800000: /* -1.0f */ *sel = V_SQ_ALU_SRC_1; *neg ^= 1; break; - case 0xBF000000: // -0.5f + case 0xBF000000: /* -0.5f */ *sel = V_SQ_ALU_SRC_0_5; *neg ^= 1; break; @@ -938,13 +946,13 @@ static int merge_inst_groups(struct r600_bc *bc, struct r600_bc_alu *slots[5], if (slots[i] && r600_bc_alu_nliterals(bc, slots[i], literal, &nliteral)) return 0; - // let's check used slots + /* Let's check used slots. */ if (prev[i] && !slots[i]) { result[i] = prev[i]; continue; } else if (prev[i] && slots[i]) { if (result[4] == NULL && prev[4] == NULL && slots[4] == NULL) { - // trans unit is still free try to use it + /* Trans unit is still free try to use it. */ if (is_alu_any_unit_inst(bc, slots[i])) { result[i] = prev[i]; result[4] = slots[i]; @@ -963,14 +971,14 @@ static int merge_inst_groups(struct r600_bc *bc, struct r600_bc_alu *slots[5], alu = slots[i]; num_once_inst += is_alu_once_inst(bc, alu); - // let's check dst gpr + /* Let's check dst gpr. */ if (alu->dst.rel) { if (have_mova) return 0; have_rel = 1; } - // let's check source gprs + /* Let's check source gprs */ num_src = r600_bc_get_num_operands(bc, alu); for (src = 0; src < num_src; ++src) { if (alu->src[src].rel) { @@ -979,7 +987,7 @@ static int merge_inst_groups(struct r600_bc *bc, struct r600_bc_alu *slots[5], have_rel = 1; } - // constants doesn't matter + /* Constants don't matter. */ if (!is_gpr(alu->src[src].sel)) continue; @@ -987,7 +995,7 @@ static int merge_inst_groups(struct r600_bc *bc, struct r600_bc_alu *slots[5], if (!prev[j] || !prev[j]->dst.write) continue; - // if it's relative then we can't determin which gpr is really used + /* If it's relative then we can't determin which gpr is really used. */ if (prev[j]->dst.chan == alu->src[src].chan && (prev[j]->dst.sel == alu->src[src].sel || prev[j]->dst.rel || alu->src[src].rel)) @@ -1390,7 +1398,7 @@ static int r600_bc_vtx_build(struct r600_bc *bc, struct r600_bc_vtx *vtx, unsign S_SQ_VTX_WORD1_SRF_MODE_ALL(vtx->srf_mode_all) | 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) | + S_SQ_VTX_WORD2_ENDIAN_SWAP(vtx->endian) | S_SQ_VTX_WORD2_MEGA_FETCH(1); bc->bytecode[id++] = 0; return 0; @@ -1927,7 +1935,7 @@ void r600_bc_dump(struct r600_bc *bc) fprintf(stderr, "%04d %08X ", id, bc->bytecode[id]); fprintf(stderr, "ENDIAN:%d ", vtx->endian); fprintf(stderr, "OFFSET:%d\n", vtx->offset); - //TODO + /* TODO */ id++; fprintf(stderr, "%04d %08X \n", id, bc->bytecode[id]); id++; @@ -1960,6 +1968,8 @@ static void r600_vertex_data_type(enum pipe_format pformat, unsigned *format, } } + *endian = r600_endian_swap(desc->channel[i].size); + switch (desc->channel[i].type) { /* Half-floats, floats, ints */ case UTIL_FORMAT_TYPE_FLOAT: @@ -1977,9 +1987,6 @@ static void r600_vertex_data_type(enum pipe_format pformat, unsigned *format, *format = FMT_16_16_16_16_FLOAT; break; } -#ifdef PIPE_ARCH_BIG_ENDIAN - *endian = ENDIAN_8IN16; -#endif break; case 32: switch (desc->nr_channels) { @@ -1996,9 +2003,6 @@ static void r600_vertex_data_type(enum pipe_format pformat, unsigned *format, *format = FMT_32_32_32_32_FLOAT; break; } -#ifdef PIPE_ARCH_BIG_ENDIAN - *endian = ENDIAN_8IN32; -#endif break; default: goto out_unknown; @@ -2036,9 +2040,6 @@ static void r600_vertex_data_type(enum pipe_format pformat, unsigned *format, *format = FMT_16_16_16_16; break; } -#ifdef PIPE_ARCH_BIG_ENDIAN - *endian = ENDIAN_8IN16; -#endif break; case 32: switch (desc->nr_channels) { @@ -2055,9 +2056,6 @@ static void r600_vertex_data_type(enum pipe_format pformat, unsigned *format, *format = FMT_32_32_32_32; break; } -#ifdef PIPE_ARCH_BIG_ENDIAN - *endian = ENDIAN_8IN32; -#endif break; default: goto out_unknown; @@ -2093,11 +2091,11 @@ int r600_vertex_elements_build_fetch_shader(struct r600_pipe_context *rctx, stru u32 *bytecode; int i, r; - /* vertex elements offset need special handling, if offset is bigger - + * than what we can put in fetch instruction then we need to alterate - * the vertex resource offset. In such case in order to simplify code - * we will bound one resource per elements. It's a worst case scenario. - */ + /* Vertex element offsets need special handling. If the offset is + * bigger than what we can put in the fetch instruction we need to + * alter the vertex resource offset. In order to simplify code we + * will bind one resource per element in such cases. It's a worst + * case scenario. */ for (i = 0; i < ve->count; i++) { ve->vbuffer_offset[i] = C_SQ_VTX_WORD2_OFFSET & elements[i].src_offset; if (ve->vbuffer_offset[i]) { @@ -2202,8 +2200,12 @@ int r600_vertex_elements_build_fetch_shader(struct r600_pipe_context *rctx, stru return -ENOMEM; } - for(i = 0; i < ve->fs_size / 4; i++) { - *(bytecode + i) = CPU_TO_LE32(*(bc.bytecode + i)); + if (R600_BIG_ENDIAN) { + for (i = 0; i < ve->fs_size / 4; ++i) { + bytecode[i] = bswap_32(bc.bytecode[i]); + } + } else { + memcpy(bytecode, bc.bytecode, ve->fs_size); } r600_bo_unmap(rctx->radeon, ve->fetch_shader); diff --git a/src/gallium/drivers/r600/r600_buffer.c b/src/gallium/drivers/r600/r600_buffer.c index 71b47e1b056..72f352df3c3 100644 --- a/src/gallium/drivers/r600/r600_buffer.c +++ b/src/gallium/drivers/r600/r600_buffer.c @@ -81,18 +81,11 @@ static void *r600_buffer_transfer_map(struct pipe_context *pipe, struct pipe_transfer *transfer) { struct r600_resource_buffer *rbuffer = r600_buffer(transfer->resource); - int write = 0; uint8_t *data; if (rbuffer->r.b.user_ptr) return (uint8_t*)rbuffer->r.b.user_ptr + transfer->box.x; - if (transfer->usage & PIPE_TRANSFER_DONTBLOCK) { - /* FIXME */ - } - if (transfer->usage & PIPE_TRANSFER_WRITE) { - write = 1; - } data = r600_bo_map((struct radeon*)pipe->winsys, rbuffer->r.bo, transfer->usage, pipe); if (!data) return NULL; @@ -268,31 +261,30 @@ void r600_upload_const_buffer(struct r600_pipe_context *rctx, struct r600_resour uint8_t *ptr = (*rbuffer)->r.b.user_ptr; unsigned size = (*rbuffer)->r.b.b.b.width0; boolean flushed; -#ifdef PIPE_ARCH_BIG_ENDIAN - int i; - uint32_t *tmpPtr; *rbuffer = NULL; - tmpPtr = (uint32_t *)malloc(size); - /* big endian swap */ - if(tmpPtr == NULL) { - return; - } - for(i = 0; i < size / 4; i++) { - tmpPtr[i] = bswap_32(*((uint32_t *)ptr + i)); - } + if (R600_BIG_ENDIAN) { + uint32_t *tmpPtr; + unsigned i; - u_upload_data(rctx->vbuf_mgr->uploader, 0, size, tmpPtr, const_offset, - (struct pipe_resource**)rbuffer, &flushed); + if (!(tmpPtr = malloc(size))) { + R600_ERR("Failed to allocate BE swap buffer.\n"); + return; + } - free(tmpPtr); -#else - *rbuffer = NULL; + for (i = 0; i < size / 4; ++i) { + tmpPtr[i] = bswap_32(((uint32_t *)ptr)[i]); + } + + u_upload_data(rctx->vbuf_mgr->uploader, 0, size, tmpPtr, const_offset, + (struct pipe_resource**)rbuffer, &flushed); - u_upload_data(rctx->vbuf_mgr->uploader, 0, size, ptr, const_offset, - (struct pipe_resource**)rbuffer, &flushed); -#endif + free(tmpPtr); + } else { + u_upload_data(rctx->vbuf_mgr->uploader, 0, size, ptr, const_offset, + (struct pipe_resource**)rbuffer, &flushed); + } } else { *const_offset = 0; } diff --git a/src/gallium/drivers/r600/r600_formats.h b/src/gallium/drivers/r600/r600_formats.h index 0c91a212384..ae0bc432ad2 100644 --- a/src/gallium/drivers/r600/r600_formats.h +++ b/src/gallium/drivers/r600/r600_formats.h @@ -1,6 +1,8 @@ #ifndef R600_FORMATS_H #define R600_FORMATS_H +#include "r600_pipe.h" + /* list of formats from R700 ISA document - apply across GPUs in different registers */ #define FMT_INVALID 0x00000000 #define FMT_8 0x00000001 @@ -52,5 +54,31 @@ #define FMT_BC3 0x00000033 #define FMT_BC4 0x00000034 #define FMT_BC5 0x00000035 +#define FMT_BC6 0x00000036 +#define FMT_BC7 0x00000037 +#define FMT_32_AS_32_32_32_32 0x00000038 + +#define ENDIAN_NONE 0 +#define ENDIAN_8IN16 1 +#define ENDIAN_8IN32 2 +#define ENDIAN_8IN64 3 + +static INLINE unsigned r600_endian_swap(unsigned size) +{ + if (R600_BIG_ENDIAN) { + switch (size) { + case 64: + return ENDIAN_8IN64; + case 32: + return ENDIAN_8IN32; + case 16: + return ENDIAN_8IN16; + default: + return ENDIAN_NONE; + } + } else { + return ENDIAN_NONE; + } +} #endif diff --git a/src/gallium/drivers/r600/r600_helper.c b/src/gallium/drivers/r600/r600_helper.c deleted file mode 100644 index 7e131093060..00000000000 --- a/src/gallium/drivers/r600/r600_helper.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2010 Jerome Glisse <[email protected]> - * - * 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. - * - * Authors: - * Jerome Glisse - */ -#include <stdio.h> -#include <errno.h> -#include <util/u_inlines.h> -#include "r600_pipe.h" -#include "r600d.h" - -int r600_conv_pipe_prim(unsigned pprim, unsigned *prim) -{ - switch (pprim) { - case PIPE_PRIM_POINTS: - *prim = V_008958_DI_PT_POINTLIST; - return 0; - case PIPE_PRIM_LINES: - *prim = V_008958_DI_PT_LINELIST; - return 0; - case PIPE_PRIM_LINE_STRIP: - *prim = V_008958_DI_PT_LINESTRIP; - return 0; - case PIPE_PRIM_LINE_LOOP: - *prim = V_008958_DI_PT_LINELOOP; - return 0; - case PIPE_PRIM_TRIANGLES: - *prim = V_008958_DI_PT_TRILIST; - return 0; - case PIPE_PRIM_TRIANGLE_STRIP: - *prim = V_008958_DI_PT_TRISTRIP; - return 0; - case PIPE_PRIM_TRIANGLE_FAN: - *prim = V_008958_DI_PT_TRIFAN; - return 0; - case PIPE_PRIM_POLYGON: - *prim = V_008958_DI_PT_POLYGON; - return 0; - case PIPE_PRIM_QUADS: - *prim = V_008958_DI_PT_QUADLIST; - return 0; - case PIPE_PRIM_QUAD_STRIP: - *prim = V_008958_DI_PT_QUADSTRIP; - return 0; - default: - fprintf(stderr, "%s:%d unsupported %d\n", __func__, __LINE__, pprim); - return -EINVAL; - } -} diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c index 89b46f5ad7e..ec13e48e14e 100644 --- a/src/gallium/drivers/r600/r600_pipe.c +++ b/src/gallium/drivers/r600/r600_pipe.c @@ -374,27 +374,29 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_SHADER_STENCIL_EXPORT: case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: case PIPE_CAP_MIXED_COLORBUFFER_FORMATS: + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: return 1; + + /* Supported except the original R600. */ case PIPE_CAP_INDEP_BLEND_ENABLE: + case PIPE_CAP_INDEP_BLEND_FUNC: /* R600 doesn't support per-MRT blends */ - if (family == CHIP_R600) - return 0; - else - return 1; + return family == CHIP_R600 ? 0 : 1; - case PIPE_CAP_TGSI_INSTANCEID: - return 0; + /* Supported on Evergreen. */ + case PIPE_CAP_SEAMLESS_CUBE_MAP: + case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE: + return family >= CHIP_CEDAR ? 1 : 0; - /* Unsupported features (boolean caps). */ + /* Unsupported features. */ case PIPE_CAP_STREAM_OUTPUT: case PIPE_CAP_PRIMITIVE_RESTART: - case PIPE_CAP_INDEP_BLEND_FUNC: /* FIXME allow this */ case PIPE_CAP_FRAGMENT_COLOR_CLAMP_CONTROL: - /* R600 doesn't support per-MRT blends */ - if (family == CHIP_R600) - return 0; - else - return 0; + case PIPE_CAP_TGSI_INSTANCEID: + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: + return 0; case PIPE_CAP_ARRAY_TEXTURES: /* fix once the CS checker upstream is fixed */ @@ -409,25 +411,16 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param) else return 14; case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS: - /* FIXME allow this once infrastructure is there */ - return 16; case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: - case PIPE_CAP_MAX_COMBINED_SAMPLERS: return 16; + case PIPE_CAP_MAX_COMBINED_SAMPLERS: + return 32; /* Render targets. */ case PIPE_CAP_MAX_RENDER_TARGETS: /* FIXME some r6xx are buggy and can only do 4 */ return 8; - /* Fragment coordinate conventions. */ - case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: - case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: - return 1; - case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: - case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: - return 0; - /* Timer queries, present when the clock frequency is non zero. */ case PIPE_CAP_TIMER_QUERY: return r600_get_clock_crystal_freq(rscreen->radeon) != 0; @@ -492,9 +485,10 @@ static int r600_get_shader_param(struct pipe_screen* pscreen, unsigned shader, e else return 16; case PIPE_SHADER_CAP_MAX_TEMPS: - return 256; //max native temporaries + return 256; /* Max native temporaries. */ case PIPE_SHADER_CAP_MAX_ADDRS: - return 1; //max native address registers/* FIXME Isn't this equal to TEMPS? */ + /* FIXME Isn't this equal to TEMPS? */ + return 1; /* Max native address registers */ case PIPE_SHADER_CAP_MAX_CONSTS: return R600_MAX_CONST_BUFFER_SIZE; case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index 88aff0e81bb..aa5ef4efb3b 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -40,6 +40,12 @@ #define R600_MAX_CONST_BUFFERS 1 #define R600_MAX_CONST_BUFFER_SIZE 4096 +#ifdef PIPE_ARCH_BIG_ENDIAN +#define R600_BIG_ENDIAN 1 +#else +#define R600_BIG_ENDIAN 0 +#endif + enum r600_pipe_state_id { R600_PIPE_STATE_BLEND = 0, R600_PIPE_STATE_BLEND_COLOR, @@ -91,6 +97,11 @@ struct r600_pipe_blend { unsigned cb_target_mask; }; +struct r600_pipe_dsa { + struct r600_pipe_state rstate; + unsigned alpha_ref; +}; + struct r600_vertex_element { unsigned count; @@ -180,6 +191,9 @@ struct r600_pipe_context { /* shader information */ unsigned sprite_coord_enable; bool flatshade; + bool export_16bpc; + unsigned alpha_ref; + bool alpha_ref_dirty; struct r600_textures_info ps_samplers; struct r600_pipe_fences fences; @@ -241,7 +255,6 @@ int r600_find_vs_semantic_index(struct r600_shader *vs, /* r600_state.c */ void r600_init_state_functions(struct r600_pipe_context *rctx); -void r600_spi_update(struct r600_pipe_context *rctx); void r600_init_config(struct r600_pipe_context *rctx); void r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader *shader); void r600_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader *shader); @@ -253,9 +266,6 @@ void r600_pipe_set_buffer_resource(struct r600_pipe_context *rctx, struct r600_resource *rbuffer, unsigned offset, unsigned stride); -/* r600_helper.h */ -int r600_conv_pipe_prim(unsigned pprim, unsigned *prim); - /* r600_texture.c */ void r600_init_screen_texture_functions(struct pipe_screen *screen); void r600_init_surface_functions(struct r600_pipe_context *r600); @@ -281,11 +291,11 @@ void *r600_create_vertex_elements(struct pipe_context *ctx, const struct pipe_vertex_element *elements); void r600_delete_vertex_element(struct pipe_context *ctx, void *state); void r600_bind_blend_state(struct pipe_context *ctx, void *state); +void r600_bind_dsa_state(struct pipe_context *ctx, void *state); void r600_bind_rs_state(struct pipe_context *ctx, void *state); void r600_delete_rs_state(struct pipe_context *ctx, void *state); void r600_sampler_view_destroy(struct pipe_context *ctx, struct pipe_sampler_view *state); -void r600_bind_state(struct pipe_context *ctx, void *state); void r600_delete_state(struct pipe_context *ctx, void *state); void r600_bind_vertex_elements(struct pipe_context *ctx, void *state); void *r600_create_shader_state(struct pipe_context *ctx, diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c index 188cea0ff88..845d41ace02 100644 --- a/src/gallium/drivers/r600/r600_shader.c +++ b/src/gallium/drivers/r600/r600_shader.c @@ -21,6 +21,7 @@ * USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "pipe/p_shader_tokens.h" +#include "tgsi/tgsi_info.h" #include "tgsi/tgsi_parse.h" #include "tgsi/tgsi_scan.h" #include "tgsi/tgsi_dump.h" @@ -35,12 +36,6 @@ #include <errno.h> #include <byteswap.h> -#ifdef PIPE_ARCH_BIG_ENDIAN -#define CPU_TO_LE32(x) bswap_32(x) -#else -#define CPU_TO_LE32(x) (x) -#endif - int r600_find_vs_semantic_index(struct r600_shader *vs, struct r600_shader *ps, int id) { @@ -69,8 +64,12 @@ static int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *s return -ENOMEM; } ptr = (uint32_t*)r600_bo_map(rctx->radeon, shader->bo, 0, NULL); - for(i = 0; i < rshader->bc.ndw; i++) { - *(ptr + i) = CPU_TO_LE32(*(rshader->bc.bytecode + i)); + if (R600_BIG_ENDIAN) { + for (i = 0; i < rshader->bc.ndw; ++i) { + ptr[i] = bswap_32(rshader->bc.bytecode[i]); + } + } else { + memcpy(ptr, rshader->bc.bytecode, rshader->bc.ndw * sizeof(*ptr)); } r600_bo_unmap(rctx->radeon, shader->bo); } @@ -477,11 +476,7 @@ static int tgsi_fetch_rel_const(struct r600_shader_ctx *ctx, unsigned int offset vtx.num_format_all = 2; /* NUM_FORMAT_SCALED */ vtx.format_comp_all = 1; /* FORMAT_COMP_SIGNED */ vtx.srf_mode_all = 1; /* SRF_MODE_NO_ZERO */ -#ifdef PIPE_ARCH_BIG_ENDIAN - vtx.endian = ENDIAN_8IN32; -#else - vtx.endian = ENDIAN_NONE; -#endif + vtx.endian = r600_endian_swap(32); if ((r = r600_bc_add_vtx(ctx->bc, &vtx))) return r; @@ -830,7 +825,8 @@ out_err: static int tgsi_unsupported(struct r600_shader_ctx *ctx) { - R600_ERR("%d tgsi opcode unsupported\n", ctx->inst_info->tgsi_opcode); + R600_ERR("%s tgsi opcode unsupported\n", + tgsi_get_opcode_name(ctx->inst_info->tgsi_opcode)); return -EINVAL; } @@ -911,6 +907,8 @@ static int tgsi_op2_s(struct r600_shader_ctx *ctx, int swap) break; case TGSI_OPCODE_ABS: alu.src[0].abs = 1; + if (alu.src[0].neg) + alu.src[0].neg = 0; break; default: break; @@ -1997,9 +1995,11 @@ static int tgsi_exp(struct r600_shader_ctx *ctx) r600_bc_src(&alu.src[0], &ctx->src[0], 0); alu.dst.sel = ctx->temp_reg; -// r = tgsi_dst(ctx, &inst->Dst[0], i, &alu.dst); -// if (r) -// return r; +#if 0 + r = tgsi_dst(ctx, &inst->Dst[0], i, &alu.dst); + if (r) + return r; +#endif alu.dst.write = 1; alu.dst.chan = 1; diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index 8646b9f4905..b9084c953ee 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -199,14 +199,17 @@ static void *r600_create_blend_state(struct pipe_context *ctx, static void *r600_create_dsa_state(struct pipe_context *ctx, const struct pipe_depth_stencil_alpha_state *state) { - struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state); + struct r600_pipe_dsa *dsa = CALLOC_STRUCT(r600_pipe_dsa); unsigned db_depth_control, alpha_test_control, alpha_ref, db_shader_control; unsigned stencil_ref_mask, stencil_ref_mask_bf, db_render_override, db_render_control; + struct r600_pipe_state *rstate; - if (rstate == NULL) { + if (dsa == NULL) { return NULL; } + rstate = &dsa->rstate; + rstate->id = R600_PIPE_STATE_DSA; /* depth TODO some of those db_shader_control field depend on shader adjust mask & add it to shader */ db_shader_control = S_02880C_Z_ORDER(V_02880C_EARLY_Z_THEN_LATE_Z); @@ -246,6 +249,7 @@ static void *r600_create_dsa_state(struct pipe_context *ctx, alpha_test_control |= S_028410_ALPHA_TEST_ENABLE(1); alpha_ref = fui(state->alpha.ref_value); } + dsa->alpha_ref = alpha_ref; /* misc */ db_render_control = 0; @@ -262,7 +266,6 @@ static void *r600_create_dsa_state(struct pipe_context *ctx, r600_pipe_state_add_reg(rstate, R_028434_DB_STENCILREFMASK_BF, stencil_ref_mask_bf, 0xFFFFFFFF & C_028434_STENCILREF_BF, NULL); - r600_pipe_state_add_reg(rstate, R_028438_SX_ALPHA_REF, alpha_ref, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_0286E0_SPI_FOG_FUNC_SCALE, 0x00000000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_0286E4_SPI_FOG_FUNC_BIAS, 0x00000000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_0286DC_SPI_FOG_CNTL, 0x00000000, 0xFFFFFFFF, NULL); @@ -371,16 +374,11 @@ static void *r600_create_sampler_state(struct pipe_context *ctx, { struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state); union util_color uc; - uint32_t coord_trunc = 0; if (rstate == NULL) { return NULL; } - if ((state->mag_img_filter == PIPE_TEX_FILTER_NEAREST) || - (state->min_img_filter == PIPE_TEX_FILTER_NEAREST)) - coord_trunc = 1; - rstate->id = R600_PIPE_STATE_SAMPLER; util_pack_color(state->border_color, PIPE_FORMAT_B8G8R8A8_UNORM, &uc); r600_pipe_state_add_reg(rstate, R_03C000_SQ_TEX_SAMPLER_WORD0_0, @@ -392,14 +390,11 @@ static void *r600_create_sampler_state(struct pipe_context *ctx, S_03C000_MIP_FILTER(r600_tex_mipfilter(state->min_mip_filter)) | S_03C000_DEPTH_COMPARE_FUNCTION(r600_tex_compare(state->compare_func)) | S_03C000_BORDER_COLOR_TYPE(uc.ui ? V_03C000_SQ_TEX_BORDER_COLOR_REGISTER : 0), 0xFFFFFFFF, NULL); - /* FIXME LOD it depends on texture base level ... */ r600_pipe_state_add_reg(rstate, R_03C004_SQ_TEX_SAMPLER_WORD1_0, S_03C004_MIN_LOD(S_FIXED(CLAMP(state->min_lod, 0, 15), 6)) | S_03C004_MAX_LOD(S_FIXED(CLAMP(state->max_lod, 0, 15), 6)) | S_03C004_LOD_BIAS(S_FIXED(CLAMP(state->lod_bias, -16, 16), 6)), 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R_03C008_SQ_TEX_SAMPLER_WORD2_0, - S_03C008_MC_COORD_TRUNCATE(coord_trunc) | - S_03C008_TYPE(1), 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(rstate, R_03C008_SQ_TEX_SAMPLER_WORD2_0, S_03C008_TYPE(1), 0xFFFFFFFF, NULL); if (uc.ui) { r600_pipe_state_add_reg(rstate, R_00A400_TD_PS_SAMPLER0_BORDER_RED, fui(state->border_color[0]), 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_00A404_TD_PS_SAMPLER0_BORDER_GREEN, fui(state->border_color[1]), 0xFFFFFFFF, NULL); @@ -477,7 +472,6 @@ static struct pipe_sampler_view *r600_create_sampler_view(struct pipe_context *c depth = texture->array_size; } - /* FIXME properly handle first level != 0 */ r600_pipe_state_add_reg(rstate, R_038000_RESOURCE0_WORD0, S_038000_DIM(r600_tex_dim(texture->target)) | S_038000_TILE_MODE(array_mode) | @@ -724,7 +718,7 @@ static void r600_cb(struct r600_pipe_context *rctx, struct r600_pipe_state *rsta struct r600_surface *surf; unsigned level = state->cbufs[cb]->u.tex.level; unsigned pitch, slice; - unsigned color_info, color_info_mask; + unsigned color_info; unsigned format, swap, ntype, endian; unsigned offset; const struct util_format_description *desc; @@ -780,17 +774,36 @@ static void r600_cb(struct r600_pipe_context *rctx, struct r600_pipe_state *rsta S_0280A0_NUMBER_TYPE(ntype) | S_0280A0_ENDIAN(endian); - color_info_mask = 0xFFFFFFFF & ~S_0280A0_BLEND_CLAMP(1); - - /* on R600 this can't be set if BLEND_CLAMP isn't set, - if BLEND_FLOAT32 is set of > 11 bits in a UNORM or SNORM */ - if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS && desc->channel[i].size < 12) { - //TODO: Seems to work on RV710, but i have no idea what to do between R600-RV710 - if (rctx->family < CHIP_RV710) { - color_info |= S_0280A0_BLEND_CLAMP(1); - color_info_mask |= S_0280A0_BLEND_CLAMP(1); - } - color_info |= S_0280A0_SOURCE_FORMAT(V_0280A0_EXPORT_NORM); + /* EXPORT_NORM is an optimzation that can be enabled for better + * performance in certain cases + */ + if (rctx->family < CHIP_RV770) { + /* EXPORT_NORM can be enabled if: + * - 11-bit or smaller UNORM/SNORM/SRGB + * - BLEND_CLAMP is enabled + * - BLEND_FLOAT32 is disabled + */ + // TODO get BLEND_CLAMP state from rasterizer state + if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS && + (desc->channel[i].size < 12 && + desc->channel[i].type != UTIL_FORMAT_TYPE_FLOAT && + ntype != V_0280A0_NUMBER_UINT && + ntype != V_0280A0_NUMBER_SINT) && + G_0280A0_BLEND_CLAMP(color_info) && + !G_0280A0_BLEND_FLOAT32(color_info)) + color_info |= S_0280A0_SOURCE_FORMAT(V_0280A0_EXPORT_NORM); + } else { + /* EXPORT_NORM can be enabled if: + * - 11-bit or smaller UNORM/SNORM/SRGB + * - 16-bit or smaller FLOAT + */ + if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS && + ((desc->channel[i].size < 12 && + desc->channel[i].type != UTIL_FORMAT_TYPE_FLOAT && + ntype != V_0280A0_NUMBER_UINT && ntype != V_0280A0_NUMBER_SINT) || + (desc->channel[i].size < 17 && + desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT))) + color_info |= S_0280A0_SOURCE_FORMAT(V_0280A0_EXPORT_NORM); } r600_pipe_state_add_reg(rstate, @@ -798,7 +811,7 @@ static void r600_cb(struct r600_pipe_context *rctx, struct r600_pipe_state *rsta (offset + r600_bo_offset(bo[0])) >> 8, 0xFFFFFFFF, bo[0]); r600_pipe_state_add_reg(rstate, R_0280A0_CB_COLOR0_INFO + cb * 4, - color_info, color_info_mask, NULL); + color_info, ~S_0280A0_BLEND_CLAMP(1), NULL); r600_pipe_state_add_reg(rstate, R_028060_CB_COLOR0_SIZE + cb * 4, S_028060_PITCH_TILE_MAX(pitch) | @@ -984,7 +997,7 @@ void r600_init_state_functions(struct r600_pipe_context *rctx) rctx->context.create_vertex_elements_state = r600_create_vertex_elements; rctx->context.create_vs_state = r600_create_shader_state; rctx->context.bind_blend_state = r600_bind_blend_state; - rctx->context.bind_depth_stencil_alpha_state = r600_bind_state; + rctx->context.bind_depth_stencil_alpha_state = r600_bind_dsa_state; rctx->context.bind_fragment_sampler_states = r600_bind_ps_sampler; rctx->context.bind_fs_state = r600_bind_ps_shader; rctx->context.bind_rasterizer_state = r600_bind_rs_state; @@ -1472,9 +1485,7 @@ void r600_pipe_set_buffer_resource(struct r600_pipe_context *rctx, r600_pipe_state_add_reg(rstate, R_038004_RESOURCE0_WORD1, rbuffer->bo_size - offset - 1, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_038008_RESOURCE0_WORD2, -#ifdef PIPE_ARCH_BIG_ENDIAN - S_038008_ENDIAN_SWAP(ENDIAN_8IN32) | -#endif + S_038008_ENDIAN_SWAP(r600_endian_swap(32)) | S_038008_STRIDE(stride), 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_03800C_RESOURCE0_WORD3, 0x00000000, 0xFFFFFFFF, NULL); diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index 997c9a597ee..de1b811ce89 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -28,9 +28,49 @@ #include <util/u_format.h> #include <pipebuffer/pb_buffer.h> #include "pipe/p_shader_tokens.h" +#include "r600_formats.h" #include "r600_pipe.h" #include "r600d.h" +static int r600_conv_pipe_prim(unsigned pprim, unsigned *prim) +{ + switch (pprim) { + case PIPE_PRIM_POINTS: + *prim = V_008958_DI_PT_POINTLIST; + return 0; + case PIPE_PRIM_LINES: + *prim = V_008958_DI_PT_LINELIST; + return 0; + case PIPE_PRIM_LINE_STRIP: + *prim = V_008958_DI_PT_LINESTRIP; + return 0; + case PIPE_PRIM_LINE_LOOP: + *prim = V_008958_DI_PT_LINELOOP; + return 0; + case PIPE_PRIM_TRIANGLES: + *prim = V_008958_DI_PT_TRILIST; + return 0; + case PIPE_PRIM_TRIANGLE_STRIP: + *prim = V_008958_DI_PT_TRISTRIP; + return 0; + case PIPE_PRIM_TRIANGLE_FAN: + *prim = V_008958_DI_PT_TRIFAN; + return 0; + case PIPE_PRIM_POLYGON: + *prim = V_008958_DI_PT_POLYGON; + return 0; + case PIPE_PRIM_QUADS: + *prim = V_008958_DI_PT_QUADLIST; + return 0; + case PIPE_PRIM_QUAD_STRIP: + *prim = V_008958_DI_PT_QUADSTRIP; + return 0; + default: + fprintf(stderr, "%s:%d unsupported %d\n", __func__, __LINE__, pprim); + return -1; + } +} + /* common state between evergreen and r600 */ void r600_bind_blend_state(struct pipe_context *ctx, void *state) { @@ -46,6 +86,21 @@ void r600_bind_blend_state(struct pipe_context *ctx, void *state) r600_context_pipe_state_set(&rctx->ctx, rstate); } +void r600_bind_dsa_state(struct pipe_context *ctx, void *state) +{ + struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; + struct r600_pipe_dsa *dsa = state; + struct r600_pipe_state *rstate; + + if (state == NULL) + return; + rstate = &dsa->rstate; + rctx->states[rstate->id] = rstate; + rctx->alpha_ref = dsa->alpha_ref; + rctx->alpha_ref_dirty = true; + r600_context_pipe_state_set(&rctx->ctx, rstate); +} + void r600_bind_rs_state(struct pipe_context *ctx, void *state) { struct r600_pipe_rasterizer *rs = (struct r600_pipe_rasterizer *)state; @@ -91,17 +146,6 @@ void r600_sampler_view_destroy(struct pipe_context *ctx, FREE(resource); } -void r600_bind_state(struct pipe_context *ctx, void *state) -{ - struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; - struct r600_pipe_state *rstate = (struct r600_pipe_state *)state; - - if (state == NULL) - return; - rctx->states[rstate->id] = rstate; - r600_context_pipe_state_set(&rctx->ctx, rstate); -} - void r600_delete_state(struct pipe_context *ctx, void *state) { struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; @@ -276,8 +320,25 @@ void r600_delete_vs_shader(struct pipe_context *ctx, void *state) free(shader); } +static void r600_update_alpha_ref(struct r600_pipe_context *rctx) +{ + unsigned alpha_ref = rctx->alpha_ref; + struct r600_pipe_state rstate; + + if (!rctx->alpha_ref_dirty) + return; + + rstate.nregs = 0; + if (rctx->export_16bpc) + alpha_ref &= ~0x1FFF; + r600_pipe_state_add_reg(&rstate, R_028438_SX_ALPHA_REF, alpha_ref, 0xFFFFFFFF, NULL); + + r600_context_pipe_state_set(&rctx->ctx, &rstate); + rctx->alpha_ref_dirty = false; +} + /* FIXME optimize away spi update when it's not needed */ -void r600_spi_update(struct r600_pipe_context *rctx) +static void r600_spi_update(struct r600_pipe_context *rctx, unsigned prim) { struct r600_pipe_shader *shader = rctx->ps_shader; struct r600_pipe_state rstate; @@ -309,6 +370,12 @@ void r600_spi_update(struct r600_pipe_context *rctx) r600_pipe_state_add_reg(&rstate, R_028644_SPI_PS_INPUT_CNTL_0 + i * 4, tmp, 0xFFFFFFFF, NULL); } + + if (prim == PIPE_PRIM_QUADS || prim == PIPE_PRIM_QUAD_STRIP || prim == PIPE_PRIM_POLYGON) { + r600_pipe_state_add_reg(&rstate, R_028814_PA_SU_SC_MODE_CNTL, + S_028814_PROVOKING_VTX_LAST(1), + S_028814_PROVOKING_VTX_LAST(1), NULL); + } r600_context_pipe_state_set(&rctx->ctx, &rstate); } @@ -472,16 +539,16 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) case 2: vgt_draw_initiator = 0; vgt_dma_index_type = 0; -#ifdef PIPE_ARCH_BIG_ENDIAN - vgt_dma_swap_mode = ENDIAN_8IN16; -#endif + if (R600_BIG_ENDIAN) { + vgt_dma_swap_mode = ENDIAN_8IN16; + } break; case 4: vgt_draw_initiator = 0; vgt_dma_index_type = 1; -#ifdef PIPE_ARCH_BIG_ENDIAN - vgt_dma_swap_mode = ENDIAN_8IN32; -#endif + if (R600_BIG_ENDIAN) { + vgt_dma_swap_mode = ENDIAN_8IN32; + } break; case 0: vgt_draw_initiator = 2; @@ -508,7 +575,8 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) return; } - r600_spi_update(rctx); + r600_update_alpha_ref(rctx); + r600_spi_update(rctx, draw.info.mode); mask = 0; for (int i = 0; i < rctx->framebuffer.nr_cbufs; i++) { diff --git a/src/gallium/drivers/r600/r600_state_inlines.h b/src/gallium/drivers/r600/r600_state_inlines.h index 5eabfdc2bc6..39c647835a6 100644 --- a/src/gallium/drivers/r600/r600_state_inlines.h +++ b/src/gallium/drivers/r600/r600_state_inlines.h @@ -343,7 +343,7 @@ static inline uint32_t r600_translate_colorswap(enum pipe_format format) case PIPE_FORMAT_A8B8G8R8_UNORM: case PIPE_FORMAT_X8B8G8R8_UNORM: - // case PIPE_FORMAT_R8SG8SB8UX8U_NORM: + /* case PIPE_FORMAT_R8SG8SB8UX8U_NORM: */ return V_0280A0_SWAP_STD_REV; case PIPE_FORMAT_Z24X8_UNORM: @@ -362,6 +362,7 @@ static inline uint32_t r600_translate_colorswap(enum pipe_format format) 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: @@ -465,6 +466,8 @@ static INLINE uint32_t r600_translate_colorformat(enum pipe_format format) 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: @@ -499,60 +502,60 @@ static INLINE uint32_t r600_translate_colorformat(enum pipe_format format) case PIPE_FORMAT_UYVY: case PIPE_FORMAT_YUYV: default: - //R600_ERR("unsupported color format %d %s\n", format, util_format_name(format)); + /* R600_ERR("unsupported color format %d %s\n", format, util_format_name(format)); */ return ~0; /* Unsupported. */ } } static INLINE uint32_t r600_colorformat_endian_swap(uint32_t colorformat) { -#ifdef PIPE_ARCH_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. */ + 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; } -#else - return ENDIAN_NONE; -#endif } static INLINE boolean r600_is_sampler_format_supported(struct pipe_screen *screen, enum pipe_format format) diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c index 690aeafcc52..77cdd8dc33d 100644 --- a/src/gallium/drivers/r600/r600_texture.c +++ b/src/gallium/drivers/r600/r600_texture.c @@ -892,13 +892,17 @@ uint32_t r600_translate_texformat(struct pipe_screen *screen, switch (format) { case PIPE_FORMAT_RGTC1_SNORM: + case PIPE_FORMAT_LATC1_SNORM: word4 |= sign_bit[0]; case PIPE_FORMAT_RGTC1_UNORM: + case PIPE_FORMAT_LATC1_UNORM: result = FMT_BC4; goto out_word4; case PIPE_FORMAT_RGTC2_SNORM: + case PIPE_FORMAT_LATC2_SNORM: word4 |= sign_bit[0] | sign_bit[1]; case PIPE_FORMAT_RGTC2_UNORM: + case PIPE_FORMAT_LATC2_UNORM: result = FMT_BC5; goto out_word4; default: @@ -935,6 +939,14 @@ uint32_t r600_translate_texformat(struct pipe_screen *screen, } } + if (format == PIPE_FORMAT_R9G9B9E5_FLOAT) { + result = FMT_5_9_9_9_SHAREDEXP; + goto out_word4; + } else if (format == PIPE_FORMAT_R11G11B10_FLOAT) { + result = FMT_10_11_11_FLOAT; + goto out_word4; + } + for (i = 0; i < desc->nr_channels; i++) { if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) { @@ -1088,6 +1100,6 @@ out_word4: *yuv_format_p = yuv_format; return result; out_unknown: -// R600_ERR("Unable to handle texformat %d %s\n", format, util_format_name(format)); + /* R600_ERR("Unable to handle texformat %d %s\n", format, util_format_name(format)); */ return ~0; } diff --git a/src/gallium/drivers/r600/r600d.h b/src/gallium/drivers/r600/r600d.h index 2bff52bec8c..8296b52eb94 100644 --- a/src/gallium/drivers/r600/r600d.h +++ b/src/gallium/drivers/r600/r600d.h @@ -3461,9 +3461,4 @@ #define SQ_TEX_INST_SAMPLE_L 0x11 #define SQ_TEX_INST_SAMPLE_C 0x18 -#define ENDIAN_NONE 0 -#define ENDIAN_8IN16 1 -#define ENDIAN_8IN32 2 -#define ENDIAN_8IN64 3 - #endif diff --git a/src/gallium/drivers/svga/svga_pipe_clear.c b/src/gallium/drivers/svga/svga_pipe_clear.c index b288c3eb2a6..2bba77769ad 100644 --- a/src/gallium/drivers/svga/svga_pipe_clear.c +++ b/src/gallium/drivers/svga/svga_pipe_clear.c @@ -46,7 +46,7 @@ try_clear(struct svga_context *svga, boolean restore_viewport = FALSE; SVGA3dClearFlag flags = 0; struct pipe_framebuffer_state *fb = &svga->curr.framebuffer; - union util_color uc; + union util_color uc = {0}; ret = svga_update_state(svga, SVGA_STATE_HW_CLEAR); if (ret) diff --git a/src/gallium/drivers/svga/svga_state_framebuffer.c b/src/gallium/drivers/svga/svga_state_framebuffer.c index cc4819431ad..502f21fc42c 100644 --- a/src/gallium/drivers/svga/svga_state_framebuffer.c +++ b/src/gallium/drivers/svga/svga_state_framebuffer.c @@ -474,9 +474,26 @@ static int emit_clip_planes( struct svga_context *svga, /* TODO: just emit directly from svga_set_clip_state()? */ for (i = 0; i < svga->curr.clip.nr; i++) { - ret = SVGA3D_SetClipPlane( svga->swc, - i, - svga->curr.clip.ucp[i] ); + /* need to express the plane in D3D-style coordinate space. + * GL coords get converted to D3D coords with the matrix: + * [ 1 0 0 0 ] + * [ 0 -1 0 0 ] + * [ 0 0 2 0 ] + * [ 0 0 -1 1 ] + * Apply that matrix to our plane equation, and invert Y. + */ + float a = svga->curr.clip.ucp[i][0]; + float b = svga->curr.clip.ucp[i][1]; + float c = svga->curr.clip.ucp[i][2]; + float d = svga->curr.clip.ucp[i][3]; + float plane[4]; + + plane[0] = a; + plane[1] = b; + plane[2] = 2.0f * c; + plane[3] = d - c; + + ret = SVGA3D_SetClipPlane(svga->swc, i, plane); if(ret != PIPE_OK) return ret; } diff --git a/src/gallium/drivers/svga/svga_state_need_swtnl.c b/src/gallium/drivers/svga/svga_state_need_swtnl.c index 68c02578789..5a37f9fc287 100644 --- a/src/gallium/drivers/svga/svga_state_need_swtnl.c +++ b/src/gallium/drivers/svga/svga_state_need_swtnl.c @@ -139,13 +139,6 @@ static int update_need_pipeline( struct svga_context *svga, need_pipeline = TRUE; } - /* SVGA_NEW_CLIP - */ - if (svga->curr.clip.nr) { - SVGA_DBG(DEBUG_SWTNL, "%s: userclip\n", __FUNCTION__); - need_pipeline = TRUE; - } - if (need_pipeline != svga->state.sw.need_pipeline) { svga->state.sw.need_pipeline = need_pipeline; svga->dirty |= SVGA_NEW_NEED_PIPELINE; @@ -163,7 +156,6 @@ struct svga_tracked_state svga_update_need_pipeline = { "need pipeline", (SVGA_NEW_RAST | - SVGA_NEW_CLIP | SVGA_NEW_VS | SVGA_NEW_REDUCED_PRIMITIVE), update_need_pipeline diff --git a/src/gallium/drivers/svga/svga_state_rss.c b/src/gallium/drivers/svga/svga_state_rss.c index ab13f3fdf19..28f32793742 100644 --- a/src/gallium/drivers/svga/svga_state_rss.c +++ b/src/gallium/drivers/svga/svga_state_rss.c @@ -240,6 +240,11 @@ static int emit_rss( struct svga_context *svga, EMIT_RS_FLOAT( svga, bias, DEPTHBIAS, fail ); } + if (dirty & SVGA_NEW_CLIP) { + /* the number of clip planes is how many planes to enable */ + unsigned enabled = (1 << svga->curr.clip.nr) - 1; + EMIT_RS( svga, enabled, CLIPPLANEENABLE, fail ); + } if (queue.rs_count) { SVGA3dRenderState *rs; @@ -276,6 +281,7 @@ struct svga_tracked_state svga_hw_rss = (SVGA_NEW_BLEND | SVGA_NEW_BLEND_COLOR | + SVGA_NEW_CLIP | SVGA_NEW_DEPTH_STENCIL | SVGA_NEW_STENCIL_REF | SVGA_NEW_RAST | diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index 75df89f2acb..6c6641588d3 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -300,7 +300,8 @@ enum pipe_transfer_usage { #define PIPE_BIND_TRANSFER_WRITE (1 << 9) /* get_transfer */ #define PIPE_BIND_TRANSFER_READ (1 << 10) /* get_transfer */ #define PIPE_BIND_STREAM_OUTPUT (1 << 11) /* set_stream_output_buffers */ -#define PIPE_BIND_CUSTOM (1 << 16) /* state-tracker/winsys usages */ +#define PIPE_BIND_CURSOR (1 << 16) /* mouse cursor */ +#define PIPE_BIND_CUSTOM (1 << 17) /* state-tracker/winsys usages */ /* The first two flags above were previously part of the amorphous * TEXTURE_USAGE, most of which are now descriptions of the ways a @@ -465,6 +466,8 @@ enum pipe_cap { PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR = 44, PIPE_CAP_FRAGMENT_COLOR_CLAMP_CONTROL = 45, PIPE_CAP_MIXED_COLORBUFFER_FORMATS = 46, + PIPE_CAP_SEAMLESS_CUBE_MAP = 47, + PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE = 48, }; /* Shader caps not specific to any single stage */ diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index f6ad4560f16..86ef255cd2e 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -94,24 +94,21 @@ struct pipe_rasterizer_state unsigned poly_smooth:1; unsigned poly_stipple_enable:1; unsigned point_smooth:1; - unsigned sprite_coord_enable:PIPE_MAX_SHADER_OUTPUTS; unsigned sprite_coord_mode:1; /**< PIPE_SPRITE_COORD_ */ unsigned point_quad_rasterization:1; /** points rasterized as quads or points */ unsigned point_size_per_vertex:1; /**< size computed in vertex shader */ unsigned multisample:1; /* XXX maybe more ms state in future */ unsigned line_smooth:1; unsigned line_stipple_enable:1; - unsigned line_stipple_factor:8; /**< [1..256] actually */ - unsigned line_stipple_pattern:16; unsigned line_last_pixel:1; - /** + /** * Use the first vertex of a primitive as the provoking vertex for * flat shading. */ - unsigned flatshade_first:1; + unsigned flatshade_first:1; - /** + /** * When true, triangle rasterization uses (0.5, 0.5) pixel centers * for determining pixel ownership. * @@ -124,6 +121,11 @@ struct pipe_rasterizer_state */ unsigned gl_rasterization_rules:1; + unsigned line_stipple_factor:8; /**< [1..256] actually */ + unsigned line_stipple_pattern:16; + + unsigned sprite_coord_enable:PIPE_MAX_SHADER_OUTPUTS; + float line_width; float point_size; /**< used when no per-vertex size */ float offset_units; @@ -267,6 +269,7 @@ struct pipe_sampler_state unsigned compare_func:3; /**< PIPE_FUNC_x */ unsigned normalized_coords:1; /**< Are coords normalized to [0,1]? */ unsigned max_anisotropy:6; + unsigned seamless_cube_map:1; float lod_bias; /**< LOD/lambda bias */ float min_lod, max_lod; /**< LOD clamp range, after bias */ float border_color[4]; diff --git a/src/gallium/state_trackers/egl/wayland/native_drm.c b/src/gallium/state_trackers/egl/wayland/native_drm.c new file mode 100644 index 00000000000..604720f6e5f --- /dev/null +++ b/src/gallium/state_trackers/egl/wayland/native_drm.c @@ -0,0 +1,303 @@ +/* + * Mesa 3-D graphics library + * Version: 7.11 + * + * Copyright (C) 2011 Benjamin Franzke <[email protected]> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "util/u_memory.h" +#include "util/u_inlines.h" + +#include "pipe/p_compiler.h" +#include "pipe/p_screen.h" +#include "pipe/p_context.h" +#include "pipe/p_state.h" +#include "state_tracker/drm_driver.h" + +#include "egllog.h" +#include <errno.h> + +#include "native_wayland.h" + +/* see get_drm_screen_name */ +#include <radeon_drm.h> +#include "radeon/drm/radeon_drm_public.h" + +#include <wayland-client.h> +#include "wayland-drm-client-protocol.h" +#include "wayland-egl-priv.h" + +#include <xf86drm.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +struct wayland_drm_display { + struct wayland_display base; + + struct native_event_handler *event_handler; + + struct wl_drm *wl_drm; + int fd; + char *device_name; + boolean authenticated; +}; + +static INLINE struct wayland_drm_display * +wayland_drm_display(const struct native_display *ndpy) +{ + return (struct wayland_drm_display *) ndpy; +} + +static void +sync_callback(void *data) +{ + int *done = data; + + *done = 1; +} + +static void +force_roundtrip(struct wl_display *display) +{ + int done = 0; + + wl_display_sync_callback(display, sync_callback, &done); + wl_display_iterate(display, WL_DISPLAY_WRITABLE); + while (!done) + wl_display_iterate(display, WL_DISPLAY_READABLE); +} + +static void +wayland_drm_display_destroy(struct native_display *ndpy) +{ + struct wayland_drm_display *drmdpy = wayland_drm_display(ndpy); + + if (drmdpy->fd) + close(drmdpy->fd); + if (drmdpy->wl_drm) + wl_drm_destroy(drmdpy->wl_drm); + if (drmdpy->device_name) + FREE(drmdpy->device_name); + if (drmdpy->base.config) + FREE(drmdpy->base.config); + + ndpy_uninit(ndpy); + + FREE(drmdpy); +} + +static struct wl_buffer * +wayland_create_drm_buffer(struct wayland_display *display, + struct wayland_surface *surface, + enum native_attachment attachment) +{ + struct wayland_drm_display *drmdpy = (struct wayland_drm_display *) display; + struct pipe_screen *screen = drmdpy->base.base.screen; + struct pipe_resource *resource; + struct winsys_handle wsh; + uint width, height; + struct wl_visual *visual; + + resource = resource_surface_get_single_resource(surface->rsurf, attachment); + resource_surface_get_size(surface->rsurf, &width, &height); + + wsh.type = DRM_API_HANDLE_TYPE_SHARED; + screen->resource_get_handle(screen, resource, &wsh); + + pipe_resource_reference(&resource, NULL); + + switch (surface->type) { + case WL_WINDOW_SURFACE: + visual = surface->win->visual; + break; + case WL_PIXMAP_SURFACE: + visual = surface->pix->visual; + break; + default: + return NULL; + } + + return wl_drm_create_buffer(drmdpy->wl_drm, wsh.handle, + width, height, wsh.stride, visual); +} + +static const char * +get_drm_screen_name(int fd, drmVersionPtr version) +{ + const char *name = version->name; + + if (name && !strcmp(name, "radeon")) { + int chip_id; + struct drm_radeon_info info; + + memset(&info, 0, sizeof(info)); + info.request = RADEON_INFO_DEVICE_ID; + info.value = pointer_to_intptr(&chip_id); + if (drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info)) != 0) + return NULL; + + name = is_r3xx(chip_id) ? "r300" : "r600"; + } + + return name; +} + +static void +drm_handle_device(void *data, struct wl_drm *drm, const char *device) +{ + struct wayland_drm_display *drmdpy = data; + drm_magic_t magic; + + drmdpy->device_name = strdup(device); + if (!drmdpy->device_name) + return; + + drmdpy->fd = open(drmdpy->device_name, O_RDWR); + if (drmdpy->fd == -1) { + _eglLog(_EGL_WARNING, "wayland-egl: could not open %s (%s)", + drmdpy->device_name, strerror(errno)); + return; + } + + drmGetMagic(drmdpy->fd, &magic); + wl_drm_authenticate(drmdpy->wl_drm, magic); +} + +static void +drm_handle_authenticated(void *data, struct wl_drm *drm) +{ + struct wayland_drm_display *drmdpy = data; + + drmdpy->authenticated = true; +} + +static const struct wl_drm_listener drm_listener = { + drm_handle_device, + drm_handle_authenticated +}; + +static boolean +wayland_drm_display_init_screen(struct native_display *ndpy) +{ + struct wayland_drm_display *drmdpy = wayland_drm_display(ndpy); + drmVersionPtr version; + const char *driver_name; + uint32_t id; + + id = wl_display_get_global(drmdpy->base.dpy, "wl_drm", 1); + if (id == 0) + force_roundtrip(drmdpy->base.dpy); + id = wl_display_get_global(drmdpy->base.dpy, "wl_drm", 1); + if (id == 0) + return FALSE; + + drmdpy->wl_drm = wl_drm_create(drmdpy->base.dpy, id, 1); + if (!drmdpy->wl_drm) + return FALSE; + + wl_drm_add_listener(drmdpy->wl_drm, &drm_listener, drmdpy); + force_roundtrip(drmdpy->base.dpy); + if (drmdpy->fd == -1) + return FALSE; + + force_roundtrip(drmdpy->base.dpy); + if (!drmdpy->authenticated) + return FALSE; + + version = drmGetVersion(drmdpy->fd); + if (!version) { + _eglLog(_EGL_WARNING, "invalid fd %d", drmdpy->fd); + return FALSE; + } + + /* FIXME: share this with native_drm or egl_dri2 */ + driver_name = get_drm_screen_name(drmdpy->fd, version); + + drmdpy->base.base.screen = + drmdpy->event_handler->new_drm_screen(&drmdpy->base.base, + driver_name, drmdpy->fd); + drmFreeVersion(version); + + if (!drmdpy->base.base.screen) { + _eglLog(_EGL_WARNING, "failed to create DRM screen"); + return FALSE; + } + + return TRUE; +} + +static struct pipe_resource * +wayland_drm_display_import_buffer(struct native_display *ndpy, + const struct pipe_resource *templ, + void *buf) +{ + return ndpy->screen->resource_from_handle(ndpy->screen, + templ, (struct winsys_handle *) buf); +} + +static boolean +wayland_drm_display_export_buffer(struct native_display *ndpy, + struct pipe_resource *res, + void *buf) +{ + return ndpy->screen->resource_get_handle(ndpy->screen, + res, (struct winsys_handle *) buf); +} + +static struct native_display_buffer wayland_drm_display_buffer = { + wayland_drm_display_import_buffer, + wayland_drm_display_export_buffer +}; + +struct wayland_display * +wayland_create_drm_display(struct wl_display *dpy, + struct native_event_handler *event_handler, + void *user_data) +{ + struct wayland_drm_display *drmdpy; + + drmdpy = CALLOC_STRUCT(wayland_drm_display); + if (!drmdpy) + return NULL; + + drmdpy->event_handler = event_handler; + drmdpy->base.base.user_data = user_data; + + drmdpy->base.dpy = dpy; + if (!drmdpy->base.dpy) { + wayland_drm_display_destroy(&drmdpy->base.base); + return NULL; + } + + if (!wayland_drm_display_init_screen(&drmdpy->base.base)) { + wayland_drm_display_destroy(&drmdpy->base.base); + return NULL; + } + drmdpy->base.base.destroy = wayland_drm_display_destroy; + drmdpy->base.base.buffer = &wayland_drm_display_buffer; + + drmdpy->base.create_buffer = wayland_create_drm_buffer; + + return &drmdpy->base; +} + +/* vim: set sw=3 ts=8 sts=3 expandtab: */ diff --git a/src/gallium/state_trackers/egl/wayland/native_shm.c b/src/gallium/state_trackers/egl/wayland/native_shm.c new file mode 100644 index 00000000000..609fc0cd04a --- /dev/null +++ b/src/gallium/state_trackers/egl/wayland/native_shm.c @@ -0,0 +1,174 @@ +/* + * Mesa 3-D graphics library + * Version: 7.11 + * + * Copyright (C) 2011 Benjamin Franzke <[email protected]> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "util/u_memory.h" +#include "util/u_inlines.h" + +#include "pipe/p_compiler.h" +#include "pipe/p_screen.h" +#include "pipe/p_context.h" +#include "pipe/p_state.h" + +#include "sw/wayland/wayland_sw_winsys.h" + +#include "egllog.h" + +#include "native_wayland.h" + +#include <wayland-client.h> +#include "wayland-egl-priv.h" + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +struct wayland_shm_display { + struct wayland_display base; + + struct native_event_handler *event_handler; + struct wl_shm *wl_shm; +}; + +static INLINE struct wayland_shm_display * +wayland_shm_display(const struct native_display *ndpy) +{ + return (struct wayland_shm_display *) ndpy; +} + + +static void +wayland_shm_display_destroy(struct native_display *ndpy) +{ + struct wayland_shm_display *shmdpy = wayland_shm_display(ndpy); + + if (shmdpy->base.config) + FREE(shmdpy->base.config); + + ndpy_uninit(ndpy); + + FREE(shmdpy); +} + + +static struct wl_buffer * +wayland_create_shm_buffer(struct wayland_display *display, + struct wayland_surface *surface, + enum native_attachment attachment) +{ + struct wayland_shm_display *shmdpy = (struct wayland_shm_display *) display; + struct pipe_screen *screen = shmdpy->base.base.screen; + struct pipe_resource *resource; + struct winsys_handle wsh; + uint width, height; + struct wl_visual *visual; + + resource = resource_surface_get_single_resource(surface->rsurf, attachment); + resource_surface_get_size(surface->rsurf, &width, &height); + + screen->resource_get_handle(screen, resource, &wsh); + + pipe_resource_reference(&resource, NULL); + + switch (surface->type) { + case WL_WINDOW_SURFACE: + visual = surface->win->visual; + break; + case WL_PIXMAP_SURFACE: + visual = surface->pix->visual; + break; + default: + return NULL; + } + + return wl_shm_create_buffer(shmdpy->wl_shm, wsh.fd, + width, height, + wsh.stride, visual); +} + +static boolean +wayland_shm_display_init_screen(struct native_display *ndpy) +{ + struct wayland_shm_display *shmdpy = wayland_shm_display(ndpy); + struct sw_winsys *winsys = NULL; + uint32_t id; + + id = wl_display_get_global(shmdpy->base.dpy, "wl_shm", 1); + if (id == 0) + wl_display_iterate(shmdpy->base.dpy, WL_DISPLAY_READABLE); + id = wl_display_get_global(shmdpy->base.dpy, "wl_shm", 1); + if (id == 0) + return FALSE; + + shmdpy->wl_shm = wl_shm_create(shmdpy->base.dpy, id, 1); + if (!shmdpy->wl_shm) + return FALSE; + + winsys = wayland_create_sw_winsys(shmdpy->base.dpy); + if (!winsys) + return FALSE; + + shmdpy->base.base.screen = + shmdpy->event_handler->new_sw_screen(&shmdpy->base.base, winsys); + + if (!shmdpy->base.base.screen) { + _eglLog(_EGL_WARNING, "failed to create shm screen"); + return FALSE; + } + + return TRUE; +} + +struct wayland_display * +wayland_create_shm_display(struct wl_display *dpy, + struct native_event_handler *event_handler, + void *user_data) +{ + struct wayland_shm_display *shmdpy; + + shmdpy = CALLOC_STRUCT(wayland_shm_display); + if (!shmdpy) + return NULL; + + shmdpy->event_handler = event_handler; + shmdpy->base.base.user_data = user_data; + + shmdpy->base.dpy = dpy; + if (!shmdpy->base.dpy) { + wayland_shm_display_destroy(&shmdpy->base.base); + return NULL; + } + + if (!wayland_shm_display_init_screen(&shmdpy->base.base)) { + wayland_shm_display_destroy(&shmdpy->base.base); + return NULL; + } + + shmdpy->base.base.destroy = wayland_shm_display_destroy; + shmdpy->base.create_buffer = wayland_create_shm_buffer; + + return &shmdpy->base; +} + +/* vim: set sw=3 ts=8 sts=3 expandtab: */ diff --git a/src/gallium/state_trackers/egl/wayland/native_wayland.c b/src/gallium/state_trackers/egl/wayland/native_wayland.c index b9cf8c48f1e..e7ed9d64b7e 100644 --- a/src/gallium/state_trackers/egl/wayland/native_wayland.c +++ b/src/gallium/state_trackers/egl/wayland/native_wayland.c @@ -31,25 +31,10 @@ #include "pipe/p_context.h" #include "pipe/p_state.h" #include "state_tracker/drm_driver.h" - #include "egllog.h" -#include <errno.h> #include "native_wayland.h" -/* see get_drm_screen_name */ -#include <radeon_drm.h> -#include "radeon/drm/radeon_drm_public.h" - -#include <wayland-client.h> -#include "wayland-drm-client-protocol.h" -#include "wayland-egl-priv.h" - -#include <xf86drm.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> - static struct native_event_handler *wayland_event_handler; static void @@ -113,12 +98,12 @@ wayland_display_get_param(struct native_display *ndpy, int val; switch (param) { - case NATIVE_PARAM_USE_NATIVE_BUFFER: - case NATIVE_PARAM_PRESERVE_BUFFER: - case NATIVE_PARAM_MAX_SWAP_INTERVAL: - default: - val = 0; - break; + case NATIVE_PARAM_USE_NATIVE_BUFFER: + case NATIVE_PARAM_PRESERVE_BUFFER: + case NATIVE_PARAM_MAX_SWAP_INTERVAL: + default: + val = 0; + break; } return val; @@ -134,48 +119,6 @@ wayland_display_is_pixmap_supported(struct native_display *ndpy, return TRUE; } -static void -wayland_display_destroy(struct native_display *ndpy) -{ - struct wayland_display *display = wayland_display(ndpy); - - if (display->fd) - close(display->fd); - if (display->wl_drm) - wl_drm_destroy(display->wl_drm); - if (display->device_name) - FREE(display->device_name); - if (display->config) - FREE(display->config); - - ndpy_uninit(ndpy); - - FREE(display); -} - - -static struct wl_buffer * -wayland_create_buffer(struct wayland_surface *surface, - enum native_attachment attachment) -{ - struct wayland_display *display = surface->display; - struct pipe_resource *resource; - struct winsys_handle wsh; - uint width, height; - - resource = resource_surface_get_single_resource(surface->rsurf, attachment); - resource_surface_get_size(surface->rsurf, &width, &height); - - wsh.type = DRM_API_HANDLE_TYPE_SHARED; - display->base.screen->resource_get_handle(display->base.screen, resource, &wsh); - - pipe_resource_reference(&resource, NULL); - - return wl_drm_create_buffer(display->wl_drm, wsh.handle, - width, height, - wsh.stride, surface->win->visual); -} - static void wayland_pixmap_destroy(struct wl_egl_pixmap *egl_pixmap) { @@ -188,7 +131,7 @@ wayland_pixmap_destroy(struct wl_egl_pixmap *egl_pixmap) wl_buffer_destroy(egl_pixmap->buffer); egl_pixmap->buffer = NULL; } - + egl_pixmap->driver_private = NULL; egl_pixmap->destroy = NULL; } @@ -196,26 +139,16 @@ wayland_pixmap_destroy(struct wl_egl_pixmap *egl_pixmap) static void wayland_pixmap_surface_initialize(struct wayland_surface *surface) { - struct native_display *ndpy = &surface->display->base; - struct pipe_resource *resource; - struct winsys_handle wsh; + struct wayland_display *display = wayland_display(&surface->display->base); const enum native_attachment front_natt = NATIVE_ATTACHMENT_FRONT_LEFT; if (surface->pix->buffer != NULL) return; - resource = resource_surface_get_single_resource(surface->rsurf, front_natt); - - wsh.type = DRM_API_HANDLE_TYPE_SHARED; - ndpy->screen->resource_get_handle(ndpy->screen, resource, &wsh); - - surface->pix->buffer = - wl_drm_create_buffer(surface->display->wl_drm, wsh.handle, - surface->pix->width, surface->pix->height, - wsh.stride, surface->pix->visual); - - surface->pix->destroy = wayland_pixmap_destroy; - surface->pix->driver_private = resource; + surface->pix->buffer = display->create_buffer(display, surface, front_natt); + surface->pix->destroy = wayland_pixmap_destroy; + surface->pix->driver_private = + resource_surface_get_single_resource(surface->rsurf, front_natt); } static void @@ -237,11 +170,11 @@ wayland_window_surface_handle_resize(struct wayland_surface *surface) struct pipe_resource *front_resource; const enum native_attachment front_natt = NATIVE_ATTACHMENT_FRONT_LEFT; int i; - + front_resource = resource_surface_get_single_resource(surface->rsurf, front_natt); if (resource_surface_set_size(surface->rsurf, - surface->win->width, surface->win->height)) { + surface->win->width, surface->win->height)) { if (surface->pending_resource) force_roundtrip(display->dpy); @@ -328,17 +261,19 @@ wayland_surface_swap_buffers(struct native_surface *nsurf) if (surface->type == WL_WINDOW_SURFACE) { resource_surface_swap_buffers(surface->rsurf, - NATIVE_ATTACHMENT_FRONT_LEFT, NATIVE_ATTACHMENT_BACK_LEFT, FALSE); + NATIVE_ATTACHMENT_FRONT_LEFT, + NATIVE_ATTACHMENT_BACK_LEFT, FALSE); wayland_buffers_swap(surface->buffer, WL_BUFFER_FRONT, WL_BUFFER_BACK); if (surface->buffer[WL_BUFFER_FRONT] == NULL) surface->buffer[WL_BUFFER_FRONT] = - wayland_create_buffer(surface, NATIVE_ATTACHMENT_FRONT_LEFT); + display->create_buffer(display, surface, + NATIVE_ATTACHMENT_FRONT_LEFT); wl_surface_attach(surface->win->surface, surface->buffer[WL_BUFFER_FRONT], surface->dx, surface->dy); - + resource_surface_get_size(surface->rsurf, (uint *) &surface->win->attached_width, (uint *) &surface->win->attached_height); @@ -348,7 +283,8 @@ wayland_surface_swap_buffers(struct native_surface *nsurf) surface->sequence_number++; wayland_event_handler->invalid_surface(&display->base, - &surface->base, surface->sequence_number); + &surface->base, + surface->sequence_number); return TRUE; } @@ -408,6 +344,8 @@ wayland_surface_destroy(struct native_surface *nsurf) FREE(surface); } + + static struct native_surface * wayland_create_pixmap_surface(struct native_display *ndpy, EGLNativePixmapType pix, @@ -417,6 +355,8 @@ wayland_create_pixmap_surface(struct native_display *ndpy, struct wayland_surface *surface; struct wl_egl_pixmap *egl_pixmap = (struct wl_egl_pixmap *) pix; enum native_attachment natt = NATIVE_ATTACHMENT_FRONT_LEFT; + uint bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW | + PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT; surface = CALLOC_STRUCT(wayland_surface); if (!surface) @@ -434,15 +374,13 @@ wayland_create_pixmap_surface(struct native_display *ndpy, surface->color_format = PIPE_FORMAT_B8G8R8A8_UNORM; surface->attachment_mask = (1 << NATIVE_ATTACHMENT_FRONT_LEFT); - + surface->rsurf = resource_surface_create(display->base.screen, - surface->color_format, - PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW | - PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT); + surface->color_format, bind); if (!surface->rsurf) { - FREE(surface); - return NULL; + FREE(surface); + return NULL; } resource_surface_set_size(surface->rsurf, @@ -461,6 +399,7 @@ wayland_create_pixmap_surface(struct native_display *ndpy, return &surface->base; } + static struct native_surface * wayland_create_window_surface(struct native_display *ndpy, EGLNativeWindowType win, @@ -469,6 +408,8 @@ wayland_create_window_surface(struct native_display *ndpy, struct wayland_display *display = wayland_display(ndpy); struct wayland_config *config = wayland_config(nconf); struct wayland_surface *surface; + uint bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW | + PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT; surface = CALLOC_STRUCT(wayland_surface); if (!surface) @@ -486,16 +427,14 @@ wayland_create_window_surface(struct native_display *ndpy, surface->buffer[WL_BUFFER_FRONT] = NULL; surface->buffer[WL_BUFFER_BACK] = NULL; surface->attachment_mask = (1 << NATIVE_ATTACHMENT_FRONT_LEFT) | - (1 << NATIVE_ATTACHMENT_BACK_LEFT); + (1 << NATIVE_ATTACHMENT_BACK_LEFT); surface->rsurf = resource_surface_create(display->base.screen, - surface->color_format, - PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW | - PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT); + surface->color_format, bind); if (!surface->rsurf) { - FREE(surface); - return NULL; + FREE(surface); + return NULL; } surface->base.destroy = wayland_surface_destroy; @@ -506,178 +445,46 @@ wayland_create_window_surface(struct native_display *ndpy, return &surface->base; } -static const char * -get_drm_screen_name(int fd, drmVersionPtr version) -{ - const char *name = version->name; - - if (name && !strcmp(name, "radeon")) { - int chip_id; - struct drm_radeon_info info; - - memset(&info, 0, sizeof(info)); - info.request = RADEON_INFO_DEVICE_ID; - info.value = pointer_to_intptr(&chip_id); - if (drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info)) != 0) - return NULL; - - name = is_r3xx(chip_id) ? "r300" : "r600"; - } - - return name; -} - -static void -drm_handle_device(void *data, struct wl_drm *drm, const char *device) -{ - struct wayland_display *display = data; - drm_magic_t magic; - - display->device_name = strdup(device); - if (!display->device_name) - return; - - display->fd = open(display->device_name, O_RDWR); - if (display->fd == -1) { - _eglLog(_EGL_WARNING, "wayland-egl: could not open %s (%s)", - display->device_name, strerror(errno)); - return; - } - - drmGetMagic(display->fd, &magic); - wl_drm_authenticate(display->wl_drm, magic); -} - -static void -drm_handle_authenticated(void *data, struct wl_drm *drm) -{ - struct wayland_display *display = data; - - display->authenticated = true; -} - -static const struct wl_drm_listener drm_listener = { - drm_handle_device, - drm_handle_authenticated -}; - -static boolean -wayland_display_init_screen(struct native_display *ndpy) -{ - struct wayland_display *display = wayland_display(ndpy); - drmVersionPtr version; - const char *driver_name; - uint32_t id; - - id = wl_display_get_global(display->dpy, "wl_drm", 1); - if (id == 0) - wl_display_iterate(display->dpy, WL_DISPLAY_READABLE); - id = wl_display_get_global(display->dpy, "wl_drm", 1); - if (id == 0) - return FALSE; - - display->wl_drm = wl_drm_create(display->dpy, id, 1); - if (!display->wl_drm) - return FALSE; - - wl_drm_add_listener(display->wl_drm, &drm_listener, display); - force_roundtrip(display->dpy); - if (display->fd == -1) - return FALSE; - - force_roundtrip(display->dpy); - if (!display->authenticated) - return FALSE; - - version = drmGetVersion(display->fd); - if (!version) { - _eglLog(_EGL_WARNING, "invalid fd %d", display->fd); - return FALSE; - } - - /* FIXME: share this with native_drm or egl_dri2 */ - driver_name = get_drm_screen_name(display->fd, version); - - display->base.screen = - wayland_event_handler->new_drm_screen(&display->base, - driver_name, display->fd); - drmFreeVersion(version); - - if (!display->base.screen) { - _eglLog(_EGL_WARNING, "failed to create DRM screen"); - return FALSE; - } - - return TRUE; -} - - static void -wayland_set_event_handler(struct native_event_handler *event_handler) +native_set_event_handler(struct native_event_handler *event_handler) { wayland_event_handler = event_handler; } -static struct pipe_resource * -wayland_display_import_buffer(struct native_display *ndpy, - const struct pipe_resource *templ, - void *buf) -{ - return ndpy->screen->resource_from_handle(ndpy->screen, - templ, (struct winsys_handle *) buf); -} - -static boolean -wayland_display_export_buffer(struct native_display *ndpy, - struct pipe_resource *res, - void *buf) -{ - return ndpy->screen->resource_get_handle(ndpy->screen, - res, (struct winsys_handle *) buf); -} - -static struct native_display_buffer wayland_display_buffer = { - wayland_display_import_buffer, - wayland_display_export_buffer -}; - static struct native_display * -wayland_display_create(void *dpy, boolean use_sw, void *user_data) +native_create_display(void *dpy, boolean use_sw, void *user_data) { - struct wayland_display *display; - - display = CALLOC_STRUCT(wayland_display); - if (!display) - return NULL; - - display->base.user_data = user_data; - - display->dpy = dpy; - if (!display->dpy) { - wayland_display_destroy(&display->base); - return NULL; + struct wayland_display *display = NULL; + + use_sw = use_sw || debug_get_bool_option("EGL_SOFTWARE", FALSE); + + if (use_sw) { + _eglLog(_EGL_INFO, "use software fallback"); + display = wayland_create_shm_display((struct wl_display *) dpy, + wayland_event_handler, + user_data); + } else { + display = wayland_create_drm_display((struct wl_display *) dpy, + wayland_event_handler, + user_data); } - if (!wayland_display_init_screen(&display->base)) { - wayland_display_destroy(&display->base); + if (!display) return NULL; - } - display->base.destroy = wayland_display_destroy; display->base.get_param = wayland_display_get_param; display->base.get_configs = wayland_display_get_configs; display->base.is_pixmap_supported = wayland_display_is_pixmap_supported; display->base.create_window_surface = wayland_create_window_surface; display->base.create_pixmap_surface = wayland_create_pixmap_surface; - display->base.buffer = &wayland_display_buffer; return &display->base; } static const struct native_platform wayland_platform = { "wayland", /* name */ - wayland_set_event_handler, - wayland_display_create + native_set_event_handler, + native_create_display }; const struct native_platform * @@ -685,3 +492,5 @@ native_get_wayland_platform(void) { return &wayland_platform; } + +/* vim: set sw=3 ts=8 sts=3 expandtab: */ diff --git a/src/gallium/state_trackers/egl/wayland/native_wayland.h b/src/gallium/state_trackers/egl/wayland/native_wayland.h index 14fc9b0fbb2..e69a8f00f82 100644 --- a/src/gallium/state_trackers/egl/wayland/native_wayland.h +++ b/src/gallium/state_trackers/egl/wayland/native_wayland.h @@ -33,17 +33,18 @@ #include "common/native_helper.h" #include "wayland-egl-priv.h" -#include "wayland-drm-client-protocol.h" + +struct wayland_surface; struct wayland_display { struct native_display base; struct wayland_config *config; struct wl_display *dpy; - struct wl_drm *wl_drm; - int fd; - char *device_name; - boolean authenticated; + + struct wl_buffer *(*create_buffer)(struct wayland_display *display, + struct wayland_surface *surface, + enum native_attachment attachment); }; enum wayland_buffer_type { @@ -78,7 +79,7 @@ struct wayland_surface { }; struct wayland_config { - struct native_config base; + struct native_config base; }; static INLINE struct wayland_display * @@ -99,4 +100,13 @@ wayland_config(const struct native_config *nconf) return (struct wayland_config *) nconf; } +struct wayland_display * +wayland_create_shm_display(struct wl_display *display, + struct native_event_handler *event_handler, + void *user_data); +struct wayland_display * +wayland_create_drm_display(struct wl_display *display, + struct native_event_handler *event_handler, + void *user_data); + #endif /* _NATIVE_WAYLAND_H_ */ diff --git a/src/gallium/state_trackers/wgl/stw_ext_pbuffer.c b/src/gallium/state_trackers/wgl/stw_ext_pbuffer.c index fb5d5e8b929..424d8daccb3 100644 --- a/src/gallium/state_trackers/wgl/stw_ext_pbuffer.c +++ b/src/gallium/state_trackers/wgl/stw_ext_pbuffer.c @@ -40,6 +40,30 @@ #include "stw_framebuffer.h" +#define LARGE_WINDOW_SIZE 60000 + + +static LRESULT CALLBACK +WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + MINMAXINFO *pMMI; + switch (uMsg) { + case WM_GETMINMAXINFO: + // Allow to create a window bigger than the desktop + pMMI = (MINMAXINFO *)lParam; + pMMI->ptMaxSize.x = LARGE_WINDOW_SIZE; + pMMI->ptMaxSize.y = LARGE_WINDOW_SIZE; + pMMI->ptMaxTrackSize.x = LARGE_WINDOW_SIZE; + pMMI->ptMaxTrackSize.y = LARGE_WINDOW_SIZE; + break; + default: + break; + } + + return DefWindowProc(hWnd, uMsg, wParam, lParam); +} + + HPBUFFERARB WINAPI wglCreatePbufferARB(HDC _hDC, int iPixelFormat, @@ -109,7 +133,7 @@ wglCreatePbufferARB(HDC _hDC, wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); - wc.lpfnWndProc = DefWindowProc; + wc.lpfnWndProc = WndProc; wc.lpszClassName = "wglpbuffer"; wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; RegisterClass(&wc); diff --git a/src/gallium/state_trackers/wgl/stw_framebuffer.c b/src/gallium/state_trackers/wgl/stw_framebuffer.c index d8b1440a688..4033365bfbe 100644 --- a/src/gallium/state_trackers/wgl/stw_framebuffer.c +++ b/src/gallium/state_trackers/wgl/stw_framebuffer.c @@ -117,13 +117,26 @@ stw_framebuffer_get_size( struct stw_framebuffer *fb ) RECT window_rect; POINT client_pos; + /* + * Sanity checking. + */ + assert(fb->hWnd); - - /* Get the client area size. */ - GetClientRect( fb->hWnd, &client_rect ); + assert(fb->width && fb->height); + assert(fb->client_rect.right == fb->client_rect.left + fb->width); + assert(fb->client_rect.bottom == fb->client_rect.top + fb->height); + + /* + * Get the client area size. + */ + + if (!GetClientRect(fb->hWnd, &client_rect)) { + return; + } + assert(client_rect.left == 0); assert(client_rect.top == 0); - width = client_rect.right - client_rect.left; + width = client_rect.right - client_rect.left; height = client_rect.bottom - client_rect.top; if (width <= 0 || height <= 0) { @@ -138,7 +151,7 @@ stw_framebuffer_get_size( struct stw_framebuffer *fb ) return; } - if(width != fb->width || height != fb->height) { + if (width != fb->width || height != fb->height) { fb->must_resize = TRUE; fb->width = width; fb->height = height; @@ -146,14 +159,14 @@ stw_framebuffer_get_size( struct stw_framebuffer *fb ) client_pos.x = 0; client_pos.y = 0; - ClientToScreen(fb->hWnd, &client_pos); - - GetWindowRect(fb->hWnd, &window_rect); + if (ClientToScreen(fb->hWnd, &client_pos) && + GetWindowRect(fb->hWnd, &window_rect)) { + fb->client_rect.left = client_pos.x - window_rect.left; + fb->client_rect.top = client_pos.y - window_rect.top; + } - fb->client_rect.left = client_pos.x - window_rect.left; - fb->client_rect.top = client_pos.y - window_rect.top; - fb->client_rect.right = fb->client_rect.left + fb->width; - fb->client_rect.bottom = fb->client_rect.top + fb->height; + fb->client_rect.right = fb->client_rect.left + fb->width; + fb->client_rect.bottom = fb->client_rect.top + fb->height; #if 0 debug_printf("\n"); @@ -253,6 +266,19 @@ stw_framebuffer_create( fb->refcnt = 1; + /* + * Windows can be sometimes have zero width and or height, but we ensure + * a non-zero framebuffer size at all times. + */ + + fb->must_resize = TRUE; + fb->width = 1; + fb->height = 1; + fb->client_rect.left = 0; + fb->client_rect.top = 0; + fb->client_rect.right = fb->client_rect.left + fb->width; + fb->client_rect.bottom = fb->client_rect.top + fb->height; + stw_framebuffer_get_size(fb); pipe_mutex_init( fb->mutex ); diff --git a/src/gallium/state_trackers/xorg/xorg_crtc.c b/src/gallium/state_trackers/xorg/xorg_crtc.c index d751ac18704..0499ed1ea0b 100644 --- a/src/gallium/state_trackers/xorg/xorg_crtc.c +++ b/src/gallium/state_trackers/xorg/xorg_crtc.c @@ -210,6 +210,9 @@ crtc_load_cursor_argb_ga3d(xf86CrtcPtr crtc, CARD32 * image) modesettingPtr ms = modesettingPTR(crtc->scrn); struct crtc_private *crtcp = crtc->driver_private; struct pipe_transfer *transfer; + struct pipe_fence_handle *fence = NULL; + struct pipe_context *ctx = ms->ctx; + struct pipe_screen *screen = ms->screen; if (!crtcp->cursor_tex) { struct pipe_resource templat; @@ -218,6 +221,7 @@ crtc_load_cursor_argb_ga3d(xf86CrtcPtr crtc, CARD32 * image) memset(&templat, 0, sizeof(templat)); templat.bind |= PIPE_BIND_RENDER_TARGET; templat.bind |= PIPE_BIND_SCANOUT; + templat.bind |= PIPE_BIND_CURSOR; templat.target = PIPE_TEXTURE_2D; templat.last_level = 0; templat.depth0 = 1; @@ -229,23 +233,28 @@ crtc_load_cursor_argb_ga3d(xf86CrtcPtr crtc, CARD32 * image) memset(&whandle, 0, sizeof(whandle)); whandle.type = DRM_API_HANDLE_TYPE_KMS; - crtcp->cursor_tex = ms->screen->resource_create(ms->screen, - &templat); - ms->screen->resource_get_handle(ms->screen, crtcp->cursor_tex, &whandle); + crtcp->cursor_tex = screen->resource_create(screen, &templat); + screen->resource_get_handle(screen, crtcp->cursor_tex, &whandle); crtcp->cursor_handle = whandle.handle; } - transfer = pipe_get_transfer(ms->ctx, crtcp->cursor_tex, + transfer = pipe_get_transfer(ctx, crtcp->cursor_tex, 0, 0, PIPE_TRANSFER_WRITE, 0, 0, 64, 64); - ptr = ms->ctx->transfer_map(ms->ctx, transfer); + ptr = ctx->transfer_map(ctx, transfer); util_copy_rect(ptr, crtcp->cursor_tex->format, transfer->stride, 0, 0, 64, 64, (void*)image, 64 * 4, 0, 0); - ms->ctx->transfer_unmap(ms->ctx, transfer); - ms->ctx->transfer_destroy(ms->ctx, transfer); + ctx->transfer_unmap(ctx, transfer); + ctx->transfer_destroy(ctx, transfer); + ctx->flush(ctx, &fence); + + if (fence) { + screen->fence_finish(screen, fence, PIPE_TIMEOUT_INFINITE); + screen->fence_reference(screen, &fence, NULL); + } if (crtc->cursor_shown) drmModeSetCursor(ms->fd, crtcp->drm_crtc->crtc_id, diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c index 19e9bf84656..063ae92f6be 100644 --- a/src/gallium/state_trackers/xorg/xorg_driver.c +++ b/src/gallium/state_trackers/xorg/xorg_driver.c @@ -831,9 +831,9 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) #endif } - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "##################################\n"); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "# Usefull debugging info follows #\n"); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "##################################\n"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "#################################\n"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "# Useful debugging info follows #\n"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "#################################\n"); xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using %s backend\n", ms->screen ? "Gallium3D" : "libkms"); xf86DrvMsg(pScrn->scrnIndex, X_INFO, "2D Acceleration is %s\n", diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c index e7d6a93e5ca..91c206f1872 100644 --- a/src/gallium/state_trackers/xorg/xorg_exa.c +++ b/src/gallium/state_trackers/xorg/xorg_exa.c @@ -336,7 +336,7 @@ ExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg) return FALSE; if (!exa->pipe) - XORG_FALLBACK("accle not enabled"); + XORG_FALLBACK("accel not enabled"); if (!priv || !priv->tex) XORG_FALLBACK("%s", !priv ? "!priv" : "!priv->tex"); @@ -414,7 +414,7 @@ ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, return FALSE; if (!exa->pipe) - XORG_FALLBACK("accle not enabled"); + XORG_FALLBACK("accel not enabled"); if (!priv || !priv->tex) XORG_FALLBACK("pDst %s", !priv ? "!priv" : "!priv->tex"); @@ -622,7 +622,7 @@ ExaPrepareComposite(int op, PicturePtr pSrcPicture, pDstPicture ? render_format_name(pDstPicture->format) : "none"); #endif if (!exa->pipe) - XORG_FALLBACK("accle not enabled"); + XORG_FALLBACK("accel not enabled"); priv = exaGetPixmapDriverPrivate(pDst); if (!priv || !priv->tex) diff --git a/src/gallium/targets/egl/Makefile b/src/gallium/targets/egl/Makefile index de01939e5f1..9d76a706122 100644 --- a/src/gallium/targets/egl/Makefile +++ b/src/gallium/targets/egl/Makefile @@ -48,6 +48,7 @@ egl_LIBS += $(TOP)/src/gallium/winsys/sw/xlib/libws_xlib.a endif ifneq ($(findstring wayland, $(EGL_PLATFORMS)),) egl_SYS += $(WAYLAND_LIBS) $(LIBDRM_LIB) +egl_LIBS += $(TOP)/src/gallium/winsys/sw/wayland/libws_wayland.a endif ifneq ($(findstring drm, $(EGL_PLATFORMS)),) egl_SYS += $(LIBDRM_LIB) diff --git a/src/gallium/targets/xorg-nouveau/Makefile b/src/gallium/targets/xorg-nouveau/Makefile index 2fcd9ffb7d6..5a2cdb1b0ef 100644 --- a/src/gallium/targets/xorg-nouveau/Makefile +++ b/src/gallium/targets/xorg-nouveau/Makefile @@ -15,6 +15,7 @@ DRIVER_PIPES = \ $(TOP)/src/gallium/winsys/nouveau/drm/libnouveaudrm.a \ $(TOP)/src/gallium/drivers/nvfx/libnvfx.a \ $(TOP)/src/gallium/drivers/nv50/libnv50.a \ + $(TOP)/src/gallium/drivers/nvc0/libnvc0.a \ $(TOP)/src/gallium/drivers/nouveau/libnouveau.a \ $(TOP)/src/gallium/drivers/trace/libtrace.a \ $(TOP)/src/gallium/drivers/rbug/librbug.a diff --git a/src/gallium/targets/xorg-nouveau/nouveau_xorg.c b/src/gallium/targets/xorg-nouveau/nouveau_xorg.c index 699af09029f..f0d64925c73 100644 --- a/src/gallium/targets/xorg-nouveau/nouveau_xorg.c +++ b/src/gallium/targets/xorg-nouveau/nouveau_xorg.c @@ -136,7 +136,7 @@ nouveau_xorg_pci_probe(DriverPtr driver, NULL, NULL, NULL, NULL, NULL); if (scrn != NULL) { scrn->driverVersion = 1; - scrn->driverName = "i915"; + scrn->driverName = "nouveau"; scrn->name = "modesetting"; scrn->Probe = NULL; diff --git a/src/gallium/winsys/i915/drm/i915_drm_winsys.h b/src/gallium/winsys/i915/drm/i915_drm_winsys.h index dae53c3e801..7f0d718bdb7 100644 --- a/src/gallium/winsys/i915/drm/i915_drm_winsys.h +++ b/src/gallium/winsys/i915/drm/i915_drm_winsys.h @@ -18,7 +18,7 @@ struct i915_drm_winsys struct i915_winsys base; boolean dump_cmd; - char *dump_raw_file; + const char *dump_raw_file; boolean send_cmd; int fd; /**< Drm file discriptor */ diff --git a/src/gallium/winsys/r600/drm/r600_bo.c b/src/gallium/winsys/r600/drm/r600_bo.c index 40d6ec4c625..100ee7cdb37 100644 --- a/src/gallium/winsys/r600/drm/r600_bo.c +++ b/src/gallium/winsys/r600/drm/r600_bo.c @@ -191,7 +191,7 @@ boolean r600_bo_get_winsys_handle(struct radeon *radeon, struct r600_bo *bo, whandle->stride = stride; switch(whandle->type) { case DRM_API_HANDLE_TYPE_KMS: - whandle->handle = r600_bo_get_handle(bo); + whandle->handle = bo->bo->handle; break; case DRM_API_HANDLE_TYPE_SHARED: if (radeon_bo_get_name(radeon, bo->bo, &whandle->handle)) diff --git a/src/gallium/winsys/r600/drm/r600_drm.c b/src/gallium/winsys/r600/drm/r600_drm.c index ddd8ee3d6dd..311324f4f71 100644 --- a/src/gallium/winsys/r600/drm/r600_drm.c +++ b/src/gallium/winsys/r600/drm/r600_drm.c @@ -199,7 +199,6 @@ static int radeon_get_clock_crystal_freq(struct radeon *radeon) uint32_t clock_crystal_freq; int r; - radeon->device = 0; info.request = RADEON_INFO_CLOCK_CRYSTAL_FREQ; info.value = (uintptr_t)&clock_crystal_freq; r = drmCommandWriteRead(radeon->fd, DRM_RADEON_INFO, &info, @@ -218,7 +217,6 @@ static int radeon_get_num_backends(struct radeon *radeon) uint32_t num_backends; int r; - radeon->device = 0; info.request = RADEON_INFO_NUM_BACKENDS; info.value = (uintptr_t)&num_backends; r = drmCommandWriteRead(radeon->fd, DRM_RADEON_INFO, &info, diff --git a/src/gallium/winsys/r600/drm/r600_hw_context.c b/src/gallium/winsys/r600/drm/r600_hw_context.c index 935ac07802e..34ea2a6bacb 100644 --- a/src/gallium/winsys/r600/drm/r600_hw_context.c +++ b/src/gallium/winsys/r600/drm/r600_hw_context.c @@ -127,10 +127,20 @@ int r600_context_add_block(struct r600_context *ctx, const struct r600_reg *reg, block->pm4_bo_index[j] = block->nbo; block->pm4[block->pm4_ndwords++] = PKT3(PKT3_NOP, 0, 0); block->pm4[block->pm4_ndwords++] = 0x00000000; - block->reloc[block->nbo].flush_flags = reg[i+j].flush_flags; - block->reloc[block->nbo].flush_mask = reg[i+j].flush_mask; + if (reg[i+j].flags & REG_FLAG_RV6XX_SBU) { + block->reloc[block->nbo].flush_flags = 0; + block->reloc[block->nbo].flush_mask = 0; + } else { + block->reloc[block->nbo].flush_flags = reg[i+j].flush_flags; + block->reloc[block->nbo].flush_mask = reg[i+j].flush_mask; + } block->reloc[block->nbo].bo_pm4_index = block->pm4_ndwords - 1; } + if ((ctx->radeon->family > CHIP_R600) && + (ctx->radeon->family < CHIP_RV770) && reg[i+j].flags & REG_FLAG_RV6XX_SBU) { + block->pm4[block->pm4_ndwords++] = PKT3(PKT3_SURFACE_BASE_UPDATE, 0, 0); + block->pm4[block->pm4_ndwords++] = reg[i+j].flush_flags; + } } for (j = 0; j < n; j++) { if (reg[i+j].flush_flags) { @@ -197,7 +207,7 @@ static const struct r600_reg r600_context_reg_list[] = { {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028028_DB_STENCIL_CLEAR, 0, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_02802C_DB_DEPTH_CLEAR, 0, 0, 0}, {0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0}, - {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028040_CB_COLOR0_BASE, REG_FLAG_NEED_BO, 0, 0}, + {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028040_CB_COLOR0_BASE, REG_FLAG_NEED_BO|REG_FLAG_RV6XX_SBU, SURFACE_BASE_UPDATE_COLOR(0), 0}, {0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280A0_CB_COLOR0_INFO, REG_FLAG_NEED_BO, 0, 0xFFFFFFFF}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028060_CB_COLOR0_SIZE, 0, 0, 0}, @@ -208,7 +218,7 @@ static const struct r600_reg r600_context_reg_list[] = { {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280C0_CB_COLOR0_TILE, REG_FLAG_NEED_BO, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028100_CB_COLOR0_MASK, 0, 0, 0}, {0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0}, - {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028044_CB_COLOR1_BASE, REG_FLAG_NEED_BO, 0, 0}, + {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028044_CB_COLOR1_BASE, REG_FLAG_NEED_BO|REG_FLAG_RV6XX_SBU, SURFACE_BASE_UPDATE_COLOR(1), 0}, {0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280A4_CB_COLOR1_INFO, REG_FLAG_NEED_BO, 0, 0xFFFFFFFF}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028064_CB_COLOR1_SIZE, 0, 0, 0}, @@ -219,7 +229,7 @@ static const struct r600_reg r600_context_reg_list[] = { {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280C4_CB_COLOR1_TILE, REG_FLAG_NEED_BO, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028104_CB_COLOR1_MASK, 0, 0, 0}, {0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0}, - {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028048_CB_COLOR2_BASE, REG_FLAG_NEED_BO, 0, 0}, + {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028048_CB_COLOR2_BASE, REG_FLAG_NEED_BO|REG_FLAG_RV6XX_SBU, SURFACE_BASE_UPDATE_COLOR(2), 0}, {0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280A8_CB_COLOR2_INFO, REG_FLAG_NEED_BO, 0, 0xFFFFFFFF}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028068_CB_COLOR2_SIZE, 0, 0, 0}, @@ -230,7 +240,7 @@ static const struct r600_reg r600_context_reg_list[] = { {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280C8_CB_COLOR2_TILE, REG_FLAG_NEED_BO, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028108_CB_COLOR2_MASK, 0, 0, 0}, {0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0}, - {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_02804C_CB_COLOR3_BASE, REG_FLAG_NEED_BO, 0, 0}, + {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_02804C_CB_COLOR3_BASE, REG_FLAG_NEED_BO|REG_FLAG_RV6XX_SBU, SURFACE_BASE_UPDATE_COLOR(3), 0}, {0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280AC_CB_COLOR3_INFO, REG_FLAG_NEED_BO, 0, 0xFFFFFFFF}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_02806C_CB_COLOR3_SIZE, 0, 0, 0}, @@ -241,7 +251,7 @@ static const struct r600_reg r600_context_reg_list[] = { {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280CC_CB_COLOR3_TILE, REG_FLAG_NEED_BO, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_02810C_CB_COLOR3_MASK, 0, 0, 0}, {0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0}, - {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028050_CB_COLOR4_BASE, REG_FLAG_NEED_BO, 0, 0}, + {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028050_CB_COLOR4_BASE, REG_FLAG_NEED_BO|REG_FLAG_RV6XX_SBU, SURFACE_BASE_UPDATE_COLOR(4), 0}, {0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280B0_CB_COLOR4_INFO, REG_FLAG_NEED_BO, 0, 0xFFFFFFFF}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028070_CB_COLOR4_SIZE, 0, 0, 0}, @@ -252,7 +262,7 @@ static const struct r600_reg r600_context_reg_list[] = { {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280D0_CB_COLOR4_TILE, REG_FLAG_NEED_BO, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028110_CB_COLOR4_MASK, 0, 0, 0}, {0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0}, - {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028054_CB_COLOR5_BASE, REG_FLAG_NEED_BO, 0, 0}, + {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028054_CB_COLOR5_BASE, REG_FLAG_NEED_BO|REG_FLAG_RV6XX_SBU, SURFACE_BASE_UPDATE_COLOR(5), 0}, {0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280B4_CB_COLOR5_INFO, REG_FLAG_NEED_BO, 0, 0xFFFFFFFF}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028074_CB_COLOR5_SIZE, 0, 0, 0}, @@ -262,7 +272,7 @@ static const struct r600_reg r600_context_reg_list[] = { {0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280D4_CB_COLOR5_TILE, REG_FLAG_NEED_BO, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028114_CB_COLOR5_MASK, 0, 0, 0}, - {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028058_CB_COLOR6_BASE, REG_FLAG_NEED_BO, 0, 0}, + {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028058_CB_COLOR6_BASE, REG_FLAG_NEED_BO|REG_FLAG_RV6XX_SBU, SURFACE_BASE_UPDATE_COLOR(6), 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280B8_CB_COLOR6_INFO, REG_FLAG_NEED_BO, 0, 0xFFFFFFFF}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028078_CB_COLOR6_SIZE, 0, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028098_CB_COLOR6_VIEW, 0, 0, 0}, @@ -272,7 +282,7 @@ static const struct r600_reg r600_context_reg_list[] = { {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280D8_CB_COLOR6_TILE, REG_FLAG_NEED_BO, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028118_CB_COLOR6_MASK, 0, 0, 0}, {0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0}, - {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_02805C_CB_COLOR7_BASE, REG_FLAG_NEED_BO, 0, 0}, + {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_02805C_CB_COLOR7_BASE, REG_FLAG_NEED_BO|REG_FLAG_RV6XX_SBU, SURFACE_BASE_UPDATE_COLOR(7), 0}, {0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280BC_CB_COLOR7_INFO, REG_FLAG_NEED_BO, 0, 0xFFFFFFFF}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_02807C_CB_COLOR7_SIZE, 0, 0, 0}, @@ -327,7 +337,7 @@ static const struct r600_reg r600_context_reg_list[] = { {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028C48_PA_SC_AA_MASK, 0, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028D2C_DB_SRESULTS_COMPARE_STATE1, 0, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028D44_DB_ALPHA_TO_MASK, 0, 0, 0}, - {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_02800C_DB_DEPTH_BASE, REG_FLAG_NEED_BO, 0, 0}, + {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_02800C_DB_DEPTH_BASE, REG_FLAG_NEED_BO|REG_FLAG_RV6XX_SBU, SURFACE_BASE_UPDATE_DEPTH, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028000_DB_DEPTH_SIZE, 0, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028004_DB_DEPTH_VIEW, 0, 0, 0}, {0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0}, @@ -766,17 +776,6 @@ out_err: return r; } -static void rv6xx_context_surface_base_update(struct r600_context *ctx, - unsigned base_update_flags) -{ - /* need to emit surface base update on rv6xx */ - if ((ctx->radeon->family > CHIP_R600) && - (ctx->radeon->family < CHIP_RV770)) { - ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_SURFACE_BASE_UPDATE, 0, 0); - ctx->pm4[ctx->pm4_cdwords++] = base_update_flags; - } -} - /* Flushes all surfaces */ void r600_context_flush_all(struct r600_context *ctx, unsigned flush_flags) { @@ -798,19 +797,40 @@ void r600_context_bo_flush(struct r600_context *ctx, unsigned flush_flags, unsigned flush_mask, struct r600_bo *rbo) { struct radeon_bo *bo; - bo = r600_bo_get_bo(rbo); + + bo = rbo->bo; /* if bo has already been flushed */ if (!(~bo->last_flush & flush_flags)) { bo->last_flush &= flush_mask; return; } - ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_SURFACE_SYNC, 3, ctx->predicate_drawing); - ctx->pm4[ctx->pm4_cdwords++] = flush_flags; - ctx->pm4[ctx->pm4_cdwords++] = (bo->size + 255) >> 8; - ctx->pm4[ctx->pm4_cdwords++] = 0x00000000; - ctx->pm4[ctx->pm4_cdwords++] = 0x0000000A; - ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_NOP, 0, ctx->predicate_drawing); - ctx->pm4[ctx->pm4_cdwords++] = bo->reloc_id; + + if ((ctx->radeon->family < CHIP_RV770) && + (G_0085F0_CB_ACTION_ENA(flush_flags) || + G_0085F0_DB_ACTION_ENA(flush_flags))) { + if (ctx->flags & R600_CONTEXT_CHECK_EVENT_FLUSH) { + /* the rv670 seems to fail fbo-generatemipmap unless we flush the CB1 dest base ena */ + if (ctx->radeon->family == CHIP_RV670) { + ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_SURFACE_SYNC, 3, ctx->predicate_drawing); + ctx->pm4[ctx->pm4_cdwords++] = S_0085F0_CB1_DEST_BASE_ENA(1); /* CP_COHER_CNTL */ + ctx->pm4[ctx->pm4_cdwords++] = 0xffffffff; /* CP_COHER_SIZE */ + ctx->pm4[ctx->pm4_cdwords++] = 0; /* CP_COHER_BASE */ + ctx->pm4[ctx->pm4_cdwords++] = 0x0000000A; /* POLL_INTERVAL */ + } + + ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE, 0, ctx->predicate_drawing); + ctx->pm4[ctx->pm4_cdwords++] = EVENT_TYPE(EVENT_TYPE_CACHE_FLUSH_AND_INV_EVENT) | EVENT_INDEX(0); + ctx->flags &= ~R600_CONTEXT_CHECK_EVENT_FLUSH; + } + } else { + ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_SURFACE_SYNC, 3, ctx->predicate_drawing); + ctx->pm4[ctx->pm4_cdwords++] = flush_flags; + ctx->pm4[ctx->pm4_cdwords++] = (bo->size + 255) >> 8; + ctx->pm4[ctx->pm4_cdwords++] = 0x00000000; + ctx->pm4[ctx->pm4_cdwords++] = 0x0000000A; + ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_NOP, 0, ctx->predicate_drawing); + ctx->pm4[ctx->pm4_cdwords++] = bo->reloc_id; + } bo->last_flush = (bo->last_flush | flush_flags) & flush_mask; } @@ -818,7 +838,7 @@ void r600_context_bo_reloc(struct r600_context *ctx, u32 *pm4, struct r600_bo *r { struct radeon_bo *bo; - bo = r600_bo_get_bo(rbo); + bo = rbo->bo; assert(bo != NULL); if (bo->reloc) { *pm4 = bo->reloc_id; @@ -1120,6 +1140,7 @@ void r600_context_block_emit_dirty(struct r600_context *ctx, struct r600_block * goto out; } + ctx->flags |= R600_CONTEXT_CHECK_EVENT_FLUSH; for (int j = 0; j < block->nreg; j++) { if (block->pm4_bo_index[j]) { /* find relocation */ @@ -1135,6 +1156,7 @@ void r600_context_block_emit_dirty(struct r600_context *ctx, struct r600_block * } } } + ctx->flags &= ~R600_CONTEXT_CHECK_EVENT_FLUSH; memcpy(&ctx->pm4[ctx->pm4_cdwords], block->pm4, block->pm4_ndwords * 4); ctx->pm4_cdwords += block->pm4_ndwords; @@ -1158,6 +1180,7 @@ void r600_context_flush_dest_caches(struct r600_context *ctx) { struct r600_bo *cb[8]; struct r600_bo *db; + int i; if (!(ctx->flags & R600_CONTEXT_DST_CACHES_DIRTY)) return; @@ -1172,8 +1195,9 @@ void r600_context_flush_dest_caches(struct r600_context *ctx) cb[6] = r600_context_reg_bo(ctx, R_028058_CB_COLOR6_BASE); cb[7] = r600_context_reg_bo(ctx, R_02805C_CB_COLOR7_BASE); + ctx->flags |= R600_CONTEXT_CHECK_EVENT_FLUSH; /* flush the color buffers */ - for (int i = 0; i < 8; i++) { + for (i = 0; i < 8; i++) { if (!cb[i]) continue; @@ -1185,7 +1209,7 @@ void r600_context_flush_dest_caches(struct r600_context *ctx) if (db) { r600_context_bo_flush(ctx, S_0085F0_DB_ACTION_ENA(1), 0, db); } - + ctx->flags &= ~R600_CONTEXT_CHECK_EVENT_FLUSH; ctx->flags &= ~R600_CONTEXT_DST_CACHES_DIRTY; } @@ -1194,7 +1218,6 @@ void r600_context_draw(struct r600_context *ctx, const struct r600_draw *draw) unsigned ndwords = 7; struct r600_block *dirty_block = NULL; struct r600_block *next_block; - unsigned rv6xx_surface_base_update = 0; if (draw->indices) { ndwords = 11; @@ -1204,33 +1227,6 @@ void r600_context_draw(struct r600_context *ctx, const struct r600_draw *draw) } } - /* rv6xx surface base update */ - if ((ctx->radeon->family > CHIP_R600) && - (ctx->radeon->family < CHIP_RV770)) { - struct r600_bo *cb[8]; - struct r600_bo *db; - - db = r600_context_reg_bo(ctx, R_02800C_DB_DEPTH_BASE); - cb[0] = r600_context_reg_bo(ctx, R_028040_CB_COLOR0_BASE); - cb[1] = r600_context_reg_bo(ctx, R_028044_CB_COLOR1_BASE); - cb[2] = r600_context_reg_bo(ctx, R_028048_CB_COLOR2_BASE); - cb[3] = r600_context_reg_bo(ctx, R_02804C_CB_COLOR3_BASE); - cb[4] = r600_context_reg_bo(ctx, R_028050_CB_COLOR4_BASE); - cb[5] = r600_context_reg_bo(ctx, R_028054_CB_COLOR5_BASE); - cb[6] = r600_context_reg_bo(ctx, R_028058_CB_COLOR6_BASE); - cb[7] = r600_context_reg_bo(ctx, R_02805C_CB_COLOR7_BASE); - for (int i = 0; i < 8; i++) { - if (cb[i]) { - rv6xx_surface_base_update |= SURFACE_BASE_UPDATE_COLOR(i); - } - } - if (db) { - rv6xx_surface_base_update |= SURFACE_BASE_UPDATE_DEPTH; - } - } - - /* XXX also need to update SURFACE_BASE_UPDATE_STRMOUT when we support it */ - /* queries need some special values */ if (ctx->num_query_running) { if (ctx->radeon->family >= CHIP_RV770) { @@ -1263,10 +1259,6 @@ void r600_context_draw(struct r600_context *ctx, const struct r600_draw *draw) r600_context_block_emit_dirty(ctx, dirty_block); } - /* rv6xx surface base udpate */ - if (rv6xx_surface_base_update) - rv6xx_context_surface_base_update(ctx, rv6xx_surface_base_update); - /* draw packet */ ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_INDEX_TYPE, 0, ctx->predicate_drawing); ctx->pm4[ctx->pm4_cdwords++] = draw->vgt_index_type; diff --git a/src/gallium/winsys/r600/drm/r600_priv.h b/src/gallium/winsys/r600/drm/r600_priv.h index ed0f3e584d3..f8363f9272b 100644 --- a/src/gallium/winsys/r600/drm/r600_priv.h +++ b/src/gallium/winsys/r600/drm/r600_priv.h @@ -64,6 +64,7 @@ struct radeon { #define REG_FLAG_NEED_BO 1 #define REG_FLAG_DIRTY_ALWAYS 2 +#define REG_FLAG_RV6XX_SBU 4 struct r600_reg { unsigned opcode; @@ -202,24 +203,6 @@ static inline void radeon_bo_unmap(struct radeon *radeon, struct radeon_bo *bo) } /* - * r600_bo - */ -static inline struct radeon_bo *r600_bo_get_bo(struct r600_bo *bo) -{ - return bo->bo; -} - -static unsigned inline r600_bo_get_handle(struct r600_bo *bo) -{ - return bo->bo->handle; -} - -static unsigned inline r600_bo_get_size(struct r600_bo *bo) -{ - return bo->size; -} - -/* * fence */ static inline bool fence_is_after(unsigned fence, unsigned ofence) diff --git a/src/gallium/winsys/r600/drm/radeon_pciid.c b/src/gallium/winsys/r600/drm/radeon_pciid.c index 146d6bd3100..35db37aa1fd 100644 --- a/src/gallium/winsys/r600/drm/radeon_pciid.c +++ b/src/gallium/winsys/r600/drm/radeon_pciid.c @@ -177,6 +177,7 @@ static const struct pci_id radeon_pci_id[] = { {0x1002, 0x688A, CHIP_CYPRESS}, {0x1002, 0x6898, CHIP_CYPRESS}, {0x1002, 0x6899, CHIP_CYPRESS}, + {0x1002, 0x689b, CHIP_CYPRESS}, {0x1002, 0x689c, CHIP_HEMLOCK}, {0x1002, 0x689d, CHIP_HEMLOCK}, {0x1002, 0x689e, CHIP_CYPRESS}, @@ -187,7 +188,9 @@ static const struct pci_id radeon_pci_id[] = { {0x1002, 0x68b0, CHIP_JUNIPER}, {0x1002, 0x68b8, CHIP_JUNIPER}, {0x1002, 0x68b9, CHIP_JUNIPER}, + {0x1002, 0x68ba, CHIP_JUNIPER}, {0x1002, 0x68be, CHIP_JUNIPER}, + {0x1002, 0x68bf, CHIP_JUNIPER}, {0x1002, 0x68c0, CHIP_REDWOOD}, {0x1002, 0x68c1, CHIP_REDWOOD}, {0x1002, 0x68c8, CHIP_REDWOOD}, @@ -203,6 +206,7 @@ static const struct pci_id radeon_pci_id[] = { {0x1002, 0x68e8, CHIP_CEDAR}, {0x1002, 0x68e9, CHIP_CEDAR}, {0x1002, 0x68f1, CHIP_CEDAR}, + {0x1002, 0x68f2, CHIP_CEDAR}, {0x1002, 0x68f8, CHIP_CEDAR}, {0x1002, 0x68f9, CHIP_CEDAR}, {0x1002, 0x68fe, CHIP_CEDAR}, @@ -459,6 +463,7 @@ static const struct pci_id radeon_pci_id[] = { {0x1002, 0x6729, CHIP_BARTS}, {0x1002, 0x6738, CHIP_BARTS}, {0x1002, 0x6739, CHIP_BARTS}, + {0x1002, 0x673e, CHIP_BARTS}, {0x1002, 0x6740, CHIP_TURKS}, {0x1002, 0x6741, CHIP_TURKS}, {0x1002, 0x6742, CHIP_TURKS}, diff --git a/src/gallium/winsys/sw/Makefile b/src/gallium/winsys/sw/Makefile index 094e811d57d..2fad717eb16 100644 --- a/src/gallium/winsys/sw/Makefile +++ b/src/gallium/winsys/sw/Makefile @@ -14,6 +14,10 @@ ifneq ($(findstring fbdev, $(EGL_PLATFORMS)),) SUBDIRS += fbdev endif +ifneq ($(findstring wayland, $(EGL_PLATFORMS)),) +SUBDIRS += wayland +endif + default install clean: @for dir in $(SUBDIRS) ; do \ if [ -d $$dir ] ; then \ diff --git a/src/gallium/winsys/sw/wayland/Makefile b/src/gallium/winsys/sw/wayland/Makefile new file mode 100644 index 00000000000..b3f2081686e --- /dev/null +++ b/src/gallium/winsys/sw/wayland/Makefile @@ -0,0 +1,13 @@ +TOP = ../../../../.. +include $(TOP)/configs/current + +LIBNAME = ws_wayland + +LIBRARY_INCLUDES = $(WAYLAND_CFLAGS) + +LIBRARY_DEFINES = + +C_SOURCES = \ + wayland_sw_winsys.c + +include ../../../Makefile.template diff --git a/src/gallium/winsys/sw/wayland/wayland_sw_winsys.c b/src/gallium/winsys/sw/wayland/wayland_sw_winsys.c new file mode 100644 index 00000000000..1a31ada0296 --- /dev/null +++ b/src/gallium/winsys/sw/wayland/wayland_sw_winsys.c @@ -0,0 +1,285 @@ +/* + * Mesa 3-D graphics library + * Version: 7.11 + * + * Copyright (C) 2011 Benjamin Franzke <[email protected]> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include <stdlib.h> +#include <sys/types.h> +#include <sys/mman.h> +#include <unistd.h> + +#include "pipe/p_compiler.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" +#include "util/u_format.h" +#include "util/u_math.h" +#include "util/u_memory.h" +#include "state_tracker/sw_winsys.h" + +#include <wayland-client.h> +#include "wayland_sw_winsys.h" + +struct wayland_sw_displaytarget +{ + int fd; + unsigned size; + + unsigned width; + unsigned height; + unsigned stride; + + enum pipe_format format; + + void *map; + unsigned map_count; +}; + +struct wayland_sw_winsys +{ + struct sw_winsys base; + + struct wl_display *display; +}; + +static INLINE struct wayland_sw_displaytarget * +wayland_sw_displaytarget(struct sw_displaytarget *dt) +{ + return (struct wayland_sw_displaytarget *) dt; +} + +static INLINE struct wayland_sw_winsys * +wayland_sw_winsys(struct sw_winsys *ws) +{ + return (struct wayland_sw_winsys *) ws; +} + +static void +wayland_displaytarget_display(struct sw_winsys *ws, + struct sw_displaytarget *dt, + void *context_private) +{ +} + +static void +wayland_displaytarget_unmap(struct sw_winsys *ws, + struct sw_displaytarget *dt) +{ + struct wayland_sw_displaytarget *wldt = wayland_sw_displaytarget(dt); + + wldt->map_count--; + if (wldt->map_count > 0) + return; + + munmap(wldt->map, wldt->size); + wldt->map = NULL; +} + +static void * +wayland_displaytarget_map(struct sw_winsys *ws, + struct sw_displaytarget *dt, + unsigned flags) +{ + struct wayland_sw_displaytarget *wldt = wayland_sw_displaytarget(dt); + uint mmap_flags = 0; + + if (wldt->map) { + wldt->map_count++; + return wldt->map; + } + + if (flags & PIPE_TRANSFER_READ) + mmap_flags |= PROT_READ; + if (flags & PIPE_TRANSFER_WRITE) + mmap_flags |= PROT_WRITE; + + wldt->map = mmap(NULL, wldt->size, mmap_flags, + MAP_SHARED, wldt->fd, 0); + + if (wldt->map == MAP_FAILED) + return NULL; + + wldt->map_count = 1; + + return wldt->map; +} + +static void +wayland_displaytarget_destroy(struct sw_winsys *ws, + struct sw_displaytarget *dt) +{ + struct wayland_sw_displaytarget *wldt = wayland_sw_displaytarget(dt); + + if (wldt->map) + wayland_displaytarget_unmap(ws, dt); + + FREE(wldt); +} + +static boolean +wayland_is_displaytarget_format_supported(struct sw_winsys *ws, + unsigned tex_usage, + enum pipe_format format) +{ + switch (format) { + case PIPE_FORMAT_B8G8R8X8_UNORM: + case PIPE_FORMAT_B8G8R8A8_UNORM: + return TRUE; + default: + return FALSE; + } +} + +static struct sw_displaytarget * +wayland_displaytarget_create(struct sw_winsys *ws, + unsigned tex_usage, + enum pipe_format format, + unsigned width, unsigned height, + unsigned alignment, + unsigned *stride) +{ + struct wayland_sw_displaytarget *wldt; + unsigned nblocksy, format_stride; + char filename[] = "/tmp/wayland-shm-XXXXXX"; + + if (!wayland_is_displaytarget_format_supported(ws, tex_usage, format)) + return NULL; + + wldt = CALLOC_STRUCT(wayland_sw_displaytarget); + if (!wldt) + return NULL; + + wldt->map = NULL; + + wldt->format = format; + wldt->width = width; + wldt->height = height; + + format_stride = util_format_get_stride(format, width); + wldt->stride = align(format_stride, alignment); + + nblocksy = util_format_get_nblocksy(format, height); + wldt->size = wldt->stride * nblocksy; + + wldt->fd = mkstemp(filename); + if (wldt->fd < 0) { + FREE(wldt); + return NULL; + } + + if (ftruncate(wldt->fd, wldt->size) < 0) { + unlink(filename); + close(wldt->fd); + FREE(wldt); + return NULL; + } + + unlink(filename); + + *stride = wldt->stride; + + return (struct sw_displaytarget *) wldt; +} + +static struct sw_displaytarget * +wayland_displaytarget_from_handle(struct sw_winsys *ws, + const struct pipe_resource *templet, + struct winsys_handle *whandle, + unsigned *stride) +{ + struct wayland_sw_displaytarget *wldt; + unsigned nblocksy; + + if (!wayland_is_displaytarget_format_supported(ws, 0, templet->format)) + return NULL; + + wldt = CALLOC_STRUCT(wayland_sw_displaytarget); + if (!wldt) + return NULL; + + wldt->fd = whandle->fd; + wldt->stride = whandle->stride; + wldt->width = templet->width0; + wldt->height = templet->height0; + wldt->format = templet->format; + + nblocksy = util_format_get_nblocksy(wldt->format, wldt->height); + + wldt->size = wldt->stride * nblocksy; + + wldt->map = NULL; + + *stride = wldt->stride; + + return (struct sw_displaytarget *) wldt; +} + + +static boolean +wayland_displaytarget_get_handle(struct sw_winsys *ws, + struct sw_displaytarget *dt, + struct winsys_handle *whandle) +{ + struct wayland_sw_displaytarget *wldt = wayland_sw_displaytarget(dt); + + whandle->fd = wldt->fd; + whandle->stride = wldt->stride; + + return TRUE; +} + +static void +wayland_destroy(struct sw_winsys *ws) +{ + struct wayland_sw_winsys *wayland = wayland_sw_winsys(ws); + + FREE(wayland); +} + +struct sw_winsys * +wayland_create_sw_winsys(struct wl_display *display) +{ + struct wayland_sw_winsys *wlws; + + wlws = CALLOC_STRUCT(wayland_sw_winsys); + if (!wlws) + return NULL; + + wlws->display = display; + + wlws->base.destroy = wayland_destroy; + wlws->base.is_displaytarget_format_supported = + wayland_is_displaytarget_format_supported; + + wlws->base.displaytarget_create = wayland_displaytarget_create; + wlws->base.displaytarget_from_handle = wayland_displaytarget_from_handle; + wlws->base.displaytarget_get_handle = wayland_displaytarget_get_handle; + wlws->base.displaytarget_destroy = wayland_displaytarget_destroy; + wlws->base.displaytarget_map = wayland_displaytarget_map; + wlws->base.displaytarget_unmap = wayland_displaytarget_unmap; + + wlws->base.displaytarget_display = wayland_displaytarget_display; + + return &wlws->base; +} + +/* vim: set sw=3 ts=8 sts=3 expandtab: */ diff --git a/src/gallium/winsys/sw/wayland/wayland_sw_winsys.h b/src/gallium/winsys/sw/wayland/wayland_sw_winsys.h new file mode 100644 index 00000000000..5e3cfd0bf23 --- /dev/null +++ b/src/gallium/winsys/sw/wayland/wayland_sw_winsys.h @@ -0,0 +1,41 @@ +/* + * Mesa 3-D graphics library + * Version: 7.11 + * + * Copyright (C) 2011 Benjamin Franzke <[email protected]> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef WAYLAND_SW_WINSYS +#define WAYLAND_SW_WINSYS + +struct sw_winsys; + +struct winsys_handle { + int fd; + unsigned stride; +}; + +struct sw_winsys * +wayland_create_sw_winsys(struct wl_display *display); + +#endif /* WAYLAND_SW_WINSYS */ + +/* vim: set sw=3 ts=8 sts=3 expandtab: */ |