#define FILE_DEBUG_FLAG DEBUG_MIPTREE
+
+
+static GLuint translate_tex_target( unsigned target )
+{
+ switch (target) {
+ case PIPE_TEXTURE_1D:
+ return BRW_SURFACE_1D;
+
+ case PIPE_TEXTURE_2D:
+ return BRW_SURFACE_2D;
+
+ case PIPE_TEXTURE_3D:
+ return BRW_SURFACE_3D;
+
+ case PIPE_TEXTURE_CUBE:
+ return BRW_SURFACE_CUBE;
+
+ default:
+ assert(0);
+ return BRW_SURFACE_1D;
+ }
+}
+
+
+static GLuint translate_tex_format( enum pipe_format pf )
+{
+ switch( pf ) {
+ case PIPE_FORMAT_L8_UNORM:
+ return BRW_SURFACEFORMAT_L8_UNORM;
+
+ case PIPE_FORMAT_I8_UNORM:
+ return BRW_SURFACEFORMAT_I8_UNORM;
+
+ case PIPE_FORMAT_A8_UNORM:
+ return BRW_SURFACEFORMAT_A8_UNORM;
+
+ case PIPE_FORMAT_A8L8_UNORM:
+ return BRW_SURFACEFORMAT_L8A8_UNORM;
+
+ case PIPE_FORMAT_A8R8G8B8_UNORM: /* XXX */
+ case PIPE_FORMAT_B8G8R8A8_UNORM: /* XXX */
+ case PIPE_FORMAT_R8G8B8A8_UNORM: /* XXX */
+ return BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
+
+ case PIPE_FORMAT_R8G8B8X8_UNORM:
+ return BRW_SURFACEFORMAT_R8G8B8X8_UNORM;
+
+ case PIPE_FORMAT_R5G6B5_UNORM:
+ return BRW_SURFACEFORMAT_B5G6R5_UNORM;
+
+ case PIPE_FORMAT_A1R5G5B5_UNORM:
+ return BRW_SURFACEFORMAT_B5G5R5A1_UNORM;
+
+ case PIPE_FORMAT_A4R4G4B4_UNORM:
+ return BRW_SURFACEFORMAT_B4G4R4A4_UNORM;
+
+
+ case PIPE_FORMAT_L16_UNORM:
+ return BRW_SURFACEFORMAT_L16_UNORM;
+
+ /* XXX: Z texturing:
+ case PIPE_FORMAT_I16_UNORM:
+ return BRW_SURFACEFORMAT_I16_UNORM;
+ */
+
+ /* XXX: Z texturing:
+ case PIPE_FORMAT_A16_UNORM:
+ return BRW_SURFACEFORMAT_A16_UNORM;
+ */
+
+ case PIPE_FORMAT_YCBCR_REV:
+ return BRW_SURFACEFORMAT_YCRCB_NORMAL;
+
+ case PIPE_FORMAT_YCBCR:
+ return BRW_SURFACEFORMAT_YCRCB_SWAPUVY;
+
+ /* XXX: Add FXT to gallium?
+ case PIPE_FORMAT_FXT1_RGBA:
+ return BRW_SURFACEFORMAT_FXT1;
+ */
+
+ case PIPE_FORMAT_DXT1_RGB:
+ return BRW_SURFACEFORMAT_DXT1_RGB;
+
+ case PIPE_FORMAT_DXT1_RGBA:
+ return BRW_SURFACEFORMAT_BC1_UNORM;
+
+ case PIPE_FORMAT_DXT3_RGBA:
+ return BRW_SURFACEFORMAT_BC2_UNORM;
+
+ case PIPE_FORMAT_DXT5_RGBA:
+ return BRW_SURFACEFORMAT_BC3_UNORM;
+
+ case PIPE_FORMAT_R8G8B8A8_SRGB:
+ return BRW_SURFACEFORMAT_B8G8R8A8_UNORM_SRGB;
+
+ case PIPE_FORMAT_A8L8_SRGB:
+ return BRW_SURFACEFORMAT_L8A8_UNORM_SRGB;
+
+ case PIPE_FORMAT_L8_SRGB:
+ return BRW_SURFACEFORMAT_L8_UNORM_SRGB;
+
+ case PIPE_FORMAT_DXT1_SRGB:
+ return BRW_SURFACEFORMAT_BC1_UNORM_SRGB;
+
+ /* XXX: which pipe depth formats does i965 suppport
+ */
+ case PIPE_FORMAT_S8Z24_UNORM:
+ case PIPE_FORMAT_X8Z24_UNORM:
+ case PIPE_FORMAT_Z24S8_UNORM:
+ case PIPE_FORMAT_Z24X8_UNORM:
+ return BRW_SURFACEFORMAT_I24X8_UNORM;
+
+#if 0
+ /* XXX: these different surface formats don't seem to
+ * make any difference for shadow sampler/compares.
+ */
+ if (depth_mode == GL_INTENSITY)
+ return BRW_SURFACEFORMAT_I24X8_UNORM;
+ else if (depth_mode == GL_ALPHA)
+ return BRW_SURFACEFORMAT_A24X8_UNORM;
+ else
+ return BRW_SURFACEFORMAT_L24X8_UNORM;
+#endif
+
+ /* XXX: presumably for bump mapping. Add this to mesa state
+ * tracker?
+ */
+ case PIPE_FORMAT_R8G8_SNORM:
+ return BRW_SURFACEFORMAT_R8G8_SNORM;
+
+ case PIPE_FORMAT_R8G8B8A8_SNORM:
+ return BRW_SURFACEFORMAT_R8G8B8A8_SNORM;
+
+ default:
+ assert(0);
+ return 0;
+ }
+}
+
+static void
+brw_set_surface_tiling(struct brw_surface_state *surf, uint32_t tiling)
+{
+ switch (tiling) {
+ case BRW_TILING_NONE:
+ surf->ss3.tiled_surface = 0;
+ surf->ss3.tile_walk = 0;
+ break;
+ case BRW_TILING_X:
+ surf->ss3.tiled_surface = 1;
+ surf->ss3.tile_walk = BRW_TILEWALK_XMAJOR;
+ break;
+ case BRW_TILING_Y:
+ surf->ss3.tiled_surface = 1;
+ surf->ss3.tile_walk = BRW_TILEWALK_YMAJOR;
+ break;
+ }
+}
+
+
GLboolean brw_miptree_layout(struct brw_context *brw,
struct intel_mipmap_tree *mt,
uint32_t tiling)
return GL_TRUE;
}
+
+static void brw_create_texture( struct pipe_screen *screen,
+ const pipe_texture *templ )
+
+{
+
+ key.format = tex->base.format;
+ key.pitch = tex->pitch;
+ key.depth = tex->base.depth[0];
+ key.bo = tex->buffer;
+ key.offset = 0;
+
+ key.target = tex->brw_target; /* translated to BRW enum */
+ //key.depthmode = 0; /* XXX: add this to gallium? or the state tracker? */
+ key.last_level = tex->base.last_level;
+ key.width = tex->base.depth[0];
+ key.height = tex->base.height[0];
+ key.cpp = tex->cpp;
+ key.tiling = tex->tiling;
+
+
+
+ surf.ss0.mipmap_layout_mode = BRW_SURFACE_MIPMAPLAYOUT_BELOW;
+ surf.ss0.surface_type = translate_tex_target(key->target);
+ surf.ss0.surface_format = translate_tex_format(key->format /* , key->depthmode */ );
+
+ /* This is ok for all textures with channel width 8bit or less:
+ */
+/* surf.ss0.data_return_format = BRW_SURFACERETURNFORMAT_S1; */
+ assert(key->bo);
+ surf.ss1.base_addr = key->bo->offset; /* reloc */
+ surf.ss2.mip_count = key->last_level;
+ surf.ss2.width = key->width - 1;
+ surf.ss2.height = key->height - 1;
+ brw_set_surface_tiling(&surf, key->tiling);
+ surf.ss3.pitch = (key->pitch * key->cpp) - 1;
+ surf.ss3.depth = key->depth - 1;
+
+ surf.ss4.min_lod = 0;
+
+ if (key->target == PIPE_TEXTURE_CUBE) {
+ surf.ss0.cube_pos_x = 1;
+ surf.ss0.cube_pos_y = 1;
+ surf.ss0.cube_pos_z = 1;
+ surf.ss0.cube_neg_x = 1;
+ surf.ss0.cube_neg_y = 1;
+ surf.ss0.cube_neg_z = 1;
+ }
+
+}
+
+
+
+
+
* Keith Whitwell <keith@tungstengraphics.com>
*/
+#include "pipe/p_format.h"
#include "brw_batchbuffer.h"
#include "brw_context.h"
#include "brw_state.h"
#include "brw_defines.h"
+#include "brw_screen.h"
-static GLuint translate_tex_target( GLenum target )
-{
- switch (target) {
- case GL_TEXTURE_1D:
- return BRW_SURFACE_1D;
-
- case GL_TEXTURE_RECTANGLE_NV:
- return BRW_SURFACE_2D;
-
- case GL_TEXTURE_2D:
- return BRW_SURFACE_2D;
-
- case GL_TEXTURE_3D:
- return BRW_SURFACE_3D;
-
- case GL_TEXTURE_CUBE_MAP:
- return BRW_SURFACE_CUBE;
-
- default:
- assert(0);
- return 0;
- }
-}
-
-
-static GLuint translate_tex_format( GLuint mesa_format,
- GLenum depth_mode )
-{
- switch( pipe_format ) {
- case PIPE_FORMAT_L8_UNORM:
- return BRW_SURFACEFORMAT_L8_UNORM;
-
- case PIPE_FORMAT_I8_UNORM:
- return BRW_SURFACEFORMAT_I8_UNORM;
-
- case PIPE_FORMAT_A8_UNORM:
- return BRW_SURFACEFORMAT_A8_UNORM;
-
- case PIPE_FORMAT_A8L8_UNORM:
- return BRW_SURFACEFORMAT_L8A8_UNORM;
-
- case PIPE_FORMAT_A8R8G8B8_UNORM:
- case PIPE_FORMAT_B8G8R8A8_UNORM:
- case PIPE_FORMAT_R8G8B8A8_UNORM:
- return BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
-
- case PIPE_FORMAT_R8G8B8X8_UNORM:
- return BRW_SURFACEFORMAT_R8G8B8X8_UNORM;
-
- case PIPE_FORMAT_:
- return BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
- case PIPE_FORMAT_RGB565:
- return BRW_SURFACEFORMAT_B5G6R5_UNORM;
-
- case PIPE_FORMAT_ARGB1555:
- return BRW_SURFACEFORMAT_B5G5R5A1_UNORM;
-
- case PIPE_FORMAT_ARGB4444:
- return BRW_SURFACEFORMAT_B4G4R4A4_UNORM;
-
-
- case PIPE_FORMAT_L16_UNORM:
- return BRW_SURFACEFORMAT_L16_UNORM;
-
- case PIPE_FORMAT_I16_UNORM:
- return BRW_SURFACEFORMAT_I16_UNORM;
-
- case PIPE_FORMAT_A16_UNORM:
- return BRW_SURFACEFORMAT_A16_UNORM;
-
- case PIPE_FORMAT_YCBCR_REV:
- return BRW_SURFACEFORMAT_YCRCB_NORMAL;
-
- case PIPE_FORMAT_YCBCR:
- return BRW_SURFACEFORMAT_YCRCB_SWAPUVY;
-
- case PIPE_FORMAT_RGB_FXT1:
- case PIPE_FORMAT_RGBA_FXT1:
- return BRW_SURFACEFORMAT_FXT1;
-
- case PIPE_FORMAT_RGB_DXT1:
- return BRW_SURFACEFORMAT_DXT1_RGB;
-
- case PIPE_FORMAT_RGBA_DXT1:
- return BRW_SURFACEFORMAT_BC1_UNORM;
-
- case PIPE_FORMAT_RGBA_DXT3:
- return BRW_SURFACEFORMAT_BC2_UNORM;
-
- case PIPE_FORMAT_RGBA_DXT5:
- return BRW_SURFACEFORMAT_BC3_UNORM;
-
- case PIPE_FORMAT_R8G8B8A8_SRGB:
- return BRW_SURFACEFORMAT_B8G8R8A8_UNORM_SRGB;
-
- case PIPE_FORMAT_A8L8_SRGB:
- return BRW_SURFACEFORMAT_L8A8_UNORM_SRGB;
-
- case PIPE_FORMAT_L8_SRGB:
- return BRW_SURFACEFORMAT_L8_UNORM_SRGB;
-
- case PIPE_FORMAT_SRGB_DXT1:
- return BRW_SURFACEFORMAT_BC1_UNORM_SRGB;
-
- case PIPE_FORMAT_S8_Z24:
- /* XXX: these different surface formats don't seem to
- * make any difference for shadow sampler/compares.
- */
- if (depth_mode == GL_INTENSITY)
- return BRW_SURFACEFORMAT_I24X8_UNORM;
- else if (depth_mode == GL_ALPHA)
- return BRW_SURFACEFORMAT_A24X8_UNORM;
- else
- return BRW_SURFACEFORMAT_L24X8_UNORM;
-
- case PIPE_FORMAT_DUDV8:
- return BRW_SURFACEFORMAT_R8G8_SNORM;
-
- case PIPE_FORMAT_SIGNED_RGBA8888_REV:
- return BRW_SURFACEFORMAT_R8G8B8A8_SNORM;
-
- default:
- assert(0);
- return 0;
- }
-}
-
-static void
-brw_set_surface_tiling(struct brw_surface_state *surf, uint32_t tiling)
-{
- switch (tiling) {
- case I915_TILING_NONE:
- surf->ss3.tiled_surface = 0;
- surf->ss3.tile_walk = 0;
- break;
- case I915_TILING_X:
- surf->ss3.tiled_surface = 1;
- surf->ss3.tile_walk = BRW_TILEWALK_XMAJOR;
- break;
- case I915_TILING_Y:
- surf->ss3.tiled_surface = 1;
- surf->ss3.tile_walk = BRW_TILEWALK_YMAJOR;
- break;
- }
-}
-
-static struct brw_winsys_buffer *
-brw_create_texture_surface( struct brw_context *brw,
- struct brw_surface_key *key )
-{
- struct brw_surface_state surf;
- struct brw_winsys_buffer *bo;
-
- memset(&surf, 0, sizeof(surf));
-
- surf.ss0.mipmap_layout_mode = BRW_SURFACE_MIPMAPLAYOUT_BELOW;
- surf.ss0.surface_type = translate_tex_target(key->target);
- if (key->bo) {
- surf.ss0.surface_format = translate_tex_format(key->format,
- key->internal_format,
- key->depthmode);
- }
- else {
- switch (key->depth) {
- case 32:
- surf.ss0.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
- break;
- default:
- case 24:
- surf.ss0.surface_format = BRW_SURFACEFORMAT_B8G8R8X8_UNORM;
- break;
- case 16:
- surf.ss0.surface_format = BRW_SURFACEFORMAT_B5G6R5_UNORM;
- break;
- }
- }
-
- /* This is ok for all textures with channel width 8bit or less:
- */
-/* surf.ss0.data_return_format = BRW_SURFACERETURNFORMAT_S1; */
- if (key->bo)
- surf.ss1.base_addr = key->bo->offset; /* reloc */
- else
- surf.ss1.base_addr = key->offset;
-
- surf.ss2.mip_count = key->last_level;
- surf.ss2.width = key->width - 1;
- surf.ss2.height = key->height - 1;
- brw_set_surface_tiling(&surf, key->tiling);
- surf.ss3.pitch = (key->pitch * key->cpp) - 1;
- surf.ss3.depth = key->depth - 1;
-
- surf.ss4.min_lod = 0;
-
- if (key->target == GL_TEXTURE_CUBE_MAP) {
- surf.ss0.cube_pos_x = 1;
- surf.ss0.cube_pos_y = 1;
- surf.ss0.cube_pos_z = 1;
- surf.ss0.cube_neg_x = 1;
- surf.ss0.cube_neg_y = 1;
- surf.ss0.cube_neg_z = 1;
- }
-
- bo = brw_upload_cache(&brw->surface_cache, BRW_SS_SURFACE,
- key, sizeof(*key),
- &key->bo, key->bo ? 1 : 0,
- &surf, sizeof(surf),
- NULL, NULL);
-
- if (key->bo) {
- /* Emit relocation to surface contents */
- dri_bo_emit_reloc(bo,
- I915_GEM_DOMAIN_SAMPLER, 0,
- 0,
- offsetof(struct brw_surface_state, ss1),
- key->bo);
- }
- return bo;
-}
static void
-brw_update_texture_surface( struct brw_context *brw, GLuint unit )
+brw_update_texture_surface( struct brw_context *brw,
+ struct brw_texture *tex,
+ GLuint surf )
{
- struct pipe_texture *tex = brw->texture[unit];
- struct brw_surface_key key;
- const GLuint surf = SURF_INDEX_TEXTURE(unit);
-
- memset(&key, 0, sizeof(key));
-
- key.format = tex->base.format;
- key.pitch = tex->pitch;
- key.depth = tex->base.depth[0];
- key.bo = tex->buffer;
- key.offset = 0;
-
- key.target = tObj->target; /* translated to BRW enum */
- /* key.depthmode = tObj->DepthMode; */ /* XXX: add this to gallium? or the state tracker? */
- key.first_level = 0;
- key.last_level = tex->base.last_level;
- key.width = tex->base.depth[0];
- key.height = tex->base.height[0];
- key.cpp = tex->cpp;
- key.tiling = tex->tiling;
-
- brw->sws->bo_unreference(brw->wm.surf_bo[surf]);
brw->wm.surf_bo[surf] = brw_search_cache(&brw->surface_cache,
BRW_SS_SURFACE,
- &key, sizeof(key),
- &key.bo, key.bo ? 1 : 0,
+ &tex->ss, sizeof tex->ss,
+ &tex->bo, 1,
NULL);
- if (brw->wm.surf_bo[surf] == NULL) {
- brw->wm.surf_bo[surf] = brw_create_texture_surface(brw, &key);
- }
-}
-
-
-
-/**
- * Create the constant buffer surface. Vertex/fragment shader constants will be
- * read from this buffer with Data Port Read instructions/messages.
- */
-struct brw_winsys_buffer *
-brw_create_constant_surface( struct brw_context *brw,
- struct brw_surface_key *key )
-{
- const GLint w = key->width - 1;
- struct brw_surface_state surf;
- struct brw_winsys_buffer *bo;
-
- memset(&surf, 0, sizeof(surf));
-
- surf.ss0.mipmap_layout_mode = BRW_SURFACE_MIPMAPLAYOUT_BELOW;
- surf.ss0.surface_type = BRW_SURFACE_BUFFER;
- surf.ss0.surface_format = BRW_SURFACEFORMAT_R32G32B32A32_FLOAT;
-
- assert(key->bo);
- if (key->bo)
- surf.ss1.base_addr = key->bo->offset; /* reloc */
- else
- surf.ss1.base_addr = key->offset;
-
- surf.ss2.width = w & 0x7f; /* bits 6:0 of size or width */
- surf.ss2.height = (w >> 7) & 0x1fff; /* bits 19:7 of size or width */
- surf.ss3.depth = (w >> 20) & 0x7f; /* bits 26:20 of size or width */
- surf.ss3.pitch = (key->pitch * key->cpp) - 1; /* ignored?? */
- brw_set_surface_tiling(&surf, key->tiling); /* tiling now allowed */
-
- bo = brw_upload_cache(&brw->surface_cache, BRW_SS_SURFACE,
- key, sizeof(*key),
- &key->bo, key->bo ? 1 : 0,
- &surf, sizeof(surf),
- NULL, NULL);
- if (key->bo) {
+ if (brw->wm.surf_bo[surf] == NULL) {
+ brw->wm.surf_bo[surf] = brw_upload_cache(&brw->surface_cache, BRW_SS_SURFACE,
+ &tex->ss, sizeof tex->ss,
+ &tex->bo, 1,
+ &tex->ss, sizeof tex->ss,
+ NULL, NULL);
+
/* Emit relocation to surface contents */
- dri_bo_emit_reloc(bo,
- I915_GEM_DOMAIN_SAMPLER, 0,
- 0,
- offsetof(struct brw_surface_state, ss1),
- key->bo);
+ brw->sws->bo_emit_reloc(brw->wm.surf_bo[surf],
+ I915_GEM_DOMAIN_SAMPLER, 0,
+ 0,
+ offsetof(struct brw_surface_state, ss1),
+ tex->bo);
}
-
- return bo;
}
-/* Creates a new WM constant buffer reflecting the current fragment program's
- * constants, if needed by the fragment program.
- *
- * Otherwise, constants go through the CURBEs using the brw_constant_buffer
- * state atom.
- */
-static drm_intel_bo *
-brw_wm_update_constant_buffer(struct brw_context *brw)
-{
- struct brw_fragment_program *fp =
- (struct brw_fragment_program *) brw->fragment_program;
- const struct gl_program_parameter_list *params = fp->program.Base.Parameters;
- const int size = params->NumParameters * 4 * sizeof(GLfloat);
- drm_intel_bo *const_buffer;
- /* BRW_NEW_FRAGMENT_PROGRAM */
- if (!fp->use_const_buffer)
- return NULL;
- const_buffer = drm_intel_bo_alloc(intel->bufmgr,
- BRW_BUFFER_TYPE_SHADER_CONSTANTS,
- size, 64);
- /* _NEW_PROGRAM_CONSTANTS */
- dri_bo_subdata(const_buffer, 0, size, params->ParameterValues);
- return const_buffer;
-}
-/**
- * Update the surface state for a WM constant buffer.
- * The constant buffer will be (re)allocated here if needed.
- */
-static void
-brw_update_wm_constant_surface( struct brw_context *brw,
- GLuint surf)
-{
- struct brw_context *brw = brw_context(ctx);
- struct brw_surface_key key;
- struct brw_fragment_program *fp =
- (struct brw_fragment_program *) brw->fragment_program;
- const struct gl_program_parameter_list *params =
- fp->program.Base.Parameters;
-
- /* If we're in this state update atom, we need to update WM constants, so
- * free the old buffer and create a new one for the new contents.
- */
- brw->sws->bo_unreference(fp->const_buffer);
- fp->const_buffer = brw_wm_update_constant_buffer(brw);
-
- /* If there's no constant buffer, then no surface BO is needed to point at
- * it.
- */
- if (fp->const_buffer == 0) {
- drm_intel_bo_unreference(brw->wm.surf_bo[surf]);
- brw->wm.surf_bo[surf] = NULL;
- return;
- }
-
- memset(&key, 0, sizeof(key));
-
- key.format = PIPE_FORMAT_RGBA_FLOAT32;
- key.internal_format = GL_RGBA;
- key.bo = fp->const_buffer;
- key.depthmode = GL_NONE;
- key.pitch = params->NumParameters;
- key.width = params->NumParameters;
- key.height = 1;
- key.depth = 1;
- key.cpp = 16;
-
- /*
- printf("%s:\n", __FUNCTION__);
- printf(" width %d height %d depth %d cpp %d pitch %d\n",
- key.width, key.height, key.depth, key.cpp, key.pitch);
- */
-
- brw->sws->bo_unreference(brw->wm.surf_bo[surf]);
- brw->wm.surf_bo[surf] = brw_search_cache(&brw->surface_cache,
- BRW_SS_SURFACE,
- &key, sizeof(key),
- &key.bo, key.bo ? 1 : 0,
- NULL);
- if (brw->wm.surf_bo[surf] == NULL) {
- brw->wm.surf_bo[surf] = brw_create_constant_surface(brw, &key);
- }
- brw->state.dirty.brw |= BRW_NEW_WM_SURFACES;
-}
-
-/**
- * Updates surface / buffer for fragment shader constant buffer, if
- * one is required.
- *
- * This consumes the state updates for the constant buffer, and produces
- * BRW_NEW_WM_SURFACES to get picked up by brw_prepare_wm_surfaces for
- * inclusion in the binding table.
- */
-static void prepare_wm_constant_surface(struct brw_context *brw )
-{
- struct brw_fragment_program *fp =
- (struct brw_fragment_program *) brw->fragment_program;
- GLuint surf = SURF_INDEX_FRAG_CONST_BUFFER;
-
- drm_intel_bo_unreference(fp->const_buffer);
- fp->const_buffer = brw_wm_update_constant_buffer(brw);
-
- /* If there's no constant buffer, then no surface BO is needed to point at
- * it.
- */
- if (fp->const_buffer == 0) {
- if (brw->wm.surf_bo[surf] != NULL) {
- drm_intel_bo_unreference(brw->wm.surf_bo[surf]);
- brw->wm.surf_bo[surf] = NULL;
- brw->state.dirty.brw |= BRW_NEW_WM_SURFACES;
- }
- return;
- }
-
- brw_update_wm_constant_surface(ctx, surf);
-}
-
-const struct brw_tracked_state brw_wm_constant_surface = {
- .dirty = {
- .mesa = (_NEW_PROGRAM_CONSTANTS),
- .brw = (BRW_NEW_FRAGMENT_PROGRAM),
- .cache = 0
- },
- .prepare = prepare_wm_constant_surface,
-};
/**
*/
static void
brw_update_renderbuffer_surface(struct brw_context *brw,
- struct gl_renderbuffer *rb,
+ struct brw_surface *surface,
unsigned int unit)
{
- struct brw_winsys_buffer *region_bo = NULL;
- struct intel_renderbuffer *irb = intel_renderbuffer(rb);
- struct intel_region *region = irb ? irb->region : NULL;
- struct {
- unsigned int surface_type;
- unsigned int surface_format;
- unsigned int width, height, pitch, cpp;
- GLubyte color_mask[4];
- GLboolean color_blend;
- uint32_t tiling;
- uint32_t draw_offset;
- } key;
-
- memset(&key, 0, sizeof(key));
-
- if (region != NULL) {
- region_bo = region->buffer;
-
- key.surface_type = BRW_SURFACE_2D;
- switch (irb->texformat->MesaFormat) {
- case PIPE_FORMAT_ARGB8888:
- key.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
- break;
- case PIPE_FORMAT_RGB565:
- key.surface_format = BRW_SURFACEFORMAT_B5G6R5_UNORM;
- break;
- case PIPE_FORMAT_ARGB1555:
- key.surface_format = BRW_SURFACEFORMAT_B5G5R5A1_UNORM;
- break;
- case PIPE_FORMAT_ARGB4444:
- key.surface_format = BRW_SURFACEFORMAT_B4G4R4A4_UNORM;
- break;
- default:
- debug_printf("Bad renderbuffer format: %d\n",
- irb->texformat->MesaFormat);
- assert(0);
- key.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
- return;
- }
- key.tiling = region->tiling;
- if (brw->intel.intelScreen->driScrnPriv->dri2.enabled) {
- key.width = rb->Width;
- key.height = rb->Height;
- } else {
- key.width = region->width;
- key.height = region->height;
- }
- key.pitch = region->pitch;
- key.cpp = region->cpp;
- key.draw_offset = region->draw_offset; /* cur 3d or cube face offset */
- } else {
- key.surface_type = BRW_SURFACE_NULL;
- key.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
- key.tiling = I915_TILING_X;
- key.width = 1;
- key.height = 1;
- key.cpp = 4;
- key.draw_offset = 0;
- }
- memcpy(key.color_mask, ctx->Color.ColorMask,
- sizeof(key.color_mask));
- key.color_blend = (!ctx->Color._LogicOpEnabled &&
- ctx->Color.BlendEnabled);
+ struct brw_surf_ss0 blend_ss0 = brw->curr.blend->ss0;
+ struct brw_surface_state ss;
+
+ /* Surfaces are potentially shared between contexts, so can't
+ * scribble the in-place ss0 value in the surface.
+ */
+ memcpy(&ss, &surface->ss, sizeof ss);
+
+ ss.ss0.color_blend = blend_ss0.color_blend;
+ ss.ss0.writedisable_blue = blend_ss0.writedisable_blue;
+ ss.ss0.writedisable_green = blend_ss0.writedisable_green;
+ ss.ss0.writedisable_red = blend_ss0.writedisable_red;
+ ss.ss0.writedisable_alpha = blend_ss0.writedisable_alpha;
brw->sws->bo_unreference(brw->wm.surf_bo[unit]);
brw->wm.surf_bo[unit] = brw_search_cache(&brw->surface_cache,
BRW_SS_SURFACE,
- &key, sizeof(key),
- ®ion_bo, 1,
+ &ss, sizeof(ss),
+ &surface->bo, 1,
NULL);
if (brw->wm.surf_bo[unit] == NULL) {
- struct brw_surface_state surf;
-
- memset(&surf, 0, sizeof(surf));
-
- surf.ss0.surface_format = key.surface_format;
- surf.ss0.surface_type = key.surface_type;
- if (key.tiling == I915_TILING_NONE) {
- surf.ss1.base_addr = key.draw_offset;
- } else {
- uint32_t tile_offset = key.draw_offset % 4096;
-
- surf.ss1.base_addr = key.draw_offset - tile_offset;
-
- assert(BRW_IS_G4X(brw) || tile_offset == 0);
- if (BRW_IS_G4X(brw)) {
- if (key.tiling == I915_TILING_X) {
- /* Note that the low bits of these fields are missing, so
- * there's the possibility of getting in trouble.
- */
- surf.ss5.x_offset = (tile_offset % 512) / key.cpp / 4;
- surf.ss5.y_offset = tile_offset / 512 / 2;
- } else {
- surf.ss5.x_offset = (tile_offset % 128) / key.cpp / 4;
- surf.ss5.y_offset = tile_offset / 128 / 2;
- }
- }
- }
- if (region_bo != NULL)
- surf.ss1.base_addr += region_bo->offset; /* reloc */
-
- surf.ss2.width = key.width - 1;
- surf.ss2.height = key.height - 1;
- brw_set_surface_tiling(&surf, key.tiling);
- surf.ss3.pitch = (key.pitch * key.cpp) - 1;
-
- /* _NEW_COLOR */
- surf.ss0.color_blend = key.color_blend;
- surf.ss0.writedisable_red = !key.color_mask[0];
- surf.ss0.writedisable_green = !key.color_mask[1];
- surf.ss0.writedisable_blue = !key.color_mask[2];
- surf.ss0.writedisable_alpha = !key.color_mask[3];
-
- /* Key size will never match key size for textures, so we're safe. */
+
brw->wm.surf_bo[unit] = brw_upload_cache(&brw->surface_cache,
BRW_SS_SURFACE,
- &key, sizeof(key),
- ®ion_bo, 1,
- &surf, sizeof(surf),
+ &ss, sizeof ss,
+ &surface->bo, 1,
+ &ss, sizeof ss,
NULL, NULL);
- if (region_bo != NULL) {
- /* We might sample from it, and we might render to it, so flag
- * them both. We might be able to figure out from other state
- * a more restrictive relocation to emit.
- */
- drm_intel_bo_emit_reloc(brw->wm.surf_bo[unit],
- offsetof(struct brw_surface_state, ss1),
- region_bo,
- surf.ss1.base_addr - region_bo->offset,
- I915_GEM_DOMAIN_RENDER,
- I915_GEM_DOMAIN_RENDER);
- }
+
+ /* XXX: we will only be rendering to this surface:
+ */
+ brw->sws->bo_emit_reloc(brw->wm.surf_bo[unit],
+ I915_GEM_DOMAIN_RENDER, 0,
+ ss.ss1.base_addr - surface->bo->offset, /* XXX */
+ offsetof(struct brw_surface_state, ss1),
+ surface->bo);
}
}
assert(brw->wm.nr_surfaces <= BRW_WM_MAX_SURF);
+ /* Note there is no key for this search beyond the values in the
+ * relocation array:
+ */
bind_bo = brw_search_cache(&brw->surface_cache, BRW_SS_SURF_BIND,
NULL, 0,
brw->wm.surf_bo, brw->wm.nr_surfaces,
NULL);
if (bind_bo == NULL) {
- GLuint data_size = brw->wm.nr_surfaces * sizeof(GLuint);
uint32_t data[BRW_WM_MAX_SURF];
+ GLuint data_size = brw->wm.nr_surfaces * sizeof data[0];
int i;
for (i = 0; i < brw->wm.nr_surfaces; i++)
- if (brw->wm.surf_bo[i])
- data[i] = brw->wm.surf_bo[i]->offset;
- else
- data[i] = 0;
+ data[i] = brw->wm.surf_bo[i]->offset;
bind_bo = brw_upload_cache( &brw->surface_cache, BRW_SS_SURF_BIND,
NULL, 0,
NULL, NULL);
/* Emit binding table relocations to surface state */
- for (i = 0; i < BRW_WM_MAX_SURF; i++) {
- if (brw->wm.surf_bo[i] != NULL) {
- dri_bo_emit_reloc(bind_bo,
- I915_GEM_DOMAIN_INSTRUCTION, 0,
- 0,
- i * sizeof(GLuint),
- brw->wm.surf_bo[i]);
- }
+ for (i = 0; i < brw->wm.nr_surfaces; i++) {
+ brw->sws->bo_emit_reloc(bind_bo,
+ I915_GEM_DOMAIN_INSTRUCTION, 0,
+ 0,
+ i * sizeof(GLuint),
+ brw->wm.surf_bo[i]);
}
}
return bind_bo;
}
-static void prepare_wm_surfaces(struct brw_context *brw )
+static int prepare_wm_surfaces(struct brw_context *brw )
{
GLuint i;
- int old_nr_surfaces;
-
- /* _NEW_BUFFERS */
- /* Update surfaces for drawing buffers */
- if (ctx->DrawBuffer->_NumColorDrawBuffers >= 1) {
- for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
- brw_update_renderbuffer_surface(brw,
- ctx->DrawBuffer->_ColorDrawBuffers[i],
- i);
- }
- } else {
- brw_update_renderbuffer_surface(brw, NULL, 0);
+ int nr_surfaces = 0;
+
+ /* Unreference old buffers
+ */
+ for (i = 0; i < brw->wm.nr_surfaces; i++) {
+ brw->sws->bo_unreference(brw->wm.surf_bo[i]);
+ brw->wm.surf_bo[i] = NULL;
}
- old_nr_surfaces = brw->wm.nr_surfaces;
- brw->wm.nr_surfaces = PIPE_MAX_COLOR_BUFS;
- if (brw->wm.surf_bo[SURF_INDEX_FRAG_CONST_BUFFER] != NULL)
- brw->wm.nr_surfaces = SURF_INDEX_FRAG_CONST_BUFFER + 1;
+ /* PIPE_NEW_COLOR_BUFFERS | PIPE_NEW_BLEND
+ *
+ * Update surfaces for drawing buffers. Mixes in colormask and
+ * blend state.
+ *
+ * XXX: no color buffer case
+ */
+ for (i = 0; i < brw->curr.fb.nr_cbufs; i++) {
+ brw_update_renderbuffer_surface(brw,
+ brw_surface(brw->curr.fb.cbufs[i]),
+ nr_surfaces++);
+ }
- /* Update surfaces for textures */
- for (i = 0; i < BRW_MAX_TEX_UNIT; i++) {
- const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i];
- const GLuint surf = SURF_INDEX_TEXTURE(i);
+ /* PIPE_NEW_TEXTURE
+ */
+ for (i = 0; i < brw->curr.num_textures; i++) {
+ brw_update_texture_surface(brw,
+ brw->curr.texture[i],
+ nr_surfaces++);
+ }
- /* _NEW_TEXTURE, BRW_NEW_TEXDATA */
- if (texUnit->_ReallyEnabled) {
- brw_update_texture_surface(ctx, i);
- brw->wm.nr_surfaces = surf + 1;
- } else {
- brw->sws->bo_unreference(brw->wm.surf_bo[surf]);
- brw->wm.surf_bo[surf] = NULL;
- }
+ /* PIPE_NEW_FRAGMENT_CONSTANTS
+ */
+#if 0
+ if (brw->curr.fragment_constants) {
+ brw_update_fragment_constant_surface(brw,
+ brw->curr.fragment_constants,
+ nr_surfaces++);
}
+#endif
brw->sws->bo_unreference(brw->wm.bind_bo);
brw->wm.bind_bo = brw_wm_get_binding_table(brw);
- if (brw->wm.nr_surfaces != old_nr_surfaces)
+ if (brw->wm.nr_surfaces != nr_surfaces) {
+ brw->wm.nr_surfaces = nr_surfaces;
brw->state.dirty.brw |= BRW_NEW_NR_WM_SURFACES;
+ }
+
+ return 0;
}
const struct brw_tracked_state brw_wm_surfaces = {
.dirty = {
- .mesa = (_NEW_COLOR |
- _NEW_TEXTURE |
- _NEW_BUFFERS),
+ .mesa = (PIPE_NEW_COLOR_BUFFERS |
+ PIPE_NEW_BOUND_TEXTURES |
+ PIPE_NEW_FRAGMENT_CONSTANTS |
+ PIPE_NEW_BLEND),
.brw = (BRW_NEW_CONTEXT |
BRW_NEW_WM_SURFACES),
.cache = 0