* IN THE SOFTWARE.
***************************************************************************/
+// llvm redefines DEBUG
+#pragma push_macro("DEBUG")
+#undef DEBUG
+#include "JitManager.h"
+#pragma pop_macro("DEBUG")
+
#include "common/os.h"
#include "jit_api.h"
-#include "JitManager.h"
#include "state_llvm.h"
#include "gallivm/lp_bld_tgsi.h"
unsigned i;
assert(shader < PIPE_SHADER_TYPES);
- assert(start + num <= Elements(ctx->samplers[shader]));
+ assert(start + num <= ARRAY_SIZE(ctx->samplers[shader]));
/* set the new samplers */
ctx->num_samplers[shader] = num;
assert(num <= PIPE_MAX_SHADER_SAMPLER_VIEWS);
assert(shader < PIPE_SHADER_TYPES);
- assert(start + num <= Elements(ctx->sampler_views[shader]));
+ assert(start + num <= ARRAY_SIZE(ctx->sampler_views[shader]));
/* set the new sampler views */
ctx->num_sampler_views[shader] = num;
swr_create_vs_state(struct pipe_context *pipe,
const struct pipe_shader_state *vs)
{
- struct swr_vertex_shader *swr_vs =
- (swr_vertex_shader *)CALLOC_STRUCT(swr_vertex_shader);
+ struct swr_vertex_shader *swr_vs = new swr_vertex_shader;
if (!swr_vs)
return NULL;
lp_build_tgsi_info(vs->tokens, &swr_vs->info);
- swr_vs->func = swr_compile_vs(pipe, swr_vs);
-
swr_vs->soState = {0};
if (swr_vs->pipe.stream_output.num_outputs) {
{
struct swr_vertex_shader *swr_vs = (swr_vertex_shader *)vs;
FREE((void *)swr_vs->pipe.tokens);
- FREE(vs);
+ delete swr_vs;
}
static void *
swr_set_constant_buffer(struct pipe_context *pipe,
uint shader,
uint index,
- struct pipe_constant_buffer *cb)
+ const struct pipe_constant_buffer *cb)
{
struct swr_context *ctx = swr_context(pipe);
struct pipe_resource *constants = cb ? cb->buffer : NULL;
assert(shader < PIPE_SHADER_TYPES);
- assert(index < Elements(ctx->constants[shader]));
+ assert(index < ARRAY_SIZE(ctx->constants[shader]));
/* note: reference counting */
util_copy_constant_buffer(&ctx->constants[shader][index], cb);
}
}
+static void
+swr_update_texture_state(struct swr_context *ctx,
+ unsigned shader_type,
+ unsigned num_sampler_views,
+ swr_jit_texture *textures)
+{
+ for (unsigned i = 0; i < num_sampler_views; i++) {
+ struct pipe_sampler_view *view =
+ ctx->sampler_views[shader_type][i];
+
+ if (view) {
+ struct pipe_resource *res = view->texture;
+ struct swr_resource *swr_res = swr_resource(res);
+ struct swr_jit_texture *jit_tex = &textures[i];
+ memset(jit_tex, 0, sizeof(*jit_tex));
+ jit_tex->width = res->width0;
+ jit_tex->height = res->height0;
+ jit_tex->depth = res->depth0;
+ jit_tex->first_level = view->u.tex.first_level;
+ jit_tex->last_level = view->u.tex.last_level;
+ jit_tex->base_ptr = swr_res->swr.pBaseAddress;
+
+ for (unsigned level = jit_tex->first_level;
+ level <= jit_tex->last_level;
+ level++) {
+ jit_tex->row_stride[level] = swr_res->row_stride[level];
+ jit_tex->img_stride[level] = swr_res->img_stride[level];
+ jit_tex->mip_offsets[level] = swr_res->mip_offsets[level];
+ }
+ }
+ }
+}
+
+static void
+swr_update_sampler_state(struct swr_context *ctx,
+ unsigned shader_type,
+ unsigned num_samplers,
+ swr_jit_sampler *samplers)
+{
+ for (unsigned i = 0; i < num_samplers; i++) {
+ const struct pipe_sampler_state *sampler =
+ ctx->samplers[shader_type][i];
+
+ if (sampler) {
+ samplers[i].min_lod = sampler->min_lod;
+ samplers[i].max_lod = sampler->max_lod;
+ samplers[i].lod_bias = sampler->lod_bias;
+ COPY_4V(samplers[i].border_color, sampler->border_color.f);
+ }
+ }
+}
+
+static void
+swr_update_constants(struct swr_context *ctx, enum pipe_shader_type shaderType)
+{
+ swr_draw_context *pDC = &ctx->swrDC;
+
+ const float **constant;
+ uint32_t *num_constants;
+ struct swr_scratch_space *scratch;
+
+ switch (shaderType) {
+ case PIPE_SHADER_VERTEX:
+ constant = pDC->constantVS;
+ num_constants = pDC->num_constantsVS;
+ scratch = &ctx->scratch->vs_constants;
+ break;
+ case PIPE_SHADER_FRAGMENT:
+ constant = pDC->constantFS;
+ num_constants = pDC->num_constantsFS;
+ scratch = &ctx->scratch->fs_constants;
+ break;
+ default:
+ debug_printf("Unsupported shader type constants\n");
+ return;
+ }
+
+ for (UINT i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
+ const pipe_constant_buffer *cb = &ctx->constants[shaderType][i];
+ num_constants[i] = cb->buffer_size;
+ if (cb->buffer) {
+ constant[i] =
+ (const float *)(swr_resource_data(cb->buffer) +
+ cb->buffer_offset);
+ } else {
+ /* Need to copy these constants to scratch space */
+ if (cb->user_buffer && cb->buffer_size) {
+ const void *ptr =
+ ((const uint8_t *)cb->user_buffer + cb->buffer_offset);
+ uint32_t size = AlignUp(cb->buffer_size, 4);
+ ptr = swr_copy_to_scratch_space(ctx, scratch, ptr, size);
+ constant[i] = (const float *)ptr;
+ }
+ }
+ }
+}
+
void
swr_update_derived(struct pipe_context *pipe,
const struct pipe_draw_info *p_draw_info)
struct swr_context *ctx = swr_context(pipe);
struct swr_screen *screen = swr_screen(ctx->pipe.screen);
+ /* Update screen->pipe to current pipe context. */
+ if (screen->pipe != pipe)
+ screen->pipe = pipe;
+
/* Any state that requires dirty flags to be re-triggered sets this mask */
/* For example, user_buffer vertex and index buffers. */
unsigned post_update_dirty_flags = 0;
}
/* Raster state */
- if (ctx->dirty & (SWR_NEW_RASTERIZER | SWR_NEW_FRAMEBUFFER)) {
+ if (ctx->dirty & (SWR_NEW_RASTERIZER |
+ SWR_NEW_VS | // clipping
+ SWR_NEW_FRAMEBUFFER)) {
pipe_rasterizer_state *rasterizer = ctx->rasterizer;
pipe_framebuffer_state *fb = &ctx->framebuffer;
rastState->msaaRastEnable = false;
rastState->rastMode = SWR_MSAA_RASTMODE_OFF_PIXEL;
rastState->sampleCount = SWR_MULTISAMPLE_1X;
- rastState->bForcedSampleCount = false;
+ rastState->forcedSampleCount = false;
bool do_offset = false;
switch (rasterizer->fill_front) {
rastState->depthClipEnable = rasterizer->depth_clip;
+ rastState->clipDistanceMask =
+ ctx->vs->info.base.num_written_clipdistance ?
+ ctx->vs->info.base.clipdist_writemask & rasterizer->clip_plane_enable :
+ rasterizer->clip_plane_enable;
+
+ rastState->cullDistanceMask =
+ ctx->vs->info.base.culldist_writemask << ctx->vs->info.base.num_written_clipdistance;
+
SwrSetRastState(ctx->swrContext, rastState);
}
max_vertex = size / pitch;
partial_inbounds = size % pitch;
- p_data = (const uint8_t *)swr_resource_data(vb->buffer)
- + vb->buffer_offset;
+ p_data = swr_resource_data(vb->buffer) + vb->buffer_offset;
} else {
/* Client buffer
* client memory is one-time use, re-trigger SWR_NEW_VERTEX to
* size is based on buffer->width0 rather than info.count
* to prevent having to validate VBO on each draw */
size = ib->buffer->width0;
- p_data =
- (const uint8_t *)swr_resource_data(ib->buffer) + ib->offset;
+ p_data = swr_resource_data(ib->buffer) + ib->offset;
} else {
/* Client buffer
* client memory is one-time use, re-trigger SWR_NEW_VERTEX to
}
/* VertexShader */
- if (ctx->dirty & (SWR_NEW_VS | SWR_NEW_FRAMEBUFFER)) {
- SwrSetVertexFunc(ctx->swrContext, ctx->vs->func);
+ if (ctx->dirty & (SWR_NEW_VS |
+ SWR_NEW_RASTERIZER | // for clip planes
+ SWR_NEW_SAMPLER |
+ SWR_NEW_SAMPLER_VIEW |
+ SWR_NEW_FRAMEBUFFER)) {
+ swr_jit_vs_key key;
+ swr_generate_vs_key(key, ctx, ctx->vs);
+ auto search = ctx->vs->map.find(key);
+ PFN_VERTEX_FUNC func;
+ if (search != ctx->vs->map.end()) {
+ func = search->second->shader;
+ } else {
+ func = swr_compile_vs(ctx, key);
+ }
+ SwrSetVertexFunc(ctx->swrContext, func);
+
+ /* JIT sampler state */
+ if (ctx->dirty & SWR_NEW_SAMPLER) {
+ swr_update_sampler_state(ctx,
+ PIPE_SHADER_VERTEX,
+ key.nr_samplers,
+ ctx->swrDC.samplersVS);
+ }
+
+ /* JIT sampler view state */
+ if (ctx->dirty & (SWR_NEW_SAMPLER_VIEW | SWR_NEW_FRAMEBUFFER)) {
+ swr_update_texture_state(ctx,
+ PIPE_SHADER_VERTEX,
+ key.nr_sampler_views,
+ ctx->swrDC.texturesVS);
+ }
}
- swr_jit_key key;
+ /* FragmentShader */
if (ctx->dirty & (SWR_NEW_FS | SWR_NEW_SAMPLER | SWR_NEW_SAMPLER_VIEW
| SWR_NEW_RASTERIZER | SWR_NEW_FRAMEBUFFER)) {
- memset(&key, 0, sizeof(key));
+ swr_jit_fs_key key;
swr_generate_fs_key(key, ctx, ctx->fs);
auto search = ctx->fs->map.find(key);
PFN_PIXEL_KERNEL func;
if (search != ctx->fs->map.end()) {
- func = search->second;
+ func = search->second->shader;
} else {
func = swr_compile_fs(ctx, key);
- ctx->fs->map.insert(std::make_pair(key, func));
}
SWR_PS_STATE psState = {0};
psState.pfnPixelShader = func;
psState.usesUAV = false; // XXX
psState.forceEarlyZ = false;
SwrSetPixelShaderState(ctx->swrContext, &psState);
- }
-
- /* JIT sampler state */
- if (ctx->dirty & SWR_NEW_SAMPLER) {
- swr_draw_context *pDC = &ctx->swrDC;
-
- for (unsigned i = 0; i < key.nr_samplers; i++) {
- const struct pipe_sampler_state *sampler =
- ctx->samplers[PIPE_SHADER_FRAGMENT][i];
- if (sampler) {
- pDC->samplersFS[i].min_lod = sampler->min_lod;
- pDC->samplersFS[i].max_lod = sampler->max_lod;
- pDC->samplersFS[i].lod_bias = sampler->lod_bias;
- COPY_4V(pDC->samplersFS[i].border_color, sampler->border_color.f);
- }
+ /* JIT sampler state */
+ if (ctx->dirty & SWR_NEW_SAMPLER) {
+ swr_update_sampler_state(ctx,
+ PIPE_SHADER_FRAGMENT,
+ key.nr_samplers,
+ ctx->swrDC.samplersFS);
}
- }
- /* JIT sampler view state */
- if (ctx->dirty & (SWR_NEW_SAMPLER_VIEW | SWR_NEW_FRAMEBUFFER)) {
- swr_draw_context *pDC = &ctx->swrDC;
-
- for (unsigned i = 0; i < key.nr_sampler_views; i++) {
- struct pipe_sampler_view *view =
- ctx->sampler_views[PIPE_SHADER_FRAGMENT][i];
-
- if (view) {
- struct pipe_resource *res = view->texture;
- struct swr_resource *swr_res = swr_resource(res);
- struct swr_jit_texture *jit_tex = &pDC->texturesFS[i];
- memset(jit_tex, 0, sizeof(*jit_tex));
- jit_tex->width = res->width0;
- jit_tex->height = res->height0;
- jit_tex->depth = res->depth0;
- jit_tex->first_level = view->u.tex.first_level;
- jit_tex->last_level = view->u.tex.last_level;
- jit_tex->base_ptr = swr_res->swr.pBaseAddress;
-
- for (unsigned level = jit_tex->first_level;
- level <= jit_tex->last_level;
- level++) {
- jit_tex->row_stride[level] = swr_res->row_stride[level];
- jit_tex->img_stride[level] = swr_res->img_stride[level];
- jit_tex->mip_offsets[level] = swr_res->mip_offsets[level];
- }
- }
+ /* JIT sampler view state */
+ if (ctx->dirty & (SWR_NEW_SAMPLER_VIEW | SWR_NEW_FRAMEBUFFER)) {
+ swr_update_texture_state(ctx,
+ PIPE_SHADER_FRAGMENT,
+ key.nr_sampler_views,
+ ctx->swrDC.texturesFS);
}
}
+
/* VertexShader Constants */
if (ctx->dirty & SWR_NEW_VSCONSTANTS) {
- swr_draw_context *pDC = &ctx->swrDC;
-
- for (UINT i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
- const pipe_constant_buffer *cb =
- &ctx->constants[PIPE_SHADER_VERTEX][i];
- pDC->num_constantsVS[i] = cb->buffer_size;
- if (cb->buffer)
- pDC->constantVS[i] =
- (const float *)((const uint8_t *)cb->buffer + cb->buffer_offset);
- else {
- /* Need to copy these constants to scratch space */
- if (cb->user_buffer && cb->buffer_size) {
- const void *ptr =
- ((const uint8_t *)cb->user_buffer + cb->buffer_offset);
- uint32_t size = AlignUp(cb->buffer_size, 4);
- ptr = swr_copy_to_scratch_space(
- ctx, &ctx->scratch->vs_constants, ptr, size);
- pDC->constantVS[i] = (const float *)ptr;
- }
- }
- }
+ swr_update_constants(ctx, PIPE_SHADER_VERTEX);
}
/* FragmentShader Constants */
if (ctx->dirty & SWR_NEW_FSCONSTANTS) {
- swr_draw_context *pDC = &ctx->swrDC;
-
- for (UINT i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
- const pipe_constant_buffer *cb =
- &ctx->constants[PIPE_SHADER_FRAGMENT][i];
- pDC->num_constantsFS[i] = cb->buffer_size;
- if (cb->buffer)
- pDC->constantFS[i] =
- (const float *)((const uint8_t *)cb->buffer + cb->buffer_offset);
- else {
- /* Need to copy these constants to scratch space */
- if (cb->user_buffer && cb->buffer_size) {
- const void *ptr =
- ((const uint8_t *)cb->user_buffer + cb->buffer_offset);
- uint32_t size = AlignUp(cb->buffer_size, 4);
- ptr = swr_copy_to_scratch_space(
- ctx, &ctx->scratch->fs_constants, ptr, size);
- pDC->constantFS[i] = (const float *)ptr;
- }
- }
- }
+ swr_update_constants(ctx, PIPE_SHADER_FRAGMENT);
}
/* Depth/stencil state */
}
}
- uint32_t linkage = ctx->vs->linkageMask;
- if (ctx->rasterizer->sprite_coord_enable)
- linkage |= (1 << ctx->vs->info.base.num_outputs);
-
- SwrSetLinkage(ctx->swrContext, linkage, NULL);
-
- // set up frontend state
- SWR_FRONTEND_STATE feState = {0};
- SwrSetFrontendState(ctx->swrContext, &feState);
+ if (ctx->dirty & SWR_NEW_CLIP) {
+ // shader exporting clip distances overrides all user clip planes
+ if (ctx->rasterizer->clip_plane_enable &&
+ !ctx->vs->info.base.num_written_clipdistance)
+ {
+ swr_draw_context *pDC = &ctx->swrDC;
+ memcpy(pDC->userClipPlanes,
+ ctx->clip.ucp,
+ sizeof(pDC->userClipPlanes));
+ }
+ }
// set up backend state
SWR_BACKEND_STATE backendState = {0};
- backendState.numAttributes = 1;
- backendState.numComponents[0] = 4;
- backendState.constantInterpolationMask = ctx->fs->constantMask;
+ backendState.numAttributes =
+ ctx->vs->info.base.num_outputs - 1 +
+ (ctx->rasterizer->sprite_coord_enable ? 1 : 0);
+ for (unsigned i = 0; i < backendState.numAttributes; i++)
+ backendState.numComponents[i] = 4;
+ backendState.constantInterpolationMask =
+ ctx->rasterizer->flatshade ?
+ ctx->fs->flatConstantMask :
+ ctx->fs->constantMask;
backendState.pointSpriteTexCoordMask = ctx->fs->pointSpriteMask;
SwrSetBackendState(ctx->swrContext, &backendState);